Browse Source

update

pull/1/head
wanggang 1 year ago
parent
commit
a20b6bdfcb
  1. 44
      docs/demo/src/WTA.Application/Identity/Data/IdentityDbSeed.cs
  2. 14
      docs/demo/src/WTA.Shared/Attributes/ManyToManyAttribute.cs
  3. 14
      docs/demo/src/WTA.Shared/Attributes/ManyToOneAttribute.cs
  4. 13
      docs/demo/src/WTA.Shared/Controllers/GenericController.cs
  5. 8
      docs/demo/src/WTA.Shared/Extensions/JsonSchemaExtensions.cs
  6. 7
      docs/demo/src/WTA/wwwroot/components/form/form-input.js
  7. 6
      docs/demo/src/WTA/wwwroot/components/form/form-item.js
  8. 5
      docs/demo/src/WTA/wwwroot/components/form/index.js
  9. 34
      docs/demo/src/WTA/wwwroot/components/icon/index.js
  10. 126
      docs/demo/src/WTA/wwwroot/components/list/index.js
  11. 36
      docs/demo/src/WTA/wwwroot/components/markdown/index.js
  12. 2
      docs/demo/src/WTA/wwwroot/index.html
  13. 13
      docs/demo/src/WTA/wwwroot/layouts/header.js
  14. 14
      docs/demo/src/WTA/wwwroot/layouts/index.js
  15. 7
      docs/demo/src/WTA/wwwroot/layouts/locale.js
  16. 9
      docs/demo/src/WTA/wwwroot/layouts/menu-item.js
  17. 19
      docs/demo/src/WTA/wwwroot/layouts/tabs.js
  18. 2
      docs/demo/src/WTA/wwwroot/main.js
  19. 2
      docs/demo/src/WTA/wwwroot/router/index.js
  20. 1
      docs/demo/src/WTA/wwwroot/store/app.js

44
docs/demo/src/WTA.Application/Identity/Data/IdentityDbSeed.cs

@ -119,18 +119,18 @@ public class IdentityDbSeed : IDbSeed<IdentityDbContext>
context.Set<User>().Add(superUser);
}
private void InitTestDate(IdentityDbContext context)
private static void InitTestDate(IdentityDbContext context)
{
context.Set<HBPO_SA>().Add(new HBPO_SA { Version = "测试数据", BillNum = "123", DNBillNum = "测试数据", State = "测试数据", RecordCount = "测试数据" });
context.Set<HBPO_SA_DETAIL>().Add(new HBPO_SA_DETAIL { KeyCode = "测试数据", Version = "测试数据", BillNum = "123", LU = "测试数据", PN = "测试数据", Site = "测试数据", SettleDate = new DateTime(), GroupNum = "测试数据" });
context.Set<BBAC_SA>().Add(new BBAC_SA { Version = "测试数据", BillNum = "123", DNBillNum = "测试数据", State = "测试数据", RecordCount = "测试数据" });
context.Set<BBAC_SA_DETAIL>().Add(new BBAC_SA_DETAIL { KeyCode = "测试数据", Version = "测试数据", BillNum = "123", LU = "测试数据", PN = "测试数据", Site = "测试数据", SettleDate = new DateTime(), GroupNum = "测试数据", Category = "测试数据", IsReturn = "测试数据" });
context.Set<JIT_SA>().Add(new JIT_SA { Version = "测试数据", BillNum = "123", DNBillNum = "测试数据", State = "测试数据", RecordCount = "测试数据" });
context.Set<JIT_SA_DETAIL>().Add(new JIT_SA_DETAIL { KeyCode = "测试数据", Version = "测试数据", BillNum = "123", LU = "测试数据", PN = "测试数据", Site = "测试数据", SettleDate = new DateTime(), GroupNum = "测试数据" });
context.Set<JIT_SA_DETAIL>().Add(new JIT_SA_DETAIL { KeyCode = "测试数据", Version = "测试数据", BillNum = "123", LU = "测试数据", PN = "测试数据", Site = "测试数据", SettleDate = new DateTime(), GroupNum = "测试数据" });
context.Set<BJ_SA>().Add(new BJ_SA { Version = "测试数据", BillNum = "123", DNBillNum = "测试数据", State = "测试数据", RecordCount = "测试数据" });
context.Set<BJ_SA_DETAIL>().Add(new BJ_SA_DETAIL { KeyCode = "测试数据", Version = "测试数据", BillNum = "123", LU = "测试数据", PN = "测试数据", Site = "测试数据", SettleDate = new DateTime(), GroupNum = "测试数据" });
context.Set<IN_SA>().Add(new IN_SA { Version = "测试数据", BillNum = "123", DNBillNum = "测试数据", State = "测试数据" });
context.Set<IN_SA_DETAIL>().Add(new IN_SA_DETAIL { KeyCode = "测试数据", Version = "测试数据", BillNum = "123", LU = "测试数据", PU = "测试数据", Site = "测试数据",SettleDate = new DateTime(), GroupNum = "测试数据" });
context.Set<IN_SA_DETAIL>().Add(new IN_SA_DETAIL { KeyCode = "测试数据", Version = "测试数据", BillNum = "123", LU = "测试数据", PU = "测试数据", Site = "测试数据", SettleDate = new DateTime(), GroupNum = "测试数据" });
context.Set<HBPO_DN>().Add(new HBPO_DN { Version = "测试数据", DNBillNum = "123", StockCount = "测试数据" });
context.Set<HBPO_DN_DETAIL>().Add(new HBPO_DN_DETAIL { KeyCode = "测试数据", Version = "测试数据", BillNum = "123", LU = "测试数据", PN = "测试数据", Site = "测试数据", SettleDate = new DateTime(), State = "测试数据", INVGroupNum = "测试数据", GroupNum = "测试数据", DNBillNum = "测试数据" });
context.Set<BBAC_DN>().Add(new BBAC_DN { Version = "测试数据", DNBillNum = "123", StockCount = "测试数据" });
@ -140,13 +140,43 @@ public class IdentityDbSeed : IDbSeed<IdentityDbContext>
context.Set<BJ_DN>().Add(new BJ_DN { Version = "测试数据", DNBillNum = "123", StockCount = "测试数据" });
context.Set<BJ_DN_DETAIL>().Add(new BJ_DN_DETAIL { KeyCode = "测试数据", Version = "测试数据", LU = "测试数据", PN = "测试数据", Site = "测试数据", SettleDate = new DateTime(), State = "测试数据", INVGroupNum = "测试数据", GroupNum = "测试数据", DNBillNum = "测试数据" });
context.Set<IN_DN>().Add(new IN_DN { Version = "测试数据", DNBillNum = "123", StockCount = "测试数据" });
context.Set<IN_DN_DETAIL>().Add(new IN_DN_DETAIL { KeyCode = "测试数据", Version = "测试数据", LU = "测试数据", PU = "测试数据", Site = "测试数据", SettleDate = new DateTime(), State = "测试数据", INVGroupNum = "测试数据", GroupNum = "测试数据", DNBillNum = "测试数据" });
context.Set<INVOICE>().Add(new INVOICE { RealnvBillNum = "测试数据", InvbillNum = "123", INVGroupNum = "测试数据", FileName ="测试数据",BusinessType="测试数据"});
context.Set<INVOICE_DETAIL>().Add(new INVOICE_DETAIL { LU = "测试数据", InvbillNum = "123"});
context.Set<IN_DN_DETAIL>().Add(new IN_DN_DETAIL { KeyCode = "测试数据", Version = "测试数据", LU = "测试数据", PU = "测试数据", Site = "测试数据", SettleDate = new DateTime(), State = "测试数据", INVGroupNum = "测试数据", GroupNum = "测试数据", DNBillNum = "测试数据" });
context.Set<INVOICE>().Add(new INVOICE { RealnvBillNum = "测试数据", InvbillNum = "123", INVGroupNum = "测试数据", FileName = "测试数据", BusinessType = "测试数据" });
context.Set<INVOICE_DETAIL>().Add(new INVOICE_DETAIL { LU = "测试数据", InvbillNum = "123" });
}
private void InitDictionaries(DbContext context)
private static void InitDictionaries(DbContext context)
{
context.Set<DictionaryItem>().Add(new DictionaryItem
{
Name = "测试1",
Number = "test1",
Children = new List<DictionaryItem> {
new DictionaryItem{
Name="测试1.1",
Number="test1.1",
},
new DictionaryItem{
Name="测试1.2",
Number="test1.2",
}
}
}.UpdateId());
context.Set<DictionaryItem>().Add(new DictionaryItem
{
Name = "测试2",
Number = "test2",
Children = new List<DictionaryItem> {
new DictionaryItem{
Name="测试2.1",
Number="test2.1",
},
new DictionaryItem{
Name="测试2.2",
Number="test2.2",
}
}
}.UpdateId());
}
private void InitPermissions(DbContext context)

14
docs/demo/src/WTA.Shared/Attributes/ManyToManyAttribute.cs

@ -0,0 +1,14 @@
namespace WTA.Shared.Attributes;
[AttributeUsage(AttributeTargets.Property)]
public class ManyToManyAttribute<TEntity> : Attribute, ITypeAttribute
{
public Type Type { get; set; } = null!;
public string? Property { get; }
public ManyToManyAttribute(string? property = null)
{
this.Type = typeof(TEntity);
this.Property = property;
}
}

14
docs/demo/src/WTA.Shared/Attributes/ManyToOneAttribute.cs

@ -0,0 +1,14 @@
namespace WTA.Shared.Attributes;
[AttributeUsage(AttributeTargets.Property)]
public class ManyToOneAttribute<TEntity> : Attribute, ITypeAttribute
{
public Type Type { get; set; } = null!;
public string? Property { get; }
public ManyToOneAttribute(string? property = null)
{
this.Type = typeof(TEntity);
this.Property = property;
}
}

13
docs/demo/src/WTA.Shared/Controllers/GenericController.cs

@ -38,13 +38,14 @@ public class GenericController<TEntity, TModel, TListModel, TSearchModel, TImpor
[HttpPost, Multiple, Order(-4), HtmlClass("el-button--primary")]
public virtual IActionResult Index([FromBody] PaginationModel<TSearchModel, TListModel> model)
{
var query = BuildQuery(model);
var isTree = typeof(TEntity).IsAssignableTo(typeof(BaseTreeEntity<TEntity>));
var query = BuildQuery(model, isTree);
model.TotalCount = query.Count();
if (!string.IsNullOrEmpty(model.OrderBy))
{
query = query.OrderBy(model.OrderBy);
}
if (model.QueryAll)
if (model.QueryAll || isTree)
{
model.PageSize = model.TotalCount;
}
@ -59,9 +60,8 @@ public class GenericController<TEntity, TModel, TListModel, TSearchModel, TImpor
return Json(model);
}
protected virtual IQueryable<TEntity> BuildQuery(PaginationModel<TSearchModel, TListModel> model)
protected virtual IQueryable<TEntity> BuildQuery(PaginationModel<TSearchModel, TListModel> model, bool isTree)
{
var isTree = typeof(TEntity).IsAssignableTo(typeof(BaseTreeEntity<TEntity>));
var query = this.Repository.AsNoTracking();
query = query.Include();
if (model.Query != null)
@ -181,8 +181,9 @@ public class GenericController<TEntity, TModel, TListModel, TSearchModel, TImpor
{
try
{
var query = this.BuildQuery(model);
if (!includeAll)
var isTree = typeof(TEntity).IsAssignableTo(typeof(BaseTreeEntity<TEntity>));
var query = this.BuildQuery(model, isTree);
if (!includeAll && !isTree)
{
query = query.Skip(model.PageSize * (model.PageIndex - 1)).Take(model.PageSize);
}

8
docs/demo/src/WTA.Shared/Extensions/JsonSchemaExtensions.cs

@ -75,6 +75,10 @@ public static class JsonSchemaExtensions
if (!modelType.IsValueType && modelType != typeof(string))
{
schema.Add("type", "object");
if (modelType.GetBaseClasses().Any(o => o.IsGenericType && o.GetGenericTypeDefinition() == typeof(BaseTreeEntity<>)))
{
schema.Add("isTree", true);
}
var properties = new Dictionary<string, object>();
foreach (var propertyMetadata in meta.Properties)
{
@ -151,11 +155,11 @@ public static class JsonSchemaExtensions
path = string.Join('.', path.Split('.').Select(o => o.ToLowerCamelCase()));
schema.Add("navigation", path);
schema.Add("input", "select");
schema.Add("url", propertyName[..^2].ToSlugify());
schema.Add("url", defaultModelMetadata.ContainerType?.GetProperty(propertyName[..^2])?.PropertyType.Name.ToSlugify()!);
}
if (defaultModelMetadata.Attributes.Attributes.FirstOrDefault(o => o.GetType().IsGenericType && o.GetType().GetGenericTypeDefinition() == typeof(OneToManyAttribute<>)) is ITypeAttribute oneToManyAttribute)
{
schema.Add("oneToMany",$"{oneToManyAttribute.Type.Name}.{oneToManyAttribute.GetType().GetProperty("Property")?.GetValue(oneToManyAttribute)??defaultModelMetadata.PropertyName}");
schema.Add("oneToMany", $"{oneToManyAttribute.Type.Name}.{oneToManyAttribute.GetType().GetProperty("Property")?.GetValue(oneToManyAttribute) ?? defaultModelMetadata.PropertyName}");
}
if (defaultModelMetadata.Attributes.Attributes.FirstOrDefault(o => o.GetType() == typeof(ScaffoldColumnAttribute)) is ScaffoldColumnAttribute scaffoldColumnAttribute
&& !scaffoldColumnAttribute.Scaffold)

7
docs/demo/src/WTA/wwwroot/components/form/form-input.js

@ -42,7 +42,7 @@ export default {
/>
<template v-else-if="schema.type==='boolean'">
<el-select :disabled="getDisabled()" v-model="model[prop]" :placeholder="schema.title" v-if="schema.nullable">
<el-option prop="select" :value="null" :label="$t('select')" />
<el-option prop="select" value="" :label="$t('select')" />
<el-option prop="true" :value="true" :label="$t('true')" />
<el-option prop="false" :value="false" :label="$t('false')" />
</el-select>
@ -85,6 +85,9 @@ export default {
return schema.input ?? schema.type;
};
/*end*/
//options
const selectProps = ref({});
const selectValues = ref([]);
const options = ref([]);
if (props.schema.options) {
options.value = props.schema.options;
@ -102,6 +105,8 @@ export default {
getDisabled,
getInput,
dayjs,
selectProps,
selectValues,
options,
};
},

6
docs/demo/src/WTA/wwwroot/components/form/form-item.js

@ -1,10 +1,9 @@
import html from "html";
import { ref, reactive, watch } from "vue";
import AppFormInput from "./form-input.js";
import { defineAsyncComponent, ref, reactive, watch } from "vue";
export default {
name: "formItem",
components: { AppFormInput },
components: { AppFormInput: defineAsyncComponent(() => import("./form-input.js")) },
template: html`
<template v-if="showItem()">
<template v-if="schema.type==='object'"></template>
@ -19,7 +18,6 @@ export default {
<app-form-input :schema="schema" :prop="prop" v-model="model" :isReadOnly="mode==='details'" />
</el-form-item>
</template>
</template>
</template>
`,
props: ["modelValue", "mode", "parentSchema", "schema", "prop", "errors"],

5
docs/demo/src/WTA/wwwroot/components/form/index.js

@ -1,9 +1,8 @@
import html from "html";
import { ref, reactive, watch } from "vue";
import AppFormItem from "./form-item.js";
import { defineAsyncComponent, ref, reactive, watch } from "vue";
export default {
components: { AppFormItem },
components: { AppFormItem: defineAsyncComponent(() => import("./form-item.js")) },
name: "AppForm",
template: html`<el-form ref="formRef" :model="model" label-width="auto">
<template v-for="(value, prop) in schema.properties">

34
docs/demo/src/WTA/wwwroot/components/icon/index.js

@ -1,29 +1,35 @@
import html from "html";
import { onMounted, ref } from "vue";
const template = `<component v-if="name.indexOf('ep-')===0" :is="name" /> <v-else g v-html="svg" /> `;
export default {
template: html`<template v-if="name.indexOf('ep-')===0">
<component :is="name" />
</template>
<template v-else>
<g v-html="svg" />
</template> `,
props: {
name: {
default: "file",
},
},
template,
setup(props) {
const svg = ref("");
async setup(props) {
const svg = ref(null);
onMounted(async () => {
if (props.name.indexOf("ep-") !== 0) {
if (!props.name.startsWith("ep-")) {
try {
const response = await fetch(`./assets/icons/${props.name}.svg`);
if (response.ok && response.status === 200) {
svg.value = await response.text();
}
const url = `./assets/icons/${props.name}.svg`;
navigator.locks.request(url, async () => {
const response = await fetch(url);
if (response.ok && response.status === 200) {
svg.value = await response.text();
}
});
} catch (error) {
console.error(error);
}
if (!svg.value) {
const response = await fetch("./assets/icons/file.svg");
svg.value = await response.text();
if (!svg.value) {
svg.value = `<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M764.288 214.592 512 466.88 259.712 214.592a31.936 31.936 0 0 0-45.12 45.12L466.752 512 214.528 764.224a31.936 31.936 0 1 0 45.12 45.184L512 557.184l252.288 252.288a31.936 31.936 0 0 0 45.12-45.12L557.12 512.064l252.288-252.352a31.936 31.936 0 1 0-45.12-45.184z"></path></svg>`;
}
}
}
});

126
docs/demo/src/WTA/wwwroot/components/list/index.js

@ -1,19 +1,21 @@
import html, { getProp } from "html";
import AppForm from "../form/index.js";
import { get, post } from "../../request/index.js";
import { ref, reactive } from "vue";
import { defineAsyncComponent, ref, reactive, onMounted } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useI18n } from "vue-i18n";
import SvgIcon from "../../components/icon/index.js";
import { schemaToModel } from "../../utils/index.js";
import { listToTree, schemaToModel } from "../../utils/index.js";
import qs from "../../lib/qs/shim.js";
import AppFormInput from "../form/form-input.js";
import VueOfficeExcel from "@vue-office/excel";
import { camelCase, capitalize } from "lodash";
export default {
name: "AppList",
components: { AppForm, SvgIcon, AppFormInput, VueOfficeExcel },
components: {
AppForm: defineAsyncComponent(() => import("../form/index.js")),
SvgIcon: defineAsyncComponent(() => import("../../components/icon/index.js")),
AppFormInput: defineAsyncComponent(() => import("../form/form-input.js")),
VueOfficeExcel,
},
template: html`
<el-row>
<el-col>
@ -49,22 +51,22 @@ export default {
<el-scrollbar>
<el-table
ref="tableRef"
v-loading="tableLoading"
:v-loading="tableLoading"
:tree-props="treeProps"
:data="tableData"
@selection-change="handleSelectionChange"
@sort-change="sortChange"
:header-cell-class-name="getClass"
row-key="id"
table-layout="auto"
border
fit
:data="data.items"
@selection-change="handleSelectionChange"
@sort-change="sortChange"
:header-cell-class-name="getClass"
v-if="data.items"
>
<el-table-column fixed="left" type="selection" />
<el-table-column type="index" :label="$t('rowIndex')">
<template #default="scope"> {{ (data.pageIndex - 1) * data.pageSize + scope.$index + 1 }} </template>
</el-table-column>
<template v-for="(item,key) in tableSchema.items.properties">
<template v-for="(item,key) in tableSchema.properties">
<template v-if="key==='properties'">
<el-table-column :label="subKey" v-for="(subItem,subKey) in item.properties">
<template #default="scope">{{ scope.row[key][subKey] }} </template>
@ -126,7 +128,7 @@ export default {
<el-row>
<el-col>
<el-pagination
v-if="data.items&&data.pageSize<data.totalCount"
v-if="tableData.length&&data.pageSize<data.totalCount"
v-model:currentPage="data.pageIndex"
v-model:page-size="data.pageSize"
:total="data.totalCount"
@ -216,6 +218,9 @@ export default {
props: ["modelValue", "controller", "buttons"],
emits: ["command"],
async setup(props, context) {
const treeProps = reactive({
children: "children",
});
const tableRef = ref(null);
const columns = ref([]);
const filterDrawer = ref(false);
@ -230,13 +235,23 @@ export default {
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));
//Object.assign(data,prop.)
const data = ref({});
const sortColumns = ref(new Map());
const queryFromSchema = ref({});
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)
@ -245,32 +260,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 (
@ -280,35 +293,29 @@ 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["Id"];
// delete postData["items"];
const listData = (await post(url, postData)).data;
if (tableSchema.value.isTree) {
listData.items = listToTree(listData.items);
}
tableData.value = listData.items;
delete 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);
@ -383,7 +390,7 @@ export default {
editFormloading.value = false;
}
} else if (editFormMode.value === "details") {
load(indexUrl);
await load(indexUrl);
editFormMode.value = null;
dialogVisible.value = false;
}
@ -410,8 +417,18 @@ export default {
subDrawer.value = true;
}
};
await load(indexUrl);
onMounted(async () => {
const vm = (await get(indexUrl)).data;
const schema = vm.schema;
queryFromSchema.value = schema.properties.query;
tableSchema.value = schema.properties.items.items;
data.value = vm.model ?? schemaToModel(schema);
getSortModel(data.value);
getColumns(schema.properties.query);
await load(indexUrl);
});
return {
treeProps,
tableRef,
tableLoading,
columns,
@ -420,12 +437,11 @@ export default {
subDrawer,
dialogVisible,
selectedRows,
schema,
queryFromSchema,
tableSchema,
buttons,
data,
sortModel,
tableData,
getClass,
sortChange,
getProp,

36
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: `<div ref="tplRef"><div class="source" style="display:none;"><slot /></div><div class="markdown-body"></div></template>`,
template: html`<div ref="tplRef">
<div class="source" style="display:none;"><slot /></div>
<div class="markdown-body"></div>
</div>`,
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,
};
}
}
},
};

2
docs/demo/src/WTA/wwwroot/index.html

@ -69,4 +69,4 @@
<script type="module" src="./main.js"></script>
</body>
</html>
</html>

13
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`
<div class="flex items-center justify-between">
<div class="flex items-center justify-center">

14
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`<el-container>
<el-header><layout-header /></el-header>
<el-container>

7
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`<el-dropdown class="cursor-pointer" v-if="appStore.settings.enableLocale">
<span class="el-dropdown-link flex">
<el-icon :size="18">
<icon name="lang" />
<svg-icon name="lang" />
</el-icon>
</span>
<template #dropdown>

9
docs/demo/src/WTA/wwwroot/layouts/menu-item.js

@ -1,18 +1,17 @@
import html from "html";
import { reactive, watch } from "vue";
import Icon from "../components/icon/index.js";
import { defineAsyncComponent, reactive, watch } from "vue";
import { useRouter } from "vue-router";
export default {
name: "menuItem",
components: { Icon },
components: { SvgIcon: defineAsyncComponent(() => import("../components/icon/index.js")) },
template: html`<template v-if="!modelValue.meta.isHidden">
<el-sub-menu
:index="modelValue.meta.path"
v-if="modelValue.children&&modelValue.children.some(o=>!o.meta.isHidden)"
>
<template #title>
<el-icon><icon :name="modelValue.meta.icon??'folder'" /></el-icon>
<el-icon><svg-icon :name="modelValue.meta.icon??'folder'" /></el-icon>
<span>{{modelValue.meta.title}}</span>
</template>
<menu-item v-for="item in modelValue.children" v-model="item" />
@ -22,7 +21,7 @@ export default {
:index="modelValue.meta.isExternal?null:modelValue.meta.path"
@click.native="click(modelValue)"
>
<el-icon><icon :name="modelValue.meta.icon??file" /></el-icon>
<el-icon><svg-icon :name="modelValue.meta.icon??file" /></el-icon>
<template #title>
<span>{{modelValue.meta.title}}</span>
</template>

19
docs/demo/src/WTA/wwwroot/layouts/tabs.js

@ -1,12 +1,10 @@
import html from "html";
import { ref, nextTick } from "vue";
import { defineAsyncComponent, ref, nextTick } from "vue";
import { useRoute, onBeforeRouteUpdate, useRouter } from "vue-router";
import Icon from "../components/icon/index.js";
import { useAppStore } from "../store/index.js";
import MenuItem from "./menu-item.js";
export default {
components: { Icon, MenuItem },
components: { SvgIcon: defineAsyncComponent(() => import("../components/icon/index.js")) },
template: html`<el-tabs
v-model="model"
type="border-card"
@ -24,23 +22,24 @@ export default {
@visible-change="showContextMenu(index, $event)"
>
<span class="inline-flex items-center">
<el-icon><icon v-if="item.meta.icon" :name="item.meta.icon" /></el-icon>
<el-icon><svg-icon v-if="item.meta.icon" :name="item.meta.icon" /></el-icon>
{{ item.meta?.title ?? item.fullPath }}
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="refresh(index)"><i-ep-refresh />刷新</el-dropdown-item>
<el-dropdown-item @click="refresh(index)">
<el-icon><ep-refresh /></el-icon><span></span>
</el-dropdown-item>
<el-dropdown-item :disabled="index === 0" @click="removeLeft(index)">
<i-ep-back />关闭左侧
<el-icon><ep-back /></el-icon><span></span>
</el-dropdown-item>
<el-dropdown-item :disabled="index === appStore.routes.length - 1" @click="removeRight(index)">
<i-ep-right />关闭右侧
<el-icon><ep-right /></el-icon><span></span>
</el-dropdown-item>
<el-dropdown-item
:disabled="index === 0 && index === appStore.routes.length - 1"
@click="removeOthers(index)"
>
<i-ep-switch />
><el-icon><ep-switch /></el-icon><span></span>
</el-dropdown-item>
</el-dropdown-menu>
</template>

2
docs/demo/src/WTA/wwwroot/main.js

@ -1,5 +1,5 @@
import { createApp } from "vue";
import style from './mixins/style.js';
import style from "./mixins/style.js";
import store, { useAppStore } from "./store/index.js";
import router from "./router/index.js";
import ElementPlus from "element-plus";

2
docs/demo/src/WTA/wwwroot/router/index.js

@ -93,7 +93,7 @@ const reset = (list, parent = null) => {
meta: o.meta,
};
if (o.type === "Resource") {
item.component = import(`../views/${o.component ? o.component : "list"}.js`);
item.component = () => import(`../views/${o.component ? o.component : "list"}.js`);
}
item.meta.controller = item.path;
item.meta.path = `${parent === null ? "/" : parent.meta.path + "/"}${item.path}`;

1
docs/demo/src/WTA/wwwroot/store/app.js

@ -11,6 +11,7 @@ const useAppStore = defineStore("app", {
isMenuCollapse: false,
isRefreshing: false,
routes: [],
cache: new Map(),
};
const localSettings = JSON.parse(localStorage.getItem("settings") ?? "{}");
Object.assign(state.settings, localSettings);

Loading…
Cancel
Save