diff --git a/vite-demo/src/hook/useModal.js b/vite-demo/src/hook/useModal.js index 298ee643920403af9845593c40d9b81e4e6091a2..c48805bc84d96e46e28cd9e3e24d26c514ce795b 100644 --- a/vite-demo/src/hook/useModal.js +++ b/vite-demo/src/hook/useModal.js @@ -31,7 +31,6 @@ export function useSelectSearch() { function selectFilterOption(input, option) { return option.componentOptions.children[0].text.toLowerCase().includes(input.toLowerCase()); } - return { selectFilterOption } diff --git a/vite-demo/src/hook/useTableMdal.js b/vite-demo/src/hook/useTableMdal.js new file mode 100644 index 0000000000000000000000000000000000000000..d65e86d2f1f6c45c45bd9ec08d6d6ede97ae4394 --- /dev/null +++ b/vite-demo/src/hook/useTableMdal.js @@ -0,0 +1,556 @@ +/** + * + * useTable 表格查询,分页, 删除 + * @modalMixin 弹窗新增,修改,详情 + */ +import {ref, reactive} from 'vue' +// import { postAction, putAction, deleteAction, httpAction } from 'api/commonApi/index'; +let postAction, putAction, deleteAction, httpAction; +let filterObjByKey, parseDate, getMoment, formatObjDate, getTreeKeys; + +// import { filterObjByKey, parseDate, getMoment, formatObjDate, getTreeKeys } from 'utils/util'; + +export function useLayout() { + // 布局 + let layout = reactive({ + labelCol: { + span: 4 + }, + wrapperCol: { + span: 16 + }, + }) + return { + layout + } +} + +export function usePaging() { + // 分页参数 + let ipagination = reactive({ + current: 1, + pageSize: 10, + pageSizeOptions: ['5', '10', '20', '30'], + showTotal: (total, range) => { + return range[0] + '-' + range[1] + ' 共' + total + '条'; + }, + showQuickJumper: true, + showSizeChanger: true, + total: 0 + }) + + return { + ipagination + } +} + +export function useTable() { + + // 字符串转日期 + const getMoment = (dateStr) => { + return getMoment(dateStr) + } + // 查询 + const searchQuery = () => { + ipagination.current = 1; + loadData(); + } + // 重置 + const searchReset = () => { + this.queryParam = {}; + this.subQueryParam = {}; + this.loadData(); + } + + // 数据查询 + const loadData = () => { + if (!this.url || !(this.url.list || this.url.dataAll)) { + console.warn('请设置url.list或url.dataAll属性!'); + return + } + const data = this.getQueryParams(); // 查询条件 + this.tableLoading = true; + /** + * get 请求 + */ + if (this.url.dataAll) { // 数据和表格总数一起请求 + httpAction(this.url.dataAll, data).then((res) => { // 列表数据 + if (res.code === 200) { + this.dataSource = res.data.rows; + this.ipagination.total = Number(res.data.count); + console.log(this.dataSource) + } + this.tableLoading = false; + }).catch(error => { + console.error(error); + this.tableLoading = false; + }) + } else { // 数据和表格总数分开请求请求 + httpAction(this.url.list, data).then((res) => { // 列表数据 + if (res.code === 200) { + this.dataSource = res.data; + console.log(this.dataSource) + } + this.tableLoading = false; + }).catch(error => { + console.error(error); + this.tableLoading = false; + }) + httpAction(this.url.count, data).then((res) => { // 列表长度 + if (res.code === 200) { + this.ipagination.total = res.data.count; + } + }).catch(error => { + console.error(error); + }) + } + } + + // 获取查询条件 + const getQueryParams = () => { + const params = Object.assign({}, this.queryParam, this.subQueryParam); + Object.keys(params).forEach(key => { + if (typeof params[key] === 'string') { // 去字符串两侧空格 + params[key] = params[key].trim(); + } + }) + params.page = this.ipagination.current - 1; + params.size = this.ipagination.pageSize; + return params; + } + + // 查询条件折叠 + const handleToggleSearch = () => { + this.toggleSearchStatus = !this.toggleSearchStatus; + // 已折叠状态 清除折叠区域表单数据 + if (!this.toggleSearchStatus) { + this.subQueryParam = {}; + } + } + + + // 表格行选择 + const onSelectChange = (selectedRowKeys, selectionRows) => { + console.log(selectedRowKeys, selectionRows) + this.selectedRowKeys = selectedRowKeys; + this.selectionRows = selectionRows; + } + + // 清除行选择 + const onClearSelected = () => { + this.selectedRowKeys = []; + this.selectionRows = []; + } + + // 新增 + const handleAdd = () => { + this.modalData = {}; + this.modalTitle = '新增'; + this.modalType = 'add'; + this.openModal(); + } + + /** + * 修改 + * @param rowData Object 行数据 + * @param keys Array 根据keys过滤rowData,防止form组件报警告 + */ + const handleEdit = (rowData, id, keys) => { + console.log(rowData, id, keys); + if (!keys) { + console.error('keys不能为空!') + return; + } + this.editId = id; + this.modalData = filterObjByKey(rowData, keys); + this.modalTitle = '修改'; + this.modalType = 'edit'; + this.openModal(); + } + + /** + * 查看详情 + * @param rowData Object 行数据 + * @param keys Array 根据keys过滤rowData,防止form组件报警告 + */ + const handleDetail = (rowData, keys) => { + if (!keys) { + console.error('keys不能为空!') + return; + } + this.modalData = filterObjByKey(rowData, keys); + this.modalTitle = '详情'; + this.modalType = 'detail'; + this.openModal(); + } + + const openModal = () => { + this.showModal = true; + } + + // 批量删除 + const batchDel = () => { + if (!this.url.delete) { + this.$message.error('请设置url.delete属性!'); + console.error('请设置url.delete属性!'); + return + } + if (this.selectedRowKeys.length <= 0) { + this.$message.warning('请选择一条记录!'); + return; + } + const ids = {idList: []}; + for (let i = 0; i < this.selectedRowKeys.length; i++) { + ids.idList.push({key: this.selectedRowKeys[i]}); + } + this.deleteFn(ids, `确认要删除选中的这${this.selectedRowKeys.length}条数据吗?`); + } + + // 单条删除 + const handleDelete = (id) => { + console.log('this.url.delete', this.url, this.url.delete); + if (!this.url.delete) { + this.$message.error('请设置url.delete属性! ==='); + console.error('请设置url.delete属性!'); + return + } + this.tableLoading = true; + const ids = { + idList: [ + {key: id} + ] + }; + deleteAction(this.url.delete, ids).then((res) => { + if (res.code === 203) { + this.modalFormOk(); + this.onClearSelected(); + } + this.tableLoading = false; + }).catch(error => { + console.error(error); + this.tableLoading = false; + }) + } + + const deleteFn = (ids, tip) => { + // 开发逻辑提示 + if (!this.url.delete) { + this.$message.error('请设置url.delete属性!'); + console.error('请设置url.delete属性!'); + return; + } + this.$confirm({ + title: '确认删除', + content: tip, + centered: true, + onOk: () => { + this.tableLoading = true; + deleteAction(this.url.delete, ids).then((res) => { + if (res.code === 203) { + this.modalFormOk(); + this.onClearSelected(); + } + this.tableLoading = false; + }).catch(error => { + console.error(error); + this.tableLoading = false; + }) + } + }); + } + + const modalFormOk = () => { + // 新增/修改 成功时,重载列表 + this.loadData(); + } + + // 排序 分页 + const handleTableChange = (pagination, filters, sorter) => { + this.ipagination = pagination; + this.loadData(); + } + + if (this.isInitTable) { + this.loadData(); + } + + return { + isInitTable: true, // 是否初始化表格 + // 查询条件 + queryParam: {}, + // 折叠区域查询条件 + subQueryParam: {}, + + // 数据源 + dataSource: [], + + // 表格加载状态 + tableLoading: false, + // table选中keys + selectedRowKeys: [], + // table选中records + selectionRows: [], + // 查询折叠 + toggleSearchStatus: false, + // 弹窗 + showModal: false, // 弹窗显示 + modalTitle: '', // 弹窗名称 + modalType: '', // 弹窗类型 add:新增 edit:修改 detail: 查看详情 + modalData: {}, // 弹窗回填数据 修改和详情 + editId: '' // 修改Id + }; +}; + +export const modalMixin = { + props: { + title: { + type: String, + default: '' + }, + type: { + type: String, + default: 'add' // add:新增 edit:修改 detail: 查看详情 + }, + show: { + type: Boolean, + default: false + }, + data: { + type: Object, + default() { + return {} + } + } + }, + data() { + return { + // 弹窗设置 + drawerWidth: 700, + // 布局 + labelCol: { + xs: {span: 24}, + sm: {span: 6} + }, + wrapperCol: { + xs: {span: 24}, + sm: {span: 16} + }, + confirmLoading: false, + form: this.$form.createForm(this) + } + }, + computed: { + disableSubmit: { + get() { + if (this.type === 'detail') { + return true; + } + return false; + }, + set() { + }// 查看详情,禁用所有表单 + } + }, + methods: { + // 回填数据 + backfillData() { + this.resetScreenSize(); + // 回填数据 + this.$nextTick().finally(() => { + this.form.resetFields(); + // 日期处理 + if (this.type !== 'add') { + this.data = parseDate(this.data); + setTimeout(() => { + this.form.setFieldsValue(this.data); + }) + } + }); + }, + handleOk(otherValues = {}, path, dateFormat = 'YYYY-MM-DD') { + this.confirmLoading = true; + // 触发表单验证 + this.form.validateFields((err, values) => { + if (!err) { + let formData = Object.assign(values, otherValues); + formData = formatObjDate(formData, dateFormat); + Object.keys(formData).forEach(item => { // 清空字符串前后空格 + if (typeof formData[item] === 'string') { + formData[item] = formData[item].trim(); + } + }) + let axios; + if (this.type === 'edit') { // 修改 + if (!this.url.edit) { + this.$message.error('请设置url.edit属性!'); + console.error('请设置url.edit属性!'); + return; + } + axios = putAction(`${this.url.edit}/${path}`, formData); + } else { // 新增 + if (!this.url.add) { + this.$message.error('请设置url.add属性!'); + console.error('请设置url.add属性!'); + return; + } + axios = postAction(this.url.add, formData); + } + axios.then((res) => { + if (res.code === 201 || res.code === 202) { + this.$emit('ok'); + this.close(); + } + }).catch(err => { + console.error(err); + }).finally(() => { + this.confirmLoading = false; + }); + } else { + this.confirmLoading = false; + } + }) + }, + close() { + this.confirmLoading = false; + this.disableSubmit = false; + this.$emit('close'); + this.$emit('update:show', false); + }, + // 根据屏幕变化,设置抽屉尺寸 + resetScreenSize() { + const screenWidth = document.body.clientWidth; + if (screenWidth < 500) { + this.drawerWidth = screenWidth; + } else { + this.drawerWidth = 700; + } + }, + // 下拉框搜索过滤 + selectFilterOption(input, option) { + return option.componentOptions.children[0].text.toLowerCase().includes(input.toLowerCase()); + } + } +}; + +export const treeMixin = { + data() { + return { + isInitTree: true, + treeLoading: true, // 刷新树 + defaultTreeUrl: 'ArchivesApi/common/getAreaRoomTree?root=0&leaf=2', // 默认tree_url + searchData: '', // 树搜索框绑定value + multiTab: 0, // 页签高度 + treeData: [], // tree数据 + searchValue: '', // 树搜索条件 + allTreeKeys: {}, // 树key集合 + dataList: [], // 树key和id + currSelected: {}, // 选中结点的属性 + selectedKeys: [], // 设置选中的树节点的key + checkedKeys: [], // 选中复选框的树节点 + checkStrictly: true, // 父子节点选中状态不再关联 + iExpandedKeys: [], // 展开指定的树节点 + autoExpandParent: true, // 是否自动展开父节点 + rowTreeData: {} // 选中树节点数据 + } + }, + methods: { + // tree搜索 + onSearchChange(e) { + const value = e.target.value.trim(); + let iExpandedKeys = [] + if (value !== '') { + iExpandedKeys = this.dataList.map(item => { + if (item.title.indexOf(value) > -1) { + return this.getParentKey(item.id, this.treeData); + } + return null; + }).filter((item, i, self) => { + return item && self.indexOf(item) === i + }); + } + Object.assign(this, { + iExpandedKeys, + searchValue: value, + autoExpandParent: true + }) + }, + // 获取父级key + getParentKey(id, tree) { // 树的父id + let parentKey; + for (let i = 0; i < tree.length; i++) { + const node = tree[i]; + if (node.children) { + if (node.children.some(item => item.id === id)) { + parentKey = node.id; + } else if (this.getParentKey(id, node.children)) { + parentKey = this.getParentKey(id, node.children); + } + } + } + return parentKey; + }, + // 重置 + emptyCurrForm() { + this.currSelected = {}; + this.selectedKeys = []; + }, + // 选择树 -选中tree子节点需要特定重写 + onSelect(selectedKeys, e) { + // 点击树子节点,图谱出现 + if (e.node.dataRef.children.length === 0) { + this.emptyCurrForm(); // 重置 + console.log(selectedKeys, e); + } + }, + onExpand(expandedKeys) { // 展开/收起节点时触发 + this.iExpandedKeys = expandedKeys; // 指点展开的节点 + this.autoExpandParent = false; // 合并父节点 + }, + // 获取tree节点数据 + getTreeData(url) { + this.emptyCurrForm(); // 重置 + httpAction(url).then(res => { + // title id children + if (res.code === 200 && res.status === 1) { + console.log('tree', res); + const treeData = (data) => { // 将isleaf转化成Boolean如果是false则删除 + data.forEach(item => { + item.key = item.key ? item.key : item.id; // 若是原tree无key,创建key + if (item.isLeaf === 'false') { + delete item.isLeaf + } else { + item.isLeaf = true + } + item.scopedSlots = {title: 'title'}; + if (item.children && item.children.length > 0) { + treeData(item.children); + } + }); + } + treeData(res.data); // 将isleaf转化成Boolean + this.treeData = res.data + // 获取树的id集合 + this.allTreeKeys = getTreeKeys(this.treeData); + const generateList = data => { + for (let i = 0; i < data.length; i++) { + const node = data[i]; + const id = node.id; + this.dataList.push({id, title: node.title}); + if (node.children) { + generateList(node.children); + } + } + }; + generateList(res.data); + } + }).finally(() => { + this.treeLoading = false; + }) + } + }, + mounted() { + if (this.isInitTree) { + this.getTreeData(this.defaultTreeUrl); + } + } +}