menu-edit.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. <!-- 编辑弹窗 -->
  2. <template>
  3. <ele-modal
  4. width="720px"
  5. :visible="visible"
  6. :close-on-click-modal="false"
  7. custom-class="ele-dialog-form"
  8. :title="isUpdate ? '修改菜单' : '添加菜单'"
  9. @update:visible="updateVisible"
  10. :maxable="true"
  11. >
  12. <el-form ref="form" :model="form" :rules="rules" label-width="100px">
  13. <el-row>
  14. <el-col :span="12">
  15. <el-form-item label="上级菜单:">
  16. <ele-tree-select
  17. clearable
  18. v-model="form.parentId"
  19. :data="menuList"
  20. label-key="name"
  21. value-key="id"
  22. default-expand-all
  23. placeholder="请选择上级菜单"
  24. />
  25. </el-form-item>
  26. </el-col>
  27. <el-col :span="12">
  28. <el-form-item label="菜单名称:" prop="name">
  29. <el-input
  30. clearable
  31. v-model="form.name"
  32. placeholder="请输入菜单名称"
  33. />
  34. </el-form-item>
  35. </el-col>
  36. <el-col :span="24">
  37. <el-form-item label="菜单来源:" prop="source">
  38. <el-radio-group v-model="form.source" @input="sourceChange">
  39. <el-radio :label="1">内部地址</el-radio>
  40. <el-radio :label="2">报表地址</el-radio>
  41. </el-radio-group>
  42. </el-form-item>
  43. </el-col>
  44. <el-col :span="12">
  45. <el-form-item label="路由地址:" prop="url">
  46. <el-input
  47. :disabled="form.source == 2"
  48. clearable
  49. v-model="form.url"
  50. placeholder="请输入路由地址"
  51. />
  52. </el-form-item>
  53. </el-col>
  54. <el-col :span="12">
  55. <el-form-item
  56. label="组件地址"
  57. prop="component"
  58. >
  59. <el-input
  60. :disabled="form.source == 2"
  61. clearable
  62. v-model="form.component"
  63. :placeholder="
  64. form.source == 1 ? '请输入组件地址' : '请输入外链地址'
  65. "
  66. />
  67. </el-form-item>
  68. </el-col>
  69. <el-col :span="12">
  70. <el-form-item label="权限编码:" prop="permissionCode">
  71. <el-input
  72. clearable
  73. v-model="form.permissionCode"
  74. placeholder="请输入路由地址"
  75. />
  76. </el-form-item>
  77. </el-col>
  78. <el-col :span="12">
  79. <el-form-item v-if="form.rootId != 99999" label="菜单图标:">
  80. <ele-icon-picker
  81. v-model="form.icon"
  82. placeholder="请选择菜单图标"
  83. :disabled="form.type === 2"
  84. />
  85. </el-form-item>
  86. <el-form-item v-if="form.rootId == 99999" label="菜单图标:">
  87. <el-input
  88. clearable
  89. v-model="form.icon"
  90. placeholder="请输入pda图标"
  91. />
  92. </el-form-item>
  93. </el-col>
  94. <el-col :span="12">
  95. <el-form-item label="密级:" prop="secretLevel">
  96. <el-select v-model="form.secretLevel" style="width: 100%">
  97. <el-option
  98. v-for="item in secretLevelList()"
  99. :key="item.value"
  100. :label="item.label"
  101. :value="item.value"
  102. ></el-option>
  103. </el-select>
  104. </el-form-item>
  105. </el-col>
  106. <el-col :span="12">
  107. <el-form-item label="排序号:" prop="sort">
  108. <el-input-number
  109. :min="0"
  110. v-model="form.sort"
  111. placeholder="请输入排序号"
  112. controls-position="right"
  113. class="ele-fluid ele-text-left"
  114. />
  115. </el-form-item>
  116. </el-col>
  117. <el-col :span="12">
  118. <el-form-item :rules="[
  119. { required: form.source === 2 ? true : false, message: '字段必填', trigger: 'blur' }
  120. ]" :label="form.source === 2 ? '报表ID:': '扩展属性:'" :prop="form.source == 2 ? 'extend' : ''">
  121. <el-input
  122. clearable
  123. v-model="form.extend"
  124. :placeholder="form.source === 2 ? '请输入报表ID' : '请输入扩展属性'"
  125. />
  126. </el-form-item>
  127. </el-col>
  128. <el-col :span="12">
  129. <el-form-item label="菜单类型:" prop="type">
  130. <el-radio-group v-model="form.type" @change="onMenuTypeChange">
  131. <el-radio :label="1">菜单</el-radio>
  132. <el-radio :label="2">按钮</el-radio>
  133. </el-radio-group>
  134. </el-form-item>
  135. </el-col>
  136. </el-row>
  137. <!-- <div style="margin: 6px 0 28px 0">
  138. <el-divider />
  139. </div> -->
  140. </el-form>
  141. <template v-slot:footer>
  142. <el-button @click="updateVisible(false)">取消</el-button>
  143. <el-button type="primary" :loading="loading" @click="save">
  144. 保存
  145. </el-button>
  146. </template>
  147. </ele-modal>
  148. </template>
  149. <script>
  150. import { EleIconPicker } from 'ele-admin';
  151. import { saveOrUpdate } from '@/api/system/menu';
  152. import { secretLevelList } from '@/enum/dict';
  153. export default {
  154. components: { EleIconPicker },
  155. props: {
  156. // 弹窗是否打开
  157. visible: Boolean,
  158. // 修改回显的数据
  159. data: Object,
  160. // 上级菜单id
  161. parentId: [Number, String],
  162. // 全部菜单数据
  163. menuList: Array
  164. },
  165. data() {
  166. const defaultForm = {
  167. id: null,
  168. parentId: '',
  169. name: '',
  170. type: 1,
  171. source: 1,
  172. icon: '',
  173. url: '/',
  174. component: '',
  175. sort: null,
  176. rootId: null,
  177. permissionCode: 1,
  178. secretLevel: 1,
  179. extend: null, //报表ID
  180. };
  181. return {
  182. defaultForm,
  183. // 表单数据
  184. form: { ...defaultForm },
  185. // 表单验证规则
  186. rules: {
  187. name: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
  188. sort: [{ required: true, message: '请输入排序号', trigger: 'blur' }],
  189. url: [{ required: true, message: '请输入菜单路由', trigger: 'blur' }],
  190. component: [
  191. { required: true, message: '请输入组件地址', trigger: 'blur' }
  192. ],
  193. type: [{ required: true, message: '请选择菜单类型', trigger: 'blur' }]
  194. },
  195. // 提交状态
  196. loading: false,
  197. // 是否是修改
  198. isUpdate: false
  199. };
  200. },
  201. computed: {
  202. // pathPlaceholder() {
  203. // return this.form.openType === 2 ? '请输入外链地址' : '请输入路由地址';
  204. // },
  205. // componentPlaceholder() {
  206. // return this.form.openType === 1 ? '请输入内链地址' : '请输入组件路径';
  207. // },
  208. // // 是否开启响应式布局
  209. // styleResponsive() {
  210. // return this.$store.state.theme.styleResponsive;
  211. // }
  212. },
  213. methods: {
  214. secretLevelList() {
  215. return secretLevelList;
  216. },
  217. sourceChange(e) {
  218. if (e == 2) {
  219. this.form.url =
  220. '/reportForms/sourceLink';
  221. this.form.component = '/reportForms/sourceLink'
  222. } else {
  223. this.form.url = '/';
  224. }
  225. },
  226. /* 保存编辑 */
  227. save() {
  228. this.$refs.form.validate((valid) => {
  229. if (!valid) {
  230. return false;
  231. }
  232. this.loading = true;
  233. const data = {
  234. ...this.form,
  235. // menuType 对应的值与后端不一致在前端处理
  236. // type: this.form.type === 2 ? 1 : 0,
  237. parentId: this.form.parentId || 0
  238. };
  239. // const saveOrUpdate = this.isUpdate ? updateMenu : addMenu;
  240. if (!this.isUpdate) {
  241. delete data.id;
  242. }
  243. saveOrUpdate(data)
  244. .then((res) => {
  245. this.loading = false;
  246. if (this.isUpdate) {
  247. this.$message.success('菜单编辑成功');
  248. } else {
  249. this.$message.success('菜单新增成功');
  250. }
  251. this.updateVisible(false);
  252. this.$emit('done');
  253. })
  254. .catch((e) => {
  255. this.loading = false;
  256. // this.$message.error(e.message);
  257. });
  258. });
  259. },
  260. /* 更新visible */
  261. updateVisible(value) {
  262. this.$emit('update:visible', value);
  263. },
  264. /* menuType选择改变 */
  265. onMenuTypeChange() {
  266. // if (this.form.menuType === 0) {
  267. // this.form.authority = null;
  268. // this.form.openType = 0;
  269. // this.form.component = null;
  270. // } else if (this.form.menuType === 1) {
  271. // if (this.form.openType === 2) {
  272. // this.form.authority = null;
  273. // }
  274. // } else {
  275. // this.form.openType = 0;
  276. // this.form.icon = null;
  277. // this.form.path = null;
  278. // this.form.component = null;
  279. // this.form.hide = 0;
  280. // }
  281. },
  282. /* openType选择改变 */
  283. onOpenTypeChange() {
  284. if (this.form.openType === 2) {
  285. this.form.component = null;
  286. this.form.authority = null;
  287. }
  288. }
  289. /* 判断是否是外链 */
  290. // isUrl(url) {
  291. // return !!(
  292. // url &&
  293. // (url.startsWith('http://') ||
  294. // url.startsWith('https://') ||
  295. // url.startsWith('//'))
  296. // );
  297. // },
  298. /* 判断是否是目录 */
  299. // isDirectory(d) {
  300. // return !!d.children?.length && !d.component;
  301. // }
  302. },
  303. watch: {
  304. visible(visible) {
  305. if (visible) {
  306. if (this.data) {
  307. // const isInnerLink = this.isUrl(this.data.component) ? 1 : 0;
  308. // menuType 对应的值与后端不一致在前端处理
  309. // const menuType =
  310. // this.data.type === 1
  311. // ? 2
  312. // : this.isDirectory(this.data)
  313. // ? 0
  314. // : 1;
  315. this.$util.assignObject(this.form, {
  316. ...this.data,
  317. // openType: this.isUrl(this.data.path) ? 2 : isInnerLink,
  318. parentId: this.data.parentId == 0 ? '' : this.data.parentId ?? ''
  319. });
  320. this.isUpdate = true;
  321. // this.sourceChange(this.form.source);
  322. } else {
  323. this.form.parentId = this.parentId ?? '';
  324. this.isUpdate = false;
  325. }
  326. } else {
  327. this.$refs.form.clearValidate();
  328. this.form = { ...this.defaultForm };
  329. // this.sourceChange(this.form.source);
  330. }
  331. }
  332. }
  333. };
  334. </script>