edit-dialog.vue 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. <script setup lang="ts">
  2. import { reactive, ref } from "vue";
  3. import { FormRules, ElForm } from "element-plus";
  4. import { httpUpdate, httpAdd } from "/@/api/system/menuOperator";
  5. import { menuTypeList, menuPrivateList } from "/@/utils/status";
  6. import { responseHandle } from "/@/utils/responseHandle";
  7. import { IconSelect } from "/@/components/ReIcon";
  8. import { useNav } from "/@/layout/hooks/nav";
  9. import type { IMenuTree } from "../types";
  10. enum FROM_TYPE {
  11. create = "create",
  12. edit = "edit",
  13. view = "view"
  14. }
  15. const { logout } = useNav();
  16. const showModel = ref(false);
  17. const currentMenuId = ref("");
  18. const TYPE = ref<FROM_TYPE>(FROM_TYPE.create);
  19. const formRef = ref<InstanceType<typeof ElForm>>(null);
  20. const currentNode = ref<IMenuTree | null>(null);
  21. const loading = ref(false);
  22. const titleType = ref("");
  23. const emit = defineEmits(["reload"]);
  24. const initform = {
  25. menu_name: "",
  26. menu_type: "1",
  27. menu_img: "",
  28. menu_route: "",
  29. menu_url: "",
  30. private: "1",
  31. weight: "1",
  32. pid: "0",
  33. level: "",
  34. id: ""
  35. };
  36. const ruleForm = ref({ ...initform });
  37. const rules = reactive<FormRules>({
  38. menu_name: [
  39. { required: true, message: "请输入菜单名称", trigger: "blur" },
  40. // { min: 1, max: 10, message: "长度在 1 到 10 个字符", trigger: "blur" }
  41. ],
  42. menu_type: [
  43. {
  44. required: true,
  45. message: "请选择菜单类型",
  46. trigger: "change"
  47. }
  48. ],
  49. menu_img: [
  50. {
  51. required: true,
  52. message: "请选择菜单图标",
  53. trigger: "change"
  54. }
  55. ],
  56. menu_route: [
  57. {
  58. required: true,
  59. message: "请输入菜单路由",
  60. trigger: "blur"
  61. },
  62. { min: 1, max: 50, message: "长度在 1 到 50 个字符", trigger: "blur" }
  63. ],
  64. menu_url: [
  65. {
  66. required: true,
  67. message: "请输入文件地址",
  68. trigger: "blur"
  69. },
  70. { min: 1, max: 100, message: "长度在 1 到 100 个字符", trigger: "blur" }
  71. ],
  72. private: [
  73. {
  74. required: true,
  75. message: "请选择页面是否显示",
  76. trigger: "change"
  77. }
  78. ],
  79. weight: [
  80. {
  81. required: true,
  82. message: "请输入排序权重",
  83. trigger: "blur"
  84. }
  85. ],
  86. level: [
  87. {
  88. required: true,
  89. message: "请选择菜单权限等级",
  90. trigger: "blur"
  91. }
  92. ]
  93. });
  94. function show(node: any, id: string, isCreate: string) {
  95. console.log(node);
  96. currentNode.value = node;
  97. Object.keys(ruleForm.value).forEach(key => {
  98. if (key == "private") {
  99. ruleForm.value[key] =
  100. isCreate === "create" ? "1" : String(node["is_private"]);
  101. } else {
  102. ruleForm.value[key] =
  103. isCreate === "create" ? initform[key] : String(node[key]);
  104. }
  105. });
  106. if (id !== "" && isCreate === "create") {
  107. ruleForm.value.pid = id;
  108. }
  109. TYPE.value = isCreate;
  110. switch (TYPE.value) {
  111. case "create":
  112. titleType.value = "新建菜单";
  113. break;
  114. case "edit":
  115. titleType.value = "编辑菜单";
  116. break;
  117. case "view":
  118. titleType.value = "菜单详情";
  119. break;
  120. default:
  121. titleType.value = "新建菜单";
  122. }
  123. console.log(ruleForm.value);
  124. menu_type_change();
  125. showModel.value = true;
  126. }
  127. function handleUpdate() {
  128. const data = {
  129. ...ruleForm.value
  130. };
  131. return {
  132. data,
  133. api: httpUpdate
  134. };
  135. }
  136. function handleCreate() {
  137. const data = {
  138. ...ruleForm.value
  139. };
  140. return {
  141. data,
  142. api: httpAdd
  143. };
  144. }
  145. function handleSave() {
  146. formRef.value.validate(async valid => {
  147. if (valid) {
  148. if (loading.value) return;
  149. const handler =
  150. TYPE.value === FROM_TYPE.create ? handleCreate : handleUpdate;
  151. loading.value = true;
  152. const { api, data } = handler();
  153. const { message, code } = await api(data);
  154. responseHandle({
  155. code,
  156. message,
  157. logout,
  158. handler: () => {
  159. showModel.value = false;
  160. loading.value = false;
  161. emit("reload");
  162. }
  163. });
  164. }
  165. });
  166. }
  167. function menu_type_change() {
  168. const { menu_type } = ruleForm.value;
  169. rules.menu_url[0].required = menu_type === "2";
  170. }
  171. defineExpose({
  172. show,
  173. changeCurrentMenuId: (id: string) => (currentMenuId.value = id)
  174. });
  175. </script>
  176. <template>
  177. <div>
  178. <el-dialog
  179. v-model="showModel"
  180. :close-on-click-modal="false"
  181. :close-on-press-escape="false"
  182. center
  183. append-to-body
  184. destroy-on-close
  185. :width="'700px'"
  186. :title="titleType"
  187. v-loading="loading"
  188. >
  189. <el-form
  190. ref="formRef"
  191. :model="ruleForm"
  192. :rules="rules"
  193. label-width="90px"
  194. class="demo-ruleForm"
  195. status-icon
  196. >
  197. <el-row>
  198. <el-col :span="24">
  199. <el-form-item label="菜单名称" prop="menu_name">
  200. <el-input
  201. v-model="ruleForm.menu_name"
  202. :disabled="TYPE === 'view'"
  203. placeholder="菜单名称"
  204. /> </el-form-item
  205. ></el-col>
  206. <el-col :span="12">
  207. <el-form-item label="菜单类型" prop="menu_type">
  208. <el-select
  209. v-model="ruleForm.menu_type"
  210. style="width: 100%"
  211. @change="menu_type_change"
  212. :disabled="TYPE === 'view'"
  213. placeholder="菜单类型"
  214. >
  215. <el-option
  216. v-for="(si, sii) in menuTypeList"
  217. :key="'type' + si.value + sii"
  218. :label="si.label"
  219. :value="si.value"
  220. />
  221. </el-select> </el-form-item
  222. ></el-col>
  223. <el-col :span="12">
  224. <el-form-item label="菜单图标" prop="menu_img">
  225. <IconSelect v-model="ruleForm.menu_img" />
  226. <!-- <IconifyIconOffline icon="user" /> -->
  227. </el-form-item></el-col
  228. >
  229. <el-col :span="12">
  230. <el-form-item label="菜单路由" prop="menu_route">
  231. <el-input
  232. v-model="ruleForm.menu_route"
  233. :disabled="TYPE === 'view'"
  234. placeholder="菜单路由" /></el-form-item
  235. ></el-col>
  236. <el-col :span="12">
  237. <el-form-item label="页面显示" prop="private">
  238. <el-radio-group
  239. v-model="ruleForm.private"
  240. :disabled="TYPE === 'view'"
  241. >
  242. <el-radio
  243. v-for="(si, sii) in menuPrivateList"
  244. :key="si.value + sii"
  245. :label="si.value"
  246. :value="si.value"
  247. >{{ si.label }}</el-radio
  248. >
  249. </el-radio-group>
  250. </el-form-item></el-col
  251. >
  252. <el-col :span="24" v-if="ruleForm.menu_type === '2'">
  253. <el-form-item label="页面地址" prop="menu_url">
  254. <el-input
  255. v-model="ruleForm.menu_url"
  256. placeholder="页面地址"
  257. :disabled="TYPE === 'view'"
  258. >
  259. <template #prepend>views/</template>
  260. <template #append>.vue</template></el-input
  261. >
  262. </el-form-item></el-col
  263. >
  264. <el-col :span="12">
  265. <el-form-item label="排序权重" prop="weight">
  266. <el-input-number
  267. v-model="ruleForm.weight"
  268. :precision="0"
  269. style="width: 100%"
  270. :min="1"
  271. :max="999"
  272. :disabled="TYPE === 'view'"
  273. /> </el-form-item
  274. ></el-col>
  275. <el-col :span="12">
  276. <el-form-item label-width="120px" label="菜单权限等级" prop="level">
  277. <el-select v-model="ruleForm.level">
  278. <el-option label="公共" value="0" />
  279. <el-option label="超管" value="1" />
  280. <el-option label="平台端" value="2" />
  281. <el-option label="供应商端" value="3" />
  282. </el-select>
  283. </el-form-item>
  284. </el-col>
  285. </el-row>
  286. <div class="flex justify-end">
  287. <el-button :loading="loading" type="primary" @click="handleSave"
  288. >保存</el-button
  289. >
  290. <el-button @click="showModel = false">取消</el-button>
  291. </div>
  292. </el-form>
  293. </el-dialog>
  294. </div>
  295. </template>