dict.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. <template>
  2. <view class="container">
  3. <view class="safe-area-inset-bottom">
  4. <rider-curd
  5. v-model="form"
  6. :option="option"
  7. :data="list"
  8. :rules="rules"
  9. :readonly.sync="readonly"
  10. @search="onSearch"
  11. @action-click="onActionClick"
  12. @submit="onSubmit"
  13. @del="onRemove"
  14. ref="crud"
  15. >
  16. <template #form>
  17. <u-form-item label="字典编号" prop="code" :label-width="option.labelWidth || 160" required>
  18. <u-input v-model="form.code" :disabled="readonly" placeholder="字典编号" />
  19. </u-form-item>
  20. <u-form-item label="字典名称" prop="dictValue" :label-width="option.labelWidth || 160" required>
  21. <u-input v-model="form.dictValue" :disabled="readonly" placeholder="字典名称" />
  22. </u-form-item>
  23. <u-form-item label="字典排序" prop="sort" :label-width="option.labelWidth || 160" required>
  24. <u-input v-model="form.sort" :disabled="readonly" type="number" placeholder="字典排序" />
  25. </u-form-item>
  26. <u-form-item label="封存" prop="isSealed" :label-width="option.labelWidth || 160" required>
  27. <u-radio-group v-model="form.isSealed" :disabled="readonly">
  28. <u-radio shape="circle" :name="1" active-color="#4E7FF9">是</u-radio>
  29. <u-radio shape="circle" :name="0" active-color="#4E7FF9">否</u-radio>
  30. </u-radio-group>
  31. </u-form-item>
  32. <u-form-item label="字典备注" :label-width="option.labelWidth || 160" prop="remark">
  33. <u-input
  34. v-model="form.remark"
  35. :disabled="readonly"
  36. type="textarea"
  37. :maxlength="-1"
  38. :height="35"
  39. placeholder="字典备注"
  40. />
  41. </u-form-item>
  42. </template>
  43. <template #loadmore>
  44. <u-loadmore :status="loadStatus" @loadmore="getList()" />
  45. </template>
  46. </rider-curd>
  47. </view>
  48. <!-- 字典配置 -->
  49. <u-popup v-model="configShow" mode="bottom" height="100vh" @close="onConfigClose" :mask-close-able="false">
  50. <scroll-view scroll-y="true" style="height: 100vh; background: #f5f5f5">
  51. <rider-curd
  52. ref="childCrud"
  53. v-model="childForm"
  54. :navBack="onConfigClose"
  55. @search="onChildSearch"
  56. :option="{ ...configOption, navTitle: `${configName} - 字典配置` }"
  57. :data="childList"
  58. :rules="rules"
  59. :readonly.sync="readonly"
  60. @action-click="onActionClick"
  61. @submit="onSubmit"
  62. @del="onRemove"
  63. >
  64. <template #form>
  65. <u-form-item label="字典编号" prop="code" :label-width="configOption.labelWidth || 160" required>
  66. <u-input v-model="childForm.code" disabled placeholder="字典编号" />
  67. </u-form-item>
  68. <u-form-item label="字典名称" prop="dictValue" :label-width="configOption.labelWidth || 160" required>
  69. <u-input v-model="childForm.dictValue" :disabled="readonly" placeholder="字典名称" />
  70. </u-form-item>
  71. <u-form-item label="上级字典" :label-width="configOption.labelWidth || 160">
  72. <u-input v-model="parentData.dictValue" disabled placeholder="上级字典" />
  73. </u-form-item>
  74. <u-form-item label="字典键值" prop="dictKey" :label-width="configOption.labelWidth || 160" required>
  75. <u-input v-model="childForm.dictKey" :disabled="readonly" placeholder="字典键值" />
  76. </u-form-item>
  77. <u-form-item label="字典排序" prop="sort" :label-width="configOption.labelWidth || 160" required>
  78. <u-input v-model="childForm.sort" :disabled="readonly" type="number" placeholder="字典排序" />
  79. </u-form-item>
  80. <u-form-item label="封存" prop="isSealed" :label-width="configOption.labelWidth || 160" required>
  81. <u-radio-group v-model="childForm.isSealed" :disabled="readonly">
  82. <u-radio shape="circle" :name="1" active-color="#4E7FF9">是</u-radio>
  83. <u-radio shape="circle" :name="0" active-color="#4E7FF9">否</u-radio>
  84. </u-radio-group>
  85. </u-form-item>
  86. <u-form-item label="字典备注" prop="remark" :label-width="configOption.labelWidth || 160">
  87. <u-input
  88. v-model="childForm.remark"
  89. :disabled="readonly"
  90. type="textarea"
  91. :maxlength="-1"
  92. :height="35"
  93. placeholder="字典备注"
  94. />
  95. </u-form-item>
  96. </template>
  97. <template #loadmore>
  98. <u-loadmore :status="childLoadStatus" @loadmore="getChild()" />
  99. </template>
  100. </rider-curd>
  101. </scroll-view>
  102. </u-popup>
  103. </view>
  104. </template>
  105. <script>
  106. import riderCurd from '@/components/rider-crud/index'
  107. import { parentList, add, update, remove, dictionary, child, dictTree } from '@/api/system/dict.js'
  108. import { getDicLabel } from '@/components/rider-crud/util/tool.js'
  109. export default {
  110. components: { riderCurd },
  111. data() {
  112. return {
  113. configShow: false, //字典管理弹窗
  114. form: {
  115. isSealed: 0
  116. },
  117. list: [],
  118. params: {
  119. current: 1,
  120. size: 10
  121. },
  122. readonly: false, // 查看时控制表单只读
  123. parentData: {}, // 上级数据信息
  124. childList: [],
  125. childForm: {
  126. isSealed: 0
  127. },
  128. childParams: {
  129. current: 1,
  130. size: 10,
  131. parentId: null
  132. },
  133. loadStatus: 'loadmore', // 列表加载状态
  134. childLoadStatus: 'loadmore', // 列表加载状态
  135. option: {
  136. navTitle: '字典管理', //标题
  137. manageBtn: true, // 右上角管理按钮,默认不显示
  138. searchShow: true, //是否显示搜索,默认不显示
  139. labelWidth: 160, //form表单lable宽度, 默认160,单位rpx
  140. column: [
  141. {
  142. label: '字典编号',
  143. prop: 'code'
  144. },
  145. {
  146. label: '字典名称',
  147. prop: 'dictValue'
  148. },
  149. {
  150. label: '字典排序',
  151. prop: 'sort'
  152. },
  153. {
  154. label: '封存',
  155. prop: 'sealedName'
  156. },
  157. {
  158. label: '字典备注',
  159. prop: 'remark'
  160. }
  161. ],
  162. actions: [
  163. {
  164. name: '编辑', // 操作名称
  165. icon: 'edit-pen', //操作图标,有图标文字不显示
  166. color: '#333', // 字体颜色
  167. fontsize: 30, //字体大小,单位rpx
  168. width: 40, // 宽度,单位px
  169. background: '#fff' // 菜单按钮背景色
  170. },
  171. {
  172. name: '删除',
  173. icon: 'trash',
  174. color: '#333',
  175. fontsize: 30,
  176. width: 40,
  177. background: '#fff'
  178. },
  179. {
  180. name: '设置',
  181. icon: 'setting',
  182. color: '#333',
  183. fontsize: 30,
  184. width: 40,
  185. background: '#fff'
  186. }
  187. ]
  188. },
  189. configName: '',
  190. configOption: {
  191. navBackIcon: 'close', //导航栏左上角icon
  192. manageBtn: true, // 右上角管理按钮,默认不显示
  193. searchShow: true, //是否显示搜索,默认不显示
  194. labelWidth: 160, //form表单lable宽度, 默认160,单位rpx
  195. column: [
  196. {
  197. label: '字典编号',
  198. prop: 'code'
  199. },
  200. {
  201. label: '字典名称',
  202. prop: 'dictValue'
  203. },
  204. {
  205. label: '字典键值',
  206. prop: 'dictKey'
  207. },
  208. {
  209. label: '字典排序',
  210. prop: 'sort'
  211. },
  212. {
  213. label: '封存',
  214. prop: 'sealedName'
  215. },
  216. {
  217. label: '字典备注',
  218. prop: 'remark'
  219. }
  220. ],
  221. actions: [
  222. {
  223. name: '编辑', // 操作名称
  224. icon: 'edit-pen', //操作图标,有图标文字不显示
  225. color: '#333', // 字体颜色
  226. fontsize: 30, //字体大小,单位rpx
  227. width: 40, // 宽度,单位px
  228. background: '#fff' // 菜单按钮背景色
  229. },
  230. {
  231. name: '删除',
  232. icon: 'trash',
  233. color: '#333',
  234. fontsize: 30,
  235. width: 40,
  236. background: '#fff'
  237. },
  238. {
  239. name: '新增子项',
  240. icon: 'plus',
  241. color: '#333',
  242. fontsize: 30,
  243. width: 40,
  244. background: '#fff'
  245. }
  246. ]
  247. },
  248. rules: {
  249. code: [{ required: true, message: '请输入字典编号', trigger: 'blur' }],
  250. dictValue: [{ required: true, message: '请输入字典名称', trigger: 'blur' }],
  251. sort: [{ required: true, message: '请输入字典排序', trigger: 'blur', type: 'number' }],
  252. isSealed: [{ required: true, message: '请选择是否封存', trigger: 'blur', type: 'number' }],
  253. dictKey: [{ required: true, message: '请输入字典键值', trigger: 'blur' }]
  254. }
  255. }
  256. },
  257. onReady() {
  258. this.getList(true)
  259. },
  260. onPullDownRefresh() {
  261. this.getList(true)
  262. this.getChild(true)
  263. },
  264. onReachBottom() {
  265. if (this.loadStatus == 'nomore') return
  266. this.getList()
  267. if (this.childLoadStatus == 'nomore') return
  268. this.getChild()
  269. },
  270. methods: {
  271. // 获取列表
  272. getList(override = false) {
  273. if (override) {
  274. this.params.current = 1
  275. }
  276. const { size } = this.params
  277. parentList(this.params)
  278. .then(res => {
  279. const { records } = res.data
  280. if (records.length < size) this.loadStatus = 'nomore'
  281. else this.loadStatus = 'loadmore'
  282. if (override) {
  283. this.list = records
  284. } else {
  285. this.list = this.list.concat(records)
  286. }
  287. if (this.list && this.list.length > 0) {
  288. this.list.map(e => {
  289. e.sealedName = e.isSealed ? '是' : '否'
  290. })
  291. }
  292. this.params.current++
  293. uni.stopPullDownRefresh()
  294. })
  295. .catch(err => {
  296. uni.stopPullDownRefresh()
  297. })
  298. },
  299. // 获取子类列表
  300. getChild(override = false) {
  301. if (override) {
  302. this.childParams.current = 1
  303. }
  304. const { size } = this.childParams
  305. child(this.childParams)
  306. .then(res => {
  307. const records = res.data
  308. if (records.length < size) this.childLoadStatus = 'nomore'
  309. else this.childLoadStatus = 'loadmore'
  310. if (override) {
  311. this.childList = records
  312. } else {
  313. this.childList = this.childList.concat(records)
  314. }
  315. if (this.childList && this.childList.length > 0) {
  316. this.childList.map(e => {
  317. e.sealedName = e.isSealed ? '是' : '否'
  318. })
  319. }
  320. this.childParams.current++
  321. uni.stopPullDownRefresh()
  322. })
  323. .catch(err => {
  324. uni.stopPullDownRefresh()
  325. })
  326. },
  327. // 左滑按钮点击
  328. onActionClick({ index, data, action, done }) {
  329. const { name } = action
  330. switch (name) {
  331. case '新增':
  332. if (this.parentData.code) {
  333. this.$set(this.childForm, 'code', this.parentData.code)
  334. this.$set(this.childForm, 'parentId', this.parentData.id)
  335. this.$set(this.childParams, 'parentId', this.parentData.id)
  336. }
  337. done()
  338. break
  339. case '删除':
  340. this.onRemove(data.id)
  341. break
  342. case '查看':
  343. this.readonly = true
  344. case '编辑':
  345. if (data.id) done()
  346. break
  347. case '设置':
  348. this.childForm = {}
  349. this.parentData = data
  350. this.configName = data.dictValue
  351. this.$set(this.childParams, 'parentId', data.id)
  352. this.getChild(true)
  353. setTimeout(() => {
  354. this.configShow = true
  355. }, 100)
  356. break
  357. case '新增子项':
  358. this.childForm = {}
  359. this.parentData = data
  360. this.$set(this.childForm, 'code', data.code)
  361. this.$set(this.childForm, 'parentId', data.id)
  362. this.$set(this.childParams, 'parentId', data.id)
  363. done()
  364. break
  365. }
  366. if (['删除', '编辑', '新增子项'].includes(name)) {
  367. this.$refs['crud'].hideChildren()
  368. this.$refs['childCrud'].hideChildren()
  369. }
  370. },
  371. // 删除
  372. onRemove(id) {
  373. uni.showModal({
  374. title: '确定要删除吗?',
  375. success: action => {
  376. if (action.confirm) {
  377. remove(id).then(() => {
  378. uni.showToast({
  379. title: '删除成功',
  380. icon: 'none'
  381. })
  382. setTimeout(() => {
  383. this.$refs['crud'].allCheckHide(false)
  384. }, 100)
  385. // #ifdef APP
  386. this.getList(true)
  387. // #endif
  388. // #ifndef APP
  389. uni.startPullDownRefresh({})
  390. // #endif
  391. })
  392. }
  393. }
  394. })
  395. },
  396. // 表单提交
  397. onSubmit(form, action, unloading, done) {
  398. if (action == '新增' || action == '新增子项') {
  399. add(form)
  400. .then(res => {
  401. uni.showToast({
  402. title: '新增成功',
  403. icon: 'none'
  404. })
  405. done()
  406. uni.startPullDownRefresh({})
  407. })
  408. .catch(() => {
  409. unloading()
  410. })
  411. } else if (action == '编辑') {
  412. update(form)
  413. .then(res => {
  414. uni.showToast({
  415. title: '编辑成功',
  416. icon: 'none'
  417. })
  418. done()
  419. uni.startPullDownRefresh({})
  420. })
  421. .catch(() => {
  422. unloading()
  423. })
  424. }
  425. },
  426. //字典配置关闭
  427. onConfigClose() {
  428. this.configShow = false
  429. this.childParams = {
  430. current: 1,
  431. size: 10,
  432. parentId: null
  433. }
  434. this.parentData = {}
  435. this.form = { isSealed: 0 }
  436. this.childForm = { isSealed: 0 }
  437. setTimeout(() => {
  438. this.getChild(true)
  439. })
  440. },
  441. // 搜索 (自行配置搜索内容)
  442. onSearch(val) {
  443. this.params = {
  444. current: 1,
  445. size: 10,
  446. dictValue: val
  447. }
  448. this.getList(true)
  449. },
  450. // 子级搜索
  451. onChildSearch(val) {
  452. this.childForm = {
  453. current: 1,
  454. size: 10,
  455. dictValue: val
  456. }
  457. this.getChild(true)
  458. }
  459. }
  460. }
  461. </script>
  462. <style>
  463. page {
  464. background: #f6f6f6;
  465. }
  466. </style>
  467. <style lang="scss" scoped>
  468. .nav-right {
  469. color: #fff;
  470. font-size: 28rpx;
  471. font-weight: normal;
  472. padding-right: 24rpx;
  473. }
  474. .config-title {
  475. padding: 30rpx;
  476. display: flex;
  477. justify-content: space-between;
  478. align-items: center;
  479. border-bottom: 20rpx solid #f5f5f5;
  480. color: #fff;
  481. background: linear-gradient(45deg, #4e7ff9 0%, #59a5fb 100%);
  482. }
  483. </style>