index.vue 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. <template>
  2. <div class="device-manager-box">
  3. <!--引用表格-->
  4. <BasicTable
  5. @register="registerTable"
  6. :rowSelection="rowSelection"
  7. :expandedRowKeys="expandedRowKeys"
  8. @expand="handleExpand"
  9. @fetch-success="onFetchSuccess"
  10. >
  11. <!--插槽:table标题-->
  12. <template #tableTitle>
  13. <a-button type="primary" preIcon="ant-design:plus-outlined" @click="handleCreate"> 新增</a-button>
  14. <a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
  15. <j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
  16. <a-dropdown v-if="selectedRowKeys.length > 0">
  17. <template #overlay>
  18. <a-menu>
  19. <a-menu-item key="1" @click="batchHandleDelete">
  20. <Icon icon="ant-design:delete-outlined" />
  21. 删除
  22. </a-menu-item>
  23. </a-menu>
  24. </template>
  25. <a-button
  26. >批量操作
  27. <Icon icon="ant-design:down-outlined" />
  28. </a-button>
  29. </a-dropdown>
  30. </template>
  31. <!--操作栏-->
  32. <template #action="{ record }">
  33. <TableAction :actions="getTableAction(record)" />
  34. </template>
  35. </BasicTable>
  36. <!--字典弹窗-->
  37. <CategoryModal @register="registerModal" @success="handleSuccess" />
  38. </div>
  39. </template>
  40. <script lang="ts" name="system-category" setup>
  41. //ts语法
  42. import { ref, unref } from 'vue';
  43. import { BasicTable, TableAction } from '/@/components/Table';
  44. import CategoryModal from './components/CategoryModal.vue';
  45. import { useModal } from '/@/components/Modal';
  46. // import { useMethods } from '/@/hooks/system/useMethods';
  47. import { columns, searchFormSchema } from './category.data';
  48. import { list, deleteCategory, batchDeleteCategory, getExportUrl, getImportUrl, getChildList, getChildListBatch } from './category.api';
  49. import { useListPage } from '/@/hooks/system/useListPage';
  50. import { defHttp } from '/@/utils/http/axios';
  51. const expandedRowKeys = ref([]);
  52. // const { handleExportXls, handleImportXls } = useMethods();
  53. //字典model
  54. const [registerModal, { openModal }] = useModal();
  55. // 列表页面公共参数、方法
  56. const { prefixCls, onExportXls, onImportXls, tableContext } = useListPage({
  57. designScope: 'category-template',
  58. tableProps: {
  59. title: '设备分类',
  60. api: list,
  61. columns: columns,
  62. actionColumn: {
  63. width: 180,
  64. },
  65. formConfig: {
  66. schemas: searchFormSchema,
  67. },
  68. },
  69. exportConfig: {
  70. name: '设备分类列表',
  71. url: getExportUrl,
  72. },
  73. importConfig: {
  74. url: getImportUrl,
  75. },
  76. });
  77. //注册table数据
  78. const [registerTable, { reload, collapseAll, updateTableDataRecord, findTableDataRecord, getDataSource }, { rowSelection, selectedRowKeys }] =
  79. tableContext;
  80. /**
  81. * 新增事件
  82. */
  83. function handleCreate() {
  84. openModal(true, {
  85. isUpdate: false,
  86. });
  87. }
  88. /**
  89. * 编辑事件
  90. */
  91. async function handleEdit(record) {
  92. openModal(true, {
  93. record,
  94. isUpdate: true,
  95. });
  96. }
  97. /**
  98. * 详情
  99. */
  100. async function handleDetail(record) {
  101. openModal(true, {
  102. record,
  103. isUpdate: true,
  104. hideFooter: true,
  105. });
  106. }
  107. /**
  108. * 删除事件
  109. */
  110. async function handleDelete(record) {
  111. await deleteCategory({ id: record.id }, importSuccess);
  112. }
  113. /**
  114. * 批量删除事件
  115. */
  116. async function batchHandleDelete() {
  117. const ids = selectedRowKeys.value.filter((item) => !item.includes('loading'));
  118. await batchDeleteCategory({ ids: ids }, importSuccess);
  119. }
  120. /**
  121. * 导入
  122. */
  123. function importSuccess() {
  124. //update-begin---author:wangshuai ---date:20220530 for:[issues/54]树字典,勾选,然后批量删除,系统错误------------
  125. (selectedRowKeys.value = []) && reload();
  126. //update-end---author:wangshuai ---date:20220530 for:[issues/54]树字典,勾选,然后批量删除,系统错误--------------
  127. }
  128. /**
  129. * 添加下级
  130. */
  131. function handleAddSub(record) {
  132. openModal(true, {
  133. record,
  134. isUpdate: false,
  135. });
  136. }
  137. /**
  138. * 成功回调
  139. */
  140. async function handleSuccess({ isUpdate, values, expandedArr }) {
  141. if (isUpdate) {
  142. //编辑回调
  143. updateTableDataRecord(values.id, values);
  144. } else {
  145. if (!values['pid']) {
  146. //新增根节点
  147. reload();
  148. } else {
  149. //新增子集
  150. expandedRowKeys.value = [];
  151. for (let key of unref(expandedArr)) {
  152. await expandTreeNode(key);
  153. }
  154. }
  155. }
  156. }
  157. /**
  158. * 接口请求成功后回调
  159. */
  160. function onFetchSuccess(result) {
  161. getDataByResult(result.items) && loadDataByExpandedRows();
  162. }
  163. /**
  164. * 根据已展开的行查询数据(用于保存后刷新时异步加载子级的数据)
  165. */
  166. async function loadDataByExpandedRows() {
  167. if (unref(expandedRowKeys).length > 0) {
  168. const res = await getChildListBatch({ parentIds: unref(expandedRowKeys).join(',') });
  169. if (res.success && res.result.records.length > 0) {
  170. //已展开的数据批量子节点
  171. let records = res.result.records;
  172. const listMap = new Map();
  173. for (let item of records) {
  174. let pid = item['pid'];
  175. if (unref(expandedRowKeys).includes(pid)) {
  176. let mapList = listMap.get(pid);
  177. if (mapList == null) {
  178. mapList = [];
  179. }
  180. mapList.push(item);
  181. listMap.set(pid, mapList);
  182. }
  183. }
  184. let childrenMap = listMap;
  185. let fn = (list) => {
  186. if (list) {
  187. list.forEach((data) => {
  188. if (unref(expandedRowKeys).includes(data.id)) {
  189. data.children = getDataByResult(childrenMap.get(data.id));
  190. fn(data.children);
  191. }
  192. });
  193. }
  194. };
  195. fn(getDataSource());
  196. }
  197. }
  198. }
  199. /**
  200. * 处理数据集
  201. */
  202. function getDataByResult(result) {
  203. if (result && result.length > 0) {
  204. return result.map((item) => {
  205. //判断是否标记了带有子节点
  206. if (item['hasChild'] == '1') {
  207. let loadChild = { id: item.id + '_loadChild', name: 'loading...', isLoading: true };
  208. item.children = [loadChild];
  209. }
  210. return item;
  211. });
  212. }
  213. }
  214. /**
  215. *树节点展开合并
  216. * */
  217. async function handleExpand(expanded, record) {
  218. // 判断是否是展开状态,展开状态(expanded)并且存在子集(children)并且未加载过(isLoading)的就去查询子节点数据
  219. if (expanded) {
  220. expandedRowKeys.value.push(record.id);
  221. if (record.children.length > 0 && !!record.children[0].isLoading) {
  222. let result = await defHttp.get({ url: `/sys/dict/getDictItems/${record.devicekind + 'kind'}` }, {}); //defHttp.get({ url: `/sys/dict/getDictItems/${record.devicekind + 'kind'}` }, {})
  223. if (result && result.length > 0) {
  224. record.children = getDataByResult(result);
  225. } else {
  226. record.children = null;
  227. record.hasChild = '0';
  228. }
  229. }
  230. } else {
  231. let keyIndex = expandedRowKeys.value.indexOf(record.id);
  232. if (keyIndex >= 0) {
  233. expandedRowKeys.value.splice(keyIndex, 1);
  234. }
  235. }
  236. }
  237. /**
  238. *操作表格后处理树节点展开合并
  239. * */
  240. async function expandTreeNode(key) {
  241. let record = findTableDataRecord(key);
  242. expandedRowKeys.value.push(key);
  243. let result = await getChildList({ pid: key });
  244. if (result && result.length > 0) {
  245. record.children = getDataByResult(result);
  246. } else {
  247. record.children = null;
  248. record.hasChild = '0';
  249. }
  250. updateTableDataRecord(key, record);
  251. }
  252. /**
  253. * 操作栏
  254. */
  255. function getTableAction(record) {
  256. debugger;
  257. return [
  258. {
  259. label: '编辑',
  260. onClick: handleEdit.bind(null, record),
  261. },
  262. {
  263. label: '删除',
  264. popConfirm: {
  265. title: '确定删除吗?',
  266. confirm: handleDelete.bind(null, record),
  267. },
  268. },
  269. {
  270. label: '添加下级',
  271. onClick: handleAddSub.bind(null, { pid: record.id }),
  272. },
  273. ];
  274. }
  275. </script>
  276. <style scoped></style>