diff --git a/code/.gitignore b/code/.gitignore index 2d5ef72f..07d8289e 100644 --- a/code/.gitignore +++ b/code/.gitignore @@ -1,3 +1,4 @@ +<<<<<<< HEAD ################################################################################ # 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。 ################################################################################ @@ -16,3 +17,21 @@ /src/Modules/SettleAccount/host/SettleAccount.HttpApi.Host/Logs/log-20220226.txt /src/.vs/SettleAccount/v17/.futdcache.v1 /src/.vs/SettleAccount/v17/fileList.bin +======= +*.bak + +#fe +node_modules/ +dist/ + +#be +.vs/ +bin/ +obj/ +*.suo +*.user +*.db +*.db-shm +*.db-wal + +>>>>>>> c0f08a7ed0ffc663a2852d4c0da54a983f033a2f diff --git a/code/WebApp/vanilla/index.html b/code/WebApp/vanilla/index.html index e487ebc9..9a32d315 100644 --- a/code/WebApp/vanilla/index.html +++ b/code/WebApp/vanilla/index.html @@ -3,7 +3,9 @@ - + + + `, + props: ["modelValue", "schema", "controller", "query", "buttons"], emits: ["command"], async setup(props, context) { + const treeProps = reactive({ + children: "children", + }); const tableRef = ref(null); const columns = ref([]); const filterDrawer = ref(false); + const subDrawer = ref(false); + const subListQuery = ref({}); const tableLoading = ref(false); const selectedRows = ref([]); const dialogVisible = ref(false); const route = useRoute(); + const router = useRouter(); const { t } = useI18n(); - const baseUrl = `${route.meta.controller}`; + const buttons = ref(props.buttons ?? route.meta.buttons); + const baseUrl = props.controller ?? `${route.meta.controller}`; const indexUrl = `${baseUrl}/index`; - const vm = (await get(indexUrl)).data; - const schema = vm.schema; - const data = reactive(vm.model ?? schemaToModel(schema)); + const data = ref({}); const sortColumns = ref(new Map()); + const schema = ref(props.schema); + const queryFromSchema = ref(null); + const tableSchema = ref({}); + const tableData = ref([]); + const editFormRef = ref(null); + const editFormloading = ref(false); + const editFormMode = ref(null); + const editFormTitle = ref(""); + const editFormSchema = reactive({}); + const editFormModel = reactive({}); + const exportModel = reactive({ + includeAll: false, + includeDeleted: false, + }); const getSortModel = (model) => { - const orderBy = model.orderBy + model.orderBy .split(",") .map((o) => o.trim()) .filter((o) => o) @@ -212,32 +262,30 @@ export default { order: (o.split(" ").filter((o) => o)[1] ?? "asc") + "ending", })) .forEach((o) => sortColumns.value.set(o.prop, o.order)); - return orderBy; }; - const sortModel = reactive(getSortModel(data)); + const getColumns = (schema) => { + Object.keys(schema.properties).forEach((propertyName) => { + const property = schema.properties[propertyName]; + if (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 = ({ column, prop, order }) => { + const sortChange = async ({ column, prop, order }) => { if (order === null) { sortColumns.value.delete(prop); } else { sortColumns.value.set(prop, order); } - data.orderBy = Array.from(sortColumns.value) + data.value.orderBy = Array.from(sortColumns.value) .map((o) => capitalize(o[0]) + (o[1] === "ascending" ? "" : ` DESC`)) .join(","); - load(indexUrl); - }; - const getColumns = (schema) => { - Object.keys(schema.properties).forEach((propertyName) => { - const property = schema.properties[propertyName]; - if (property.type !== "object" && property.type !== "array" && !property.hidden) { - columns.value.push({ name: propertyName, title: property.title, checked: true }); - } - }); + await load(indexUrl); }; const showColumn = (item, prop) => { return ( @@ -247,35 +295,28 @@ export default { columns.value.findIndex((o) => o.name === prop && o.checked) >= 0 ); }; - getColumns(schema.properties.query); - const queryFromSchema = schema.properties.query; - const tableSchema = schema.properties.items; - const editFormRef = ref(null); - const editFormloading = ref(false); - const editFormMode = ref(null); - const editFormTitle = ref(""); - const editFormSchema = reactive({}); - const editFormModel = reactive({}); - const exportModel = reactive({ - includeAll: false, - includeDeleted: false, - }); + const handleSelectionChange = (rows) => (selectedRows.value = rows); const load = async (url) => { tableLoading.value = true; try { - const postData = JSON.parse(JSON.stringify(data)); - delete postData["Id"]; - delete postData["items"]; - Object.assign(data, (await post(url, postData)).data); + const postData = JSON.parse(JSON.stringify(data.value)); + delete postData.query["items"]; + delete postData.query["id"]; + const listData = (await post(url, postData)).data; + if (tableSchema.value.isTree) { + listData.items = listToTree(listData.items); + } + tableData.value = listData.items; + data.value = listData; } catch (error) { console.log(error); } finally { tableLoading.value = false; } }; - const onPageIndexChange = () => load(indexUrl); - const onPageSizeChange = () => load(indexUrl); + const onPageIndexChange = async () => await load(indexUrl); + const onPageSizeChange = async () => await load(indexUrl); const click = async (item, rows) => { editFormMode.value = item.path; context.emit("command", item, rows); @@ -285,25 +326,25 @@ export default { } else if (item.path === "details") { //details const detailsUrl = `${baseUrl}/${item.path}?${qs.stringify({ id: rows[0].id })}`; - Object.assign(editFormSchema, schema.properties.items.items); + Object.assign(editFormSchema, schema.value.properties.items.items); Object.assign(editFormModel, (await post(detailsUrl)).data); - editFormTitle.value = `${t("details")}${schema.title}`; + editFormTitle.value = `${t("details")}${schema.value?.title}`; dialogVisible.value = true; } else if (item.path === "create") { //create const url = `${baseUrl}/${item.path}`; const vm = (await get(url)).data; - Object.assign(editFormSchema, vm.schema); + Object.assign(editFormSchema, schema.value); Object.assign(editFormModel, vm.model); - editFormTitle.value = `${t("create")}${schema.title}`; + editFormTitle.value = `${t("create")}${schema.value?.title}`; dialogVisible.value = true; } else if (item.path === "update") { //update const url = `${baseUrl}/${item.path}`; const vm = (await get(url, { id: rows[0].id })).data; - Object.assign(editFormSchema, vm.schema); + Object.assign(editFormSchema, schema.value); Object.assign(editFormModel, vm.model); - editFormTitle.value = `${t("update")}${schema.title}`; + editFormTitle.value = `${t("update")}${schema.value?.title}`; dialogVisible.value = true; } else if (item.path === "delete") { //delete @@ -324,7 +365,7 @@ export default { } else if (item.path === "import") { //import const url = `${baseUrl}/${item.path}`; - editFormTitle.value = `${t("import")}${schema.title}`; + editFormTitle.value = `${t("import")}${schema.value?.title}`; dialogVisible.value = true; } }; @@ -350,26 +391,61 @@ export default { editFormloading.value = false; } } else if (editFormMode.value === "details") { - load(indexUrl); + await load(indexUrl); editFormMode.value = null; dialogVisible.value = false; } }; - await load(indexUrl); + 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; + } + }; + onMounted(async () => { + const vm = (await get(indexUrl)).data; + schema.value = vm.schema; + queryFromSchema.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); + await load(indexUrl); + }); return { - route, + treeProps, tableRef, tableLoading, columns, showColumn, filterDrawer, + subDrawer, dialogVisible, selectedRows, - schema, queryFromSchema, tableSchema, + buttons, data, - sortModel, + tableData, getClass, sortChange, getProp, @@ -385,6 +461,8 @@ export default { load, click, submit, + showList, + subListQuery, }; }, }; diff --git a/docs/demo/src/WTA/wwwroot/components/markdown/index.js b/docs/demo/src/WTA/wwwroot/components/markdown/index.js index e36c75a7..10c942ae 100644 --- a/docs/demo/src/WTA/wwwroot/components/markdown/index.js +++ b/docs/demo/src/WTA/wwwroot/components/markdown/index.js @@ -1,14 +1,18 @@ -import { ref, onMounted } from 'vue'; -import { marked, setOptions } from '../../lib/marked/marked.esm.js'; -import mermaid from '../../lib/mermaid/mermaid.esm.min.mjs'; -import hljs from '../../lib/highlightjs/highlight.min.js'; +import html from "html"; +import { ref, onMounted } from "vue"; +import { marked, setOptions } from "../../lib/marked/marked.esm.js"; +import mermaid from "../../lib/mermaid/mermaid.esm.min.mjs"; +import hljs from "../../lib/highlightjs/highlight.min.js"; export default { - template: `
`, + template: html`
+ +
+
`, props: { name: { - default: null - } + default: null, + }, }, setup(props) { const tplRef = ref(null); @@ -17,25 +21,25 @@ export default { onMounted(async () => { setOptions({ highlight: function (code, lang) { - if (lang === 'mermaid') { + if (lang === "mermaid") { return mermaid.mermaidAPI.render(`mermaid${id++}`, code, undefined); } else { - const language = hljs.getLanguage(lang) ? lang : 'plaintext'; + const language = hljs.getLanguage(lang) ? lang : "plaintext"; return hljs.highlight(code, { language }).value; } }, - langPrefix: 'hljs language-', + langPrefix: "hljs language-", }); - let mdText = tplRef.value.querySelector('.source').innerText; + let mdText = tplRef.value.querySelector(".source").innerText; if (props.name !== null) { const response = await fetch(`./assets/docs/${props.name}.md`); mdText = await response.text(); } - tplRef.value.querySelector('.markdown-body').innerHTML = marked(mdText); - tplRef.value.querySelector('.source').remove(); + tplRef.value.querySelector(".markdown-body").innerHTML = marked(mdText); + tplRef.value.querySelector(".source").remove(); }); return { - tplRef + tplRef, }; - } -} + }, +}; diff --git a/docs/demo/src/WTA/wwwroot/index.html b/docs/demo/src/WTA/wwwroot/index.html index e487ebc9..b0e0eda0 100644 --- a/docs/demo/src/WTA/wwwroot/index.html +++ b/docs/demo/src/WTA/wwwroot/index.html @@ -69,4 +69,4 @@ - + \ No newline at end of file diff --git a/docs/demo/src/WTA/wwwroot/layouts/header.js b/docs/demo/src/WTA/wwwroot/layouts/header.js index fc7be257..d57f347f 100644 --- a/docs/demo/src/WTA/wwwroot/layouts/header.js +++ b/docs/demo/src/WTA/wwwroot/layouts/header.js @@ -1,18 +1,21 @@ import html from "html"; -import { ref, onMounted, onUnmounted } from "vue"; +import { defineAsyncComponent, ref, onMounted, onUnmounted } from "vue"; import { useAppStore } from "../store/index.js"; -import SvgIcon from "../components/icon/index.js"; -import LayoutLogo from "./logo.js"; import { useDark, useFullscreen, useToggle } from "@vueuse/core"; import { ElMessage, ElMessageBox } from "element-plus"; import { useI18n } from "vue-i18n"; import { logout } from "../api/user.js"; -import LayoutLocale from "./locale.js"; import router from "../router/index.js"; import { treeToList } from "../utils/index.js"; export default { - components: { SvgIcon, LayoutLogo, LayoutLocale, ElMessage, ElMessageBox }, + components: { + SvgIcon: defineAsyncComponent(() => import("../components/icon/index.js")), + LayoutLogo: defineAsyncComponent(() => import("./logo.js")), + LayoutLocale: defineAsyncComponent(() => import("./locale.js")), + ElMessage, + ElMessageBox, + }, template: html`
diff --git a/docs/demo/src/WTA/wwwroot/layouts/index.js b/docs/demo/src/WTA/wwwroot/layouts/index.js index e7f989b3..380813c3 100644 --- a/docs/demo/src/WTA/wwwroot/layouts/index.js +++ b/docs/demo/src/WTA/wwwroot/layouts/index.js @@ -1,14 +1,14 @@ import html from "html"; -import LayoutHeader from "./header.js"; -import LayoutMenu from "./menu.js"; -import LayoutTabs from "./tabs.js"; -import LayoutFooter from "./footer.js"; -import Icon from "../components/icon/index.js"; import { useAppStore } from "../store/index.js"; -import { computed } from "vue"; +import { defineAsyncComponent, computed } from "vue"; export default { - components: { Icon, LayoutHeader, LayoutMenu, LayoutTabs, LayoutFooter }, + components: { + LayoutHeader: defineAsyncComponent(() => import("./header.js")), + LayoutMenu: defineAsyncComponent(() => import("./menu.js")), + LayoutTabs: defineAsyncComponent(() => import("./tabs.js")), + LayoutFooter: defineAsyncComponent(() => import("./footer.js")), + }, template: html` diff --git a/docs/demo/src/WTA/wwwroot/layouts/locale.js b/docs/demo/src/WTA/wwwroot/layouts/locale.js index 579b05c6..221aa90a 100644 --- a/docs/demo/src/WTA/wwwroot/layouts/locale.js +++ b/docs/demo/src/WTA/wwwroot/layouts/locale.js @@ -1,13 +1,14 @@ import html from "html"; +import { defineAsyncComponent } from "vue"; import { useAppStore } from "../store/index.js"; import { useI18n } from "vue-i18n"; -import Icon from "../components/icon/index.js"; + export default { - components: { Icon }, + components: { SvgIcon: defineAsyncComponent(() => import("../components/icon/index.js")) }, template: html` - +