You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

340 lines
11 KiB

9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
8 months ago
9 months ago
9 months ago
9 months ago
9 months ago
  1. <template>
  2. <el-dialog
  3. class="sl-menu-item"
  4. width="465px"
  5. :title="!dataForm.id ? buttons.add :buttons.edit"
  6. :close-on-click-modal="false"
  7. :visible.sync="visible">
  8. <el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmit()" label-width="80px">
  9. <el-form-item :label="buttons.type || '类型'" prop="type">
  10. <el-radio-group v-model="dataForm.type">
  11. <el-radio v-for="(type, index) in dataForm.typeList" :label="index" :key="index">{{ type }}</el-radio>
  12. </el-radio-group>
  13. </el-form-item>
  14. <el-form-item :label="buttons.parentName ||'上级菜单'" prop="parentName">
  15. <el-popover
  16. ref="menuListPopover"
  17. placement="bottom-start"
  18. v-model="treeVisible"
  19. onclick="treeVisible=true"
  20. trigger="click">
  21. <el-tree
  22. :data="menuList"
  23. :props="menuListTreeProps"
  24. node-key="menuId"
  25. ref="menuListTree"
  26. @current-change="menuListTreeCurrentChangeHandle"
  27. :default-expand-all="false"
  28. :highlight-current="true"
  29. :expand-on-click-node="false">
  30. </el-tree>
  31. </el-popover>
  32. <el-input style="width: 349px;" v-model="dataForm.parentName" v-popover:menuListPopover :readonly="true" class="menu-list__input"></el-input>
  33. </el-form-item>
  34. <el-form-item label="目录编号" prop="menuId">
  35. <el-input :readonly="dataForm.id?true:false" style="width: 349px;" v-model="dataForm.menuId" oninput="value=value.replace(/[^\d]/g, '')"></el-input>
  36. </el-form-item>
  37. <el-form-item label="目录名称" prop="name">
  38. <el-input style="width: 349px;" v-model="dataForm.name"></el-input>
  39. </el-form-item>
  40. <el-form-item v-if="dataForm.type === 1" :label="buttons.route || '菜单路由'" prop="url">
  41. <el-input style="width: 349px;" v-model="dataForm.url" placeholder="菜单路由"></el-input>
  42. </el-form-item>
  43. <el-form-item v-if="dataForm.type !== 0" :label="buttons.perms || '授权标识'" prop="perms">
  44. <el-input style="width: 349px;" v-model="dataForm.perms" placeholder="多个用逗号分隔, 如: user:list,user:create"></el-input>
  45. </el-form-item>
  46. <el-form-item v-if="dataForm.type !== 2" :label="buttons.orderNum || '排序号'" prop="orderNum">
  47. <el-input style="width: 349px;" oninput="value=value.replace(/[^\d]/g, '')" v-model="dataForm.orderNum" :min="0" ></el-input>
  48. </el-form-item>
  49. <el-form-item :label="buttons.menuType || '菜单类型'" prop="menuType">
  50. <el-select v-model="dataForm.menuType">
  51. <el-option label="pc" value="pc"></el-option>
  52. <el-option label="pda" value="pda"></el-option>
  53. </el-select>
  54. </el-form-item>
  55. <el-form-item v-if="dataForm.type !== 2" label="菜单图标" prop="icon">
  56. <el-row>
  57. <el-col :span="22">
  58. <el-popover
  59. ref="iconListPopover"
  60. placement="bottom-start"
  61. trigger="click"
  62. popper-class="mod-menu__icon-popover">
  63. <div class="mod-menu__icon-inner">
  64. <div class="mod-menu__icon-list">
  65. <el-button
  66. v-for="(item, index) in iconList"
  67. :key="index"
  68. @click="iconActiveHandle(item)"
  69. :class="{ 'is-active': item === dataForm.icon }">
  70. <icon-svg :name="item"></icon-svg>
  71. </el-button>
  72. </div>
  73. </div>
  74. </el-popover>
  75. <el-input style="width: 349px;" v-model="dataForm.icon" v-popover:iconListPopover :readonly="true" class="icon-list__input"></el-input>
  76. </el-col>
  77. </el-row>
  78. </el-form-item>
  79. </el-form>
  80. <span slot="footer" class="dialog-footer">
  81. <el-button type="primary" @click="dataFormSubmit()">{{ buttons.submit || '确定' }}</el-button>
  82. <el-button type="primary" @click="visible = false">{{ buttons.close || '关闭' }}</el-button>
  83. </span>
  84. </el-dialog>
  85. </template>
  86. <script>
  87. import { treeDataTranslate } from '@/utils'
  88. import Icon from '@/icons'
  89. import {
  90. searchFunctionButtonList,
  91. } from "@/api/sysLanguage.js"
  92. export default {
  93. data () {
  94. var validateUrl = (rule, value, callback) => {
  95. if (this.dataForm.type === 1 && !/\S/.test(value)) {
  96. callback(new Error('菜单URL不能为空'))
  97. } else {
  98. callback()
  99. }
  100. }
  101. return {
  102. visible: false,
  103. treeVisible: false,
  104. dataForm: {
  105. id: 0,
  106. type: 1,
  107. typeList: ['目录', '菜单', '按钮'],
  108. name: '',
  109. parentId: 0,
  110. parentName: '',
  111. url: '',
  112. perms: '',
  113. orderNum: 0,
  114. icon: '',
  115. iconList: [],
  116. menuType: '',
  117. menuId:'',
  118. typeName:'名称'
  119. },
  120. dataRule: {
  121. menuId: [
  122. { required: true, message: '目录编号不能为空', trigger: 'blur' },
  123. { pattern: /^\d+$/, message: '目录编号必须是纯数字', trigger: 'blur' }
  124. ],
  125. name: [
  126. { required: true, message: '菜单名称不能为空', trigger: 'blur' }
  127. ],
  128. parentName: [
  129. { required: true, message: '上级菜单不能为空', trigger: 'change' }
  130. ],
  131. url: [
  132. { validator: validateUrl, trigger: 'blur' }
  133. ]
  134. },
  135. buttons: {
  136. cz: '操作',
  137. add: '添加',
  138. edit: '编辑',
  139. close: '关闭',
  140. submit: '确定',
  141. menuType:'菜单类型',
  142. name:'名称',
  143. parentName:'上级菜单',
  144. icon:'图标',
  145. type:'类型',
  146. menu:'菜单',
  147. button:'按钮',
  148. orderNum:'排序号',
  149. url:'菜单URL',
  150. perms:'授权标识',
  151. helpFile : '帮助文档',
  152. language:'语言',
  153. route:'菜单路由',
  154. type1: '目录',
  155. type2: '菜单',
  156. type3: '按钮',
  157. code:'编号'
  158. },
  159. menuList: [],
  160. flatMenuList: [],
  161. menuListTreeProps: {
  162. label: 'name',
  163. children: 'children'
  164. }
  165. }
  166. },
  167. created () {
  168. this.iconList = Icon.getNameList()
  169. // this.getFunctionButtonList()
  170. },
  171. methods: {
  172. init (id) {
  173. this.dataForm.id = id || 0
  174. this.$http({
  175. url: this.$http.adornUrl('/sys/menu/select'),
  176. method: 'get',
  177. params: this.$http.adornParams()
  178. }).then(({data}) => {
  179. this.flatMenuList = data.menuList || []
  180. this.menuList = treeDataTranslate(data.menuList, 'menuId')
  181. }).then(() => {
  182. this.visible = true
  183. this.$nextTick(() => {
  184. this.$refs['dataForm'].resetFields()
  185. })
  186. }).then(() => {
  187. if (!this.dataForm.id) {
  188. // 新增
  189. this.menuListTreeSetCurrentNode()
  190. } else {
  191. // 修改
  192. this.$http({
  193. url: this.$http.adornUrl(`/sys/menu/info/${this.dataForm.id}`),
  194. method: 'get',
  195. params: this.$http.adornParams()
  196. }).then(({data}) => {
  197. this.dataForm.id = data.menu.menuId
  198. this.dataForm.type = data.menu.type
  199. this.dataForm.name = data.menu.name
  200. this.dataForm.parentId = data.menu.parentId
  201. this.dataForm.url = data.menu.url
  202. this.dataForm.perms = data.menu.perms
  203. this.dataForm.orderNum = data.menu.orderNum
  204. this.dataForm.icon = data.menu.icon
  205. this.dataForm.menuType = data.menu.menuType
  206. this.dataForm.menuId = data.menu.menuId
  207. this.menuListTreeSetCurrentNode()
  208. })
  209. }
  210. })
  211. },
  212. // 获取button的词典
  213. getFunctionButtonList() {
  214. let queryButton = {
  215. functionId: this.$route.meta.menuId,
  216. tableId: '*',
  217. languageCode: this.$i18n.locale,
  218. objectType: 'button'
  219. }
  220. searchFunctionButtonList(queryButton).then(({data}) => {
  221. if (data.code == 0 && data.data) {
  222. this.buttons = data.data
  223. this.typeList= [this.buttons.type1, this.buttons.type2, this.buttons.type3]
  224. }
  225. })
  226. },
  227. // 菜单树选中
  228. menuListTreeCurrentChangeHandle (data, node) {
  229. this.dataForm.parentId = data.menuId
  230. this.dataForm.parentName = data.name
  231. this.treeVisible = false
  232. // 在添加时,根据用户选的上级菜单的menuId作为parentId去查最大的menuId+1,赋值给目录编码
  233. if (!this.dataForm.id) {
  234. let children = this.flatMenuList.filter(item => item.parentId === data.menuId)
  235. if (children.length > 0) {
  236. let maxId = Math.max(...children.map(item => Number(item.menuId)))
  237. this.dataForm.menuId = String(maxId + 1)
  238. } else {
  239. this.dataForm.menuId = String(data.menuId) + '01'
  240. }
  241. }
  242. },
  243. // 菜单树设置当前选中节点
  244. menuListTreeSetCurrentNode () {
  245. this.$refs.menuListTree.setCurrentKey(this.dataForm.parentId)
  246. this.dataForm.parentName = (this.$refs.menuListTree.getCurrentNode() || {})['name']
  247. },
  248. // 图标选中
  249. iconActiveHandle (iconName) {
  250. this.dataForm.icon = iconName
  251. },
  252. // 表单提交
  253. dataFormSubmit () {
  254. this.$refs['dataForm'].validate((valid) => {
  255. if (valid) {
  256. this.$http({
  257. url: this.$http.adornUrl(`/sys/menu/${!this.dataForm.id ? 'save' : 'update'}`),
  258. method: 'post',
  259. data: this.$http.adornData({
  260. 'menuId': this.dataForm.menuId,
  261. 'type': this.dataForm.type,
  262. 'name': this.dataForm.name,
  263. 'parentId': this.dataForm.parentId,
  264. 'url': this.dataForm.url,
  265. 'perms': this.dataForm.perms,
  266. 'orderNum': this.dataForm.orderNum,
  267. 'icon': this.dataForm.icon,
  268. 'menuType': this.dataForm.menuType,
  269. })
  270. }).then(({data}) => {
  271. if (data && data.code === 0) {
  272. this.$message.success('操作成功')
  273. this.visible = false
  274. this.$emit('refreshDataList')
  275. } else {
  276. this.$message.error(data.msg)
  277. }
  278. })
  279. }
  280. })
  281. }
  282. },
  283. }
  284. </script>
  285. <style lang="scss" >
  286. .mod-menu {
  287. .menu-list__input,
  288. .icon-list__input {
  289. > .el-input__inner {
  290. cursor: pointer;
  291. }
  292. }
  293. &__icon-popover {
  294. width: 458px;
  295. overflow: hidden;
  296. }
  297. &__icon-inner {
  298. width: 478px;
  299. max-height: 258px;
  300. overflow-x: hidden;
  301. overflow-y: auto;
  302. }
  303. &__icon-list {
  304. width: 458px;
  305. padding: 0;
  306. margin: -8px 0 0 -8px;
  307. > .el-button {
  308. padding: 8px;
  309. margin: 8px 0 0 8px;
  310. > span {
  311. display: inline-block;
  312. vertical-align: middle;
  313. width: 18px;
  314. height: 18px;
  315. font-size: 18px;
  316. }
  317. }
  318. }
  319. .icon-list__tips {
  320. font-size: 18px;
  321. text-align: center;
  322. color: #e6a23c;
  323. cursor: pointer;
  324. }
  325. }
  326. .el-popover {
  327. height: 50%;
  328. width: 350px;
  329. overflow:auto;
  330. }
  331. .sl-menu-item .el-form-item {
  332. margin-bottom: 5px;
  333. }
  334. </style>