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.

327 lines
11 KiB

2 years 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="dataForm.typeList[dataForm.type] + buttons.code ||'编号'" prop="menuId">
  15. <el-input :readonly="dataForm.id?true:false" style="width: 349px;" v-model="dataForm.menuId" ></el-input>
  16. </el-form-item>
  17. <el-form-item :label="dataForm.typeList[dataForm.type] + buttons.typeName ||'名称'" prop="name">
  18. <el-input style="width: 349px;" v-model="dataForm.name" ></el-input>
  19. </el-form-item>
  20. <el-form-item :label="buttons.parentName ||'上级菜单'" prop="parentName">
  21. <el-popover
  22. ref="menuListPopover"
  23. placement="bottom-start"
  24. v-model="treeVisible"
  25. onclick="treeVisible=true"
  26. trigger="click">
  27. <el-tree
  28. :data="menuList"
  29. :props="menuListTreeProps"
  30. node-key="menuId"
  31. ref="menuListTree"
  32. @current-change="menuListTreeCurrentChangeHandle"
  33. :default-expand-all="false"
  34. :highlight-current="true"
  35. :expand-on-click-node="false">
  36. </el-tree>
  37. </el-popover>
  38. <el-input style="width: 349px;" v-model="dataForm.parentName" v-popover:menuListPopover :readonly="true" class="menu-list__input"></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. name: [
  122. { required: true, message: '菜单名称不能为空', trigger: 'blur' }
  123. ],
  124. parentName: [
  125. { required: true, message: '上级菜单不能为空', trigger: 'change' }
  126. ],
  127. menuId: [
  128. { required: true, message: '上级菜单不能为空', trigger: 'change' }
  129. ],
  130. url: [
  131. { validator: validateUrl, trigger: 'blur' }
  132. ],
  133. },
  134. buttons: {
  135. cz: '操作',
  136. add: '添加',
  137. edit: '编辑',
  138. close: '关闭',
  139. submit: '确定',
  140. menuType:'菜单类型',
  141. name:'名称',
  142. parentName:'上级菜单',
  143. icon:'图标',
  144. type:'类型',
  145. menu:'菜单',
  146. button:'按钮',
  147. orderNum:'排序号',
  148. url:'菜单URL',
  149. perms:'授权标识',
  150. helpFile : '帮助文档',
  151. language:'语言',
  152. route:'菜单路由',
  153. type1: '目录',
  154. type2: '菜单',
  155. type3: '按钮',
  156. code:'编号'
  157. },
  158. menuList: [],
  159. menuListTreeProps: {
  160. label: 'name',
  161. children: 'children'
  162. }
  163. }
  164. },
  165. created () {
  166. this.iconList = Icon.getNameList()
  167. this.getFunctionButtonList()
  168. },
  169. methods: {
  170. init (id) {
  171. this.dataForm.id = id || 0
  172. this.$http({
  173. url: this.$http.adornUrl('/sys/menu/select'),
  174. method: 'get',
  175. params: this.$http.adornParams()
  176. }).then(({data}) => {
  177. this.menuList = treeDataTranslate(data.menuList, 'menuId')
  178. console.log( this.menuList)
  179. }).then(() => {
  180. this.visible = true
  181. this.$nextTick(() => {
  182. this.$refs['dataForm'].resetFields()
  183. })
  184. }).then(() => {
  185. if (!this.dataForm.id) {
  186. // 新增
  187. this.menuListTreeSetCurrentNode()
  188. } else {
  189. // 修改
  190. this.$http({
  191. url: this.$http.adornUrl(`/sys/menu/info/${this.dataForm.id}`),
  192. method: 'get',
  193. params: this.$http.adornParams()
  194. }).then(({data}) => {
  195. this.dataForm.id = data.menu.menuId
  196. this.dataForm.type = data.menu.type
  197. this.dataForm.name = data.menu.name
  198. this.dataForm.parentId = data.menu.parentId
  199. this.dataForm.url = data.menu.url
  200. this.dataForm.perms = data.menu.perms
  201. this.dataForm.orderNum = data.menu.orderNum
  202. this.dataForm.icon = data.menu.icon
  203. this.dataForm.menuType = data.menu.menuType
  204. this.dataForm.menuId = data.menu.menuId
  205. this.menuListTreeSetCurrentNode()
  206. })
  207. }
  208. })
  209. },
  210. // 获取button的词典
  211. getFunctionButtonList() {
  212. let queryButton = {
  213. functionId: this.$route.meta.menuId,
  214. tableId: '*',
  215. languageCode: this.$i18n.locale,
  216. objectType: 'button'
  217. }
  218. searchFunctionButtonList(queryButton).then(({data}) => {
  219. if (data.code == 0 && data.data) {
  220. this.buttons = data.data
  221. this.typeList= [this.buttons.type1,this.buttons.type2,this.buttons.type3]
  222. }
  223. })
  224. },
  225. // 菜单树选中
  226. menuListTreeCurrentChangeHandle (data, node) {
  227. this.dataForm.parentId = data.menuId
  228. this.dataForm.parentName = data.name
  229. this.treeVisible = false
  230. },
  231. // 菜单树设置当前选中节点
  232. menuListTreeSetCurrentNode () {
  233. this.$refs.menuListTree.setCurrentKey(this.dataForm.parentId)
  234. this.dataForm.parentName = (this.$refs.menuListTree.getCurrentNode() || {})['name']
  235. },
  236. // 图标选中
  237. iconActiveHandle (iconName) {
  238. this.dataForm.icon = iconName
  239. },
  240. // 表单提交
  241. dataFormSubmit () {
  242. this.$refs['dataForm'].validate((valid) => {
  243. if (valid) {
  244. this.$http({
  245. url: this.$http.adornUrl(`/sys/menu/${!this.dataForm.id ? 'save' : 'update'}`),
  246. method: 'post',
  247. data: this.$http.adornData({
  248. 'menuId': this.dataForm.menuId,
  249. 'type': this.dataForm.type,
  250. 'name': this.dataForm.name,
  251. 'parentId': this.dataForm.parentId,
  252. 'url': this.dataForm.url,
  253. 'perms': this.dataForm.perms,
  254. 'orderNum': this.dataForm.orderNum,
  255. 'icon': this.dataForm.icon,
  256. 'menuType': this.dataForm.menuType,
  257. })
  258. }).then(({data}) => {
  259. if (data && data.code === 0) {
  260. this.$message.success('操作成功')
  261. this.visible = false
  262. this.$emit('refreshDataList')
  263. } else {
  264. this.$message.error(data.msg)
  265. }
  266. })
  267. }
  268. })
  269. }
  270. },
  271. }
  272. </script>
  273. <style lang="scss" >
  274. .mod-menu {
  275. .menu-list__input,
  276. .icon-list__input {
  277. > .el-input__inner {
  278. cursor: pointer;
  279. }
  280. }
  281. &__icon-popover {
  282. width: 458px;
  283. overflow: hidden;
  284. }
  285. &__icon-inner {
  286. width: 478px;
  287. max-height: 258px;
  288. overflow-x: hidden;
  289. overflow-y: auto;
  290. }
  291. &__icon-list {
  292. width: 458px;
  293. padding: 0;
  294. margin: -8px 0 0 -8px;
  295. > .el-button {
  296. padding: 8px;
  297. margin: 8px 0 0 8px;
  298. > span {
  299. display: inline-block;
  300. vertical-align: middle;
  301. width: 18px;
  302. height: 18px;
  303. font-size: 18px;
  304. }
  305. }
  306. }
  307. .icon-list__tips {
  308. font-size: 18px;
  309. text-align: center;
  310. color: #e6a23c;
  311. cursor: pointer;
  312. }
  313. }
  314. .el-popover {
  315. height: 50%;
  316. width: 350px;
  317. overflow:auto;
  318. }
  319. .sl-menu-item .el-form-item {
  320. margin-bottom: 5px;
  321. }
  322. </style>