😎1、同步代码生成模板 2、修复库表管理里面生成实体错误

This commit is contained in:
zuohuaijun 2025-09-14 22:56:08 +08:00
parent 0a01141fef
commit 8663139322
29 changed files with 2428 additions and 4899 deletions

View File

@ -11,12 +11,12 @@ public class TableEntityEngine : ViewEngineModel
/// <summary>
/// 作者
/// </summary>
public string AuthorName { get; set; } = "喵你个汪呀";
public string AuthorName { get; set; } = "Admin.NET";
/// <summary>
/// 邮箱
/// </summary>
public string Email { get; set; } = "jason-dom@qq.com";
public string Email { get; set; } = "Admin.NET@qq.com";
/// <summary>
/// 命名空间

View File

@ -11,12 +11,12 @@ public class TableSeedDataEngine : ViewEngineModel
/// <summary>
/// 作者
/// </summary>
public string AuthorName { get; set; } = "喵你个汪呀";
public string AuthorName { get; set; } = "Admin.NET";
/// <summary>
/// 邮箱
/// </summary>
public string Email { get; set; } = "jason-dom@qq.com";
public string Email { get; set; } = "Admin.NET@qq.com";
/// <summary>
/// 命名空间

View File

@ -52,7 +52,6 @@ public class TableEntityCodeGenStrategy : CodeGenEntityStrategyBase<CreateEntity
: dbTableInfo.Description,
TableFields = dbColumnInfos
};
var result = await RenderAsync(_template, (context, builder) => _viewEngine.RunCompile(context, engine, builder));
result.OutPath = Path.Combine(Path.Combine(new DirectoryInfo(App.WebHostEnvironment.ContentRootPath).Parent!.FullName, input.Position), result.OutPath.Replace("{ModuleName}", input.EntityName));
return [result];

File diff suppressed because it is too large Load Diff

View File

@ -1,30 +0,0 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace @Model.NameSpace;
/// <summary>
/// @(@Model.BusName)输出参数
/// </summary>
public class @(@Model.ClassName)Dto
{
@foreach (var column in Model.TableField){
if(@column.EffectType == "ForeignKey" && @column.FkEntityName != "" && @column.FkColumnName != ""){
@:/// <summary>
@:/// @column.ColumnComment
@:/// </summary>
@:public @(@column.FkColumnNetType) @(@column.PropertyName)@(@column.FkColumnName) { get; set; }
@:
}
}
@foreach (var column in Model.TableField){
@:/// <summary>
@:/// @column.ColumnComment
@:/// </summary>
@:public @column.NetType @column.PropertyName { get; set; }
@:
}
}

View File

@ -4,9 +4,11 @@
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
@if(@Model.BaseClassName!=""){
@:using Admin.NET.Core;
}
////////////////////////////////////////////////////////////////////
// 作者:@(Model.AuthorName ?? "Admin.NET")
// 时间:@(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
// 邮箱:@(Model.Email ?? "Admin.NET@qq.com")
////////////////////////////////////////////////////////////////////
namespace @Model.NameSpace;
@ -14,86 +16,75 @@ namespace @Model.NameSpace;
/// @(@Model.Description)
/// </summary>
[SugarTable(null, "@(@Model.Description)")]
@if(@Model.ConfigId!="1300000000001"){
@if (Model.ConfigId != "1300000000001") {
@:[Tenant("@(@Model.ConfigId)")]
}
public class @(@Model.EntityName) @Model.BaseClassName
public partial class @(Model.EntityName) @(Model.BaseClassName)
{
@foreach (var column in Model.TableField){
if(@Model.BaseClassName=="" && @column.IsPrimarykey){
@foreach (var column in Model.TableFields) {
if (Model.BaseClassName == "" && column.IsPrimarykey) {
@:/// <summary>
@:/// @column.ColumnDescription
@:/// </summary>
if(!@column.IsNullable){
if (!column.IsNullable) {
@:[Required]
}
if(@column.DataType=="string"||@column.DataType=="string?"){
@:[SugarColumn(ColumnName = "@column.DbColumnName", IsIdentity = @column.IsIdentity.ToString().ToLower(), ColumnDescription = "@column.ColumnDescription", IsPrimaryKey = true, Length = @column.Length)]
if (column.DataType == "string" || column.DataType=="string?") {
@:[SugarColumn(ColumnName = "@column.DbColumnName", IsIdentity = @column.IsIdentity.ToString().ToLower(), ColumnDescription = "@column.ColumnDescription", IsPrimarykey = true, Length = @column.Length)]
} else if (column.DataType == "decimal" || column.DataType == "decimal?") {
@:[SugarColumn(ColumnName = "@column.DbColumnName", IsIdentity = @column.IsIdentity.ToString().ToLower(), ColumnDescription = "@column.ColumnDescription", IsPrimarykey = true, Length = @column.Length, DecimalDigits=@column.DecimalDigits )]
} else {
@:[SugarColumn(ColumnName = "@column.DbColumnName", IsIdentity = @column.IsIdentity.ToString().ToLower(), ColumnDescription = "@column.ColumnDescription", IsPrimarykey = true)]
}
else if(@column.DataType=="decimal"||@column.DataType=="decimal?"){
@:[SugarColumn(ColumnName = "@column.DbColumnName", IsIdentity = @column.IsIdentity.ToString().ToLower(), ColumnDescription = "@column.ColumnDescription", IsPrimaryKey = true, Length = @column.Length, DecimalDigits=@column.DecimalDigits )]
}
else{
@:[SugarColumn(ColumnName = "@column.DbColumnName", IsIdentity = @column.IsIdentity.ToString().ToLower(), ColumnDescription = "@column.ColumnDescription", IsPrimaryKey = true)]
}
@:public @column.DataType @column.PropertyName { get; set; }
@:public virtual @column.DataType @column.PropertyName { get; set; }
@:
}
else if(@Model.BaseClassName=="" && !@column.IsPrimarykey){
} else if (Model.BaseClassName == "" && !column.IsPrimarykey) {
@:/// <summary>
@:/// @column.ColumnDescription
@:/// </summary>
if(!@column.IsNullable){
if(!column.IsNullable){
@:[Required]
}
if(@column.DataType=="string"||@column.DataType=="string?"){
if (column.DataType == "string" || column.DataType == "string?") {
@:[SugarColumn(ColumnName = "@column.DbColumnName", ColumnDescription = "@column.ColumnDescription", Length = @column.Length)]
}
else if(@column.DataType=="decimal"||@column.DataType=="decimal?"){
} else if (column.DataType == "decimal" || column.DataType=="decimal?") {
@:[SugarColumn(ColumnName = "@column.DbColumnName", ColumnDescription = "@column.ColumnDescription", Length = @column.Length, DecimalDigits=@column.DecimalDigits )]
}
else{
} else {
@:[SugarColumn(ColumnName = "@column.DbColumnName", ColumnDescription = "@column.ColumnDescription")]
}
@:public @column.DataType @column.PropertyName { get; set; }
@:public virtual @column.DataType @column.PropertyName { get; set; }
@:
}
else if(@Model.BaseClassName!="" && @column.IsPrimarykey && @column.DbColumnName.ToLower()!="id"){
} else if (Model.BaseClassName!="" && column.IsPrimarykey && column.DbColumnName.ToLower()!="id") {
@:/// <summary>
@:/// @column.ColumnDescription
@:/// </summary>
if(!@column.IsNullable){
if (!column.IsNullable) {
@:[Required]
}
if(@column.DataType=="string"||@column.DataType=="string?"){
@:[SugarColumn(ColumnName = "@column.DbColumnName", IsIdentity = @column.IsIdentity.ToString().ToLower(), ColumnDescription = "@column.ColumnDescription", IsPrimaryKey = true, Length = @column.Length)]
if (column.DataType == "string" || column.DataType == "string?") {
@:[SugarColumn(ColumnName = "@column.DbColumnName", IsIdentity = @column.IsIdentity.ToString().ToLower(), ColumnDescription = "@column.ColumnDescription", IsPrimarykey = true, Length = @column.Length)]
} else if (column.DataType == "decimal" || column.DataType == "decimal?") {
@:[SugarColumn(ColumnName = "@column.DbColumnName", IsIdentity = @column.IsIdentity.ToString().ToLower(), ColumnDescription = "@column.ColumnDescription", IsPrimarykey = true, Length = @column.Length, DecimalDigits=@column.DecimalDigits )]
} else {
@:[SugarColumn(ColumnName = "@column.DbColumnName", IsIdentity = @column.IsIdentity.ToString().ToLower(), ColumnDescription = "@column.ColumnDescription", IsPrimarykey = true)]
}
else if(@column.DataType=="decimal"||@column.DataType=="decimal?"){
@:[SugarColumn(ColumnName = "@column.DbColumnName", IsIdentity = @column.IsIdentity.ToString().ToLower(), ColumnDescription = "@column.ColumnDescription", IsPrimaryKey = true, Length = @column.Length, DecimalDigits=@column.DecimalDigits )]
}
else{
@:[SugarColumn(ColumnName = "@column.DbColumnName", IsIdentity = @column.IsIdentity.ToString().ToLower(), ColumnDescription = "@column.ColumnDescription", IsPrimaryKey = true)]
}
@:public @column.DataType @column.PropertyName { get; set; }
@:public virtual @column.DataType @column.PropertyName { get; set; }
@:
}
else if(@Model.BaseClassName!="" && !@column.IsPrimarykey && @column.DbColumnName.ToLower()!="id"){
} else if (Model.BaseClassName != "" && !column.IsPrimarykey && column.DbColumnName.ToLower() != "id") {
@:/// <summary>
@:/// @column.ColumnDescription
@:/// </summary>
if(!@column.IsNullable){
if (!column.IsNullable) {
@:[Required]
}
if(@column.DataType=="string"||@column.DataType=="string?"){
if(column.DataType == "string" || column.DataType == "string?") {
@:[SugarColumn(ColumnName = "@column.DbColumnName", ColumnDescription = "@column.ColumnDescription", Length = @column.Length)]
}
else if(@column.DataType=="decimal"||@column.DataType=="decimal?"){
} else if (column.DataType == "decimal" || column.DataType == "decimal?") {
@:[SugarColumn(ColumnName = "@column.DbColumnName", ColumnDescription = "@column.ColumnDescription", Length = @column.Length, DecimalDigits=@column.DecimalDigits )]
}
else{
} else {
@:[SugarColumn(ColumnName = "@column.DbColumnName", ColumnDescription = "@column.ColumnDescription")]
}
@:public @column.DataType @column.PropertyName { get; set; }
@:public virtual @column.DataType @column.PropertyName { get; set; }
@:
}
}

View File

@ -1,56 +0,0 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
@if(@Model.NameSpace != "Admin.NET.Core"){
@:using Admin.NET.Core;
}
namespace @(@Model.NameSpace);
/// <summary>
/// 扩展@(@Model.BusName)输出实体
/// </summary>
public partial class @(@Model.ClassName)Output
{
/// <summary>
/// count
/// </summary>
public int count { get; set; }
@if(Model.TableField.FirstOrDefault(u => u.ColumnName.ToLower() == "name") == null){
@:/// <summary>
@:/// Name
@:/// </summary>
@:public string Name { get; set; }
}
@if(Model.TabType=="Tree"){
@:/// <summary>
@:/// @(@Model.BusName)子项
@:/// </summary>
@:[SugarColumn(IsIgnore = true)]
@:public List<@(@Model.ClassName)Output> Children { get; set; }
@:/// <summary>
@:/// 是否禁止选中
@:/// </summary>
@:[SugarColumn(IsIgnore = true)]
@:public bool Disabled { get; set; }
}
}
/// <summary>
/// 扩展@(@Model.BusName)分页查询输入参数
/// </summary>
public partial class Page@(@Model.ClassName)Input
{
@if(@Model.TableField.Any(x=>x.Statistical == "Y")){
@:public string[] GroupBy { get; set; }
@:public string[] Sum { get; set; }
@:public IEnumerable<AggregationConfig> Aggregations { get; set; }
}
}

View File

@ -1,76 +0,0 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Microsoft.AspNetCore.Http;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
@{
string joinTableName = "u";
Dictionary<string, int> definedObjects = new Dictionary<string, int>();
bool haveLikeCdt = false;
string RemoteField="";
string PKName="";
foreach (var column in Model.TableField){
if (column.QueryWhether == "Y" && column.QueryType == "like"){
haveLikeCdt = true;
}
if(column.RemoteVerify){
RemoteField=@column.PropertyName;
}
if(column.ColumnKey == "True"){
PKName=column.PropertyName;
}
}
}
@if(@Model.NameSpace != "Admin.NET.Core"){
@:using Admin.NET.Core;
}
namespace @Model.NameSpace;
/// <summary>
/// 扩展@(@Model.BusName)服务
/// </summary>
public partial class @(@Model.ClassName)Service
{
/// <summary>
/// 获取列表 🔖
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[ApiDescriptionSettings(Name = "GetTreeList", Description = "获取列表", Order = 1100), HttpPost]
[DisplayName("获取列表")]
public async Task<List<@(@Model.ClassName)Output>> GetTreeList(Page@(@Model.ClassName)Input input)
{
@if(Model.TabType=="Tree"){
@:var list = await @(@Model.ClassName)Mid.GetQuery(_@(@Model.LowerClassName)Rep, input).OrderBuilder(input).ToTreeAsync(u => u.Children, u => u.@(@Model.TreeKey), input.Id);
@://var list = await @(@Model.ClassName)Mid.GetQuery(_@(@Model.LowerClassName)Rep, input).OrderBuilder(input).ToListAsync();//非树形结构表
@:var md = await _@(@Model.LowerClassName)Rep.AsQueryable().Where(u => u.Id == input.Id).Select<@(@Model.ClassName)Output>().FirstAsync();
@:if (md == null) return list;
@:
@:md.Children = list;
@:list = [md];
@:return list;
}else{
@://return await @(@Model.ClassName)Mid.GetQuery(_@(@Model.LowerClassName)Rep, input).OrderBuilder(input).ToTreeAsync(u => u.Children, u => u.@(@Model.TreeKey), input.Id));//树形结构表
@:return await @(@Model.ClassName)Mid.GetQuery(_@(@Model.LowerClassName)Rep, input).OrderBuilder(input).ToListAsync();
}
}
}
/// <summary>
/// 扩展@(@Model.BusName)中间件
/// </summary>
public partial class @(@Model.ClassName)Mid
{
}
@{
string LowerFirstLetter(string text)
{
return text.ToString()[..1].ToLower() + text[1..]; // 首字母小写
}
}

View File

@ -4,15 +4,18 @@
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Admin.NET.Core;
using @Model.EntityNameSpace;
////////////////////////////////////////////////////////////////////
// 作者:@(Model.AuthorName ?? "Admin.NET")
// 时间:@(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
// 邮箱:@(Model.Email ?? "Admin.NET@qq.com")
////////////////////////////////////////////////////////////////////
namespace @Model.NameSpace;
/// <summary>
/// @(Model.Description) 表种子数据
/// </summary>
public class @(Model.SeedDataName): ISqlSugarEntitySeedData<@(Model.EntityName)>
public class @(Model.EntityName)SeedData : ISqlSugarEntitySeedData<@(Model.EntityName)>
{
/// <summary>
/// 种子数据

View File

@ -1,165 +0,0 @@
import { h } from 'vue';
import { BasicColumn, FormSchema } from '/@@/components/Table';
import { useUserInfo } from '/@@/stores/userInfo';
@foreach (var column in Model.TableField){
if(@column.EffectType == "Upload"){
@:import { uploadFile } from '/@@/api/sys/admin';
}else if(@column.EffectType == "ForeignKey"){
@:import { get@(@column.FkEntityName)Dropdown } from '/@@/api/main/@(@Model.ClassName)';
}else if(@column.EffectType == "DictSelector"){
@:import { getDataList } from '/@@/api/sys/admin';
}else if(@column.EffectType == "ApiTreeSelector"){
@:import { get@(@column.FkEntityName)Tree } from '/@@/api/main/@(@Model.ClassName)';
}else if(@column.EffectType == "Switch"){
@:import { Switch } from 'ant-design-vue';
}else if(@column.EffectType == "ConstSelector"){
@:const codeToName = useUserInfo().codeToName;
@:const getConstType = useUserInfo().getConstDataByTypeCode;
}
}
export const columns: BasicColumn[] = [
@foreach (var column in Model.TableField){
if(@column.WhetherTable == "Y"){
@:{
@:title: '@column.ColumnComment',
@:dataIndex: '@column.LowerPropertyName',
@:sorter: true,
if(@column.EffectType == "Upload"){
@:slots: { customRender: '@(@column.LowerPropertyName)' },
}else if(@column.EffectType == "ForeignKey"){
@:customRender: ({ record }) => {
@:return record.fk@(@column.PropertyName).@(@column.LowerFkColumnName);
@:},
}else if(@column.EffectType == "Switch"){
@:customRender: ({ record }) => {
@:return h(@(@column.EffectType), { checked: record.@(@column.LowerPropertyName) });
@:},
}else if(@column.EffectType == "ConstSelector"){
@:customRender: ({ record }) => {
@:return codeToName(record.@(@column.LowerPropertyName), '@(@column.DictTypeCode)');
@:},
}
@:},
}
}
];
export const searchFormSchema: FormSchema[] = [
@foreach (var column in Model.QueryWhetherList){
@:{
@:field: '@column.LowerPropertyName',
@:label: '@column.ColumnComment',
@:colProps: { span: 8 },
if(@column.EffectType == "ForeignKey"){
@:component: 'ApiSelect',
@:componentProps: {
@:api: get@(@column.FkEntityName)Dropdown,
@:labelField: 'label',
@:valueField: 'value',
@:},
}else if(@column.EffectType == "DictSelector"){
@:component: 'ApiSelect',
@:componentProps: {
@:api: getDataList,
@:params: '@(@column.DictTypeCode)',
@:fieldNames: {
@:label: 'label',
@:value: 'value',
@:},
@:},
}else if(@column.EffectType == "ConstSelector"){
@:component: 'Select',
@:componentProps: {
@:options: getConstType('@(@column.DictTypeCode)'),
@:fieldNames: {
@:label: 'name',
@:value: 'code',
@:},
@:},
}else if(@column.EffectType == "ApiTreeSelector"){
@:component: '@(@column.EffectType)',
@:componentProps: {
@:api: get@(@column.FkEntityName)Tree,
@:},
}
else if(@column.NetType?.TrimEnd('?') == "DateTime" && @column.QueryType == "~"){
@:component: 'RangePicker',
@:componentProps: {
@: valueFormat:"YYYY-MM-DD"
@:},
}
else{
@:component: 'Input',
}
@:},
}
];
export const formSchema: FormSchema[] = [
@foreach (var column in Model.TableField){
@:{
@:label: '@column.ColumnComment',
@:field: '@column.LowerPropertyName',
if(@column.EffectType == "ForeignKey"){
@:component: 'ApiSelect',
@:componentProps: {
@:api: get@(@column.FkEntityName)Dropdown,
@:labelField: 'label',
@:valueField: 'value',
@:},
}else if(@column.EffectType == "DictSelector"){
@:component: 'ApiSelect',
@:componentProps: {
@:api: getDataList,
@:params: '@(@column.DictTypeCode)',
@:fieldNames: {
@:label: 'label',
@:value: 'value',
@:},
@:},
}else if(@column.EffectType == "ConstSelector"){
@:component: 'Select',
@:componentProps: {
@:options: getConstType('@(@column.DictTypeCode)'),
@:fieldNames: {
@:label: 'name',
@:value: 'code',
@:},
@:},
}else if(@column.EffectType == "ApiTreeSelector"){
@:component: '@(@column.EffectType)',
@:componentProps: {
@:api: get@(@column.FkEntityName)Tree,
@:},
}else if(@column.EffectType == "Switch"){
@:component: '@(@column.EffectType)',
@:componentProps: {
@:checkedChildren: '是',
@:unCheckedChildren: '否',
@:},
}else{
@:component: '@column.EffectType',
}
if(@column.WhetherRequired == "Y"){
@:required: true,
}else{
@:required: false,
}
if(@column.EffectType == "Upload"){
@:componentProps: {
@:maxNumber: 1,
@:api: uploadFile,
@:},
}
if(@column.LowerPropertyName == "id"){
@:show: false,
}
@:colProps: { span: 12 },
@:},
}
];

View File

@ -1,71 +0,0 @@
<template>
<BasicModal v-bind="$attrs" @@register="registerModal" :width="700" :title="getTitle" @@ok="handleSubmit">
<BasicForm @@register="registerForm" />
</BasicModal>
</template>
<script lang="ts">
import { defineComponent, ref, computed, unref } from 'vue';
import { BasicModal, useModalInner } from '/@@/components/Modal';
import { BasicForm, useForm } from '/@@/components/Form/index';
import { formSchema } from './data.data';
import { add@(@Model.ClassName), update@(@Model.ClassName) } from '/@@/api/main/@(@Model.ClassName)';
export default defineComponent({
components: { BasicModal, BasicForm },
emits: ['success', 'register'],
setup(_, { emit }) {
const isUpdate = ref(true);
const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({
labelWidth: 100,
schemas: formSchema,
showActionButtonGroup: false,
actionColOptions: {
span: 23,
},
});
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields();
setModalProps({ confirmLoading: false });
isUpdate.value = !!data?.isUpdate;
if (unref(isUpdate)) {
setFieldsValue({
...data.record,
});
@foreach (var column in Model.TableField){
if(@column.EffectType == "Upload"){
@:if (data.record.@(@column.LowerPropertyName)) {
@:setFieldsValue({
@:@(@column.LowerPropertyName): [data.record.@(@column.LowerPropertyName)Attachment],
@:});
@:}
}
}
}
});
const getTitle = computed(() => (!unref(isUpdate) ? '新增@(@Model.BusName)' : '编辑@(@Model.BusName)'));
async function handleSubmit() {
try {
var values = await validate();
@foreach (var column in Model.TableField){
if(@column.EffectType == "Upload"){
@:if (values.@(@column.LowerPropertyName)) {
@:values = { ...values, @(@column.LowerPropertyName): values.@(@column.LowerPropertyName)[0].id };
@:}
}
}
setModalProps({ confirmLoading: true });
if (!unref(isUpdate)) {
await add@(@Model.ClassName)(values);
} else {
await update@(@Model.ClassName)(values);
}
closeModal();
emit('success');
} finally {
setModalProps({ confirmLoading: false });
}
}
return { registerModal, registerForm, getTitle, handleSubmit };
},
});
</script>

View File

@ -4,222 +4,259 @@
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Admin.NET.Core;
using System.ComponentModel.DataAnnotations;
@{
string RemoteField="";
string PKName="";
foreach (var column in Model.TableField){
if(column.RemoteVerify){
RemoteField=@column.PropertyName;
}
if(column.ColumnKey == "True"){
PKName=column.PropertyName;
}
}
}
////////////////////////////////////////////////////////////////////
// 作者:@(Model.AuthorName ?? "Admin.NET")
// 时间:@(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
// 邮箱:@(Model.Email ?? "Admin.NET@qq.com")
////////////////////////////////////////////////////////////////////
namespace @Model.NameSpace;
/// <summary>
/// @(@Model.BusName)基础输入参数
/// </summary>
public class @(@Model.ClassName)BaseInput
{
@foreach (var column in Model.TableField){
if (@column.ColumnKey != "True"){
@:/// <summary>
@:/// @column.ColumnComment
@:/// </summary>
@:public virtual @column.NetType @column.PropertyName { get; set; }
@:
}
}
}
/// <summary>
/// @(@Model.BusName)分页查询输入参数
/// </summary>
public partial class Page@(@Model.ClassName)Input : BasePageInput
{
/// <summary>
/// 关键字查询
/// </summary>
public string? SearchKey { get; set; }
@foreach (var column in Model.TableField){
if (@column.QueryWhether == "Y"){
@:/// <summary>
@:/// @column.ColumnComment
@:/// </summary>
if(@column.NetType?.EndsWith("?") == true){
@:public @column.NetType @column.PropertyName { get; set; }
}else {
@:public @(@column.NetType)? @column.PropertyName { get; set; }
}
@:
if(@column.NetType?.TrimEnd('?') == "DateTime" && @column.QueryType == "~"){
@:/// <summary>
@: /// @(@column.ColumnComment)范围
@: /// </summary>
@: public DateTime?[] @(@column.PropertyName)Range { get; set; }
}
}
}
}
/// <summary>
/// @(@Model.BusName)增加输入参数
/// </summary>
public class Add@(@Model.ClassName)Input : @(@Model.ClassName)BaseInput
{
@foreach (var column in Model.TableField){
if (@column.WhetherAddUpdate == "Y"){
@:/// <summary>
@:/// @column.ColumnComment
@:/// </summary>
@if(@column.WhetherRequired=="Y"){
@:[Required(ErrorMessage = "@(@column.ColumnComment)不能为空")]
}
@if(@column.NetType.StartsWith("string")&&!@column.RuleItems.Any(t=>t.Type=="length")&&@column.ColumnLength>0){
@:[StringLength(@(@column.ColumnLength), ErrorMessage = "@(@column.ColumnComment)不能超过@(@column.ColumnLength)个字符")]
}
@if(@column.AnyRule){
@foreach(var rule in @column.RuleItems){
@if(rule.Type=="pattern"){
@:[RegularExpression(@@"@(@FormatPattern(rule.Pattern))", ErrorMessage = "@(@rule.Message)")]
}
@if(rule.Type=="length"&&column.NetType.StartsWith("string")){
@:[StringLength(@(@rule.Max),MinimumLength = @(@rule.Min), ErrorMessage = "@(@column.ColumnComment)只能是@(@rule.Min)至@(@rule.Max)字符")]
}
@if(rule.Type=="length"&&column.NetType.StartsWith("DateTime")){
@:[Range(typeof(DateTime), "@(@rule.Min)", "@(@rule.Max)", ErrorMessage = "@(@column.ColumnComment)只能是@(@rule.Min)到@(@rule.Max)")]
}
@if(rule.Type=="length"&&(column.NetType.StartsWith("int")||column.NetType.StartsWith("long")||column.NetType.StartsWith("decimal")||column.NetType.StartsWith("float")||column.NetType.StartsWith("double"))){
@:[Range(@(@rule.Min), @(@rule.Max), ErrorMessage = "@(@column.ColumnComment)只能是@(@rule.Min)至@(@rule.Max)")]
}
}
}
@:public override @column.NetType @column.PropertyName { get; set; }
@:
}
}
}
/// <summary>
/// @(@Model.BusName)删除输入参数
/// </summary>
public class Delete@(@Model.ClassName)Input : BaseIdInput
{
@foreach (var column in Model.TableField){
if (@column.NetType == "Guid" && @column.PropertyName == "Id"){
@:/// <summary>
@:/// @column.ColumnComment
@:/// </summary>
@:public @column.NetType @column.PropertyName { get; set; }
@:
}
}
@foreach (var column in Model.TableField){
if (@column.ColumnKey == "True" && @column.PropertyName != "Id"){
@:/// <summary>
@:/// @column.ColumnComment
@:/// </summary>
@:[Required(ErrorMessage = "@(@column.ColumnComment)不能为空")]
@:public @column.NetType @column.PropertyName { get; set; }
@:
}
}
}
/// <summary>
/// @(@Model.BusName)更新输入参数
/// </summary>
public class Update@(@Model.ClassName)Input : @(@Model.ClassName)BaseInput
{
@foreach (var column in Model.TableField){
if (@column.ColumnKey == "True"){
@:/// <summary>
@:/// @column.ColumnComment
@:/// </summary>
@:[Required(ErrorMessage = "@(@column.ColumnComment)不能为空")]
@if (@column.NetType == "Guid" && @column.PropertyName == "Id"){
@:[AdaptIgnore]
}
@:public @column.NetType @column.PropertyName { get; set; }
@:
}
if (@column.WhetherAddUpdate == "Y"){
@:/// <summary>
@:/// @column.ColumnComment
@:/// </summary>
@if(@column.WhetherRequired=="Y"){
@:[Required(ErrorMessage = "@(@column.ColumnComment)不能为空")]
}
@if(@column.NetType.StartsWith("string")&&!@column.RuleItems.Any(t=>t.Type=="length")&&@column.ColumnLength>0){
@:[StringLength(@(@column.ColumnLength), ErrorMessage = "@(@column.ColumnComment)不能超过@(@column.ColumnLength)个字符")]
}
@if(@column.AnyRule){
@foreach(var rule in @column.RuleItems){
@if(rule.Type=="pattern"){
@:[RegularExpression(@@"@(@FormatPattern(rule.Pattern))", ErrorMessage = "@(@rule.Message)")]
}
@if(rule.Type=="length"&&column.NetType.StartsWith("string")){
@:[StringLength(@(@rule.Max),MinimumLength = @(@rule.Min), ErrorMessage = "@(@column.ColumnComment)只能是@(@rule.Min)至@(@rule.Max)字符")]
}
@if(rule.Type=="length"&&column.NetType.StartsWith("DateTime")){
@:[Range(typeof(DateTime), "@(@rule.Min)", "@(@rule.Max)", ErrorMessage = "@(@column.ColumnComment)只能是@(@rule.Min)到@(@rule.Max)")]
}
@if(rule.Type=="length"&&(column.NetType.StartsWith("int")||column.NetType.StartsWith("long")||column.NetType.StartsWith("decimal")||column.NetType.StartsWith("float")||column.NetType.StartsWith("double"))){
@:[Range(@(@rule.Min), @(@rule.Max), ErrorMessage = "@(@column.ColumnComment)只能是@(@rule.Min)至@(@rule.Max)")]
}
}
}
@:public override @column.NetType @column.PropertyName { get; set; }
@:
}
}
}
/// <summary>
/// @(@Model.BusName)主键查询输入参数
/// </summary>
public class QueryById@(@Model.ClassName)Input : Delete@(@Model.ClassName)Input
{
}
@if(@Model.RemoteVerify){
@:/// <summary>
@:/// 检查@(RemoteField)字段参数
@:/// </summary>
@:public class Exists@(RemoteField)Input
@:{
@:/// <summary>
@:/// 字段值
@:/// </summary>
@:public string FieldValue { get; set; }
@:
@:/// <summary>
@:/// 旧字段值
@:/// </summary>
@:public string OldFieldValue { get; set; }
@:}
}
@{
string FormatPattern(string pattern)
/// <summary>
/// @(Model.BusName)基础输入参数
/// </summary>
public class @(Model.ClassName)BaseInput
{
if (pattern.EndsWith('g'))
{
pattern = pattern.TrimEnd('g');
@{ var i = 0; }
@foreach (var column in Model.AllFields){
if (column.IsPrimarykey) continue;
if (!@column.IsCommon) {
if (i++ != 0) {
@:
}
pattern = pattern.Trim('/');
return pattern;
@:/// <summary>
@:/// @column.ColumnComment
@:/// </summary>
if (column.IsDict) {
@:[Dict("@(column.DictConfig?.Code)")]
}
if (column.IsEnum) {
@:[Dict(nameof(@column.DictConfig?.Code))]
}
@:public virtual @column.NullableNetType @column.PropertyName { get; set; }
}
}
}
/// <summary>
/// @(@Model.BusName)分页查询输入参数
/// </summary>
public class Page@(@Model.ClassName)Input : BasePageInput
{
@{ i = 0; }
@foreach (var column in Model.QueryFields) {
if (i++ != 0) {
@:
}
@:/// <summary>
@:/// @column.ColumnComment
@:/// </summary>
if (column.IsConst) {
@:[Const(nameof(@column.DictConfig?.Code))]
}
if (column.IsDict) {
@:[Dict("@(column.DictConfig?.Code)")]
}
if (column.IsEnum) {
@:[Dict(nameof(@column.DictConfig?.Code))]
}
@:public @column.NullableNetType @column.PropertyName { get; set; }
if (@column.NetType?.TrimEnd('?') == "DateTime" && @column.QueryType == "~") {
@:
@:/// <summary>
@:/// @(column.ColumnComment)范围
@:/// </summary>
@:public DateTime?[] @(column.PropertyName)Range { get; set; }
}
}
}
/// <summary>
/// @(Model.BusName)增加输入参数
/// </summary>
public class Add@(Model.ClassName)Input : @(Model.ClassName)BaseInput
{
@{ i = 0; }
@foreach (var column in Model.AddUpdateFields.Where(u => u.IsRequired)) {
if (i++ != 0) {
@:
}
@:/// <summary>
@:/// @column.ColumnComment
@:/// </summary>
if (@column.IsRequired) {
@:[Required(ErrorMessage = "@(column.ColumnComment)不能为空")]
} else if (column.FromValid != null && (int)column.FromValid != 100) {
@:@(column.GetFromValidAttribute())
}
if (column.IsConst) {
@:[Const(nameof(@column.DictConfig?.Code))]
}
if (column.IsDict) {
@:[Dict("@(column.DictConfig?.Code)"@(column.IsRequired ? "" : ""))]
} else if (column.IsEnum) {
@:[Dict(nameof(@column.DictConfig?.Code)@(column.IsRequired ? "" : ""))]
}
@:public override @column.NullableNetType @column.PropertyName { get; set; }
}
}
/// <summary>
/// @(Model.BusName)主键输入参数
/// </summary>
public class Primarykey@(Model.ClassName)Input
{
@foreach (var column in Model.PrimaryFields){
@:/// <summary>
@:/// @column.ColumnComment
@:/// </summary>
@:[Required(ErrorMessage = "@(column.ColumnComment)不能为空")]
if (@column.NetType == "Guid" && @column.PropertyName == "Id") {
@:public @column.NullableNetType @column.PropertyName { get; set; }
} else if (@column.IsPrimarykey) {
@:public @column.NullableNetType @column.PropertyName { get; set; }
}
}
}
/// <summary>
/// @(@Model.BusName)更新输入参数
/// </summary>
public class Update@(Model.ClassName)Input : Add@(Model.ClassName)Input
{
@foreach (var column in Model.PrimaryFields){
@:/// <summary>
@:/// @column.ColumnComment
@:/// </summary>
@:[Required(ErrorMessage = "@(column.ColumnComment)不能为空")]
if (@column.NetType == "Guid" && @column.PropertyName == "Id") {
@:public @column.NullableNetType @column.PropertyName { get; set; }
} else if (@column.IsPrimarykey) {
@:public @column.NullableNetType @column.PropertyName { get; set; }
}
}
}
@foreach (var column in Model.ApiFields.GroupBy(u => new { u.IsTree, u.JoinConfig.EntityName }).Select(u => u.First()).ToList()) {
var methodName = (column.IsTree ? "Tree" : "Page") + Model.ClassName + column.JoinConfig.EntityName;
@:/// <summary>
@:/// 获取@(column.JoinConfig.TableComment)数据输入参数
@:/// </summary>
@:public class @(methodName)Input : Base@(column.IsTree ? "Dropdown" : "Page")Input
@:{
if (!column.IsTree) {
@:/// <summary>
@:/// 数据来自于表
@:/// </summary>
@:public bool All { get; set; }
}
@:}
@:
}
@if (Model.HasStatus) {
@:/// <summary>
@:/// 设置状态输入参数
@:/// </summary>
@:public class Set@(Model.ClassName)StatusInput : BaseStatusInput
@:{
foreach (var column in Model.AllFields.Where(u => u.IsPrimarykey && (u.NetType == "Guid" && u.PropertyName == "Id" || !(u.NetType == "long" && u.PropertyName == "Id")))) {
@:/// <summary>
@:/// @column.ColumnComment
@:/// </summary>
@:[Required(ErrorMessage = "@(column.ColumnComment)不能为空")]
if (column.NetType == "Guid" && column.PropertyName == "Id") {
@:public new @column.NullableNetType @column.PropertyName { get; set; }
} else if (column.IsPrimarykey) {
@:public @column.NullableNetType @column.PropertyName { get; set; }
}
}
@:}
@:
}
/// <summary>
/// @(Model.BusName)主键查询输入参数
/// </summary>
public class QueryById@(@Model.ClassName)Input : Primarykey@(Model.ClassName)Input
{
}
@if (Model.ImportFields?.Count > 0){
@:/// <summary>
@:/// @(Model.BusName)主键查询输入参数
@:/// </summary>
@:public class Export@(@Model.ClassName)Input : Page@(@Model.ClassName)Input
@:{
@:/// <summary>
@:/// 需要导入的主键集
@:/// </summary>
@:[ImporterHeader(IsIgnore = true)]
@:[ExporterHeader(IsIgnore = true)]
@:public List<@(Model.PrimaryFields.First().NetType)> SelectKeyList { get; set; }
@:}
@:
@:/// <summary>
@:/// @(Model.BusName)数据导入实体
@:/// </summary>
@:[ExcelImporter(SheetIndex = 1, IsOnlyErrorRows = true)]
@:public class Import@(Model.ClassName)Input : BaseImportInput
@:{
foreach (var column in Model.AllFields) {
if (@column.NetType == "Guid" && @column.PropertyName == "Id") {
@:/// <summary>
@:/// 记录Id
@:/// </summary>
@:[ImporterHeader(IsIgnore = true)]
@:[ExporterHeader(IsIgnore = true)]
@:public new @column.NullableNetType @column.PropertyName { get; set; }
@:
}
}
foreach (var column in Model.ImportFields) {
var headerName = (column.IsRequired ? "*" : "") + column.ColumnComment;
if (column.HasJoinTable || column.IsDict) {
@:/// <summary>
@:/// @column.ColumnComment 关联值
@:/// </summary>
@:[ImporterHeader(IsIgnore = true)]
@:[ExporterHeader(IsIgnore = true)]
@:public @column.NullableNetType @column.PropertyName { get; set; }
@:
@:/// <summary>
@:/// @column.ColumnComment 文本
@:/// </summary>
if (column.IsDict) {
@:[Dict("@(column.DictConfig?.Code)"@(column.IsRequired ? "" : ""))]
}
@:[ImporterHeader(Name = "@(headerName)")]
@:[ExporterHeader("@(headerName)", Format = "@", Width = 25, IsBold = true)]
@:public string @(column.PropertyName + "Label") { get; set; }
} else {
@:/// <summary>
@:/// @column.ColumnComment
@:/// </summary>
if (column.IsConst) {
@:[Const(nameof(@column.DictConfig?.Code))]
}
if (column.IsEnum) {
@:[Dict(nameof(@column.DictConfig?.Code)@(column.IsRequired ? "" : ""))]
}
@:[ImporterHeader(Name = "@(headerName)")]
@:[ExporterHeader("@(headerName)", Format = "@", Width = 25, IsBold = true)]
@:public @column.NullableNetType @column.PropertyName { get; set; }
}
@:
}
@:}
}

View File

@ -1,129 +0,0 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
@{
string joinTableName = "u";
Dictionary<string, int> definedObjects = new Dictionary<string, int>();
bool haveLikeCdt = false;
string RemoteField="";
string PKName="";
foreach (var column in Model.TableField){
if (column.QueryWhether == "Y" && column.QueryType == "like"){
haveLikeCdt = true;
}
if(column.RemoteVerify){
RemoteField=@column.PropertyName;
}
if(column.ColumnKey == "True"){
PKName=column.PropertyName;
}
}
}
@if(@Model.NameSpace != "Admin.NET.Core"){
@:using Admin.NET.Core;
}
using Admin.NET.Core.Service;
namespace @(@Model.NameSpace);
public partial class @(@Model.ClassName)Mid
{
/// <summary>
/// 获取查询
/// </summary>
/// <param name="_@(@Model.LowerClassName)Rep"></param>
/// <param name="input"></param>
/// <returns></returns>
public static ISugarQueryable<@(@Model.ClassName)> GetQuery(SqlSugarRepository<@(@Model.ClassName)> _@(@Model.LowerClassName)Rep,Page@(@Model.ClassName)Input input)
{
var sysCacheService = App.GetRequiredService<SysCacheService>();
var db = App.GetRequiredService<ISqlSugarClient>();
@if (haveLikeCdt) {
@:input.SearchKey = input.SearchKey?.Trim();
}
var query = _@(@Model.LowerClassName)Rep.AsQueryable()
@{string conditionFlag = "";}
@if (haveLikeCdt) {
@:.WhereIF(!string.IsNullOrEmpty(input.SearchKey), u =>
@foreach (var column in Model.TableField){
if (@column.QueryWhether == "Y" && column.QueryType == "like"){
@:@(conditionFlag)u.@(@column.PropertyName).Contains(input.SearchKey)
conditionFlag="|| ";
}
}
@:)
}
@foreach (var column in Model.TableField){
if (@column.QueryWhether == "Y"){
if (@column.NetType?.TrimEnd('?') == "string"){
if(@column.QueryType == "like"){
@:.WhereIF(!string.IsNullOrWhiteSpace(input.@column.PropertyName), u => u.@(@column.PropertyName).Contains(input.@(@column.PropertyName).Trim()))
}else{
@:.WhereIF(!string.IsNullOrWhiteSpace(input.@column.PropertyName), u => u.@(@column.PropertyName) @column.QueryType input.@(@column.PropertyName))
}
}else if(@column.NetType?.TrimEnd('?') == "int" || @column.NetType?.TrimEnd('?') == "long"){
@:.WhereIF(input.@column.PropertyName>0, u => (int)u.@(@column.PropertyName) @column.QueryType input.@(@column.PropertyName))
}else if(@column.NetType?.TrimEnd('?') == "DateTime" && @column.QueryType == "~"){
@:.WhereIF(input.@(@column.PropertyName)Range != null && input.@(@column.PropertyName)Range.Length == 2, u => u.@(@column.PropertyName) >= input.@(@column.PropertyName)Range[0] && u.@(@column.PropertyName) <= input.@(@column.PropertyName)Range[1])
}else if(@column.NetType?.TrimEnd('?').EndsWith("Enum") == true) {
@:.WhereIF(input.@(@column.PropertyName).HasValue, u => u.@(@column.PropertyName) @column.QueryType input.@(@column.PropertyName))
}
}
if(@column.PropertyName == "IsDelete") {
@:.Where( u => u.IsDelete == false)
}
}
@if (Model.TableField.Any(c => c.PropertyName == "OrderNo"))
{
@:.OrderBy(u => u.OrderNo)
}
@if(!string.IsNullOrEmpty(Model.TreeName)){
@:.Mapper(c => c.Name= c.@(@Model.TreeName).ToString())
}
@foreach (var column in Model.TableField){
if(@column.EffectType == "Upload"){
@://.Mapper(c => c.@(@column.PropertyName)Attachment, c => c.@(@column.PropertyName))
}
else if(@column.EffectType == "ForeignKey"){
@:.Mapper(t =>
@:{
@: //使用缓存
@: var key = $"@(@column.FkEntityName)_{t.@(@column.PropertyName)}";
@: if (!sysCacheService.ExistKey(key))
@: {
@: var m = db.ForTenant<@(@column.FkEntityName)>().Queryable<@(@column.FkEntityName)>().First(f => f.@(@column.FkLinkColumnName) == t.@(@column.PropertyName));
@: if (m != null) sysCacheService.Set(key, m);
@: }
@: t.@(@column.PropertyName)@(@column.FkColumnName) = sysCacheService.Get<@(@column.FkEntityName)>(key)?.@(@column.FkColumnName);
@: //t.@(@column.PropertyName)@(@column.FkColumnName)=db.Queryable<@(@column.FkEntityName)>().First(f => f.@(@column.FkLinkColumnName) == t.@(@column.PropertyName))).@(@column.FkColumnName);//
@:})
}
else if(@column.EffectType == "ApiTreeSelector"){
@:.Mapper(t =>
@:{
@: //使用缓存
@: var key = $"@(@column.FkEntityName)_{t.@(@column.PropertyName)}";
@: if (!sysCacheService.ExistKey(key))
@: {
@: var m = db.ForTenant<@(@column.FkEntityName)>().Queryable<@(@column.FkEntityName)>().First(f => f.@(@column.ValueColumn) == t.@(@column.PropertyName));
@: if (m != null) sysCacheService.Set(key, m);
@: }
@: t.@(@column.PropertyName)@(@column.DisplayColumn) = sysCacheService.Get<@(@column.FkEntityName)>(key)?.@(@column.DisplayColumn);
@: //t.@(@column.PropertyName)@(@column.FkColumnName)=db.Queryable<@(@column.FkEntityName)>().FirstAsync(f => f.@(@column.FkLinkColumnName) == t.@(@column.PropertyName))).@(@column.FkColumnName);//
@:})
}
}
;
return query;
}
}
@{
string LowerFirstLetter(string text)
{
return text.ToString()[..1].ToLower() + text[1..]; // 首字母小写
}
}

View File

@ -4,110 +4,69 @@
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
////////////////////////////////////////////////////////////////////
// 作者:@(Model.AuthorName ?? "Admin.NET")
// 时间:@(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
// 邮箱:@(Model.Email ?? "Admin.NET@qq.com")
////////////////////////////////////////////////////////////////////
namespace @Model.NameSpace;
/// <summary>
/// 这里做优化 如果是富文本不传入
/// @(@Model.BusName)基类输出参数
/// @(@Model.BusName)输出参数
/// </summary>
public partial class Base@(@Model.ClassName)Output
public class Page@(@Model.ClassName)Output
{
@foreach (var column in Model.TableField){
@foreach (var column in Model.AllFields) {
@:/// <summary>
@:/// @column.ColumnComment
@:/// </summary>
if(column.EffectType == "ForeignKey")
if (column.IsForeignKey)
{
@:public @column.NetType @column.PropertyName { get; set; }
@:public @column.NullableNetType @column.PropertyName { get; set; }
@:
@:/// <summary>
@:/// @(column.ColumnComment) 描述
@:/// </summary>
@:public @(@column.FkColumnNetType) @(@column.PropertyName)@(@column.FkColumnName) { get; set; }
@:public string @(column.LeftJoinPropertyName) { get; set; }
}else if(column.EffectType == "Upload"){
@:public @column.NetType @column.PropertyName { get; set; }
@:public SysFile @(@column.PropertyName)Attachment { get; set; }
}else if(column.EffectType == "ApiTreeSelector"){
@:public @column.NetType @column.PropertyName { get; set; }
} else if (column.IsUpload) {
@:public @column.NullableNetType @column.PropertyName { get; set; }
@:
@:/// <summary>
@:/// 树型@(column.ColumnComment) 描述
@:/// @(column.ColumnComment) 文件对象
@:/// </summary>
@:public string? @(@column.PropertyName)@(@column.DisplayColumn) { get; set; }
@:public SysFile @(column.LeftJoinPropertyName) { get; set; }
} else if (column.IsTree) {
@:public @column.NullableNetType @column.PropertyName { get; set; }
@:
@:/// <summary>
@:/// 树型分类子项
@:/// @(column.ColumnComment) 描述
@:/// </summary>
@:public List<@(@Model.ClassName)Output> Children { get; set; } = [];
@:public string @(column.LeftJoinPropertyName) { get; set; }
}else if(column.EffectType == "RichTextEditor"){
@:/// HJ:富文本不传,提高性能
}else{
@:public @column.NetType @(@column.PropertyName) { get; set; }
} else {
@:public @column.NullableNetType @(@column.PropertyName) { get; set; }
}
@:
@:
}
}
/// <summary>
/// @(@Model.BusName)分页输出参数
/// </summary>
public partial class Page@(@Model.ClassName)Output : Base@(@Model.ClassName)Output
{
}
/// <summary>
/// @(@Model.BusName)列表输出参数
/// @(@Model.BusName)详情输出参数
/// </summary>
public partial class List@(@Model.ClassName)Output : Base@(@Model.ClassName)Output
{
public class Detail@(@Model.ClassName)Output : Page@(@Model.ClassName)Output {
}
@foreach (var column in Model.TableField){
if (@column.EffectType == "ApiTreeSelector"){
@:// 使用实际实体@(@column.FkTableName),所以这里就删了
@:/*
@:[SugarTable("@(@column.FkTableName)")]
@:public class @(@column.FkEntityName)TreeOutput: EntityBaseId
@:{
@:[SugarColumn(ColumnName = "@(@column.DisplayColumn)")]
@:public @(@Model.GetColumnNetType(@column.FkTableName,@column.DisplayColumn)) Label { get; set; }
@:[SugarColumn(ColumnName = "@(@column.ValueColumn)", IsPrimaryKey = true, IsIdentity = false)]
@:public @(@Model.GetColumnNetType(@column.FkTableName,@column.ValueColumn)) Value { get; set; }
@:public @(@Model.GetColumnNetType(@column.FkTableName,@column.PidColumn)) @column.PidColumn { get; set; }
@:[SugarColumn(IsIgnore = true)]
@:public List<@(@column.FkEntityName)TreeOutput> Children { get; set; }
@:}
@:*/
}
}
/// <summary>
/// HJ:这里用的标准的Dto,如果有特殊需要可以在Dto中添加
/// @(@Model.BusName)导入导出输出参数
/// </summary>
public partial class @(@Model.ClassName)Dto
{
@foreach (var column in Model.TableField){
@:/// <summary>
@:/// @column.ColumnComment
@:/// </summary>
@:[ImporterHeader(Name = "@(column.ColumnComment)")]
@:[ExporterHeader(DisplayName = "@(column.ColumnComment)", IsBold = true)]
@:public @column.NetType @column.PropertyName { get; set; }
@:
}
}
@if (Model.ImportFields.Count > 0) {
@:/// <summary>
@:/// @(Model.BusName)数据导出模板实体
@:/// </summary>
@:public class Export@(Model.ClassName)Output : Import@(Model.ClassName)Input
@:{
@: [ImporterHeader(IsIgnore = true)]
@: [ExporterHeader(IsIgnore = true)]
@: public override string Error { get; set; }
@:}
}

View File

@ -4,471 +4,463 @@
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Admin.NET.Core.Service;
using Microsoft.AspNetCore.Http;
using System.Linq.Expressions;
using Furion.EventBus;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
@{
string joinTableName = "u";
Dictionary<string, int> definedObjects = new Dictionary<string, int>();
bool haveLikeCdt = false;
string RemoteField="";
string PKName="";
foreach (var column in Model.TableField){
if (column.QueryWhether == "Y" && column.QueryType == "like"){
haveLikeCdt = true;
}
if(column.RemoteVerify){
RemoteField=@column.PropertyName;
}
if(column.ColumnKey == "True"){
PKName=column.PropertyName;
}
}
}
////////////////////////////////////////////////////////////////////
// 作者:@(Model.AuthorName ?? "Admin.NET")
// 时间:@(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
// 邮箱:@(Model.Email ?? "Admin.NET@qq.com")
////////////////////////////////////////////////////////////////////
namespace @Model.NameSpace;
namespace @(Model.NameSpace);
/// <summary>
/// @(@Model.BusName)服务
/// @(Model.BusName)服务 🧩
/// </summary>
[ApiDescriptionSettings(@(@Model.ProjectLastName)Const.GroupName, Name = "@(@Model.LowerClassName)", Order = 100)]
public partial class @(@Model.ClassName)Service : IDynamicApiController, ITransient
[ApiDescriptionSettings(@(Model.ProjectLastName)Const.GroupName, Order = 100)]
public class @(Model.ClassName)Service : IDynamicApiController, ITransient
{
private readonly SysCacheService _sysCacheService;//默认CacheService
private readonly UserManager _userManager;//默认用户管理
private readonly IEventPublisher _eventPublisher;//默认事件总线
private readonly SqlSugarRepository<@(@Model.ClassName)> _@(@Model.LowerClassName)Rep;
@foreach (var column in Model.TableField){
if(@column.EffectType == "ForeignKey"||@column.EffectType == "ApiTreeSelector"){
if(@column.FkEntityName != @Model.ClassName){
@:private readonly SqlSugarRepository<@(@column.FkEntityName)> _@(@column.LowerFkEntityName)Rep;
}
private readonly SqlSugarRepository<@(Model.ClassName)> _@(Model.LowerClassName)Rep;
@if (Model.ImportFields.Any()) {
@:private readonly SysDictTypeService _sysDictTypeService;
}
@if (Model.UploadFields.Any()) {
@:private readonly SysFileService _sysFileService;
}
@if (Model.DropdownFields.Any() || Model.UploadFields.Any()) {
@:private readonly ISqlSugarClient _db;
}
public @(Model.ClassName)Service(SqlSugarRepository<@(Model.ClassName)> @(Model.LowerClassName)Rep@(Model.ImportFields.Any() ? ", SysDictTypeService sysDictTypeService" : "")@(Model.DropdownFields.Any() ? ", ISqlSugarClient sqlSugarClient" : "")@(Model.UploadFields.Any() ? ", SysFileService sysFileService" : ""))
{
_@(Model.LowerClassName)Rep = @(Model.LowerClassName)Rep;
@if (Model.DropdownFields.Any()) {
@:_db = sqlSugarClient;
}
@if (Model.UploadFields.Any()) {
@:_sysFileService = sysFileService;
}
@if (Model.ImportFields.Any()) {
@:_sysDictTypeService = sysDictTypeService;
}
}
/// <summary>
/// 分页查询@(Model.BusName) 🔖
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[DisplayName("分页查询@(Model.BusName)")]
[ApiDescriptionSettings(Name = "Page"), HttpPost]
public async Task<SqlSugarPagedList<Page@(Model.ClassName)Output>> Page(Page@(Model.ClassName)Input input)
{
input.Keyword = input.Keyword?.Trim();
var query = _@(Model.LowerClassName)Rep.AsQueryable()
@{
string joinTableName = "u";
// 关键字模糊查询
if (Model.QueryFields.Any(u => u.QueryType == "like")) {
@:.WhereIF(!string.IsNullOrWhiteSpace(input.Keyword), u => @string.Join(" || ", Model.QueryFields.Where(u => u.QueryType == "like").Select(col => $"u.{col.PropertyName}.Contains(input.Keyword)")))
}
// 单字段模糊查询
foreach(var column in Model.QueryFields.Where(u => u.QueryType == "like")) {
@:.WhereIF(!string.IsNullOrWhiteSpace(input.@(column.PropertyName)), u => u.@(column.PropertyName).Contains(input.@(column.PropertyName).Trim()))
}
// 字段组合查询
foreach(var column in Model.QueryFields.Where(u => u.QueryType != "like")) {
if (column.NetType.TrimEnd('?') == "string") {
@:.WhereIF(!string.IsNullOrWhiteSpace(input.@(column.PropertyName)), u => u.@(column.PropertyName) == input.@(column.PropertyName))
} else if (column.NetType.TrimEnd('?') == "int" || column.NetType.TrimEnd('?') == "long") {
@:.WhereIF(input.@(column.PropertyName) != null, u => u.@(column.PropertyName) @(column.QueryType) input.@(column.PropertyName))
} else if (column.NetType.TrimEnd('?').EndsWith("Enum") || column.NetType.TrimEnd('?').EndsWith("bool")) {
@:.WhereIF(input.@(column.PropertyName).HasValue, u => u.@(column.PropertyName) == input.@(column.PropertyName))
} else if (column.NetType.TrimEnd('?') == "DateTime" && column.QueryType == "~") {
@:.WhereIF(input.@(column.PropertyName)Range?.Length == 2, u => u.@(column.PropertyName) >= input.@(column.PropertyName)Range[0] && u.@(column.PropertyName) <= input.@(column.PropertyName)Range[1])
}
}
// 联表
if (Model.HasJoinTable) {
foreach (var column in Model.TableFields.Where(u => (u.IsForeignKey || u.IsTree) && !u.Multiple)) {
joinTableName += ", " + column.LeftJoinAliasName;
@:.LeftJoin<@(column.JoinConfig?.EntityName)>((@joinTableName) => u.@(column.PropertyName) == @(column.LeftJoinAliasName).@(column.JoinConfig?.LinkPropertyName))
}
// 查询列表
@:.Select((@joinTableName) => new Page@(Model.ClassName)Output
@:{
foreach (var column in Model.TableFields) {
@:@(column.PropertyName) = u.@(column.PropertyName),
if (column.IsForeignKey || column.IsTree) {
if (column.Multiple) {
@:@(column.LeftJoinPropertyName) = SqlFunc.Subqueryable<@(column.JoinConfig?.EntityName)>().Where(@(column.LeftJoinAliasName) => u.@(column.PropertyName).Contains(@(column.LeftJoinAliasName).@(column.JoinConfig?.LinkPropertyName).ToString())).SelectStringJoin(@(column.LeftJoinAliasName) => @(column.LeftJoinAliasName).@(column.JoinConfig.DisplayPropertyNames.Split(",").First()), ","),
} else {
@:@(column.LeftJoinPropertyName) = @(column.DisplayPropertyNames),
}
}
}
@:}, true);
} else {
// 无联表
@:.Select<Page@(Model.ClassName)Output>();
}
@:query = query.MergeTable();
if (Model.TableFields.Any(u => u.IsUpload)) {
@:query = query.Mapper(u => {
foreach (var column in Model.TableFields.Where(u => u.IsUpload)) {
@:if (u.@(column.PropertyName) > 0) u.@(column.LeftJoinPropertyName) = _db.Queryable<SysFile>().First(w => w.Id == u.@(column.PropertyName)@(column.NetType.Last() == '?' ? "!.Value" : ""));
}
@:});
}
}
return await query.OrderBuilder(input).ToPagedListAsync(input.Page, input.PageSize);
}
private TypeAdapterConfig _typeAdapterConfig = TypeAdapterConfig.GlobalSettings;
public @(@Model.ClassName)Service(SqlSugarRepository<@(@Model.ClassName)> @(@Model.LowerClassName)Rep
,SysCacheService sysCacheService
, UserManager userManager
,IEventPublisher eventPublisher
@foreach (var column in Model.TableField){
if(@column.EffectType == "ForeignKey"||@column.EffectType == "ApiTreeSelector"){
if(@column.FkEntityName != @Model.ClassName){
@:,SqlSugarRepository<@(@column.FkEntityName)> @(@column.LowerFkEntityName)Rep
}
/// <summary>
/// 获取@(Model.BusName)列表 🔖
/// </summary>
/// <returns></returns>
[DisplayName("获取@(Model.BusName)列表")]
[ApiDescriptionSettings(Name = "List"), HttpGet]
public async Task<List<@(Model.ClassName)>> GetList([FromQuery] Page@(@Model.ClassName)Input input) {
return await _@(Model.LowerClassName)Rep.AsQueryable()
@foreach(var column in Model.QueryFields.Where(u => u.QueryType == "like")) {
@:.WhereIF(!string.IsNullOrWhiteSpace(input.@(column.PropertyName)?.Trim()), u => u.@(column.PropertyName).Contains(input.@(column.PropertyName).Trim()))
}
@foreach(var column in Model.QueryFields.Where(u => u.QueryType != "like")) {
if (column.NetType.TrimEnd('?') == "string") {
@:.WhereIF(!string.IsNullOrWhiteSpace(input.@(column.PropertyName)?.Trim()), u => u.@(column.PropertyName) == input.@(column.PropertyName))
} else if (column.NetType.TrimEnd('?') == "int" || column.NetType.TrimEnd('?') == "long") {
@:.WhereIF(input.@(column.PropertyName) != null, u => u.@(column.PropertyName) @(column.QueryType) input.@(column.PropertyName))
} else if (column.NetType.TrimEnd('?').EndsWith("Enum") || column.NetType.TrimEnd('?').EndsWith("bool")) {
@:.WhereIF(input.@(column.PropertyName).HasValue, u => u.@(column.PropertyName) == input.@(column.PropertyName))
} else if (column.NetType.TrimEnd('?') == "DateTime" && column.QueryType == "~") {
@:.WhereIF(input.@(column.PropertyName)Range?.Length == 2, u => u.@(column.PropertyName) >= input.@(column.PropertyName)Range[0] && u.@(column.PropertyName) <= input.@(column.PropertyName)Range[1])
}
}
.ToListAsync();
}
/// <summary>
/// 获取@(Model.BusName)详情
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[DisplayName("获取@(Model.BusName)详情")]
[ApiDescriptionSettings(Name = "Detail"), HttpGet]
public async Task<Detail@(@Model.ClassName)Output> Detail([FromQuery] QueryById@(Model.ClassName)Input input)
{
var query = _@(Model.LowerClassName)Rep.AsQueryable()
@{
joinTableName = "u";
// 联表
if (Model.HasJoinTable) {
foreach (var column in Model.TableFields.Where(u => (u.IsForeignKey || u.IsTree) && !u.Multiple)) {
joinTableName += ", " + column.LeftJoinAliasName;
@:.LeftJoin<@(column.JoinConfig?.EntityName)>((@joinTableName) => u.@(column.PropertyName) == @(column.LeftJoinAliasName).@(column.JoinConfig?.LinkPropertyName))
}
// 查询列表
@:.Select((@joinTableName) => new Detail@(@Model.ClassName)Output
@:{
foreach (var column in Model.TableFields) {
@:@(column.PropertyName) = u.@(column.PropertyName),
if (column.IsForeignKey || column.IsTree) {
if (column.Multiple) {
@:@(column.LeftJoinPropertyName) = SqlFunc.Subqueryable<@(column.JoinConfig?.EntityName)>().Where(@(column.LeftJoinAliasName) => u.@(column.PropertyName).Contains(@(column.LeftJoinAliasName).@(column.JoinConfig?.LinkPropertyName).ToString())).SelectStringJoin(@(column.LeftJoinAliasName) => @(column.LeftJoinAliasName).@(column.JoinConfig.DisplayPropertyNames.Split(",").First()), ","),
} else {
@:@(column.LeftJoinPropertyName) = @(column.DisplayPropertyNames),
}
}
}
)
{
_@(@Model.LowerClassName)Rep = @(@Model.LowerClassName)Rep;
@foreach (var column in Model.TableField){
if(@column.EffectType == "ForeignKey"||@column.EffectType == "ApiTreeSelector"){
if(@column.FkEntityName != @Model.ClassName){
@:_@(@column.LowerFkEntityName)Rep = @(@column.LowerFkEntityName)Rep;
}
}
}
_typeAdapterConfig.ForType<T, @(@Model.ClassName)>().IgnoreNullValues(true);
_sysCacheService = sysCacheService;
_eventPublisher = eventPublisher;
_userManager = userManager;
}
/// <summary>
/// 分页查询@(@Model.BusName)
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[ApiDescriptionSettings(Name = "Page", Description = "分页查询", Order = 1000), HttpPost]
[DisplayName("分页查询@(@Model.BusName)")]
public async Task<SqlSugarPagedList<Page@(@Model.ClassName)Output>> Page(Page@(@Model.ClassName)Input input)
{
return await @(@Model.ClassName)Mid.GetQuery(_@(@Model.LowerClassName)Rep, input).Select<Page@(@Model.ClassName)Output>().OrderBuilder(input).ToPagedListAsync(input.Page, input.PageSize);
}
/// <summary>
/// 增加@(@Model.BusName)
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[ApiDescriptionSettings(Name = "Add", Description = "增加@(@Model.BusName)", Order = 990), HttpPost]
[DisplayName("增加@(@Model.BusName)")]
public async Task<object> Add(Add@(@Model.ClassName)Input input)
{
var entity = input.Adapt<@(@Model.ClassName)>(_typeAdapterConfig);
@if(Model.RemoteVerify){
@://验证重复值
@:if (await _@(@Model.LowerClassName)Rep.IsAnyAsync(t => t.@(RemoteField) == entity.@(RemoteField)))
@:{
@://已存在
@:throw Oops.Oh(ErrorCodeEnum.D1006);
@:}
}
@:}, true);
} else {
// 无联表
@:.Select<Detail@(@Model.ClassName)Output>();
}
await _@(@Model.LowerClassName)Rep.InsertAsync(entity);
return entity.@(@PKName);
}
/// <summary>
/// 删除@(@Model.BusName)
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[ApiDescriptionSettings(Name = "Delete", Description = "删除(@Model.BusName)", Order = 980), HttpPost]
[DisplayName("删除@(@Model.BusName)")]
public async Task Delete(Delete@(@Model.ClassName)Input input)
{
@foreach (var column in Model.TableField){
if (@column.ColumnKey == "True"){
@:var entity = await _@(@Model.LowerClassName)Rep.GetFirstAsync(u => u.@(@column.PropertyName) == input.@(@column.PropertyName)) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
}
}
//HJ:通过模板判断是否存在IsDelete字段决定删除方式
@if (Model.TableField.Any(c => c.PropertyName == "IsDelete"))
{
@:await _@(Model.LowerClassName)Rep.FakeDeleteAsync(entity); // 假删除存在IsDelete字段
}
else
{
@:await _@(Model.LowerClassName)Rep.DeleteAsync(entity); // 真删除不存在IsDelete字段
}
return await query.FirstAsync(u => @Model.PrimaryKeysFormat(" && ", "u.{0} == input.{0}"));
}
/// <summary>
/// 更新@(@Model.BusName)
/// 增加@(Model.BusName)
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[ApiDescriptionSettings(Name = "Update", Description = "更新@(@Model.BusName)", Order = 970), HttpPost]
[DisplayName("更新@(@Model.BusName)")]
public async Task Update(Update@(@Model.ClassName)Input input)
[DisplayName("增加@(Model.BusName)")]
[ApiDescriptionSettings(Name = "Add"), HttpPost]
public async Task<@(Model.PrimaryFields.First().NetType)> Add(Add@(Model.ClassName)Input input)
{
var entity = input.Adapt<@(@Model.ClassName)>(_typeAdapterConfig);
entity.Id = input.Id;
@if(Model.RemoteVerify){
@://验证重复值
@:if (await _@(@Model.LowerClassName)Rep.IsAnyAsync(t => t.@(RemoteField) == entity.@(RemoteField) && t.@(@PKName) != entity.@(@PKName)))
@:{
@://已存在
@:throw Oops.Oh(ErrorCodeEnum.D1006);
@:}
var entity = input.Adapt<@(Model.ClassName)>();
@foreach (var column in Model.AllFields.Where(u => u.IsUnique)) {
@:if (@(column.IsRequired ? "" : $"input.{column.PropertyName} != null && ")await _@(Model.LowerClassName)Rep.IsAnyAsync(u => u.@(column.PropertyName) == input.@(column.PropertyName))) throw Oops.Oh("@(column.ColumnComment)已存在");
}
await _@(@Model.LowerClassName)Rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
return await _@(Model.LowerClassName)Rep.InsertAsync(entity) ? entity.@(Model.PrimaryFields.First().PropertyName) : default;
}
/// <summary>
/// 获取@(@Model.BusName)详情
/// 更新@(Model.BusName) ✏️
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[ApiDescriptionSettings(Name = "Detail", Description = "获取@(@Model.BusName)", Order = 960), HttpGet]
[DisplayName("获取@(@Model.BusName)")]
public async Task<@(@Model.ClassName)> Detail([FromQuery] QueryById@(@Model.ClassName)Input input)
[DisplayName("更新@(Model.BusName)")]
[ApiDescriptionSettings(Name = "Update"), HttpPost]
public async Task Update(Update@(Model.ClassName)Input input)
{
@foreach (var column in Model.TableField){
if (@column.ColumnKey == "True"){
@:return await _@(@Model.LowerClassName)Rep.GetFirstAsync(u => u.@(@column.PropertyName) == input.@(@column.PropertyName));
}
}
@foreach (var column in Model.AllFields.Where(u => u.IsUnique)) {
var preWhere = column.IsRequired ? "" : $"input.{column.PropertyName} != null && ";
var preWhere2 = Model.PrimaryKeysFormat(" && ", "u.{0} != input.{0}");
@:if (@(preWhere)await _@(Model.LowerClassName)Rep.IsAnyAsync(u => @preWhere2 && u.@(column.PropertyName) == input.@(column.PropertyName))) throw Oops.Oh("@(column.ColumnComment)已存在");
}
var entity = await _@(Model.LowerClassName)Rep.GetFirstAsync(u => @Model.PrimaryKeysFormat(" && ", "u.{0} == input.{0}")) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
entity.Copy(input);
await _@(Model.LowerClassName)Rep.AsUpdateable(entity).ExecuteCommandAsync();
}
/// <summary>
/// 导入@(@Model.BusName)
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
[DisplayName("导入@(@Model.BusName)")]
public async Task Import([Required] IFormFile file)
{
using MemoryStream stream = new();
await file.CopyToAsync(stream);
var res = await new ExcelImporter().Import<@(@Model.ClassName)Dto>(stream);
if (res == null || res.Exception != null)
throw Oops.Oh(res.Exception);
var importData = res.Data.ToList();
// 按照编码条件进行批量更新或者新增
await _@(@Model.LowerClassName)Rep.Context.Storageable(importData.Adapt<List<@(@Model.ClassName)>>()).WhereColumns(u => u.Id).ExecuteCommandAsync();
}
/// <summary>
/// 导出@(@Model.BusName)
/// </summary>
/// <returns></returns>
[DisplayName("导出@(@Model.BusName)")]
public async Task<IActionResult> Export(Page@(@Model.ClassName)Input input)
{
var list = await @(@Model.ClassName)Mid.GetQuery(_@(@Model.LowerClassName)Rep, input).Select<@(@Model.ClassName)Dto>().OrderBuilder(input).ToListAsync();
if (list == null || list.Count < 1)
throw Oops.Oh("数据为空,导出已取消");
var res = await new ExcelExporter().ExportAsByteArray(list);
return new FileStreamResult(new MemoryStream(res), "application/octet-stream") { FileDownloadName = DateTime.Now.ToString("yyyyMMddHHmm") + "@(@Model.BusName)列表.xlsx" };
}
/// <summary>
/// 下载导入@(@Model.BusName)模板
/// </summary>
/// <returns></returns>
[DisplayName("下载导入@(@Model.BusName)模板")]
public async Task<IActionResult> DownloadTemplate()
{
var res = await new ExcelImporter().GenerateTemplateBytes<@(@Model.ClassName)Dto>();
return new FileStreamResult(new MemoryStream(res), "application/octet-stream") { FileDownloadName = "@(@Model.BusName)导入模板.xlsx" };
}
/// <summary>
/// 获取@(@Model.BusName)列表
/// 删除@(Model.BusName) ❌
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[ApiDescriptionSettings(Name = "List", Description = "获取@(@Model.BusName)列表", Order = 950), HttpPost]
[DisplayName("获取@(@Model.BusName)列表")]
public async Task<List<List@(@Model.ClassName)Output>> List(Page@(@Model.ClassName)Input input)
[DisplayName("删除@(Model.BusName)")]
[ApiDescriptionSettings(Name = "Delete"), HttpPost]
public async Task Delete(Primarykey@(Model.ClassName)Input input)
{
return await @(@Model.ClassName)Mid.GetQuery(_@(@Model.LowerClassName)Rep, input).Select<List@(@Model.ClassName)Output>().OrderBuilder(input).ToListAsync();
var entity = await _@(Model.LowerClassName)Rep.GetFirstAsync(u => @Model.PrimaryKeysFormat(" && ", "u.{0} == input.{0}")) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
@if (Model.AllFields.Any(u => u.PropertyName == "IsDelete")) {
@:await _@(Model.LowerClassName)Rep.FakeDeleteAsync(entity); // 假删除
// await _@(Model.LowerClassName)Rep.DeleteAsync(entity); //真删除
} else {
// await _@(Model.LowerClassName)Rep.FakeDeleteAsync(entity); // 假删除
@:await _@(Model.LowerClassName)Rep.DeleteAsync(entity); //真删除
}
}
/*HJ:不要这应该在视图里,或者用ReZero里用
/// <summary>
/// 获取@(@Model.BusName)
/// 批量删除@(Model.BusName) ❌
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[ApiDescriptionSettings(Name = "GetTotalSum", Description = "获取@(@Model.BusName)统计", Order = 960), HttpPost]
[DisplayName("获取@(@Model.BusName)统计")]
public async Task<List<@(@Model.ClassName)Output>> GetTotalSum(Page@(@Model.ClassName)Input input)
[DisplayName("批量删除@(Model.BusName)")]
[ApiDescriptionSettings(Name = "BatchDelete"), HttpPost]
public async Task<int> BatchDelete([Required(ErrorMessage = "主键列表不能为空")]List<@(Model.IsOnlyIdPrimary ? Model.PrimaryFields.First().NetType : $"Delete{Model.ClassName}")> input)
{
// 单次查询同时获取统计值
var querystats = @(@Model.ClassName)Mid.GetQuery(_@(@Model.LowerClassName)Rep, input)
@if(@Model.TableField.Any(x=>x.IsGroupBy == "Y")){
@foreach (var column in Model.TableField){
if (@column.IsGroupBy == "Y"){
@: .GroupByIF(input.GroupBy.Contains("@column.PropertyName"), u => u.@column.PropertyName)
}
@if (Model.IsOnlyIdPrimary) {
@:var list = await _@(Model.LowerClassName)Rep.AsQueryable().Where(u => input.Contains(u.Id)).ToListAsync();
} else {
@:var exp = Expressionable.Create<@(Model.ClassName)>();
@:foreach (var row in input) exp = exp.Or(it => @Model.PrimaryKeysFormat(" && ", "it.{0} == row.{0}"));
@:var list = await _@(Model.LowerClassName)Rep.AsQueryable().Where(exp.ToExpression()).ToListAsync();
}
@: //.Having(it => SqlFunc.AggregateCount(it.Id) > 0)//聚合函数过滤
}
.Select(it => new @(@Model.ClassName)Output
{
// count = SqlFunc.AggregateCount(it.Id),
@foreach (var column in Model.TableField){
if (@column.IsGroupBy == "Y"){
@: @(@column.PropertyName) = it.@(@column.PropertyName),
}
if (@column.Statistical == "Y"){
@: @(@column.PropertyName) = SqlFunc.AggregateSum(it.@(@column.PropertyName)) ?? 0,
}
}
});
return await querystats.ToListAsync();
}
*/
/*HJ:不要危险度大,容易SQL注入,且不符合规范
/// <summary>
/// 根据输入参数获取@(@Model.BusName)统计
/// 支持双模式聚合配置:
/// 常规模式Field + Function
/// 高级模式CustomExpression支持任意合法SQL表达式
/// 智能条件组合:
/// 多个HAVING条件自动用AND连接
/// 条件表达式自动包裹聚合函数如SUM(cost) > 10000
/// 可扩展支持OR条件
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[ApiDescriptionSettings(Name = "GetAggregTotalSum", Order = 970), HttpPost]
[DisplayName("根据输入参数获取@(@Model.BusName)统计")]
public async Task<List<@(@Model.ClassName)Output>> GetAggregTotalSum(Page@(@Model.ClassName)Input input)
{
var query = @(@Model.ClassName)Mid.GetQuery(_@(@Model.LowerClassName)Rep, input);
// 输入参数示例
//input = new Page@(@Model.ClassName)Input
//{
// GroupBy = ["department", "project"],
// GroupBy = input.GroupBy,
// Aggregations =
// [
// new AggregationConfig
//{
// Field = "cost",
// Function = AggregateFunction.Sum,
// Alias = "totalCost",
// HavingCondition = "> 10000"
//},
//new AggregationConfig
//{
// CustomExpression = "AVG(CAST(response_time AS FLOAT))",
// Alias = "avgResponse",
// HavingCondition = "< 500"
//}
// ]
//};
// 生成SQL示例
// SELECT
// department, project,
// SUM(cost) AS totalCost,
// AVG(CAST(response_time AS FLOAT)) AS avgResponse
// FROM...
// GROUP BY department, project
// HAVING(SUM(cost) > 10000) AND(AVG(CAST(response_time AS FLOAT)) < 500)
@if(@Model.TableField.Any(x=>x.Statistical == "Y")){
@:// 处理分组字段
@:var groupFields = AggregationBuilder.ValidateFields<@(@Model.ClassName)Output>(input.GroupBy, typeof(@(@Model.ClassName)Output));
@:if (groupFields.Count > 0)
@:{
@: query = query.GroupBy(string.Join(",", groupFields));
@:}
@:// 构建聚合配置
@:var aggregator = new AggregationBuilder(
@: configs: input.Aggregations,
@: entityType: typeof(@(@Model.ClassName)),
@: outputType: typeof(@(@Model.ClassName)Output)
@:);
@:// 组合SELECT语句
@:var selectParts = groupFields.Select(f => $"{f} AS {f}")
@: .Concat(aggregator.SelectParts)
@: .ToList();
@:// 应用HAVING条件
@:if (aggregator.HavingConditions.Count > 0)
@:{
@: query = query.Having(string.Join(" AND ", aggregator.HavingConditions));
@:}
@:// 执行查询
@:return await query.Select<@(@Model.ClassName)Output>(string.Join(", ", selectParts)).ToListAsync();
}
else
{
@:return await query.ToListAsync();
@if (Model.AllFields.Any(u => u.PropertyName == "IsDelete")) {
@:return await _@(Model.LowerClassName)Rep.FakeDeleteAsync(list); // 假删除
//return await _@(Model.LowerClassName)Rep.DeleteAsync(list); //真删除
} else {
//return await _@(Model.LowerClassName)Rep.FakeDeleteAsync(list) ? list.Count : 0; // 假删除
@:return await _@(Model.LowerClassName)Rep.DeleteAsync(list) ? list.Count : 0; //真删除
}
}
*/
@foreach (var column in Model.TableField){
if(@column.EffectType == "ForeignKey" && (@column.WhetherAddUpdate == "Y" || column.QueryWhether == "Y")){
@if (Model.HasStatus) {
@:
@:/// <summary>
@:/// 获取@(@column.ColumnComment)列表
@:/// </summary>
@:/// <returns></returns>
@:[ApiDescriptionSettings(Name = "@(LowerFirstLetter(@column.FkEntityName))@(@column.PropertyName)Dropdown", Description = "获取@(@column.ColumnComment)列表", Order = 940), HttpGet]
@:[DisplayName("获取@(@column.ColumnComment)列表")]
@:public async Task<List<LabelValueOutput>> @(@column.FkEntityName)@(@column.PropertyName)Dropdown()
@:{
@:return (await _@(@column.LowerFkEntityName)Rep.GetListAsync(t => t.Id > 0))
@:.Select(u => new LabelValueOutput
@:{
@:Label = u.@(@column.FkColumnName),
@:Value = u.@(@column.FkLinkColumnName).ToString()
@:}
@:).ToList();
@:}
}
}
@foreach (var column in Model.TableField){
if(@column.EffectType == "Upload"){
@:/// <summary>
@:/// 上传@(@column.ColumnComment)
@:/// </summary>
@:/// <param name="file"></param>
@:/// <returns></returns>
@:[ApiDescriptionSettings(Name = "Upload@(@column.PropertyName)", Description = "上传@(@column.ColumnComment)", Order = 930), HttpPost]
@:[DisplayName("上传@(@column.ColumnComment)")]
@:public async Task<SysFile> Upload@(@column.PropertyName)([Required] IFormFile file)
@:{
@:var service = App.GetRequiredService<SysFileService>();
@:return await service.UploadFile(new UploadFileInput { File = file}, "upload/@(@column.PropertyName)" );
@:}
}
}
@foreach (var column in Model.TableField){
if(@column.EffectType == "ApiTreeSelector" && !definedObjects.ContainsKey("@(@column.FkEntityName)Tree")){
@:/// <summary>
@:/// 获取@(@Model.BusName)树列表
@:/// 设置@(Model.BusName)状态 🚫
@:/// </summary>
@:/// <param name="input"></param>
@:/// <returns></returns>
@:[ApiDescriptionSettings(Name = "Tree", Description = "获取@(@Model.BusName)树列表", Order = 960), HttpPost]
@:[DisplayName("获取@(@Model.BusName)树列表")]
@:public async Task<dynamic> Tree(Page@(@Model.ClassName)Input input)
@:[DisplayName("设置@(Model.BusName)状态")]
@:[ApiDescriptionSettings(Name = "SetStatus"), HttpPost]
@:public async Task SetStatus(Set@(Model.ClassName)StatusInput input)
@:{
@:// 有筛选条件时返回list列表防止构造不出树
@:var isSearch=false;
foreach (var columnTree in Model.TableField){
if (@columnTree.QueryWhether == "Y"){
if (@columnTree.NetType?.TrimEnd('?') == "string"){
@:if(!string.IsNullOrWhiteSpace(input.@columnTree.PropertyName))isSearch=true;
}else if((@columnTree.NetType?.TrimEnd('?') == "int" || @columnTree.NetType?.TrimEnd('?') == "long")){
@:if(input.@columnTree.PropertyName>0)isSearch=true;
}else if((@columnTree.NetType?.TrimEnd('?') == "DateTime" && @columnTree.QueryType == "~")){
@:if(input.@(@columnTree.PropertyName)Range != null)isSearch=true;
} }}
@:if (isSearch||!string.IsNullOrEmpty(input.SearchKey?.Trim()))
@:{
@:// 有筛选条件时返回列表
@:return await @(@Model.ClassName)Mid.GetQuery(_@(@Model.LowerClassName)Rep, input).OrderBuilder(input).Distinct().ToListAsync();
@:}
@:// 无筛选条件时返回树列表
@:return await @(@Model.ClassName)Mid.GetQuery(_@(@Model.LowerClassName)Rep, input).OrderBuilder(input).ToTreeAsync(u => u.Children, u => u.Pid, 0, u => u.Id);
@:await _@(Model.LowerClassName)Rep.AsUpdateable().SetColumns(u => u.Status, input.Status).Where(u => @Model.PrimaryKeysFormat(" && ", "u.{0} == input.{0}")).ExecuteCommandAsync();
@:}
}
}
@if(Model.RemoteVerify){
@foreach (var column in Model.UploadFields) {
@:/// <summary>
@:/// 检查@(RemoteField)字段是否可用
@:/// 上传@(column.ColumnComment) ⬆️
@:/// </summary>
@:/// <param name="param">检查字段参数</param>
@:/// <param name="file"></param>
@:/// <returns></returns>
@:[ApiDescriptionSettings(Name = "exists@(RemoteField)",Description = "检查@(RemoteField)字段是否可用", Order = 910), HttpPost]
@:[DisplayName("检查@(RemoteField)字段是否可用")]
@:public async Task<bool> Exists@(RemoteField)Async(Exists@(RemoteField)Input param)
@:[DisplayName("上传@(column.ColumnComment)")]
@:[ApiDescriptionSettings(Name = "Upload@(column.PropertyName)"), HttpPost]
@:public async Task<SysFile> Upload@(column.PropertyName)([Required] IFormFile file)
@:{
@:if (string.IsNullOrWhiteSpace(param.FieldValue))
@:{
@:return false;
@:}
@:if (!string.IsNullOrWhiteSpace(param.OldFieldValue))
@:{
@:if (param.FieldValue.Trim() == param.OldFieldValue.Trim())
@:{
@://编辑状态下触发的
@:return true;
@:}
@:}
@:return await _sysFileService.UploadFile(new UploadFileInput { File = file, SavePath = "upload/@(Model.ClassName)/@(column.PropertyName)" });
@:}
@:
}
@:return !(await _@(@Model.LowerClassName)Rep.IsAnyAsync(t => t.@(RemoteField).Equals(param.FieldValue.Trim())));
@foreach (var column in Model.ApiFields.GroupBy(u => new { u.IsTree, u.JoinConfig.EntityName }).Select(u => u.First()).ToList()) {
var extarName = column.IsTree ? "Tree" : "Page";
var methodName = column.JoinConfig.EntityName + extarName;
@:/// <summary>
@:/// 获取@(column.JoinConfig.TableComment)数据 ⬆️
@:/// </summary>
@:/// <param name="input"></param>
@:/// <returns></returns>
@:[DisplayName("获取@(column.JoinConfig.TableComment)数据")]
@:[ApiDescriptionSettings(Name = "@(methodName)"), HttpPost]
@:public async Task<@(column.IsTree ? "List" : "SqlSugarPagedList")<@(column.JoinConfig.EntityName)>> @(methodName)(@(extarName + Model.ClassName + column.JoinConfig.EntityName)Input input)
@:{
@:return await _db.Queryable<@(column.JoinConfig.EntityName)>()
if (!string.IsNullOrWhiteSpace(column.JoinConfig.SearchPropertyName)) {
@:.WhereIF(!string.IsNullOrWhiteSpace(input.Keyword), u => u.@(column.JoinConfig.SearchPropertyName).Contains(input.Keyword))
}
if (column.IsTree) {
if (string.IsNullOrWhiteSpace(column.JoinConfig.ParentPropertyName)) {
@:.ToListAsync();
} else {
@:.ToTreeAsync(u => u.Children, u => u.@(column.JoinConfig.ParentPropertyName), 0);
}
} else {
@:.InnerJoinIF<@Model.ClassName>(!input.All, (u, r) => @(column.Multiple ? $"r.{column.PropertyName}.Contains(u.{column.JoinConfig.LinkPropertyName}.ToString())" : $"u.{column.JoinConfig.LinkPropertyName} == r.{column.PropertyName}"))
@:.Select(u => u).MergeTable().OrderBuilder(input)
@:.ToPagedListAsync(input.Page, input.PageSize);
}
@:}
@:
}
@if (Model.ImportFields.Count > 0) {
@:/// <summary>
@:/// 导出@(Model.BusName)记录 🔖
@:/// </summary>
@:/// <param name="input"></param>
@:/// <returns></returns>
@:[DisplayName("导出@(Model.BusName)记录")]
@:[ApiDescriptionSettings(Name = "Export"), HttpPost, NonUnify]
@:public async Task<IActionResult> Export(Export@(@Model.ClassName)Input input)
@:{
@:var list = (await Page(input)).Items?.Adapt<List<Export@(Model.ClassName)Output>>() ?? new();
@:if (input.SelectKeyList?.Count > 0) list = list.Where(x => input.SelectKeyList.Contains(x.@(Model.PrimaryFields.First().PropertyName))).ToList();
var dictFields = Model.TableFields.Where(x => x.IsImport && x.IsDict) ?? default;
foreach (var column in dictFields) {
@:var @(column.LowerPropertyName)DictMap = _sysDictTypeService.GetDataList(new GetDataDictTypeInput { Code = "@(column.DictConfig.Code)" }).Result.ToDictionary(x => x.Value, x => x.Label);
}
if (dictFields.Count() > 0) {
@:list.ForEach(e => {
foreach (var column in dictFields) {
@:e.@(column.PropertyName + "Label") = @(column.LowerPropertyName)DictMap.GetValueOrDefault(e.@(column.PropertyName) ?? "", e.@(column.PropertyName));
}
@:});
}
@:return ExcelHelper.ExportTemplate(list, "@(Model.BusName)导出记录");
@:}
@:
@:/// <summary>
@:/// 下载@(Model.BusName)数据导入模板 ⬇️
@:/// </summary>
@:/// <returns></returns>
@:[DisplayName("下载@(Model.BusName)数据导入模板")]
@:[ApiDescriptionSettings(Name = "Import"), HttpGet, NonUnify]
@:public IActionResult DownloadTemplate()
@:{
var fieldsList = Model.ImportFields.Where(u => u.IsForeignKey || u.IsTree).ToList();
if (fieldsList.Any()) {
@:return ExcelHelper.ExportTemplate(new List<Export@(Model.ClassName)Output>(), "@(Model.BusName)导入模板", (_, info) =>
@:{
@:// 自定义指定列下拉框数据源
foreach (var column in fieldsList) {
var columnList = column.JoinConfig.DisplayPropertyNames.Split(",").Select(n => $"{{u.{n}}}").ToList();
@:if (nameof(Export@(Model.ClassName)Output.@(column.PropertyName + "Label")) == info.Name) return _db.Queryable<@(column.JoinConfig.EntityName)>().Select(u => $"@(string.Join("-", columnList))").Distinct().ToList();
}
@:return null;
@:});
} else {
@:return ExcelHelper.ExportTemplate(new List<Export@(Model.ClassName)Output>(), "@(Model.BusName)导入模板");
}
@:}
@:
@:/// <summary>
@:/// 导入@(Model.BusName)记录 💾
@:/// </summary>
@:/// <returns></returns>
@:[DisplayName("导入@(Model.BusName)记录")]
@:[ApiDescriptionSettings(Name = "Import"), HttpPost, NonUnify, UnitOfWork]
@:public IActionResult ImportData([Required] IFormFile file)
@:{
@:lock (this)
@:{
var dictTableField = Model.TableFields.Where(x => x.IsImport && x.IsDict) ?? default;
foreach (var column in dictTableField) {
@:var @(column.LowerPropertyName)DictMap = _sysDictTypeService.GetDataList(new GetDataDictTypeInput { Code = "@(column.DictConfig.Code)" }).Result.ToDictionary(x => x.Label!, x => x.Value);
}
@:var stream = ExcelHelper.ImportData<Import@(Model.ClassName)Input, @(Model.ClassName)>(file, (list, markerErrorAction) =>
@:{
@:_db.Utilities.PageEach(list, 1024, pageItems =>
@:{
foreach (var column in Model.ImportFields.Where(u => u.IsForeignKey || u.IsTree)) {
@:// 链接 @(column.ColumnComment)
@:var @(column.LowerPropertyName)LabelList = pageItems.Where(x => x.@(column.PropertyName + "Label") != null).Select(x => x.@(column.PropertyName + "Label")).Distinct().ToList();
@:if (@(column.LowerPropertyName)LabelList.Any()) {
var columnList = column.JoinConfig.DisplayPropertyNames.Split(",").Select(n => $"{{u.{n}}}").ToList();
@:var @(column.LowerPropertyName)LinkMap = _db.Queryable<@(column.JoinConfig.EntityName)>().Where(u => @(column.LowerPropertyName)LabelList.Contains($"@(string.Join("-", columnList))")).ToList().ToDictionary(u => $"@(string.Join("-", columnList))", u => u.@(column.JoinConfig.LinkPropertyName));
@:pageItems.ForEach(e => {
if (column.Multiple) {
@:e.@(column.PropertyName) = e.@(column.PropertyName + "Label").Split(",").Select(x => @(column.LowerPropertyName)LinkMap.GetValueOrDefault(x)).Join();
} else {
@:e.@(column.PropertyName) = @(column.LowerPropertyName)LinkMap.GetValueOrDefault(e.@(column.PropertyName + "Label") ?? "");
}
@:if (e.@(column.PropertyName) == null) e.Error = "@(column.ColumnComment)链接失败";
@:});
@:}
}
if (dictTableField.Any()) {
@:
@:// 映射字典值
@:foreach(var item in pageItems) {
foreach (var column in dictTableField) {
@:if (string.IsNullOrWhiteSpace(item.@(column.PropertyName + "Label"))) continue;
@:item.@(column.PropertyName) = @(column.LowerPropertyName)DictMap.GetValueOrDefault(item.@(column.PropertyName + "Label"));
@:if (item.@(column.PropertyName) == null) item.Error = "@(column.ColumnComment)字典映射失败";
}
@:}
}
@:
@:// 校验并过滤必填基本类型为null的字段
@:var rows = pageItems.Where(x => {
foreach (var column in Model.ImportFields.Where(x => x.IsRequired && Regex.IsMatch(x.NetType, "(int|long|double|float|bool|Enum[?]?)"))){
@:if (!string.IsNullOrWhiteSpace(x.Error)) return false;
@:if (x.@(column.PropertyName) == null) {
@:x.Error = "@(column.ColumnComment)不能为空";
@:return false;
@:}
}
@:return true;
@:}).Adapt<List<@(Model.ClassName)>>();
@:
@:var storageable = _@(Model.LowerClassName)Rep.Context.Storageable(rows)
foreach (var column in Model.ImportFields) {
if (column.IsRequired) {
if(column.NetType.TrimEnd('?') == "string") {
@:.SplitError(it => string.IsNullOrWhiteSpace(it.Item.@(column.PropertyName)), "@(column.ColumnComment)不能为空")
} else if(column.NetType.EndsWith('?') == true) {
@:.SplitError(it => it.Item.@(column.PropertyName) == null, "@(column.ColumnComment)不能为空")
}}
if (column.NetType?.TrimEnd('?') == "string" && column.ColumnLength > 0) {
@:.SplitError(it => it.Item.@(column.PropertyName)?.Length > @(column.ColumnLength), "@(column.ColumnComment)长度不能超过@(column.ColumnLength)个字符")
}
if (column.IsUnique) {
@:.WhereColumns(it => it.@(column.PropertyName)).SplitError(it => it.Any(), "@(column.ColumnComment)已存在")
}}
@:.SplitInsert(_ => true)
@:.ToStorage();
@:
@:storageable.BulkCopy();
@:storageable.BulkUpdate();
@:
@:// 标记错误信息
@:markerErrorAction.Invoke(storageable, pageItems, rows);
@:});
@:});
@:
@:return stream;
@:}
@:}
}
}
@{
string LowerFirstLetter(string text)
{
return text.ToString()[..1].ToLower() + text[1..]; // 首字母小写
}
}
}

View File

@ -1,71 +0,0 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
@{
long lastId=0;
long pid=0;
int zindex=0;
int orderNo=0;
string createTime="";
}
namespace @(@Model.NameSpace).SeedData;
/// <summary>
/// @(@Model.BusName)系统菜单表种子数据
/// </summary>
// [IncreSeed]
public class @(@Model.ClassName)MenuSeedData : ISqlSugarEntitySeedData<SysMenu>
{
/// <summary>
/// 种子数据
/// </summary>
/// <returns></returns>
public IEnumerable<SysMenu> HasData()
{
//菜单列表
var list = new List<SysMenu>();
#region @(@Model.BusName)
@foreach (var menu in Model.MenuList){
@{
zindex=zindex+1;
}
@if((int)menu.Type==1){
@:list.Add(new SysMenu { Id = @(menu.Id), Pid = @(menu.Pid), Title = "@(menu.Title)", Path = "@(menu.Path)", Name = "@(menu.Name)", Component = "Layout", Icon = "@(menu.Icon)", Type = MenuTypeEnum.Dir, CreateTime = DateTime.Parse("@(menu.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"))"), OrderNo = @(menu.OrderNo) });
}
@if((int)menu.Type==2){
@{
pid=menu.Id;
}
@:list.Add(new SysMenu { Id = @(menu.Id), Pid = @(menu.Pid), Title = "@(menu.Title)", Path = "@(menu.Path)", Name = "@(menu.Name)", Component = "@(menu.Component)", Icon = "@(menu.Icon)", Type = MenuTypeEnum.Menu, CreateTime = DateTime.Parse("@(menu.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"))"), OrderNo = @(menu.OrderNo) });
}
@if((int)menu.Type==3) {
@:list.Add(new SysMenu { Id = @(menu.Id), Pid = @(menu.Pid), Title = "@(menu.Title)", Permission = "@(menu.Permission)", Type = MenuTypeEnum.Btn, CreateTime = DateTime.Parse("@(menu.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"))"), OrderNo = @(menu.OrderNo) });
}
@if(zindex==Model.MenuList.Count){
lastId=menu.Id-18888;
orderNo=menu.OrderNo;
createTime=menu.CreateTime.ToString("yyyy-MM-dd HH:mm:ss");
}
}
@if(@Model.PrintType != "off"){
@:list.Add(new SysMenu { Id = @(lastId+1), Pid = @(pid), Title = "打印", Permission = "@(LowerFirstLetter(@Model.ClassName))/print", Type = MenuTypeEnum.Btn, CreateTime = DateTime.Parse("@(createTime)"), OrderNo = @(orderNo+10) });
}
// list.Add(new SysMenu { Id = @(lastId+2), Pid = @(pid), Title = "导入", Permission = "@(LowerFirstLetter(@Model.ClassName))/import", Type = MenuTypeEnum.Btn, CreateTime = DateTime.Parse("@(createTime)"), OrderNo = @(orderNo+20) });
// list.Add(new SysMenu { Id = @(lastId+3), Pid = @(pid), Title = "导出", Permission = "@(LowerFirstLetter(@Model.ClassName))/export", Type = MenuTypeEnum.Btn, CreateTime = DateTime.Parse("@(createTime)"), OrderNo = @(orderNo+30) });
#endregion
return list;
}
}
@{
string LowerFirstLetter(string text)
{
return text.ToString()[..1].ToLower() + text[1..]; // 首字母小写
}
}

View File

@ -1,177 +1,63 @@
////////////////////////////////////////////////////////////////////
// 作者:@(Model.AuthorName ?? "喵你个汪")
// 时间:@(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
// 邮箱:@(Model.Email ?? "Admin.NET@qq.com")
////////////////////////////////////////////////////////////////////
import {useBaseApi} from '/@@/api/base';
// @(Model.BusName)接口服务
export const use@(Model.ClassName)Api = () => {
const baseApi = useBaseApi("@(Model.LowerClassName)");
return {
// 分页查询@(Model.BusName)
page: baseApi.page,
// 查看@(Model.BusName)列表
list: baseApi.list,
// 查看@(Model.BusName)详细
detail: baseApi.detail,
// 新增@(Model.BusName)
add: baseApi.add,
// 更新@(Model.BusName)
update: baseApi.update,
@if (Model.HasStatus) {
@:// 设置@(Model.BusName)状态
@:setStatus: baseApi.setStatus,
}
// 删除@(Model.BusName)
delete: baseApi.delete,
// 批量删除@(Model.BusName)
batchDelete: baseApi.batchDelete,
@if (Model.ImportFields.Count > 0) {
@:// 导出@(Model.BusName)数据
@:exportData: baseApi.exportData,
@:// 导入@(Model.BusName)数据
@:importData: baseApi.importData,
@:// 下载@(Model.BusName)数据导入模板
@:downloadTemplate: baseApi.downloadTemplate,
}
@foreach (var column in Model.ApiFields.GroupBy(u => new { u.IsTree, u.JoinConfig.EntityName }).Select(u => u.First()).ToList()) {
var methodName = column.JoinConfig.EntityName + (column.IsTree ? "Tree" : "Page");
@:// 获取@(column.JoinConfig.TableComment)数据
@:get@(methodName): (data: any, cancel: boolean = false) => baseApi.request({
@: url: baseApi.baseUrl + '@(Model.GetFirstLower(methodName))',
@: method: 'post',
@: data
@:}, cancel),
}
@foreach (var column in Model.UploadFields) {
@:// 上传@(column.ColumnComment)
@:upload@(column.PropertyName): (params: any, cancel: boolean = false) => baseApi.uploadFile(params, 'upload@(column.PropertyName)', cancel),
}
}
}
// @(Model.BusName)实体
export interface @(Model.ClassName) {
@{
Dictionary<string, int> definedObjects = new Dictionary<string, int>();
string RemoteField="";
string PKName="";
foreach (var column in Model.TableField){
if(column.RemoteVerify){
RemoteField=@column.PropertyName;
}
if(column.ColumnKey == "True"){
PKName=column.PropertyName;
}
}
foreach (var column in Model.AllFields) {
@:// @(column.ColumnComment) @(column.NetType)
@:@(column.LowerPropertyName)@(column.IsRequired ? "" : "?"): @(Model.GetTypeScriptType(column.NetType));
}
import request from '/@@/utils/request';
enum Api {
Add@(@Model.ClassName) = '/api/@(@Model.LowerClassName)/add',
Delete@(@Model.ClassName) = '/api/@(@Model.LowerClassName)/delete',
Update@(@Model.ClassName) = '/api/@(@Model.LowerClassName)/update',
Page@(@Model.ClassName) = '/api/@(@Model.LowerClassName)/page',
List@(@Model.ClassName) = '/api/@(@Model.LowerClassName)/list',
Tree@(@Model.ClassName) = '/api/@(@Model.LowerClassName)/GetTreeList',
Get@(@Model.ClassName)TotalSum = '/api/@(@Model.LowerClassName)/GetTotalSum',
Get@(@Model.ClassName)AggregTotalSum = '/api/@(@Model.LowerClassName)/GetAggregTotalSum',
Detail@(@Model.ClassName) = '/api/@(@Model.LowerClassName)/detail',
@if(Model.RemoteVerify){
@:Exists@(RemoteField) = '/api/@(@Model.LowerClassName)/exists@(RemoteField)',
}
@foreach (var column in Model.TableField){
if(@column.EffectType == "ForeignKey" && (@column.WhetherAddUpdate == "Y" || column.QueryWhether == "Y")){
@:Get@(@column.FkEntityName)@(@column.PropertyName)Dropdown = '/api/@(@Model.LowerClassName)/@(LowerFirstLetter(@column.FkEntityName))@(@column.PropertyName)Dropdown',
}else if(@column.EffectType == "ApiTreeSelector" && !definedObjects.ContainsKey("Get@(@column.FkEntityName)Tree")){
@{definedObjects.Add("Get@(@column.FkEntityName)Tree", 1);}
@:Get@(@column.FkEntityName)Tree = '/api/@(@Model.LowerClassName)/@(LowerFirstLetter(@column.FkEntityName))Tree',
}else if(@column.EffectType == "Upload"){
@:Upload@(@column.PropertyName) = '/api/@(@Model.LowerClassName)/upload@(@column.PropertyName)',
}
}
}
// 增加@(@Model.BusName)
export const add@(@Model.ClassName) = (params?: any) =>
request({
url: Api.Add@(@Model.ClassName),
method: 'post',
data: params,
});
// 删除@(@Model.BusName)
export const delete@(@Model.ClassName) = (params?: any) =>
request({
url: Api.Delete@(@Model.ClassName),
method: 'post',
data: params,
});
// 编辑@(@Model.BusName)
export const update@(@Model.ClassName) = (params?: any) =>
request({
url: Api.Update@(@Model.ClassName),
method: 'post',
data: params,
});
// 分页查询@(@Model.BusName)
export const page@(@Model.ClassName) = (params?: any) =>
request({
url: Api.Page@(@Model.ClassName),
method: 'post',
data: params,
});
// 列表查询@(@Model.BusName)
export const list@(@Model.ClassName) = (params?: any) =>
request({
url: Api.List@(@Model.ClassName),
method: 'post',
data: params,
});
// treelist@(@Model.BusName)
export const treelist@(@Model.ClassName) = (params?: any) =>
request({
url: Api.Tree@(@Model.ClassName),
method: 'post',
data: params,
});
// 获取统计,支持全表和分组
export const get@(@Model.ClassName)TotalSum = (params?: any) =>
request({
url: Api.Get@(@Model.ClassName)TotalSum,
method: 'post',
data: params,
});
// 输入参数获取统计
export const get@(@Model.ClassName)AggregTotalSum = (params?: any) =>
request({
url: Api.Get@(@Model.ClassName)AggregTotalSum,
method: 'post',
data: params,
});
// 详情@(@Model.BusName)
export const detail@(@Model.ClassName) = (id: any) =>
request({
url: Api.Detail@(@Model.ClassName),
method: 'get',
data: { id },
});
@foreach (var column in Model.TableField){
if(@column.EffectType == "ForeignKey" && (@column.WhetherAddUpdate == "Y" || column.QueryWhether == "Y")){
@:export const get@(@column.FkEntityName)@(@column.PropertyName)Dropdown = () =>
@:request({
@:url: Api.Get@(@column.FkEntityName)@(@column.PropertyName)Dropdown,
@:method: 'get'
@:});
}else if(@column.EffectType == "ApiTreeSelector" && !definedObjects.ContainsKey("get@(@column.FkEntityName)Tree")){
@{definedObjects.Add("get@(@column.FkEntityName)Tree", 1);}
@:export const get@(@column.FkEntityName)Tree = () =>
@:request({
@:url: Api.Get@(@column.FkEntityName)Tree,
@:method: 'get'
@:});
}else if(@column.EffectType == "Upload"){
@:// 上传@(@column.ColumnComment)
@:export const upload@(@column.PropertyName) = (params: any) => uploadFileHandle(params, Api.Upload@(@column.PropertyName))
}
}
@foreach (var column in Model.TableField){
if(@column.EffectType == "Upload"){
@:export const uploadFileHandle = (params: any, url: string) => {
@:const formData = new window.FormData();
@:formData.append('file', params.file);
@://自定义参数
@:if (params.data) {
@:Object.keys(params.data).forEach((key) => {
@:const value = params.data![key];
@:if (Array.isArray(value)) {
@:value.forEach((item) => {
@:formData.append(`${key}[]`, item);
@:});
@:return;
@:}
@:formData.append(key, params.data![key]);
@:});
@:}
@:return request({
@:url: url,
@:method: 'POST',
@:data: formData,
@:headers: {
@:'Content-type': 'multipart/form-data;charset=UTF-8',
@:// ts-ignore
@:ignoreCancelToken: true,
@:},
@:});
@:};
break;
}
}
@if(Model.RemoteVerify){
@:// 检查@(RemoteField)是否存在
@:export const exists@(RemoteField) = (params?: any) =>
@:request({
@:url: Api.Exists@(RemoteField),
@:method: 'post',
@:data: params,
@:});
}
@{
string LowerFirstLetter(string text)
{
return text.ToString()[..1].ToLower() + text[1..]; // 首字母小写
}
}

View File

@ -1,113 +0,0 @@
@{
string LowerFirstLetter(string text)
{
return text.ToString()[..1].ToLower() + text[1..]; // 首字母小写
}
var pkField = Model.TableField.Where(c => c.ColumnKey == "True").FirstOrDefault();
string pkFieldName = null;
if(pkField != null && !string.IsNullOrEmpty(pkField.PropertyName))
{
pkFieldName = LowerFirstLetter(pkField.PropertyName);
}
Dictionary<string, int> definedObjects = new Dictionary<string, int>();
bool haveLikeCdt = false;
foreach (var column in Model.TableField){
if (column.QueryWhether == "Y" && column.QueryType == "like"){
haveLikeCdt = true;
}
}
}
<template>
<div class="@(@Model.LowerClassName)-container">
<splitpanes class="default-theme">
<pane size="15" style="display: flex">
<@(@Model.LeftTab)Tree ref="@(@Model.LowerLeftTab)TreeRef" @@node-click="handleNodeChange" />
</pane>
<pane size="85" style="display: flex; flex-direction: column;">
<splitpanes horizontal>
<pane size="60" style="display: flex;flex-direction: column;">
<IndexList ref="indexListRef" @@list-click="handleIndexChange" />
</pane>
<pane size="40" style="display: flex; flex-direction: column;">
<el-tabs v-model="activeName" type="border-card"
style="height: 100%; padding: 0px; margin-bottom: 0px; position: relative">
<el-tab-pane label="属性1" name="1" style="height: 100%; margin-bottom: 0px; position: relative">
<@(@Model.BottomTab)Bottom ref="@(@Model.LowerBottomTab)BottomRef" @@list-click="handleBottomChange" />
</el-tab-pane>
<el-tab-pane label="属性2" name="2" style="height: 100%; margin-bottom: 0px; position: relative">
<div></div>
</el-tab-pane>
</el-tabs>
</pane>
</splitpanes>
</pane>
</splitpanes>
</div>
</template>
<script lang="ts" setup name="@(@Model.LowerClassName)">
import { onMounted, reactive, ref } from 'vue';
import { ElMessageBox, ElMessage } from "element-plus";
import { Splitpanes, Pane } from 'splitpanes';
import 'splitpanes/dist/splitpanes.css';
import @(@Model.LeftTab)Tree from '/@@/views/@(@Model.PagePath)/@(@Model.LowerLeftTab)/component/@(@Model.LowerLeftTab)Tree.vue';
import IndexList from '/@@/views/@(@Model.PagePath)/@(@Model.LowerClassName)/component/@(@Model.LowerClassName)List.vue';
import @(@Model.BottomTab)Bottom from '/@@/views/@(@Model.PagePath)/@(@Model.LowerBottomTab)/component/@(@Model.LowerBottomTab)List.vue';
const indexListRef = ref<InstanceType<typeof IndexList>>();
const @(@Model.LowerBottomTab)BottomRef = ref<InstanceType<typeof @(@Model.BottomTab)Bottom>>();
const activeName = ref('1');
// 变量
const state = reactive({
queryParams: {
searchKey: undefined,
@if(Model.QueryWhetherList.Count > 0) {
@foreach (var column in Model.QueryWhetherList) {
@:@(@column.LowerPropertyName): undefined,
}
}
},
});
// 页面初始化
onMounted(() => {
});
// 树组件点击
const handleNodeChange = async (node: any) => {
console.log('handleNodeChange--', JSON.stringify(node));
state.queryParams={};//每次重置参数
state.queryParams["@(@Model.LowerLeftPrimaryKey)"] = node.data.@(@Model.LowerLeftKey);//树主表关联字段=树关联字段
console.log('handleNodeChange--', state.queryParams.@(@Model.LowerLeftPrimaryKey));
await indexListRef.value?.listhandleQuery(state.queryParams);
await @(@Model.LowerBottomTab)BottomRef.value?.listhandleQuery({@(@Model.LowerBottomKey):'1'});//重置下表一个不可能有的条件
};
// 主表List组件点击
const handleIndexChange = async (row: any,column: any) => {
console.log('handleIndexChange--', JSON.stringify(row));
console.log('handleIndexChange--', JSON.stringify(column));
state.queryParams.@(@Model.LowerBottomKey) = row.@(@Model.LowerBottomPrimaryKey);//下关联字段=下表主表关联字段
console.log('handleIndexChange--', state.queryParams.@(@Model.LowerBottomKey));
await @(@Model.LowerBottomTab)BottomRef.value?.listhandleQuery(state.queryParams);
};
const handleBottomChange = async (row: any) => {
console.log('handleBottomChange--', JSON.stringify(row));
};
</script>
<style lang="scss" scoped>
:deep(.el-input),
:deep(.el-select),
:deep(.el-input-number) {
width: 100%;
}
:deep(.el-slider .el-input-number){
width: auto;
}
</style>

View File

@ -1,82 +0,0 @@
@{
string LowerFirstLetter(string text)
{
return text.ToString()[..1].ToLower() + text[1..]; // 首字母小写
}
var pkField = Model.TableField.Where(c => c.ColumnKey == "True").FirstOrDefault();
string pkFieldName = null;
if(pkField != null && !string.IsNullOrEmpty(pkField.PropertyName))
{
pkFieldName = LowerFirstLetter(pkField.PropertyName);
}
Dictionary<string, int> definedObjects = new Dictionary<string, int>();
bool haveLikeCdt = false;
foreach (var column in Model.TableField){
if (column.QueryWhether == "Y" && column.QueryType == "like"){
haveLikeCdt = true;
}
}
}
<template>
<div class="@(@Model.LowerClassName)-container">
<splitpanes class="default-theme">
<pane size="15" style="display: flex">
<@(@Model.LeftTab)Tree ref="@(@Model.LowerLeftTab)TreeRef" @@node-click="handleNodeChange" />
</pane>
<pane size="85" style="display: flex; flex-direction: column">
<IndexList ref="indexListRef" @@list-click="handleIndexChange" />
</pane>
</splitpanes>
</div>
</template>
<script lang="ts" setup name="@(@Model.LowerClassName)">
import { onMounted, reactive, ref } from 'vue';
import { ElMessageBox, ElMessage } from "element-plus";
import { Splitpanes, Pane } from 'splitpanes';
import 'splitpanes/dist/splitpanes.css';
import @(@Model.LeftTab)Tree from '/@@/views/@(@Model.PagePath)/@(@Model.LowerLeftTab)/component/@(@Model.LowerLeftTab)Tree.vue';
import IndexList from '/@@/views/@(@Model.PagePath)/@(@Model.LowerClassName)/component/@(@Model.LowerClassName)List.vue';
const indexListRef = ref<InstanceType<typeof IndexList>>();
// 变量
const state = reactive({
queryParams: {
searchKey: undefined,
@if(Model.QueryWhetherList.Count > 0) {
@foreach (var column in Model.QueryWhetherList) {
@:@(@column.LowerPropertyName): undefined,
}
}
}
});
// 页面初始化
onMounted(() => {
indexListRef.value?.listhandleQuery(state.queryParams);//列表控件初始化不请求数据,这里要请求一下
});
// 树组件点击
const handleNodeChange = async (node: any) => {
console.log('handleNodeChange--', JSON.stringify(node));
state.queryParams["@(@Model.LowerLeftPrimaryKey)"] = node.data.@(@Model.LowerLeftKey);//树主表关联字段=树关联字段
console.log('handleNodeChange--', state.queryParams.@(@Model.LowerLeftPrimaryKey));
await indexListRef.value?.listhandleQuery(state.queryParams);
};
// 主表List组件点击
const handleIndexChange = async (row: any,column: any) => {
console.log('handleIndexChange--', JSON.stringify(row));
console.log('handleIndexChange--', JSON.stringify(column));
};
</script>
<style lang="scss" scoped>
:deep(.el-input),
:deep(.el-select),
:deep(.el-input-number) {
width: 100%;
}
:deep(.el-slider .el-input-number){
width: auto;
}
</style>

View File

@ -1,657 +0,0 @@
@{
string LowerFirstLetter(string text)
{
return text.ToString()[..1].ToLower() + text[1..]; // 首字母小写
}
var pkField = Model.TableField.Where(c => c.ColumnKey == "True").FirstOrDefault();
string pkFieldName = null;
if(pkField != null && !string.IsNullOrEmpty(pkField.PropertyName))
{
pkFieldName = LowerFirstLetter(pkField.PropertyName);
}
Dictionary<string, int> definedObjects = new Dictionary<string, int>();
bool haveLikeCdt = false;
foreach (var column in Model.TableField){
if (column.QueryWhether == "Y" && column.QueryType == "like"){
haveLikeCdt = true;
}
}
}
<template>
<el-card shadow="hover" :body-style="{ padding: '20px 20px 16px 10px', display: 'flex', width: '100%', height: '100%', alignItems: 'start' }">
<el-form :model="state.queryParams" ref="queryForm" :show-message="false" :inlineMessage="true" label-width="auto" style="flex: 1 1 0%" @@submit.prevent="handleQuery" >
<el-row :gutter="10">
@if(Model.QueryWhetherList.Count > 0){
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb5">
<el-form-item :label="$t('message.list.searchKey')" prop="searchKey">
<el-input v-model="state.queryParams.searchKey" :placeholder="$t('message.list.searchKeyInput')" clearable @@keyup.enter.native="handleQuery(true)" />
</el-form-item>
</el-col>
foreach (var column in Model.QueryWhetherList) {
if(@column.EffectType == "Input" || @column.EffectType == "InputTextArea") {
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb5" v-if="state.showAdvanceQueryUI">
<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" prop="@(@column.LowerPropertyName)">
<el-input v-model="state.queryParams.@(@column.LowerPropertyName)" :placeholder="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" clearable @@keyup.enter.native="handleQuery(true)" />
</el-form-item>
</el-col>
} else if(@column.EffectType == "InputNumber") {
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb5" v-if="state.showAdvanceQueryUI">
<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')">
<el-input-number v-model="state.queryParams.@(@column.LowerPropertyName)" :placeholder="$t('message.list.pleaseInput') + $t('message.@Model.LowerClassName.@column.LowerPropertyName')" clearable @@keyup.enter.native="handleQuery(true)" />
</el-form-item>
</el-col>
} else if(@column.EffectType == "ForeignKey") {
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb5" v-if="state.showAdvanceQueryUI">
<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')">
<el-select filterable="" v-model="state.queryParams.@(@column.LowerPropertyName)" :placeholder="$t('message.list.pleaseChoose') + $t('message.@Model.LowerClassName.@column.LowerPropertyName')" clearable>
<el-option v-for="(item,index) in @LowerFirstLetter(@column.FkEntityName)@(@column.PropertyName)DropdownList" :key="index" :value="item.value" :label="item.label" />
</el-select>
</el-form-item>
</el-col>
} else if(@column.EffectType == "DictSelector") {
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb5" v-if="state.showAdvanceQueryUI">
<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" prop="@(@column.LowerPropertyName)">
<el-select v-model="state.queryParams.@(@column.LowerPropertyName)" filterable :placeholder="$t('message.list.pleaseChoose') + $t('message.@Model.LowerClassName.@column.LowerPropertyName')" clearable @@keyup.enter.native="handleQuery(true)" >
<el-option v-for="(item,index) in dl('@(@column.DictTypeCode)')" :key="index" :value="item.value" :label="`${item.label} [${item.code}] ${item.value}`" />
</el-select>
</el-form-item>
</el-col>
} else if(@column.EffectType == "EnumSelector") {
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb5" v-if="state.showAdvanceQueryUI">
<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" prop="@(@column.LowerPropertyName)">
<el-select v-model="state.queryParams.@(@column.LowerPropertyName)" filterable :placeholder="$t('message.list.pleaseChoose') + $t('message.@Model.LowerClassName.@column.LowerPropertyName')" clearable @@keyup.enter.native="handleQuery(true)" >
<el-option v-for="(item,index) in dl('@(@column.DictTypeCode)')" :key="index" :value="item.value" :label="`${item.label} [${item.code}] ${item.value}`" />
</el-select>
</el-form-item>
</el-col>
} else if(@column.EffectType == "ApiTreeSelector") {
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb5" v-if="state.showAdvanceQueryUI">
<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" prop="@(@column.LowerPropertyName)">
<el-cascader
@:options="@LowerFirstLetter(@column.FkEntityName)TreeData"
@:props="{ checkStrictly: true, emitPath: false, value: '@LowerFirstLetter(@column.ValueColumn)', label: '@LowerFirstLetter(@column.DisplayColumn)' }"
:placeholder="$t('message.list.pleaseChoose')+ $t('message.@Model.LowerClassName.@column.LowerPropertyName')"
clearable=""
class="w100"
v-model="state.queryParams.@(@column.LowerPropertyName)"
>
<template #default="{ node, data }">
<span>{{ data.@LowerFirstLetter(@column.DisplayColumn) }}</span>
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
</template>
</el-cascader>
</el-form-item>
</el-col>
} else if(@column.EffectType == "DatePicker") {
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb5" v-if="state.showAdvanceQueryUI">
<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" prop="@(@column.LowerPropertyName)">
@if(@column.QueryType == "~"){
@:<el-date-picker type="daterange" v-model="state.queryParams.@(@column.LowerPropertyName)Range" value-format="YYYY-MM-DD HH:mm:ss" :start-placeholder="$t('message.list.beginTime')" :end-placeholder="$t('message.list.endTime')" :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" />
} else {
@:<el-date-picker :placeholder="$t('message.list.pleaseChoose') + $t('message.@Model.LowerClassName.@column.LowerPropertyName')" value-format="YYYY/MM/DD" v-model="state.queryParams.@(@column.LowerPropertyName)" />
}
</el-form-item>
</el-col>
}
}
}
</el-row>
</el-form>
<el-divider style="height: calc(100% - 5px); margin: 0 10px" direction="vertical" />
<el-row>
<el-col>
<el-button-group>
<el-button type="primary" icon="ele-Search" @@click="handleQuery(true)" v-auth="'@(@Model.LowerClassName)/page'" :loading="options.loading"> {{ $t('message.list.search') }} </el-button>
<el-button icon="ele-Refresh" @@click="resetQuery" :loading="options.loading"> {{ $t('message.list.reset') }} </el-button>
<el-button icon="ele-ZoomIn" @@click="changeAdvanceQueryUI" v-if="!state.showAdvanceQueryUI" style="margin-left: 5px"> {{ $t('message.list.zoomIn') }} </el-button>
<el-button icon="ele-ZoomOut" @@click="changeAdvanceQueryUI" v-if="state.showAdvanceQueryUI" style="margin-left: 5px"> {{ $t('message.list.zoomOut') }} </el-button>
</el-button-group>
</el-col>
</el-row>
</el-card>
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
<vxe-grid ref="xGrid" class="xGrid-style" v-bind="options" v-on="gridEvents">
<template #toolbar_buttons>
<el-button type="primary" icon="ele-Plus" @@click="handleAdd" v-auth="'@(@Model.LowerClassName)/add'"> {{ $t('message.list.add') }} </el-button>
<el-button-group type="primary" style="padding-left: 12px">
<el-button plain icon="ele-Upload" @@click="importData" v-auth="'@(@Model.LowerClassName)/import'"> {{ $t('message.list.import') }} </el-button>
<el-button plain icon="ele-Download" @@click="exportData" v-auth="'@(@Model.LowerClassName)/export'"> {{ $t('message.list.export') }} </el-button>
<el-button plain icon="ele-FolderOpened" @@click="downloadTemplate"> {{ $t('message.list.downloadTemplate') }} </el-button>
</el-button-group>
</template>
<template #toolbar_tools> </template>
<template #empty>
<el-empty :image-size="200" />
</template>
@foreach (var column in Model.TableField) {
if(@column.WhetherTable == "Y") {
if(@column.EffectType == "Upload") {
@:<template #row_@(@column.LowerPropertyName)="{ row }">
@:<el-popover
@:v-if="row.@column.LowerPropertyName"
@:placement="bottom"
@::width="60"
@::height="60"
@:trigger="hover">
@:<template #reference>
@:<el-tag>{{ $t('message.list.seeFile') }}</el-tag>
@:</template>
@:<template #default>
@:<el-image
@::src="row.@column.LowerPropertyName"
@::hide-on-click-modal="true"
@::preview-src-list="[row.@column.LowerPropertyName]"
@::initial-index="0"
@:fit="scale-down"
@:preview-teleported=""/>
@:</template>
@:</el-popover>
@:<el-tag v-else type="info">{{ $t('message.list.noFile') }}</el-tag>
@:</template>
} else if(@column.EffectType == "ForeignKey") {
@:<template #row_@(@column.LowerPropertyName)="{ row }">
@:<span>{{ row.@LowerFirstLetter(@column.PropertyName)@(@column.FkColumnName) }}</span>
@:</template>
} else if(@column.EffectType == "ApiTreeSelector") {
@:<template #row_@(@column.LowerPropertyName)="{ row }">
@:<span>{{ row.@LowerFirstLetter(@column.PropertyName)@(column.DisplayColumn) }}</span>
@:</template>
} else if(@column.EffectType == "Switch") {
@:<template #row_@(@column.LowerPropertyName)="{ row }">
@:<el-tag v-if="row.@(@column.LowerPropertyName)"> {{ $t('message.list.yes') }} </el-tag>
@:<el-tag type="danger" v-else> {{ $t('message.list.no') }} </el-tag>
@:</template>
} else if(@column.EffectType == "ConstSelector") {
@:<template #row_@(@column.LowerPropertyName)="{ row }">
@:<span>{{codeToName(row.@(@column.LowerPropertyName), '@(@column.DictTypeCode)')}}</span>
@:</template>
} else if(@column.EffectType == "DictSelector") {
@:<template #row_@(@column.LowerPropertyName)="{ row }">
@:<el-tag v-if="row.@(@column.LowerPropertyName)" :type="dc('@(@column.DictTypeCode)', row.@(@column.LowerPropertyName))?.tagType"> {{dc('@(@column.DictTypeCode)', row.@column.LowerPropertyName)?.label}}</el-tag>
@:</template>
} else if(@column.EffectType == "EnumSelector") {
@:<template #row_@(@column.LowerPropertyName)="{ row }">
@:<el-tag :type="dv('@(@column.DictTypeCode)', row.@(@column.LowerPropertyName))?.tagType"> {{dv('@(@column.DictTypeCode)', row.@column.LowerPropertyName)?.name}}</el-tag>
@:</template>
}
}
}
<template #row_record="{ row }">
<ModifyRecord :data="row" />
</template>
<template #row_buttons="{ row }">
@if(@Model.PrintType != "off") {
<el-tooltip content="打印" placement="top">
<el-button icon="ele-Printer" size="small" text type="primary" @@click="handlePrint(row)" v-auth="'@(@Model.LowerClassName)/print'" />
</el-tooltip>
}
<el-tooltip :content="$t('message.list.edit')" placement="top">
<el-button icon="ele-Edit" size="small" text type="primary" @@click="handleEdit(row)" v-auth="'@(@Model.LowerClassName)/update'" />
</el-tooltip>
<el-tooltip :content="$t('message.list.delete')" placement="top">
<el-button icon="ele-Delete" size="small" text type="danger" @@click="handleDelete(row)" v-auth="'@(@Model.LowerClassName)/delete'" />
</el-tooltip>
</template>
</vxe-grid>
</el-card>
@if(@Model.PrintType != "off"){
@:<PrintDialog ref="printDialogRef" :title="state.title" @@reloadTable="handleQuery" />
}
<el-dialog v-model="state.uploadVisible" :lock-scroll="false" draggable width="400px">
<template #header>
<div style="color: #fff">
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-UploadFilled /> </el-icon>
<span> {{ $t('message.list.import') }} </span>
</div>
</template>
<div>
<el-upload ref="uploadRef" drag :auto-upload="false" :limit="1" :file-list="state.fileList" action="" :on-change="handleChange" accept=".xlsx">
<el-icon class="el-icon--upload">
<ele-UploadFilled />
</el-icon>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<template #tip>
<div class="el-upload__tip">请上传大小不超过 10MB 的文件</div>
</template>
</el-upload>
</div>
<template #footer>
<span class="dialog-footer">
<el-button icon="ele-CircleCloseFilled" @@click="state.uploadVisible = false">{{ $t('message.list.cancelButtonText') }}</el-button>
<el-button type="primary" icon="ele-CircleCheckFilled" @@click="uploadFile">{{ $t('message.list.confirmButtonText') }}</el-button>
</span>
</template>
</el-dialog>
<EditDialog ref="editDialogRef" :title="state.title" @@reloadTable="handleQuery" />
</template>
<script lang="ts" setup name="@(@Model.LowerClassName)">
import { onMounted, reactive, ref } from 'vue';
import { ElMessageBox, ElMessage } from "element-plus";
import { useUserInfo } from '/@@/stores/userInfo';
import { VxeGridInstance, VxeGridListeners, VxeGridPropTypes } from 'vxe-table';
import { useVxeTable } from '/@@/hooks/useVxeTableOptionsHook';
import { Local } from '/@@/utils/storage';
import { auth } from '/@@/utils/authFunction';
import EditDialog from '/@@/views/@(@Model.PagePath)/@(@Model.LowerClassName)/component/edit.vue';
import ModifyRecord from '/@@/components/table/modifyRecord.vue';
import { useI18n } from 'vue-i18n';
import { downloadByData, getFileName } from '/@@/utils/download';
@if(@Model.TableField.Any(x=>x.EffectType == "DatePicker")){
@:// 日历控件
@:import { formatDate } from '/@@/utils/formatTime';
}
@if(@Model.PrintType != "off"){
@://打印控件
@:import { hiprint } from 'vue-plugin-hiprint';
@:import { SysPrintApi } from '/@@/api-services/api';
@:import { SysPrint } from '/@@/api-services/models';
@:import PrintDialog from '/@@/views/system/print/component/hiprint/preview.vue';
}
@if (@Model.IsApiService) {
@://接口控件
@:import { getAPI } from '/@@/utils/axios-utils';
@:import { @(@Model.ClassName)Api } from '/@@/api-services/api';
@:import { @(@Model.ClassName), Page@(@Model.ClassName)Input, Page@(@Model.ClassName)Output } from '/@@/api-services/models';
} else {
//下面这个是废弃的
@:import { page@(@Model.ClassName), delete@(@Model.ClassName), get@(@Model.ClassName)TotalSum } from '/@@/api/@(@Model.PagePath)/@(@Model.LowerClassName)';
foreach (var column in Model.QueryWhetherList){
if(@column.EffectType == "ForeignKey"){
@:import { get@(@column.FkEntityName)@(@column.PropertyName)Dropdown } from '/@@/api/@(@Model.PagePath)/@(@Model.LowerClassName)';
}
if(@column.EffectType == "ApiTreeSelector"){
@:import { get@(@column.FkEntityName)Tree } from '/@@/api/@(@Model.PagePath)/@(@Model.LowerClassName)';
}
}
}
//基础变量
const { t } = useI18n();
const xGrid = ref<VxeGridInstance>();
const editDialogRef = ref<InstanceType<typeof EditDialog>>();
const userStore = useUserInfo();
@if(@Model.PrintType != "off") {
@://打印控件
@:const printDialogRef = ref<InstanceType<typeof PrintDialog>>();
}
@if(@Model.TableField.Any(x=>x.EffectType == "ConstSelector")){
@://常量控件
@:const codeToName = userStore.codeToName;
}
@if(@Model.TableField.Any(x=>x.EffectType == "DictSelector") || @Model.TableField.Any(x=>x.EffectType == "EnumSelector")){
@//字典枚举控件
@:const dc = userStore.getDictItemByValue;
@:const dv = userStore.getDictItemByLabel;
@:const dl = userStore.getDictDataByCode;
}
// 变量赋值
const state = reactive({
showAdvanceQueryUI: false,
queryParams: {
searchKey: undefined,
GroupBy: [] as any,
@if(Model.QueryWhetherList.Count > 0) {
@foreach (var column in Model.QueryWhetherList) {
@:@(@column.LowerPropertyName): undefined,
@if(@column.EffectType == "DatePicker"){
@:@(@column.LowerPropertyName)Range: undefined,
}
}
}
},
localPageParam: {
pageSize: 50 as number,
defaultSort: { field: 'Id', order: 'asc', descStr: 'desc' },
},
totalSum:[] as any,
visible: false,
title: '',
uploadVisible: false,
fileList: [] as any,
});
// 本地存储参数
const localPageParamKey = 'localPageParam:@(@Model.LowerClassName)';
// 改变高级查询的控件显示状态
const changeAdvanceQueryUI = () => {
state.showAdvanceQueryUI = !state.showAdvanceQueryUI;
};
// 校验表格字段权限
const checkTableColumnVisible = (tableColumnName: any) => {
return !userStore.userTableList.includes(tableColumnName);
};
// 表格参数配置
@if (@Model.IsApiService) {
@:const options = useVxeTable<Page@(@Model.ClassName)Output>(
} else {
@:const options = useVxeTable(
}
{
id: '@(@Model.ClassName)',
name: t('message.@Model.LowerClassName.@Model.LowerClassName'),
columns: [
{ type: 'seq', title: t('message.list.number'), width: 60, fixed: 'left' },
@foreach (var column in Model.TableField) {
var whethersortable =column.WhetherSortable == "Y" ? "sortable: true" : "sortable: false";
if(@column.WhetherTable == "Y") {
if(@column.EffectType == "Upload" || @column.EffectType == "ForeignKey" || @column.EffectType == "ApiTreeSelector" || @column.EffectType == "Switch" || @column.EffectType == "ConstSelector") {
if(@column.EffectType == "Upload") {
@:{ visible: checkTableColumnVisible('@(@Model.LowerClassName):@(@column.LowerPropertyName)'), field: '@column.LowerPropertyName', title: t('message.@Model.LowerClassName.@column.LowerPropertyName'), minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' }, @whethersortable },
} else if(@column.EffectType == "ForeignKey") {
@:{ visible: checkTableColumnVisible('@(@Model.LowerClassName):@(@column.LowerPropertyName)'), field: '@column.LowerPropertyName', title: t('message.@Model.LowerClassName.@column.LowerPropertyName'), minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' }, @whethersortable },
} else if(@column.EffectType == "ApiTreeSelector") {
@:{ visible: checkTableColumnVisible('@(@Model.LowerClassName):@(@column.LowerPropertyName)'), field: '@column.LowerPropertyName', title: t('message.@Model.LowerClassName.@column.LowerPropertyName'), minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' }, @whethersortable },
} else if(@column.EffectType == "Switch") {
@:{ visible: checkTableColumnVisible('@(@Model.LowerClassName):@(@column.LowerPropertyName)'), field: '@column.LowerPropertyName', title: t('message.@Model.LowerClassName.@column.LowerPropertyName'), minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' }, @whethersortable },
} else if(@column.EffectType == "ConstSelector") {
@:{ visible: checkTableColumnVisible('@(@Model.LowerClassName):@(@column.LowerPropertyName)'), field: '@column.LowerPropertyName', title: t('message.@Model.LowerClassName.@column.LowerPropertyName'), minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' }, @whethersortable },
}
} else if(@column.EffectType == "DictSelector") {
@:{ visible: checkTableColumnVisible('@(@Model.LowerClassName):@(@column.LowerPropertyName)'), field: '@column.LowerPropertyName', title: t('message.@Model.LowerClassName.@column.LowerPropertyName'), minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' }, @whethersortable },
} else if(@column.EffectType == "EnumSelector") {
@:{ visible: checkTableColumnVisible('@(@Model.LowerClassName):@(@column.LowerPropertyName)'), field: '@column.LowerPropertyName', title: t('message.@Model.LowerClassName.@column.LowerPropertyName'), minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' }, @whethersortable },
} else if(@column.EffectType == "DatePicker") {
@:{ visible: checkTableColumnVisible('@(@Model.LowerClassName):@(@column.LowerPropertyName)'), field: '@column.LowerPropertyName', title: t('message.@Model.LowerClassName.@column.LowerPropertyName'), minWidth: 100, showOverflow: 'tooltip', formatter: ({ cellValue }) => cellValue==null?'':formatDate(new Date(cellValue), 'YYYY-mm-dd HH:MM:SS'), @whethersortable },
} else {
@:{ visible: checkTableColumnVisible('@(@Model.LowerClassName):@(@column.LowerPropertyName)'), field: '@column.LowerPropertyName', title: t('message.@Model.LowerClassName.@column.LowerPropertyName'), minWidth: 100, showOverflow: 'tooltip', @whethersortable},
}
}
}
@if(@Model.TableField.Any(t => t.ColumnName == "CreateTime") && @Model.TableField.Any(t => t.ColumnName == "UpdateTime") && @Model.TableField.Any(t => t.ColumnName == "CreateUserId")){
@:{ field: 'record', title: t('message.list.record'), width: 100, showOverflow: 'tooltip', slots: { default: 'row_record' } },
}
{ field: 'buttons', title: t('message.list.action'), fixed: 'right', width: 180, showOverflow: true, slots: { default: 'row_buttons' } },
],
@if(@Model.TableField.Any(x=>x.Statistical == "Y")){
@:footerMethod: ({ columns, data }) => {
@: const totalSum=state.totalSum[0];
@: return [
@: columns.map((column, colIndex) => {
@: if (colIndex === 0) {
@: return `合计:`
@: }
@foreach (var column in Model.TableField){
if (@column.Statistical == "Y"){
@: if (column.field === '@(@column.LowerPropertyName)') {
@: // 计算表格内总和
@: return `${data.reduce((sum, row) => sum + (row.@(@column.LowerPropertyName) || 0), 0)}/总数:${totalSum?.@(@column.LowerPropertyName)||0}`
@: }
}
}
@: })
@: ]
@:},
}
},
// vxeGrid配置参数(此处可覆写任何参数)参考vxe-table官方文档
{
// 代理配置//加载时不立刻获取
proxyConfig: { autoLoad: false, ajax: { query: ({ page, sort }) => handleQueryApi(page, sort) , queryAll: ({ sort }) => handleQueryAllApi(sort) } },
// 排序配置
sortConfig: { defaultSort: Local.get(localPageParamKey)?.defaultSort || state.localPageParam.defaultSort },
// 分页配置
pagerConfig: { pageSize: Local.get(localPageParamKey)?.pageSize || state.localPageParam.pageSize },
// 工具栏配置
toolbarConfig: { export: false },
// 行设置
// rowConfig: { height: 80 },
// 设置列显隐
customConfig: {
visibleMethod({ column }) {
return checkTableColumnVisible(`@Model.LowerClassName:${column.field}`);
},
},
@if(@Model.TableField.Any(x=>x.Statistical == "Y")||@Model.TableField.Any(x=>x.IsGroupBy == "Y")){
@:showFooter: true, // ✅ 正确控制表尾显示
}
}
);
// 页面初始化
onMounted(() => {
});
// 查询api
const handleQueryApi = async (page: VxeGridPropTypes.ProxyAjaxQueryPageParams, sort: VxeGridPropTypes.ProxyAjaxQuerySortCheckedParams) => {
const params = Object.assign(state.queryParams, { page: page.currentPage, pageSize: page.pageSize, field: sort.field, order: sort.order, descStr: 'desc' }) as Page@(@Model.ClassName)Input;
@if (@Model.IsApiService) {
@:return getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)PagePost(params);
} else {
@:return page@(@Model.ClassName)(params);
}
};
// 查询所有api
const handleQueryAllApi = async (sort: VxeGridPropTypes.ProxyAjaxQuerySortCheckedParams) => {
const params = Object.assign(state.queryParams, { field: sort.field, order: sort.order, descStr: 'desc' }) as Page@(@Model.ClassName)Input;
@if (@Model.IsApiService) {
@:return getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)ListPost(params);
} else {
@:return list@(@Model.ClassName)(params);
}
};
// 查询操作
const handleQuery = async (reset = false) => {
options.loading = true;
state.queryParams.GroupBy = [];
@foreach (var column in Model.TableField){
if (@column.IsGroupBy == "Y"){
@:state.queryParams.GroupBy.push('@(@column.PropertyName)');
}
}
@if(@Model.TableField.Any(x=>x.Statistical == "Y")){
@if (@Model.IsApiService) {
@:state.totalSum =getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)GetTotalSumPost(params).data.result;
} else {
@:state.totalSum =(await get@(@Model.ClassName)TotalSum(state.queryParams)).data.result;
}
}
reset ? await xGrid.value?.commitProxy('reload') : await xGrid.value?.commitProxy('query');
options.loading = false;
};
const listhandleQuery= async (qparams: any) => {
console.log('listhandleQuery--', JSON.stringify(qparams));
if(qparams) state.queryParams=qparams;
await handleQuery(true);
};
// 重置操作
const resetQuery = async () => {
state.queryParams.searchKey = undefined;
@if(Model.QueryWhetherList.Count > 0) {
@foreach (var column in Model.QueryWhetherList) {
@:state.queryParams.@(@column.LowerPropertyName) = undefined;
}
}
await xGrid.value?.commitProxy('reload');
};
// 打开新增页面
const handleAdd = () => {
state.title = t('message.list.add')+t('message.@Model.LowerClassName.@Model.LowerClassName') ;
let data = {
@foreach (var column in Model.TableField){
if(@column.WhetherAddUpdate == "Y"&&@column.DefaultValue!=null){
if(@column.NetType.StartsWith("int")||@column.NetType.StartsWith("decimal")){
@:@column.LowerPropertyName:@(string.IsNullOrEmpty(@column.DefaultValue)?0:@column.DefaultValue),
}
if(@column.NetType.StartsWith("string")){
@:@column.LowerPropertyName:'@(@column.DefaultValue)',
}
}
}
};
editDialogRef.value?.openDialog(data);
};
// 打开编辑页面
const handleEdit = (row: any) => {
state.title = t('message.list.edit')+t('message.@Model.LowerClassName.@Model.LowerClassName') ;
editDialogRef.value?.openDialog(row);
};
@if(@Model.PrintType != "off") {
@:// 打开打印页面
@:const handlePrint = async (row: any) => {
@:state.title = t('message.list.print')+t('message.@Model.LowerClassName.@Model.LowerClassName') ;
@if(@Model.PrintType != "off"){
if (@Model.IsApiService) {
@:var res = await getAPI(SysPrintApi).apiSysPrintPrintNameGet('@Model.PrintName');
} else {
@:var res = await getPrint@(@Model.ClassName)(row);
}
@:var printTemplate = res.data.result as SysPrint;
@:var template = JSON.parse(printTemplate.template);
@:var width = template.panels[0].width;
@:row['barCode'] = row.code;
@:row['qrCode'] = row.code;
@:row["printDate"] = formatDate(new Date(), 'YYYY-mm-dd HH:MM');
@:printDialogRef.value.showDialog(new hiprint.PrintTemplate({template: template}), row, width);
}
@if(@Model.PrintType == "auto"){
@:printDialogRef.value.showDialog(row);
}
@:};
}
// 删除
const handleDelete = (row: any) => {
ElMessageBox.confirm(t('message.list.confirmDelete')+t('message.@Model.LowerClassName.@Model.LowerClassName')+`:【${row.id}】?`, t('message.list.tips'), {
confirmButtonText: t('message.list.submit'),
cancelButtonText: t('message.list.cancel'),
type: 'warning',
}).then(async () => {
@if (@Model.IsApiService) {
@:await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)DeletePost({ id: row.id });
} else {
@:await delete@(@Model.ClassName)(row);
}
await handleQuery();
ElMessage.success(t('message.list.deleteSuccess'));
})
.catch(() => {});
};
// 表格事件
@if (@Model.IsApiService) {
@:const gridEvents: VxeGridListeners<@(@Model.ClassName)> = {
} else {
@:const gridEvents: VxeGridListeners = {
}
// 行单击事件
async cellClick({ row, column }) {
listClick(row,column);
},
// 只对 pager-config 配置时有效,分页发生改变时会触发该事件
async pageChange({ pageSize }) {
state.localPageParam.pageSize = pageSize;
Local.set(localPageParamKey, state.localPageParam);
},
// 当排序条件发生变化时会触发该事件
async sortChange({ field, order }) {
state.localPageParam.defaultSort = { field: field, order: order!, descStr: 'desc' };
Local.set(localPageParamKey, state.localPageParam);
},
// 行双击事件
async cellDblclick({ row }) {
if (auth('@(@Model.LowerClassName)/update')) await handleEdit(row);
},
};
@foreach (var column in Model.QueryWhetherList) {
@if(@column.EffectType == "ForeignKey") {
@:const @LowerFirstLetter(@column.FkEntityName)@(@column.PropertyName)DropdownList = ref<any>([]);
@:const get@(@column.FkEntityName)@(@column.PropertyName)DropdownList = async () => {
@if (@Model.IsApiService) {
@:let list = await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)@(@column.FkEntityName)@(@column.PropertyName)DropdownGet();
} else {
@:let list = await get@(@column.FkEntityName)@(@column.PropertyName)Dropdown();
}
@:@LowerFirstLetter(@column.FkEntityName)@(@column.PropertyName)DropdownList.value = list.data.result ?? [];
@:};
@:get@(@column.FkEntityName)@(@column.PropertyName)DropdownList();
}
}
@foreach (var column in Model.QueryWhetherList) {
@if(@column.EffectType == "ApiTreeSelector") {
@:const @LowerFirstLetter(@column.FkEntityName)TreeData = ref<any>([]);
@:const get@(@column.FkEntityName)TreeData = async () => {
@if (@Model.IsApiService) {
@:let list = await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)@(@column.FkEntityName)Tree();
} else {
@:let list = await get@(@column.FkEntityName)Tree();
}
@:@LowerFirstLetter(@column.FkEntityName)TreeData.value = list.data.result ?? [];
@:};
@:get@(@column.FkEntityName)TreeData();
}
}
// 通过onChanne方法获得文件列表
const handleChange = (file: any, fileList: []) => {
state.fileList = fileList;
};
// 上传
const uploadFile = async () => {
if (state.fileList.length < 1) return;
state.uploadVisible = false;
options.loading = true;
await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)ImportPostForm(state.fileList[0].raw);
handleQuery();
ElMessage.success('上传成功');
state.fileList = [];
options.loading = false;
};
// 导入
const importData = () => {
state.uploadVisible = true;
};
// 导出
const exportData = async () => {
options.loading = true;
var res = await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)ExportPost(state.queryParams, { responseType: 'blob' });
options.loading = false;
var fileName = getFileName(res.headers);
downloadByData(res.data as any, fileName);
};
// 下载模板
const downloadTemplate = async () => {
var res = await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)DownloadTemplatePost({ responseType: 'blob' });
var fileName = getFileName(res.headers);
downloadByData(res.data as any, fileName);
};
// 与父组件的交互逻辑
const emits = defineEmits(['list-click']);
const listClick = (row: any,column:any) => {
emits('list-click', row,column);
};
// 将属性或者函数暴露给父组件
defineExpose({ listhandleQuery });
</script>

View File

@ -1,77 +1,58 @@
@{
string LowerFirstLetter(string text)
{
return text.ToString()[..1].ToLower() + text[1..]; // 首字母小写
}
var pkField = Model.TableField.Where(c => c.ColumnKey == "True").FirstOrDefault();
string pkFieldName = null;
if(pkField != null && !string.IsNullOrEmpty(pkField.PropertyName))
{
pkFieldName = LowerFirstLetter(pkField.PropertyName);
}
Dictionary<string, int> definedObjects = new Dictionary<string, int>();
bool haveLikeCdt = false;
foreach (var column in Model.TableField){
if (column.QueryWhether == "Y" && column.QueryType == "like"){
haveLikeCdt = true;
}
}
}
<template>
<el-card class="box-card" shadow="hover" body-style="height:100%;overflow:auto;padding:5px;width:100%;">
<template #header>
<div class="card-header">
<div class="tree-h-flex">
<div class="tree-h-left">
<el-input :prefix-icon="Search" v-model.lazy="filterText" clearable placeholder="@(@Model.BusName)" />
</div>
<div class="tree-h-right">
<el-dropdown @@command="handleCommand">
<el-button style="margin-left: 8px; width: 34px">
<el-icon class="el-icon--center">
<more-filled />
</el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="expandAll">全部展开</el-dropdown-item>
<el-dropdown-item command="collapseAll">全部折叠</el-dropdown-item>
<el-dropdown-item command="rootNode">根节点</el-dropdown-item>
<el-dropdown-item command="refresh">刷新</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
<el-checkbox v-if="!props.checkStrictly && state.isShowCheckbox" v-model="state.strictly" label="联动" style="margin-left: 8px" border />
</div>
</div>
</template>
<div style="margin-bottom: 45px" v-loading="state.loading">
<el-scrollbar>
<el-tree
ref="treeRef"
class="filter-tree"
:data="state.@(@Model.LowerClassName)Data"
node-key="id"
:props="{ children: 'children', label: 'name' }"
:filter-node-method="filterNode"
@@node-click="nodeClick"
:show-checkbox="state.isShowCheckbox"
:default-expanded-keys="state.@(@Model.LowerClassName)Data[0] && [state.@(@Model.LowerClassName)Data[0].id]"
:default-checked-keys="state.own@(@Model.ClassName)Data"
highlight-current
:check-strictly="!state.strictly"
>
<template #default="{ node }">
<el-icon v-if="node.level == 1" size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-School /></el-icon>
<el-icon v-else-if="node.level == 2" size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-Refrigerator /></el-icon>
<el-icon v-else size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-CollectionTag /></el-icon>
{{ node.label }}
</template>
</el-tree>
</el-scrollbar>
</div>
</el-card>
<template>
<el-card class="box-card" shadow="hover" body-style="height:100%; overflow:auto; padding:5px; width:100%;">
<template #header>
<div class="card-header">
<div class="tree-h-flex">
<div class="tree-h-left">
<el-input :prefix-icon="Search" v-model.lazy="filterText" clearable placeholder="@(Model.TreeConfig.TreeTitle)" />
</div>
<div class="tree-h-right">
<el-dropdown @@command="handleCommand">
<el-button style="margin-left: 8px; width: 34px">
<el-icon class="el-icon--center">
<more-filled />
</el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="expandAll">全部展开</el-dropdown-item>
<el-dropdown-item command="collapseAll">全部折叠</el-dropdown-item>
<el-dropdown-item command="rootNode">根节点</el-dropdown-item>
<el-dropdown-item command="refresh">刷新</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
<el-checkbox v-if="!props.checkStrictly && state.isShowCheckbox" v-model="state.strictly" label="联动" style="margin-left: 8px" border />
</div>
</div>
</template>
<div style="margin-bottom: 45px" v-loading="state.loading">
<el-scrollbar>
<el-tree
ref="treeRef"
class="filter-tree"
:data="state.@(Model.TreeConfig.LowerEntityName)Data"
node-key="@(Model.TreeConfig.LowerLinkPropertyName)"
:props="{ children: 'children', label: '@(Model.TreeConfig.LowerFirstDisplayName)' }"
:filter-node-method="filterNode"
@@node-click="nodeClick"
:show-checkbox="state.isShowCheckbox"
:default-expanded-keys="state.@(Model.TreeConfig.LowerEntityName)Data[0] && [state.@(Model.TreeConfig.LowerEntityName)Data[0].@(Model.TreeConfig.LowerLinkPropertyName)]"
:default-checked-keys="state.own@(Model.TreeConfig.EntityName)Data"
highlight-current
:check-strictly="!state.strictly"
>
<template #default="{ node }">
<el-icon v-if="node.level == 1" size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-School /></el-icon>
<el-icon v-else-if="node.level == 2" size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-Refrigerator /></el-icon>
<el-icon v-else size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-CollectionTag /></el-icon>
{{ node.label }}
</template>
</el-tree>
</el-scrollbar>
</div>
</el-card>
</template>
<script lang="ts" setup>
@ -79,91 +60,89 @@ import { onMounted, reactive, ref, watch } from 'vue';
import type { ElTree } from 'element-plus';
import { Search, MoreFilled } from '@@element-plus/icons-vue';
import { treelist@(@Model.ClassName)} from '/@@/api/@(@Model.PagePath)/@(@Model.LowerClassName)';
import { getAPI } from '/@@/utils/axios-utils';
import { @(Model.TreeConfig.EntityName)Api } from '/@@/api-services/@(Model.PagePath)/api';
import { @(Model.TreeConfig.EntityName) } from '/@@/api-services/@(Model.PagePath)/models';
import { TreeKey } from 'element-plus/es/components/tree/src/tree.type';
const props = defineProps({
checkStrictly: { type: Boolean, defaul: true },
checkStrictly: { type: Boolean, default: true },
});
const filterText = ref('');
const treeRef = ref<InstanceType<typeof ElTree>>();
const state = reactive({
loading: false,
@(@Model.LowerClassName)Data: [] as any,
isShowCheckbox: false,
own@(@Model.ClassName)Data: [],
strictly: false,
loading: false,
@(Model.TreeConfig.LowerEntityName)Data: [] as Array<@(Model.TreeConfig.EntityName)>,
isShowCheckbox: false,
own@(Model.TreeConfig.EntityName)Data: [],
strictly: false,
});
// 页面初始化
onMounted(async () => {
await fetchTreeData();
await fetchTreeData();
});
// 查询监听
watch(filterText, (val) => {
treeRef.value!.filter(val);
treeRef.value!.filter(val);
});
// 获取树数据
const fetchTreeData = async (showLoading: boolean = true) => {
if (showLoading) state.loading = true;
@if (@Model.IsApiService) {
@:var res = await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)GetTreeListPost({Id:0});
} else {
@:var res = await treelist@(@Model.ClassName)({Id:0});
}
state.@(@Model.LowerClassName)Data = res.data.result ?? [];
if (showLoading) state.loading = false;
return res.data.result ?? [];
if (showLoading) state.loading = true;
var res = await getAPI(@(Model.TreeConfig.EntityName)Api).api@(Model.TreeConfig.EntityName)ListGet(0);
state.@(Model.TreeConfig.LowerEntityName)Data = res.data.result ?? [];
if (showLoading) state.loading = false;
return res.data.result ?? [];
};
// 设置默认选择
const setCheckedKeys = (@(@Model.LowerClassName)Data: any) => {
state.isShowCheckbox = true;
treeRef.value!.setCheckedKeys([]);
state.own@(@Model.ClassName)Data = @(@Model.LowerClassName)Data;
const setCheckedKeys = (@(Model.TreeConfig.LowerEntityName)Data: any) => {
state.isShowCheckbox = true;
treeRef.value!.setCheckedKeys([]);
state.own@(Model.TreeConfig.EntityName)Data = @(Model.TreeConfig.LowerEntityName)Data;
};
// 获取已经选择
const getCheckedKeys = () => {
return treeRef.value!.getCheckedKeys();
return treeRef.value!.getCheckedKeys();
};
// 节点过滤
const filterNode = (value: string, data: any) => {
if (!value) return true;
return data.name.includes(value);
if (!value) return true;
return data.@(Model.TreeConfig.LowerSearchPropertyName).includes(value);
};
// 节点操作
const handleCommand = async (command: string | number | object) => {
if ('expandAll' == command) {
for (let i = 0; i < treeRef.value!.store._getAllNodes().length; i++) {
treeRef.value!.store._getAllNodes()[i].expanded = true;
}
} else if ('collapseAll' == command) {
for (let i = 0; i < treeRef.value!.store._getAllNodes().length; i++) {
treeRef.value!.store._getAllNodes()[i].expanded = false;
}
} else if ('refresh' == command) {
fetchTreeData();
} else if ('rootNode' == command) {
treeRef.value?.setCurrentKey();
emits('node-click', { id: 0, name: '' });
}
if ('expandAll' == command) {
for (let i = 0; i < treeRef.value!.store._getAllNodes().length; i++) {
treeRef.value!.store._getAllNodes()[i].expanded = true;
}
} else if ('collapseAll' == command) {
for (let i = 0; i < treeRef.value!.store._getAllNodes().length; i++) {
treeRef.value!.store._getAllNodes()[i].expanded = false;
}
} else if ('refresh' == command) {
fetchTreeData();
} else if ('rootNode' == command) {
treeRef.value?.setCurrentKey();
emits('node-click', { @(Model.TreeConfig.LowerLinkPropertyName): 0, @(Model.TreeConfig.LowerFirstDisplayName): '' });
}
};
// 与父组件的交互逻辑
const emits = defineEmits(['node-click']);
const nodeClick = (node: any) => {
emits('node-click', { id: node.id, name: node.name, data: node });
emits('node-click', { @(Model.TreeConfig.LowerLinkPropertyName): node.@(Model.TreeConfig.LowerLinkPropertyName), @(Model.TreeConfig.LowerFirstDisplayName): node.@(Model.TreeConfig.LowerFirstDisplayName) });
};
//设置当前选中节点
const setCurrentKey = (key?: TreeKey | undefined, shouldAutoExpandParent?: boolean | undefined) => {
treeRef.value?.setCurrentKey(key, shouldAutoExpandParent);
treeRef.value?.setCurrentKey(key, shouldAutoExpandParent);
};
// 导出对象
@ -172,22 +151,22 @@ defineExpose({ fetchTreeData, setCheckedKeys, getCheckedKeys, setCurrentKey });
<style lang="scss" scoped>
.box-card {
flex: 1;
> :deep(.el-card__header) {
padding: 5px;
}
flex: 1;
> :deep(.el-card__header) {
padding: 5px;
}
}
.tree-h-flex {
display: flex;
display: flex;
}
.tree-h-left {
flex: 1;
width: 100%;
flex: 1;
width: 100%;
}
.tree-h-right {
width: 42px;
min-width: 42px;
width: 42px;
min-width: 42px;
}
</style>
</style>

View File

@ -1,554 +0,0 @@
@{
string LowerFirstLetter(string text)
{
return text.ToString()[..1].ToLower() + text[1..]; // 首字母小写
}
var pkField = Model.TableField.Where(c => c.ColumnKey == "True").FirstOrDefault();
string pkFieldName = null;
if(pkField != null && !string.IsNullOrEmpty(pkField.PropertyName))
{
pkFieldName = LowerFirstLetter(pkField.PropertyName);
}
Dictionary<string, int> definedObjects = new Dictionary<string, int>();
bool haveLikeCdt = false;
foreach (var column in Model.TableField){
if (column.QueryWhether == "Y" && column.QueryType == "like"){
haveLikeCdt = true;
}
}
}
<template>
<el-card shadow="hover" :body-style="{ padding: '20px 20px 16px 10px', display: 'flex', width: '100%', height: '100%', alignItems: 'start' }">
<el-form :model="state.queryParams" ref="queryForm" :show-message="false" :inlineMessage="true" label-width="auto" style="flex: 1 1 0%" @@submit.prevent="handleQuery" >
<el-row :gutter="10">
@if(Model.QueryWhetherList.Count > 0){
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb5">
<el-form-item :label="$t('message.list.searchKey')" prop="searchKey">
<el-input v-model="state.queryParams.searchKey" :placeholder="$t('message.list.searchKeyInput')" clearable @@keyup.enter.native="handleQuery(true)" />
</el-form-item>
</el-col>
foreach (var column in Model.QueryWhetherList) {
if(@column.EffectType == "Input" || @column.EffectType == "InputTextArea") {
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb5" v-if="state.showAdvanceQueryUI">
<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" prop="@(@column.LowerPropertyName)">
<el-input v-model="state.queryParams.@(@column.LowerPropertyName)" :placeholder="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" clearable @@keyup.enter.native="handleQuery(true)" />
</el-form-item>
</el-col>
} else if(@column.EffectType == "InputNumber") {
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb5" v-if="state.showAdvanceQueryUI">
<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')">
<el-input-number v-model="state.queryParams.@(@column.LowerPropertyName)" :placeholder="$t('message.list.pleaseInput') + $t('message.@Model.LowerClassName.@column.LowerPropertyName')" clearable @@keyup.enter.native="handleQuery(true)" />
</el-form-item>
</el-col>
} else if(@column.EffectType == "ForeignKey") {
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb5" v-if="state.showAdvanceQueryUI">
<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')">
<el-select filterable="" v-model="state.queryParams.@(@column.LowerPropertyName)" :placeholder="$t('message.list.pleaseChoose') + $t('message.@Model.LowerClassName.@column.LowerPropertyName')" clearable>
<el-option v-for="(item,index) in @LowerFirstLetter(@column.FkEntityName)@(@column.PropertyName)DropdownList" :key="index" :value="item.value" :label="item.label" />
</el-select>
</el-form-item>
</el-col>
} else if(@column.EffectType == "DictSelector") {
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb5" v-if="state.showAdvanceQueryUI">
<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" prop="@(@column.LowerPropertyName)">
<el-select v-model="state.queryParams.@(@column.LowerPropertyName)" filterable :placeholder="$t('message.list.pleaseChoose') + $t('message.@Model.LowerClassName.@column.LowerPropertyName')" clearable @@keyup.enter.native="handleQuery(true)" >
<el-option v-for="(item,index) in dl('@(@column.DictTypeCode)')" :key="index" :value="item.value" :label="`${item.label} [${item.code}] ${item.value}`" />
</el-select>
</el-form-item>
</el-col>
} else if(@column.EffectType == "EnumSelector") {
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb5" v-if="state.showAdvanceQueryUI">
<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" prop="@(@column.LowerPropertyName)">
<el-select v-model="state.queryParams.@(@column.LowerPropertyName)" filterable :placeholder="$t('message.list.pleaseChoose') + $t('message.@Model.LowerClassName.@column.LowerPropertyName')" clearable @@keyup.enter.native="handleQuery(true)" >
<el-option v-for="(item,index) in dl('@(@column.DictTypeCode)')" :key="index" :value="item.value" :label="`${item.label} [${item.code}] ${item.value}`" />
</el-select>
</el-form-item>
</el-col>
} else if(@column.EffectType == "ApiTreeSelector") {
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb5" v-if="state.showAdvanceQueryUI">
<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" prop="@(@column.LowerPropertyName)">
<el-cascader
@:options="@LowerFirstLetter(@column.FkEntityName)TreeData"
@:props="{ checkStrictly: true, emitPath: false, value: '@LowerFirstLetter(@column.ValueColumn)', label: '@LowerFirstLetter(@column.DisplayColumn)' }"
:placeholder="$t('message.list.pleaseChoose') + $t('message.@Model.LowerClassName.@column.LowerPropertyName')"
clearable=""
class="w100"
v-model="state.queryParams.@(@column.LowerPropertyName)"
>
<template #default="{ node, data }">
<span>{{ data.@LowerFirstLetter(@column.DisplayColumn) }}</span>
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
</template>
</el-cascader>
</el-form-item>
</el-col>
} else if(@column.EffectType == "DatePicker") {
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb5" v-if="state.showAdvanceQueryUI">
<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" prop="@(@column.LowerPropertyName)">
@if(@column.QueryType == "~"){
@:<el-date-picker type="daterange" v-model="state.queryParams.@(@column.LowerPropertyName)Range" value-format="YYYY-MM-DD HH:mm:ss" :start-placeholder="$t('message.list.beginTime')" :end-placeholder="$t('message.list.endTime')" :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" />
} else {
@:<el-date-picker :placeholder="$t('message.list.pleaseChoose') + $t('message.@Model.LowerClassName.@column.LowerPropertyName')" value-format="YYYY/MM/DD" v-model="state.queryParams.@(@column.LowerPropertyName)" />
}
</el-form-item>
</el-col>
}
}
}
</el-row>
</el-form>
<el-divider style="height: calc(100% - 5px); margin: 0 10px" direction="vertical" />
<el-row>
<el-col>
<el-button-group>
<el-button type="primary" icon="ele-Search" @@click="handleQuery(true)" v-auth="'@(@Model.LowerClassName)/page'" :loading="options.loading"> {{ $t('message.list.search') }} </el-button>
<el-button icon="ele-Refresh" @@click="resetQuery" :loading="options.loading"> {{ $t('message.list.refresh') }} </el-button>
<el-button icon="ele-ZoomIn" @@click="changeAdvanceQueryUI" v-if="!state.showAdvanceQueryUI" style="margin-left: 5px"> {{ $t('message.list.zoomIn') }} </el-button>
<el-button icon="ele-ZoomOut" @@click="changeAdvanceQueryUI" v-if="state.showAdvanceQueryUI" style="margin-left: 5px"> {{ $t('message.list.zoomOut') }} </el-button>
</el-button-group>
</el-col>
</el-row>
</el-card>
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
<vxe-grid ref="xGrid" class="xGrid-style" v-bind="options" v-on="gridEvents">
<template #toolbar_buttons>
<el-button type="primary" icon="ele-Plus" @@click="handleAdd" v-auth="'@(@Model.LowerClassName)/add'"> {{ $t('message.list.add') }} </el-button>
<el-button-group style="padding-left: 12px">
<el-button type="primary" icon="ele-Expand" @@click="handleExpand"> {{ $t('message.list.expand') }} </el-button>
<el-button type="primary" icon="ele-Fold" @@click="handleFold"> {{ $t('message.list.fold') }} </el-button>
</el-button-group>
</template>
<template #toolbar_tools> </template>
<template #empty>
<el-empty :image-size="200" />
</template>
@foreach (var column in Model.TableField) {
if(@column.WhetherTable == "Y") {
if(@column.EffectType == "Upload") {
@:<template #row_@(@column.LowerPropertyName)="{ row }">
@:<el-popover
@:v-if="row.@column.LowerPropertyName"
@:placement="bottom"
@::width="60"
@::height="60"
@:trigger="hover">
@:<template #reference>
@:<el-tag>{{ $t('message.list.seeFile') }}</el-tag>
@:</template>
@:<template #default>
@:<el-image
@::src="row.@column.LowerPropertyName"
@::hide-on-click-modal="true"
@::preview-src-list="[row.@column.LowerPropertyName]"
@::initial-index="0"
@:fit="scale-down"
@:preview-teleported=""/>
@:</template>
@:</el-popover>
@:<el-tag v-else type="info">{{ $t('message.list.noFile') }}</el-tag>
@:</template>
} else if(@column.EffectType == "ForeignKey") {
@:<template #row_@(@column.LowerPropertyName)="{ row }">
@:<span>{{ row.@LowerFirstLetter(@column.PropertyName)@(@column.FkColumnName) }}</span>
@:</template>
} else if(@column.EffectType == "ApiTreeSelector") {
@:<template #row_@(@column.LowerPropertyName)="{ row }">
@:<span>{{ row.@LowerFirstLetter(@column.PropertyName)@(column.DisplayColumn) }}</span>
@:</template>
} else if(@column.EffectType == "Switch") {
@:<template #row_@(@column.LowerPropertyName)="{ row }">
@:<el-tag v-if="row.@(@column.LowerPropertyName)"> {{ $t('message.list.yes') }} </el-tag>
@:<el-tag type="danger" v-else> {{ $t('message.list.no') }} </el-tag>
@:</template>
} else if(@column.EffectType == "ConstSelector") {
@:<template #row_@(@column.LowerPropertyName)="{ row }">
@:<span>{{codeToName(row.@(@column.LowerPropertyName), '@(@column.DictTypeCode)')}}</span>
@:</template>
} else if(@column.EffectType == "DictSelector") {
@:<template #row_@(@column.LowerPropertyName)="{ row }">
@:<el-tag v-if="row.@(@column.LowerPropertyName)" :type="dc('@(@column.DictTypeCode)', row.@(@column.LowerPropertyName))?.tagType"> {{dc('@(@column.DictTypeCode)', row.@column.LowerPropertyName)?.label}}</el-tag>
@:</template>
} else if(@column.EffectType == "EnumSelector") {
@:<template #row_@(@column.LowerPropertyName)="{ row }">
@:<el-tag :type="dv('@(@column.DictTypeCode)', row.@(@column.LowerPropertyName))?.tagType"> {{dv('@(@column.DictTypeCode)', row.@column.LowerPropertyName)?.name}}</el-tag>
@:</template>
}
}
}
<template #row_record="{ row }">
<ModifyRecord :data="row" />
</template>
<template #row_buttons="{ row }">
@if(@Model.PrintType != "off") {
<el-tooltip content="打印" placement="top">
<el-button icon="ele-Printer" size="small" text type="primary" @@click="handlePrint(row)" v-auth="'@(@Model.LowerClassName)/print'" />
</el-tooltip>
}
<el-tooltip :content="$t('message.list.edit')" placement="top">
<el-button icon="ele-Edit" size="small" text type="primary" @@click="handleEdit(row)" v-auth="'@(@Model.LowerClassName)/update'" />
</el-tooltip>
<el-tooltip :content="$t('message.list.delete')" placement="top">
<el-button icon="ele-Delete" size="small" text type="danger" @@click="handleDelete(row)" v-auth="'@(@Model.LowerClassName)/delete'" />
</el-tooltip>
</template>
</vxe-grid>
</el-card>
@if(@Model.PrintType != "off"){
@:<PrintDialog ref="printDialogRef" :title="state.title" @@reloadTable="handleQuery" />
}
<EditDialog ref="editDialogRef" :title="state.title" @@reloadTable="handleQuery" />
</template>
<script lang="ts" setup name="@(@Model.LowerClassName)">
import { onMounted, reactive, ref } from 'vue';
import { ElMessageBox, ElMessage } from "element-plus";
import { useUserInfo } from '/@@/stores/userInfo';
import { VxeGridInstance, VxeGridListeners, VxeGridPropTypes } from 'vxe-table';
import { useVxeTable } from '/@@/hooks/useVxeTableOptionsHook';
import { Local } from '/@@/utils/storage';
import EditDialog from '/@@/views/@(@Model.PagePath)/@(@Model.LowerClassName)/component/edit.vue';
import ModifyRecord from '/@@/components/table/modifyRecord.vue';
import { useI18n } from 'vue-i18n';
@if(@Model.TableField.Any(x=>x.EffectType == "DatePicker")){
@://日期控件
@:import { formatDate } from '/@@/utils/formatTime';
}
@if(@Model.PrintType != "off"){
@:// 推荐设置操作 width 为 200
@:import { hiprint } from 'vue-plugin-hiprint';
@:import { SysPrintApi } from '/@@/api-services/api';
@:import { SysPrint } from '/@@/api-services/models';
@:import PrintDialog from '/@@/views/system/print/component/hiprint/preview.vue';
}
@if (@Model.IsApiService) {
@:// 接口函数
@:import { getAPI } from '/@@/utils/axios-utils';
@:import { @(@Model.ClassName)Api } from '/@@/api-services/api';
@:import { @(@Model.ClassName), @(@Model.ClassName)Input, @(@Model.ClassName)Output } from '/@@/api-services/models';
} else {
@://HJ: 废弃,没有使用和适配
@:import { treelist@(@Model.ClassName), delete@(@Model.ClassName) } from '/@@/api/@(@Model.PagePath)/@(@Model.LowerClassName)';
@:import { @(@Model.ClassName) } from '/@@/api/models/@(@Model.LowerClassName)';
foreach (var column in Model.QueryWhetherList){
if(@column.EffectType == "ForeignKey"){
@:import { get@(@column.FkEntityName)@(@column.PropertyName)Dropdown } from '/@@/api/@(@Model.PagePath)/@(@Model.LowerClassName)';
}
if(@column.EffectType == "ApiTreeSelector"){
@:import { get@(@column.FkEntityName)Tree } from '/@@/api/@(@Model.PagePath)/@(@Model.LowerClassName)';
}
}
}
// 子窗口对象
const { t } = useI18n();
const xGrid = ref<VxeGridInstance>();
const editDialogRef = ref<InstanceType<typeof EditDialog>>();
const userStore = useUserInfo();
@if(@Model.PrintType != "off") {
@:const printDialogRef = ref<InstanceType<typeof PrintDialog>>();
}
@if(@Model.TableField.Any(x=>x.EffectType == "ConstSelector")){
@:const codeToName = userStore.codeToName;
}
@if(@Model.TableField.Any(x=>x.EffectType == "DictSelector") || @Model.TableField.Any(x=>x.EffectType == "EnumSelector")){
@:const dc = userStore.getDictItemByValue;
@:const dv = userStore.getDictItemByLabel;
@:const dl = userStore.getDictDataByCode;
}
// 变量初始化
const state = reactive({
showAdvanceQueryUI: false,
treeData: [] as Array<@(@Model.ClassName)>, // 树所有数据
queryParams: {
searchKey: undefined,
@if(Model.QueryWhetherList.Count > 0) {
@foreach (var column in Model.QueryWhetherList) {
@:@(@column.LowerPropertyName): undefined,
}
}
},
localPageParam: {
pageSize: 50 as number,
defaultSort: { field: 'Id', order: 'asc', descStr: 'desc' },
},
visible: false,
title: '',
key:'',
val:null,
});
// 本地存储参数
const localPageParamKey = 'localPageParam:@(@Model.LowerClassName)';
// 改变高级查询的控件显示状态
const changeAdvanceQueryUI = () => {
state.showAdvanceQueryUI = !state.showAdvanceQueryUI;
};
// 校验表格字段权限
const checkTableColumnVisible = (tableColumnName: any) => {
return !userStore.userTableList.includes(tableColumnName);
};
// 表格参数配置
@if (@Model.IsApiService) {
@:const options = useVxeTable<@(@Model.ClassName)>(
} else {
@:const options = useVxeTable<@(@Model.ClassName)>(
}
{
id: '@(@Model.ClassName)',
name: t('message.@Model.LowerClassName.@Model.LowerClassName'),
columns: [
{ type: 'seq', title: t('message.list.number'), width: 60, fixed: 'left' },
@foreach (var column in Model.TableField) {
var whethersortable =column.WhetherSortable == "Y" ? "sortable: true" : "sortable: false";
var treetable =((Model.TabType == "Tree"||Model.TabType == "OnlyTree")&&column.ColumnName==Model.TreeName) ? ", treeNode: true, align: 'left'" : "";
if(@column.WhetherTable == "Y") {
if(@column.EffectType == "Upload" || @column.EffectType == "ForeignKey" || @column.EffectType == "ApiTreeSelector" || @column.EffectType == "Switch" || @column.EffectType == "ConstSelector") {
if(@column.EffectType == "Upload") {
@:{ visible: checkTableColumnVisible('@(@Model.LowerClassName):@(@column.LowerPropertyName)'), field: '@column.LowerPropertyName', title: t('message.@Model.LowerClassName.@column.LowerPropertyName'), minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' } @treetable, @whethersortable },
} else if(@column.EffectType == "ForeignKey") {
@:{ visible: checkTableColumnVisible('@(@Model.LowerClassName):@(@column.LowerPropertyName)'), field: '@column.LowerPropertyName', title: t('message.@Model.LowerClassName.@column.LowerPropertyName'), minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' } @treetable, @whethersortable },
} else if(@column.EffectType == "ApiTreeSelector") {
@:{ visible: checkTableColumnVisible('@(@Model.LowerClassName):@(@column.LowerPropertyName)'), field: '@column.LowerPropertyName', title: t('message.@Model.LowerClassName.@column.LowerPropertyName'), minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' } @treetable, @whethersortable },
} else if(@column.EffectType == "Switch") {
@:{ visible: checkTableColumnVisible('@(@Model.LowerClassName):@(@column.LowerPropertyName)'), field: '@column.LowerPropertyName', title: t('message.@Model.LowerClassName.@column.LowerPropertyName'), minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' } @treetable, @whethersortable },
} else if(@column.EffectType == "ConstSelector") {
@:{ visible: checkTableColumnVisible('@(@Model.LowerClassName):@(@column.LowerPropertyName)'), field: '@column.LowerPropertyName', title: t('message.@Model.LowerClassName.@column.LowerPropertyName'), minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' } @treetable, @whethersortable },
}
} else if(@column.EffectType == "DictSelector") {
@:{ visible: checkTableColumnVisible('@(@Model.LowerClassName):@(@column.LowerPropertyName)'), field: '@column.LowerPropertyName', title: t('message.@Model.LowerClassName.@column.LowerPropertyName'), minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' } @treetable, @whethersortable },
} else if(@column.EffectType == "EnumSelector") {
@:{ visible: checkTableColumnVisible('@(@Model.LowerClassName):@(@column.LowerPropertyName)'), field: '@column.LowerPropertyName', title: t('message.@Model.LowerClassName.@column.LowerPropertyName'), minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' } @treetable, @whethersortable },
} else if(@column.EffectType == "DatePicker") {
@:{ visible: checkTableColumnVisible('@(@Model.LowerClassName):@(@column.LowerPropertyName)'), field: '@column.LowerPropertyName', title: t('message.@Model.LowerClassName.@column.LowerPropertyName'), minWidth: 100, showOverflow: 'tooltip', formatter: ({ cellValue }) => formatDate(new Date(cellValue), 'YYYY-mm-dd HH:MM:SS'), @whethersortable },
} else {
@:{ visible: checkTableColumnVisible('@(@Model.LowerClassName):@(@column.LowerPropertyName)'), field: '@column.LowerPropertyName', title: t('message.@Model.LowerClassName.@column.LowerPropertyName'), minWidth: 100, showOverflow: 'tooltip' @treetable, @whethersortable},
}
}
}
@if(@Model.TableField.Any(t => t.ColumnName == "CreateTime") && @Model.TableField.Any(t => t.ColumnName == "UpdateTime") && @Model.TableField.Any(t => t.ColumnName == "CreateUserId")){
@:{ field: 'record',title: t('message.list.record'), width: 100, showOverflow: 'tooltip', slots: { default: 'row_record' } },
}
{ field: 'buttons',title: t('message.list.action'), fixed: 'right', width: 180, showOverflow: true, slots: { default: 'row_buttons' } },
],
},
// vxeGrid配置参数(此处可覆写任何参数)参考vxe-table官方文档
{
stripe: false,
// 多选配置
checkboxConfig: { range: false },
// 代理配置//加载时不立刻获取
proxyConfig: { autoLoad: false, ajax: { query: () => handleQueryApi() } },
// 分页配置
pagerConfig: { enabled: false },
// 工具栏配置
toolbarConfig: { export: false },
// 树形配置
treeConfig: { expandAll: false },
// 设置列显隐
customConfig: {
visibleMethod({ column }) {
return checkTableColumnVisible(`@Model.LowerClassName:${column.field}`);
},
},
}
);
// 页面初始化
onMounted(() => {
});
// 查询api
const handleQueryApi = async () => {
const params = Object.assign(state.queryParams);
@if (@Model.IsApiService) {
@:return getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)TreePost(params);
} else {
@:return treelist@(@Model.ClassName)(params);
}
};
// 查询操作
const handleQuery = async (updateTree: boolean = false) => {
options.loading = true;
var res = await handleQueryApi();
xGrid.value?.loadData(res.data.result ?? []);
options.loading = false;
// 是否更新左侧树
if (updateTree == true) {
//HJ 暂无该功能 emits('list-reload');
}
// 若无选择节点并且查询条件为空时,更新编辑页面机构列表树
if (state.queryParams.id == 0 && state.queryParams.name == undefined && state.queryParams.code == undefined && state.queryParams.type == undefined && updateTree == false)
state.treeData = res.data.result ?? [];
};
// 列表点击事件
const listhandleQuery= async (qparams: any,key:string,val:any) => {
console.log('listhandleQuery--', JSON.stringify(qparams));
state.key=key;
state.val=val;
if(qparams) state.queryParams=qparams;
await handleQuery(true);
};
// 重置操作
const resetQuery = async () => {
state.queryParams.searchKey = undefined;
@if(Model.QueryWhetherList.Count > 0) {
@foreach (var column in Model.QueryWhetherList) {
@:state.queryParams.@(@column.LowerPropertyName) = undefined;
}
}
await xGrid.value?.commitProxy('reload');
};
// 打开新增页面
const handleAdd = () => {
state.title = t('message.list.add')+t('message.@Model.LowerClassName.@Model.LowerClassName') ;
let data = {
[state.key]: state.val,
@foreach (var column in Model.TableField){
if(@column.WhetherAddUpdate == "Y"&&@column.DefaultValue!=null){
if(@column.NetType.StartsWith("int")||@column.NetType.StartsWith("decimal")){
@:@column.LowerPropertyName:@(string.IsNullOrEmpty(@column.DefaultValue)?0:@column.DefaultValue),
}
if(@column.NetType.StartsWith("string")){
@:@column.LowerPropertyName:'@(@column.DefaultValue)',
}
}
}
};
editDialogRef.value?.openDialog(data);
};
// 打开编辑页面
const handleEdit = (row: any) => {
state.title = t('message.list.edit')+t('message.@Model.LowerClassName.@Model.LowerClassName') ;
editDialogRef.value?.openDialog(row);
};
@if(@Model.PrintType != "off") {
@:// 打开打印页面
@:const handlePrint = async (row: any) => {
@:state.title = t('message.list.print')+t('message.@Model.LowerClassName.@Model.LowerClassName') ;
@if(@Model.PrintType != "off"){
if (@Model.IsApiService) {
@:var res = await getAPI(SysPrintApi).apiSysPrintPrintNameGet('@Model.PrintName');
} else {
@:var res = await getPrint@(@Model.ClassName)(row);
}
@:var printTemplate = res.data.result as SysPrint;
@:var template = JSON.parse(printTemplate.template);
@:var width = template.panels[0].width;
@:row['barCode'] = row.code;
@:row['qrCode'] = row.code;
@:row["printDate"] = formatDate(new Date(), 'YYYY-mm-dd HH:MM');
@:printDialogRef.value.showDialog(new hiprint.PrintTemplate({template: template}), row, width);
}
@if(@Model.PrintType == "auto"){
@:printDialogRef.value.showDialog(row);
}
@:};
}
// 删除
const handleDelete = (row: any) => {
ElMessageBox.confirm(t('message.list.confirmDelete')+t('message.@Model.LowerClassName.@Model.LowerClassName')+`:【${row.id}】?`, t('message.list.tips'), {
confirmButtonText: t('message.list.submit'),
cancelButtonText: t('message.list.cancel'),
type: 'warning',
}).then(async () => {
@if (@Model.IsApiService) {
@:await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)DeletePost({ id: row.id });
} else {
@:await delete@(@Model.ClassName)(row);
}
await handleQuery();
ElMessage.success(t('message.list.deleteSuccess'));
})
.catch(() => {});
};
// 表格事件
@if (@Model.IsApiService) {
@:const gridEvents: VxeGridListeners<@(@Model.ClassName)> = {
} else {
@:const gridEvents: VxeGridListeners = {
}
//行单击事件
async cellClick({ row, column }) {
listClick(row,column);
},
// 只对 pager-config 配置时有效,分页发生改变时会触发该事件
async pageChange({ pageSize }) {
state.localPageParam.pageSize = pageSize;
Local.set(localPageParamKey, state.localPageParam);
},
// 当排序条件发生变化时会触发该事件
async sortChange({ field, order }) {
state.localPageParam.defaultSort = { field: field, order: order!, descStr: 'desc' };
Local.set(localPageParamKey, state.localPageParam);
},
async proxyQuery() {
state.treeData = xGrid.value?.getTableData().tableData ?? [];
},
};
@foreach (var column in Model.QueryWhetherList) {
@if(@column.EffectType == "ForeignKey") {
@:const @LowerFirstLetter(@column.FkEntityName)@(@column.PropertyName)DropdownList = ref<any>([]);
@:const get@(@column.FkEntityName)@(@column.PropertyName)DropdownList = async () => {
@if (@Model.IsApiService) {
@:let list = await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)@(@column.FkEntityName)@(@column.PropertyName)DropdownGet();
} else {
@:let list = await get@(@column.FkEntityName)@(@column.PropertyName)Dropdown();
}
@:@LowerFirstLetter(@column.FkEntityName)@(@column.PropertyName)DropdownList.value = list.data.result ?? [];
@:};
@:get@(@column.FkEntityName)@(@column.PropertyName)DropdownList();
}
}
@foreach (var column in Model.QueryWhetherList) {
@if(@column.EffectType == "ApiTreeSelector") {
@:const @LowerFirstLetter(@column.FkEntityName)TreeData = ref<any>([]);
@:const get@(@column.FkEntityName)TreeData = async () => {
@if (@Model.IsApiService) {
@:let list = await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)@(@column.FkEntityName)Tree();
} else {
@:let list = await get@(@column.FkEntityName)Tree();
}
@:@LowerFirstLetter(@column.FkEntityName)TreeData.value = list.data.result ?? [];
@:};
@:get@(@column.FkEntityName)TreeData();
}
}
// 全部展开
const handleExpand = () => {
xGrid.value?.setAllTreeExpand(true);
};
// 全部折叠
const handleFold = () => {
xGrid.value?.clearTreeExpand();
};
// 与父组件的交互逻辑
const emits = defineEmits(['list-click']);
const listClick = (row: any,column:any) => {
emits('list-click', row,column);
};
// 将属性或者函数暴露给父组件
defineExpose({ listhandleQuery });
</script>

View File

@ -1,91 +0,0 @@
@{
string LowerFirstLetter(string text)
{
return text.ToString()[..1].ToLower() + text[1..]; // 首字母小写
}
var pkField = Model.TableField.Where(c => c.ColumnKey == "True").FirstOrDefault();
string pkFieldName = null;
if(pkField != null && !string.IsNullOrEmpty(pkField.PropertyName))
{
pkFieldName = LowerFirstLetter(pkField.PropertyName);
}
Dictionary<string, int> definedObjects = new Dictionary<string, int>();
bool haveLikeCdt = false;
foreach (var column in Model.TableField){
if (column.QueryWhether == "Y" && column.QueryType == "like"){
haveLikeCdt = true;
}
}
}
<template>
<div class="@(@Model.LowerClassName)-container">
<splitpanes horizontal class="default-theme">
<pane size="60" style="display: flex;flex-direction: column;">
<IndexList ref="indexListRef" @@list-click="handleIndexChange" />
</pane>
<pane size="40" style="display: flex; flex-direction: column;">
<el-tabs v-model="activeName" type="border-card"
style="height: 100%; padding: 0px; margin-bottom: 0px; position: relative">
<el-tab-pane label="属性1" name="1" style="height: 100%; margin-bottom: 0px; position: relative">
<@(@Model.BottomTab)Bottom ref="@(@Model.LowerBottomTab)BottomRef" @@list-click="handleBottomChange" />
</el-tab-pane>
<el-tab-pane label="属性2" name="2" style="height: 100%; margin-bottom: 0px; position: relative">
<div></div>
</el-tab-pane>
</el-tabs>
</pane>
</splitpanes>
</div>
</template>
<script lang="ts" setup name="@(@Model.LowerClassName)">
import { onMounted, reactive, ref } from 'vue';
import { ElMessageBox, ElMessage } from "element-plus";
import { Splitpanes, Pane } from 'splitpanes';
import 'splitpanes/dist/splitpanes.css';
import IndexList from '/@@/views/@(@Model.PagePath)/@(@Model.LowerClassName)/component/@(@Model.LowerClassName)List.vue';
import @(@Model.BottomTab)Bottom from '/@@/views/@(@Model.PagePath)/@(@Model.LowerBottomTab)/component/@(@Model.LowerBottomTab)List.vue';
const indexListRef = ref<InstanceType<typeof IndexList>>();
const @(@Model.LowerBottomTab)BottomRef = ref<InstanceType<typeof @(@Model.BottomTab)Bottom>>();
const activeName = ref('1');
// 变量
const state = reactive({
queryParams: {
searchKey: undefined,
@if(Model.QueryWhetherList.Count > 0) {
@foreach (var column in Model.QueryWhetherList) {
@:@(@column.LowerPropertyName): undefined,
}
}
},
});
// 页面初始化
onMounted(() => {
indexListRef.value?.listhandleQuery(state.queryParams);//列表控件初始化不请求数据,这里要请求一下
});
// 主表List组件点击
const handleIndexChange = async (row: any,column: any) => {
console.log('handleIndexChange--', JSON.stringify(row));
state.queryParams.@(@Model.LowerBottomKey) = row.@(@Model.LowerBottomPrimaryKey);//下关联字段=下表主表关联字段
console.log('handleIndexChange--', state.queryParams.@(@Model.LowerBottomKey));
await @(@Model.LowerBottomTab)BottomRef.value?.listhandleQuery(state.queryParams);
};
const handleBottomChange = async (row: any) => {
console.log('handleBottomChange--', JSON.stringify(row));
};
</script>
<style lang="scss" scoped>
:deep(.el-input),
:deep(.el-select),
:deep(.el-input-number) {
width: 100%;
}
:deep(.el-slider .el-input-number){
width: auto;
}
</style>

View File

@ -1,461 +1,238 @@
@{Dictionary<string, int> definedObjects = new Dictionary<string, int>();}
@{var pkField = Model.TableField.Where(c => c.ColumnKey == "True").FirstOrDefault();}
@{
string pkFieldName = LowerFirstLetter(pkField.PropertyName);
string RemoteField="";
string PKName="";
foreach (var column in Model.TableField){
if(column.RemoteVerify){
RemoteField=@column.PropertyName;
}
if(column.ColumnKey == "True"){
PKName=column.PropertyName;
}
}
}
<template>
<div class="@(@Model.LowerClassName)-container">
<el-dialog v-model="state.isShowDialog" :width="800" draggable="" :close-on-click-modal="false" :before-close="cancel">
<template #header>
<div style="color: #fff">
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
<span>{{ props.title }}</span>
</div>
</template>
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto" :rules="rules">
<el-row :gutter="35">
@foreach (var column in Model.TableField){
if(@column.ColumnKey == "True"){
@:<el-form-item style="display: none !important;">
<el-input v-model="state.ruleForm.@(@column.LowerPropertyName)" />
</el-form-item>
}else{
if (@column.WhetherAddUpdate == "Y"){
if(@column.EffectType == "ForeignKey"){
@:<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
@:<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" prop="@(@column.LowerPropertyName)">
@:<el-select clearable filterable v-model="state.ruleForm.@(@column.LowerPropertyName)" :placeholder="$t('message.list.pleaseChoose') + $t('message.@Model.LowerClassName.@column.LowerPropertyName')">
@if(column.NetType.StartsWith("int")||column.NetType.StartsWith("long")){
@:<el-option v-for="(item,index) in @LowerFirstLetter(@column.FkEntityName)@(@column.PropertyName)DropdownList" :key="index" :value="parseInt(item.value)" :label="item.label" />
}
@if(column.NetType.StartsWith("decimal")||column.NetType.StartsWith("float")||column.NetType.StartsWith("double")){
@:<el-option v-for="(item,index) in @LowerFirstLetter(@column.FkEntityName)@(@column.PropertyName)DropdownList" :key="index" :value="parseFloat(item.value)" :label="item.label" />
}
@if(column.NetType.StartsWith("string")){
@:<el-option v-for="(item,index) in @LowerFirstLetter(@column.FkEntityName)@(@column.PropertyName)DropdownList" :key="index" :value="item.value" :label="item.label" />
}
</el-select>
</el-form-item>
</el-col>
}else if(@column.EffectType == "ApiTreeSelector"){
@:<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
@:<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" prop="@(@column.LowerPropertyName)">
<el-cascader
@:options="@LowerFirstLetter(@column.FkEntityName)TreeData"
@:props="{ checkStrictly: true, emitPath: false, value: '@LowerFirstLetter(@column.ValueColumn)', label: '@LowerFirstLetter(@column.DisplayColumn)' }"
:placeholder="$t('message.list.pleaseChoose') + $t('message.@Model.LowerClassName.@column.LowerPropertyName')"
clearable=""
class="w100"
v-model="state.ruleForm.@(@column.LowerPropertyName)"
>
<template #default="{ node, data }">
<span>{{ data.@LowerFirstLetter(@column.DisplayColumn) }}</span>
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
</template>
</el-cascader>
</el-form-item>
</el-col>
}else if(@column.EffectType == "Input"){
@:<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
@:<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" prop="@(@column.LowerPropertyName)">
@:<el-input v-model="state.ruleForm.@(@column.LowerPropertyName)" autocomplete="new-password" :placeholder="$t('message.list.pleaseInput') + $t('message.@Model.LowerClassName.@column.LowerPropertyName')" maxlength="@(@column.ColumnLength)" show-word-limit clearable />
</el-form-item>
</el-col>
}else if(@column.EffectType == "InputNumber"){
@:<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
@:<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" prop="@(@column.LowerPropertyName)">
@:<el-input-number v-model="state.ruleForm.@(@column.LowerPropertyName)" :placeholder="$t('message.list.pleaseInput') + $t('message.@Model.LowerClassName.@column.LowerPropertyName')" clearable />
</el-form-item>
</el-col>
}else if(@column.EffectType == "InputTextArea"){
@:<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
@:<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" prop="@(@column.LowerPropertyName)">
@:<el-input v-model="state.ruleForm.@(@column.LowerPropertyName)" autocomplete="new-password" :placeholder="$t('message.list.pleaseInput') + $t('message.@Model.LowerClassName.@column.LowerPropertyName')" type="textarea"
@if(@column.ColumnLength>0){
@:maxlength="@(@column.ColumnLength)"
}
@:show-word-limit clearable />
</el-form-item>
</el-col>
}else if(@column.EffectType == "DictSelector"){
@:<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
@:<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" prop="@(@column.LowerPropertyName)">
@:<el-select clearable v-model="state.ruleForm.@(@column.LowerPropertyName)" :placeholder="$t('message.list.pleaseChoose') + $t('message.@Model.LowerClassName.@column.LowerPropertyName')">
@:<el-option v-for="(item,index) in dl('@(@column.DictTypeCode)')" :key="index" :value="@(@column.NetType.StartsWith("string") ? "item.code" : "Number(item.value)")" :label="`${item.label||''} [${item.code}] ${item.value}`"></el-option>
</el-select>
</el-form-item>
</el-col>
}else if(@column.EffectType == "ConstSelector"){
@:<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
@:<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" prop="@(@column.LowerPropertyName)">
@:<el-select clearable v-model="state.ruleForm.@(@column.LowerPropertyName)" :placeholder="$t('message.list.pleaseChoose') + $t('message.@Model.LowerClassName.@column.LowerPropertyName')">
@:<el-option v-for="(item,index) in getConstType('@column.DictTypeCode')" :key="index" :label="item.name" :value="@(@column.NetType.StartsWith("string") ? "item.code" : "Number(item.value)")">{{ item.name }}</el-option>
</el-select>
</el-form-item>
</el-col>
}else if(@column.EffectType == "Switch"){
@:<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
@:<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" prop="@(@column.LowerPropertyName)">
@:<el-switch v-model="state.ruleForm.@(@column.LowerPropertyName)"
@if(@column.NetType.StartsWith("int")){
@::active-value="1" :inactive-value="0"
}
@if(@column.NetType.StartsWith("string")){
@:active-value="1" inactive-value="0"
}
@::active-text="$t('message.list.yes')" :inactive-text="$t('message.list.no')" />
</el-form-item>
</el-col>
}else if(@column.EffectType == "DatePicker"){
@:<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
@:<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" prop="@(@column.LowerPropertyName)">
@:<el-date-picker v-model="state.ruleForm.@(@column.LowerPropertyName)" type="date" :placeholder="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" />
</el-form-item>
</el-col>
}else if(@column.EffectType == "Upload"){
@:<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
@:<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" prop="@(@column.LowerPropertyName)">
@:<el-upload
@:list-type="picture-card"
@::show-file-list="false"
@::http-request="upload@(@column.PropertyName)Handle">
@:<img
@:v-if="state.ruleForm.@(@column.LowerPropertyName)"
@::src="state.ruleForm.@(@column.LowerPropertyName)"
@:@@click="state.ruleForm.@(@column.LowerPropertyName)=''"
@:style="width: 100%; height: 100%; object-fit: contain"/>
@:<el-icon v-else></el-icon>
</el-upload>
</el-form-item>
</el-col>
}else if(@column.EffectType == "EnumSelector"){
@:<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
@:<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" prop="@(@column.LowerPropertyName)">
@:<el-select clearable v-model="state.ruleForm.@(@column.LowerPropertyName)" :placeholder="$t('message.list.pleaseChoose') + $t('message.@Model.LowerClassName.@column.LowerPropertyName')">
@:<el-option v-for="(item,index) in dl('@(@column.DictTypeCode)')" :key="index" :value="@(@column.NetType.StartsWith("string") ? "item.value" : "Number(item.value)")" :label="`${item.label||''} (${item.code}) [${item.value}]`"></el-option>
</el-select>
</el-form-item>
</el-col>
}else if(@column.EffectType == "RichTextEditor"){
//HJ:添加富文本插件
@:<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
@:<el-form-item :label="$t('message.@Model.LowerClassName.@column.LowerPropertyName')" prop="@(@column.LowerPropertyName)">
@:<Editor v-model:get-html="state.ruleForm.@(@column.LowerPropertyName)" />
</el-form-item>
</el-col>
}else{
}
}
}
}
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button icon="ele-CircleCloseFilled" @@click="cancel">{{ $t('message.list.cancel') }}</el-button>
<el-button type="primary" icon="ele-CircleCheckFilled" @@click="submit">{{ $t('message.list.submit') }}</el-button>
</span>
</template>
</el-dialog>
</div>
<template>
<div class="@(Model.LowerClassName)-container">
<el-dialog v-model="state.showDialog" :width="800" draggable :close-on-click-modal="false">
<template #header>
<div style="color: #fff">
<span>{{ state.title }}</span>
</div>
</template>
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto" v-loading="state.loading">
<el-row :gutter="35">
@foreach (var column in Model.AddUpdateFields.Where(u => !u.IsStatus)) {
@:<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
@:<el-form-item label="@column.ColumnComment" prop="@(column.LowerPropertyName)"@(column.GetFormRules)>
if (column.IsDatePicker) {
// 时间
@:<el-date-picker v-model="state.ruleForm.@(column.LowerPropertyName)" value-format="YYYY/MM/DD" placeholder="请选择@(column.ColumnComment)" :disabled="state.disabled" class="w100" />
} else if (column.IsInputNumber) {
// 数字
@:<el-input-number v-model="state.ruleForm.@(column.LowerPropertyName)" placeholder="请输入@(column.ColumnComment)" :min="0" :step="1"@(column.NetType.StartsWith("decimal") ? " :precision='2'" : "") :disabled="state.disabled" clearable class="w100" />
} else if (column.IsSwitch) {
// 开关
@:<el-switch v-model="state.ruleForm.@(column.LowerPropertyName)" active-value="1" inactive-value="0" :disabled="state.disabled" class="w100" />
} else if (column.IsConst) {
// 常量
@:<el-select v-model="state.ruleForm.@(column.LowerPropertyName)" :placeholder="'请选择@(column.ColumnComment)'" clearable@(column.Multiple ? " multiple" : "") :disabled="state.disabled" class="w100">
@:<el-option v-for="item in userInfo.getConstDataByTypeCode('@(column.DictConfig.Code)')" :key="item.code" :label="item.name" :value="item.code" />
@:</el-select>
} else if (column.IsDict || column.IsEnum) {
// 字典枚举
@:<g-sys-dict v-model="state.ruleForm.@(column.LowerPropertyName)" code="@(column.DictConfig.Code)" render-as="select" clearable@(column.Multiple ? " multiple" : "") :disabled="state.disabled" class="w100" />
} else if (column.IsTree) {
// 树组件
@:<el-cascader
@::options="state.dropdownData.@(column.LowerPropertyName) ?? []"
@::props="{ value: '@(Model.GetFirstLower(column.JoinConfig.LinkPropertyName))', label: '@(Model.GetFirstLower(column.JoinConfig.DisplayPropertyNames.Split(",").First()))', checkStrictly: true, emitPath: false }"
@:v-model="state.ruleForm.@(column.LowerPropertyName)"
@:placeholder="请选择@(column.ColumnComment)"
@::disabled="state.disabled"
@:clearable
@:filterable
@:class="w100">
@:<template #default="{ node, data }">
@:<span>@(string.Join("-", column.JoinConfig.DisplayPropertyNames.Split(",").Select(x => $"{{{{ data.{Model.GetFirstLower(x)} }}}}")))</span>
@:<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
@:</template>
@:</el-cascader>
} else if (column.IsForeignKey) {
// 外键组件
var firstDisplayName = Model.GetFirstLower(column.JoinConfig.DisplayPropertyNames.Split(",").First());
var linkPropertyName = Model.GetFirstLower(column.JoinConfig.LinkPropertyName);
var leftJoinPropertyName = Model.GetFirstLower(column.LeftJoinPropertyName);
@:<pulldown-selecter
@:v-model="state.ruleForm.@(column.LowerPropertyName)"
@::default-options="[{ @(firstDisplayName): state.ruleForm.@(leftJoinPropertyName), @(linkPropertyName): state.ruleForm.@(column.LowerPropertyName)}]"
@::fetch-options="handle@(column.JoinConfig.EntityName)Table"
@::query-params="{ pageSize: 10 }"
@:value-prop="@(linkPropertyName)"
@:label-prop="@(firstDisplayName)"
@:placeholder="选择@(column.ColumnComment)"
@:filterable
@:clearable
@:class="w100">
@:<template #columns>
@:<el-table-column prop="id" label="ID" width="150" />
@:<el-table-column prop="@(firstDisplayName)" label="@(firstDisplayName)" width="150" />
@:</template>
@:</pulldown-selecter>
@:<!--
@:<el-select v-model="state.ruleForm.@(column.LowerPropertyName)" :placeholder="'请选择@(column.ColumnComment)'" clearable@(column.Multiple ? " multiple" : "") :disabled="state.disabled" class="w100">
@: <el-option v-for="item in state.dropdownData.@(column.LowerPropertyName) ?? []" :key="item.@(linkPropertyName)" :label="item.@(firstDisplayName)" :value="item.@(linkPropertyName)" />
@:</el-select>
@:-->
} else if (column.IsUpload) {
// 文件上传
@:<el-upload
@:list-type="picture-card"
@::show-file-list="false"
@::disabled="state.disabled"
@::http-request="upload@(column.PropertyName)Handle"
@:class="w100">
@:<img v-if="state.ruleForm.@(column.LowerPropertyName)"
@::src="state.ruleForm.@(column.LowerPropertyName)"
@:@@click="state.ruleForm.@(column.LowerPropertyName)=''"
@:style="width: 100%; height: 100%; object-fit: contain"/>
@:<el-icon v-else><Plus /></el-icon>
@:</el-upload>
} else if (column.IsInputTextArea) {
// 文本域
@:<el-input v-model="state.ruleForm.@(column.LowerPropertyName)" type="textarea" placeholder="请输入@(column.ColumnComment)" clearable :disabled="state.disabled" class="w100" />
} else {
// 输入框
@:<el-input v-model="state.ruleForm.@(column.LowerPropertyName)" placeholder="请输入@(column.ColumnComment)" clearable :disabled="state.disabled" class="w100" />
}
@:</el-form-item>
@:</el-col>
}
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @@click="() => state.showDialog = false" :disabled="state.loading">取 消</el-button>
<el-button v-if="!state.disabled" @@click="submit" type="primary" v-reclick="1500" :disabled="state.loading">确 定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script lang="ts" setup name="@(@Model.LowerClassName)">
import { ref,onMounted, reactive } from "vue";
<!-- @(Model.BusName) -->
<script lang="ts" name="@(Model.LowerClassName)" setup>
import { ref, reactive, onMounted } from "vue";
import { ElMessage } from "element-plus";
import type { FormRules } from "element-plus";
import { useUserInfo } from '/@@/stores/userInfo';
import { useI18n } from 'vue-i18n';
@if(@Model.TableField.Any(x=>x.EffectType == "RichTextEditor")){
@://HJ:添加富文本插件
@:import Editor from '/@@/components/editor/index.vue';
import type { FormInstance } from "element-plus";
@if (Model.AllFields.Any(u => u.IsConst)) {
@:import {useUserInfo} from "/@@/stores/userInfo";
}
@if (@Model.IsApiService) {
@://接口控件
@:import { getAPI } from '/@@/utils/axios-utils';
@:import { @(@Model.ClassName)Api } from '/@@/api-services/api';
@:import { Update@(@Model.ClassName)Input } from '/@@/api-services/models';
}
else{
@://HJ:废弃,不要用这个接口 Begin
@:import {
@if(Model.RemoteVerify){
@:exists@(RemoteField),
}
@foreach (var column in Model.TableField.Where(x=>x.EffectType == "ForeignKey").ToList()){
@:get@(@column.FkEntityName)@(@column.PropertyName)Dropdown,
}
@foreach (var column in Model.TableField.Where(x=>x.EffectType == "ApiTreeSelector").ToList()){
@:get@(@column.FkEntityName)Tree,
}
@:add@(@Model.ClassName),
@:update@(@Model.ClassName),
@:detail@(@Model.ClassName) } from "/@@/api/@(@Model.PagePath)/@(@Model.LowerClassName)";
if(@Model.TableField.Any(x=>x.EffectType == "Upload")){
@:import { Plus } from "@@element-plus/icons-vue";
@:import { UploadRequestOptions } from "element-plus";
@:import { @string.Join(",",Model.TableField.Where(x=>x.EffectType == "Upload").Select(x=>"upload"+x.PropertyName).ToList()) } from '/@@/api/@(@Model.PagePath)/@(@Model.LowerClassName)';
}
@://HJ:废弃,不要用这个接口 END
}
@if(@Model.TableField.Any(x=>x.EffectType == "DatePicker")){
@://日期控件
@if(Model.TableFields.Any(x => x.IsDatePicker)) {
@:import { formatDate } from '/@@/utils/formatTime';
}
@foreach (var column in Model.TableField){
if(@column.EffectType == "ApiTreeSelector" && !definedObjects.ContainsKey("import__@(@column.FkEntityName)Tree")){
@{definedObjects.Add("import__@(@column.FkEntityName)Tree", 1);}
}
}
@if(@Model.TableField.Any(x=>x.EffectType == "EnumSelector")){
@://枚举控件
@:import { SysEnumApi } from '/@@/api-services/api';
@if(Model.UploadFields.Count > 0) {
@:import { Plus } from "@@element-plus/icons-vue";
@:import { UploadRequestOptions } from "element-plus";
}
const userStore = useUserInfo();
@if(@Model.TableField.Any(x=>x.EffectType == "ConstSelector")){
@:const getConstType = userStore.getConstDataByTypeCode;
}
@if(@Model.TableField.Any(x=>x.EffectType == "DictSelector") || @Model.TableField.Any(x=>x.EffectType == "EnumSelector")){
@:const dl = userStore.getDictDataByCode;
@if (Model.AllFields.Any(u => u.IsForeignKey)) {
@:import PulldownSelecter from "/@@/components/selector/pulldownSelecter.vue";
}
// 父级传递来的参数
var props = defineProps({
title: {
type: String,
default: "",
},
});
// 父级传递来的函数,用于回调
const emit = defineEmits(["reloadTable"]);
const { t } = useI18n();
const ruleFormRef = ref();
@if(Model.IsApiService) {
@:import { getAPI } from '/@@/utils/axios-utils';
@:import { @(Model.ClassName)Api } from '/@@/api-services/@(Model.PagePath)/api';
@:import { Detail@(Model.ClassName)Output } from '/@@/api-services/@(Model.PagePath)/models';
} else {
@:import { use@(Model.ClassName)Api } from '/@@/api/@(Model.PagePath)/@(Model.LowerClassName)';
}
//父级传递来的函数,用于回调
const emit = defineEmits(["handleQuery"]);
@if (Model.AllFields.Any(u => u.IsConst)) {
@:const userInfo = useUserInfo();
}
const ruleFormRef = ref<FormInstance>();
const state = reactive({
isShowDialog: false,
@if (@Model.IsApiService) {
@:ruleForm: {} as Update@(@Model.ClassName)Input,
}
else
{
@:ruleForm: {
@:@(@pkFieldName):0,
@foreach (var column in Model.TableField){
if (@column.WhetherAddUpdate == "Y"){
if(@column.NetType.StartsWith("int")||@column.NetType.StartsWith("decimal")||@column.NetType.StartsWith("float")||@column.NetType.StartsWith("double")){
@:@(@column.LowerPropertyName):@(string.IsNullOrEmpty(@column.DefaultValue)?"null":@column.DefaultValue),
} else if(@column.NetType.StartsWith("string")){
@:@column.LowerPropertyName:@(string.IsNullOrEmpty(@column.DefaultValue)?"null":("'"+column.DefaultValue+"'")),
}else{
@:@column.LowerPropertyName:null,
}
}
}
@:},
}
});
// 自行添加其他规则
const rules = ref<FormRules>({
@foreach (var column in Model.TableField){
if(@column.WhetherAddUpdate == "Y"){
@if(@column.AnyRule){
@:@column.LowerPropertyName: [
@foreach(var rule in @column.RuleItems){
string trigger="blur";
if(@column.EffectType == "DatePicker" || @column.EffectType == "DictSelector" ||@column.EffectType == "ApiTreeSelector"){
trigger="change";
}
if(rule.Type=="required"){
@:{required: true, message:t('message.list.pleaseInputTitle') +t('message.@Model.LowerClassName.@column.LowerPropertyName'), trigger: '@(@trigger)',},
}else if(rule.Type=="array"){
@:{ type: 'array', required: true, message:"$t('message.list.pleaseInputTitle') + $t('message.@Model.LowerClassName.@column.LowerPropertyName')'" , trigger: 'change', },
}else if(rule.Type=="length"&&(column.EffectType=="Input"||column.EffectType == "InputTextArea")){
@:{ min: @(@rule.Min), max: @(@rule.Max), message: t('message.list.length') + '@(@rule.Min) - @(@rule.Max)', trigger: '@(@trigger)' },
}else if(rule.Type=="pattern"){
@:{ pattern: @(@rule.Pattern), message: t('message.@Model.LowerClassName.@column.LowerPropertyName'), trigger: '@(@trigger)' },
}else if(rule.Type=="remote"){
@:{
@:asyncValidator: (rule, value, callback) => {
@:if (!value) {
@:callback(new Error("$t('message.list.pleaseInput') + $t('message.@Model.LowerClassName.@column.LowerPropertyName')"));
@:}
@:let param = {
@:fieldValue: value,
@:oldFieldValue: state.ruleForm.old@(RemoteField)
@:};
@:exists@(RemoteField)(param).then((res) => {
@:if (res.data.result) {
@:callback();
@:} else {
@:callback(new Error("'@(@column.ColumnComment)'+ $t('message.list.disable') "));
@:}
@:}).finally(() => {
@:callback(new Error("$t('message.list.error')"));
@:});
@:}, trigger: '@(@trigger)'
@:},
}else{
}
}
@:],
}
}
}
title: '',
loading: false,
disabled: false,
showDialog: false,
ruleForm: {} as @(Model.IsApiService ? $"Detail{Model.ClassName}Output" : "any"),
@if (Model.AllFields.Any(u => u.IsTree || u.IsForeignKey)) {
@:dropdownData: {} as any,
}
});
// 页面加载时
onMounted(() => {
onMounted(async () => {
@foreach (var column in Model.AllFields.Where(u => u.IsTree).GroupBy(u => new { u.IsTree }).Select(u => u.First())) {
if (column.JoinConfig.UseTable) continue;
var methodName = column.JoinConfig.EntityName + (column.IsTree ? "Tree" : "Table");
@:// 查询@(column.JoinConfig.TableComment)数据
@:state.dropdownData.@(column.LowerPropertyName) = await handle@(methodName)({}).then(res => res.data.result ?? []);
}
});
// 打开弹窗
const openDialog = async (row: any) => {
// state.ruleForm = JSON.parse(JSON.stringify(row));
// 改用detail获取最新数据来编辑
let rowData = JSON.parse(JSON.stringify(row));
if (rowData.@(@pkFieldName)) {
@if (@Model.IsApiService) {
@:let data = (await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)DetailGet(rowData.@(@pkFieldName))).data.result;
@if(Model.RemoteVerify){
@:const { @LowerFirstLetter(@RemoteField) } = data;
@:data.old@(RemoteField) = @LowerFirstLetter(@RemoteField);
}
@:state.ruleForm = data;
} else {
@:let data = (await detail@(@Model.ClassName)(rowData.@(@pkFieldName))).data.result;
@if(Model.RemoteVerify){
@:const { @LowerFirstLetter(@RemoteField) } = data;
@:data.old@(RemoteField) = @LowerFirstLetter(@RemoteField);
}
@:state.ruleForm = data;
}
} else {
state.ruleForm = rowData;
}
state.isShowDialog = true;
const openDialog = async (row: any, title: string) => {
state.title = title;
state.showDialog = true;
ruleFormRef.value?.resetFields();
state.disabled = title?.endsWith('详情');
if (row?.id) {
const res = await @(Model.GetHttpApiMethodName(null, "detail"))(row.id);
state.ruleForm = res.data.result ?? {};
} else {
const defaultData = { orderNo: 100, status: 1 };
state.ruleForm = Object.assign(defaultData, row ?? {});
}
@foreach (var column in Model.AddUpdateFields.Where(u => (u.IsDict || u.IsEnum || u.IsConst || u.IsForeignKey) && u.NetType.Trim('?') == "string" && u.Multiple)) { // 处理多选字段值
@:state.ruleForm.@(column.LowerPropertyName) = state.ruleForm.@(column.LowerPropertyName) ? state.ruleForm.@(column.LowerPropertyName).split(",") : state.ruleForm.@(column.LowerPropertyName);
}
};
// 关闭弹窗
const closeDialog = () => {
emit("reloadTable");
state.isShowDialog = false;
resetForm();
emit("handleQuery");
state.showDialog = false;
};
// 取消
const cancel = () => {
state.isShowDialog = false;
resetForm();
};
// 重置表单
const resetForm = () => {
ruleFormRef.value.resetFields();
}
// 提交
const submit = async () => {
ruleFormRef.value.validate(async (isValid: boolean, fields?: any) => {
if (isValid) {
let values = state.ruleForm;
if (state.ruleForm.@(@pkFieldName) == undefined || state.ruleForm.@(@pkFieldName) == null || state.ruleForm.@(@pkFieldName) == "" || state.ruleForm.@(@pkFieldName) == 0) {
@if (@Model.IsApiService) {
@:await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)AddPost(state.ruleForm);
} else {
@:await add@(@Model.ClassName)(values);
}
} else {
@if (@Model.IsApiService) {
@:await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)UpdatePost(state.ruleForm);
} else {
@:await update@(@Model.ClassName)(values);
}
}
closeDialog();
} else {
ElMessage({
message: `表单有${Object.keys(fields).length}处验证失败,请修改后再提交`,
type: "error",
});
}
});
ruleFormRef.value?.validate(async (isValid: boolean, fields?: any) => {
if (isValid) {
state.loading = true;
try {
let values = JSON.parse(JSON.stringify(state.ruleForm));
// 处理多选字段值
@foreach (var column in Model.AddUpdateFields.Where(u => (u.IsDict || u.IsEnum || u.IsConst || u.IsForeignKey) && u.NetType.Trim('?') == "string" && u.Multiple)) {
@:values.@(column.LowerPropertyName) = Array.isArray(values.@(column.LowerPropertyName)) ? values.@(column.LowerPropertyName)?.join(",") : values.@(column.LowerPropertyName);
}
if (state.ruleForm.id) {
await @(Model.GetHttpApiMethodName(null, "update"))(values);
} else {
await @(Model.GetHttpApiMethodName(null, "add"))(values);
}
closeDialog();
} finally {
state.loading = false;
}
} else {
ElMessage({
message: `表单有${Object.keys(fields).length}处验证失败,请修改后再提交`,
type: "error",
});
}
});
};
@foreach (var column in Model.TableField){
if(@column.EffectType == "ForeignKey" && @column.WhetherAddUpdate == "Y"){
@:// 下拉列表@(@column.ColumnComment)
@:const @LowerFirstLetter(@column.FkEntityName)@(@column.PropertyName)DropdownList = ref<any>([]);
@:const get@(@column.FkEntityName)@(@column.PropertyName)DropdownList = async () => {
@if (@Model.IsApiService) {
@:let list = await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)@(@column.FkEntityName)@(@column.PropertyName)DropdownGet();
} else {
@:let list = await get@(@column.FkEntityName)@(@column.PropertyName)Dropdown();
}
@:@LowerFirstLetter(@column.FkEntityName)@(@column.PropertyName)DropdownList.value = list.data.result ?? [];
@:};
@:get@(@column.FkEntityName)@(@column.PropertyName)DropdownList();
@foreach (var column in Model.ApiFields.GroupBy(u => new { u.IsTree, u.JoinConfig.EntityName }).Select(u => u.First())) {
var methodName = column.JoinConfig.EntityName + (column.IsTree ? "Tree" : "Table");
@:// 查询@(column.JoinConfig.TableComment)数据
@:const handle@(methodName) = async (data: any) => {
@:return await @(Model.GetHttpApiMethodName(column, column.IsTree ? "fkTree" : "fkTable"))(data);
@:}
@:
}
}
@foreach (var column in Model.TableField){
if(@column.EffectType == "ApiTreeSelector" && !definedObjects.ContainsKey("define_get@(@column.FkEntityName)TreeData")){
@{definedObjects.Add("define_get@(@column.FkEntityName)TreeData", 1);}
@:const @LowerFirstLetter(@column.FkEntityName)TreeData = ref<any>([]);
@:const get@(@column.FkEntityName)TreeData = async () => {
@:let list = await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)TreePost();
@:@LowerFirstLetter(@column.FkEntityName)TreeData.value = list.data.result ?? [];
@:};
@:get@(@column.FkEntityName)TreeData();
@foreach (var column in Model.UploadFields) {
@:// 上传@(column.ColumnComment)
@:const upload@(column.PropertyName)Handle = async (options: UploadRequestOptions) => {
@:const res = await @(Model.GetHttpApiMethodName(column, "upload"))(options);
@:state.ruleForm.@(column.LowerPropertyName) = res.data.result?.@(column.NetType.StartsWith("long") ? "id" : "url");
@:}
@:
}
else if(@column.EffectType == "ConstSelector"){
@:const @LowerFirstLetter(@column.DictTypeCode)DropdownList = ref<any>([]);
@:const get@(@column.DictTypeCode)DropdownList = async () => {
@:let list = await getConstSelectorList("@column.DictTypeCode");
@:@LowerFirstLetter(@column.DictTypeCode)DropdownList.value = list.data.result ?? [];
@:};
@:get@(@column.DictTypeCode)DropdownList();
@:
}
}
@foreach (var column in Model.TableField){
if(column.WhetherAddUpdate=="N") continue;
if(@column.EffectType == "Upload"){
@:// 上传@(@column.ColumnComment)
@:const upload@(@column.PropertyName)Handle = async (options: UploadRequestOptions) => {
@if (@Model.IsApiService) {
@:let res = await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)Upload@(@column.PropertyName)PostForm(options.file);
} else {
@:let res = await upload@(@column.PropertyName)(options.file);
}
@:state.ruleForm.@(column.LowerPropertyName) = res.data.result?.url;
@:};
}
}
// 将属性或者函数暴露给父组件
//将属性或函数暴露给父组件
defineExpose({ openDialog });
</script>
@{
string LowerFirstLetter(string text)
{
return text.ToString()[..1].ToLower() + text[1..]; // 首字母小写
}
}
<style lang="scss" scoped>
</style>

View File

@ -1,404 +0,0 @@
@{
var pkField = Model.TableField.Where(c => c.ColumnKey == "True").FirstOrDefault();
string pkFieldName = null;
if(pkField != null && !string.IsNullOrEmpty(pkField.PropertyName))
{
pkFieldName = LowerFirstLetter(pkField.PropertyName);
}
Dictionary<string, int> definedObjects = new Dictionary<string, int>();
bool haveLikeCdt = false;
foreach (var column in Model.TableField){
if (column.QueryWhether == "Y" && column.QueryType == "like"){
haveLikeCdt = true;
}
}
}
<template>
<div class="@(@Model.LowerClassName)-container">
<el-card shadow="hover" :body-style="{ paddingBottom: '0' }">
@<el-form :model="queryParams" ref="queryForm" labelWidth="90">
@<el-row>
@if(Model.QueryWhetherList.Count > 0){
@if(haveLikeCdt){
@:<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="4" class="mb10">
@:<el-form-item label="关键字">
@:<el-input v-model="queryParams.searchKey" clearable="" placeholder="请输入模糊查询关键字"/>
@:
</el-form-item>
</el-col>
}
foreach (var column in Model.QueryWhetherList){
@:<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="4" class="mb10" v-if="showAdvanceQueryUI">
if(@column.EffectType == "Input" || @column.EffectType == "InputTextArea"){
@:<el-form-item label="@column.ColumnComment">
@:<el-input v-model="queryParams.@(@column.LowerPropertyName)" clearable="" placeholder="请输入@(@column.ColumnComment)"/>
@:
</el-form-item>
}else if(@column.EffectType == "InputTextArea"){
@:<el-form-item label="@column.ColumnComment">
@:<el-input-number v-model="queryParams.@(@column.LowerPropertyName)" clearable="" placeholder="请输入@(@column.ColumnComment)"/>
@:
</el-form-item>
}else if(@column.EffectType == "InputNumber"){
@:<el-form-item label="@column.ColumnComment">
@:<el-input-number v-model="queryParams.@(@column.LowerPropertyName)" clearable="" placeholder="请输入@(@column.ColumnComment)"/>
@:
</el-form-item>
}else if(@column.EffectType == "ForeignKey"){
@:<el-form-item label="@column.ColumnComment">
@:<el-select clearable="" filterable="" v-model="queryParams.@(@column.LowerPropertyName)" placeholder="请选择@(@column.ColumnComment)">
@:<el-option v-for="(item,index) in @LowerFirstLetter(@column.FkEntityName)@(@column.PropertyName)DropdownList" :key="index" :value="item.value" :label="item.label" />
@:
</el-select>
@:
</el-form-item>
}else if(@column.EffectType == "DictSelector"){
@:<el-form-item label="@column.ColumnComment">
@:<el-select clearable="" v-model="queryParams.@(@column.LowerPropertyName)" placeholder="请选择@(@column.ColumnComment)">
@:<el-option v-for="(item,index) in dl('@(@column.DictTypeCode)')" :key="index" :value="item.code" :label="`[${item.code}] ${item.value}`" />
@:
</el-select>
@:
</el-form-item>
}else if(@column.EffectType == "EnumSelector"){
@:<el-form-item label="@column.ColumnComment">
@:<el-select clearable="" v-model="queryParams.@(@column.LowerPropertyName)" placeholder="请选择@(@column.ColumnComment)">
@:<el-option v-for="(item,index) in dl('@(@column.DictTypeCode)')" :key="index" :value="item.value" :label="`${item.name} (${item.code}) [${item.value}] `" />
@:
</el-select>
@:
</el-form-item>
}else if(@column.EffectType == "DatePicker"){
@:<el-form-item label="@column.ColumnComment">
if(@column.QueryType == "~"){
@:<el-date-picker type="daterange" v-model="queryParams.@(@column.LowerPropertyName)Range" value-format="YYYY-MM-DD HH:mm:ss" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" />
}else
{
@:<el-date-picker placeholder="请选择@(@column.ColumnComment)" value-format="YYYY/MM/DD" v-model="queryParams.@(@column.LowerPropertyName)" />
}
@:
</el-form-item>
}
@:</el-col>
}
}
@<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="4" class="mb10">
@<el-form-item @(Model.QueryWhetherList.Count > 0?"":"label-width=\"0px\"")>
@<el-button-group style="display: flex; align-items: center;">
@<el-button type="primary" icon="ele-Search" @@click="handleQuery" v-auth="'@(@Model.LowerClassName)/page'"> @(Model.QueryWhetherList.Count > 0?"查询":"刷新") </el-button>
@if(Model.QueryWhetherList.Count > 0){
@:<el-button icon="ele-Refresh" @@click="() => queryParams = {}"> 重置 </el-button>
@if(haveLikeCdt){
@:<el-button icon="ele-ZoomIn" @@click="changeAdvanceQueryUI" v-if="!showAdvanceQueryUI" style="margin-left:5px;"> 高级查询 </el-button>
@:<el-button icon="ele-ZoomOut" @@click="changeAdvanceQueryUI" v-if="showAdvanceQueryUI" style="margin-left:5px;"> 隐藏 </el-button>
}
}
@<el-button type="primary" style="margin-left:5px;" icon="ele-Plus" @@click="openAdd@(@Model.ClassName)" v-auth="'@(@Model.LowerClassName)/add'"> 新增 </el-button>
@
</el-button-group>
</el-form-item>
@
@</el-col>
</el-row>
@* 操作区另起一行
@:<el-row>
@:<el-col>
@:<el-button-group style="margin-left:20px;margin-bottom:5px;">
@:<el-button type="primary" icon="ele-Plus" @@click="openAdd@(@Model.ClassName)" v-auth="'@(@Model.LowerClassName)/add'"> 新增 </el-button>
</el-button-group>
@:</el-col>
</el-row>
*@
</el-form>
</el-card>
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
<el-table
:data="tableData"
style="width: 100%"
v-loading="loading"
tooltip-effect="light"
@if(@pkFieldName != null)
{
@:row-key="@(@pkFieldName)"
}
@@sort-change="sortChange"
border="">
<el-table-column type="index" label="序号" width="55" align="center"/>
@foreach (var column in Model.TableField){
if(@column.WhetherTable == "Y"){
if(@column.EffectType == "Upload"||@column.EffectType == "ForeignKey"||@column.EffectType == "ApiTreeSelector"||@column.EffectType == "Switch"||@column.EffectType == "ConstSelector"){
@:<el-table-column prop="@column.LowerPropertyName" label="@column.ColumnComment" @(column.WhetherSortable == "Y" ? "sortable='custom'" : "") show-overflow-tooltip="">
@:<template #default="scope">
if(@column.EffectType == "Upload"){
@:<el-image
@:v-if="scope.row.@column.LowerPropertyName"
@:style="width: 60px; height: 60px"
@::src="scope.row.@column.LowerPropertyName"
@::lazy="true"
@::hide-on-click-modal="true"
@::preview-src-list="[scope.row.@column.LowerPropertyName]"
@::initial-index="0"
@:fit="scale-down"
@:preview-teleported=""/>
}else if(@column.EffectType == "ForeignKey"){
@:<span>{{scope.row.@LowerFirstLetter(@column.PropertyName)@(@column.FkColumnName)}}</span>
}else if(@column.EffectType == "ApiTreeSelector"){
@:<span>{{scope.row.@LowerFirstLetter(@column.PropertyName)@(column.DisplayColumn)}}</span>
}else if(@column.EffectType == "Switch"){
@:<el-tag v-if="scope.row.@(@column.LowerPropertyName)"> 是 </el-tag>
@:<el-tag type="danger" v-else> 否 </el-tag>
}else if(@column.EffectType == "ConstSelector"){
@:<span>{{codeToName(scope.row.@(@column.LowerPropertyName), '@(@column.DictTypeCode)')}}</span>
}
@:
</template>
@:
</el-table-column>
}
else if(@column.EffectType == "DictSelector"){
@:<el-table-column prop="@column.LowerPropertyName" label="@column.ColumnComment" @(column.WhetherSortable == "Y" ? "sortable='custom'" : "") show-overflow-tooltip="" >
@:<template #default="scope">
@:<el-tag :type="dc('@(@column.DictTypeCode)', scope.row.@(@column.LowerPropertyName))?.tagType"> {{dc("@(@column.DictTypeCode)", scope.row.@(@column.LowerPropertyName))?.label}} </el-tag>
@:</template>
@:</el-table-column>
}
else if(@column.EffectType == "EnumSelector"){
@:<el-table-column prop="@column.LowerPropertyName" label="@column.ColumnComment" @(column.WhetherSortable == "Y" ? "sortable='custom'" : "") show-overflow-tooltip="" >
@:<template #default="scope">
@:<el-tag :type="dv('@(@column.DictTypeCode)', scope.row.@(@column.LowerPropertyName))?.tagType"> {{dv('@(@column.DictTypeCode)', scope.row.@column.LowerPropertyName)?.name}}</el-tag>
@:</template>
@:</el-table-column>
}
else {
@:<el-table-column prop="@column.LowerPropertyName" label="@column.ColumnComment" @(column.WhetherSortable == "Y" ? "sortable='custom'" : "") show-overflow-tooltip="" />
}
}
}
@if(@Model.PrintType != "off"){
@:<el-table-column label="操作" width="200" align="center" fixed="right" show-overflow-tooltip="" v-if="auth('@(@Model.LowerClassName)/update') || auth('@(@Model.LowerClassName)/delete')">
@:<template #default="scope">
@:<el-button icon="ele-Printer" size="small" text="" type="primary" @@click="openPrint@(@Model.ClassName)(scope.row)" v-auth="'@(@Model.LowerClassName)/print'"> 打印 </el-button>
}else{
@:<el-table-column label="操作" width="140" align="center" fixed="right" show-overflow-tooltip="" v-if="auth('@(@Model.LowerClassName)/update') || auth('@(@Model.LowerClassName)/delete')">
@:<template #default="scope">
}
<el-button icon="ele-Edit" size="small" text="" type="primary" @@click="openEdit@(@Model.ClassName)(scope.row)" v-auth="'@(@Model.LowerClassName)/update'"> 编辑 </el-button>
<el-button icon="ele-Delete" size="small" text="" type="primary" @@click="del@(@Model.ClassName)(scope.row)" v-auth="'@(@Model.LowerClassName)/delete'"> 删除 </el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
v-model:currentPage="tableParams.page"
v-model:page-size="tableParams.pageSize"
:total="tableParams.total"
:page-sizes="[10, 20, 50, 100, 200, 500]"
size="small"
background=""
@@size-change="handleSizeChange"
@@current-change="handleCurrentChange"
layout="total, sizes, prev, pager, next, jumper"
/>
@if(@Model.PrintType != "off"){
@:<printDialog
@:ref="printDialogRef"
@::title="print@(@Model.ClassName)Title"
@:@@reloadTable="handleQuery" />
}
<editDialog
ref="editDialogRef"
:title="edit@(@Model.ClassName)Title"
@@reloadTable="handleQuery"
/>
</el-card>
</div>
</template>
<script lang="ts" setup="" name="@(@Model.LowerClassName)">
import { ref } from "vue";
import { ElMessageBox, ElMessage } from "element-plus";
import { auth } from '/@@/utils/authFunction';
import { useUserInfo } from '/@@/stores/userInfo';
import { Local } from '/@@/utils/storage';
@if(@Model.TableField.Any(x=>x.EffectType == "DatePicker")){
@:import { formatDate } from '/@@/utils/formatTime';
}
@if(@Model.PrintType != "off"){
@:// 推荐设置操作 width 为 200
@:import { hiprint } from 'vue-plugin-hiprint';
@:import { SysPrintApi } from '/@@/api-services/api';
@:import { SysPrint } from '/@@/api-services/models';
}
@if(@Model.PrintType != "off"){
@:import printDialog from '/@@/views/system/print/component/hiprint/preview.vue';
}
import editDialog from '/@@/views/@(@Model.PagePath)/@(@Model.LowerClassName)/component/editDialog.vue'
import { page@(@Model.ClassName), delete@(@Model.ClassName) } from '/@@/api/@(@Model.PagePath)/@(@Model.LowerClassName)';
@foreach (var column in Model.QueryWhetherList){
if(@column.EffectType == "ForeignKey"){
@:import { get@(@column.FkEntityName)@(@column.PropertyName)Dropdown } from '/@@/api/@(@Model.PagePath)/@(@Model.LowerClassName)';
}
}
@if(@Model.QueryWhetherList.Any(x=>x.EffectType == "EnumSelector")){
@:import { getAPI } from '/@@/utils/axios-utils';
@:import { SysEnumApi } from '/@@/api-services/api';
@:import commonFunction from '/@@/utils/commonFunction';
}
const userStore = useUserInfo();
@if(@Model.TableField.Any(x=>x.EffectType == "ConstSelector")){
@:const codeToName = userStore.codeToName;
}
@if(@Model.TableField.Any(x=>x.EffectType == "DictSelector") || @Model.TableField.Any(x=>x.EffectType == "EnumSelector")){
@:const dc = userStore.getDictItemByValue;
@:const dv = userStore.getDictItemByLabel;
@:const dl = userStore.getDictDataByCode;
}
// 本地存储参数
const localPageParamKey = 'localPageParam:@(@Model.LowerClassName)';
@if(haveLikeCdt){
@:const showAdvanceQueryUI = ref(false);
}else {
@:const showAdvanceQueryUI = ref(true);
}
@if(@Model.PrintType != "off"){
@:const printDialogRef = ref();
}
const editDialogRef = ref();
const loading = ref(false);
const tableData = ref<any>([]);
const queryParams = ref<any>({});
const tableParams = ref({
page: 1,
pageSize: Local.get(localPageParamKey)?.pageSize || 10,
field: 'createTime', // 默认的排序字段
order: 'descending', // 排序方向
descstr: 'descending', // 降序排序的关键字符
total: 0 as any,
});
@if(@Model.PrintType != "off"){
@:const print@(@Model.ClassName)Title = ref("");
}
const edit@(@Model.ClassName)Title = ref("");
// 改变高级查询的控件显示状态
const changeAdvanceQueryUI = () => {
showAdvanceQueryUI.value = !showAdvanceQueryUI.value;
}
// 查询操作
const handleQuery = async () => {
loading.value = true;
var res = await page@(@Model.ClassName)(Object.assign(queryParams.value, tableParams.value));
tableData.value = res.data.result?.items ?? [];
tableParams.value.total = res.data.result?.total;
loading.value = false;
};
// 列排序
const sortChange = async (column: any) => {
tableParams.value.field = column.prop;
tableParams.value.order = column.order;
await handleQuery();
};
// 打开新增页面
const openAdd@(@Model.ClassName) = () => {
edit@(@Model.ClassName)Title.value = '添加@(@Model.BusName)';
let data = {
@foreach (var column in Model.TableField){
if(@column.WhetherAddUpdate == "Y"&&@column.DefaultValue!=null){
if(@column.NetType.StartsWith("int")||@column.NetType.StartsWith("decimal")){
@:@column.LowerPropertyName:@(string.IsNullOrEmpty(@column.DefaultValue)?0:@column.DefaultValue),
}
if(@column.NetType.StartsWith("string")){
@:@column.LowerPropertyName:'@(@column.DefaultValue)',
}
}
}
};
editDialogRef.value.openDialog(data);
};
@if(@Model.PrintType != "off"){
@:// 打开打印页面
@:const openPrint@(@Model.ClassName) = async (row: any) => {
@:print@(@Model.ClassName)Title.value = '打印@(@Model.BusName)';
@if(@Model.PrintType != "off"){
@:var res = await getAPI(SysPrintApi).apiSysPrintPrintNameGet('@Model.PrintName');
@:var printTemplate = res.data.result as SysPrint;
@:var template = JSON.parse(printTemplate.template);
@:row['printDate'] = formatDate(new Date(), 'YYYY-mm-dd HH:MM:SS')
@:printDialogRef.value.showDialog(new hiprint.PrintTemplate({template: template}), row, template.panels[0].width);
}
@:}
}
// 打开编辑页面
const openEdit@(@Model.ClassName) = (row: any) => {
edit@(@Model.ClassName)Title.value = '编辑@(@Model.BusName)';
editDialogRef.value.openDialog(row);
};
// 删除
const del@(@Model.ClassName) = (row: any) => {
ElMessageBox.confirm(`确定要删除吗?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(async () => {
await delete@(@Model.ClassName)(row);
handleQuery();
ElMessage.success("删除成功");
})
.catch(() => {});
};
// 改变页面容量
const handleSizeChange = (val: number) => {
tableParams.value.pageSize = val;
Local.set(localPageParamKey, {pageSize:val});
handleQuery();
};
// 改变页码序号
const handleCurrentChange = (val: number) => {
tableParams.value.page = val;
handleQuery();
};
@foreach (var column in Model.QueryWhetherList){
if(@column.EffectType == "ForeignKey"){
@:const @LowerFirstLetter(@column.FkEntityName)@(@column.PropertyName)DropdownList = ref<any>([]);
@:const get@(@column.FkEntityName)@(@column.PropertyName)DropdownList = async () => {
@:let list = await get@(@column.FkEntityName)@(@column.PropertyName)Dropdown();
@:@LowerFirstLetter(@column.FkEntityName)@(@column.PropertyName)DropdownList.value = list.data.result ?? [];
@:};
@:get@(@column.FkEntityName)@(@column.PropertyName)DropdownList();
@:
}
}
handleQuery();
</script>
<style scoped>
:deep(.el-input),
:deep(.el-select),
:deep(.el-input-number) {
width: 100%;
}
:deep(.el-slider .el-input-number){
width: auto;
}
</style>
@{
string LowerFirstLetter(string text)
{
return text.ToString()[..1].ToLower() + text[1..]; // 首字母小写
}
}

View File

@ -1,51 +1,462 @@
@{
string LowerFirstLetter(string text)
{
return text.ToString()[..1].ToLower() + text[1..]; // 首字母小写
}
var pkField = Model.TableField.Where(c => c.ColumnKey == "True").FirstOrDefault();
string pkFieldName = null;
if(pkField != null && !string.IsNullOrEmpty(pkField.PropertyName))
{
pkFieldName = LowerFirstLetter(pkField.PropertyName);
}
Dictionary<string, int> definedObjects = new Dictionary<string, int>();
bool haveLikeCdt = false;
foreach (var column in Model.TableField){
if (column.QueryWhether == "Y" && column.QueryType == "like"){
haveLikeCdt = true;
}
}
<template>
@{
// 查询表单渲染方法
void ReaderTableSearchForm(CustomTemplateEngine sender, string nameSuffix) {
@:<el-card shadow="hover" :body-style="{ padding: '5px', display: 'flex', width: '100%', height: '100%', alignItems: 'start' }">
@:<el-form :model="state@(nameSuffix).queryParams" ref="queryForm" :show-message="false" :inlineMessage="true" label-width="auto" style="flex: 1 1 0%">
@:<el-row :gutter="10">
if (sender.QueryFields.Any(u => u.QueryType == "like")) {
@:<el-col :xs="24" @(Model.IsHorizontal ? ":sm=\"12\" :md=\"12\" :lg=\"12\" :xl=\"12\"" : ":sm=\"12\" :md=\"8\" :lg=\"6\" :xl=\"6\"") v-if="!state@(nameSuffix).showAdvanceQueryUI">
@:<el-form-item label="关键字">
@:<el-input v-model="state@(nameSuffix).queryParams.keyword" clearable placeholder="请输入模糊查询关键字" style="width: 150px" class="w100" />
@:</el-form-item>
@:</el-col>
}
foreach (var column in sender.QueryFields) {
@:<el-col class="mb5" :xs="24" @(Model.IsHorizontal ? ":sm=\"12\" :md=\"12\" :lg=\"12\" :xl=\"12\"" : ":sm=\"12\" :md=\"8\" :lg=\"6\" :xl=\"6\"") v-if="state@(nameSuffix).showAdvanceQueryUI">
@:<el-form-item label="@(column.ColumnComment)" prop="@(column.LowerPropertyName)">
if (column.IsInputTextArea) { // 文本框
@:<el-input v-model="state@(nameSuffix).queryParams.@(column.LowerPropertyName)" type="textarea" placeholder="请输入@(column.ColumnComment)" @@keyup.enter.native="handleQuery(false)" class="w100" clearable />
} else if (column.IsDatePicker) { // 时间
if (column.QueryType == "~") {
@:<el-date-picker type="daterange" v-model="state@(nameSuffix).queryParams.@(column.LowerPropertyName)Range" value-format="YYYY-MM-DD HH:mm:ss" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" class="w100" />
} else {
@:<el-date-picker placeholder="请选择@(column.ColumnComment)" value-format="YYYY/MM/DD" v-model="state@(nameSuffix).tableQueryParams.@(column.LowerPropertyName)" class="w100" />
}
} else if (column.IsInputNumber) { // 数字
@:<el-input-number v-model="state@(nameSuffix).queryParams.@(column.LowerPropertyName)" placeholder="请输入@(column.ColumnComment)" @@keyup.enter.native="handleQuery(false)" class="w100" clearable />
} else if (column.IsSwitch) { // 开关
@:<el-select v-model="state@(nameSuffix).queryParams.@(column.LowerPropertyName)" :placeholder="'请选择@(column.ColumnComment)'" class="w100" clearable>
@:<el-option label="是" :value="1" />
@:<el-option label="否" :value="0" />
@:</el-select>
} else if (column.IsConst) { // 常量
@:<el-select v-model="state@(nameSuffix).queryParams.@(column.LowerPropertyName)" :placeholder="'请选择@(column.ColumnComment)'" class="w100" clearable>
@:<el-option v-for="item in userInfo.getConstDataByTypeCode('@(column.DictConfig.Code)')" :key="item.code" :label="item.name" :value="item.code" />
@:</el-select>
} else if (column.IsDict || column.IsEnum) { // 字典枚举
@:<g-sys-dict v-model="state@(nameSuffix).queryParams.@(column.LowerPropertyName)" code="@(column.DictConfig.Code)" render-as="select" @@keyup.enter.native="handleQuery(false)" class="w100" clearable />
} else if (column.IsTree) { // 树组件
@:<el-cascader
@::options="state@(nameSuffix).dropdownData.@(column.LowerPropertyName) ?? []"
@::props="{ value: '@(Model.GetFirstLower(column.JoinConfig.LinkPropertyName))', label: '@(Model.GetFirstLower(column.JoinConfig.DisplayPropertyNames.Split(",").First()))', checkStrictly: true, emitPath: false }"
@:v-model="state@(nameSuffix).queryParams.@(column.LowerPropertyName)"
@:placeholder="请选择@(column.ColumnComment)"
@:clearable
@:filterable
@:class="w100">
@:<template #default="{ node, data }">
@:<span>@(string.Join("-", column.JoinConfig.DisplayPropertyNames.Split(",").Select(x => $"{{{{ data.{Model.GetFirstLower(x)} }}}}")))</span>
@:<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
@:</template>
@:</el-cascader>
} else if (column.IsForeignKey) { // 外键组件
var firstDisplayName = Model.GetFirstLower(column.JoinConfig.DisplayPropertyNames.Split(",").First());
var linkPropertyName = Model.GetFirstLower(column.JoinConfig.LinkPropertyName);
var leftJoinPropertyName = Model.GetFirstLower(column.LeftJoinPropertyName);
@:<pulldown-selecter
@:v-model="state@(nameSuffix).queryParams.@(column.LowerPropertyName)"
@::fetch-options="handle@(column.JoinConfig.EntityName)Table"
@::query-params="{ pageSize: 10 }"
@:value-prop="@(linkPropertyName)"
@:label-prop="@(firstDisplayName)"
@:placeholder="选择@(column.ColumnComment)"
@:filterable
@:clearable
@:class="w100">
@:<template #columns>
@:<el-table-column prop="id" label="主键ID" width="150" />
@:<el-table-column prop="@(firstDisplayName)" label="@(firstDisplayName)" width="150" />
@:</template>
@:</pulldown-selecter>
@:<!--
@:<el-select v-model="state@(nameSuffix).ruleForm.@(column.LowerPropertyName)" :placeholder="'请选择@(column.ColumnComment)'" clearable@(column.Multiple ? " multiple" : "") class="w100">
@:<el-option v-for="item in state@(nameSuffix).dropdownData.@(column.LowerPropertyName) ?? []" :key="item.@(linkPropertyName)" :label="item.@(firstDisplayName)" :value="item.@(linkPropertyName)" />
@:</el-select>
@:-->
} else { // 输入框
@:<el-input v-model="state@(nameSuffix).queryParams.@(column.LowerPropertyName)" placeholder="请输入@(column.ColumnComment)" @@keyup.enter.native="handleQuery(false)" class="w100" clearable />
}
@:</el-form-item>
@:</el-col>
}
@:</el-row>
@:</el-form>
@:<el-divider style="height: calc(100% - 5px); margin: 0 10px" direction="vertical" />
@:<el-row>
@:<el-col>
@:<el-button-group>
@:<el-button type="primary" icon="ele-Search" @@click="handleQuery@(nameSuffix)(false)"> @(sender.QueryFields.Any() ? "查询" : "刷新") </el-button>
if (sender.QueryFields.Any()) {
@:<el-button icon="ele-ZoomIn" @@click="() => state@(nameSuffix).showAdvanceQueryUI = true" v-if="!state@(nameSuffix).showAdvanceQueryUI" style="margin-left:5px;"> 高级查询 </el-button>
@:<el-button icon="ele-ZoomOut" @@click="() => state@(nameSuffix).showAdvanceQueryUI = false" v-if="state@(nameSuffix).showAdvanceQueryUI" style="margin-left:5px;"> 隐藏 </el-button>
@:<el-button icon="ele-Refresh" @@click="resetQuery@(nameSuffix)"> 重置 </el-button>
}
@:</el-button-group>
@:</el-col>
@:</el-row>
@:</el-card>
}
// 表格渲染方法
void ReaderTableGrid(CustomTemplateEngine sender, string nameSuffix) {
@:<vxe-card class="full-height" style="margin-top: 5px; height: calc(100vh - 160px)">
@:<vxe-grid ref="xGrid@(nameSuffix)" class="xGrid-style" v-bind="options@(nameSuffix)" v-on="gridEvents@(nameSuffix)"@(sender.TableFields.Any(u => u.IsStatistical) ? " :footer-data=\"[{ seq: '合计' } ]\"" : "")>
@:<template #toolbar_buttons>
@:<el-button type="primary" icon="ele-Plus" @@click="handleAdd@(nameSuffix)" v-auth="'@(sender.LowerClassName)/add'"> 新增 </el-button>
@:</template>
@:<template #import_button>
@:<div style="position: absolute; right: 5px; top: 15px">
@:<el-button type="primary" @@click="handleDownload@(nameSuffix)"> 下载模板 </el-button>
@:</div>
@:</template>
@:<template #toolbar_tools></template>
@:<template #empty><el-empty :image-size="200" /></template>
@:<template #row_record="{ row }"><ModifyRecord :data="row" /></template>
@:<template #$row_sysDict="{ row, column }">
@:<g-sys-dict v-model="row[column.field]" :code="column.params?.code" :multiple="column.params?.multiple" :isConst="column.params?.isConst" />
@:</template>
@:<template #$row_switch="{ row, column }">
@:<el-tag v-if="row[column.field]" type="success">是</el-tag>
@:<el-tag v-if="!row[column.field]" type="warring">否</el-tag>
@:</template>
@:<template #$row_status="{ row, column }">
@:<el-switch v-model="row[column.field]" :active-value="1" :inactive-value="2" @@click="handleStatusChange@(nameSuffix)(row)" />
@:</template>
@:<template #$row_copy="{ row, column }">
@:{{ row[column.field] }}
@:<el-button v-if="row[column.field]" class="ml5" icon="ele-CopyDocument" text type="primary" @@click="commonFun.copyText(row[column.field]?.toString())" />
@:</template>
@:<template #$row_upload="{ row, column }">
@:<el-avatar v-if="column.params?.isImage && row[column.params?.attachmentName]?.url" :src="row[column.params?.attachmentName]?.url" />
@:<el-link v-if="column.params?.useDownload && row[column.params?.attachmentName]?.url" type="primary" :href="row[column.params?.attachmentName]?.url" target="_blank"> {{ column.params?.DownloadText }} </el-link>
@:</template>
@:<template #$row_statistical="scope">
<span class="table-footer">{{commonFun.getStatistical(scope)}}</span>
@:</template>
@:<template #row_buttons="{ row }">
@:<el-button icon="ele-Delete" size="small" text type="danger" @@click="handleDelete@(nameSuffix)(row)" v-auth="'@(sender.LowerClassName)/delete'">删除</el-button>
@:<el-button icon="ele-Edit" size="small" text type="primary" @@click="handleEdit@(nameSuffix)(row)" v-auth="'@(sender.LowerClassName)/update'">编辑</el-button>
@:<el-button icon="ele-Warning" size="small" text type="primary" @@click="handleDetail@(nameSuffix)(row)" v-auth="'@(sender.LowerClassName)/detail'">详情</el-button>
@:</template>
@:</vxe-grid>
@:</vxe-card>
}
}
<template>
<div class="@(@Model.LowerClassName)-container">
<IndexList ref="indexListRef" @@list-click="handleIndexChange" />
</div>
<div class="sys-@(Model.LowerClassName)-container">
<splitpanes@(Model.TreeConfig == null && Model.IsHorizontal ? " horizontal" : "")>
@if (Model.TreeConfig != null) {
@:<pane size="15" style="display: flex">
@:<@(Model.TreeConfig.LowerEntityName)Tree ref="@(Model.TreeConfig.LowerEntityName)TreeRef" @@node-click="handleNodeChange" />
@:</pane>
}
<pane>
@{ ReaderTableSearchForm(Model, ""); }
@{ ReaderTableGrid(Model, ""); }
</pane>
@if (Model.SlaveTable != null) {
@:<pane>
@{ ReaderTableSearchForm(Model.SlaveTable, "Slave"); }
@{ ReaderTableGrid(Model.SlaveTable, "Slave"); }
@:</pane>
}
</splitpanes>
<Edit@(Model.ClassName)Dialog ref="edit@(Model.ClassName)DialogRef" @@handleQuery="handleQuery" />
@if (Model.SlaveTable != null) {
@:<Edit@(Model.SlaveTable.ClassName)Dialog ref="edit@(Model.SlaveTable.ClassName)DialogRef" @@handleQuery="handleQuerySlave" />
}
</div>
</template>
<script lang="ts" setup name="@(@Model.LowerClassName)">
<!-- @(Model.BusName) -->
<script lang="ts" setup name="@(Model.LowerClassName)">
import { onMounted, reactive, ref } from 'vue';
import IndexList from '/@@/views/@(@Model.PagePath)/@(@Model.LowerClassName)/component/list.vue';
const indexListRef = ref<InstanceType<typeof IndexList>>();
// 变量初始化
const state = reactive({
queryParams: {
searchKey: undefined,
@if(Model.QueryWhetherList.Count > 0) {
@foreach (var column in Model.QueryWhetherList) {
@:@(@column.LowerPropertyName): undefined,
}
}
}
});
// 页面初始化,列表控件初始化不请求数据,这里要请求一下
onMounted(() => {
indexListRef.value?.listhandleQuery(state.queryParams);
});
// 主表List组件点击
const handleIndexChange = async (row: any,column: any) => {
console.log('handleIndexChange--', JSON.stringify(row));
console.log('handleIndexChange--', JSON.stringify(column));
};
import { ElMessageBox, ElMessage } from 'element-plus';
import { VxeGridInstance, VxeGridListeners, VxeGridPropTypes } from 'vxe-table';
import { useVxeTable } from '/@@/hooks/useVxeTableOptionsHook';
import commonFunction from "/@@/utils/commonFunction";
import {downloadStreamFile} from "/@@/utils/download";
@if (Model.AllFields.Concat(Model.SlaveTable?.AllFields ?? []).Any(u => u.IsConst)) {
@:import {useUserInfo} from "/@@/stores/userInfo";
}
import { Local } from '/@@/utils/storage';
import ModifyRecord from '/@@/components/table/modifyRecord.vue';
@if (Model.AllFields.Concat(Model.SlaveTable?.AllFields ?? []).Any(u => u.IsForeignKey)) {
@:import PulldownSelecter from "/@@/components/selector/pulldownSelecter.vue";
}
import Edit@(Model.ClassName)Dialog from './component/edit@(Model.ClassName)Dialog.vue';
@if (Model.SlaveTable != null) {
@:import Edit@(Model.SlaveTable.ClassName)Dialog from './component/edit@(Model.SlaveTable.ClassName)Dialog.vue';
}
@if (Model.TreeConfig != null) {
@:import @(Model.TreeConfig.EntityName)Tree from "./component/@(Model.TreeConfig.LowerEntityName)Tree.vue";
}
@if (Model.IsApiService) {
@:import { getAPI } from '/@@/utils/axios-utils';
var useApiList = new List<string>() { $"{Model.ClassName}Api" };
var useApiModelList = new List<string>() { $"Page{Model.ClassName}Input", $"Page{Model.ClassName}Output", $"Update{Model.ClassName}Input" };
if (Model.SlaveTable != null) { // 增加从表Api依赖导入
useApiList.Add($"{Model.SlaveTable.ClassName}Api");
useApiModelList.AddRange(new List<string>() { $"Page{Model.SlaveTable.ClassName}Input", $"Page{Model.SlaveTable.ClassName}Output", $"Update{Model.SlaveTable.ClassName}Input" });
}
@:import { @(string.Join(", ", useApiList)) } from '/@@/api-services/@(Model.PagePath)/api';
@:import { @(string.Join(", ", useApiModelList)) } from '/@@/api-services/@(Model.PagePath)/models';
} else {
var useApiList = new List<string>() { $"use{Model.ClassName}Api" };
if (Model.SlaveTable != null) { // 增加从表Api依赖导入
useApiList.Add($"use{Model.SlaveTable.ClassName}Api");
}
@:import { @(string.Join(", ", useApiList)) } from '/@@/api/@(Model.PagePath)/@(Model.LowerClassName)';
}
@if (Model.AllFields.Concat(Model.SlaveTable?.AllFields ?? []).Any(u => u.IsConst)) {
@:const userInfo = useUserInfo();
}
const commonFun = commonFunction();
@if(!Model.IsApiService) {
@:const @(Model.LowerClassName)Api = use@(Model.ClassName)Api();
if (Model.SlaveTable != null) {
@:const @(Model.SlaveTable.LowerClassName)Api = use@(Model.SlaveTable.ClassName)Api();
}
}
@if (Model.TreeConfig != null) {
@:const @(Model.TreeConfig.LowerEntityName)TreeRef = ref<InstanceType<typeof @(Model.TreeConfig.LowerEntityName)Tree>>();
}
// 页面初始化
onMounted(async () => {
initModule();
@if (Model.SlaveTable != null) {
@:initModuleSlave();
}
})
@{
RenderMethod(Model, "");
if (Model.SlaveTable != null) {
@:
RenderMethod(Model.SlaveTable, "Slave");
}
void RenderMethod(CustomTemplateEngine sender, string nameSuffix) {
@:// @(sender.BusName)状态参数
@:const state@(nameSuffix) = reactive({
if (!string.IsNullOrWhiteSpace(sender.LastLinkPropertyName)) {
@:@(Model.GetFirstLower(sender.LastLinkPropertyName)): undefined as any,
}
@:resetQueryParams: {} as Page@(sender.ClassName)Input,
@:queryParams: {} as Page@(sender.ClassName)Input,
if (sender.AllFields.Any(u => u.IsTree)) {
@:dropdownData: {} as any,
}
@:showAdvanceQueryUI: false,
@:localPageParam: {
@:pageSize: 20 as number,
@:defaultSort: { field: '@(sender.AllFields.Any(u => u.PropertyName == "OrderNo") ? "orderNo" : "id")', order: 'asc', descStr: 'desc' },
@:},
@:visible: false
@:})
@:
@:const xGrid@(nameSuffix) = ref<VxeGridInstance>();
@:const edit@(sender.ClassName)DialogRef = ref<InstanceType<typeof Edit@(sender.ClassName)Dialog>>();
@:const localPageParamKey@(nameSuffix) = 'localPageParam:@(sender.LowerClassName)'; // @(sender.BusName)本地存储参数
@:const options@(nameSuffix) = useVxeTable<Page@(sender.ClassName)Output>( // @(sender.BusName)表格参数配置
@:{
@:id: '@(sender.LowerClassName)',
@:name: '@(sender.BusName)',
@:columns: [
@:// { type: 'checkbox', width: 40, fixed: 'left' },
@:{ field: 'seq', type: 'seq', title: '序号', width: 60, fixed: 'left' },
foreach(var column in sender.TableFields) {
@:{ field: '@(column.LowerPropertyName)', title: '@(column.ColumnComment)', minWidth: 150,@(column.IsSortable ? " sortable: true," : "") showOverflow: 'tooltip'@(column.GetVxeColumnExtraConfig) },
}
@:{ field: 'record', title: '修改记录', width: 100, showOverflow: 'tooltip', slots: { default: 'row_record' } },
@:{ field: 'buttons', title: '操作', fixed: 'right', width: 200, showOverflow: true, slots: { default: 'row_buttons' } },
@:],
@:}, {// vxeGrid配置参数(此处可覆写任何参数)参考vxe-table官方文档
@if (sender.TableFields.Any(u => u.IsStatistical)) {
@:// 显示表格统计行
@:showFooter: true,
}
@:// 代理配置
@:proxyConfig: { autoLoad: true, ajax: { query: ({ page, sort }) => handleQueryApi@(nameSuffix)(page, sort) } },
@:// 排序配置
@:sortConfig: { defaultSort: Local.get(localPageParamKey@(nameSuffix))?.defaultSort || state@(nameSuffix).localPageParam.defaultSort },
@:// 分页配置
@:pagerConfig: { pageSize: Local.get(localPageParamKey@(nameSuffix))?.pageSize || state@(nameSuffix).localPageParam.pageSize },
@:// 导入配置
@:importConfig: @(sender.ImportFields.Any() ? ("{ remote: true, importMethod: (options: any) => handleImport" + nameSuffix + "(options), slots: { top: 'import_button' }}") : "{} as any"),
@:// 工具栏配置
@:toolbarConfig: { import: @(sender.ImportFields.Any() ? "true" : "false"), export: true },
@:}
@:)
@:
@:// @(sender.BusName)模块初始化
@:const initModule@(nameSuffix) = async () => {
@:state@(nameSuffix).resetQueryParams = Object.assign({}, state@(nameSuffix).queryParams);
@:state@(nameSuffix).localPageParam = Local.get(localPageParamKey) || state@(nameSuffix).localPageParam;
@foreach (var column in Model.AllFields.Where(u => u.IsTree).GroupBy(u => new { u.IsTree }).Select(u => u.First())) {
if (column.JoinConfig.UseTable) continue;
var methodName = column.JoinConfig.EntityName + (column.IsTree ? "Tree" : "Table");
@:// 查询@(column.JoinConfig.TableComment)数据
@:state@(nameSuffix).dropdownData.@(column.LowerPropertyName) = await handle@(methodName)({}).then(res => res.data.result ?? []);
}
@:}
@:
@:// @(sender.BusName)表格查询api
@:const handleQueryApi@(nameSuffix) = (page: VxeGridPropTypes.ProxyAjaxQueryPageParams, sort: VxeGridPropTypes.ProxyAjaxQuerySortCheckedParams) => {
@:const params = Object.assign(state@(nameSuffix).queryParams, { page: page.currentPage, pageSize: page.pageSize, field: sort.field, order: sort.order, descStr: 'desc' }) as Page@(sender.ClassName)Input;
@:return @(Model.GetHttpApiMethodName(null, "page", sender))(params);
@:}
@:
@:// @(sender.BusName)表格查询操作
@:const handleQuery@(nameSuffix) = async (reset = false) => {
@:options@(nameSuffix).loading = true;
@:reset ? await xGrid@(nameSuffix).value?.commitProxy('reload') : await xGrid@(nameSuffix).value?.commitProxy('query');
@:options@(nameSuffix).loading = false;
@:}
@:
@:// @(sender.BusName)重置操作
@:const resetQuery@(nameSuffix) = async () => {
@:state@(nameSuffix).queryParams = Object.assign({}, state@(nameSuffix).resetQueryParams);
@:await xGrid@(nameSuffix).value?.commitProxy('reload');
@:}
@:
@:// 打开@(sender.BusName)新增页面
@:const handleAdd@(nameSuffix) = () => {
@:edit@(sender.ClassName)DialogRef.value?.openDialog(undefined, '添加@(sender.BusName)');
@:}
@:
@:// @(sender.BusName)删除操作
@:const handleDelete@(nameSuffix) = (row: any) => {
@:ElMessageBox.confirm(`确定删除记录?`, '提示', {
@:confirmButtonText: '确定',
@:cancelButtonText: '取消',
@:type: 'warning',
@:}).then(async () => {
@:await @(Model.GetHttpApiMethodName(null, "delete", sender))({ id: row.id });
@:await handleQuery@(nameSuffix)();
@:ElMessage.success('删除成功');
@:}).catch(() => {});
@:}
@:
@:// 打开@(sender.BusName)编辑页面
@:const handleEdit@(nameSuffix) = async (row: any) => {
@:edit@(sender.ClassName)DialogRef.value?.openDialog(row, '编辑@(sender.BusName)');
@:}
@:
@:// 打开@(sender.BusName)详情页面
@:const handleDetail@(nameSuffix) = async (row: any) => {
@:edit@(sender.ClassName)DialogRef.value?.openDialog(row, '@(sender.BusName)详情');
@:}
if (sender.AllFields.Any(u => u.IsStatus)) {
@:
@:// @(sender.BusName)设置状态
@:const handleStatusChange@(nameSuffix) = (row: any) => {
@:ElMessageBox.confirm(`确定${row.status === 2 ? '停用' : '启用'}该记录?`, '提示', {
@:confirmButtonText: '确定',
@:cancelButtonText: '取消',
@:type: 'warning',
@:closeOnClickModal: false, // 禁止点击遮罩层关闭
@:closeOnPressEscape: false, // 禁止按 Esc 键关闭
@:}).then(async () => {
@:@(Model.GetHttpApiMethodName(null, "setStatus", sender))({ id: row.id, status: row.status });
@:ElMessage.success('操作成功');
@:}).catch(() => {
@:// 取消操作,还原状态
@:row.status = row.status === 1 ? 2 : 1;
@:});
@:}
}
if (sender.ImportFields.Any()) {
@:
@:// 下载@(sender.BusName)模板
@:const handleDownload@(nameSuffix) = async () => {
@:await @(Model.GetHttpApiMethodName(null, "downloadTemplate", sender))({ responseType: 'arraybuffer' }).then(downloadStreamFile);
@:}
@:
@:// @(sender.BusName)数据导入
@:const handleImport@(nameSuffix) = async (options: any) => {
@:const res = @(Model.GetHttpApiMethodName(null, "importData", sender))(options.file, { responseType: 'arraybuffer' });
@:res.then(downloadStreamFile);
@:return res;
@:}
}
@:
@:// @(sender.BusName)表格事件
@:const gridEvents@(nameSuffix): VxeGridListeners<Page@(sender.ClassName)Output> = {
@:// 只对 pager-config 配置时有效,分页发生改变时会触发该事件
@:async pageChange({ pageSize }) {
@:state@(nameSuffix).localPageParam.pageSize = pageSize;
@:Local.set(localPageParamKey@(nameSuffix), state@(nameSuffix).localPageParam);
@:},
@:// 当排序条件发生变化时会触发该事件
@:async sortChange({ field, order }) {
@:const config = state@(nameSuffix).localPageParam.defaultSort;
@:state@(nameSuffix).localPageParam.defaultSort = { field: field ?? config?.field, order: order ?? config?.order, descStr: 'desc' };
@:Local.set(localPageParamKey@(nameSuffix), state@(nameSuffix).localPageParam);
@:},
if (sender.SlaveTable != null && !string.IsNullOrWhiteSpace(sender.NextLinkPropertyName)) {
@:// 单元格点击事件
@:async cellClick({ row }) {
@:if (stateSlave.queryParams.@(Model.GetFirstLower(sender.SlaveTable.LastLinkPropertyName)) == row.@(Model.GetFirstLower(sender.NextLinkPropertyName))) return;
@:stateSlave.queryParams.@(Model.GetFirstLower(sender.SlaveTable.LastLinkPropertyName)) = row.@(Model.GetFirstLower(sender.NextLinkPropertyName)) as any;
@:handleQuerySlave();
@:},
}
@:}
}
}
@if(Model.TreeConfig != null) {
@:// 树组件点击
@:const handleNodeChange = async (node: any) => {
@:state.queryParams.@(Model.GetFirstLower(Model.LastLinkPropertyName)) = node.@(Model.GetFirstLower(Model.TreeConfig.LinkPropertyName));
@:@(Model.TreeConfig.LowerEntityName)TreeRef?.value?.setCurrentKey();
@:await handleQuery();
@:};
}
@{
var methodNameList = new List<string>();
foreach (var column in Model.ApiFields.Concat(Model.SlaveTable?.ApiFields ?? [])) {
var methodName = column.JoinConfig.EntityName + (column.IsTree ? "Tree" : "Table");
if (methodNameList.Contains(methodName)) continue;
methodNameList.Add(methodName);
@:// 查询@(column.JoinConfig.TableComment)@(column.IsTree ? "树结构" : "")数据
@:const handle@(methodName) = async (data: any) => {
@:return await @(Model.GetHttpApiMethodName(column, column.IsTree ? "fkTree" : "fkTable"))(data);
@:}
@:
}
}
</script>
<style scoped>
:deep(.el-card) {
overflow: visible !important;
}
.full-height {
display: flex;
flex-direction: column;
height: calc(100% - 40px);
}
.table-footer {
color: red;
}
</style>

View File

@ -1,8 +0,0 @@
export default {
@Model.LowerClassName: {
@Model.LowerClassName: '@Model.BusName',
@foreach (var column in Model.TableField) {
@:@column.LowerPropertyName: '@column.ColumnComment',
}
},
};

View File

@ -33,7 +33,7 @@
"@wangeditor/editor-for-vue": "^5.1.12",
"animate.css": "^4.1.1",
"async-validator": "^4.2.5",
"axios": "^1.12.1",
"axios": "^1.12.2",
"compressorjs": "^1.2.1",
"countup.js": "^2.9.0",
"cropperjs": "^1.6.2",

View File

@ -72,6 +72,7 @@ const openDialog = (row: any) => {
state.ruleForm.entityName = upperFirst(camelCase(row.tableName));
state.ruleForm.baseClassName = 'EntityBase';
state.ruleForm.position = row.position;
state.ruleForm.authorName = 'Admin.NET';
state.isShowDialog = true;
};
@ -97,7 +98,7 @@ const submit = () => {
ElNotification({
title: '提示',
message: '生成成功,请重启项目以加载最新代码',
message: '生成成功,请重启服务加载最新代码',
type: 'success',
position: 'bottom-right',
});