阅行客电子档案
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.

275 lines
12 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. <template>
  2. <div class="app-container row-container">
  3. <!--工具栏-->
  4. <div class="head-container">
  5. <div v-if="crud.props.searchToggle" class="head-search">
  6. <!-- 搜索 -->
  7. <el-input v-model="query.blurry" clearable size="small" placeholder="模糊搜索" prefix-icon="el-icon-search" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
  8. <date-range-picker v-model="query.createTime" class="date-item" />
  9. <rrOperation />
  10. </div>
  11. <crudOperation :permission="permission" />
  12. </div>
  13. <!--表单渲染-->
  14. <el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title">
  15. <span class="dialog-right-top" />
  16. <span class="dialog-left-bottom" />
  17. <div class="setting-dialog">
  18. <el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px">
  19. <el-row>
  20. <el-form-item label="菜单类型" prop="type">
  21. <el-radio-group v-model="form.type" size="mini" style="width: 178px">
  22. <el-radio-button label="0">目录</el-radio-button>
  23. <el-radio-button label="1">菜单</el-radio-button>
  24. <el-radio-button label="2">按钮</el-radio-button>
  25. </el-radio-group>
  26. </el-form-item>
  27. </el-row>
  28. <el-row>
  29. <el-form-item v-show="form.type.toString() !== '2'" label="菜单图标" prop="icon">
  30. <el-popover
  31. placement="bottom-start"
  32. width="450"
  33. trigger="click"
  34. @show="$refs['iconSelect'].reset()"
  35. >
  36. <IconSelect ref="iconSelect" @selected="selected" />
  37. <el-input slot="reference" v-model="form.icon" style="width: 450px;" placeholder="点击选择图标" readonly>
  38. <svg-icon v-if="form.icon" slot="prefix" :icon-class="form.icon" class="el-input__icon" style="height: 30px;width: 16px;" />
  39. <i v-else slot="prefix" class="el-icon-search el-input__icon" />
  40. </el-input>
  41. </el-popover>
  42. </el-form-item>
  43. </el-row>
  44. <el-row>
  45. <!-- <el-col :span="8"> -->
  46. <el-form-item v-show="form.type.toString() !== '2'" label="外链菜单" prop="iFrame" style="width: 180px; margin-right: 0;">
  47. <el-radio-group v-model="form.iFrame" size="mini">
  48. <el-radio-button label="true"></el-radio-button>
  49. <el-radio-button label="false"></el-radio-button>
  50. </el-radio-group>
  51. </el-form-item>
  52. <!-- </el-col>
  53. <el-col :span="8"> -->
  54. <el-form-item v-show="form.type.toString() !== '2'" label="菜单可见" prop="hidden" style="width: 180px; margin-right: 0;">
  55. <el-radio-group v-model="form.hidden" size="mini">
  56. <el-radio-button label="false"></el-radio-button>
  57. <el-radio-button label="true"></el-radio-button>
  58. </el-radio-group>
  59. </el-form-item>
  60. <!-- </el-col>
  61. <el-col :span="8"> -->
  62. <el-form-item v-show="form.type.toString() === '1'" label="菜单缓存" prop="cache" style="width: 180px; margin-right: 0;">
  63. <el-radio-group v-model="form.cache" size="mini">
  64. <el-radio-button label="true"></el-radio-button>
  65. <el-radio-button label="false"></el-radio-button>
  66. </el-radio-group>
  67. </el-form-item>
  68. <!-- </el-col> -->
  69. </el-row>
  70. <el-form-item v-if="form.type.toString() !== '2'" label="菜单名称" prop="title">
  71. <el-input v-model="form.title" :style=" form.type.toString() === '0' ? 'width: 580px' : 'width: 225px'" placeholder="菜单标题" />
  72. </el-form-item>
  73. <el-row>
  74. <el-form-item v-if="form.type.toString() === '2'" label="按钮名称" prop="title">
  75. <el-input v-model="form.title" placeholder="按钮名称" style="width:580px;" />
  76. </el-form-item>
  77. </el-row>
  78. <el-form-item v-show="form.type.toString() !== '0'" label="权限标识" prop="permission">
  79. <el-input v-model="form.permission" :disabled="form.iFrame.toString() === 'true'" placeholder="权限标识" />
  80. </el-form-item>
  81. <el-form-item v-if="form.type.toString() !== '2'" label="路由地址" prop="path">
  82. <el-input v-model="form.path" placeholder="路由地址" />
  83. </el-form-item>
  84. <el-form-item label="菜单排序" prop="menuSort">
  85. <el-input-number v-model.number="form.menuSort" :min="0" :max="999" controls-position="right" />
  86. </el-form-item>
  87. <el-form-item v-show="form.iFrame.toString() !== 'true' && form.type.toString() === '1'" label="组件名称" prop="componentName">
  88. <el-input v-model="form.componentName" placeholder="匹配组件内Name字段" />
  89. </el-form-item>
  90. <el-form-item v-show="form.iFrame.toString() !== 'true' && form.type.toString() === '1'" label="组件路径" prop="component">
  91. <el-input v-model="form.component" placeholder="组件路径" />
  92. </el-form-item>
  93. <el-row>
  94. <el-form-item label="上级类目" prop="pid">
  95. <treeselect
  96. v-model="form.pid"
  97. :options="menus"
  98. :load-options="loadMenus"
  99. style="width: 450px;"
  100. placeholder="选择上级类目"
  101. />
  102. </el-form-item>
  103. </el-row>
  104. </el-form>
  105. <div slot="footer" class="dialog-footer">
  106. <el-button type="text" @click="crud.cancelCU">取消</el-button>
  107. <el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">确认</el-button>
  108. </div>
  109. </div>
  110. </el-dialog>
  111. <!--表格渲染-->
  112. <div class="container-wrap">
  113. <span class="right-top-line" />
  114. <span class="left-bottom-line" />
  115. <el-table
  116. ref="table"
  117. v-loading="crud.loading"
  118. lazy
  119. :load="getMenus"
  120. :data="crud.data"
  121. :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
  122. row-key="id"
  123. @select="crud.selectChange"
  124. @select-all="crud.selectAllChange"
  125. @selection-change="crud.selectionChangeHandler"
  126. >
  127. <el-table-column type="selection" align="center" width="55" />
  128. <el-table-column :show-overflow-tooltip="true" label="菜单标题" width="300px" prop="title" />
  129. <el-table-column prop="icon" label="图标" align="center" width="75px">
  130. <template slot-scope="scope">
  131. <svg-icon :icon-class="scope.row.icon ? scope.row.icon : ''" />
  132. </template>
  133. </el-table-column>
  134. <el-table-column :show-overflow-tooltip="true" prop="permission" label="权限标识" />
  135. <el-table-column :show-overflow-tooltip="true" prop="component" label="组件路径" />
  136. <el-table-column prop="menuSort" align="center" label="排序" width="100px">
  137. <template slot-scope="scope">
  138. {{ scope.row.menuSort }}
  139. </template>
  140. </el-table-column>
  141. <el-table-column prop="iFrame" label="外链" width="75px">
  142. <template slot-scope="scope">
  143. <span v-if="scope.row.iFrame"></span>
  144. <span v-else></span>
  145. </template>
  146. </el-table-column>
  147. <el-table-column prop="cache" label="缓存" width="75px">
  148. <template slot-scope="scope">
  149. <span v-if="scope.row.cache"></span>
  150. <span v-else></span>
  151. </template>
  152. </el-table-column>
  153. <el-table-column prop="hidden" label="可见" width="75px">
  154. <template slot-scope="scope">
  155. <span v-if="scope.row.hidden"></span>
  156. <span v-else></span>
  157. </template>
  158. </el-table-column>
  159. <el-table-column prop="createTime" label="创建日期" width="200px">
  160. <template slot-scope="scope">
  161. <div>{{ scope.row.createTime | parseTime }}</div>
  162. </template>
  163. </el-table-column>
  164. <!-- <el-table-column v-if="checkPer(['admin','menu:edit','menu:del'])" label="操作" width="130px" align="center" fixed="right">
  165. <template slot-scope="scope">
  166. <udOperation
  167. :data="scope.row"
  168. :permission="permission"
  169. msg="确定删除吗,如果存在下级节点则一并删除,此操作不能撤销!"
  170. />
  171. </template>
  172. </el-table-column> -->
  173. </el-table>
  174. </div>
  175. </div>
  176. </template>
  177. <script>
  178. import crudMenu from '@/api/system/menu'
  179. import IconSelect from '@/components/IconSelect'
  180. import Treeselect from '@riophae/vue-treeselect'
  181. import '@riophae/vue-treeselect/dist/vue-treeselect.css'
  182. import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect'
  183. import CRUD, { presenter, header, form, crud } from '@crud/crud'
  184. import rrOperation from '@crud/RR.operation'
  185. import crudOperation from '@crud/CRUD.operation'
  186. import DateRangePicker from '@/components/DateRangePicker'
  187. // crud交由presenter持有
  188. const defaultForm = { id: null, title: null, menuSort: 999, path: null, component: null, componentName: null, iFrame: false, roles: [], pid: 0, icon: null, cache: false, hidden: false, type: 0, permission: null }
  189. export default {
  190. name: 'Menu',
  191. components: { Treeselect, IconSelect, crudOperation, rrOperation, DateRangePicker },
  192. cruds() {
  193. return CRUD({ title: '菜单', url: 'api/menus', crudMethod: { ...crudMenu }})
  194. },
  195. mixins: [presenter(), header(), form(defaultForm), crud()],
  196. data() {
  197. return {
  198. menus: [],
  199. permission: {
  200. add: ['admin', 'menu:add'],
  201. edit: ['admin', 'menu:edit'],
  202. del: ['admin', 'menu:del']
  203. },
  204. rules: {
  205. title: [
  206. { required: true, message: '请输入标题', trigger: 'blur' }
  207. ],
  208. path: [
  209. { required: true, message: '请输入地址', trigger: 'blur' }
  210. ]
  211. }
  212. }
  213. },
  214. methods: {
  215. // 新增与编辑前做的操作
  216. [CRUD.HOOK.afterToCU](crud, form) {
  217. this.menus = []
  218. if (form.id != null) {
  219. if (form.pid === null) {
  220. form.pid = 0
  221. }
  222. this.getSupDepts(form.id)
  223. } else {
  224. this.menus.push({ id: 0, label: '顶级类目', children: null })
  225. }
  226. },
  227. getMenus(tree, treeNode, resolve) {
  228. const params = { pid: tree.id }
  229. setTimeout(() => {
  230. crudMenu.getMenus(params).then(res => {
  231. resolve(res.content)
  232. })
  233. }, 100)
  234. },
  235. getSupDepts(id) {
  236. crudMenu.getMenuSuperior(id).then(res => {
  237. const children = res.map(function(obj) {
  238. if (!obj.leaf && !obj.children) {
  239. obj.children = null
  240. }
  241. return obj
  242. })
  243. this.menus = [{ id: 0, label: '顶级类目', children: children }]
  244. })
  245. },
  246. loadMenus({ action, parentNode, callback }) {
  247. if (action === LOAD_CHILDREN_OPTIONS) {
  248. crudMenu.getMenusTree(parentNode.id).then(res => {
  249. parentNode.children = res.map(function(obj) {
  250. if (!obj.leaf) {
  251. obj.children = null
  252. }
  253. return obj
  254. })
  255. setTimeout(() => {
  256. callback()
  257. }, 100)
  258. })
  259. }
  260. },
  261. // 选中图标
  262. selected(name) {
  263. this.form.icon = name
  264. }
  265. }
  266. }
  267. </script>
  268. <style rel="stylesheet/scss" lang="scss" scoped>
  269. ::v-deep .el-input-number .el-input__inner {
  270. text-align: left;
  271. }
  272. </style>