Browse Source

update

pull/1/head
wanggang 2 years ago
parent
commit
aa7cb93754
  1. 1
      .gitignore
  2. 1
      docs/demo/src/WTA.Shared/Application/PaginationModel.cs
  3. 9
      docs/demo/src/WTA.Shared/Application/QueryFilter.cs
  4. 17
      docs/demo/src/WTA.Shared/Controllers/GenericController.cs
  5. 8
      docs/demo/src/WTA.Shared/Extensions/JsonSchemaExtensions.cs
  6. 14
      docs/demo/src/WTA.Shared/Extensions/StringExtensions.cs
  7. 2
      docs/demo/src/WTA/wwwroot/components/form/index.js
  8. 2
      docs/demo/src/WTA/wwwroot/components/icon/index.js
  9. 465
      docs/demo/src/WTA/wwwroot/components/list/index.js
  10. 4
      docs/demo/src/WTA/wwwroot/layouts/tabs.js
  11. 2
      docs/demo/src/WTA/wwwroot/signalr/index.js
  12. 5
      docs/demo/src/WTA/wwwroot/styles/site.css
  13. BIN
      docs/结算系统寄售库变动及表结构整理.xlsx

1
.gitignore

@ -8,6 +8,7 @@ dist/
.vs/ .vs/
bin/ bin/
obj/ obj/
[Ll]ogs/
*.suo *.suo
*.user *.user
*.db *.db

1
docs/demo/src/WTA.Shared/Application/PaginationModel.cs

@ -21,4 +21,5 @@ public class PaginationModel<TSearchModel, TListModel>
public List<TListModel> Items { get; set; } = new List<TListModel>(); public List<TListModel> Items { get; set; } = new List<TListModel>();
public bool QueryAll { get; set; } public bool QueryAll { get; set; }
public TSearchModel Query { get; set; } = Activator.CreateInstance<TSearchModel>(); public TSearchModel Query { get; set; } = Activator.CreateInstance<TSearchModel>();
public List<QueryFilter> Filters { get; set; } = new List<QueryFilter>();
} }

9
docs/demo/src/WTA.Shared/Application/QueryFilter.cs

@ -0,0 +1,9 @@
namespace WTA.Shared.Application;
public class QueryFilter
{
public string Property { get; set; } = null!;
public string Operator { get; set; } = null!;
public string Value { get; set; } = null!;
public string Logic { get; set; } = null!;
}

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

@ -1,3 +1,4 @@
using System.Globalization;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@ -40,6 +41,10 @@ public class GenericController<TEntity, TModel, TListModel, TSearchModel, TImpor
{ {
var isTree = typeof(TEntity).IsAssignableTo(typeof(BaseTreeEntity<TEntity>)); var isTree = typeof(TEntity).IsAssignableTo(typeof(BaseTreeEntity<TEntity>));
var query = BuildQuery(model, isTree); var query = BuildQuery(model, isTree);
foreach (var item in model.Filters)
{
query = query.Where(string.Format(CultureInfo.InvariantCulture, item.Operator, item.Property.ToPascalCase()), item.Value);
}
model.TotalCount = query.Count(); model.TotalCount = query.Count();
if (!string.IsNullOrEmpty(model.OrderBy)) if (!string.IsNullOrEmpty(model.OrderBy))
{ {
@ -76,6 +81,12 @@ public class GenericController<TEntity, TModel, TListModel, TSearchModel, TImpor
return query; return query;
} }
[HttpGet]
public IActionResult Details()
{
return Json(typeof(TModel).GetMetadataForType());
}
[HttpPost, Order(-2), HtmlClass("el-button--primary")] [HttpPost, Order(-2), HtmlClass("el-button--primary")]
public virtual IActionResult Details(Guid id) public virtual IActionResult Details(Guid id)
{ {
@ -87,7 +98,11 @@ public class GenericController<TEntity, TModel, TListModel, TSearchModel, TImpor
[HttpGet] [HttpGet]
public IActionResult Create() public IActionResult Create()
{ {
return Json(typeof(TModel).GetViewModel()); return Json(new
{
Schema = typeof(TModel).GetMetadataForType(),
Model = Activator.CreateInstance<TModel>(),
});
} }
[HttpPost, Multiple, Order(-3), HtmlClass("el-button--success")] [HttpPost, Multiple, Order(-3), HtmlClass("el-button--success")]

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

@ -133,8 +133,8 @@ public static class JsonSchemaExtensions
} }
schema.AddNotNull("description", meta.Description); schema.AddNotNull("description", meta.Description);
schema.AddNotNull("format", meta.DataTypeName?.ToLowerCamelCase()); schema.AddNotNull("format", meta.DataTypeName?.ToCamelCase());
schema.AddNotNull("input", meta.TemplateHint?.ToLowerCamelCase()); schema.AddNotNull("input", meta.TemplateHint?.ToCamelCase());
if (meta.TemplateHint == "select" && meta.IsEnumerableType && modelType.IsGenericType) if (meta.TemplateHint == "select" && meta.IsEnumerableType && modelType.IsGenericType)
{ {
schema.TryAdd("url", modelType.GetGenericArguments().First().Name.ToSlugify()); schema.TryAdd("url", modelType.GetGenericArguments().First().Name.ToSlugify());
@ -152,7 +152,7 @@ public static class JsonSchemaExtensions
if (defaultModelMetadata.Attributes.Attributes.FirstOrDefault(o => o.GetType() == typeof(NavigationAttribute)) is NavigationAttribute navigationAttribute) if (defaultModelMetadata.Attributes.Attributes.FirstOrDefault(o => o.GetType() == typeof(NavigationAttribute)) is NavigationAttribute navigationAttribute)
{ {
var path = navigationAttribute.Property ?? $"{propertyName[..^2]}.Name"; var path = navigationAttribute.Property ?? $"{propertyName[..^2]}.Name";
path = string.Join('.', path.Split('.').Select(o => o.ToLowerCamelCase())); path = string.Join('.', path.Split('.').Select(o => o.ToCamelCase()));
schema.Add("navigation", path); schema.Add("navigation", path);
schema.Add("input", "select"); schema.Add("input", "select");
schema.Add("url", defaultModelMetadata.ContainerType?.GetProperty(propertyName[..^2])?.PropertyType.Name.ToSlugify()!); schema.Add("url", defaultModelMetadata.ContainerType?.GetProperty(propertyName[..^2])?.PropertyType.Name.ToSlugify()!);
@ -257,7 +257,7 @@ public static class JsonSchemaExtensions
else if (attribute is CompareAttribute compare)//?? else if (attribute is CompareAttribute compare)//??
{ {
rule.Add("validator", "compare"); rule.Add("validator", "compare");
rule.Add("compare", compare.OtherProperty.ToLowerCamelCase()); rule.Add("compare", compare.OtherProperty.ToCamelCase());
} }
else if (attribute is MinLengthAttribute minLength) else if (attribute is MinLengthAttribute minLength)
{ {

14
docs/demo/src/WTA.Shared/Extensions/StringExtensions.cs

@ -57,7 +57,19 @@ public static class StringExtensions
return input.EndsWith(end) ? input[..^end.Length] : input; return input.EndsWith(end) ? input[..^end.Length] : input;
} }
public static string ToLowerCamelCase(this string input) public static string ToPascalCase(this string value)
{
if (!string.IsNullOrEmpty(value))
{
var sb = new StringBuilder(value);
sb[0] = char.ToUpperInvariant(sb[0]);
return sb.ToString();
}
return value;
}
public static string ToCamelCase(this string input)
{ {
if (string.IsNullOrEmpty(input) || !char.IsUpper(input[0])) if (string.IsNullOrEmpty(input) || !char.IsUpper(input[0]))
{ {

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

@ -55,7 +55,7 @@ export default {
}); });
//} //}
} catch (error) { } catch (error) {
console.error(error); console.log(error);
} finally { } finally {
loading.value = false; loading.value = false;
} }

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

@ -24,7 +24,7 @@ export default {
svg.value = await response.text(); svg.value = await response.text();
} }
} catch (error) { } catch (error) {
console.error(error); console.log(error);
if (!svg.value) { 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>`; 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>`;
} }

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

@ -17,192 +17,137 @@ export default {
VueOfficeExcel, VueOfficeExcel,
}, },
template: html` template: html`
<el-row> <div v-loading="tableLoading">
<el-col> <el-row>
<app-form <el-col>
inline <app-form
mode="query" inline
label-position="left" mode="query"
:schema="queryFromSchema" label-position="left"
v-model="data.query" :schema="queryFromSchema"
@submit="load" v-model="data.query"
:hideButton="true" @submit="load"
:isQueryForm="true" :hideButton="true"
v-if="queryFromSchema" :isQueryForm="true"
/> v-if="queryFromSchema"
</el-col> />
</el-row> </el-col>
<el-row style="padding-bottom:20px;"> </el-row>
<el-col> <el-row style="padding-bottom:20px;">
<template v-for="item in buttons"> <el-col>
<el-button <template v-for="item in buttons">
:class="item.meta.htmlClass??'el-button--primary'" <el-button
v-if="item.meta.isTop" :class="item.meta.htmlClass??'el-button--primary'"
@click="click(item,selectedRows)" v-if="item.meta.isTop"
> @click="click(item,selectedRows)"
<el-icon v-if="item.meta.icon"><svg-icon :name="item.meta.icon" /></el-icon> >
<span>{{item.meta.title}}</span> <el-icon v-if="item.meta.icon"><svg-icon :name="item.meta.icon" /></el-icon>
<span>{{item.meta.title}}</span>
</el-button>
</template>
<el-button @click="click('filter',selectedRows)">
<el-icon><ep-filter /></el-icon>
<span>{{$t('筛选')}}</span>
</el-button> </el-button>
</template> <slot name="tableButtons" :rows="selectedRows"></slot>
<el-button @click="queryDialog=true"> </el-col>
<el-icon><ep-filter /></el-icon> </el-row>
<span>{{$t('高级筛选')}}</span> <el-row>
</el-button> <el-col>
<slot name="tableButtons" :rows="selectedRows"></slot> <el-scrollbar>
</el-col> <el-table
</el-row> ref="tableRef"
<el-row> :tree-props="treeProps"
<el-col> :data="tableData"
<el-scrollbar> @selection-change="handleSelectionChange"
<el-table @sort-change="sortChange"
ref="tableRef" :header-cell-class-name="getClass"
:v-loading="tableLoading" row-key="id"
:tree-props="treeProps" table-layout="auto"
:data="tableData" border
@selection-change="handleSelectionChange" fit
@sort-change="sortChange" >
:header-cell-class-name="getClass" <el-table-column fixed="left" type="selection" />
row-key="id" <el-table-column type="index" :label="$t('rowIndex')">
table-layout="auto" <template #default="scope"> {{ (data.pageIndex - 1) * data.pageSize + scope.$index + 1 }} </template>
border </el-table-column>
fit <template v-for="(item,key) in tableSchema.properties">
> <template v-if="key==='properties'">
<el-table-column fixed="left" type="selection" /> <el-table-column :label="subKey" v-for="(subItem,subKey) in item.properties">
<el-table-column type="index" :label="$t('rowIndex')"> <template #default="scope">{{ scope.row[key][subKey] }} </template>
<template #default="scope"> {{ (data.pageIndex - 1) * data.pageSize + scope.$index + 1 }} </template> </el-table-column>
</el-table-column> </template>
<template v-for="(item,key) in tableSchema.properties"> <template v-else-if="item.navigation">
<template v-if="key==='properties'"> <el-table-column :prop="key" :label="item.title">
<el-table-column :label="subKey" v-for="(subItem,subKey) in item.properties"> <template #default="scope">{{getProp(scope.row,item.navigation)}}</template>
<template #default="scope">{{ scope.row[key][subKey] }} </template> </el-table-column>
</el-table-column> </template>
</template> <template v-else-if="item.oneToMany">
<template v-else-if="item.navigation"> <el-table-column :prop="key" :label="item.title">
<el-table-column :prop="key" :label="item.title">
<template #default="scope">{{getProp(scope.row,item.navigation)}}</template>
</el-table-column>
</template>
<template v-else-if="item.oneToMany">
<el-table-column :prop="key" :label="item.title">
<template #default="scope">
<el-link type="primary" @click="showList(scope.row[key],item.oneToMany)">
<app-form-input :isReadOnly="true" :schema="item" :prop="key" v-model="scope.row" />
</el-link>
</template>
</el-table-column>
</template>
<template v-else>
<template v-if="showColumn(item,key)">
<el-table-column :prop="key" sortable="custom" :sort-orders="['descending', 'ascending', null]">
<template #header="scope">{{item.title}}</template>
<template #default="scope"> <template #default="scope">
<app-form-input :isReadOnly="true" :schema="item" :prop="key" v-model="scope.row" /> <el-link type="primary" @click="showList(scope.row[key],item.oneToMany)">
<app-form-input :isReadOnly="true" :schema="item" :prop="key" v-model="scope.row" />
</el-link>
</template> </template>
</el-table-column> </el-table-column>
</template> </template>
</template> <template v-else>
</template> <template v-if="showColumn(item,key)">
<slot name="columns"></slot> <el-table-column :prop="key" sortable="custom" :sort-orders="['descending', 'ascending', null]">
<el-table-column fixed="right"> <template #header="scope">{{item.title}}</template>
<template #header> <template #default="scope">
<el-button @click="filterDrawer = true"> <app-form-input :isReadOnly="true" :schema="item" :prop="key" v-model="scope.row" />
{{$t('operations')}} </template>
<el-icon class="el-icon--right"><ep-filter /></el-icon> </el-table-column>
</el-button>
</template>
<template #default="scope">
<div class="flex">
<template v-for="item in buttons">
<el-button
:class="item.meta.htmlClass??'el-button--primary'"
v-if="!item.meta.isTop"
@click="click(item,[scope.row])"
>
<el-icon v-if="item.meta.icon"><svg-icon :name="item.meta.icon" /></el-icon>
<span>{{item.meta.title}}</span>
</el-button>
</template> </template>
<slot name="rowButtons" :rows="[scope.row]"></slot> </template>
</div>
</template> </template>
</el-table-column> <slot name="columns"></slot>
</el-table> <el-table-column fixed="right">
</el-scrollbar> <template #header>
</el-col> <el-button @click="filterDrawer = true">
</el-row> {{$t('operations')}}
<el-row> <el-icon class="el-icon--right"><ep-filter /></el-icon>
<el-col> </el-button>
<el-pagination </template>
v-if="tableData.length&&data.pageSize<data.totalCount" <template #default="scope">
v-model:currentPage="data.pageIndex" <div class="flex">
v-model:page-size="data.pageSize" <template v-for="item in buttons">
:total="data.totalCount" <el-button
:page-sizes="[20, 50, 100]" :class="item.meta.htmlClass??'el-button--primary'"
class="justify-end" v-if="!item.meta.isTop"
:background="true" @click="click(item,[scope.row])"
layout="total, sizes, prev, pager, next, jumper" >
@size-change="onPageSizeChange" <el-icon v-if="item.meta.icon"><svg-icon :name="item.meta.icon" /></el-icon>
@current-change="onPageIndexChange" <span>{{item.meta.title}}</span>
style="margin-top:20px" </el-button>
/> </template>
</el-col> <slot name="rowButtons" :rows="[scope.row]"></slot>
</el-row> </div>
<el-dialog v-model="queryDialog" align-center destroy-on-close> </template>
<template #header> <span class="el-dialog__title"> {{$t('高级筛选')}} </span> </template> </el-table-column>
<el-row> </el-table>
<el-col style="max-height:calc(100vh - 180px );">
<el-scrollbar>
<el-row :gutter="20" v-for="(item,index) in queryList" style="margin-top:20px;">
<el-col :span="6">
<el-select v-model="item.property" :placeholder="$t('字段')">
<el-option v-for="(value, prop) in queryFromSchema.properties">{{value.title}}</el-option>
</el-select>
</el-col>
<el-col :span="6">
<el-select v-model="item.operator" :placeholder="$t('操作符')">
<el-option>{{$t('等于')}}</el-option>
<el-option>{{$t('不等于')}}</el-option>
<el-option>{{$t('大于')}}</el-option>
<el-option>{{$t('大于等于')}}</el-option>
<el-option>{{$t('小于')}}</el-option>
<el-option>{{$t('小于等于')}}</el-option>
<el-option>{{$t('包含')}}</el-option>
<el-option>{{$t('不包含')}}</el-option>
</el-select>
</el-col>
<el-col :span="6">
<el-input v-model="item.value" :placeholder="$t('值')" />
</el-col>
<el-col :span="4">
<el-select v-model="item.logical" :placeholder="$t('关系')">
<el-option>{{$t('且')}}</el-option>
<el-option>{{$t('或')}}</el-option>
</el-select>
</el-col>
<el-col :span="2">
<el-space style="height:32px">
<el-icon class="cursor-pointer" @click="queryList.splice(index, 1)">
<ep-close />
</el-icon>
</el-space>
</el-col>
</el-row>
<el-row>
<el-col>
<el-space style="height:32px;">
<el-icon class="cursor-pointer" @click="pushQueryList"><ep-plus /></el-icon>
</el-space>
</el-col>
</el-row>
</el-scrollbar> </el-scrollbar>
</el-col> </el-col>
</el-row> </el-row>
<template #footer> <el-row>
<span class="dialog-footer"> <el-col>
<el-button type="primary" @click="queryDialog=false"> {{$t('confirm')}} </el-button> <el-pagination
</span> v-if="tableData.length&&data.pageSize<data.totalCount"
</template> v-model:currentPage="data.pageIndex"
</el-dialog> v-model:page-size="data.pageSize"
:total="data.totalCount"
:page-sizes="[20, 50, 100]"
class="justify-end"
:background="true"
layout="total, sizes, prev, pager, next, jumper"
@size-change="onPageSizeChange"
@current-change="onPageIndexChange"
style="margin-top:20px"
/>
</el-col>
</el-row>
</div>
<el-drawer v-model="filterDrawer" destroy-on-close @close="tableRef.doLayout()"> <el-drawer v-model="filterDrawer" destroy-on-close @close="tableRef.doLayout()">
<template #header> <span class="el-dialog__title"> {{$t('filter')}} </span> </template> <template #header> <span class="el-dialog__title"> {{$t('filter')}} </span> </template>
<el-scrollbar> <el-scrollbar>
@ -245,23 +190,100 @@ export default {
</span> </span>
</template> </template>
</el-drawer> </el-drawer>
<el-dialog v-model="dialogVisible" align-center destroy-on-close width="700"> <el-dialog v-model="dialogVisible" align-center destroy-on-close v-loading="editFormloading">
<template #header> <span class="el-dialog__title"> {{editFormTitle}} </span> </template> <template #header> <span class="el-dialog__title"> {{editFormTitle}} </span> </template>
<el-row> <el-row>
<el-col style="max-height:calc(100vh - 180px );"> <el-col style="max-height:calc(100vh - 180px );min-height:100%;">
<el-scrollbar> <el-scrollbar>
<app-form <template v-if="editFormMode==='create'||editFormMode==='update'||editFormMode==='details'">
v-loading="editFormloading" <app-form
:disabled="editFormMode==='details'" :disabled="editFormMode==='details'"
:mode="editFormMode" :mode="editFormMode"
ref="editFormRef" ref="editFormRef"
inline inline
label-position="left" label-position="left"
:hideButton="true" :hideButton="true"
:schema="editFormSchema" :schema="editFormSchema"
v-model="editFormModel" v-model="editFormModel"
v-if="editFormMode!=='import'" v-if="editFormSchema&&editFormMode"
/> />
</template>
<template v-else-if="editFormMode==='export'">
<el-form :model="exportModel" style="height:100%;">
<el-form-item :label="$t('全部')">
<el-switch v-model="exportModel.includeAll" />
</el-form-item>
<el-form-item :label="$t('已删除')">
<el-switch v-model="exportModel.includeDeleted" />
</el-form-item>
</el-form>
</template>
<template v-else-if="editFormMode==='import'">
<el-form :model="exportModel" style="height:100%;">
<el-form-item :label="$t('部分成功')">
<el-switch v-model="exportModel.includeAll" />
</el-form-item>
<el-form-item :label="$t('只更新')">
<el-switch v-model="exportModel.includeDeleted" />
</el-form-item>
</el-form>
</template>
<template v-else-if="editFormMode==='filter'">
<el-form :model="queryList" inline>
<el-row v-for="(item,index) in queryList" style="padding:10px;">
<el-col :span="6">
<el-select v-model="item.property" :placeholder="$t('字段')">
<el-option
v-for="(value, prop) in queryFromSchema.properties"
:value="prop"
:label="value.title"
/>
</el-select>
</el-col>
<el-col :span="6">
<el-select v-model="item.operator" :placeholder="$t('操作符')">
<el-option value="{0}=@0" :label="$t('等于')" />
<el-option value="{0}!=@0" :label="$t('不等于')" />
<el-option value="{0}>@0" :label="$t('大于')" />
<el-option value="{0}>=@0" :label="$t('大于等于')" />
<el-option value="{0}<@0" :label="$t('小于')" />
<el-option value="{0}<=@0" :label="$t('小于等于')" />
<el-option value="{0}.Contains(@0)" :label="$t('包含')" />
<el-option value="{0}.StartsWith(@0)" :label="$t('开始于')" />
<el-option value="{0}.StartsWith(@0)" :label="$t('结束于')" />
</el-select>
</el-col>
<el-col :span="6">
<el-input v-model="item.value" :placeholder="$t('值')" />
</el-col>
<el-col :span="4">
<el-select v-model="item.logic" :placeholder="$t('关系')">
<el-option value="and" :label="$t('且')" />
<el-option value="or" :label="$t('或')" />
</el-select>
</el-col>
<el-col :span="2">
<el-button circle @click="queryList.splice(index, 1)" style="margin-left:10px;">
<template #icon>
<ep-close />
</template>
</el-button>
</el-col>
</el-row>
<el-row>
<el-col>
<el-button circle @click="pushQueryList" style="margin-left:10px;">
<template #icon>
<ep-plus />
</template>
</el-button>
</el-col>
</el-row>
</el-form>
</template>
<template v-else>
<slot :name="editFormMode"></slot>
</template>
</el-scrollbar> </el-scrollbar>
</el-col> </el-col>
</el-row> </el-row>
@ -287,7 +309,7 @@ export default {
const filterDrawer = ref(false); const filterDrawer = ref(false);
const subDrawer = ref(false); const subDrawer = ref(false);
const subListQuery = ref({}); const subListQuery = ref({});
const tableLoading = ref(false); const tableLoading = ref(true);
const selectedRows = ref([]); const selectedRows = ref([]);
const dialogVisible = ref(false); const dialogVisible = ref(false);
const route = useRoute(); const route = useRoute();
@ -301,15 +323,14 @@ export default {
const schema = ref(props.schema); const schema = ref(props.schema);
const queryFromSchema = ref(null); const queryFromSchema = ref(null);
const queryList = ref([]); const queryList = ref([]);
const queryDialog = ref(false);
const tableSchema = ref({}); const tableSchema = ref({});
const tableData = ref([]); const tableData = ref([]);
const editFormRef = ref(null); const editFormRef = ref(null);
const editFormloading = ref(false); const editFormloading = ref(false);
const editFormMode = ref(null); const editFormMode = ref(null);
const editFormTitle = ref(""); const editFormTitle = ref("");
const editFormSchema = reactive({}); const editFormSchema = ref(null);
const editFormModel = reactive({}); const editFormModel = ref(null);
const exportModel = reactive({ const exportModel = reactive({
includeAll: false, includeAll: false,
includeDeleted: false, includeDeleted: false,
@ -363,6 +384,7 @@ export default {
tableLoading.value = true; tableLoading.value = true;
try { try {
const postData = JSON.parse(JSON.stringify(data.value)); const postData = JSON.parse(JSON.stringify(data.value));
postData.filters = queryList.value.filter((o) => o.property && o.value);
delete postData.query["items"]; delete postData.query["items"];
delete postData.query["id"]; delete postData.query["id"];
const listData = (await post(url, postData)).data; const listData = (await post(url, postData)).data;
@ -380,33 +402,28 @@ export default {
const onPageIndexChange = async () => await load(indexUrl); const onPageIndexChange = async () => await load(indexUrl);
const onPageSizeChange = async () => await load(indexUrl); const onPageSizeChange = async () => await load(indexUrl);
const click = async (item, rows) => { const click = async (item, rows) => {
editFormMode.value = item.path; editFormMode.value = item.path ?? item;
context.emit("command", item, rows); context.emit("command", item, rows);
if (item.path === "index") { if (item.path === "index") {
//list //list
await load(indexUrl); await load(indexUrl);
} else if (item.path === "details") { } else if (item.path === "details") {
//details //details
const detailsUrl = `${baseUrl}/${item.path}?${qs.stringify({ id: rows[0].id })}`; const url = `${baseUrl}/${item.path}?${qs.stringify({ id: rows[0].id })}`;
Object.assign(editFormSchema, schema.value.properties.items.items); editFormSchema.value = (await get(url)).data;
Object.assign(editFormModel, (await post(detailsUrl)).data); editFormModel.value = (await post(url)).data;
editFormTitle.value = `${t("details")}${schema.value?.title}`; editFormTitle.value = `${schema.value?.title}${t("details")}`;
dialogVisible.value = true; dialogVisible.value = true;
} else if (item.path === "create") { } else if (item.path === "create" || item.path === "update") {
//create //create
const url = `${baseUrl}/${item.path}`; let url = `${baseUrl}/${item.path}`;
if (item.path === "update") {
url = `${url}?${qs.stringify({ id: rows[0].id })}`;
}
const vm = (await get(url)).data; const vm = (await get(url)).data;
Object.assign(editFormSchema, schema.value); editFormSchema.value = vm.schema;
Object.assign(editFormModel, vm.model); editFormModel.value = vm.model;
editFormTitle.value = `${t("create")}${schema.value?.title}`; editFormTitle.value = `${t(item.path)}${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, schema.value);
Object.assign(editFormModel, vm.model);
editFormTitle.value = `${t("update")}${schema.value?.title}`;
dialogVisible.value = true; dialogVisible.value = true;
} else if (item.path === "delete") { } else if (item.path === "delete") {
//delete //delete
@ -421,14 +438,15 @@ export default {
await load(indexUrl); await load(indexUrl);
} else if (item.path === "export") { } else if (item.path === "export") {
//export //export
const url = `${baseUrl}/${item.path}`; dialogVisible.value = true;
const exportUrl = `${url}?${qs.stringify(exportModel)}`;
await load(exportUrl);
} else if (item.path === "import") { } else if (item.path === "import") {
//import //import
const url = `${baseUrl}/${item.path}`; const url = `${baseUrl}/${item.path}`;
editFormTitle.value = `${t("import")}${schema.value?.title}`; editFormTitle.value = `${t("import")}${schema.value?.title}`;
dialogVisible.value = true; dialogVisible.value = true;
} else if (item === "filter") {
editFormTitle.value = t("自定义查询");
dialogVisible.value = true;
} }
}; };
const submit = async () => { const submit = async () => {
@ -448,7 +466,7 @@ export default {
} }
} }
} catch (error) { } catch (error) {
console.error(error); console.log(error);
} finally { } finally {
editFormloading.value = false; editFormloading.value = false;
} }
@ -456,6 +474,14 @@ export default {
await load(indexUrl); await load(indexUrl);
editFormMode.value = null; editFormMode.value = null;
dialogVisible.value = false; dialogVisible.value = false;
} else if (editFormMode.value === "export") {
const url = `${baseUrl}/${item.path}?${qs.stringify(exportModel)}`;
// await load(exportUrl);
} else if (editFormMode.value === "filter") {
alert(JSON.stringify(queryList.value));
//const url = `${baseUrl}/${item.path}?${qs.stringify(exportModel)}`;
// await load(exportUrl);
dialogVisible.value = false;
} }
}; };
const showList = (value, nav) => { const showList = (value, nav) => {
@ -483,12 +509,13 @@ export default {
const pushQueryList = () => { const pushQueryList = () => {
queryList.value.push({ queryList.value.push({
property: "", property: "",
operator: "等于", operator: "{0}=@0",
value: "", value: "",
logical: "", logic: "or",
}); });
}; };
onMounted(async () => { onMounted(async () => {
pushQueryList();
const vm = (await get(indexUrl)).data; const vm = (await get(indexUrl)).data;
schema.value = vm.schema; schema.value = vm.schema;
queryFromSchema.value = vm.schema.properties.query; queryFromSchema.value = vm.schema.properties.query;
@ -512,7 +539,6 @@ export default {
dialogVisible, dialogVisible,
selectedRows, selectedRows,
queryFromSchema, queryFromSchema,
queryDialog,
queryList, queryList,
tableSchema, tableSchema,
buttons, buttons,
@ -522,6 +548,7 @@ export default {
sortChange, sortChange,
getProp, getProp,
editFormRef, editFormRef,
editFormloading,
editFormMode, editFormMode,
editFormTitle, editFormTitle,
editFormSchema, editFormSchema,

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

@ -65,6 +65,10 @@ export default {
.router-tab .el-tabs__content { .router-tab .el-tabs__content {
display: none; display: none;
} }
.router-tab .el-icon {
margin-right: 5px;
}
</style> </style>
`, `,
setup() { setup() {

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

@ -22,7 +22,7 @@ const connect = async () => {
console.log("signalr connected"); console.log("signalr connected");
}) })
.catch(function (error) { .catch(function (error) {
console.error(error); console.log(error);
//setTimeout(connect, 5000); //setTimeout(connect, 5000);
}); });
} }

5
docs/demo/src/WTA/wwwroot/styles/site.css

@ -103,16 +103,13 @@ a.logo {
white-space: nowrap; white-space: nowrap;
} }
.el-icon {
margin-right: 5px;
}
.el-dialog__header, .el-dialog__header,
.el-dialog__footer, .el-dialog__footer,
.el-drawer__header, .el-drawer__header,
.el-drawer__footer { .el-drawer__footer {
height: var(--header); height: var(--header);
padding: 15px; padding: 15px;
margin: 0;
} }
.el-dialog__header, .el-dialog__header,

BIN
docs/结算系统寄售库变动及表结构整理.xlsx

Binary file not shown.
Loading…
Cancel
Save