index.vue 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. <template>
  2. <div class="__normal-page">
  3. <div class="__normal-tree" v-loading="loadingTree">
  4. <div class="tree-filter">
  5. <CusFormColumn
  6. :span="24"
  7. v-model:param="treeFilter">
  8. <template #suffix>
  9. <SvgIcon name="search"/>
  10. </template>
  11. </CusFormColumn>
  12. </div>
  13. <div class="tree-content">
  14. <template v-for="p in dictTree">
  15. <div class="tree-parent __hover" :class="{active: p.expend}" @click="p.expend = !p.expend">{{p.name}}</div>
  16. <template v-if="p.expend">
  17. <template v-for="s in p.children?.filter(v => v.name.includes(treeFilter))">
  18. <div class="tree-son __hover" :class="{active: selectDict === s.value}" @click="handleTreeClick(s.value)">{{s.name}}</div>
  19. </template>
  20. </template>
  21. </template>
  22. </div>
  23. </div>
  24. <div class="__normal-content" v-if="selectDict">
  25. <CusContent
  26. v-model:tableHead="tableHead"
  27. @handleReset="handleReset"
  28. @handleSearch="onSearch"
  29. >
  30. <template #fieldOut>
  31. <CusForm labelWidth="120px" @handleEnter="onSearch">
  32. <CusFormColumn
  33. :span="8"
  34. label="字典显示名称:"
  35. v-model:param="queryForm.dictLabel"/>
  36. <CusFormColumn
  37. :span="8"
  38. label="字典值内容:"
  39. v-model:param="queryForm.dictValue"/>
  40. <CusSearchButtons
  41. @handleReset="handleReset"
  42. @handleSearch="onSearch"
  43. />
  44. </CusForm>
  45. </template>
  46. <template #buttons>
  47. <div class="__cus-button_submit __hover" @click="onAdd">
  48. <SvgIcon name="add" size="16"/>新增
  49. </div>
  50. </template>
  51. <template #table>
  52. <CusTable
  53. v-loading="loading"
  54. ref="ref_cusTable"
  55. :tableData="queryResult.tableData"
  56. :tableHead="tableHead"
  57. :total="queryResult.total"
  58. :page="queryPage.pageNum"
  59. :pageSize="queryPage.pageSize"
  60. @handlePage="handlePage"
  61. >
  62. <template #updateTime-column-value="{ scope }">
  63. {{$util.YMDHms(scope.row.updateTime)}}
  64. </template>
  65. <template #do-column-value="{ scope }">
  66. <div class="__cus-table_do">
  67. <div class="__cus-table_do-green __hover" @click="onView(scope.row)">
  68. <SvgIcon name="view" size="16"/>查看
  69. </div>
  70. <div class="__cus-table_do-blue __hover" @click="onEdit(scope.row)">
  71. <SvgIcon name="edit" size="16"/>编辑
  72. </div>
  73. <div class="__cus-table_do-red __hover" @click="onDel(scope.row)">
  74. <SvgIcon name="del" size="16"/>删除
  75. </div>
  76. </div>
  77. </template>
  78. </CusTable>
  79. </template>
  80. </CusContent>
  81. </div>
  82. <DetailCom v-model:show="showDetail" :transfer="transfer" @refresh="handleSearch()"/>
  83. </div>
  84. </template>
  85. <script lang="ts">
  86. import {
  87. defineComponent,
  88. computed,
  89. onMounted,
  90. ref,
  91. reactive,
  92. watch,
  93. getCurrentInstance,
  94. ComponentInternalInstance,
  95. toRefs,
  96. nextTick
  97. } from 'vue'
  98. import {useStore} from 'vuex'
  99. import {useRouter, useRoute} from 'vue-router'
  100. import DetailCom from './detail.vue'
  101. import { ElMessage, ElMessageBox } from 'element-plus';
  102. export default defineComponent({
  103. name: '',
  104. components: {
  105. DetailCom
  106. },
  107. setup(props, {emit}) {
  108. const store = useStore();
  109. const router = useRouter();
  110. const route = useRoute();
  111. const that = (getCurrentInstance() as ComponentInternalInstance).appContext.config.globalProperties
  112. const state = reactive({
  113. // 加载中
  114. loading: false,
  115. // 查询分页参数
  116. queryPage: {
  117. pageNum: 1,
  118. pageSize: 10
  119. },
  120. // 查询结果
  121. queryResult: {
  122. total: 0,
  123. tableData: []
  124. },
  125. // 查询表单参数
  126. queryForm: <any>{},
  127. // 查询表单参数备份
  128. back_queryForm: {},
  129. // 表格表头
  130. tableHead: [
  131. {value: "dictLabel", label: "字典显示名称", show: true},
  132. {value: "dictValue", label: "字典值内容", show: true},
  133. {value: "dictSort", label: "排序", show: true},
  134. {value: "updateTime", label: "更新时间", show: true, width: 180},
  135. {value: "do", label: "操作", show: true, popover: true, width: 260},
  136. ],
  137. showDetail: false,
  138. transfer: {},
  139. treeFilter: '',
  140. dictTree: [],
  141. loadingTree: false,
  142. selectDict: ''
  143. });
  144. const ref_cusTable = ref()
  145. // 获取字典
  146. const initDictionary = () => {
  147. }
  148. // 查询分页参数改变处理方法
  149. const handlePage = ({page, pageSize}: any) => {
  150. state.queryPage.pageNum = page
  151. state.queryPage.pageSize = pageSize
  152. handleSearch(page, pageSize)
  153. }
  154. // 重置查询表单方法
  155. const handleReset = () => {
  156. state.queryForm = {}
  157. state.back_queryForm = JSON.parse(JSON.stringify(state.queryForm))
  158. handleSearch()
  159. }
  160. // 查询方法
  161. const handleSearch = (page = 1, pageSize = 10) => {
  162. // 添加分页参数
  163. const queryParams: any = {
  164. pageNum: page,
  165. pageSize: pageSize,
  166. dictType: state.selectDict
  167. }
  168. // 添加表单参数
  169. for (const [k, v] of Object.entries(state.back_queryForm)) {
  170. that.$util.isValue(v) ? (queryParams[k] = v) : null;
  171. }
  172. state.loading = true
  173. that.$api.getDictDataList(that.$util.formatGetParam(queryParams)).then((res: any) => {
  174. if (res.code === 200) {
  175. state.queryResult.tableData = res.rows
  176. state.queryResult.total = res.total
  177. } else {
  178. ElMessage.error(res.message)
  179. }
  180. state.loading = false
  181. }).catch(() => {
  182. state.loading = false
  183. })
  184. }
  185. // 点击查询按钮后
  186. const onSearch = () => {
  187. ref_cusTable.value.resetFilter()
  188. state.back_queryForm = JSON.parse(JSON.stringify(state.queryForm))
  189. state.queryPage.pageNum = 1
  190. handleSearch()
  191. }
  192. const onAdd = () => {
  193. state.transfer = {
  194. method: 'add',
  195. dictType: state.selectDict
  196. }
  197. state.showDetail = true
  198. }
  199. const onEdit = (val) => {
  200. state.transfer = {
  201. method: 'edit',
  202. detail: JSON.parse(JSON.stringify(val)),
  203. dictType: state.selectDict
  204. }
  205. state.showDetail = true
  206. }
  207. const onView = (val) => {
  208. state.transfer = {
  209. method: 'view',
  210. detail: JSON.parse(JSON.stringify(val))
  211. }
  212. state.showDetail = true
  213. }
  214. const initTree = () => {
  215. state.loadingTree = true
  216. state.dictTree = []
  217. that.$api.getDictTypeTreeSelectTree().then(res => {
  218. if (res.code === 200) {
  219. state.dictTree = res.data.map((p) => {
  220. p.expend = false
  221. p.name = p.label
  222. p.value = p.attachedField
  223. if (p.children?.length > 0) {
  224. p.children = p.children.map(c => {
  225. c.name = c.label
  226. c.value = c.attachedField
  227. return c
  228. })
  229. }
  230. return p
  231. })
  232. } else {
  233. ElMessage.error(res.message)
  234. }
  235. state.loadingTree = false
  236. }).catch(() => {
  237. state.loadingTree = false
  238. })
  239. }
  240. const handleTreeClick = (val) => {
  241. state.selectDict = val
  242. handleSearch()
  243. }
  244. const onDel = (val) => {
  245. ElMessageBox.confirm(`是否删除${val.dictLabel}?`, "提示", {
  246. confirmButtonText: "确定",
  247. cancelButtonText: "取消",
  248. type: "warning",
  249. }).then(() => {
  250. state.loading = true
  251. that.$api.delDictData(val.id).then(res => {
  252. if (res.code === 200) {
  253. ElMessage.success(res.message)
  254. handleSearch()
  255. } else {
  256. ElMessage.error(res.message)
  257. state.loading = false
  258. }
  259. }).catch(() => {
  260. state.loading = false
  261. })
  262. }).catch(() => {})
  263. }
  264. onMounted(() => {
  265. state.back_queryForm = JSON.parse(JSON.stringify(state.queryForm))
  266. initDictionary()
  267. initTree()
  268. })
  269. return {
  270. ref_cusTable,
  271. ...toRefs(state),
  272. handleSearch,
  273. handlePage,
  274. handleReset,
  275. onSearch,
  276. onAdd,
  277. onEdit,
  278. onView,
  279. handleTreeClick,
  280. onDel
  281. }
  282. },
  283. })
  284. </script>
  285. <style scoped lang="scss">
  286. .__normal-tree {
  287. width: 224px;
  288. margin-right: 24px;
  289. padding-top: 40px;
  290. display: flex;
  291. flex-direction: column;
  292. box-sizing: border-box;
  293. .tree-content {
  294. flex: 1;
  295. display: flex;
  296. flex-direction: column;
  297. align-items: center;
  298. .tree-parent {
  299. background-image: url("./dict_bg.png");
  300. width: 188px;
  301. height: 34px;
  302. display: flex;
  303. align-items: center;
  304. justify-content: center;
  305. font-size: 18px;
  306. font-family: PingFang SC-Medium, PingFang SC;
  307. font-weight: 500;
  308. color: rgba(46,184,255,0.6);
  309. margin-bottom: 10px;
  310. &.active {
  311. background-image: url("./dict_bg-active.png");
  312. width: 196px;
  313. height: 54px;
  314. color: #3EFFBB;
  315. text-shadow: 0px 0px 4px rgba(62,255,187,0.1);
  316. }
  317. }
  318. .tree-son {
  319. font-size: 18px;
  320. font-family: PingFang SC-Medium, PingFang SC;
  321. font-weight: 500;
  322. color: rgba(255,255,255,0.6);
  323. text-shadow: 0px 0px 4px rgba(62,255,187,0.1);
  324. margin-bottom: 10px;
  325. align-self: flex-start;
  326. padding-left: 76px;
  327. &.active {
  328. color: #3EFFBB;
  329. }
  330. }
  331. }
  332. }
  333. </style>