index.vue 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. <template>
  2. <div class="auxiliary-area-container layout-padding">
  3. <div class="layout-padding-auto layout-padding-view pd20">
  4. <el-row class="mb20" :gutter="10">
  5. <el-col :xs="24" :sm="12" :md="18" :lg="18" :xl="18">
  6. <el-form :model="state.queryParams" ref="ruleFormRef" :inline="true" @submit.native.prevent>
  7. <el-form-item label="关键字" prop="keyword" class="mb0">
  8. <el-input v-model="state.queryParams.keyword" placeholder="区域名称" clearable @keyup.enter="handleQuery" style="width: 250px" />
  9. </el-form-item>
  10. <el-form-item class="mb0">
  11. <el-button type="primary" @click="handleQuery" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
  12. <el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button" :loading="state.loading">
  13. <SvgIcon name="ele-Refresh" class="mr5" />重置
  14. </el-button>
  15. </el-form-item>
  16. </el-form>
  17. </el-col>
  18. <el-col :xs="24" :sm="12" :md="6" :lg="6" :xl="6" style="text-align: right">
  19. <el-button type="primary" @click="expand"
  20. ><SvgIcon
  21. name="ele-ArrowDownBold"
  22. style="transition: transform var(--el-transition-duration)"
  23. :style="state.isExpand ? 'transform: none' : 'transform: rotateZ(180deg)'"
  24. class="mr5"
  25. />
  26. {{ state.isExpand ? '收起' : '展开' }}</el-button
  27. >
  28. <el-button type="primary" @click="onOpenAddArea('')" v-auth="'auxiliary:area:add'"> <SvgIcon name="ele-Plus" class="mr5" />新增 </el-button>
  29. </el-col>
  30. </el-row>
  31. <!-- 表格 -->
  32. <el-auto-resizer class="table" v-loading="state.loading">
  33. <template #default="{ height, width }">
  34. <el-table-v2
  35. v-model:expanded-row-keys="state.expandedRowKeys"
  36. :columns="state.columns"
  37. :data="state.orgTableData"
  38. expand-column-key="areaName"
  39. fixed
  40. :width="width"
  41. :height="height"
  42. >
  43. <template #empty>
  44. <Empty />
  45. </template>
  46. </el-table-v2>
  47. </template>
  48. </el-auto-resizer>
  49. </div>
  50. <area-add ref="areaAddRef" @updateList="queryList" />
  51. <area-edit ref="areaEditRef" @updateList="queryList" />
  52. </div>
  53. </template>
  54. <script lang="ts" setup name="auxiliaryArea">
  55. import { defineAsyncComponent, ref, h, reactive, onMounted, watch } from 'vue';
  56. import { ElButton, ElMessage, ElMessageBox } from 'element-plus';
  57. import type { FormInstance } from 'element-plus';
  58. import { formatDate } from '/@/utils/formatTime';
  59. import { auth } from '/@/utils/authFunction';
  60. import { throttle } from '/@/utils/tools';
  61. import other from '/@/utils/other';
  62. import { treeArea, treeAreaDelete } from '/@/api/auxiliary/area';
  63. // 引入组件
  64. const AreaAdd = defineAsyncComponent(() => import('/@/views/auxiliary/area/component/Area-add.vue')); // 新增区域
  65. const AreaEdit = defineAsyncComponent(() => import('/@/views/auxiliary/area/component/Area-edit.vue')); // 编辑区域
  66. // 定义变量内容
  67. const state = reactive({
  68. orgTableData: <EmptyArrayType>[], // 获取所有菜单
  69. staticArr: <EmptyArrayType>[], // 静态数据
  70. loading: false, // 加载状态
  71. queryParams: {
  72. keyword: '', // 关键字
  73. },
  74. expandedRowKeys: <EmptyArrayType>[], // 展开行
  75. columns: [
  76. {
  77. key: 'areaName',
  78. dataKey: 'areaName',
  79. title: '区域名称',
  80. width: 600,
  81. },
  82. {
  83. key: 'id',
  84. dataKey: 'id',
  85. title: '区域代码',
  86. width: 400,
  87. },
  88. {
  89. key: 'creationTime',
  90. dataKey: 'creationTime',
  91. title: '创建时间',
  92. width: 200,
  93. cellRenderer: (data: any) => h('span', {}, { default: () => formatDate(new Date(data.rowData.creationTime), 'YYYY-mm-dd HH:MM:SS') }),
  94. },
  95. {
  96. key: 'handle',
  97. title: '操作',
  98. width: 100,
  99. fixed: 'right',
  100. align: 'center',
  101. cellRenderer: ({ rowData }: any) => {
  102. return h('span', { class: 'flex' }, [
  103. auth('auxiliary:area:edit') && rowData.isCanModify
  104. ? h(
  105. ElButton,
  106. {
  107. onClick: () => onOpenEditArea(rowData),
  108. type: 'primary',
  109. title: '修改',
  110. link: true,
  111. },
  112. { default: () => '修改' }
  113. )
  114. : '',
  115. auth('auxiliary:area:delete') && rowData.isCanModify
  116. ? h(
  117. ElButton,
  118. {
  119. onClick: () => onDelArea(rowData),
  120. type: 'danger',
  121. title: '删除',
  122. link: true,
  123. },
  124. { default: () => '删除' }
  125. )
  126. : '',
  127. ]);
  128. },
  129. },
  130. ],
  131. isExpand: false, // 是否展开
  132. });
  133. const ruleFormRef = ref<RefType>(); // 搜索表单ref
  134. // 搜索
  135. const formatTable = (list: any[], keyword: string) => {
  136. if (!list.length || !Array.isArray(list)) return [];
  137. let emptyArr: any[] = [];
  138. list.map((item) => {
  139. if (item.areaName.includes(keyword)) {
  140. if (item.children && Array.isArray(item.children) && item.children.length > 0) {
  141. item.children = formatTable(item.children, keyword);
  142. }
  143. emptyArr.push(item);
  144. } else if (item.children && Array.isArray(item.children) && item.children.length > 0) {
  145. item.children = formatTable(item.children, keyword);
  146. if (item.children.length) {
  147. emptyArr.push(item);
  148. }
  149. }
  150. });
  151. return emptyArr;
  152. };
  153. let emptyArr: any[] = [];
  154. const getExpand = (list: any[]) => {
  155. if (!list.length || !Array.isArray(list)) return [];
  156. list.map((item) => {
  157. if (item.children && Array.isArray(item.children) && item.children.length > 0) {
  158. getExpand(item.children);
  159. }
  160. emptyArr.push(item.id);
  161. });
  162. return emptyArr;
  163. };
  164. /** 搜索按钮操作 节流操作 */
  165. const handleQuery = throttle(() => {
  166. if (state.queryParams.keyword) {
  167. state.loading = true;
  168. state.expandedRowKeys = [];
  169. emptyArr = [];
  170. state.orgTableData = formatTable(other.deepClone(state.staticArr), state.queryParams.keyword);
  171. state.expandedRowKeys = getExpand(state.orgTableData);
  172. state.loading = false;
  173. } else {
  174. queryList();
  175. }
  176. }, 300);
  177. /** 重置按钮操作 */
  178. const resetQuery = throttle((formEl: FormInstance | undefined) => {
  179. if (!formEl) return;
  180. formEl.resetFields();
  181. queryList();
  182. state.expandedRowKeys = [];
  183. emptyArr = [];
  184. }, 300);
  185. // 打开新增弹窗
  186. const areaAddRef = ref<RefType>(); // 新增组织机构ref
  187. const onOpenAddArea = (row?: any) => {
  188. areaAddRef.value.openDialog(state.orgTableData, row);
  189. };
  190. // 打开编辑弹窗
  191. const areaEditRef = ref<RefType>(); // 编辑组织机构ref
  192. const onOpenEditArea = (row: any) => {
  193. areaEditRef.value.openDialog(row, state.orgTableData);
  194. };
  195. const expand = () => {
  196. state.isExpand = !state.isExpand;
  197. };
  198. watch(
  199. () => state.isExpand,
  200. (old: Boolean) => {
  201. if (old) getAllIds(state.orgTableData);
  202. else state.expandedRowKeys = [];
  203. }
  204. );
  205. const getAllIds = (arr: any) => {
  206. if (!arr) return [];
  207. arr.forEach((v: any) => {
  208. if (v.children?.length) {
  209. getAllIds(v.children);
  210. state.expandedRowKeys.push(v.id);
  211. }
  212. });
  213. };
  214. // 删除当前行
  215. const onDelArea = (row: any) => {
  216. ElMessageBox.confirm(`此操作将永久删除次区域:${row.areaName}, 是否继续?`, '提示', {
  217. confirmButtonText: '确定',
  218. cancelButtonText: '取消',
  219. type: 'warning',
  220. })
  221. .then(() => {
  222. treeAreaDelete(row.id).then(() => {
  223. ElMessage.success('删除成功');
  224. queryList();
  225. });
  226. })
  227. .catch(() => {});
  228. };
  229. // 获取所有部门结构
  230. const queryList = async () => {
  231. if (!auth('auxiliary:area:query')) ElMessage.error('抱歉,您没有权限获区域列表!');
  232. else {
  233. state.loading = true;
  234. try {
  235. const res: any = await Promise.all([treeArea()]);
  236. state.orgTableData = res[0].result ?? [];
  237. state.staticArr = res[0].result ?? [];
  238. state.loading = false;
  239. } catch (error) {
  240. console.log(error);
  241. state.loading = false;
  242. }
  243. }
  244. };
  245. // 页面加载时
  246. onMounted(() => {
  247. queryList();
  248. });
  249. </script>
  250. <style lang="scss" scoped>
  251. .auxiliary-area-container {
  252. .table {
  253. flex: 1;
  254. }
  255. }
  256. </style>