diff --git a/code/src/Modules/SettleAccount/host/SettleAccount.HttpApi.Host/wwwroot/components/list/index copy.js b/code/src/Modules/SettleAccount/host/SettleAccount.HttpApi.Host/wwwroot/components/list/index copy.js new file mode 100644 index 00000000..db892174 --- /dev/null +++ b/code/src/Modules/SettleAccount/host/SettleAccount.HttpApi.Host/wwwroot/components/list/index copy.js @@ -0,0 +1,872 @@ +import html, { getProp } from "html"; +import request, { getUrl } from "../../request/index.js"; +import { defineAsyncComponent, ref, reactive, onMounted, watch, nextTick } from "vue"; +import { useRoute, useRouter } from "vue-router"; +import { useI18n } from "vue-i18n"; +import { listToTree, schemaToModel, importFunction, format } from "../../utils/index.js"; +import { camelCase, capitalize } from "lodash"; +import { ElMessage, ElMessageBox } from "element-plus"; + +export default { + name: "AppList", + components: { + AppForm: defineAsyncComponent(() => import("../form/index.js")), + AppFormInput: defineAsyncComponent(() => import("../../components/form/form-input.js")), + SvgIcon: defineAsyncComponent(() => import("../../components/icon/index.js")), + AppFormInput: defineAsyncComponent(() => import("../form/form-input.js")), + }, + template: html` +
+
+ + + + + + + + + + {{$t('筛选')}} + + + + + + + + + + + + + + + + + +
+
+ + + +
+
+ + + + + + + + {{$t('selectAll')}} + + + {{$t('selectInverse')}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + `, + styles: html``, + props: ["modelValue", "config", "querySchema", "query", "buttons"], + emits: ["command"], + setup(props, context) { + const listScrollbarRef = ref(null); + /*变量定义*/ + // 配置 + const config = reactive(props.config); + // 分页 + const pageModel = reactive({ + sizeList: [10, 100, 1000, 10000], + 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(props.query ?? {}); + const tableLoading = ref(false); + const selectedRows = ref([]); + const dialogVisible = ref(false); + const route = useRoute(); + const router = useRouter(); + const { t } = useI18n(); + // 注释一下代码暂停权限验证 + // const buttons = ref(props.buttons ?? route.meta.children.filter((o) => o.meta.hasPermission)); + // 添加下行代码暂停权限验证 + const buttons = ref(props.buttons ?? route.meta.children); + const queryModel = ref(schemaToModel(config.query.schema)); + watch(queryModel.value, async (value, oldValue, a) => { + if (config.query.autoSubmit) { + await load(); + } + }); + const sortColumns = ref(new Map()); + const querySchema = ref(props.querySchema); + const filterList = ref([]); + const tableSchema = ref({}); + const tableData = ref([]); + const editFormRef = ref(null); + const importFormRef = ref(null); + const editFormloading = ref(false); + const editFormMode = ref(null); + const editFormTitle = ref(""); + const editFormSchema = ref(null); + const editFormModel = ref(null); + // + config.import ??= { schema: { type: "object", properties: {} } }; + config.import.schema.properties.files ??= { + title: "文件", + type: "array", + multiple: true, + input: "file", + accept: ".xlsx", + default: [], + limit: 10, + size: 100 * 1024 * 1024, + rules: [ + { + required: true, + trigger: "change", + }, + ], + }; + const defaultImportModel = schemaToModel(config.import.schema); + const importModel = ref(null); + const versions = ref([]); + const onClick = async (method, confirMmessage = "确认操作吗?", reload = true) => { + try { + if (confirMmessage) { + await ElMessageBox.confirm(confirMmessage, "提示", { + type: "warning", + }); + } + tableLoading.value = true; + let result = null; + if (method.constructor.name == "AsyncFunction") { + result = await method(); + } else { + result = method(); + } + if (!result.errors && reload) { + pageModel.pageIndex = 1; + await load(); + } + } catch (error) { + if (error === "cancel") { + ElMessage({ + type: "info", + message: "操作取消", + }); + } + } finally { + tableLoading.value = false; + } + }; + const getSortModel = (model) => { + (model.sorting ?? "") + .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.hideForList || (property.type !== "object" && property.type !== "array" && !property.hidden)) { + 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.sorting = Array.from(sortColumns.value) + .map((o) => capitalize(o[0]) + (o[1] === "ascending" ? "" : ` DESC`)) + .join(","); + await load(); + }; + const showColumn = (item, prop) => { + return columns.value.some((o) => o.name === prop && o.checked); + }; + const getFilters = (item, prop) => { + if (item.input === "select" && item.options) { + return item.options.map((o) => ({ text: o.label, value: o.value })); + } + return null; + }; + const filterHandler = (value, row, column) => { + return row[column.property] === value; + }; + const handleSelectionChange = (rows) => (selectedRows.value = rows); + const load = async () => { + tableLoading.value = true; + try { + const url = config.query.url; + const method = config.query.method; + const postData = buildQuery(); + 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; + nextTick(() => { + tableRef.value.doLayout(); + nextTick(() => listScrollbarRef.value.update()); + }); + } catch (error) { + console.log(error); + } finally { + tableLoading.value = false; + } + }; + const reload = async () => { + pageModel.pageIndex = 1; + await load(); + }; + const onPageIndexChange = async () => await load(); + const onPageSizeChange = async () => { + await reload(); + }; + const click = async (item, rows) => { + editFormloading.value = true; + editFormMode.value = item.path ?? item; + if (item.path === "query") { + //list + await load(); + } 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") { + if (!rows.length) { + return; + } + //delete + const url = format(config.edit.deleteUrl, rows[0].id); + if (item.meta.isTop) { + // 批量删除 + try { + await ElMessageBox.confirm(format("确认删除选中的%s行数据吗?", rows.length), "提示", { + type: "warning", + }); + tableLoading.value = true; + const result = await request( + url, + rows.map((o) => o.id), + { method: config.edit.deleteMethod }, + true + ); + if (!result.errors) { + pageModel.pageIndex = 1; + await reload(); + } + } catch (error) { + if (error === "cancel") { + ElMessage({ + type: "info", + message: "操作取消", + }); + } + } finally { + tableLoading.value = false; + } + } else { + // 单个删除 + try { + await ElMessageBox.confirm(format("确认删除当前行数据吗?", rows[0]), "提示", { + type: "warning", + }); + await request(url, null, { method: config.edit.deleteMethod }, true); + await reload(); + } catch (error) { + if (error === "cancel") { + ElMessage({ + type: "info", + message: "操作取消", + }); + } + } + } + await load(); + } else if (item.path === "export") { + if (item.meta.pattern === "paged") { + const url = config.edit.exportUrl; + const method = config.edit.exportMethod; + const postData = buildQuery(); + await onClick(async () => { + const response = await request(url, postData, { method }); + if (!response.errors) { + window.open(getUrl(`settleaccount/getblobfile/download/${response.data}`)); + } + }, "确认导出?"); + } else if (item.meta.pattern === "file") { + window.open(getUrl(`settleaccount/getblobfile/download/${rows[0]["downFileName"]}`)); + } else if ((item.meta.pattern = "row")) { + const url = config.edit.exportUrl; + const method = config.edit.exportMethod ?? "POST"; + const postData = { + [item.meta.key]: rows[0][item.meta.key], + }; + const response = await request(url, postData, { method }); + if (!response.errors) { + window.open(getUrl(`settleaccount/getblobfile/download/${response.data}`)); + } + } else { + console.log(item); + } + } else if (item.path === "import") { + //import + try { + importModel.value = Object.assign({}, defaultImportModel); + editFormloading.value = true; + editFormTitle.value = `${t(item.path)}${config.query.schema.title}`; + dialogVisible.value = true; + } catch (e) { + console.log(e); + } finally { + editFormloading.value = false; + } + } else if (item === "filter") { + editFormTitle.value = t("自定义查询"); + dialogVisible.value = true; + } else { + context.emit("command", item, rows, load, showList); + } + editFormloading.value = false; + }; + const submit = async () => { + if (editFormMode.value === "create" || editFormMode.value === "update") { + try { + const valid = await editFormRef.value.validate(); + if (valid) { + await onClick( + async () => { + 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 }, true); + if (!result.errors) { + dialogVisible.value = false; + editFormMode.value = null; + await reload(); + } + }, + null, + true + ); + } + } catch (error) { + console.log(error); + } finally { + editFormloading.value = false; + } + } else if (editFormMode.value === "details") { + dialogVisible.value = false; + editFormMode.value = null; + } else if (editFormMode.value === "import") { + try { + const valid = await importFormRef.value.validate(); + if (valid) { + editFormloading.value = true; + const url = config.edit.importUrl; + const formData = new FormData(); + // + if (route.meta.businessType) { + formData.append("businessType", route.meta.businessType); + } + Object.keys(importModel.value).forEach((propertyName) => { + if (importModel.value[propertyName]) { + const schema = config.import.schema.properties[propertyName]; + const value = importModel.value[propertyName]; + if (schema?.type === "array") { + importModel.value[propertyName].forEach((item) => { + formData.append(propertyName, schema.input === "file" ? item.raw : item); + }); + } else { + formData.append(propertyName, schema.input === "file" ? value.raw : value); + } + } + }); + const result = await request(url, formData); + if (!result.errors) { + editFormloading.value = false; + dialogVisible.value = false; + await load(); + } else if (result.data?.code === 400 && result.data.fileName) { + window.open(getUrl(`settleaccount/getblobfile/download/${result.data.fileName}`)); + } + } + } catch (error) { + console.log(error); + } finally { + editFormloading.value = false; + } + } else if (editFormMode.value === "filter") { + await load(); + dialogVisible.value = false; + } + }; + const showList = async (value, nav, config) => { + if (!subDrawer.value) { + const targetRoute = router.getRoutes().find((o) => o.path === nav); + if (config.constructor === String) { + const value = (await import(config)).default; + config = value.constructor === Function ? value(route.meta.businessType) : value; + } + subListQuery.value = { + query: value, + buttons: targetRoute.meta.children, + config, + }; + subDrawer.value = true; + } + }; + const download = (url, filename) => { + const downloadUrl = window.URL.createObjectURL(url); + let link = document.createElement("a"); + link.href = downloadUrl; + link.download = filename; + link.click(); + window.URL.revokeObjectURL(downloadUrl); + }; + const getButtonDisabled = async (src, row) => { + if (src) { + const method = await importFunction(src); + return src.startsWith("async") ? await method(row) : method(row); + } + return false; + }; + const pushfilterList = () => { + filterList.value.push({ + logic: "and", + column: "", + action: "equal", + value: null, + }); + }; + const operators = [ + { + value: "equal", + label: "等于", + }, + { + value: "notEqual", + label: "不等于", + }, + { + value: "biggerThan", + label: "大于", + }, + { + value: "smallThan", + label: "小于", + }, + { + value: "biggerThanOrEqual", + label: "大于等于", + }, + { + value: "smallThanOrEqual", + label: "小于等于", + }, + { + value: "like", + label: "类似于", + }, + { + value: "notLike", + label: "不类似于", + }, + { + value: "in", + label: "包含于", + }, + { + value: "notIn", + label: "不包含于", + }, + ]; + const getOperators = (schema) => { + const values = ["equal", "notEqual"]; + if (schema.type === "string") { + values.push("like", "notLike"); + if (schema.input && ["year", "month", "date", "datetime"].includes(schema.input)) { + values.push("biggerThan", "smallThan", "biggerThanOrEqual", "smallThanOrEqual"); + } + } else if (schema.type === "boolean") { + } else { + values.push("biggerThan", "smallThan", "biggerThanOrEqual", "smallThanOrEqual"); + } + return operators.filter((o) => values.includes(o.value)); + }; + function buildQuery() { + queryModel.value.maxResultCount = pageModel.pageSize; + queryModel.value.skipCount = (pageModel.pageIndex - 1) * pageModel.pageSize; + // + const postData = JSON.parse(JSON.stringify(queryModel.value)); + //Object.assign(postData, subListQuery.value.query);//注释掉子表DTO查询 + postData.filters = filterList.value.filter((o) => o.column && o.action && (o.value || o.value === false)); + if (subListQuery.value.query) { + Object.keys(subListQuery.value.query).forEach((o) => { + postData.filters.push({ + logic: "and", + column: o, + action: "equal", + value: subListQuery.value.query[o], + }); + }); + } + //添加子表filter查询 + if (route.meta.businessType && route.meta.path !== "/jis-bbac/settlement/bbac_can_sa_service") { + postData.filters.push({ + logic: "and", + column: "businessType", + action: "equal", + value: route.meta.businessType, + }); + } + if (postData.items) { + delete postData["items"]; + } + if (postData.query?.id) { + delete postData.query["id"]; + } + return postData; + } + 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); + } + } + } + // + getSortModel(queryModel.value); + filterList.value = queryModel.value?.filters ?? []; + filterList.value.forEach((o) => { + if (o.default) { + o.value = o.default.constructor === Function ? o.default() : o.default; + } + }); + getColumns(config.table.schema); + // if (props.query) { + // Object.assign(queryModel.value.query, props.query); + // } + if (!config.query.disableQueryOnLoad) { + await load(); + } + }); + return { + listScrollbarRef, + load, + reload, + onClick, + config, + queryModel, + buildQuery, + pageModel, + treeProps, + tableKey, + tableRef, + uploadRef, + tableLoading, + columns, + showColumn, + filterDrawer, + subDrawer, + dialogVisible, + selectedRows, + querySchema, + filterList, + tableSchema, + buttons, + tableData, + getClass, + sortChange, + getProp, + importFormRef, + editFormRef, + editFormloading, + editFormMode, + editFormTitle, + editFormSchema, + editFormModel, + importModel, + onPageSizeChange, + onPageIndexChange, + handleSelectionChange, + load, + click, + submit, + showList, + subListQuery, + getButtonDisabled, + versions, + pushfilterList, + getOperators, + getFilters, + filterHandler, + }; + }, +}; diff --git a/code/src/Modules/SettleAccount/host/SettleAccount.HttpApi.Host/wwwroot/components/list/index.js b/code/src/Modules/SettleAccount/host/SettleAccount.HttpApi.Host/wwwroot/components/list/index.js index db892174..d83d4360 100644 --- a/code/src/Modules/SettleAccount/host/SettleAccount.HttpApi.Host/wwwroot/components/list/index.js +++ b/code/src/Modules/SettleAccount/host/SettleAccount.HttpApi.Host/wwwroot/components/list/index.js @@ -16,10 +16,10 @@ export default { AppFormInput: defineAsyncComponent(() => import("../form/form-input.js")), }, template: html` -
+
- +