import html, { getProp } from "html"; import request, { get, post } from "../../request/index.js"; import { defineAsyncComponent, ref, reactive, onMounted } from "vue"; import { useRoute, useRouter } from "vue-router"; import { useI18n } from "vue-i18n"; import { listToTree, schemaToModel, importFunction, format } from "../../utils/index.js"; import qs from "../../lib/qs/shim.js"; import VueOfficeExcel from "@vue-office/excel"; import { camelCase, capitalize } from "lodash"; import { useAppStore } from "../../store/index.js"; import { ElMessage, ElMessageBox } from "element-plus"; export default { name: "AppList", components: { AppForm: defineAsyncComponent(() => import("../form/index.js")), SvgIcon: defineAsyncComponent(() => import("../../components/icon/index.js")), AppFormInput: defineAsyncComponent(() => import("../form/form-input.js")), VueOfficeExcel, }, template: html`
{{$t('筛选')}}
{{$t('selectAll')}} {{$t('selectInverse')}} `, styles: html``, props: ["modelValue", "config", "querySchema", "controller", "query", "buttons"], emits: ["command"], setup(props, context) { /*变量定义*/ // 配置 const config = reactive(props.config); // 分页 const pageModel = reactive({ sizeList: [1, 50, 100], pageIndex: 1, pageSize: 10, total: 0, }); const treeProps = reactive({ children: "children", }); const tableKey = ref(false); const tableRef = ref(null); const uploadRef = ref(null); const columns = ref([]); const filterDrawer = ref(false); const subDrawer = ref(false); const subListQuery = ref({}); const tableLoading = ref(true); const selectedRows = ref([]); const dialogVisible = ref(false); const route = useRoute(); const router = useRouter(); const { t } = useI18n(); const appStore = useAppStore(); // 注释一下代码暂停权限验证 // const buttons = ref(props.buttons ?? route.meta.children.filter((o) => o.meta.hasPermission)); // 添加下行代码暂停权限验证 const buttons = ref(props.buttons ?? route.meta.children); const baseUrl = props.controller ?? `${route.meta.path}`; const queryModel = ref({}); const sortColumns = ref(new Map()); const querySchema = ref(props.querySchema); const queryList = ref([]); const tableSchema = ref({}); const tableData = ref([]); const editFormRef = ref(null); const editFormloading = ref(false); const editFormMode = ref(null); const editFormTitle = ref(""); const editFormSchema = ref(null); const editFormModel = ref(null); const exportModel = reactive({ includeAll: false, includeDeleted: false, }); const importModel = reactive({ partial: true, replace: false, }); const fileList = ref([]); const getSortModel = (model) => { model.orderBy .split(",") .map((o) => o.trim()) .filter((o) => o) .map((o) => ({ prop: camelCase(o.split(" ")[0]), order: (o.split(" ").filter((o) => o)[1] ?? "asc") + "ending", })) .forEach((o) => sortColumns.value.set(o.prop, o.order)); }; const getColumns = (schema) => { Object.keys(schema.properties).forEach((propertyName) => { const property = schema.properties[propertyName]; if (property.type !== "object" && property.type !== "array" && !property.hidden && property.showForList) { columns.value.push({ name: propertyName, title: property.title, checked: true }); } }); }; const getClass = ({ row, column }) => { if (column.property) { column.order = sortColumns.value.get(column.property); } }; const sortChange = async ({ column, prop, order }) => { if (order === null) { sortColumns.value.delete(prop); } else { sortColumns.value.set(prop, order); } queryModel.value.orderBy = Array.from(sortColumns.value) .map((o) => capitalize(o[0]) + (o[1] === "ascending" ? "" : ` DESC`)) .join(","); await load(); }; const showColumn = (item, prop) => { return ( item.type !== "object" && item.type !== "array" && !item.hidden && columns.value.findIndex((o) => o.name === prop && o.checked) >= 0 ); }; const handleSelectionChange = (rows) => (selectedRows.value = rows); const load = async () => { tableLoading.value = true; try { const url = config.query.url; const method = config.query.method; // queryModel.value = schemaToModel(config.query.schema); queryModel.value.maxResultCount = pageModel.pageSize; queryModel.value.skipCount = (pageModel.pageIndex - 1) * pageModel.pageSize; // const postData = JSON.parse(JSON.stringify(queryModel.value)); postData.filters = queryList.value.filter((o) => o.property && o.value); if (postData.items) { delete postData["items"]; } if (postData.query?.id) { delete postData.query["id"]; } const listData = (await request(url, postData, { method })).data; const items = listData.items; if (tableSchema.value.isTree) { items = listToTree(listData.items); } tableData.value = items; pageModel.total = listData.totalCount; //data.value = listData; tableKey.value = !tableKey.value; } catch (error) { console.log(error); } finally { tableLoading.value = false; } }; const onPageIndexChange = async () => await load(); const onPageSizeChange = async () => await load(); const click = async (item, rows) => { editFormloading.value = true; editFormMode.value = item.path ?? item; context.emit("command", item, rows); if (item.path === "index") { //list await load(); } else if (item.path === "details") { //details const url = `${baseUrl}/${item.path}?${qs.stringify({ id: rows[0].id })}`; editFormSchema.value = (await get(url)).data; editFormModel.value = (await post(url)).data; editFormTitle.value = `${config.edit.schema.title}${t("details")}`; dialogVisible.value = true; } else if (item.path === "create" || item.path === "update") { //create if (item.path === "create") { editFormModel.value = schemaToModel(config.edit.schema); } else { const url = format(config.edit.detailsUrl, rows[0].id); editFormModel.value = (await request(url, null, { method: config.edit.detailsMethod })).data; editFormModel.value.id = rows[0].id; } editFormTitle.value = `${t(item.path)}${config.edit.schema.title}`; dialogVisible.value = true; } else if (item.path === "delete") { //delete if (item.meta.isTop) { // 批量删除 return; } else { // 单个删除 const url = format(config.edit.deleteUrl, rows[0].id); try { await ElMessageBox.confirm("删除", "提示", { type: "warning", message: format("确认删除当前行数据吗?", rows[0]), }); await request(url, null, { method: config.edit.deleteMethod }); ElMessage({ type: "info", message: "操作完毕", }); } catch (error) { if (error === "cancel") { ElMessage({ type: "info", message: "删除取消", }); } } } const url = `${baseUrl}/${item.path}`; // await post( // url, // rows.map((o) => o.id) // ); await load(); } else if (item.path === "export") { //export editFormTitle.value = `${t(item.path)}${querySchema.value?.title}`; dialogVisible.value = true; } else if (item.path === "import") { //import const url = `${baseUrl}/${item.path}`; editFormTitle.value = `${t(item.path)}${querySchema.value?.title}`; fileList.value = []; dialogVisible.value = true; } else if (item === "filter") { editFormTitle.value = t("自定义查询"); dialogVisible.value = true; } editFormloading.value = false; }; const submit = async () => { if (editFormMode.value === "create" || editFormMode.value === "update") { try { const valid = await editFormRef.value.validate(); if (valid) { editFormloading.value = true; let url = (editFormMode.value === "create" ? config.edit.createUrl : config.edit.updateUrl) ?? config.query.url; if (editFormMode.value === "update") { url = format(url, editFormModel.value.id); } const method = editFormMode.value === "create" ? config.edit.createMethod : config.edit.updateMethod; const result = await request(url, editFormModel.value, { method }); if (result.errors) { model.errors = result.errors; //?? } else { await load(); editFormMode.value = null; dialogVisible.value = false; } } } catch (error) { console.log(error); } finally { editFormloading.value = false; } } else if (editFormMode.value === "details") { dialogVisible.value = false; editFormMode.value = null; } else if (editFormMode.value === "export") { const postData = JSON.parse(JSON.stringify(queryModel.value)); postData.filters = queryList.value.filter((o) => o.property && o.value); delete postData.query["items"]; delete postData.query["id"]; const url = `${baseUrl}/${editFormMode.value}?${qs.stringify(exportModel)}`; const response = await post(url, postData); download(response); dialogVisible.value = false; } else if (editFormMode.value === "import") { editFormloading.value = true; const url = `${baseUrl}/${editFormMode.value}`; const formData = new FormData(); formData.append("partial", importModel.partial); formData.append("replace", importModel.replace); formData.append("file", fileList.value[0]?.raw); console.log(uploadRef.value); const response = await post(url, formData); editFormloading.value = false; dialogVisible.value = false; await load(); } else if (editFormMode.value === "filter") { await load(); dialogVisible.value = false; } }; const showList = (value, nav) => { if (!subDrawer.value) { const controller = nav.substr(0, nav.lastIndexOf(".")).toLowerCase(); const findRoute = (tree) => { for (const item of tree) { if (item.meta.controller === controller) { return item; } if (item.children) { return findRoute(item.children); } } }; const targetRoute = router.getRoutes().find((o) => o.meta?.controller === controller); subListQuery.value = { controller, query: { [camelCase(nav.substr(nav.lastIndexOf(".") + 1))]: value }, buttons: targetRoute.meta.buttons, }; subDrawer.value = true; } }; const pushQueryList = () => { queryList.value.push({ property: "", operator: "{0}=@0", value: "", logic: "and", }); }; const download = (response) => { const downloadUrl = window.URL.createObjectURL(response.data); const filename = response.filename; let link = document.createElement("a"); link.href = downloadUrl; link.download = filename; link.click(); window.URL.revokeObjectURL(downloadUrl); }; const getImportTemplate = async () => { const url = `${baseUrl}/${editFormMode.value}`; const response = await get(url); download(response); }; const handleChange = (uploadFile, uploadFiles) => { fileList.value = uploadFiles; }; const getButtonDisabled = async (src, row) => { if (src) { const method = await importFunction(src); return src.startsWith("async") ? await method(row) : method(row); } return false; }; onMounted(async () => { if (route.meta.children?.length) { for (const item of route.meta.children) { if (item.meta.disabled?.constructor === String) { item.meta.disabled = await importFunction(item.meta.disabled); } } } pushQueryList(); // if (!querySchema.value) { // const vm = (await get(indexUrl)).data; // querySchema.value = vm.schema.properties.query; // tableSchema.value = vm.schema.properties.items.items; // data.value = vm.model ?? schemaToModel(vm.schema); // if (props.query) { // Object.assign(data.value.query, props.query); // } // getSortModel(data.value); // getColumns(vm.schema.properties.query); // } if (!config) { // } getColumns(config.table.schema); if (props.query) { Object.assign(queryModel.value.query, props.query); } // getSortModel(data.value); // getColumns(vm.schema.properties.query); await load(); }); return { config, queryModel, pageModel, treeProps, tableKey, tableRef, uploadRef, tableLoading, columns, showColumn, filterDrawer, subDrawer, dialogVisible, selectedRows, querySchema, queryList, tableSchema, buttons, tableData, getClass, sortChange, getProp, getImportTemplate, editFormRef, editFormloading, editFormMode, editFormTitle, editFormSchema, editFormModel, exportModel, importModel, onPageSizeChange, onPageIndexChange, handleSelectionChange, load, click, submit, showList, subListQuery, pushQueryList, fileList, handleChange, getButtonDisabled, }; }, };