Merge remote-tracking branch 'source/main' into main
This commit is contained in:
commit
8ab703ff8b
@ -17,27 +17,27 @@
|
|||||||
<PackageReference Include="AngleSharp" Version="1.1.2" />
|
<PackageReference Include="AngleSharp" Version="1.1.2" />
|
||||||
<PackageReference Include="AspectCore.Extensions.Reflection" Version="2.4.0" />
|
<PackageReference Include="AspectCore.Extensions.Reflection" Version="2.4.0" />
|
||||||
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
|
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
|
||||||
<PackageReference Include="Elastic.Clients.Elasticsearch" Version="8.14.3" />
|
<PackageReference Include="Elastic.Clients.Elasticsearch" Version="8.14.4" />
|
||||||
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.4.2" />
|
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.4.3" />
|
||||||
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.9.4.2" />
|
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.9.4.3" />
|
||||||
<PackageReference Include="Furion.Pure" Version="4.9.4.2" />
|
<PackageReference Include="Furion.Pure" Version="4.9.4.3" />
|
||||||
<PackageReference Include="IPTools.China" Version="1.6.0" />
|
<PackageReference Include="IPTools.China" Version="1.6.0" />
|
||||||
<PackageReference Include="IPTools.International" Version="1.6.0" />
|
<PackageReference Include="IPTools.International" Version="1.6.0" />
|
||||||
<PackageReference Include="Magicodes.IE.Excel" Version="2.7.5.1" />
|
<PackageReference Include="Magicodes.IE.Excel" Version="2.7.5.1" />
|
||||||
<PackageReference Include="Magicodes.IE.Pdf" Version="2.7.5.1" />
|
<PackageReference Include="Magicodes.IE.Pdf" Version="2.7.5.1" />
|
||||||
<PackageReference Include="Magicodes.IE.Word" Version="2.7.5.1" />
|
<PackageReference Include="Magicodes.IE.Word" Version="2.7.5.1" />
|
||||||
<PackageReference Include="MailKit" Version="4.6.0" />
|
<PackageReference Include="MailKit" Version="4.7.0" />
|
||||||
<PackageReference Include="NewLife.Redis" Version="5.7.2024.602" />
|
<PackageReference Include="NewLife.Redis" Version="5.7.2024.701" />
|
||||||
<PackageReference Include="Novell.Directory.Ldap.NETStandard" Version="3.6.0" />
|
<PackageReference Include="Novell.Directory.Ldap.NETStandard" Version="3.6.0" />
|
||||||
<PackageReference Include="QRCoder" Version="1.5.1" />
|
<PackageReference Include="QRCoder" Version="1.6.0" />
|
||||||
<PackageReference Include="RabbitMQ.Client" Version="6.8.1" />
|
<PackageReference Include="RabbitMQ.Client" Version="6.8.1" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp.Web" Version="3.1.2" />
|
<PackageReference Include="SixLabors.ImageSharp.Web" Version="3.1.2" />
|
||||||
<PackageReference Include="SKIT.FlurlHttpClient.Wechat.Api" Version="3.3.0" />
|
<PackageReference Include="SKIT.FlurlHttpClient.Wechat.Api" Version="3.3.0" />
|
||||||
<PackageReference Include="SKIT.FlurlHttpClient.Wechat.TenpayV3" Version="3.5.0" />
|
<PackageReference Include="SKIT.FlurlHttpClient.Wechat.TenpayV3" Version="3.5.0" />
|
||||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.160" />
|
<PackageReference Include="SqlSugarCore" Version="5.1.4.160" />
|
||||||
<PackageReference Include="SSH.NET" Version="2024.0.0" />
|
<PackageReference Include="SSH.NET" Version="2024.1.0" />
|
||||||
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.4.2" />
|
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.4.3" />
|
||||||
<PackageReference Include="TencentCloudSDK.Sms" Version="3.0.1036" />
|
<PackageReference Include="TencentCloudSDK.Sms" Version="3.0.1038" />
|
||||||
<PackageReference Include="UAParser" Version="3.1.47" />
|
<PackageReference Include="UAParser" Version="3.1.47" />
|
||||||
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
|
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@ -1,41 +0,0 @@
|
|||||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
|
||||||
//
|
|
||||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
|
||||||
//
|
|
||||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
|
||||||
|
|
||||||
using System.Net;
|
|
||||||
|
|
||||||
namespace Admin.NET.Core;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// HttpContext拓展
|
|
||||||
/// </summary>
|
|
||||||
[SuppressSniffer]
|
|
||||||
public static partial class HttpContextExtension
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 获取客户端真实 IP 地址
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>bool</returns>
|
|
||||||
public static string GetRemoteIp(this HttpContext httpContext)
|
|
||||||
{
|
|
||||||
var ip = string.Empty;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// 从 X-Forwarded-For 头获取 IP
|
|
||||||
ip = httpContext.Request.Headers["X-Forwarded-For"];
|
|
||||||
if (string.IsNullOrEmpty(ip))
|
|
||||||
{
|
|
||||||
ip = httpContext.GetRemoteIpAddressToIPv4();
|
|
||||||
}
|
|
||||||
// 验证 IP 地址有效性
|
|
||||||
if (!IPAddress.TryParse(ip, out _))
|
|
||||||
{
|
|
||||||
ip = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
return ip;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -167,6 +167,13 @@ public class SysMenuSeedData : ISqlSugarEntitySeedData<SysMenu>
|
|||||||
|
|
||||||
new SysMenu{ Id=1310000000431, Pid=1310000000301, Title="系统配置", Path="/platform/infoSetting", Name="sysInfoSetting", Component="/system/infoSetting/index", Icon="ele-Setting", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=220 },
|
new SysMenu{ Id=1310000000431, Pid=1310000000301, Title="系统配置", Path="/platform/infoSetting", Name="sysInfoSetting", Component="/system/infoSetting/index", Icon="ele-Setting", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=220 },
|
||||||
|
|
||||||
|
new SysMenu{ Id=1310000000441, Pid=1310000000301, Title="微信支付", Path="/platform/wechatpay", Name="sysWechatPay", Component="/system/weChatPay/index", Icon="ele-Coin", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=230 },
|
||||||
|
new SysMenu{ Id=1310000000442, Pid=1310000000441, Title="微信支付下单Native", Permission="sysWechatPay:payTransactionNative", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
|
||||||
|
new SysMenu{ Id=1310000000443, Pid=1310000000441, Title="查询退款信息", Permission="sysWechatPay:listRefund", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
|
||||||
|
new SysMenu{ Id=1310000000444, Pid=1310000000441, Title="获取支付订单详情(本地库)", Permission="sysWechatPay:payInfo", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
|
||||||
|
new SysMenu{ Id=1310000000445, Pid=1310000000441, Title="获取支付订单详情(微信接口)", Permission="sysWechatPay:payInfoFromWechat", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
|
||||||
|
new SysMenu{ Id=1310000000446, Pid=1310000000441, Title="退款申请", Permission="sysWechatPay:refundDomestic", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
|
||||||
|
|
||||||
new SysMenu{ Id=1310000000501, Pid=0, Title="日志管理", Path="/log", Name="log", Component="Layout", Icon="ele-DocumentCopy", Type=MenuTypeEnum.Dir, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=12000 },
|
new SysMenu{ Id=1310000000501, Pid=0, Title="日志管理", Path="/log", Name="log", Component="Layout", Icon="ele-DocumentCopy", Type=MenuTypeEnum.Dir, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=12000 },
|
||||||
new SysMenu{ Id=1310000000511, Pid=1310000000501, Title="访问日志", Path="/log/vislog", Name="sysVisLog", Component="/system/log/vislog/index", Icon="ele-Document", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
|
new SysMenu{ Id=1310000000511, Pid=1310000000501, Title="访问日志", Path="/log/vislog", Name="sysVisLog", Component="/system/log/vislog/index", Icon="ele-Document", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
|
||||||
new SysMenu{ Id=1310000000512, Pid=1310000000511, Title="查询", Permission="sysVislog:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
|
new SysMenu{ Id=1310000000512, Pid=1310000000511, Title="查询", Permission="sysVislog:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
|
||||||
|
|||||||
@ -238,7 +238,7 @@ public class SysAuthService : IDynamicApiController, ITransient
|
|||||||
// ke.global.setAllHeader('Authorization', 'Bearer ' + ke.response.headers['access-token']);
|
// ke.global.setAllHeader('Authorization', 'Bearer ' + ke.response.headers['access-token']);
|
||||||
|
|
||||||
// 更新用户登录信息
|
// 更新用户登录信息
|
||||||
user.LastLoginIp = _httpContextAccessor.HttpContext.GetRemoteIp();
|
user.LastLoginIp = _httpContextAccessor.HttpContext.GetRemoteIpAddressToIPv4(true);
|
||||||
(user.LastLoginAddress, double? longitude, double? latitude) = CommonUtil.GetIpAddress(user.LastLoginIp);
|
(user.LastLoginAddress, double? longitude, double? latitude) = CommonUtil.GetIpAddress(user.LastLoginIp);
|
||||||
user.LastLoginTime = DateTime.Now;
|
user.LastLoginTime = DateTime.Now;
|
||||||
user.LastLoginDevice = CommonUtil.GetClientDeviceInfo(_httpContextAccessor.HttpContext?.Request?.Headers?.UserAgent);
|
user.LastLoginDevice = CommonUtil.GetClientDeviceInfo(_httpContextAccessor.HttpContext?.Request?.Headers?.UserAgent);
|
||||||
|
|||||||
@ -64,33 +64,6 @@ public class SysFileService : IDynamicApiController, ITransient
|
|||||||
return await HandleUploadFile(input.File, input.Path, fileType: input.FileType);
|
return await HandleUploadFile(input.File, input.Path, fileType: input.FileType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 上传文件Base64
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="strBase64"></param>
|
|
||||||
/// <param name="fileName"></param>
|
|
||||||
/// <param name="contentType"></param>
|
|
||||||
/// <param name="path"></param>
|
|
||||||
/// <param name="fileType"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private async Task<SysFile> UploadFileFromBase64(string strBase64, string fileName, string contentType, string? path, string? fileType)
|
|
||||||
{
|
|
||||||
byte[] fileData = Convert.FromBase64String(strBase64);
|
|
||||||
var ms = new MemoryStream();
|
|
||||||
ms.Write(fileData);
|
|
||||||
ms.Seek(0, SeekOrigin.Begin);
|
|
||||||
if (string.IsNullOrEmpty(fileName))
|
|
||||||
fileName = $"{YitIdHelper.NextId()}.jpg";
|
|
||||||
if (string.IsNullOrEmpty(contentType))
|
|
||||||
contentType = "image/jpg";
|
|
||||||
IFormFile formFile = new FormFile(ms, 0, fileData.Length, "file", fileName)
|
|
||||||
{
|
|
||||||
Headers = new HeaderDictionary(),
|
|
||||||
ContentType = contentType
|
|
||||||
};
|
|
||||||
return await UploadFile(new FileUploadInput { File = formFile, Path = path, FileType = fileType });
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 上传文件Base64 🔖
|
/// 上传文件Base64 🔖
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -99,7 +72,20 @@ public class SysFileService : IDynamicApiController, ITransient
|
|||||||
[DisplayName("上传文件Base64")]
|
[DisplayName("上传文件Base64")]
|
||||||
public async Task<SysFile> UploadFileFromBase64(UploadFileFromBase64Input input)
|
public async Task<SysFile> UploadFileFromBase64(UploadFileFromBase64Input input)
|
||||||
{
|
{
|
||||||
return await UploadFileFromBase64(input.FileDataBase64, input.FileName, input.ContentType, input.Path, input.FileType);
|
byte[] fileData = Convert.FromBase64String(input.FileDataBase64);
|
||||||
|
var ms = new MemoryStream();
|
||||||
|
ms.Write(fileData);
|
||||||
|
ms.Seek(0, SeekOrigin.Begin);
|
||||||
|
if (string.IsNullOrEmpty(input.FileName))
|
||||||
|
input.FileName = $"{YitIdHelper.NextId()}.jpg";
|
||||||
|
if (string.IsNullOrEmpty(input.ContentType))
|
||||||
|
input.ContentType = "image/jpg";
|
||||||
|
IFormFile formFile = new FormFile(ms, 0, fileData.Length, "file", input.FileName)
|
||||||
|
{
|
||||||
|
Headers = new HeaderDictionary(),
|
||||||
|
ContentType = input.ContentType
|
||||||
|
};
|
||||||
|
return await UploadFile(new FileUploadInput { File = formFile, Path = input.Path, FileType = input.FileType });
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -335,7 +321,7 @@ public class SysFileService : IDynamicApiController, ITransient
|
|||||||
|
|
||||||
// 获取文件后缀
|
// 获取文件后缀
|
||||||
var suffix = Path.GetExtension(file.FileName).ToLower(); // 后缀
|
var suffix = Path.GetExtension(file.FileName).ToLower(); // 后缀
|
||||||
if (string.IsNullOrWhiteSpace(suffix))
|
if (!string.IsNullOrWhiteSpace(suffix))
|
||||||
{
|
{
|
||||||
var contentTypeProvider = FS.GetFileExtensionContentTypeProvider();
|
var contentTypeProvider = FS.GetFileExtensionContentTypeProvider();
|
||||||
suffix = contentTypeProvider.Mappings.FirstOrDefault(u => u.Value == file.ContentType).Key;
|
suffix = contentTypeProvider.Mappings.FirstOrDefault(u => u.Value == file.ContentType).Key;
|
||||||
|
|||||||
@ -51,7 +51,7 @@ public class JobClusterServer : IJobClusterServer
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ICache _cache = App.GetRequiredService<ICache>();
|
ICache _cache = App.GetRequiredService<ICacheProvider>().Cache;
|
||||||
// 使用分布式锁
|
// 使用分布式锁
|
||||||
using (_cache.AcquireLock("lock:JobClusterServer:WaitingForAsync", 1000))
|
using (_cache.AcquireLock("lock:JobClusterServer:WaitingForAsync", 1000))
|
||||||
{
|
{
|
||||||
|
|||||||
@ -168,8 +168,11 @@ public class Startup : AppStartup
|
|||||||
services.AddViewEngine();
|
services.AddViewEngine();
|
||||||
|
|
||||||
// 即时通讯
|
// 即时通讯
|
||||||
services.AddSignalR(SetNewtonsoftJsonSetting);
|
|
||||||
//services.AddSingleton<IUserIdProvider, UserIdProvider>();
|
//services.AddSingleton<IUserIdProvider, UserIdProvider>();
|
||||||
|
services.AddSignalR(options =>
|
||||||
|
{
|
||||||
|
options.KeepAliveInterval = TimeSpan.FromSeconds(5);
|
||||||
|
}).AddNewtonsoftJsonProtocol(options => SetNewtonsoftJsonSetting(options.PayloadSerializerSettings));
|
||||||
|
|
||||||
// 系统日志
|
// 系统日志
|
||||||
services.AddLoggingSetup();
|
services.AddLoggingSetup();
|
||||||
|
|||||||
@ -199,6 +199,7 @@ if(@column.EffectType == "fk" && (@column.WhetherAddUpdate == "Y" || column.Quer
|
|||||||
@:/// </summary>
|
@:/// </summary>
|
||||||
@:/// <returns></returns>
|
@:/// <returns></returns>
|
||||||
@:[ApiDescriptionSettings(Name = "@(@column.FkEntityName)@(@column.PropertyName)Dropdown"), HttpGet]
|
@:[ApiDescriptionSettings(Name = "@(@column.FkEntityName)@(@column.PropertyName)Dropdown"), HttpGet]
|
||||||
|
@:[DisplayName("获取@(@column.ColumnComment)列表")]
|
||||||
@:public async Task<dynamic> @(@column.FkEntityName)@(@column.PropertyName)Dropdown()
|
@:public async Task<dynamic> @(@column.FkEntityName)@(@column.PropertyName)Dropdown()
|
||||||
@:{
|
@:{
|
||||||
@:return await _rep.Context.Queryable<@(@column.FkEntityName)>()
|
@:return await _rep.Context.Queryable<@(@column.FkEntityName)>()
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@{
|
@{
|
||||||
var pkField = Model.TableField.Where(c => c.ColumnKey == "True").FirstOrDefault();
|
var pkField = Model.TableField.Where(c => c.ColumnKey == "True").FirstOrDefault();
|
||||||
string pkFieldName = null;
|
string pkFieldName = null;
|
||||||
if(pkField != null && !string.IsNullOrEmpty(pkField.PropertyName))
|
if(pkField != null && !string.IsNullOrEmpty(pkField.PropertyName))
|
||||||
@ -192,7 +192,7 @@
|
|||||||
v-model:page-size="tableParams.pageSize"
|
v-model:page-size="tableParams.pageSize"
|
||||||
:total="tableParams.total"
|
:total="tableParams.total"
|
||||||
:page-sizes="[10, 20, 50, 100, 200, 500]"
|
:page-sizes="[10, 20, 50, 100, 200, 500]"
|
||||||
small=""
|
size="small"
|
||||||
background=""
|
background=""
|
||||||
@@size-change="handleSizeChange"
|
@@size-change="handleSizeChange"
|
||||||
@@current-change="handleCurrentChange"
|
@@current-change="handleCurrentChange"
|
||||||
|
|||||||
@ -49,7 +49,7 @@
|
|||||||
"print-js": "^1.6.0",
|
"print-js": "^1.6.0",
|
||||||
"push.js": "^1.0.12",
|
"push.js": "^1.0.12",
|
||||||
"qrcodejs2-fixes": "^0.0.2",
|
"qrcodejs2-fixes": "^0.0.2",
|
||||||
"qs": "^6.12.1",
|
"qs": "^6.12.2",
|
||||||
"relation-graph": "^2.2.1",
|
"relation-graph": "^2.2.1",
|
||||||
"screenfull": "^6.0.2",
|
"screenfull": "^6.0.2",
|
||||||
"sm-crypto-v2": "^1.9.0",
|
"sm-crypto-v2": "^1.9.0",
|
||||||
@ -68,11 +68,11 @@
|
|||||||
"vue-signature-pad": "^3.0.2",
|
"vue-signature-pad": "^3.0.2",
|
||||||
"vue3-tree-org": "^4.2.2",
|
"vue3-tree-org": "^4.2.2",
|
||||||
"vuedraggable": "4.0.3",
|
"vuedraggable": "4.0.3",
|
||||||
"vxe-pc-ui": "^4.0.42",
|
"vxe-pc-ui": "^4.0.44",
|
||||||
"vxe-table": "^4.7.39",
|
"vxe-table": "^4.7.40",
|
||||||
"vxe-table-plugin-element": "^4.0.4",
|
"vxe-table-plugin-element": "^4.0.4",
|
||||||
"vxe-table-plugin-export-xlsx": "^4.0.4",
|
"vxe-table-plugin-export-xlsx": "^4.0.4",
|
||||||
"xe-utils": "^3.5.27",
|
"xe-utils": "^3.5.28",
|
||||||
"xlsx-js-style": "^1.2.0"
|
"xlsx-js-style": "^1.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -81,8 +81,8 @@
|
|||||||
"@types/node": "^20.14.9",
|
"@types/node": "^20.14.9",
|
||||||
"@types/nprogress": "^0.2.3",
|
"@types/nprogress": "^0.2.3",
|
||||||
"@types/sortablejs": "^1.15.8",
|
"@types/sortablejs": "^1.15.8",
|
||||||
"@typescript-eslint/eslint-plugin": "^7.14.1",
|
"@typescript-eslint/eslint-plugin": "^7.15.0",
|
||||||
"@typescript-eslint/parser": "^7.14.1",
|
"@typescript-eslint/parser": "^7.15.0",
|
||||||
"@vitejs/plugin-vue": "^5.0.5",
|
"@vitejs/plugin-vue": "^5.0.5",
|
||||||
"@vitejs/plugin-vue-jsx": "^4.0.0",
|
"@vitejs/plugin-vue-jsx": "^4.0.0",
|
||||||
"@vue/compiler-sfc": "^3.4.31",
|
"@vue/compiler-sfc": "^3.4.31",
|
||||||
@ -94,10 +94,10 @@
|
|||||||
"rollup-plugin-visualizer": "^5.12.0",
|
"rollup-plugin-visualizer": "^5.12.0",
|
||||||
"sass": "^1.77.6",
|
"sass": "^1.77.6",
|
||||||
"terser": "^5.31.1",
|
"terser": "^5.31.1",
|
||||||
"typescript": "^5.5.2",
|
"typescript": "^5.5.3",
|
||||||
"vite": "^5.3.2",
|
"vite": "^5.3.2",
|
||||||
"vite-plugin-cdn-import": "^1.0.1",
|
"vite-plugin-cdn-import": "^1.0.1",
|
||||||
"vite-plugin-compression2": "^1.1.1",
|
"vite-plugin-compression2": "^1.1.2",
|
||||||
"vite-plugin-vue-setup-extend": "^0.4.0",
|
"vite-plugin-vue-setup-extend": "^0.4.0",
|
||||||
"vue-eslint-parser": "^9.4.3"
|
"vue-eslint-parser": "^9.4.3"
|
||||||
},
|
},
|
||||||
|
|||||||
17
Web/src/views/system/cache/index.vue
vendored
17
Web/src/views/system/cache/index.vue
vendored
@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-cache-container">
|
<div class="sys-cache-container">
|
||||||
<NoticeBar text="系统缓存数据管理,请慎重操作!" leftIcon="iconfont icon-tongzhi2" background="var(--el-color-primary-light-9)" color="var(--el-color-primary)" />
|
<NoticeBar text="系统缓存数据管理,请慎重操作!" leftIcon="iconfont icon-tongzhi2" background="var(--el-color-primary-light-9)" color="var(--el-color-primary)" />
|
||||||
<el-row :gutter="8" style="width: 100%">
|
<el-row :gutter="5" class="mt5">
|
||||||
<el-col :span="8" :xs="24">
|
<el-col :span="8" :xs="24">
|
||||||
<el-card shadow="hover" header="缓存列表" v-loading="state.loading" class="mt8">
|
<el-card shadow="hover" header="缓存列表" style="height: calc(100vh - 156px)" v-loading="state.loading" body-style="height:100%;overflow:auto;padding:5px 5px 50px 5px;">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<span>缓存列表</span>
|
<span>缓存列表</span>
|
||||||
@ -21,12 +21,11 @@
|
|||||||
highlight-current
|
highlight-current
|
||||||
check-strictly
|
check-strictly
|
||||||
default-expand-all
|
default-expand-all
|
||||||
accordion
|
|
||||||
/>
|
/>
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="16" :xs="24">
|
<el-col :span="16" :xs="24">
|
||||||
<el-card shadow="hover" header="缓存数据" v-loading="state.loading1" class="mt8">
|
<el-card shadow="hover" header="缓存数据" style="height: calc(100vh - 156px)" v-loading="state.loadingData" body-style="height:calc(100% - 36px);overflow:auto;">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<span>{{ `缓存数据${state.cacheKey ? `【${state.cacheKey}】` : ''}` }}</span>
|
<span>{{ `缓存数据${state.cacheKey ? `【${state.cacheKey}】` : ''}` }}</span>
|
||||||
@ -54,12 +53,13 @@ const treeRef = ref<InstanceType<typeof ElTree>>();
|
|||||||
const currentNode = ref<any>({});
|
const currentNode = ref<any>({});
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
loading: false,
|
loading: false,
|
||||||
loading1: false,
|
loadingData: false,
|
||||||
cacheData: [] as any,
|
cacheData: [] as any,
|
||||||
cacheValue: undefined as any,
|
cacheValue: undefined as any,
|
||||||
cacheKey: undefined,
|
cacheKey: undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 页面初始化
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
handleQuery();
|
handleQuery();
|
||||||
});
|
});
|
||||||
@ -122,7 +122,7 @@ const nodeClick = async (node: any) => {
|
|||||||
if (node.id == 0) return;
|
if (node.id == 0) return;
|
||||||
|
|
||||||
currentNode.value = node;
|
currentNode.value = node;
|
||||||
state.loading1 = true;
|
state.loadingData = true;
|
||||||
var res = await getAPI(SysCacheApi).apiSysCacheValueKeyGet(node.id);
|
var res = await getAPI(SysCacheApi).apiSysCacheValueKeyGet(node.id);
|
||||||
// state.cacheValue = JSON.parse(res.data.result);
|
// state.cacheValue = JSON.parse(res.data.result);
|
||||||
var result = res.data.result;
|
var result = res.data.result;
|
||||||
@ -142,7 +142,7 @@ const nodeClick = async (node: any) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
state.cacheKey = node.id;
|
state.cacheKey = node.id;
|
||||||
state.loading1 = false;
|
state.loadingData = false;
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -152,4 +152,7 @@ const nodeClick = async (node: any) => {
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
:deep(.el-card__header) {
|
||||||
|
padding: 6px !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
||||||
<el-row :gutter="35">
|
<el-row :gutter="10">
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||||
<el-form-item label="库定位器" prop="configId">
|
<el-form-item label="库定位器" prop="configId">
|
||||||
<el-select v-model="state.ruleForm.configId" placeholder="库名" filterable @change="dbChanged()" class="w100">
|
<el-select v-model="state.ruleForm.configId" placeholder="库名" filterable @change="dbChanged()" class="w100">
|
||||||
@ -258,6 +258,11 @@ const submit = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isOrNotSelect = () => [
|
||||||
|
{ label: '是', value: 1 },
|
||||||
|
{ label: '否', value: 0 },
|
||||||
|
];
|
||||||
|
|
||||||
// 导出对象
|
// 导出对象
|
||||||
defineExpose({ openDialog });
|
defineExpose({ openDialog });
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-codeGenFk-container">
|
<div class="sys-codeGenFk-container">
|
||||||
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="700px" destroy-on-close>
|
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="700px">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div style="color: #fff">
|
<div style="color: #fff">
|
||||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
||||||
@ -8,7 +8,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
||||||
<el-row :gutter="35">
|
<el-row :gutter="10">
|
||||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||||
<el-form-item label="库定位器" prop="configId">
|
<el-form-item label="库定位器" prop="configId">
|
||||||
<el-select clearable v-model="state.ruleForm.configId" placeholder="库名" filterable @change="DbChanged()" class="w100">
|
<el-select clearable v-model="state.ruleForm.configId" placeholder="库名" filterable @change="DbChanged()" class="w100">
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-codeGenConfig-container">
|
<div class="sys-codeGenConfig-container">
|
||||||
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="1500px">
|
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="80vw">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div style="color: #fff">
|
<div style="color: #fff">
|
||||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
||||||
@ -8,9 +8,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-table :data="state.tableData" style="width: 100%" v-loading="state.loading" border>
|
<el-table :data="state.tableData" style="width: 100%" v-loading="state.loading" border>
|
||||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
<el-table-column type="index" label="序号" width="50" align="center" />
|
||||||
<el-table-column prop="propertyName" label="实体属性" width="180" show-overflow-tooltip />
|
<el-table-column prop="columnName" label="字段" width="160" show-overflow-tooltip />
|
||||||
<el-table-column prop="columnComment" label="描述" width="180" show-overflow-tooltip>
|
<el-table-column prop="columnComment" label="描述" width="160" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-input v-model="scope.row.columnComment" autocomplete="off" />
|
<el-input v-model="scope.row.columnComment" autocomplete="off" />
|
||||||
</template>
|
</template>
|
||||||
@ -31,17 +31,17 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column prop="whetherTable" label="列表显示" width="85" align="center" show-overflow-tooltip>
|
<el-table-column prop="whetherTable" label="列表显示" width="70" align="center" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-checkbox v-model="scope.row.whetherTable" />
|
<el-checkbox v-model="scope.row.whetherTable" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="whetherAddUpdate" label="增改" width="80" align="center" show-overflow-tooltip>
|
<el-table-column prop="whetherAddUpdate" label="增改" width="70" align="center" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-checkbox v-model="scope.row.whetherAddUpdate" :disabled="judgeColumns(scope.row)" />
|
<el-checkbox v-model="scope.row.whetherAddUpdate" :disabled="judgeColumns(scope.row)" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="whetherRequired" label="必填" width="80" align="center" show-overflow-tooltip>
|
<el-table-column prop="whetherRequired" label="必填" width="70" align="center" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-checkbox v-model="scope.row.whetherRequired" :disabled="judgeColumns(scope.row)" />
|
<el-checkbox v-model="scope.row.whetherRequired" :disabled="judgeColumns(scope.row)" />
|
||||||
</template>
|
</template>
|
||||||
@ -85,6 +85,7 @@
|
|||||||
<script lang="ts" setup name="sysCodeGenConfig">
|
<script lang="ts" setup name="sysCodeGenConfig">
|
||||||
import { onMounted, onUnmounted, reactive, ref } from 'vue';
|
import { onMounted, onUnmounted, reactive, ref } from 'vue';
|
||||||
import mittBus from '/@/utils/mitt';
|
import mittBus from '/@/utils/mitt';
|
||||||
|
|
||||||
import fkDialog from '/@/views/system/codeGen/component/fkDialog.vue';
|
import fkDialog from '/@/views/system/codeGen/component/fkDialog.vue';
|
||||||
import treeDialog from '/@/views/system/codeGen/component/treeDialog.vue';
|
import treeDialog from '/@/views/system/codeGen/component/treeDialog.vue';
|
||||||
|
|
||||||
@ -276,18 +277,10 @@ const convertDbType = (dbType: number) => {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
const isOrNotSelect = () => {
|
const isOrNotSelect = () => [
|
||||||
return [
|
{ label: '是', value: 1 },
|
||||||
{
|
{ label: '否', value: 0 },
|
||||||
label: '是',
|
];
|
||||||
value: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '否',
|
|
||||||
value: 0,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
// 导出对象
|
// 导出对象
|
||||||
defineExpose({ openDialog });
|
defineExpose({ openDialog });
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-codeGenPreview-container">
|
<div class="sys-codeGenPreview-container">
|
||||||
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="70%">
|
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="80vw">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div style="color: #fff">
|
<div style="color: #fff">
|
||||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
||||||
@ -17,7 +17,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-segmented>
|
</el-segmented>
|
||||||
</div>
|
</div>
|
||||||
<div ref="monacoEditorRef" style="width: 100%; height: 700px;"></div>
|
<div ref="monacoEditorRef" style="width: 100%; height: 700px; margin-top: 6px"></div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button icon="ele-Close" @click="cancel">关 闭</el-button>
|
<el-button icon="ele-Close" @click="cancel">关 闭</el-button>
|
||||||
@ -123,11 +123,14 @@ defineExpose({ openDialog });
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
.cs-style .el-segmented {
|
.cs-style .el-segmented {
|
||||||
--el-segmented-item-selected-bg-color: #5c2d91;
|
--el-segmented-item-selected-bg-color: #5c2d91;
|
||||||
|
--el-border-radius-base: 6px;
|
||||||
}
|
}
|
||||||
.vue-style .el-segmented {
|
.vue-style .el-segmented {
|
||||||
--el-segmented-item-selected-bg-color: #42b883;
|
--el-segmented-item-selected-bg-color: #42b883;
|
||||||
|
--el-border-radius-base: 6px;
|
||||||
}
|
}
|
||||||
.js-style .el-segmented {
|
.js-style .el-segmented {
|
||||||
--el-segmented-item-selected-bg-color: #e44d26;
|
--el-segmented-item-selected-bg-color: #e44d26;
|
||||||
|
--el-border-radius-base: 6px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
||||||
<el-row :gutter="35">
|
<el-row :gutter="10">
|
||||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||||
<el-form-item label="库定位器" prop="configId">
|
<el-form-item label="库定位器" prop="configId">
|
||||||
<el-select clearable v-model="state.ruleForm.configId" placeholder="库名" filterable @change="DbChanged()" class="w100">
|
<el-select clearable v-model="state.ruleForm.configId" placeholder="库名" filterable @change="DbChanged()" class="w100">
|
||||||
|
|||||||
@ -1,94 +1,108 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-codeGen-container">
|
<div class="sys-codeGen-container" v-loading="options.loading">
|
||||||
<el-card shadow="hover" :body-style="{ paddingBottom: '0' }">
|
<el-card shadow="hover" :body-style="{ padding: '5px 5px 0 5px', display: 'flex', width: '100%', height: '100%', alignItems: 'start' }">
|
||||||
<el-form :model="state.queryParams" ref="queryForm" :inline="true">
|
<el-form :model="state.queryParams" ref="queryForm" :show-message="false" :inlineMessage="true" :label-width="'60px'" style="flex: 1 1 0%">
|
||||||
<el-form-item label="业务名">
|
<el-row :gutter="10">
|
||||||
<el-input placeholder="业务名" clearable @keyup.enter="handleQuery" v-model="state.queryParams.busName" />
|
<el-col class="mb5" :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
|
||||||
</el-form-item>
|
<el-form-item label="业务名" prop="busName">
|
||||||
<el-form-item label="数据库表名">
|
<el-input placeholder="业务名" clearable @keyup.enter="handleQuery" v-model="state.queryParams.busName" @keyup.enter.native="handleQuery(true)" />
|
||||||
<el-input placeholder="数据库表名" clearable @keyup.enter="handleQuery" v-model="state.queryParams.tableName" />
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
<el-form-item>
|
<el-col class="mb5" :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
|
||||||
<el-button-group>
|
<el-form-item label="数据库表名" prop="tableName">
|
||||||
<el-button type="primary" icon="ele-Search" @click="handleQuery" v-auth="'sysMenu:list'"> 查询 </el-button>
|
<el-input placeholder="数据库表名" clearable @keyup.enter="handleQuery" v-model="state.queryParams.tableName" @keyup.enter.native="handleQuery(true)" />
|
||||||
<el-button icon="ele-Refresh" @click="resetQuery"> 重置 </el-button>
|
</el-form-item>
|
||||||
</el-button-group>
|
</el-col>
|
||||||
</el-form-item>
|
</el-row>
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="ele-Plus" @click="openAddDialog"> 增加 </el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
</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)" :loading="options.loading"> 查询 </el-button>
|
||||||
|
<el-button icon="ele-Refresh" @click="resetQuery" :loading="options.loading"> 重置 </el-button>
|
||||||
|
</el-button-group>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
|
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
|
||||||
<el-table :data="state.tableData" style="width: 100%" v-loading="state.loading" border>
|
<vxe-grid ref="xGrid" class="xGrid-style" v-bind="options" @sort-change="sortChange">
|
||||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
<template #toolbar_buttons>
|
||||||
<el-table-column prop="configId" label="库定位器" align="center" show-overflow-tooltip />
|
<el-button type="primary" icon="ele-Plus" @click="handleAdd"> 新增 </el-button>
|
||||||
<el-table-column prop="tableName" label="表名称" align="center" show-overflow-tooltip />
|
</template>
|
||||||
<el-table-column prop="busName" label="业务名" align="center" show-overflow-tooltip />
|
<template #toolbar_tools> </template>
|
||||||
<el-table-column prop="nameSpace" label="命名空间" align="center" show-overflow-tooltip />
|
<template #empty>
|
||||||
<el-table-column prop="authorName" label="作者姓名" align="center" show-overflow-tooltip />
|
<el-empty :image-size="200" />
|
||||||
<el-table-column prop="generateType" label="生成方式" align="center" show-overflow-tooltip>
|
</template>
|
||||||
<template #default="scope">
|
<template #row_generateType="{ row }">
|
||||||
<el-tag v-if="scope.row.generateType == 100"> 下载压缩包 </el-tag>
|
<el-tag v-if="row.generateType == 100"> 下载压缩包 </el-tag>
|
||||||
<el-tag v-else-if="scope.row.generateType == 111"> 下载压缩包(前端) </el-tag>
|
<el-tag v-else-if="row.generateType == 111"> 下载压缩包(前端) </el-tag>
|
||||||
<el-tag v-else-if="scope.row.generateType == 121"> 下载压缩包(后端) </el-tag>
|
<el-tag v-else-if="row.generateType == 121"> 下载压缩包(后端) </el-tag>
|
||||||
<el-tag v-else-if="scope.row.generateType == 211"> 生成到本项目(前端) </el-tag>
|
<el-tag v-else-if="row.generateType == 211"> 生成到本项目(前端) </el-tag>
|
||||||
<el-tag v-else-if="scope.row.generateType == 221"> 生成到本项目(后端) </el-tag>
|
<el-tag v-else-if="row.generateType == 221"> 生成到本项目(后端) </el-tag>
|
||||||
<el-tag type="danger" v-else> 生成到本项目 </el-tag>
|
<el-tag type="danger" v-else> 生成到本项目 </el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
<template #row_buttons="{ row }">
|
||||||
<el-table-column label="操作" width="350" fixed="right" align="center" show-overflow-tooltip>
|
<el-tooltip content="编辑" placement="top">
|
||||||
<template #default="scope">
|
<el-button icon="ele-Edit" text type="primary" @click="handleEdit(row)"> </el-button>
|
||||||
<el-button icon="ele-Position" size="small" text type="primary" @click="handleGenerate(scope.row)">开始生成</el-button>
|
</el-tooltip>
|
||||||
<el-button icon="ele-View" size="small" text type="primary" @click="handlePreview(scope.row)">预览</el-button>
|
<el-tooltip content="删除" placement="top">
|
||||||
<el-button icon="ele-Setting" size="small" text type="primary" @click="openConfigDialog(scope.row)">配置</el-button>
|
<el-button icon="ele-Delete" text type="danger" @click="handleDelete(row)"> </el-button>
|
||||||
<el-button icon="ele-Edit" size="small" text type="primary" @click="openEditDialog(scope.row)">编辑</el-button>
|
</el-tooltip>
|
||||||
<el-button icon="ele-Delete" size="small" text type="danger" @click="deleConfig(scope.row)">删除</el-button>
|
<el-tooltip content="配置" placement="top">
|
||||||
</template>
|
<el-button icon="ele-Setting" text type="danger" @click="handleConfig(row)">配置</el-button>
|
||||||
</el-table-column>
|
</el-tooltip>
|
||||||
</el-table>
|
<el-tooltip content="预览" placement="top">
|
||||||
<el-pagination
|
<el-button icon="ele-Camera" text type="primary" @click="handlePreview(row)">预览</el-button>
|
||||||
v-model:currentPage="state.tableParams.page"
|
</el-tooltip>
|
||||||
v-model:page-size="state.tableParams.pageSize"
|
<el-tooltip content="开始生成" placement="top">
|
||||||
:total="state.tableParams.total"
|
<el-button icon="ele-Cpu" text type="primary" @click="handleGenerate(row)">生成</el-button>
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
</el-tooltip>
|
||||||
small
|
</template>
|
||||||
background
|
<template #pager>
|
||||||
@size-change="handleSizeChange"
|
<vxe-pager
|
||||||
@current-change="handleCurrentChange"
|
:loading="options.loading"
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
v-model:current-page="state.tableParams.page"
|
||||||
/>
|
v-model:page-size="state.tableParams.pageSize"
|
||||||
|
:total="state.tableParams.total"
|
||||||
|
@page-change="pageChange"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</vxe-grid>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<EditCodeGenDialog :title="state.editMenuTitle" ref="EditCodeGenRef" @handleQuery="handleQuery" :application-namespaces="state.applicationNamespaces" />
|
<EditCodeGenDialog :title="state.title" ref="EditCodeGenRef" @handleQuery="handleQuery" :application-namespaces="state.applicationNamespaces" />
|
||||||
<CodeConfigDialog ref="CodeConfigRef" @handleQuery="handleQuery" />
|
<CodeConfigDialog ref="CodeConfigRef" @handleQuery="handleQuery" />
|
||||||
<PreviewDialog :title="state.editMenuTitle" ref="PreviewRef" />
|
<PreviewDialog :title="state.title" ref="PreviewRef" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup name="sysCodeGen">
|
<script lang="ts" setup name="sysCodeGen">
|
||||||
import { onMounted, reactive, ref, defineAsyncComponent } from 'vue';
|
import { onMounted, reactive, ref, defineAsyncComponent } from 'vue';
|
||||||
import { ElMessageBox, ElMessage } from 'element-plus';
|
import { ElMessageBox, ElMessage } from 'element-plus';
|
||||||
|
import { auth } from '/@/utils/authFunction';
|
||||||
|
import { VxeGridInstance, VxePagerEvents, VxePagerDefines } from 'vxe-table';
|
||||||
|
import { useVxeTable } from '/@/hooks/vxeTableOptionsHook';
|
||||||
|
import { downloadByUrl } from '/@/utils/download';
|
||||||
|
|
||||||
import EditCodeGenDialog from './component/editCodeGenDialog.vue';
|
import EditCodeGenDialog from './component/editCodeGenDialog.vue';
|
||||||
import CodeConfigDialog from './component/genConfigDialog.vue';
|
import CodeConfigDialog from './component/genConfigDialog.vue';
|
||||||
import { downloadByUrl } from '/@/utils/download';
|
|
||||||
|
|
||||||
import { getAPI } from '/@/utils/axios-utils';
|
import { getAPI } from '/@/utils/axios-utils';
|
||||||
import { SysCodeGenApi } from '/@/api-services/api';
|
import { SysCodeGenApi } from '/@/api-services/api';
|
||||||
import { SysCodeGen } from '/@/api-services/models';
|
import { SysCodeGen } from '/@/api-services/models';
|
||||||
|
|
||||||
const PreviewDialog = defineAsyncComponent(() => import('./component/previewDialog.vue'));
|
const PreviewDialog = defineAsyncComponent(() => import('./component/previewDialog.vue'));
|
||||||
|
const xGrid = ref<VxeGridInstance>();
|
||||||
const EditCodeGenRef = ref<InstanceType<typeof EditCodeGenDialog>>();
|
const EditCodeGenRef = ref<InstanceType<typeof EditCodeGenDialog>>();
|
||||||
const CodeConfigRef = ref<InstanceType<typeof CodeConfigDialog>>();
|
const CodeConfigRef = ref<InstanceType<typeof CodeConfigDialog>>();
|
||||||
const PreviewRef = ref<InstanceType<typeof PreviewDialog>>();
|
const PreviewRef = ref<InstanceType<typeof PreviewDialog>>();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
loading: false,
|
|
||||||
loading1: false,
|
|
||||||
dbData: [] as any,
|
dbData: [] as any,
|
||||||
configId: '',
|
configId: '',
|
||||||
tableData: [] as Array<SysCodeGen>,
|
|
||||||
tableName: '',
|
tableName: '',
|
||||||
queryParams: {
|
queryParams: {
|
||||||
name: undefined,
|
name: undefined,
|
||||||
@ -98,56 +112,88 @@ const state = reactive({
|
|||||||
},
|
},
|
||||||
tableParams: {
|
tableParams: {
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 10,
|
pageSize: 50,
|
||||||
|
field: 'id', // 默认的排序字段
|
||||||
|
order: 'aes', // 排序方向
|
||||||
|
descStr: 'desc', // 降序排序的关键字符
|
||||||
total: 0 as any,
|
total: 0 as any,
|
||||||
},
|
},
|
||||||
editMenuTitle: '',
|
visible: false,
|
||||||
|
title: '',
|
||||||
applicationNamespaces: [] as Array<string>,
|
applicationNamespaces: [] as Array<string>,
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(async () => {
|
// 表格参数配置
|
||||||
handleQuery();
|
const options = useVxeTable<SysCodeGen>({
|
||||||
|
id: 'sysCodeGen',
|
||||||
|
name: '代码生成',
|
||||||
|
columns: [
|
||||||
|
// { type: 'checkbox', width: 40, fixed: 'left' },
|
||||||
|
{ type: 'seq', title: '序号', width: 60, fixed: 'left' },
|
||||||
|
{ field: 'configId', title: '库定位器', minWidth: 200, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'tableName', title: '表名称', minWidth: 200, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'busName', title: '业务名', minWidth: 200, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'nameSpace', title: '命名空间', minWidth: 200, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'authorName', title: '作者姓名', minWidth: 200, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'generateType', title: '生成方式', minWidth: 140, showOverflow: 'tooltip', slots: { default: 'row_generateType' } },
|
||||||
|
{ title: '操作', fixed: 'right', width: 280, showOverflow: true, slots: { default: 'row_buttons' } },
|
||||||
|
],
|
||||||
|
enableExport: auth('sysCodeGen:export'),
|
||||||
|
searchCallback: () => handleQuery(),
|
||||||
|
queryAllCallback: () => fetchData({ pageSize: 99999 }),
|
||||||
|
});
|
||||||
|
|
||||||
|
// 页面初始化
|
||||||
|
onMounted(async () => {
|
||||||
|
await handleQuery();
|
||||||
let res = await getAPI(SysCodeGenApi).apiSysCodeGenApplicationNamespacesGet();
|
let res = await getAPI(SysCodeGenApi).apiSysCodeGenApplicationNamespacesGet();
|
||||||
state.applicationNamespaces = res.data.result as Array<string>;
|
state.applicationNamespaces = res.data.result as Array<string>;
|
||||||
});
|
});
|
||||||
|
|
||||||
const openConfigDialog = (row: any) => {
|
// 查询操作
|
||||||
CodeConfigRef.value?.openDialog(row);
|
const handleQuery = async (reset = false) => {
|
||||||
|
options.loading = true;
|
||||||
|
if (reset) state.tableParams.page = 1;
|
||||||
|
var res = await fetchData(null);
|
||||||
|
xGrid.value?.loadData(res.data.result?.items ?? []);
|
||||||
|
state.tableParams.total = res.data.result?.total;
|
||||||
|
options.loading = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 表查询操作
|
// 获取数据
|
||||||
const handleQuery = async () => {
|
const fetchData = async (tableParams: any) => {
|
||||||
state.loading = true;
|
let params = Object.assign(state.queryParams, state.tableParams, tableParams);
|
||||||
let params = Object.assign(state.queryParams, state.tableParams);
|
return getAPI(SysCodeGenApi).apiSysCodeGenPagePost(params);
|
||||||
let res = await getAPI(SysCodeGenApi).apiSysCodeGenPagePost(params);
|
|
||||||
state.tableData = res.data.result?.items ?? [];
|
|
||||||
state.tableParams.total = res.data.result?.total;
|
|
||||||
state.loading = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 重置操作
|
// 重置操作
|
||||||
const resetQuery = () => {
|
const resetQuery = () => {
|
||||||
state.queryParams.busName = undefined;
|
state.queryParams.busName = undefined;
|
||||||
state.queryParams.tableName = undefined;
|
state.queryParams.tableName = undefined;
|
||||||
|
handleQuery(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleConfig = (row: any) => {
|
||||||
|
CodeConfigRef.value?.openDialog(row);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 改变页码序号或页面容量
|
||||||
|
const pageChange: VxePagerEvents.PageChange = ({ currentPage, pageSize }: VxePagerDefines.PageChangeEventParams) => {
|
||||||
|
state.tableParams.page = currentPage;
|
||||||
|
state.tableParams.pageSize = pageSize;
|
||||||
handleQuery();
|
handleQuery();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 改变页面容量
|
// 列排序
|
||||||
const handleSizeChange = (val: number) => {
|
const sortChange = (options: any) => {
|
||||||
state.tableParams.pageSize = val;
|
state.tableParams.field = options.field;
|
||||||
|
state.tableParams.order = options.order;
|
||||||
handleQuery();
|
handleQuery();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 改变页码序号
|
// 打开新增页面
|
||||||
const handleCurrentChange = (val: number) => {
|
const handleAdd = () => {
|
||||||
state.tableParams.page = val;
|
state.title = '增加';
|
||||||
handleQuery();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 打开表增加页面
|
|
||||||
const openAddDialog = () => {
|
|
||||||
state.editMenuTitle = '增加';
|
|
||||||
EditCodeGenRef.value?.openDialog({
|
EditCodeGenRef.value?.openDialog({
|
||||||
authorName: 'Admin.NET',
|
authorName: 'Admin.NET',
|
||||||
generateType: '200',
|
generateType: '200',
|
||||||
@ -155,18 +201,18 @@ const openAddDialog = () => {
|
|||||||
menuIcon: 'ele-Menu',
|
menuIcon: 'ele-Menu',
|
||||||
pagePath: 'main',
|
pagePath: 'main',
|
||||||
nameSpace: state.applicationNamespaces[0],
|
nameSpace: state.applicationNamespaces[0],
|
||||||
generateMenu: true,
|
generateMenu: false,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开表编辑页面
|
// 打开编辑页面
|
||||||
const openEditDialog = (row: any) => {
|
const handleEdit = (row: any) => {
|
||||||
state.editMenuTitle = '编辑';
|
state.title = '编辑';
|
||||||
EditCodeGenRef.value?.openDialog(row);
|
EditCodeGenRef.value?.openDialog(row);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 删除表
|
// 删除
|
||||||
const deleConfig = (row: any) => {
|
const handleDelete = (row: any) => {
|
||||||
ElMessageBox.confirm(`确定删除吗?`, '提示', {
|
ElMessageBox.confirm(`确定删除吗?`, '提示', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
@ -198,7 +244,7 @@ const handleGenerate = (row: any) => {
|
|||||||
|
|
||||||
// 预览代码
|
// 预览代码
|
||||||
const handlePreview = (row: any) => {
|
const handlePreview = (row: any) => {
|
||||||
state.editMenuTitle = '预览代码';
|
state.title = '预览代码';
|
||||||
PreviewRef.value?.openDialog(row);
|
PreviewRef.value?.openDialog(row);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-config-container">
|
<div class="sys-config-container">
|
||||||
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="700px">
|
<el-dialog v-model="state.isShowDialog" draggable overflow destroy-on-close width="700px">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div style="color: #fff">
|
<div style="color: #fff">
|
||||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
||||||
@ -8,7 +8,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
||||||
<el-row :gutter="35">
|
<el-row :gutter="10">
|
||||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||||
<el-form-item label="配置名称" prop="name" :rules="[{ required: true, message: '配置名称不能为空', trigger: 'blur' }]">
|
<el-form-item label="配置名称" prop="name" :rules="[{ required: true, message: '配置名称不能为空', trigger: 'blur' }]">
|
||||||
<el-input v-model="state.ruleForm.name" placeholder="配置名称" clearable />
|
<el-input v-model="state.ruleForm.name" placeholder="配置名称" clearable />
|
||||||
|
|||||||
@ -1,170 +1,208 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-config-container">
|
<div class="sys-config-container" v-loading="options.loading">
|
||||||
<el-card shadow="hover" :body-style="{ paddingBottom: '0' }">
|
<el-card shadow="hover" :body-style="{ padding: '5px 5px 0 5px', display: 'flex', width: '100%', height: '100%', alignItems: 'start' }">
|
||||||
<TableSearch :search="tb.tableData.search" @search="onSearch" />
|
<el-form :model="state.queryParams" ref="queryForm" :show-message="false" :inlineMessage="true" :label-width="'60px'" style="flex: 1 1 0%">
|
||||||
|
<el-row :gutter="10">
|
||||||
|
<el-col class="mb5" :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
|
||||||
|
<el-form-item label="配置名称" prop="name">
|
||||||
|
<el-input v-model="state.queryParams.name" placeholder="配置名称" clearable @keyup.enter.native="handleQuery(true)" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col class="mb5" :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
|
||||||
|
<el-form-item label="配置编码" prop="code">
|
||||||
|
<el-input v-model="state.queryParams.code" placeholder="配置编码" clearable @keyup.enter.native="handleQuery(true)" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col class="mb5" :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
|
||||||
|
<el-form-item label="分组编码" prop="groupCode">
|
||||||
|
<el-select v-model="state.queryParams.groupCode" clearable placeholder="分组编码" @clear="state.queryParams.groupCode = undefined">
|
||||||
|
<el-option v-for="item in state.groupList" :key="item" :label="item" :value="item" />
|
||||||
|
</el-select>
|
||||||
|
</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="'sysConfig:page'" :loading="options.loading"> 查询 </el-button>
|
||||||
|
<el-button icon="ele-Refresh" @click="resetQuery" :loading="options.loading"> 重置 </el-button>
|
||||||
|
</el-button-group>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
|
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
|
||||||
<Table ref="tableRef" v-bind="tb.tableData" :getData="getData" :exportChangeData="exportChangeData" @sortHeader="onSortHeader" @selectionChange="tableSelection" border>
|
<vxe-grid ref="xGrid" class="xGrid-style" v-bind="options" @sort-change="sortChange" @checkbox-all="handleSelectChange" @checkbox-change="handleSelectChange">
|
||||||
<template #command>
|
<template #toolbar_buttons>
|
||||||
<el-button type="primary" icon="ele-Plus" @click="openAddConfig" v-auth="'sysConfig:add'"> 新增 </el-button>
|
<el-button type="primary" icon="ele-Plus" @click="handleAdd" v-auth="'sysConfig:add'"> 新增 </el-button>
|
||||||
|
<!-- <el-button v-if="state.selectList.length > 0" type="danger" icon="ele-Delete" @click="handleBacthDelete" > 批量删除 </el-button> -->
|
||||||
<el-button v-if="state.selectlist.length > 0" type="danger" icon="ele-Delete" @click="bacthDelete" v-auth="'sysConfig:batchDelete'"> 批量删除 </el-button>
|
|
||||||
</template>
|
</template>
|
||||||
<template #sysFlag="scope">
|
<template #toolbar_tools> </template>
|
||||||
<el-tag v-if="scope.row.sysFlag === 1"> 是 </el-tag>
|
<template #empty>
|
||||||
<el-tag type="danger" v-else> 否 </el-tag>
|
<el-empty :image-size="200" />
|
||||||
</template>
|
</template>
|
||||||
<template #remark="scope">
|
<template #row_sysFlag="{ row }">
|
||||||
<ModifyRecord :data="scope.row" />
|
<el-tag v-if="row.sysFlag === 1" type="success">是</el-tag>
|
||||||
|
<el-tag v-else type="danger">否</el-tag>
|
||||||
</template>
|
</template>
|
||||||
<template #action="scope">
|
<template #row_record="{ row }">
|
||||||
<el-button icon="ele-Edit" size="small" text type="primary" @click="openEditConfig(scope.row)" v-auth="'sysConfig:update'"> 编辑 </el-button>
|
<ModifyRecord :data="row" />
|
||||||
<el-button icon="ele-Delete" size="small" text type="danger" @click="delConfig(scope.row)" v-auth="'sysConfig:delete'" :disabled="scope.row.sysFlag === 1"> 删除 </el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</Table>
|
<template #row_buttons="{ row }">
|
||||||
|
<el-tooltip content="编辑" placement="top">
|
||||||
|
<el-button icon="ele-Edit" text type="primary" v-auth="'sysConfig:update'" @click="handleEdit(row)"> </el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip content="删除" placement="top">
|
||||||
|
<el-button icon="ele-Delete" text type="danger" v-auth="'sysConfig:delete'" :disabled="row.sysFlag === 1" @click="handleDelete(row)"> </el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
<template #pager>
|
||||||
|
<vxe-pager
|
||||||
|
:loading="options.loading"
|
||||||
|
v-model:current-page="state.tableParams.page"
|
||||||
|
v-model:page-size="state.tableParams.pageSize"
|
||||||
|
:total="state.tableParams.total"
|
||||||
|
@page-change="pageChange"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</vxe-grid>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<EditConfig ref="editConfigRef" :title="state.editConfigTitle" :groupList="state.groupList" @updateData="updateData" />
|
<EditConfig ref="editConfigRef" :title="state.title" :groupList="state.groupList" @updateData="updateData" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup name="sysConfig">
|
<script lang="ts" setup name="sysConfig">
|
||||||
import { onMounted, onUnmounted, reactive, ref, defineAsyncComponent, nextTick } from 'vue';
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
import { ElMessageBox, ElMessage } from 'element-plus';
|
import { ElMessageBox, ElMessage } from 'element-plus';
|
||||||
|
import { auth } from '/@/utils/authFunction';
|
||||||
|
import { VxeGridInstance, VxePagerEvents, VxePagerDefines } from 'vxe-table';
|
||||||
|
import { useVxeTable } from '/@/hooks/vxeTableOptionsHook';
|
||||||
|
|
||||||
import EditConfig from '/@/views/system/config/component/editConfig.vue';
|
import EditConfig from '/@/views/system/config/component/editConfig.vue';
|
||||||
import ModifyRecord from '/@/components/table/modifyRecord.vue';
|
import ModifyRecord from '/@/components/table/modifyRecord.vue';
|
||||||
|
|
||||||
import { getAPI } from '/@/utils/axios-utils';
|
import { getAPI } from '/@/utils/axios-utils';
|
||||||
import { SysConfigApi } from '/@/api-services/api';
|
import { SysConfigApi } from '/@/api-services/api';
|
||||||
import { auth } from '/@/utils/authFunction';
|
import { SysConfig } from '/@/api-services/models';
|
||||||
|
|
||||||
// 引入组件
|
const xGrid = ref<VxeGridInstance>();
|
||||||
const Table = defineAsyncComponent(() => import('/@/components/table/index.vue'));
|
|
||||||
const TableSearch = defineAsyncComponent(() => import('/@/components/table/search.vue'));
|
|
||||||
const editConfigRef = ref<InstanceType<typeof EditConfig>>();
|
const editConfigRef = ref<InstanceType<typeof EditConfig>>();
|
||||||
const tableRef = ref<RefType>();
|
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
editConfigTitle: '',
|
queryParams: {
|
||||||
selectlist: [] as EmptyObjectType[],
|
name: undefined,
|
||||||
groupList: [] as Array<String>,
|
code: undefined,
|
||||||
});
|
groupCode: undefined,
|
||||||
|
|
||||||
const tb = reactive<TableDemoState>({
|
|
||||||
tableData: {
|
|
||||||
// 表头内容(必传,注意格式)
|
|
||||||
columns: [
|
|
||||||
{ prop: 'name', minWidth: 150, label: '配置名称', headerAlign: 'center', sortable: 'custom', isCheck: true, hideCheck: true },
|
|
||||||
{ prop: 'code', minWidth: 150, label: '配置编码', headerAlign: 'center', toolTip: true, sortable: 'custom', isCheck: true },
|
|
||||||
{ prop: 'value', minWidth: 150, label: '属性值', headerAlign: 'center', isCheck: true },
|
|
||||||
{ prop: 'sysFlag', width: 100, label: '内置参数', align: 'center', isCheck: true },
|
|
||||||
{ prop: 'groupCode', width: 120, label: '分组编码', align: 'center', sortable: 'custom', isCheck: true },
|
|
||||||
{ prop: 'orderNo', width: 80, label: '排序', align: 'center', sortable: 'custom', isCheck: true },
|
|
||||||
{ prop: 'remark', width: 100, label: '修改记录', align: 'center', headerAlign: 'center', showOverflowTooltip: true, isCheck: true },
|
|
||||||
{ prop: 'action', width: 140, label: '操作', type: 'action', align: 'center', isCheck: true, fixed: 'right', hideCheck: true },
|
|
||||||
],
|
|
||||||
// 配置项(必传)
|
|
||||||
config: {
|
|
||||||
isStripe: true, // 是否显示表格斑马纹
|
|
||||||
isBorder: false, // 是否显示表格边框
|
|
||||||
isSerialNo: true, // 是否显示表格序号
|
|
||||||
isSelection: true, // 是否勾选表格多选
|
|
||||||
showSelection: auth('sysConfig:batchDelete'), //是否显示表格多选
|
|
||||||
pageSize: 20, // 每页条数
|
|
||||||
hideExport: false, //是否隐藏导出按钮
|
|
||||||
exportFileName: '系统参数', //导出报表的文件名,不填写取应用名称
|
|
||||||
},
|
|
||||||
// 搜索表单,动态生成(传空数组时,将不显示搜索,type有3种类型:input,date,select)
|
|
||||||
search: [
|
|
||||||
{ label: '配置名称', prop: 'name', placeholder: '搜索配置名称', required: false, type: 'input' },
|
|
||||||
{ label: '配置编码', prop: 'code', placeholder: '搜索配置编码', required: false, type: 'input' },
|
|
||||||
// { label: '创建时间', prop: 'time', placeholder: '请选择', required: false, type: 'date' },
|
|
||||||
],
|
|
||||||
param: {},
|
|
||||||
defaultSort: {
|
|
||||||
prop: 'orderNo',
|
|
||||||
order: 'ascending',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
tableParams: {
|
||||||
|
page: 1,
|
||||||
|
pageSize: 50,
|
||||||
|
field: 'orderNo', // 默认的排序字段
|
||||||
|
order: 'aes', // 排序方向
|
||||||
|
descStr: 'desc', // 降序排序的关键字符
|
||||||
|
total: 0 as any,
|
||||||
|
},
|
||||||
|
visible: false,
|
||||||
|
title: '',
|
||||||
|
groupList: [] as string[],
|
||||||
|
selectList: [] as SysConfig[],
|
||||||
|
});
|
||||||
|
//表格参数配置
|
||||||
|
const options = useVxeTable<SysConfig>({
|
||||||
|
id: 'sysConfig',
|
||||||
|
name: '参数配置',
|
||||||
|
columns: [
|
||||||
|
// { type: 'checkbox', width: 40, fixed: 'left' },
|
||||||
|
{ type: 'seq', title: '序号', width: 60, fixed: 'left' },
|
||||||
|
{ field: 'name', title: '配置名称', minWidth: 200, showOverflow: 'tooltip', sortable: true },
|
||||||
|
{ field: 'code', title: '配置编码', minWidth: 200, showOverflow: 'tooltip', sortable: true },
|
||||||
|
{ field: 'value', title: '属性值', minWidth: 150, showOverflow: 'tooltip', sortable: true },
|
||||||
|
{ field: 'sysFlag', title: '内置参数', width: 80, showOverflow: 'tooltip', sortable: true, slots: { default: 'row_sysFlag' } },
|
||||||
|
{ field: 'groupCode', title: '分组编码', minWidth: 120, showOverflow: 'tooltip', sortable: true },
|
||||||
|
{ field: 'orderNo', title: '排序', width: 80, showOverflow: 'tooltip', sortable: true },
|
||||||
|
{ field: 'remark', title: '备注', minWidth: 300, showOverflow: 'tooltip', sortable: true },
|
||||||
|
{ field: '', title: '修改记录', width: 100, showOverflow: 'tooltip', slots: { default: 'row_record' } },
|
||||||
|
{ title: '操作', fixed: 'right', width: 100, showOverflow: true, slots: { default: 'row_buttons' } },
|
||||||
|
],
|
||||||
|
enableExport: auth('sysConfig:export'),
|
||||||
|
searchCallback: () => handleQuery(),
|
||||||
|
queryAllCallback: () => fetchData({ pageSize: 99999 }),
|
||||||
});
|
});
|
||||||
const getData = (param: any) => {
|
|
||||||
return getAPI(SysConfigApi)
|
|
||||||
.apiSysConfigPagePost(param)
|
|
||||||
.then((res) => {
|
|
||||||
return res.data;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const exportChangeData = (data: Array<EmptyObjectType>) => {
|
|
||||||
data.forEach((item) => {
|
|
||||||
item.sysFlag = item.sysFlag == 1 ? '是' : '否';
|
|
||||||
});
|
|
||||||
return data;
|
|
||||||
};
|
|
||||||
// 拖动显示列排序回调
|
|
||||||
const onSortHeader = (data: object[]) => {
|
|
||||||
tb.tableData.columns = data;
|
|
||||||
};
|
|
||||||
// 搜索点击时表单回调
|
|
||||||
const onSearch = (data: EmptyObjectType) => {
|
|
||||||
tb.tableData.param = Object.assign({}, tb.tableData.param, { ...data });
|
|
||||||
nextTick(() => {
|
|
||||||
tableRef.value.pageReset();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const getGroupList = async () => {
|
|
||||||
const res = await getAPI(SysConfigApi).apiSysConfigGroupListGet();
|
|
||||||
const groupSearch = {
|
|
||||||
label: '分组编码',
|
|
||||||
prop: 'groupCode',
|
|
||||||
placeholder: '请选择',
|
|
||||||
required: false,
|
|
||||||
type: 'select',
|
|
||||||
options: [],
|
|
||||||
} as TableSearchType;
|
|
||||||
state.groupList = res.data.result ?? [];
|
|
||||||
res.data.result?.forEach((item) => {
|
|
||||||
groupSearch.options?.push({ label: item, value: item });
|
|
||||||
});
|
|
||||||
let group = tb.tableData.search.filter((item) => {
|
|
||||||
return item.prop == 'groupCode';
|
|
||||||
});
|
|
||||||
if (group.length == 0) {
|
|
||||||
tb.tableData.search.push(groupSearch);
|
|
||||||
} else {
|
|
||||||
group[0] = groupSearch;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//表格多选事件
|
|
||||||
const tableSelection = (data: EmptyObjectType[]) => {
|
|
||||||
state.selectlist = data;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
// 页面初始化
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
getGroupList();
|
await handleQuery();
|
||||||
|
fetchGroupData();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 更新数据
|
// 查询操作
|
||||||
const updateData = () => {
|
const handleQuery = async (reset = false) => {
|
||||||
tableRef.value.handleList();
|
options.loading = true;
|
||||||
getGroupList();
|
if (reset) state.tableParams.page = 1;
|
||||||
|
var res = await fetchData(null);
|
||||||
|
xGrid.value?.loadData(res.data.result?.items ?? []);
|
||||||
|
state.tableParams.total = res.data.result?.total;
|
||||||
|
state.selectList = [];
|
||||||
|
options.loading = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取数据
|
||||||
|
const fetchData = async (tableParams: any) => {
|
||||||
|
let params = Object.assign(state.queryParams, state.tableParams, tableParams);
|
||||||
|
return getAPI(SysConfigApi).apiSysConfigPagePost(params);
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchGroupData = async () => {
|
||||||
|
const res = await getAPI(SysConfigApi).apiSysConfigGroupListGet();
|
||||||
|
state.groupList = res.data.result ?? [];
|
||||||
|
};
|
||||||
|
|
||||||
|
// 重置操作
|
||||||
|
const resetQuery = () => {
|
||||||
|
state.queryParams.code = undefined;
|
||||||
|
state.queryParams.name = undefined;
|
||||||
|
state.queryParams.groupCode = undefined;
|
||||||
|
handleQuery(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 改变页码序号或页面容量
|
||||||
|
const pageChange: VxePagerEvents.PageChange = ({ currentPage, pageSize }: VxePagerDefines.PageChangeEventParams) => {
|
||||||
|
state.tableParams.page = currentPage;
|
||||||
|
state.tableParams.pageSize = pageSize;
|
||||||
|
handleQuery();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 列排序
|
||||||
|
const sortChange = (options: any) => {
|
||||||
|
state.tableParams.field = options.field;
|
||||||
|
state.tableParams.order = options.order;
|
||||||
|
handleQuery();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开新增页面
|
// 打开新增页面
|
||||||
const openAddConfig = () => {
|
const handleAdd = () => {
|
||||||
state.editConfigTitle = '添加配置';
|
state.title = '添加配置';
|
||||||
editConfigRef.value?.openDialog({ sysFlag: 2, orderNo: 100 });
|
editConfigRef.value?.openDialog({ sysFlag: 2, orderNo: 100 });
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开编辑页面
|
// 打开编辑页面
|
||||||
const openEditConfig = (row: any) => {
|
const handleEdit = (row: any) => {
|
||||||
state.editConfigTitle = '编辑配置';
|
state.title = '编辑配置';
|
||||||
editConfigRef.value?.openDialog(row);
|
editConfigRef.value?.openDialog(row);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 更新数据
|
||||||
|
const updateData = async () => {
|
||||||
|
await handleQuery();
|
||||||
|
fetchGroupData();
|
||||||
|
};
|
||||||
|
|
||||||
// 删除
|
// 删除
|
||||||
const delConfig = (row: any) => {
|
const handleDelete = (row: any) => {
|
||||||
ElMessageBox.confirm(`确定删除配置:【${row.name}】?`, '提示', {
|
ElMessageBox.confirm(`确定删除配置:【${row.name}】?`, '提示', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
@ -172,26 +210,28 @@ const delConfig = (row: any) => {
|
|||||||
})
|
})
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
await getAPI(SysConfigApi).apiSysConfigDeletePost({ id: row.id });
|
await getAPI(SysConfigApi).apiSysConfigDeletePost({ id: row.id });
|
||||||
tableRef.value.handleList();
|
handleQuery();
|
||||||
ElMessage.success('删除成功');
|
ElMessage.success('删除成功');
|
||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
};
|
};
|
||||||
|
|
||||||
//批量删除
|
const handleSelectChange = () => {
|
||||||
const bacthDelete = () => {
|
state.selectList = xGrid.value?.getCheckboxRecords() ?? [];
|
||||||
if (state.selectlist.length == 0) return false;
|
};
|
||||||
ElMessageBox.confirm(`确定批量删除【${state.selectlist[0].name}】等${state.selectlist.length}个配置?`, '提示', {
|
|
||||||
|
// 批量删除
|
||||||
|
const handleBacthDelete = () => {
|
||||||
|
if (state.selectList.length == 0) return false;
|
||||||
|
ElMessageBox.confirm(`确定批量删除【${state.selectList[0].name}】等${state.selectList.length}个配置?`, '提示', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
})
|
})
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
const ids = state.selectlist.map((item) => {
|
const ids = state.selectList.map((item: any) => item.id);
|
||||||
return item.id;
|
|
||||||
});
|
|
||||||
var res = await getAPI(SysConfigApi).apiSysConfigBatchDeletePost(ids);
|
var res = await getAPI(SysConfigApi).apiSysConfigBatchDeletePost(ids);
|
||||||
tableRef.value.pageReset();
|
handleQuery();
|
||||||
ElMessage.success('删除成功');
|
ElMessage.success('删除成功');
|
||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
||||||
<el-row :gutter="35">
|
<el-row :gutter="10">
|
||||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||||
<el-form-item label="列名" prop="dbColumnName" :rules="[{ required: true, message: '名称不能为空', trigger: 'blur' }]">
|
<el-form-item label="列名" prop="dbColumnName" :rules="[{ required: true, message: '名称不能为空', trigger: 'blur' }]">
|
||||||
<el-input v-model="state.ruleForm.dbColumnName" placeholder="列名称" clearable />
|
<el-input v-model="state.ruleForm.dbColumnName" placeholder="列名称" clearable />
|
||||||
@ -72,10 +72,11 @@
|
|||||||
<script lang="ts" setup name="sysAddColumn">
|
<script lang="ts" setup name="sysAddColumn">
|
||||||
import { reactive, ref } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
|
|
||||||
|
import { dataTypeList, yesNoSelect } from '../database';
|
||||||
|
|
||||||
import { getAPI } from '/@/utils/axios-utils';
|
import { getAPI } from '/@/utils/axios-utils';
|
||||||
import { SysDatabaseApi } from '/@/api-services/api';
|
import { SysDatabaseApi } from '/@/api-services/api';
|
||||||
import { DbColumnInput } from '/@/api-services/models';
|
import { DbColumnInput } from '/@/api-services/models';
|
||||||
import { dataTypeList, yesNoSelect } from '../database';
|
|
||||||
|
|
||||||
const emits = defineEmits(['handleQueryColumn']);
|
const emits = defineEmits(['handleQueryColumn']);
|
||||||
const ruleFormRef = ref();
|
const ruleFormRef = ref();
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-dbTable-container">
|
<div class="sys-dbTable-container">
|
||||||
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="1400px">
|
<el-dialog v-model="state.visible" :z-index="2008" draggable :close-on-click-modal="false" width="70vw">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div style="color: #fff">
|
<div style="color: #fff">
|
||||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
||||||
<span> 增加表 </span>
|
<span> 增加表 </span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-divider content-position="left">数据表信息</el-divider>
|
<el-divider content-position="left" style="margin: 10px 0 18px 0">数据表信息</el-divider>
|
||||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
||||||
<el-row :gutter="35">
|
<el-row :gutter="10">
|
||||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||||
<el-form-item label="表名称" prop="tableName" :rules="[{ required: true, message: '名称不能为空', trigger: 'blur' }]">
|
<el-form-item label="表名称" prop="tableName" :rules="[{ required: true, message: '名称不能为空', trigger: 'blur' }]">
|
||||||
<el-input v-model="state.ruleForm.tableName" placeholder="表名称" clearable />
|
<el-input v-model="state.ruleForm.tableName" placeholder="表名称" clearable />
|
||||||
@ -22,69 +22,21 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
<el-divider content-position="left">数据列信息</el-divider>
|
<el-divider content-position="left" style="margin: 10px 0 18px 0">数据列信息</el-divider>
|
||||||
<el-table :data="state.tableData" style="width: 100%" max-height="400">
|
<div style="height: calc(90vh - 252px)">
|
||||||
<el-table-column prop="dbColumnName" label="字段名" width="220" fixed>
|
<vxe-grid ref="xGrid" class="xGrid-table-style" v-bind="options">
|
||||||
<template #default="scope">
|
<template #toolbar_buttons>
|
||||||
<el-input v-model="scope.row.dbColumnName" autocomplete="off" />
|
<el-button icon="ele-Plus" @click="addPrimaryColumn">新增主键字段</el-button>
|
||||||
|
<el-button icon="ele-Plus" @click="addColumn">新增普通字段</el-button>
|
||||||
|
<el-button icon="ele-Plus" @click="addTenantColumn">新增租户字段</el-button>
|
||||||
|
<el-button icon="ele-Plus" @click="addBaseColumn">新增基础字段</el-button>
|
||||||
|
<el-button icon="ele-Delete" type="danger" @click="deleteSelected">删除选中</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
<template #toolbar_tools> </template>
|
||||||
<el-table-column prop="columnDescription" label="描述" width="220">
|
<template #empty>
|
||||||
<template #default="scope">
|
<el-empty :image-size="200" />
|
||||||
<el-input v-model="scope.row.columnDescription" autocomplete="off" />
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</vxe-grid>
|
||||||
<el-table-column prop="isPrimarykey" label="主键" width="100">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-select v-model="scope.row.isPrimarykey" class="m-2" placeholder="Select">
|
|
||||||
<el-option v-for="item in yesNoSelect" :key="item.value" :label="item.label" :value="item.value" />
|
|
||||||
</el-select>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="isIdentity" label="自增" width="100">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-select v-model="scope.row.isIdentity" class="m-2" placeholder="Select">
|
|
||||||
<el-option v-for="item in yesNoSelect" :key="item.value" :label="item.label" :value="item.value" />
|
|
||||||
</el-select>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="dataType" label="类型" width="150">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-select v-model="scope.row.dataType" class="m-2" placeholder="Select">
|
|
||||||
<el-option v-for="item in dataTypeList" :key="item.value" :label="item.value" :value="item.value" />
|
|
||||||
</el-select>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="isNullable" label="可空" width="100">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-select v-model="scope.row.isNullable" class="m-2" placeholder="Select">
|
|
||||||
<el-option v-for="item in yesNoSelect" :key="item.value" :label="item.label" :value="item.value" />
|
|
||||||
</el-select>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="length" label="长度" width="100">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-input-number v-model="scope.row.length" controls-position="right" class="w100" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="decimalDigits" label="小数位" width="100">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-input-number v-model="scope.row.decimalDigits" controls-position="right" class="w100" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="操作" min-width="200" align="center" fixed="right">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-button link type="primary" icon="el-icon-delete" @click.prevent="handleColDelete(scope.$index)">删除</el-button>
|
|
||||||
<el-button v-if="state.tableData.length > 1" link type="primary" icon="ele-Top" @click.prevent="handleColUp(scope.row, scope.$index)">上移</el-button>
|
|
||||||
<el-button v-if="state.tableData.length > 1" link type="primary" icon="ele-Bottom" @click.prevent="handleColDown(scope.row, scope.$index)">下移</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
<div style="text-align: left; margin-top: 10px">
|
|
||||||
<el-button icon="ele-Plus" @click="addPrimaryColumn">新增主键字段</el-button>
|
|
||||||
<el-button icon="ele-Plus" @click="addColumn">新增普通字段</el-button>
|
|
||||||
<el-button icon="ele-Plus" @click="addTenantColumn">新增租户字段</el-button>
|
|
||||||
<el-button icon="ele-Plus" @click="addBaseColumn">新增基础字段</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@ -97,56 +49,251 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup name="sysAddTable">
|
<script lang="tsx" setup name="sysAddTable">
|
||||||
import { reactive, ref } from 'vue';
|
import { nextTick, reactive, ref } from 'vue';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage, dayjs } from 'element-plus';
|
||||||
|
import { VxeGridInstance, VxeGridProps } from 'vxe-table';
|
||||||
|
import { Rank } from '@element-plus/icons-vue';
|
||||||
|
import Sortable from 'sortablejs';
|
||||||
|
import { dataTypeList } from '../database';
|
||||||
|
|
||||||
import { getAPI } from '/@/utils/axios-utils';
|
import { getAPI } from '/@/utils/axios-utils';
|
||||||
import { SysDatabaseApi } from '/@/api-services/api';
|
import { SysDatabaseApi } from '/@/api-services/api';
|
||||||
import { UpdateDbTableInput } from '/@/api-services/models';
|
import { UpdateDbTableInput } from '/@/api-services/models';
|
||||||
import { dataTypeList, EditRecordRow, yesNoSelect } from '../database';
|
|
||||||
|
|
||||||
var colIndex = 0;
|
const xGrid = ref<VxeGridInstance>();
|
||||||
|
let initTime: any;
|
||||||
const emits = defineEmits(['addTableSubmitted']);
|
const emits = defineEmits(['addTableSubmitted']);
|
||||||
const ruleFormRef = ref();
|
const ruleFormRef = ref();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
isShowDialog: false,
|
visible: false,
|
||||||
ruleForm: {} as UpdateDbTableInput,
|
ruleForm: {} as UpdateDbTableInput,
|
||||||
tableData: [] as any,
|
sortable: undefined as any,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 表格参数配置
|
||||||
|
const options = reactive<VxeGridProps>({
|
||||||
|
id: 'sysAddTable',
|
||||||
|
height: 'auto',
|
||||||
|
autoResize: true,
|
||||||
|
size: 'mini',
|
||||||
|
loading: false,
|
||||||
|
align: 'center', // 自动监听父元素的变化去重新计算表格(对于父元素可能存在动态变化、显示隐藏的容器中、列宽异常等场景中的可能会用到)
|
||||||
|
data: [] as Array<any>,
|
||||||
|
rowConfig: { useKey: true },
|
||||||
|
seqConfig: { seqMethod: ({ row }) => row.orderNo },
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
width: 80,
|
||||||
|
slots: {
|
||||||
|
default: () => (
|
||||||
|
<span class="drag-btn">
|
||||||
|
<el-icon>
|
||||||
|
<Rank />
|
||||||
|
</el-icon>
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ type: 'seq', title: '序号', width: 50 },
|
||||||
|
{ type: 'checkbox', width: 40 },
|
||||||
|
{
|
||||||
|
field: 'dbColumnName',
|
||||||
|
title: '字段名',
|
||||||
|
minWidth: 160,
|
||||||
|
showOverflow: 'tooltip',
|
||||||
|
editRender: { name: '$input', props: { clearable: true, placeholder: '请输入字段名' } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'columnDescription',
|
||||||
|
title: '描述',
|
||||||
|
minWidth: 220,
|
||||||
|
showOverflow: 'tooltip',
|
||||||
|
editRender: { name: '$input', props: { clearable: true, placeholder: '请输入描述' } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'isPrimarykey',
|
||||||
|
title: '主键',
|
||||||
|
minWidth: 100,
|
||||||
|
editRender: { name: '$switch', props: { openValue: 1, closeValue: 0, openLabel: '是', closeLabel: '否' } },
|
||||||
|
slots: {
|
||||||
|
default: (scope) => <vxe-switch vModel={scope.row.isPrimarykey} open-label="是" close-label="否" openValue={1} closeValue={0}></vxe-switch>,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'isIdentity',
|
||||||
|
title: '自增',
|
||||||
|
minWidth: 100,
|
||||||
|
editRender: { name: '$switch', props: { openValue: 1, closeValue: 0, openLabel: '是', closeLabel: '否' } },
|
||||||
|
slots: {
|
||||||
|
default: (scope) => <vxe-switch vModel={scope.row.isIdentity} open-label="是" close-label="否" openValue={1} closeValue={0}></vxe-switch>,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'dataType',
|
||||||
|
title: '类型',
|
||||||
|
minWidth: 100,
|
||||||
|
editRender: {
|
||||||
|
name: '$select',
|
||||||
|
options: dataTypeList,
|
||||||
|
optionProps: { value: 'value', label: 'value' },
|
||||||
|
props: { optionProps: { value: 'value', label: 'value' }, placeholder: '请选择类型', popupClassName: 'zIndex2023' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'isNullable',
|
||||||
|
title: '可空',
|
||||||
|
minWidth: 100,
|
||||||
|
editRender: { name: '$switch', props: { openValue: 1, closeValue: 0, openLabel: '是', closeLabel: '否' } },
|
||||||
|
slots: {
|
||||||
|
default: (scope) => <vxe-switch vModel={scope.row.isNullable} open-label="是" close-label="否" openValue={1} closeValue={0}></vxe-switch>,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'length',
|
||||||
|
title: '长度',
|
||||||
|
minWidth: 100,
|
||||||
|
showOverflow: 'tooltip',
|
||||||
|
editRender: { name: '$input', props: { type: 'integer', clearable: true, placeholder: '请输入长度' } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'decimalDigits',
|
||||||
|
title: '小数位',
|
||||||
|
minWidth: 100,
|
||||||
|
showOverflow: 'tooltip',
|
||||||
|
editRender: { name: '$input', props: { type: 'integer', clearable: true, placeholder: '请输入小数位' } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
width: 80,
|
||||||
|
showOverflow: true,
|
||||||
|
fixed: 'right',
|
||||||
|
slots: {
|
||||||
|
default: (scope) => <el-button icon="ele-Delete" text type="danger" onClick={() => deleteRow(scope.row)}></el-button>,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
editRules: {
|
||||||
|
dbColumnName: [{ required: true, message: '字段名必填' }],
|
||||||
|
dataType: [{ required: true, message: '类型必填' }],
|
||||||
|
},
|
||||||
|
toolbarConfig: {
|
||||||
|
size: 'small',
|
||||||
|
slots: { buttons: 'toolbar_buttons', tools: 'toolbar_tools' },
|
||||||
|
refresh: false,
|
||||||
|
export: true,
|
||||||
|
print: true,
|
||||||
|
zoom: true,
|
||||||
|
custom: false,
|
||||||
|
},
|
||||||
|
checkboxConfig: { range: true },
|
||||||
|
sortConfig: {
|
||||||
|
trigger: 'cell',
|
||||||
|
remote: false,
|
||||||
|
},
|
||||||
|
editConfig: { trigger: 'click', mode: 'row', showStatus: true },
|
||||||
|
exportConfig: {
|
||||||
|
remote: false, //设置使用服务端导出
|
||||||
|
filename: `数据列信息导出_${dayjs().format('YYMMDDHHmmss')}`,
|
||||||
|
exportMethod: ({ options }) => handleExport(options), //服务器导出方法
|
||||||
|
},
|
||||||
|
printConfig: { sheetName: '' },
|
||||||
|
proxyConfig: {
|
||||||
|
props: {
|
||||||
|
list: 'data.result.items', //不分页时
|
||||||
|
// result: 'data.result.items', //分页时
|
||||||
|
total: 'data.result.total',
|
||||||
|
message: 'data.message',
|
||||||
|
},
|
||||||
|
ajax: {
|
||||||
|
query: () => Promise.resolve(), //不加会报错
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// 打开弹窗
|
// 打开弹窗
|
||||||
const openDialog = (row: any) => {
|
const openDialog = (row: any) => {
|
||||||
state.ruleForm = row;
|
state.ruleForm = row;
|
||||||
state.isShowDialog = true;
|
state.visible = true;
|
||||||
ruleFormRef.value?.resetFields();
|
ruleFormRef.value?.resetFields();
|
||||||
|
nextTick(() => {
|
||||||
|
rowDrop();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const rowDrop = () => {
|
||||||
|
const el = document.querySelector('.xGrid-table-style .vxe-table--body tbody') as HTMLElement;
|
||||||
|
state.sortable = Sortable.create(el, {
|
||||||
|
animation: 300,
|
||||||
|
handle: '.drag-btn',
|
||||||
|
onEnd: (sortableEvent: any) => {
|
||||||
|
const fullData = xGrid.value?.getTableData().fullData;
|
||||||
|
const newIndex = sortableEvent.newIndex as number;
|
||||||
|
const oldIndex = sortableEvent.oldIndex as number;
|
||||||
|
// 往前移动
|
||||||
|
if (oldIndex > newIndex) {
|
||||||
|
const moveRow = fullData?.find((e) => e.orderNo == oldIndex + 1);
|
||||||
|
for (let i = oldIndex; i > newIndex; i--) {
|
||||||
|
const row = fullData?.find((e) => e.orderNo == i);
|
||||||
|
row.orderNo += 1;
|
||||||
|
}
|
||||||
|
moveRow.orderNo = newIndex + 1;
|
||||||
|
} else {
|
||||||
|
// 往后移动
|
||||||
|
const moveRow = fullData?.find((e) => e.orderNo == oldIndex + 1);
|
||||||
|
for (let i = oldIndex; i < newIndex; i++) {
|
||||||
|
const row = fullData?.find((e) => e.orderNo == i + 2);
|
||||||
|
row.orderNo -= 1;
|
||||||
|
}
|
||||||
|
moveRow.orderNo = newIndex + 1;
|
||||||
|
}
|
||||||
|
xGrid.value?.updateData();
|
||||||
|
},
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 关闭弹窗
|
// 关闭弹窗
|
||||||
const closeDialog = () => {
|
const closeDialog = () => {
|
||||||
emits('addTableSubmitted', state.ruleForm.tableName ?? '');
|
emits('addTableSubmitted', state.ruleForm.tableName ?? '');
|
||||||
state.tableData = [];
|
cancel();
|
||||||
state.isShowDialog = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 取消
|
// 取消
|
||||||
const cancel = () => {
|
const cancel = () => {
|
||||||
state.isShowDialog = false;
|
xGrid.value?.loadData([]);
|
||||||
|
state.visible = false;
|
||||||
|
clearTimeout(initTime);
|
||||||
|
if (state.sortable) {
|
||||||
|
state.sortable.destroy();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 导出日志(服务端导出)
|
||||||
|
const handleExport = async (opts: any) => {
|
||||||
|
console.log(opts);
|
||||||
|
options.loading = true;
|
||||||
|
// var res = await getAPI(SysLogExApi).apiSysLogExExportPost(state.queryParams as any, { responseType: 'blob' });
|
||||||
|
options.loading = false;
|
||||||
|
// VXETable.saveFile({ filename: getFileName(res.headers), type: 'xlsx', content: res.data as any });
|
||||||
|
return Promise.resolve();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 提交
|
// 提交
|
||||||
const submit = () => {
|
const submit = () => {
|
||||||
ruleFormRef.value.validate(async (valid: boolean) => {
|
ruleFormRef.value.validate(async (valid: boolean) => {
|
||||||
if (!valid) return;
|
if (!valid) return;
|
||||||
if (state.tableData.length === 0) {
|
const tableData = xGrid.value?.getTableData().fullData ?? [];
|
||||||
ElMessage({
|
if (tableData.length === 0) {
|
||||||
type: 'error',
|
ElMessage({ type: 'error', message: `请添加列!` });
|
||||||
message: `请添加列!`,
|
return;
|
||||||
});
|
}
|
||||||
|
const rowValid = await xGrid.value?.validate(true);
|
||||||
|
if (rowValid) {
|
||||||
|
ElMessage.error('校验不通过');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const params: any = {
|
const params: any = {
|
||||||
dbColumnInfoList: state.tableData,
|
dbColumnInfoList: tableData,
|
||||||
...state.ruleForm,
|
...state.ruleForm,
|
||||||
};
|
};
|
||||||
await getAPI(SysDatabaseApi).apiSysDatabaseAddTablePost(params);
|
await getAPI(SysDatabaseApi).apiSysDatabaseAddTablePost(params);
|
||||||
@ -155,164 +302,146 @@ const submit = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 增加主键列
|
// 增加主键列
|
||||||
function addPrimaryColumn() {
|
const addPrimaryColumn = async () => {
|
||||||
state.tableData.push({
|
const fullData = xGrid.value?.getTableData().fullData;
|
||||||
columnDescription: '主键Id',
|
const colIndex = (fullData?.length ?? 0) + 1;
|
||||||
dataType: 'bigint',
|
const temp = await xGrid.value?.insertAt(
|
||||||
dbColumnName: 'Id',
|
|
||||||
decimalDigits: 0,
|
|
||||||
isIdentity: 0,
|
|
||||||
isNullable: 0,
|
|
||||||
isPrimarykey: 1,
|
|
||||||
length: 0,
|
|
||||||
key: colIndex,
|
|
||||||
editable: true,
|
|
||||||
isNew: true,
|
|
||||||
});
|
|
||||||
colIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 增加普通列
|
|
||||||
function addColumn() {
|
|
||||||
state.tableData.push({
|
|
||||||
columnDescription: '',
|
|
||||||
dataType: 'varchar',
|
|
||||||
dbColumnName: '',
|
|
||||||
decimalDigits: 0,
|
|
||||||
isIdentity: 0,
|
|
||||||
isNullable: 1,
|
|
||||||
isPrimarykey: 0,
|
|
||||||
length: 32,
|
|
||||||
key: colIndex,
|
|
||||||
editable: true,
|
|
||||||
isNew: true,
|
|
||||||
});
|
|
||||||
colIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 增加租户列
|
|
||||||
function addTenantColumn() {
|
|
||||||
state.tableData.push({
|
|
||||||
columnDescription: '租户Id',
|
|
||||||
dataType: 'bigint',
|
|
||||||
dbColumnName: 'TenantId',
|
|
||||||
decimalDigits: 0,
|
|
||||||
isIdentity: 0,
|
|
||||||
isNullable: 1,
|
|
||||||
isPrimarykey: 0,
|
|
||||||
length: 0,
|
|
||||||
key: colIndex,
|
|
||||||
editable: true,
|
|
||||||
isNew: true,
|
|
||||||
});
|
|
||||||
colIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 增加通用基础列
|
|
||||||
function addBaseColumn() {
|
|
||||||
const fileds = [
|
|
||||||
{
|
|
||||||
dataType: 'datetime',
|
|
||||||
name: 'CreateTime',
|
|
||||||
desc: '创建时间',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
dataType: 'datetime',
|
|
||||||
name: 'UpdateTime',
|
|
||||||
desc: '更新时间',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
|
columnDescription: '主键Id',
|
||||||
dataType: 'bigint',
|
dataType: 'bigint',
|
||||||
name: 'CreateUserId',
|
dbColumnName: 'Id',
|
||||||
desc: '创建者Id',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
dataType: 'varchar',
|
|
||||||
name: 'CreateUserName',
|
|
||||||
desc: '创建者姓名',
|
|
||||||
length: 64,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
dataType: 'bigint',
|
|
||||||
name: 'UpdateUserId',
|
|
||||||
desc: '修改者Id',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
dataType: 'varchar',
|
|
||||||
name: 'UpdateUserName',
|
|
||||||
desc: '修改者姓名',
|
|
||||||
length: 64,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
dataType: 'bigint',
|
|
||||||
name: 'CreateOrgId',
|
|
||||||
desc: '创建者部门Id',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
dataType: 'varchar',
|
|
||||||
name: 'CreateOrgName',
|
|
||||||
desc: '创建者部门名称',
|
|
||||||
length: 64,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
dataType: 'bit',
|
|
||||||
name: 'IsDelete',
|
|
||||||
desc: '软删除',
|
|
||||||
isNullable: 0,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
fileds.forEach((m: any) => {
|
|
||||||
state.tableData.push({
|
|
||||||
columnDescription: m.desc,
|
|
||||||
dataType: m.dataType,
|
|
||||||
dbColumnName: m.name,
|
|
||||||
decimalDigits: 0,
|
decimalDigits: 0,
|
||||||
isIdentity: 0,
|
isIdentity: 0,
|
||||||
isNullable: m.isNullable === 0 ? 0 : 1,
|
isNullable: 0,
|
||||||
isPrimarykey: 0,
|
isPrimarykey: 1,
|
||||||
length: m.length || 0,
|
length: 0,
|
||||||
key: colIndex,
|
orderNo: colIndex,
|
||||||
editable: true,
|
editable: true,
|
||||||
isNew: true,
|
isNew: true,
|
||||||
});
|
},
|
||||||
|
-1
|
||||||
|
);
|
||||||
|
if (temp && temp.row) await xGrid.value?.setEditCell(temp?.row, 'dbColumnName');
|
||||||
|
};
|
||||||
|
|
||||||
|
// 增加普通列
|
||||||
|
const addColumn = async () => {
|
||||||
|
const fullData = xGrid.value?.getTableData().fullData;
|
||||||
|
const colIndex = (fullData?.length ?? 0) + 1;
|
||||||
|
const temp = await xGrid.value?.insertAt(
|
||||||
|
{
|
||||||
|
columnDescription: '',
|
||||||
|
dataType: 'varchar',
|
||||||
|
dbColumnName: '',
|
||||||
|
decimalDigits: 0,
|
||||||
|
isIdentity: 0,
|
||||||
|
isNullable: 1,
|
||||||
|
isPrimarykey: 0,
|
||||||
|
length: 32,
|
||||||
|
orderNo: colIndex,
|
||||||
|
editable: true,
|
||||||
|
isNew: true,
|
||||||
|
},
|
||||||
|
-1
|
||||||
|
);
|
||||||
|
if (temp && temp.row) await xGrid.value?.setEditCell(temp?.row, 'dbColumnName');
|
||||||
|
};
|
||||||
|
|
||||||
|
// 增加租户列
|
||||||
|
const addTenantColumn = async () => {
|
||||||
|
const fullData = xGrid.value?.getTableData().fullData;
|
||||||
|
const colIndex = (fullData?.length ?? 0) + 1;
|
||||||
|
const temp = await xGrid.value?.insertAt(
|
||||||
|
{
|
||||||
|
columnDescription: '租户Id',
|
||||||
|
dataType: 'bigint',
|
||||||
|
dbColumnName: 'TenantId',
|
||||||
|
decimalDigits: 0,
|
||||||
|
isIdentity: 0,
|
||||||
|
isNullable: 1,
|
||||||
|
isPrimarykey: 0,
|
||||||
|
length: 0,
|
||||||
|
orderNo: colIndex,
|
||||||
|
editable: true,
|
||||||
|
isNew: true,
|
||||||
|
},
|
||||||
|
-1
|
||||||
|
);
|
||||||
|
if (temp && temp.row) await xGrid.value?.setEditCell(temp?.row, 'dbColumnName');
|
||||||
|
};
|
||||||
|
|
||||||
|
// 增加通用基础列
|
||||||
|
const addBaseColumn = async () => {
|
||||||
|
const fileds = [
|
||||||
|
{ dataType: 'datetime', name: 'CreateTime', desc: '创建时间' },
|
||||||
|
{ dataType: 'datetime', name: 'UpdateTime', desc: '更新时间' },
|
||||||
|
{ dataType: 'bigint', name: 'CreateUserId', desc: '创建者Id' },
|
||||||
|
{ dataType: 'varchar', name: 'CreateUserName', desc: '创建者姓名', length: 64 },
|
||||||
|
{ dataType: 'bigint', name: 'UpdateUserId', desc: '修改者Id' },
|
||||||
|
{ dataType: 'varchar', name: 'UpdateUserName', desc: '修改者姓名', length: 64 },
|
||||||
|
{ dataType: 'bigint', name: 'CreateOrgId', desc: '创建者部门Id' },
|
||||||
|
{ dataType: 'varchar', name: 'CreateOrgName', desc: '创建者部门名称', length: 64 },
|
||||||
|
{ dataType: 'bit', name: 'IsDelete', desc: '软删除', isNullable: 0 },
|
||||||
|
];
|
||||||
|
let temp = {} as any;
|
||||||
|
const fullData = xGrid.value?.getTableData().fullData;
|
||||||
|
let colIndex = (fullData?.length ?? 0) + 1;
|
||||||
|
for (let i = 0; i < fileds.length; i++) {
|
||||||
|
temp = await xGrid.value?.insertAt(
|
||||||
|
{
|
||||||
|
columnDescription: fileds[i].desc,
|
||||||
|
dataType: fileds[i].dataType,
|
||||||
|
dbColumnName: fileds[i].name,
|
||||||
|
decimalDigits: 0,
|
||||||
|
isIdentity: 0,
|
||||||
|
isNullable: fileds[i].isNullable === 0 ? 0 : 1,
|
||||||
|
isPrimarykey: 0,
|
||||||
|
length: (fileds[i] as any).length || 0,
|
||||||
|
orderNo: colIndex,
|
||||||
|
editable: true,
|
||||||
|
isNew: true,
|
||||||
|
},
|
||||||
|
-1
|
||||||
|
);
|
||||||
colIndex++;
|
colIndex++;
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleColDelete(index: number) {
|
|
||||||
state.tableData.splice(index, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 上移
|
|
||||||
function handleColUp(record: EditRecordRow, index: number) {
|
|
||||||
if (record.isNew) {
|
|
||||||
var data1 = ChangeExForArray(index, index - 1, state.tableData);
|
|
||||||
return data1;
|
|
||||||
}
|
}
|
||||||
}
|
if (temp && temp.row) await xGrid.value?.setEditCell(temp?.row, 'dbColumnName');
|
||||||
|
};
|
||||||
|
|
||||||
// 下移
|
// 删除行
|
||||||
function handleColDown(record: EditRecordRow, index: number) {
|
const deleteRow = (row: any) => {
|
||||||
if (record.isNew) {
|
const fullData = xGrid.value?.getTableData().fullData;
|
||||||
return ChangeExForArray(index, index + 1, state.tableData);
|
fullData?.filter((e: any) => e.orderNo > row.orderNo)?.forEach((e: any) => (e.orderNo = e.orderNo - 1));
|
||||||
}
|
xGrid.value?.remove(row);
|
||||||
}
|
};
|
||||||
|
|
||||||
function ChangeExForArray(index1: number, index2: number, array: Array<EditRecordRow>) {
|
// 删除选中行
|
||||||
let maxIndex = state.tableData.length - 1; //最大索引
|
const deleteSelected = () => {
|
||||||
if (index2 > maxIndex) {
|
const selected = xGrid.value?.getCheckboxRecords();
|
||||||
index2 = 0;
|
const fullData = xGrid.value?.getTableData().fullData;
|
||||||
|
// 更新序号
|
||||||
|
for (let i = 0; i < selected!.length; i++) {
|
||||||
|
fullData?.filter((e: any) => e.orderNo > selected![i].orderNo)?.forEach((e: any) => (e.orderNo = e.orderNo - 1));
|
||||||
}
|
}
|
||||||
if (index2 < 0) {
|
// 移除选中
|
||||||
index2 = maxIndex;
|
xGrid.value?.removeCheckboxRow();
|
||||||
}
|
};
|
||||||
let temp = array[index1];
|
|
||||||
array[index1] = array[index2];
|
|
||||||
array[index2] = temp;
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 导出对象
|
// 导出对象
|
||||||
defineExpose({ openDialog });
|
defineExpose({ openDialog });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.sys-dbTable-container :deep(.el-dialog__body) {
|
||||||
|
height: 90vh;
|
||||||
|
max-height: 90vh;
|
||||||
|
}
|
||||||
|
.xGrid-table-style .drag-btn {
|
||||||
|
cursor: move;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
.xGrid-table-style .vxe-body--row.sortable-ghost,
|
||||||
|
.xGrid-table-style .vxe-body--row.sortable-chosen {
|
||||||
|
background-color: #e40000 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
||||||
<el-row :gutter="35">
|
<el-row :gutter="10">
|
||||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||||
<el-form-item label="列名称" prop="columnName" :rules="[{ required: true, message: '名称不能为空', trigger: 'blur' }]">
|
<el-form-item label="列名称" prop="columnName" :rules="[{ required: true, message: '名称不能为空', trigger: 'blur' }]">
|
||||||
<el-input v-model="state.ruleForm.columnName" placeholder="列名称" clearable />
|
<el-input v-model="state.ruleForm.columnName" placeholder="列名称" clearable />
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-dbTable-container">
|
<div class="sys-dbTable-container">
|
||||||
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="700px">
|
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="500px">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div style="color: #fff">
|
<div style="color: #fff">
|
||||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
||||||
@ -8,7 +8,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
||||||
<el-row :gutter="35">
|
<el-row :gutter="10">
|
||||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||||
<el-form-item label="表名称" prop="tableName" :rules="[{ required: true, message: '名称不能为空', trigger: 'blur' }]">
|
<el-form-item label="表名称" prop="tableName" :rules="[{ required: true, message: '名称不能为空', trigger: 'blur' }]">
|
||||||
<el-input v-model="state.ruleForm.tableName" placeholder="表名称" clearable />
|
<el-input v-model="state.ruleForm.tableName" placeholder="表名称" clearable />
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
||||||
<el-row :gutter="35">
|
<el-row :gutter="10">
|
||||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||||
<el-form-item label="表名" prop="tableName" :rules="[{ required: true, message: '表名不能为空', trigger: 'blur' }]">
|
<el-form-item label="表名" prop="tableName" :rules="[{ required: true, message: '表名不能为空', trigger: 'blur' }]">
|
||||||
<el-input disabled v-model="state.ruleForm.tableName" placeholder="表名" clearable />
|
<el-input disabled v-model="state.ruleForm.tableName" placeholder="表名" clearable />
|
||||||
@ -49,6 +49,7 @@
|
|||||||
<script lang="ts" setup name="sysGenEntity">
|
<script lang="ts" setup name="sysGenEntity">
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
import { camelCase, upperFirst } from 'lodash-es';
|
import { camelCase, upperFirst } from 'lodash-es';
|
||||||
|
|
||||||
import { getAPI } from '/@/utils/axios-utils';
|
import { getAPI } from '/@/utils/axios-utils';
|
||||||
import { SysDatabaseApi, SysDictTypeApi } from '/@/api-services/api';
|
import { SysDatabaseApi, SysDictTypeApi } from '/@/api-services/api';
|
||||||
|
|
||||||
|
|||||||
@ -4,11 +4,11 @@
|
|||||||
<template #header>
|
<template #header>
|
||||||
<div style="color: #fff">
|
<div style="color: #fff">
|
||||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Cpu /> </el-icon>
|
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Cpu /> </el-icon>
|
||||||
<span> 生成种子数据 </span>
|
<span> 生成种子数据【生成实体后必须重启服务才生效】</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto" :rules="state.rules">
|
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto" :rules="state.rules">
|
||||||
<el-row :gutter="35">
|
<el-row :gutter="10">
|
||||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||||
<el-form-item label="表名" prop="tableName" :rules="[{ required: true, message: '表名不能为空', trigger: 'blur' }]">
|
<el-form-item label="表名" prop="tableName" :rules="[{ required: true, message: '表名不能为空', trigger: 'blur' }]">
|
||||||
<el-input disabled v-model="state.ruleForm.tableName" placeholder="表名" clearable />
|
<el-input disabled v-model="state.ruleForm.tableName" placeholder="表名" clearable />
|
||||||
@ -46,7 +46,6 @@ import { getAPI } from '/@/utils/axios-utils';
|
|||||||
import { SysDatabaseApi, SysDictTypeApi } from '/@/api-services/api';
|
import { SysDatabaseApi, SysDictTypeApi } from '/@/api-services/api';
|
||||||
|
|
||||||
const emits = defineEmits(['handleQueryColumn']);
|
const emits = defineEmits(['handleQueryColumn']);
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
applicationNamespaces: { type: Array },
|
applicationNamespaces: { type: Array },
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,74 +1,73 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-database-container">
|
<div class="sys-database-container" v-loading="options.loading">
|
||||||
<el-card shadow="hover" :body-style="{ paddingBottom: '0' }">
|
<el-card shadow="hover" :body-style="{ padding: '5px 5px 0 5px', display: 'flex', width: '100%', height: '100%', alignItems: 'start' }">
|
||||||
<el-form :model="state.queryParams" ref="queryForm" :inline="true" v-loading="state.loading">
|
<el-form :model="state.queryParams" ref="queryForm" :show-message="false" :inlineMessage="true" :label-width="'60px'" style="flex: 1 1 0%">
|
||||||
<el-form-item label="库名">
|
<el-row :gutter="10">
|
||||||
<el-select v-model="state.configId" placeholder="库名" filterable @change="handleQueryTable">
|
<el-col class="mb5" :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
|
||||||
<el-option v-for="item in state.dbData" :key="item" :label="item" :value="item" />
|
<el-form-item label="库名" prop="configId">
|
||||||
</el-select>
|
<el-select v-model="state.configId" placeholder="库名" filterable @change="handleQueryTable">
|
||||||
</el-form-item>
|
<el-option v-for="item in state.dbData" :key="item" :label="item" :value="item" />
|
||||||
<el-form-item label="表名">
|
</el-select>
|
||||||
<el-select v-model="state.tableName" placeholder="表名" filterable clearable @change="handleQueryColumn">
|
</el-form-item>
|
||||||
<el-option v-for="item in state.tableData" :key="item.name" :label="item.name + '[' + item.description + ']'" :value="item.name" />
|
</el-col>
|
||||||
</el-select>
|
<el-col class="mb5" :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
|
||||||
</el-form-item>
|
<el-form-item label="表名" prop="tableName">
|
||||||
<el-form-item>
|
<el-select v-model="state.tableName" placeholder="表名" filterable clearable @change="handleQueryColumn">
|
||||||
<el-button-group>
|
<el-option v-for="item in state.tableData" :key="item.name" :label="`${item.name}${item.description ? '[' + item.description + ']' : ''}`" :value="item.name" />
|
||||||
<el-button icon="ele-Plus" type="primary" @click="openAddTable"> 增加表 </el-button>
|
</el-select>
|
||||||
<el-button icon="ele-Edit" @click="openEditTable"> 编辑表 </el-button>
|
</el-form-item>
|
||||||
<el-button icon="ele-Delete" type="danger" @click="delTable" disabled> 删除表 </el-button>
|
</el-col>
|
||||||
<el-button icon="ele-View" @click="visualTable"> 可视化 </el-button>
|
</el-row>
|
||||||
</el-button-group>
|
|
||||||
<el-button-group style="padding-left: 10px">
|
|
||||||
<el-button icon="ele-Plus" @click="openAddColumn"> 增加列 </el-button>
|
|
||||||
<el-button icon="ele-Plus" @click="openGenDialog"> 生成实体 </el-button>
|
|
||||||
<el-button icon="ele-Plus" @click="openGenSeedDataDialog"> 生成种子 </el-button>
|
|
||||||
</el-button-group>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
|
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
|
||||||
<el-table :data="state.columnData" style="width: 100%" v-loading="state.loading1" border>
|
<vxe-grid ref="xGrid" class="xGrid-style" v-bind="options">
|
||||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
<template #toolbar_buttons>
|
||||||
<el-table-column prop="dbColumnName" label="字段名" align="center" show-overflow-tooltip />
|
<el-button-group>
|
||||||
<el-table-column prop="dataType" label="数据类型" align="center" show-overflow-tooltip />
|
<el-button icon="ele-Plus" type="primary" @click="handleAddTable"> 增加表 </el-button>
|
||||||
<el-table-column prop="isPrimarykey" label="主键" width="70" align="center" show-overflow-tooltip>
|
<el-button icon="ele-Edit" type="primary" @click="showEditTable"> 编辑表 </el-button>
|
||||||
<template #default="scope">
|
<el-button icon="ele-Delete" type="danger" @click="handleDeleteTable"> 删除表 </el-button>
|
||||||
<el-tag type="success" v-if="scope.row.isPrimarykey === true">是</el-tag>
|
</el-button-group>
|
||||||
<el-tag type="info" v-else>否</el-tag>
|
<el-button-group style="padding-left: 12px; padding-right: 12px">
|
||||||
</template>
|
<el-button icon="ele-Plus" @click="showAddColumn"> 增加列 </el-button>
|
||||||
</el-table-column>
|
<el-button icon="ele-Plus" @click="showGenDialog"> 生成实体 </el-button>
|
||||||
<el-table-column prop="isIdentity" label="自增" width="70" align="center" show-overflow-tooltip>
|
<el-button icon="ele-Plus" @click="showGenSeedDataDialog"> 生成种子 </el-button>
|
||||||
<template #default="scope">
|
</el-button-group>
|
||||||
<el-tag type="success" v-if="scope.row.isIdentity === true">是</el-tag>
|
<el-button icon="ele-View" type="primary" @click="visualTable" plain> 可视化 </el-button>
|
||||||
<el-tag type="info" v-else>否</el-tag>
|
</template>
|
||||||
</template>
|
<template #toolbar_tools> </template>
|
||||||
</el-table-column>
|
<template #empty>
|
||||||
<el-table-column prop="isNullable" label="可空" width="70" align="center" show-overflow-tooltip>
|
<el-empty :image-size="200" />
|
||||||
<template #default="scope">
|
</template>
|
||||||
<el-tag v-if="scope.row.isNullable === true">是</el-tag>
|
<template #row_isPrimarykey="{ row }">
|
||||||
<el-tag type="info" v-else>否</el-tag>
|
<el-tag type="success" v-if="row.isPrimarykey === true">是</el-tag>
|
||||||
</template>
|
<el-tag type="info" v-else>否</el-tag>
|
||||||
</el-table-column>
|
</template>
|
||||||
<el-table-column prop="length" label="长度" width="70" align="center" show-overflow-tooltip />
|
<template #row_isIdentity="{ row }">
|
||||||
<el-table-column prop="decimalDigits" label="精度" width="70" align="center" show-overflow-tooltip />
|
<el-tag type="success" v-if="row.isIdentity === true">是</el-tag>
|
||||||
<el-table-column prop="defaultValue" label="默认值" align="center" show-overflow-tooltip />
|
<el-tag type="info" v-else>否</el-tag>
|
||||||
<el-table-column prop="columnDescription" label="描述" header-align="center" show-overflow-tooltip />
|
</template>
|
||||||
<el-table-column label="操作" width="145" fixed="right" align="center" show-overflow-tooltip>
|
<template #row_isNullable="{ row }">
|
||||||
<template #default="scope">
|
<el-tag v-if="row.isNullable === true">是</el-tag>
|
||||||
<el-button icon="ele-Edit" size="small" text type="primary" @click="openEditColumn(scope.row)"> 编辑 </el-button>
|
<el-tag type="info" v-else>否</el-tag>
|
||||||
<el-button icon="ele-Delete" size="small" text type="danger" @click="delColumn(scope.row)"> 删除 </el-button>
|
</template>
|
||||||
</template>
|
<template #row_buttons="{ row }">
|
||||||
</el-table-column>
|
<el-tooltip content="编辑" placement="top">
|
||||||
</el-table>
|
<el-button icon="ele-Edit" text type="primary" @click="showEditColumn(row)"> </el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip content="删除" placement="top">
|
||||||
|
<el-button icon="ele-Delete" text type="danger" @click="handleDeleteColumn(row)"> </el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
</vxe-grid>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<EditTable ref="editTableRef" @handleQueryTable="handleQueryTable" />
|
<EditTable ref="editTableRef" @handleQueryTable="handleQueryTable" />
|
||||||
<EditColumn ref="editColumnRef" @handleQueryColumn="handleQueryColumn" />
|
<EditColumn ref="editColumnRef" @handleQueryColumn="handleQueryColumn" />
|
||||||
<AddTable ref="addTableRef" @addTableSubmitted="addTableSubmitted" />
|
<AddTable ref="addTableRef" @addTableSubmitted="addTableSubmitted" />
|
||||||
<AddColumn ref="addColumnRef" @handleQueryColumn="handleQueryColumn" />
|
<AddColumn ref="addColumnRef" @handleQueryColumn="handleQueryColumn" />
|
||||||
<GenEntity ref="genEntityRef" @handleQueryColumn="handleQueryColumn" :application-namespaces="state.appNamespaces" />
|
<GenEntity ref="genEntityRef" @handleQueryColumn="handleQueryColumn" />
|
||||||
<GenSeedData ref="genSeedDataRef" :application-namespaces="state.appNamespaces" />
|
<GenSeedData ref="genSeedDataRef" :application-namespaces="state.appNamespaces" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -77,6 +76,9 @@
|
|||||||
import { onMounted, reactive, ref } from 'vue';
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
import { ElMessageBox, ElMessage } from 'element-plus';
|
import { ElMessageBox, ElMessage } from 'element-plus';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
import { VxeGridInstance } from 'vxe-table';
|
||||||
|
import { useVxeTable } from '/@/hooks/vxeTableOptionsHook';
|
||||||
|
|
||||||
import EditTable from '/@/views/system/database/component/editTable.vue';
|
import EditTable from '/@/views/system/database/component/editTable.vue';
|
||||||
import EditColumn from '/@/views/system/database/component/editColumn.vue';
|
import EditColumn from '/@/views/system/database/component/editColumn.vue';
|
||||||
import AddTable from '/@/views/system/database/component/addTable.vue';
|
import AddTable from '/@/views/system/database/component/addTable.vue';
|
||||||
@ -88,6 +90,7 @@ import { getAPI } from '/@/utils/axios-utils';
|
|||||||
import { SysDatabaseApi, SysCodeGenApi } from '/@/api-services/api';
|
import { SysDatabaseApi, SysCodeGenApi } from '/@/api-services/api';
|
||||||
import { DbColumnOutput, DbTableInfo, DbColumnInput, DeleteDbTableInput, DeleteDbColumnInput } from '/@/api-services/models';
|
import { DbColumnOutput, DbTableInfo, DbColumnInput, DeleteDbTableInput, DeleteDbColumnInput } from '/@/api-services/models';
|
||||||
|
|
||||||
|
const xGrid = ref<VxeGridInstance>();
|
||||||
const editTableRef = ref<InstanceType<typeof EditTable>>();
|
const editTableRef = ref<InstanceType<typeof EditTable>>();
|
||||||
const editColumnRef = ref<InstanceType<typeof EditColumn>>();
|
const editColumnRef = ref<InstanceType<typeof EditColumn>>();
|
||||||
const addTableRef = ref<InstanceType<typeof AddTable>>();
|
const addTableRef = ref<InstanceType<typeof AddTable>>();
|
||||||
@ -97,72 +100,98 @@ const genSeedDataRef = ref<InstanceType<typeof GenSeedData>>();
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
loading: false,
|
loading: false,
|
||||||
loading1: false,
|
|
||||||
dbData: [] as any,
|
dbData: [] as any,
|
||||||
configId: '',
|
configId: '',
|
||||||
tableData: [] as Array<DbTableInfo>,
|
tableData: [] as Array<DbTableInfo>,
|
||||||
tableName: '',
|
tableName: '',
|
||||||
columnData: [] as Array<DbColumnOutput>,
|
|
||||||
queryParams: {
|
queryParams: {
|
||||||
name: undefined,
|
name: undefined,
|
||||||
code: undefined,
|
code: undefined,
|
||||||
},
|
},
|
||||||
|
visible: false,
|
||||||
|
title: '',
|
||||||
appNamespaces: [] as Array<String>, // 存储位置
|
appNamespaces: [] as Array<String>, // 存储位置
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 表格参数配置
|
||||||
|
const options = useVxeTable<DbColumnOutput>({
|
||||||
|
id: 'sysDatabase',
|
||||||
|
name: '库表信息',
|
||||||
|
columns: [
|
||||||
|
// { type: 'checkbox', width: 40, fixed: 'left' },
|
||||||
|
{ type: 'seq', title: '序号', width: 50, fixed: 'left' },
|
||||||
|
{ field: 'dbColumnName', title: '字段名', minWidth: 200, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'dataType', title: '数据类型', minWidth: 120, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'isPrimarykey', title: '主键', minWidth: 70, slots: { default: 'row_isPrimarykey' } },
|
||||||
|
{ field: 'isIdentity', title: '自增', minWidth: 70, slots: { default: 'row_isIdentity' } },
|
||||||
|
{ field: 'isNullable', title: '可空', minWidth: 70, slots: { default: 'row_isNullable' } },
|
||||||
|
{ field: 'length', title: '长度', minWidth: 80, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'decimalDigits', title: '精度', minWidth: 80, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'defaultValue', title: '默认值', minWidth: 80, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'columnDescription', title: '描述', minWidth: 200, showOverflow: 'tooltip' },
|
||||||
|
{ title: '操作', fixed: 'right', width: 100, showOverflow: true, slots: { default: 'row_buttons' } },
|
||||||
|
],
|
||||||
|
enableExport: true,
|
||||||
|
searchCallback: () => handleQueryColumn(),
|
||||||
|
queryAllCallback: () => fetchData({ pageSize: 99999 }),
|
||||||
|
});
|
||||||
|
|
||||||
|
// 页面初始化
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
state.loading = true;
|
options.loading = true;
|
||||||
var res = await getAPI(SysDatabaseApi).apiSysDatabaseListGet();
|
var res = await getAPI(SysDatabaseApi).apiSysDatabaseListGet();
|
||||||
state.dbData = res.data.result;
|
state.dbData = res.data.result;
|
||||||
state.loading = false;
|
options.loading = false;
|
||||||
|
|
||||||
let appNamesRes = await getAPI(SysCodeGenApi).apiSysCodeGenApplicationNamespacesGet();
|
let appNamesRes = await getAPI(SysCodeGenApi).apiSysCodeGenApplicationNamespacesGet();
|
||||||
state.appNamespaces = appNamesRes.data.result as Array<string>;
|
state.appNamespaces = appNamesRes.data.result as Array<string>;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 查询操作
|
||||||
|
const handleQueryColumn = async () => {
|
||||||
|
if (state.tableName == '' || typeof state.tableName == 'undefined') {
|
||||||
|
await xGrid.value?.loadData([]);
|
||||||
|
options.loading = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
options.loading = true;
|
||||||
|
var res = await fetchData();
|
||||||
|
await xGrid.value?.loadData(res.data.result ?? []);
|
||||||
|
options.loading = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取数据
|
||||||
|
const fetchData = async (tableParams?: any) => {
|
||||||
|
return getAPI(SysDatabaseApi).apiSysDatabaseColumnListTableNameConfigIdGet(state.tableName, state.configId);
|
||||||
|
};
|
||||||
|
|
||||||
// 增加表
|
// 增加表
|
||||||
const addTableSubmitted = (e: any) => {
|
const addTableSubmitted = async (e: any) => {
|
||||||
handleQueryTable();
|
await handleQueryTable();
|
||||||
state.tableName = e;
|
state.tableName = e;
|
||||||
handleQueryColumn();
|
await handleQueryColumn();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 表查询操作
|
// 表查询操作
|
||||||
const handleQueryTable = async () => {
|
const handleQueryTable = async () => {
|
||||||
state.tableName = '';
|
state.tableName = '';
|
||||||
state.columnData = [];
|
xGrid.value?.loadData([]);
|
||||||
state.loading = true;
|
options.loading = true;
|
||||||
|
|
||||||
var res = await getAPI(SysDatabaseApi).apiSysDatabaseTableListConfigIdGet(state.configId);
|
var res = await getAPI(SysDatabaseApi).apiSysDatabaseTableListConfigIdGet(state.configId);
|
||||||
let tableData = res.data.result ?? [];
|
let tableData = res.data.result ?? [];
|
||||||
state.tableData = [];
|
state.tableData = [];
|
||||||
tableData.forEach((element: any) => {
|
tableData.forEach((element: any) => {
|
||||||
//排除zero_开头的表
|
// 排除zero_开头的表
|
||||||
if (!element.name.startsWith('zero_')) {
|
if (!element.name.startsWith('zero_')) {
|
||||||
state.tableData.push(element);
|
state.tableData.push(element);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
state.loading = false;
|
options.loading = false;
|
||||||
};
|
|
||||||
|
|
||||||
// 列查询操作
|
|
||||||
const handleQueryColumn = async () => {
|
|
||||||
state.columnData = [];
|
|
||||||
if (state.tableName == '' || typeof state.tableName == 'undefined') return;
|
|
||||||
|
|
||||||
state.loading1 = true;
|
|
||||||
var res = await getAPI(SysDatabaseApi).apiSysDatabaseColumnListTableNameConfigIdGet(state.tableName, state.configId);
|
|
||||||
state.columnData = res.data.result ?? [];
|
|
||||||
state.loading1 = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开表编辑页面
|
// 打开表编辑页面
|
||||||
const openEditTable = () => {
|
const showEditTable = () => {
|
||||||
if (state.configId == '' || state.tableName == '') {
|
if (state.configId == '' || state.tableName == '') {
|
||||||
ElMessage({
|
ElMessage({ type: 'error', message: `请选择库名和表名!` });
|
||||||
type: 'error',
|
|
||||||
message: `请选择库名和表名!`,
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var res = state.tableData.filter((u: any) => u.name == state.tableName);
|
var res = state.tableData.filter((u: any) => u.name == state.tableName);
|
||||||
@ -176,12 +205,9 @@ const openEditTable = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 打开实体生成页面
|
// 打开实体生成页面
|
||||||
const openGenDialog = () => {
|
const showGenDialog = () => {
|
||||||
if (state.configId == '' || state.tableName == '') {
|
if (state.configId == '' || state.tableName == '') {
|
||||||
ElMessage({
|
ElMessage({ type: 'error', message: `请选择库名和表名!` });
|
||||||
type: 'error',
|
|
||||||
message: `请选择库名和表名!`,
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// var res = state.tableData.filter((u: any) => u.name == state.tableName);
|
// var res = state.tableData.filter((u: any) => u.name == state.tableName);
|
||||||
@ -194,12 +220,9 @@ const openGenDialog = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 生成种子数据页面
|
// 生成种子数据页面
|
||||||
const openGenSeedDataDialog = () => {
|
const showGenSeedDataDialog = () => {
|
||||||
if (state.configId == '' || state.tableName == '') {
|
if (state.configId == '' || state.tableName == '') {
|
||||||
ElMessage({
|
ElMessage({ type: 'error', message: `请选择库名和表名!` });
|
||||||
type: 'error',
|
|
||||||
message: `请选择库名和表名!`,
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var table: any = {
|
var table: any = {
|
||||||
@ -211,12 +234,9 @@ const openGenSeedDataDialog = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 打开表增加页面
|
// 打开表增加页面
|
||||||
const openAddTable = () => {
|
const handleAddTable = () => {
|
||||||
if (state.configId == '') {
|
if (state.configId == '') {
|
||||||
ElMessage({
|
ElMessage({ type: 'error', message: `请选择库名!` });
|
||||||
type: 'error',
|
|
||||||
message: `请选择库名!`,
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var table: any = {
|
var table: any = {
|
||||||
@ -229,7 +249,7 @@ const openAddTable = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 打开列编辑页面
|
// 打开列编辑页面
|
||||||
const openEditColumn = (row: any) => {
|
const showEditColumn = (row: any) => {
|
||||||
var column: any = {
|
var column: any = {
|
||||||
configId: state.configId,
|
configId: state.configId,
|
||||||
tableName: row.tableName,
|
tableName: row.tableName,
|
||||||
@ -241,12 +261,9 @@ const openEditColumn = (row: any) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 打开列增加页面
|
// 打开列增加页面
|
||||||
const openAddColumn = () => {
|
const showAddColumn = () => {
|
||||||
if (state.configId == '' || state.tableName == '') {
|
if (state.configId == '' || state.tableName == '') {
|
||||||
ElMessage({
|
ElMessage({ type: 'error', message: `请选择库名和表名!` });
|
||||||
type: 'error',
|
|
||||||
message: `请选择库名和表名!`,
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const addRow: DbColumnInput = {
|
const addRow: DbColumnInput = {
|
||||||
@ -268,12 +285,9 @@ const openAddColumn = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 删除表
|
// 删除表
|
||||||
const delTable = () => {
|
const handleDeleteTable = () => {
|
||||||
if (state.tableName == '') {
|
if (state.tableName == '') {
|
||||||
ElMessage({
|
ElMessage({ type: 'error', message: `请选择表名!` });
|
||||||
type: 'error',
|
|
||||||
message: `请选择表名!`,
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ElMessageBox.confirm(`确定删除表:【${state.tableName}】?`, '提示', {
|
ElMessageBox.confirm(`确定删除表:【${state.tableName}】?`, '提示', {
|
||||||
@ -287,14 +301,14 @@ const delTable = () => {
|
|||||||
tableName: state.tableName,
|
tableName: state.tableName,
|
||||||
};
|
};
|
||||||
await getAPI(SysDatabaseApi).apiSysDatabaseDeleteTablePost(deleteDbTableInput);
|
await getAPI(SysDatabaseApi).apiSysDatabaseDeleteTablePost(deleteDbTableInput);
|
||||||
handleQueryTable();
|
await handleQueryTable();
|
||||||
ElMessage.success('表删除成功');
|
ElMessage.success('表删除成功');
|
||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 删除列
|
// 删除列
|
||||||
const delColumn = (row: any) => {
|
const handleDeleteColumn = (row: any) => {
|
||||||
ElMessageBox.confirm(`确定删除列:【${row.dbColumnName}】?`, '提示', {
|
ElMessageBox.confirm(`确定删除列:【${row.dbColumnName}】?`, '提示', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
@ -307,7 +321,7 @@ const delColumn = (row: any) => {
|
|||||||
dbColumnName: row.dbColumnName,
|
dbColumnName: row.dbColumnName,
|
||||||
};
|
};
|
||||||
await getAPI(SysDatabaseApi).apiSysDatabaseDeleteColumnPost(eleteDbColumnInput);
|
await getAPI(SysDatabaseApi).apiSysDatabaseDeleteColumnPost(eleteDbColumnInput);
|
||||||
handleQueryTable();
|
await handleQueryTable();
|
||||||
ElMessage.success('列删除成功');
|
ElMessage.success('列删除成功');
|
||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
@ -316,10 +330,7 @@ const delColumn = (row: any) => {
|
|||||||
// 可视化表
|
// 可视化表
|
||||||
const visualTable = () => {
|
const visualTable = () => {
|
||||||
if (state.configId == '') {
|
if (state.configId == '') {
|
||||||
ElMessage({
|
ElMessage({ type: 'error', message: `请选择库名!` });
|
||||||
type: 'error',
|
|
||||||
message: `请选择库名!`,
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
router.push(`/develop/database/visual?configId=${state.configId}`);
|
router.push(`/develop/database/visual?configId=${state.configId}`);
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-dictData-container">
|
<div class="sys-dictData-container">
|
||||||
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="700px">
|
<el-dialog v-model="state.visible" draggable overflow destroy-on-close width="700px">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div style="color: #fff">
|
<div style="color: #fff">
|
||||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
||||||
<span> {{ props.title }} </span>
|
<span> {{ props.title }} </span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
<el-form :model="state.ruleForm" ref="formRef" label-width="auto">
|
||||||
<el-row :gutter="35">
|
<el-row :gutter="10">
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||||
<el-form-item label="字典值" prop="value" :rules="[{ required: true, message: '字典值不能为空', trigger: 'blur' }]">
|
<el-form-item label="字典值" prop="value" :rules="[{ required: true, message: '字典值不能为空', trigger: 'blur' }]">
|
||||||
<el-input v-model="state.ruleForm.value" placeholder="字典值" clearable />
|
<el-input v-model="state.ruleForm.value" placeholder="字典值" clearable />
|
||||||
@ -31,7 +31,7 @@
|
|||||||
<el-radio value="success"><el-tag type="success">success</el-tag></el-radio>
|
<el-radio value="success"><el-tag type="success">success</el-tag></el-radio>
|
||||||
<el-radio value="info"><el-tag type="info">info</el-tag></el-radio>
|
<el-radio value="info"><el-tag type="info">info</el-tag></el-radio>
|
||||||
<el-radio value="warning"><el-tag type="warning">warning</el-tag></el-radio>
|
<el-radio value="warning"><el-tag type="warning">warning</el-tag></el-radio>
|
||||||
<el-radio value="danger"><el-tag type="danger" style="font:">danger</el-tag></el-radio>
|
<el-radio value="danger"><el-tag type="danger">danger</el-tag></el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
@ -92,9 +92,9 @@ const props = defineProps({
|
|||||||
dictTypeId: Number,
|
dictTypeId: Number,
|
||||||
});
|
});
|
||||||
const emits = defineEmits(['handleQuery', 'handleUpdate']);
|
const emits = defineEmits(['handleQuery', 'handleUpdate']);
|
||||||
const ruleFormRef = ref();
|
const formRef = ref();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
isShowDialog: false,
|
visible: false,
|
||||||
ruleForm: {} as UpdateDictDataInput,
|
ruleForm: {} as UpdateDictDataInput,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -104,24 +104,24 @@ const openDialog = (row: any) => {
|
|||||||
if (JSON.stringify(row) == '{}') {
|
if (JSON.stringify(row) == '{}') {
|
||||||
state.ruleForm.dictTypeId = props.dictTypeId;
|
state.ruleForm.dictTypeId = props.dictTypeId;
|
||||||
}
|
}
|
||||||
state.isShowDialog = true;
|
state.visible = true;
|
||||||
ruleFormRef.value?.resetFields();
|
formRef.value?.resetFields();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 关闭弹窗
|
// 关闭弹窗
|
||||||
const closeDialog = () => {
|
const closeDialog = () => {
|
||||||
emits('handleQuery');
|
emits('handleQuery');
|
||||||
state.isShowDialog = false;
|
state.visible = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 取消
|
// 取消
|
||||||
const cancel = () => {
|
const cancel = () => {
|
||||||
state.isShowDialog = false;
|
state.visible = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 提交
|
// 提交
|
||||||
const submit = () => {
|
const submit = () => {
|
||||||
ruleFormRef.value.validate(async (valid: boolean) => {
|
formRef.value.validate(async (valid: boolean) => {
|
||||||
if (!valid) return;
|
if (!valid) return;
|
||||||
if (state.ruleForm.id != undefined && state.ruleForm.id > 0) {
|
if (state.ruleForm.id != undefined && state.ruleForm.id > 0) {
|
||||||
await getAPI(SysDictDataApi).apiSysDictDataUpdatePost(state.ruleForm);
|
await getAPI(SysDictDataApi).apiSysDictDataUpdatePost(state.ruleForm);
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-dictType-container">
|
<div class="sys-dictType-container">
|
||||||
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="700px">
|
<el-dialog v-model="state.visible" draggable overflow destroy-on-close width="700px">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div style="color: #fff">
|
<div style="color: #fff">
|
||||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
||||||
<span> {{ props.title }} </span>
|
<span> {{ props.title }} </span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
<el-form :model="state.ruleForm" ref="formRef" label-width="auto">
|
||||||
<el-row :gutter="35">
|
<el-row :gutter="10">
|
||||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||||
<el-form-item label="字典名称" prop="name" :rules="[{ required: true, message: '字典名称不能为空', trigger: 'blur' }]">
|
<el-form-item label="字典名称" prop="name" :rules="[{ required: true, message: '字典名称不能为空', trigger: 'blur' }]">
|
||||||
<el-input v-model="state.ruleForm.name" placeholder="字典名称" clearable />
|
<el-input v-model="state.ruleForm.name" placeholder="字典名称" clearable />
|
||||||
@ -60,33 +60,33 @@ const props = defineProps({
|
|||||||
title: String,
|
title: String,
|
||||||
});
|
});
|
||||||
const emits = defineEmits(['handleQuery', 'handleUpdate']);
|
const emits = defineEmits(['handleQuery', 'handleUpdate']);
|
||||||
const ruleFormRef = ref();
|
const formRef = ref();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
isShowDialog: false,
|
visible: false,
|
||||||
ruleForm: {} as UpdateDictTypeInput,
|
ruleForm: {} as UpdateDictTypeInput,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 打开弹窗
|
// 打开弹窗
|
||||||
const openDialog = (row: any) => {
|
const openDialog = (row: any) => {
|
||||||
state.ruleForm = JSON.parse(JSON.stringify(row));
|
state.ruleForm = JSON.parse(JSON.stringify(row));
|
||||||
state.isShowDialog = true;
|
state.visible = true;
|
||||||
ruleFormRef.value?.resetFields();
|
formRef.value?.resetFields();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 关闭弹窗
|
// 关闭弹窗
|
||||||
const closeDialog = () => {
|
const closeDialog = () => {
|
||||||
emits('handleQuery');
|
emits('handleQuery');
|
||||||
state.isShowDialog = false;
|
state.visible = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 取消
|
// 取消
|
||||||
const cancel = () => {
|
const cancel = () => {
|
||||||
state.isShowDialog = false;
|
state.visible = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 提交
|
// 提交
|
||||||
const submit = () => {
|
const submit = () => {
|
||||||
ruleFormRef.value.validate(async (valid: boolean) => {
|
formRef.value.validate(async (valid: boolean) => {
|
||||||
if (!valid) return;
|
if (!valid) return;
|
||||||
if (state.ruleForm.id != undefined && state.ruleForm.id > 0) {
|
if (state.ruleForm.id != undefined && state.ruleForm.id > 0) {
|
||||||
await getAPI(SysDictTypeApi).apiSysDictTypeUpdatePost(state.ruleForm);
|
await getAPI(SysDictTypeApi).apiSysDictTypeUpdatePost(state.ruleForm);
|
||||||
|
|||||||
@ -1,279 +1,281 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-dict-container">
|
<div class="sys-dict-container" v-loading="options.loading">
|
||||||
<el-row :gutter="8" style="width: 100%; height: 100%; flex: 1">
|
<el-row :gutter="8" style="width: 100%; height: 100%; flex: 1">
|
||||||
<el-col :span="12" :xs="24" style="display: flex; height: 100%; flex: 1">
|
<el-col :span="12" :xs="24" class="full-height">
|
||||||
<el-card class="full-table" shadow="hover" :body-style="{ height: 'calc(100% - 51px)' }">
|
<el-card shadow="hover" :body-style="{ padding: '5px 5px 0 5px', display: 'flex', width: '100%', height: '100%', alignItems: 'start' }">
|
||||||
<template #header>
|
<el-form :model="state.queryParams" :show-message="false" :inlineMessage="true" :label-width="'60px'" style="flex: 1 1 0%">
|
||||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-Collection /></el-icon>字典
|
<el-row :gutter="10">
|
||||||
</template>
|
<el-col class="mb5" :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
|
||||||
<el-form :model="state.queryDictTypeParams" ref="queryForm" :inline="true" @submit.native.prevent>
|
<el-form-item label="字典名称" prop="name">
|
||||||
<el-form-item label="名称">
|
<el-input v-model="state.queryParams.name" placeholder="字典名称" clearable @keyup.enter.native="handleQuery(true)" />
|
||||||
<el-input v-model="state.queryDictTypeParams.name" @keyup.enter.native="handleDictTypeQuery" placeholder="字典名称" clearable />
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
<!-- <el-form-item label="字典编码">
|
<el-col class="mb5" :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
|
||||||
<el-input v-model="state.queryDictTypeParams.code" placeholder="字典编码" clearable />
|
<el-form-item label="字典编码" prop="code">
|
||||||
</el-form-item> -->
|
<el-input v-model="state.queryParams.code" placeholder="字典编码" clearable @keyup.enter.native="handleQuery(true)" />
|
||||||
<el-form-item>
|
</el-form-item>
|
||||||
<el-button-group>
|
</el-col>
|
||||||
<el-button type="primary" icon="ele-Search" @click="handleDictTypeQuery" v-auth="'sysDictType:page'"> 查询 </el-button>
|
</el-row>
|
||||||
<el-button icon="ele-Refresh" @click="resetDictTypeQuery"> 重置 </el-button>
|
|
||||||
</el-button-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="ele-Plus" @click="openAddDictType" v-auth="'sysDictType:add'"> 新增 </el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
</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="'sysDictType:page'" :loading="options.loading"> 查询 </el-button>
|
||||||
|
<el-button icon="ele-Refresh" @click="resetQuery" :loading="options.loading"> 重置 </el-button>
|
||||||
|
</el-button-group>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
<el-table :data="state.dictTypeData" style="width: 100%" v-loading="state.typeLoading" @row-click="handleDictType" highlight-current-row border>
|
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
|
||||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
<vxe-grid ref="xGrid" class="xGrid-style" v-bind="options" @sort-change="sortChange" @cell-click="handleDictData">
|
||||||
<el-table-column prop="name" label="字典名称" min-width="120" header-align="center" show-overflow-tooltip />
|
<template #toolbar_buttons>
|
||||||
<el-table-column prop="code" label="字典编码" min-width="140" header-align="center" show-overflow-tooltip />
|
<el-icon size="16" style="margin-right: 3px; margin-top: 2px; display: inline; vertical-align: middle"><ele-Collection /></el-icon>字典
|
||||||
<el-table-column prop="status" label="状态" width="70" align="center" show-overflow-tooltip>
|
<el-button type="primary" style="margin-left: 10px" icon="ele-Plus" @click="handleAdd" v-auth="'sysDictType:add'"> 新增 </el-button>
|
||||||
<template #default="scope">
|
</template>
|
||||||
<el-tag type="success" v-if="scope.row.status === 1">启用</el-tag>
|
<template #toolbar_tools> </template>
|
||||||
<el-tag type="danger" v-else>禁用</el-tag>
|
<template #empty>
|
||||||
</template>
|
<el-empty :image-size="200" />
|
||||||
</el-table-column>
|
</template>
|
||||||
<el-table-column prop="orderNo" label="排序" width="60" align="center" show-overflow-tooltip />
|
<template #row_status="{ row }">
|
||||||
<el-table-column label="修改记录" width="100" align="center" show-overflow-tooltip>
|
<el-tag v-if="row.status === 1" type="success">启用</el-tag>
|
||||||
<template #default="scope">
|
<el-tag v-else type="danger">禁用</el-tag>
|
||||||
<ModifyRecord :data="scope.row" />
|
</template>
|
||||||
</template>
|
<template #row_record="{ row }">
|
||||||
</el-table-column>
|
<ModifyRecord :data="row" />
|
||||||
<el-table-column label="操作" width="110" fixed="right" align="center">
|
</template>
|
||||||
<template #default="scope">
|
<template #row_buttons="{ row }">
|
||||||
<el-tooltip content="字典值">
|
<el-tooltip content="编辑" placement="top">
|
||||||
<el-button icon="ele-Memo" size="small" text type="primary" @click="openDictDataDialog(scope.row)" v-auth="'sysDictType:page'"> </el-button>
|
<el-button icon="ele-Edit" text type="primary" v-auth="'sysDictType:update'" @click="handleEdit(row)"> </el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip content="编辑">
|
<el-tooltip content="删除" placement="top">
|
||||||
<el-button icon="ele-Edit" size="small" text type="primary" @click="openEditDictType(scope.row)" v-auth="'sysDictType:update'"> </el-button>
|
<el-button icon="ele-Delete" text type="danger" v-auth="'sysDictType:delete'" @click="handleDelete(row)"> </el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip content="删除">
|
</template>
|
||||||
<el-button icon="ele-Delete" size="small" text type="danger" @click="delDictType(scope.row)" v-auth="'sysDictType:delete'"> </el-button>
|
<template #pager>
|
||||||
</el-tooltip>
|
<vxe-pager
|
||||||
</template>
|
:loading="options.loading"
|
||||||
</el-table-column>
|
v-model:current-page="state.tableParams.page"
|
||||||
</el-table>
|
v-model:page-size="state.tableParams.pageSize"
|
||||||
<el-pagination
|
:total="state.tableParams.total"
|
||||||
v-model:currentPage="state.tableDictTypeParams.page"
|
@page-change="pageChange"
|
||||||
v-model:page-size="state.tableDictTypeParams.pageSize"
|
/>
|
||||||
:total="state.tableDictTypeParams.total"
|
</template>
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
</vxe-grid>
|
||||||
small
|
|
||||||
background
|
|
||||||
@size-change="handleDictTypeSizeChange"
|
|
||||||
@current-change="handleDictTypeCurrentChange"
|
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
|
||||||
/>
|
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" :xs="24" style="display: flex; height: 100%; flex: 1">
|
<el-col :span="12" :xs="24" class="full-height">
|
||||||
<el-card class="full-table" shadow="hover" :body-style="{ height: 'calc(100% - 51px)' }">
|
<el-card shadow="hover" :body-style="{ padding: '5px 5px 0 5px', display: 'flex', width: '100%', height: '100%', alignItems: 'start' }">
|
||||||
<template #header>
|
<el-form :model="state.queryDictParams" :show-message="false" :inlineMessage="true" :label-width="'60px'" style="flex: 1 1 0%">
|
||||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-Collection /></el-icon>字典值【{{ state.editDictTypeName }}】
|
<el-row :gutter="10">
|
||||||
</template>
|
<el-col class="mb5" :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
|
||||||
<el-form :model="state.queryDictDataParams" ref="queryForm" :inline="true" @submit.native.prevent>
|
<el-form-item label="字典值" prop="value">
|
||||||
<!-- <el-form-item label="字典值">
|
<el-input v-model="state.queryDictParams.value" placeholder="字典值" clearable @keyup.enter.native="handleDictQuery(true)" />
|
||||||
<el-input v-model="state.queryDictDataParams.value" placeholder="字典值" />
|
</el-form-item>
|
||||||
</el-form-item> -->
|
</el-col>
|
||||||
<el-form-item label="编码">
|
<el-col class="mb5" :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
|
||||||
<el-input v-model="state.queryDictDataParams.code" placeholder="编码" @keyup.enter="handleDictDataQuery" />
|
<el-form-item label="编码" prop="code">
|
||||||
</el-form-item>
|
<el-input v-model="state.queryDictParams.code" placeholder="编码" clearable @keyup.enter.native="handleDictQuery(true)" />
|
||||||
<el-form-item>
|
</el-form-item>
|
||||||
<el-button-group>
|
</el-col>
|
||||||
<el-button type="primary" icon="ele-Search" @click="handleDictDataQuery"> 查询 </el-button>
|
</el-row>
|
||||||
<el-button icon="ele-Refresh" @click="resetDictDataQuery"> 重置 </el-button>
|
|
||||||
</el-button-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="ele-Plus" @click="openAddDictData"> 新增 </el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
</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="handleDictQuery(true)" v-auth="'sysDictType:page'" :loading="options.loading"> 查询 </el-button>
|
||||||
|
<el-button icon="ele-Refresh" @click="resetDictQuery" :loading="options.loading"> 重置 </el-button>
|
||||||
|
</el-button-group>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
<el-table :data="state.dictDataData" style="width: 100%" v-loading="state.loading" border>
|
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
|
||||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
<vxe-grid ref="xDictGrid" class="xGrid-style" v-bind="dictOptions" @sort-change="dictSortChange">
|
||||||
<el-table-column prop="value" label="字典值" header-align="center" min-width="120" show-overflow-tooltip>
|
<template #toolbar_buttons>
|
||||||
<template #default="scope">
|
<el-icon size="16" style="margin-right: 3px; margin-top: 2px; display: inline; vertical-align: middle"><ele-Collection /></el-icon>字典值
|
||||||
<el-tag :type="scope.row.tagType" :style="scope.row.styleSetting" :class="scope.row.classSetting">{{ scope.row.value }}</el-tag>
|
<el-button type="primary" style="margin-left: 10px" icon="ele-Plus" @click="handleDictAdd" v-auth="'sysDictType:add'"> 新增 </el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
<template #toolbar_tools> </template>
|
||||||
<el-table-column prop="code" label="编码" header-align="center" min-width="120" show-overflow-tooltip />
|
<template #empty>
|
||||||
<el-table-column prop="name" label="名称" header-align="center" min-width="120" show-overflow-tooltip />
|
<el-empty :image-size="200" />
|
||||||
<el-table-column prop="extData" label="拓展数据" width="90" align="center">
|
</template>
|
||||||
<template #default="scope">
|
<template #row_value="{ row }">
|
||||||
<el-tag type="warning" v-if="scope.row.extData == null || scope.row.extData == ''">空</el-tag>
|
<el-tag :type="row.tagType" :style="row.styleSetting" :class="row.classSetting">{{ row.value }}</el-tag>
|
||||||
<el-tag type="success" v-else>有值</el-tag>
|
</template>
|
||||||
</template>
|
<template #row_extData="{ row }">
|
||||||
</el-table-column>
|
<el-tag type="warning" v-if="row.extData == null || row.extData == ''">空</el-tag>
|
||||||
<el-table-column prop="status" label="状态" width="70" align="center" show-overflow-tooltip>
|
<el-tag type="success" v-else>有值</el-tag>
|
||||||
<template #default="scope">
|
</template>
|
||||||
<el-tag type="success" v-if="scope.row.status === 1">启用</el-tag>
|
<template #row_status="{ row }">
|
||||||
<el-tag type="danger" v-else>禁用</el-tag>
|
<el-tag v-if="row.status === 1" type="success">启用</el-tag>
|
||||||
</template>
|
<el-tag v-else type="danger">禁用</el-tag>
|
||||||
</el-table-column>
|
</template>
|
||||||
<el-table-column prop="orderNo" label="排序" width="60" align="center" show-overflow-tooltip />
|
<template #row_record="{ row }">
|
||||||
<el-table-column label="修改记录" width="100" align="center" show-overflow-tooltip>
|
<ModifyRecord :data="row" />
|
||||||
<template #default="scope">
|
</template>
|
||||||
<ModifyRecord :data="scope.row" />
|
<template #row_buttons="{ row }">
|
||||||
</template>
|
<el-tooltip content="编辑" placement="top">
|
||||||
</el-table-column>
|
<el-button icon="ele-Edit" text type="primary" v-auth="'sysDictType:update'" @click="handleDictEdit(row)"> </el-button>
|
||||||
<el-table-column label="操作" width="80" fixed="right" align="center" show-overflow-tooltip>
|
</el-tooltip>
|
||||||
<template #default="scope">
|
<el-tooltip content="删除" placement="top">
|
||||||
<el-tooltip content="编辑">
|
<el-button icon="ele-Delete" text type="danger" v-auth="'sysDictType:delete'" @click="handleDictDelete(row)"> </el-button>
|
||||||
<el-button icon="ele-Edit" size="small" text type="primary" @click="openEditDictData(scope.row)"> </el-button>
|
</el-tooltip>
|
||||||
</el-tooltip>
|
</template>
|
||||||
<el-tooltip content="删除">
|
<template #pager>
|
||||||
<el-button icon="ele-Delete" size="small" text type="danger" @click="delDictData(scope.row)"> </el-button>
|
<vxe-pager
|
||||||
</el-tooltip>
|
:loading="dictOptions.loading"
|
||||||
</template>
|
v-model:current-page="state.tableDictParams.page"
|
||||||
</el-table-column>
|
v-model:page-size="state.tableDictParams.pageSize"
|
||||||
</el-table>
|
:total="state.tableDictParams.total"
|
||||||
<el-pagination
|
@page-change="dictPageChange"
|
||||||
v-model:currentPage="state.tableDictDataParams.page"
|
/>
|
||||||
v-model:page-size="state.tableDictDataParams.pageSize"
|
</template>
|
||||||
:total="state.tableDictDataParams.total"
|
</vxe-grid>
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
|
||||||
small
|
|
||||||
background
|
|
||||||
@size-change="handleDictDataSizeChange"
|
|
||||||
@current-change="handleDictDataCurrentChange"
|
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
|
||||||
/>
|
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<EditDictType ref="editDictTypeRef" :title="state.editDictTypeTitle" @handleQuery="handleDictTypeQuery" @handleUpdate="updateDictSession" />
|
<EditDictType ref="editRef" :title="state.title" @handleQuery="handleQuery(false)" @handleUpdate="updateDictSession" />
|
||||||
<EditDictData ref="editDictDataRef" :title="state.editDictDataTitle" @handleQuery="handleDictDataQuery" @handleUpdate="updateDictSession" />
|
<EditDcitData ref="editDictRef" :title="state.title" @handleQuery="handleDictQuery(false)" @handleUpdate="updateDictSession" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup name="sysDict">
|
<script lang="ts" setup name="sysDict">
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
import { ElMessageBox, ElMessage } from 'element-plus';
|
import { ElMessageBox, ElMessage } from 'element-plus';
|
||||||
|
import { auth } from '/@/utils/authFunction';
|
||||||
|
import { VxeGridInstance, VxePagerEvents, VxePagerDefines } from 'vxe-table';
|
||||||
|
import { useVxeTable } from '/@/hooks/vxeTableOptionsHook';
|
||||||
|
import { useUserInfo } from '/@/stores/userInfo';
|
||||||
|
|
||||||
import EditDictType from '/@/views/system/dict/component/editDictType.vue';
|
import EditDictType from '/@/views/system/dict/component/editDictType.vue';
|
||||||
import EditDictData from '/@/views/system/dict/component/editDictData.vue';
|
import EditDcitData from '/@/views/system/dict/component/editDictData.vue';
|
||||||
import ModifyRecord from '/@/components/table/modifyRecord.vue';
|
import ModifyRecord from '/@/components/table/modifyRecord.vue';
|
||||||
|
|
||||||
import { getAPI } from '/@/utils/axios-utils';
|
import { getAPI } from '/@/utils/axios-utils';
|
||||||
import { Session } from '/@/utils/storage';
|
|
||||||
import { useUserInfo } from '/@/stores/userInfo';
|
|
||||||
import { SysDictTypeApi, SysDictDataApi } from '/@/api-services/api';
|
import { SysDictTypeApi, SysDictDataApi } from '/@/api-services/api';
|
||||||
import { SysDictType, SysDictData } from '/@/api-services/models';
|
import { SysDictType, SysDictData } from '/@/api-services/models';
|
||||||
|
|
||||||
const editDictTypeRef = ref<InstanceType<typeof EditDictType>>();
|
const xGrid = ref<VxeGridInstance>();
|
||||||
const editDictDataRef = ref<InstanceType<typeof EditDictData>>();
|
const xDictGrid = ref<VxeGridInstance>();
|
||||||
|
const editRef = ref<InstanceType<typeof EditDictType>>();
|
||||||
|
const editDictRef = ref<InstanceType<typeof EditDcitData>>();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
loading: false,
|
queryParams: {
|
||||||
typeLoading: false,
|
|
||||||
dictTypeData: [] as Array<SysDictType>,
|
|
||||||
dictDataData: [] as Array<SysDictData>,
|
|
||||||
queryDictTypeParams: {
|
|
||||||
name: undefined,
|
name: undefined,
|
||||||
code: undefined,
|
code: undefined,
|
||||||
},
|
},
|
||||||
tableDictTypeParams: {
|
queryDictParams: {
|
||||||
page: 1,
|
dictTypeId: undefined,
|
||||||
pageSize: 20,
|
|
||||||
total: 0 as any,
|
|
||||||
},
|
|
||||||
queryDictDataParams: {
|
|
||||||
value: undefined,
|
value: undefined,
|
||||||
code: undefined,
|
code: undefined,
|
||||||
dictTypeId: 0, // 字典类型Id
|
|
||||||
},
|
},
|
||||||
tableDictDataParams: {
|
tableParams: {
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 20,
|
pageSize: 50,
|
||||||
|
field: 'orderNo', // 默认的排序字段
|
||||||
|
order: 'aes', // 排序方向
|
||||||
|
descStr: 'desc', // 降序排序的关键字符
|
||||||
total: 0 as any,
|
total: 0 as any,
|
||||||
},
|
},
|
||||||
editDictTypeTitle: '',
|
tableDictParams: {
|
||||||
editDictDataTitle: '',
|
page: 1,
|
||||||
editDictTypeName: '',
|
pageSize: 50,
|
||||||
|
field: 'orderNo', // 默认的排序字段
|
||||||
|
order: 'aes', // 排序方向
|
||||||
|
descStr: 'desc', // 降序排序的关键字符
|
||||||
|
total: 0 as any,
|
||||||
|
},
|
||||||
|
title: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 表格参数配置-字典类型
|
||||||
|
const options = useVxeTable<SysDictType>(
|
||||||
|
{
|
||||||
|
id: 'sysDict',
|
||||||
|
name: '字典信息',
|
||||||
|
columns: [
|
||||||
|
{ type: 'seq', title: '序号', width: 60, fixed: 'left' },
|
||||||
|
{ field: 'name', title: '字典名称', minWidth: 140, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'code', title: '字典编码', minWidth: 140, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'orderNo', title: '排序', width: 80, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'status', title: '状态', width: 80, showOverflow: 'tooltip', slots: { default: 'row_status' } },
|
||||||
|
{ field: '', title: '修改记录', width: 100, showOverflow: 'tooltip', slots: { default: 'row_record' } },
|
||||||
|
{ title: '操作', fixed: 'right', width: 100, showOverflow: true, slots: { default: 'row_buttons' } },
|
||||||
|
],
|
||||||
|
enableExport: auth('sysDictType:export'),
|
||||||
|
searchCallback: () => handleQuery(),
|
||||||
|
queryAllCallback: () => fetchData({ pageSize: 99999 }),
|
||||||
|
},
|
||||||
|
{ rowConfig: { isCurrent: true, isHover: true }, checkboxConfig: { range: true, highlight: false } }
|
||||||
|
);
|
||||||
|
|
||||||
|
// 页面初始化
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
handleDictTypeQuery();
|
await handleQuery();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 查询字典操作
|
// 查询操作
|
||||||
const handleDictTypeQuery = async () => {
|
const handleQuery = async (reset = false) => {
|
||||||
state.typeLoading = true;
|
options.loading = true;
|
||||||
let params = Object.assign(state.queryDictTypeParams, state.tableDictTypeParams);
|
if (reset) state.tableParams.page = 1;
|
||||||
var res = await getAPI(SysDictTypeApi).apiSysDictTypePagePost(params);
|
var res = await fetchData(null);
|
||||||
state.dictTypeData = res.data.result?.items ?? [];
|
await xGrid.value?.loadData(res.data.result?.items ?? []);
|
||||||
state.tableDictTypeParams.total = res.data.result?.total;
|
state.tableParams.total = res.data.result?.total;
|
||||||
state.typeLoading = false;
|
options.loading = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 查询字典值操作
|
// 获取数据
|
||||||
const handleDictDataQuery = async () => {
|
const fetchData = async (tableParams: any) => {
|
||||||
state.loading = true;
|
let params = Object.assign(state.queryParams, state.tableParams, tableParams);
|
||||||
let params = Object.assign(state.queryDictDataParams, state.tableDictDataParams);
|
return getAPI(SysDictTypeApi).apiSysDictTypePagePost(params);
|
||||||
var res = await getAPI(SysDictDataApi).apiSysDictDataPagePost(params);
|
|
||||||
state.dictDataData = res.data.result?.items ?? [];
|
|
||||||
state.tableDictDataParams.total = res.data.result?.total;
|
|
||||||
state.loading = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 点击表格
|
// 重置操作
|
||||||
const handleDictType = (row: any, event: any, column: any) => {
|
const resetQuery = async () => {
|
||||||
openDictDataDialog(row);
|
state.queryParams.code = undefined;
|
||||||
|
state.queryParams.name = undefined;
|
||||||
|
await handleQuery(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 重置字典操作
|
// 改变页码序号或页面容量
|
||||||
const resetDictTypeQuery = () => {
|
const pageChange: VxePagerEvents.PageChange = async ({ currentPage, pageSize }: VxePagerDefines.PageChangeEventParams) => {
|
||||||
state.queryDictTypeParams.name = undefined;
|
state.tableParams.page = currentPage;
|
||||||
state.queryDictTypeParams.code = undefined;
|
state.tableParams.pageSize = pageSize;
|
||||||
handleDictTypeQuery();
|
await handleQuery();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 重置字典值操作
|
// 列排序
|
||||||
const resetDictDataQuery = () => {
|
const sortChange = async (options: any) => {
|
||||||
state.queryDictDataParams.value = undefined;
|
state.tableParams.field = options.field;
|
||||||
state.queryDictDataParams.code = undefined;
|
state.tableParams.order = options.order;
|
||||||
handleDictDataQuery();
|
await handleQuery();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开新增字典页面
|
// 打开新增页面
|
||||||
const openAddDictType = () => {
|
const handleAdd = () => {
|
||||||
state.editDictTypeTitle = '添加字典';
|
state.title = '添加字典';
|
||||||
editDictTypeRef.value?.openDialog({ status: 1, orderNo: 100 });
|
editRef.value?.openDialog({ status: 1, orderNo: 100 });
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开新增字典值页面
|
// 打开编辑页面
|
||||||
const openAddDictData = () => {
|
const handleEdit = (row: any) => {
|
||||||
if (!state.queryDictDataParams.dictTypeId) {
|
state.title = '编辑字典';
|
||||||
ElMessage.warning('请选择字典');
|
editRef.value?.openDialog(row);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
state.editDictDataTitle = '添加字典值';
|
|
||||||
editDictDataRef.value?.openDialog({ status: 1, orderNo: 100, dictTypeId: state.queryDictDataParams.dictTypeId });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开编辑字典页面
|
// 点击表格,加载字典值表格数据
|
||||||
const openEditDictType = (row: any) => {
|
const handleDictData = async (scope: any) => {
|
||||||
state.editDictTypeTitle = '编辑字典';
|
state.queryDictParams.dictTypeId = scope.row.id;
|
||||||
editDictTypeRef.value?.openDialog(row);
|
await handleDictQuery(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开编辑字典值页面
|
// 删除
|
||||||
const openEditDictData = (row: any) => {
|
const handleDelete = (row: any) => {
|
||||||
state.editDictDataTitle = '编辑字典值';
|
|
||||||
editDictDataRef.value?.openDialog(row);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 打开字典值页面
|
|
||||||
const openDictDataDialog = (row: any) => {
|
|
||||||
state.editDictTypeName = row.name;
|
|
||||||
state.queryDictDataParams.dictTypeId = row.id;
|
|
||||||
handleDictDataQuery();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 删除字典
|
|
||||||
const delDictType = (row: any) => {
|
|
||||||
ElMessageBox.confirm(`确定删除字典:【${row.name}】?`, '提示', {
|
ElMessageBox.confirm(`确定删除字典:【${row.name}】?`, '提示', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
@ -281,15 +283,78 @@ const delDictType = (row: any) => {
|
|||||||
})
|
})
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
await getAPI(SysDictTypeApi).apiSysDictTypeDeletePost({ id: row.id });
|
await getAPI(SysDictTypeApi).apiSysDictTypeDeletePost({ id: row.id });
|
||||||
handleDictTypeQuery();
|
handleQuery();
|
||||||
updateDictSession();
|
updateDictSession();
|
||||||
|
xDictGrid.value?.loadData([]);
|
||||||
|
state.tableDictParams.total = 0;
|
||||||
ElMessage.success('删除成功');
|
ElMessage.success('删除成功');
|
||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 删除字典值
|
// 表格参数配置-字典值
|
||||||
const delDictData = (row: any) => {
|
const dictOptions = useVxeTable<SysDictData>(
|
||||||
|
{
|
||||||
|
id: 'dictInfo',
|
||||||
|
name: '字典值信息',
|
||||||
|
columns: [
|
||||||
|
{ type: 'seq', title: '序号', width: 60, fixed: 'left' },
|
||||||
|
{ field: 'value', title: '字典值', minWidth: 90, showOverflow: 'tooltip', slots: { default: 'row_value' } },
|
||||||
|
{ field: 'code', title: '编码', minWidth: 120, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'name', title: '名称', minWidth: 120, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'extData', title: '拓展数据', showOverflow: 'tooltip', slots: { default: 'row_extData' } },
|
||||||
|
{ field: 'orderNo', title: '排序', width: 80, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'status', title: '状态', width: 80, showOverflow: 'tooltip', slots: { default: 'row_status' } },
|
||||||
|
{ field: '', title: '修改记录', width: 100, showOverflow: 'tooltip', slots: { default: 'row_record' } },
|
||||||
|
{ title: '操作', fixed: 'right', width: 100, showOverflow: true, slots: { default: 'row_buttons' } },
|
||||||
|
],
|
||||||
|
enableExport: auth('sysDictType:export'),
|
||||||
|
searchCallback: () => handleDictQuery(),
|
||||||
|
queryAllCallback: () => fetchDictData({ pageSize: 99999 }),
|
||||||
|
},
|
||||||
|
{ loading: false, rowConfig: { isCurrent: true, isHover: true }, checkboxConfig: { range: true, highlight: false } }
|
||||||
|
);
|
||||||
|
|
||||||
|
// 查询操作
|
||||||
|
const handleDictQuery = async (reset = false) => {
|
||||||
|
dictOptions.loading = true;
|
||||||
|
if (reset) state.tableDictParams.page = 1;
|
||||||
|
var res = await fetchDictData(null);
|
||||||
|
xDictGrid.value?.loadData(res.data.result?.items ?? []);
|
||||||
|
state.tableDictParams.total = res.data.result?.total;
|
||||||
|
dictOptions.loading = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取数据
|
||||||
|
const fetchDictData = async (tableParams: any) => {
|
||||||
|
let params = Object.assign(state.queryDictParams, state.tableDictParams, tableParams);
|
||||||
|
return getAPI(SysDictDataApi).apiSysDictDataPagePost(params);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 重置操作
|
||||||
|
const resetDictQuery = async () => {
|
||||||
|
state.queryDictParams.value = undefined;
|
||||||
|
state.queryDictParams.code = undefined;
|
||||||
|
await handleDictQuery(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDictAdd = () => {
|
||||||
|
if (!state.queryDictParams.dictTypeId) {
|
||||||
|
ElMessage.warning('请选择字典');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state.title = '添加字典值';
|
||||||
|
editDictRef.value?.openDialog({ status: 1, orderNo: 100, dictTypeId: state.queryDictParams.dictTypeId });
|
||||||
|
};
|
||||||
|
|
||||||
|
// 打开编辑页面
|
||||||
|
const handleDictEdit = (row: any) => {
|
||||||
|
state.title = '编辑字典值';
|
||||||
|
editDictRef.value?.openDialog(row);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
const handleDictDelete = (row: any) => {
|
||||||
ElMessageBox.confirm(`确定删除字典值:【${row.value}】?`, '提示', {
|
ElMessageBox.confirm(`确定删除字典值:【${row.value}】?`, '提示', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
@ -297,35 +362,25 @@ const delDictData = (row: any) => {
|
|||||||
})
|
})
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
await getAPI(SysDictDataApi).apiSysDictDataDeletePost({ id: row.id });
|
await getAPI(SysDictDataApi).apiSysDictDataDeletePost({ id: row.id });
|
||||||
handleDictDataQuery();
|
handleDictQuery();
|
||||||
updateDictSession();
|
updateDictSession();
|
||||||
ElMessage.success('删除成功');
|
ElMessage.success('删除成功');
|
||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 改变字典页面容量
|
// 改变字典值页码序号或页面容量
|
||||||
const handleDictTypeSizeChange = (val: number) => {
|
const dictPageChange: VxePagerEvents.PageChange = async ({ currentPage, pageSize }: VxePagerDefines.PageChangeEventParams) => {
|
||||||
state.tableDictTypeParams.pageSize = val;
|
state.tableDictParams.page = currentPage;
|
||||||
handleDictTypeQuery();
|
state.tableDictParams.pageSize = pageSize;
|
||||||
|
await handleDictQuery();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 改变字典页码序号
|
// 字典值列排序
|
||||||
const handleDictTypeCurrentChange = (val: number) => {
|
const dictSortChange = async (options: any) => {
|
||||||
state.tableDictTypeParams.page = val;
|
state.tableDictParams.field = options.field;
|
||||||
handleDictTypeQuery();
|
state.tableDictParams.order = options.order;
|
||||||
};
|
await handleDictQuery();
|
||||||
|
|
||||||
// 改变字典值页面容量
|
|
||||||
const handleDictDataSizeChange = (val: number) => {
|
|
||||||
state.tableDictDataParams.pageSize = val;
|
|
||||||
handleDictDataQuery();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 改变字典值页码序号
|
|
||||||
const handleDictDataCurrentChange = (val: number) => {
|
|
||||||
state.tableDictDataParams.page = val;
|
|
||||||
handleDictDataQuery();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 更新前端字典缓存
|
// 更新前端字典缓存
|
||||||
@ -337,3 +392,11 @@ const updateDictSession = async () => {
|
|||||||
await useUserInfo().setDictList();
|
await useUserInfo().setDictList();
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.full-height {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-file-container">
|
<div class="sys-file-container">
|
||||||
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="500px">
|
<el-dialog v-model="state.isShowDialog" draggable overflow destroy-on-close width="500px">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div style="color: #fff">
|
<div style="color: #fff">
|
||||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
||||||
|
|||||||
@ -1,89 +1,90 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-file-container">
|
<div class="sys-file-container" v-loading="options.loading">
|
||||||
<el-card shadow="hover" :body-style="{ paddingBottom: '0' }">
|
<el-card shadow="hover" :body-style="{ padding: '5px 5px 0 5px', display: 'flex', width: '100%', height: '100%', alignItems: 'start' }">
|
||||||
<el-form :model="state.queryParams" ref="queryForm" :inline="true">
|
<el-form :model="state.queryParams" ref="queryForm" :show-message="false" :inlineMessage="true" :label-width="'60px'" style="flex: 1 1 0%">
|
||||||
<el-form-item label="文件名称" prop="fileName">
|
<el-row :gutter="10">
|
||||||
<el-input v-model="state.queryParams.fileName" placeholder="文件名称" clearable />
|
<el-col class="mb5" :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
|
||||||
</el-form-item>
|
<el-form-item label="文件名称" prop="fileName">
|
||||||
<el-form-item label="开始时间" prop="name">
|
<el-input v-model="state.queryParams.fileName" placeholder="文件名称" clearable @keyup.enter.native="handleQuery(true)" />
|
||||||
<el-date-picker v-model="state.queryParams.startTime" type="datetime" placeholder="开始时间" value-format="YYYY-MM-DD HH:mm:ss" />
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
<el-form-item label="结束时间" prop="code">
|
<el-col class="mb5" :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
|
||||||
<el-date-picker v-model="state.queryParams.endTime" type="datetime" placeholder="结束时间" value-format="YYYY-MM-DD HH:mm:ss" />
|
<el-form-item label="开始时间" prop="name">
|
||||||
</el-form-item>
|
<el-date-picker v-model="state.queryParams.startTime" type="datetime" placeholder="开始时间" value-format="YYYY-MM-DD HH:mm:ss" />
|
||||||
<el-form-item>
|
</el-form-item>
|
||||||
<el-button-group>
|
</el-col>
|
||||||
<el-button type="primary" icon="ele-Search" @click="handleQuery" v-auth="'sysFile:page'"> 查询 </el-button>
|
<el-col class="mb5" :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
|
||||||
<el-button icon="ele-Refresh" @click="resetQuery"> 重置 </el-button>
|
<el-form-item label="结束时间" prop="code">
|
||||||
</el-button-group>
|
<el-date-picker v-model="state.queryParams.endTime" type="datetime" placeholder="结束时间" value-format="YYYY-MM-DD HH:mm:ss" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
</el-col>
|
||||||
<el-button type="primary" icon="ele-Plus" @click="openUploadDialog" v-auth="'sysFile:uploadFile'"> 上传 </el-button>
|
</el-row>
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
</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="'sysFile:page'" :loading="options.loading"> 查询 </el-button>
|
||||||
|
<el-button icon="ele-Refresh" @click="resetQuery" :loading="options.loading"> 重置 </el-button>
|
||||||
|
</el-button-group>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
|
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
|
||||||
<el-table :data="state.fileData" style="width: 100%" v-loading="state.loading" border>
|
<vxe-grid ref="xGrid" class="xGrid-style" v-bind="options" @sort-change="sortChange">
|
||||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
<template #toolbar_buttons>
|
||||||
<el-table-column prop="fileName" label="名称" min-width="150" header-align="center" show-overflow-tooltip />
|
<el-button type="primary" icon="ele-Plus" @click="showUpload" v-auth="'sysFile:uploadFile'"> 上传 </el-button>
|
||||||
<el-table-column prop="suffix" label="后缀" align="center" show-overflow-tooltip>
|
</template>
|
||||||
<template #default="scope">
|
<template #toolbar_tools> </template>
|
||||||
<el-tag round>{{ scope.row.suffix }}</el-tag>
|
<template #empty>
|
||||||
</template>
|
<el-empty :image-size="200" />
|
||||||
</el-table-column>
|
</template>
|
||||||
<el-table-column prop="sizeKb" label="大小kb" align="center" show-overflow-tooltip />
|
<template #row_suffix="{ row }">
|
||||||
<el-table-column prop="url" label="预览" align="center">
|
<el-tag round>{{ row.suffix }}</el-tag>
|
||||||
<template #default="scope">
|
</template>
|
||||||
<el-image
|
<template #row_url="{ row }">
|
||||||
style="width: 60px; height: 60px"
|
<el-image
|
||||||
:src="getFileUrl(scope.row)"
|
style="width: 60px; height: 60px"
|
||||||
alt="无法预览"
|
:src="fetchFileUrl(row)"
|
||||||
:lazy="true"
|
alt="无法预览"
|
||||||
:hide-on-click-modal="true"
|
lazy
|
||||||
:preview-src-list="[getFileUrl(scope.row)]"
|
hide-on-click-modal
|
||||||
:initial-index="0"
|
:preview-src-list="[fetchFileUrl(row)]"
|
||||||
fit="scale-down"
|
:initial-index="0"
|
||||||
preview-teleported
|
fit="scale-down"
|
||||||
>
|
preview-teleported
|
||||||
<template #error> </template>
|
></el-image>
|
||||||
</el-image>
|
</template>
|
||||||
</template>
|
<template #row_buttons="{ row }">
|
||||||
</el-table-column>
|
<el-tooltip content="编辑" placement="top">
|
||||||
<el-table-column prop="bucketName" label="存储位置" align="center" show-overflow-tooltip />
|
<el-button icon="ele-Edit" size="small" text type="primary" @click="handleEdit(row)" v-auth="'sysFile:update'" />
|
||||||
<el-table-column prop="id" label="存储标识" align="center" show-overflow-tooltip />
|
</el-tooltip>
|
||||||
<el-table-column prop="fileType" label="文件类型" min-width="100" header-align="center" show-overflow-tooltip />
|
<el-tooltip content="删除" placement="top">
|
||||||
<el-table-column type="relationName" label="关联对象名称" min-width="150" align="center" />
|
<el-button icon="ele-Delete" size="small" text type="danger" @click="handleDelete(row)" v-auth="'sysFile:delete'" />
|
||||||
<el-table-column type="relationId" label="关联对象Id" align="center" />
|
</el-tooltip>
|
||||||
<el-table-column type="belongId" label="所属Id" align="center" />
|
<el-tooltip content="预览" placement="top">
|
||||||
<el-table-column label="修改记录" width="100" align="center" show-overflow-tooltip>
|
<el-button icon="ele-View" size="small" text type="primary" @click="showPreviewDialog(row)" v-auth="'sysFile:delete'" />
|
||||||
<template #default="scope">
|
</el-tooltip>
|
||||||
<ModifyRecord :data="scope.row" />
|
<el-tooltip content="下载" placement="top">
|
||||||
</template>
|
<el-button icon="ele-Download" size="small" text type="primary" @click="handleDownload(row)" v-auth="'sysFile:downloadFile'" />
|
||||||
</el-table-column>
|
</el-tooltip>
|
||||||
<el-table-column label="操作" width="260" fixed="right" align="center" show-overflow-tooltip>
|
</template>
|
||||||
<template #default="scope">
|
<template #pager>
|
||||||
<el-button icon="ele-View" size="small" text type="primary" @click="openFilePreviewDialog(scope.row)" v-auth="'sysFile:delete'"> 预览 </el-button>
|
<vxe-pager
|
||||||
<el-button icon="ele-Download" size="small" text type="primary" @click="downloadFile(scope.row)" v-auth="'sysFile:downloadFile'"> 下载 </el-button>
|
:loading="options.loading"
|
||||||
<el-button icon="ele-Delete" size="small" text type="danger" @click="delFile(scope.row)" v-auth="'sysFile:delete'"> 删除 </el-button>
|
v-model:current-page="state.tableParams.page"
|
||||||
<el-button icon="ele-Edit" size="small" text type="primary" @click="openEditSysFile(scope.row)" v-auth="'sysFile:update'"> 编辑 </el-button>
|
v-model:page-size="state.tableParams.pageSize"
|
||||||
</template>
|
:total="state.tableParams.total"
|
||||||
</el-table-column>
|
@page-change="pageChange"
|
||||||
</el-table>
|
/>
|
||||||
<el-pagination
|
</template>
|
||||||
v-model:currentPage="state.tableParams.page"
|
</vxe-grid>
|
||||||
v-model:page-size="state.tableParams.pageSize"
|
|
||||||
:total="state.tableParams.total"
|
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
|
||||||
small
|
|
||||||
background
|
|
||||||
@size-change="handleSizeChange"
|
|
||||||
@current-change="handleCurrentChange"
|
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
|
||||||
/>
|
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-dialog v-model="state.dialogUploadVisible" :lock-scroll="false" draggable width="400px">
|
<el-dialog v-model="state.visible" :lock-scroll="false" draggable overflow destroy-on-close width="400px">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div style="color: #fff">
|
<div style="color: #fff">
|
||||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-UploadFilled /> </el-icon>
|
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-UploadFilled /> </el-icon>
|
||||||
@ -108,49 +109,50 @@
|
|||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button @click="state.dialogUploadVisible = false">取消</el-button>
|
<el-button @click="state.visible = false">取消</el-button>
|
||||||
<el-button type="primary" @click="uploadFile">确定</el-button>
|
<el-button type="primary" @click="handleUpload">确定</el-button>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<el-drawer :title="state.fileName" v-model="state.dialogDocxVisible" size="50%" destroy-on-close>
|
<el-drawer :title="state.fileName" v-model="state.docxVisible" size="70%" destroy-on-close>
|
||||||
<vue-office-docx :src="state.docxUrl" style="height: 100vh" @rendered="renderedHandler" @error="errorHandler" />
|
<vue-office-docx :src="state.docxUrl" style="height: calc(100vh - 37px)" @rendered="handleRendered" @error="handleError" />
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
<el-drawer :title="state.fileName" v-model="state.dialogXlsxVisible" size="50%" destroy-on-close>
|
<el-drawer :title="state.fileName" v-model="state.xlsxVisible" size="70%" destroy-on-close>
|
||||||
<vue-office-excel :src="state.excelUrl" style="height: 100vh" @rendered="renderedHandler" @error="errorHandler" />
|
<vue-office-excel :src="state.excelUrl" style="height: calc(100vh - 37px)" @rendered="handleRendered" @error="handleError" />
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
<el-drawer :title="state.fileName" v-model="state.dialogPdfVisible" size="50%" destroy-on-close>
|
<el-drawer :title="state.fileName" v-model="state.pdfVisible" size="70%" destroy-on-close>
|
||||||
<vue-office-pdf :src="state.pdfUrl" style="height: 100vh" @rendered="renderedHandler" @error="errorHandler" />
|
<vue-office-pdf :src="state.pdfUrl" style="height: calc(100vh - 37px)" @rendered="handleRendered" @error="handleError" />
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
<el-image-viewer v-if="state.showViewer" :url-list="state.previewList" :hideOnClickModal="true" @close="state.showViewer = false"></el-image-viewer>
|
<el-image-viewer v-if="state.showViewer" :url-list="state.previewList" :hideOnClickModal="true" @close="state.showViewer = false"></el-image-viewer>
|
||||||
<EditSysFile ref="editSysFileRef" title="编辑文件" @handleQuery="handleQuery" />
|
<EditFile ref="editRef" title="编辑文件" @handleQuery="handleQuery" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup name="sysFile">
|
<script lang="ts" setup name="sysFile">
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
import { ElMessageBox, ElMessage, UploadInstance } from 'element-plus';
|
import { ElMessageBox, ElMessage, UploadInstance } from 'element-plus';
|
||||||
|
import { auth } from '/@/utils/authFunction';
|
||||||
|
import { VxeGridInstance, VxePagerEvents, VxePagerDefines } from 'vxe-table';
|
||||||
|
import { useVxeTable } from '/@/hooks/vxeTableOptionsHook';
|
||||||
|
import { downloadByUrl } from '/@/utils/download';
|
||||||
import VueOfficeDocx from '@vue-office/docx';
|
import VueOfficeDocx from '@vue-office/docx';
|
||||||
import VueOfficeExcel from '@vue-office/excel';
|
import VueOfficeExcel from '@vue-office/excel';
|
||||||
import VueOfficePdf from '@vue-office/pdf';
|
import VueOfficePdf from '@vue-office/pdf';
|
||||||
import '@vue-office/docx/lib/index.css';
|
import '@vue-office/docx/lib/index.css';
|
||||||
import '@vue-office/excel/lib/index.css';
|
import '@vue-office/excel/lib/index.css';
|
||||||
|
|
||||||
import EditSysFile from '/@/views/system/file/component/editSysfile.vue';
|
import EditFile from '/@/views/system/file/component/editSysfile.vue';
|
||||||
import ModifyRecord from '/@/components/table/modifyRecord.vue';
|
|
||||||
|
|
||||||
import { downloadByUrl } from '/@/utils/download';
|
|
||||||
import { getAPI } from '/@/utils/axios-utils';
|
import { getAPI } from '/@/utils/axios-utils';
|
||||||
import { SysFileApi } from '/@/api-services/api';
|
import { SysFileApi } from '/@/api-services/api';
|
||||||
import { SysFile } from '/@/api-services/models';
|
import { SysFile } from '/@/api-services/models';
|
||||||
|
|
||||||
|
const xGrid = ref<VxeGridInstance>();
|
||||||
// const baseUrl = window.__env__.VITE_API_URL;
|
// const baseUrl = window.__env__.VITE_API_URL;
|
||||||
const uploadRef = ref<UploadInstance>();
|
const uploadRef = ref<UploadInstance>();
|
||||||
const editSysFileRef = ref<InstanceType<typeof EditSysFile>>();
|
const editRef = ref<InstanceType<typeof EditFile>>();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
loading: false,
|
|
||||||
fileData: [] as Array<SysFile>,
|
|
||||||
queryParams: {
|
queryParams: {
|
||||||
fileName: undefined,
|
fileName: undefined,
|
||||||
startTime: undefined,
|
startTime: undefined,
|
||||||
@ -158,15 +160,18 @@ const state = reactive({
|
|||||||
},
|
},
|
||||||
tableParams: {
|
tableParams: {
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 10,
|
pageSize: 50,
|
||||||
|
field: 'id', // 默认的排序字段
|
||||||
|
order: 'aes', // 排序方向
|
||||||
|
descStr: 'desc', // 降序排序的关键字符
|
||||||
total: 0 as any,
|
total: 0 as any,
|
||||||
},
|
},
|
||||||
dialogUploadVisible: false,
|
visible: false,
|
||||||
diaglogEditFile: false,
|
diaglogEditFile: false,
|
||||||
fileList: [] as any,
|
fileList: [] as any,
|
||||||
dialogDocxVisible: false,
|
docxVisible: false,
|
||||||
dialogXlsxVisible: false,
|
xlsxVisible: false,
|
||||||
dialogPdfVisible: false,
|
pdfVisible: false,
|
||||||
showViewer: false,
|
showViewer: false,
|
||||||
docxUrl: '',
|
docxUrl: '',
|
||||||
excelUrl: '',
|
excelUrl: '',
|
||||||
@ -176,21 +181,55 @@ const state = reactive({
|
|||||||
previewList: [] as string[],
|
previewList: [] as string[],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 表格参数配置
|
||||||
|
const options = useVxeTable<SysFile>(
|
||||||
|
{
|
||||||
|
id: 'sysFile',
|
||||||
|
name: '文件信息',
|
||||||
|
columns: [
|
||||||
|
// { type: 'checkbox', width: 40, fixed: 'left' },
|
||||||
|
{ type: 'seq', title: '序号', width: 60, fixed: 'left' },
|
||||||
|
{ field: 'fileName', title: '名称', minWidth: 200, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'suffix', title: '后缀', minWidth: 80, showOverflow: 'tooltip', slots: { default: 'row_suffix' } },
|
||||||
|
{ field: 'sizeKb', title: '大小(KB)', minWidth: 100, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'url', title: '预览', minWidth: 100, slots: { default: 'row_url' } },
|
||||||
|
{ field: 'bucketName', title: '存储位置', minWidth: 180, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'id', title: '存储标识', minWidth: 120, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'fileType', title: '文件类型', minWidth: 140, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'relationName', title: '关联对象名称', minWidth: 150, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'relationId', title: '关联对象ID', minWidth: 150, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'belongId', title: '所属ID', minWidth: 120, showOverflow: 'tooltip' },
|
||||||
|
// { field: 'userName', title: '上传者', minWidth: 150, showOverflow: 'tooltip', sortable: true },
|
||||||
|
{ field: 'createTime', title: '创建时间', minWidth: 150, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'remark', title: '备注', minWidth: 200, showOverflow: 'tooltip' },
|
||||||
|
{ title: '操作', fixed: 'right', width: 150, showOverflow: true, slots: { default: 'row_buttons' } },
|
||||||
|
],
|
||||||
|
enableExport: auth('sysFile:export'),
|
||||||
|
searchCallback: () => handleQuery(),
|
||||||
|
queryAllCallback: () => fetchData({ pageSize: 99999 }),
|
||||||
|
},
|
||||||
|
{ rowConfig: { height: 80 } }
|
||||||
|
);
|
||||||
|
|
||||||
|
// 页面初始化
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
handleQuery();
|
await handleQuery();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 查询操作
|
// 查询操作
|
||||||
const handleQuery = async () => {
|
const handleQuery = async (reset = false) => {
|
||||||
if (state.queryParams.startTime == null) state.queryParams.startTime = undefined;
|
options.loading = true;
|
||||||
if (state.queryParams.endTime == null) state.queryParams.endTime = undefined;
|
if (reset) state.tableParams.page = 1;
|
||||||
|
var res = await fetchData(null);
|
||||||
state.loading = true;
|
xGrid.value?.loadData(res.data.result?.items ?? []);
|
||||||
let params = Object.assign(state.queryParams, state.tableParams);
|
|
||||||
var res = await getAPI(SysFileApi).apiSysFilePagePost(params);
|
|
||||||
state.fileData = res.data.result?.items ?? [];
|
|
||||||
state.tableParams.total = res.data.result?.total;
|
state.tableParams.total = res.data.result?.total;
|
||||||
state.loading = false;
|
options.loading = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取数据
|
||||||
|
const fetchData = async (tableParams: any) => {
|
||||||
|
let params = Object.assign(state.queryParams, state.tableParams, tableParams);
|
||||||
|
return getAPI(SysFileApi).apiSysFilePagePost(params);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 重置操作
|
// 重置操作
|
||||||
@ -198,13 +237,27 @@ const resetQuery = () => {
|
|||||||
state.queryParams.fileName = undefined;
|
state.queryParams.fileName = undefined;
|
||||||
state.queryParams.startTime = undefined;
|
state.queryParams.startTime = undefined;
|
||||||
state.queryParams.endTime = undefined;
|
state.queryParams.endTime = undefined;
|
||||||
|
handleQuery(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 改变页码序号或页面容量
|
||||||
|
const pageChange: VxePagerEvents.PageChange = ({ currentPage, pageSize }: VxePagerDefines.PageChangeEventParams) => {
|
||||||
|
state.tableParams.page = currentPage;
|
||||||
|
state.tableParams.pageSize = pageSize;
|
||||||
|
handleQuery();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 列排序
|
||||||
|
const sortChange = (options: any) => {
|
||||||
|
state.tableParams.field = options.field;
|
||||||
|
state.tableParams.order = options.order;
|
||||||
handleQuery();
|
handleQuery();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开上传页面
|
// 打开上传页面
|
||||||
const openUploadDialog = () => {
|
const showUpload = () => {
|
||||||
state.fileList = [];
|
state.fileList = [];
|
||||||
state.dialogUploadVisible = true;
|
state.visible = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 通过onChanne方法获得文件列表
|
// 通过onChanne方法获得文件列表
|
||||||
@ -213,23 +266,23 @@ const handleChange = (file: any, fileList: []) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 上传
|
// 上传
|
||||||
const uploadFile = async () => {
|
const handleUpload = async () => {
|
||||||
if (state.fileList.length < 1) return;
|
if (state.fileList.length < 1) return;
|
||||||
await getAPI(SysFileApi).apiSysFileUploadFilePostForm(state.fileList[0].raw, state.fileType, undefined);
|
await getAPI(SysFileApi).apiSysFileUploadFilePostForm(state.fileList[0].raw, state.fileType, undefined);
|
||||||
handleQuery();
|
handleQuery();
|
||||||
ElMessage.success('上传成功');
|
ElMessage.success('上传成功');
|
||||||
state.dialogUploadVisible = false;
|
state.visible = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 下载
|
// 下载
|
||||||
const downloadFile = async (row: any) => {
|
const handleDownload = async (row: any) => {
|
||||||
// var res = await getAPI(SysFileApi).sysFileDownloadPost({ id: row.id });
|
// var res = await getAPI(SysFileApi).sysFileDownloadPost({ id: row.id });
|
||||||
var fileUrl = getFileUrl(row);
|
var fileUrl = fetchFileUrl(row);
|
||||||
downloadByUrl({ url: fileUrl });
|
downloadByUrl({ url: fileUrl });
|
||||||
};
|
};
|
||||||
|
|
||||||
// 删除
|
// 删除
|
||||||
const delFile = (row: any) => {
|
const handleDelete = (row: any) => {
|
||||||
ElMessageBox.confirm(`确定删除文件:【${row.fileName}】?`, '提示', {
|
ElMessageBox.confirm(`确定删除文件:【${row.fileName}】?`, '提示', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
@ -243,42 +296,30 @@ const delFile = (row: any) => {
|
|||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开文件预览页面
|
// 打开Pdf预览页面
|
||||||
const openFilePreviewDialog = async (row: any) => {
|
const showPreviewDialog = async (row: any) => {
|
||||||
if (row.suffix == '.pdf') {
|
if (row.suffix == '.pdf') {
|
||||||
state.fileName = `【${row.fileName}${row.suffix}】`;
|
state.fileName = `【${row.fileName}${row.suffix}】`;
|
||||||
state.pdfUrl = getFileUrl(row);
|
state.pdfUrl = fetchFileUrl(row);
|
||||||
state.dialogPdfVisible = true;
|
state.pdfVisible = true;
|
||||||
} else if (row.suffix == '.docx') {
|
} else if (row.suffix == '.docx') {
|
||||||
state.fileName = `【${row.fileName}${row.suffix}】`;
|
state.fileName = `【${row.fileName}${row.suffix}】`;
|
||||||
state.docxUrl = getFileUrl(row);
|
state.docxUrl = fetchFileUrl(row);
|
||||||
state.dialogDocxVisible = true;
|
state.docxVisible = true;
|
||||||
} else if (row.suffix == '.xlsx') {
|
} else if (row.suffix == '.xlsx') {
|
||||||
state.fileName = `【${row.fileName}${row.suffix}】`;
|
state.fileName = `【${row.fileName}${row.suffix}】`;
|
||||||
state.excelUrl = getFileUrl(row);
|
state.excelUrl = fetchFileUrl(row);
|
||||||
state.dialogXlsxVisible = true;
|
state.xlsxVisible = true;
|
||||||
} else if (['.jpg', '.png', '.jpeg', '.bmp'].findIndex((e) => e == row.suffix) > -1) {
|
} else if (['.jpg', '.png', '.jpeg', '.bmp'].findIndex((e) => e == row.suffix) > -1) {
|
||||||
state.previewList = [getFileUrl(row)];
|
state.previewList = [fetchFileUrl(row)];
|
||||||
state.showViewer = true;
|
state.showViewer = true;
|
||||||
} else {
|
} else {
|
||||||
ElMessage.error('此文件格式不支持预览');
|
ElMessage.error('此文件格式不支持预览');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 改变页面容量
|
|
||||||
const handleSizeChange = (val: number) => {
|
|
||||||
state.tableParams.pageSize = val;
|
|
||||||
handleQuery();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 改变页码序号
|
|
||||||
const handleCurrentChange = (val: number) => {
|
|
||||||
state.tableParams.page = val;
|
|
||||||
handleQuery();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取文件地址
|
// 获取文件地址
|
||||||
const getFileUrl = (row: SysFile): string => {
|
const fetchFileUrl = (row: SysFile): string => {
|
||||||
if (row.bucketName == 'Local') {
|
if (row.bucketName == 'Local') {
|
||||||
return `/${row.filePath}/${row.id}${row.suffix}`;
|
return `/${row.filePath}/${row.id}${row.suffix}`;
|
||||||
} else {
|
} else {
|
||||||
@ -287,12 +328,13 @@ const getFileUrl = (row: SysFile): string => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 打开编辑页面
|
// 打开编辑页面
|
||||||
const openEditSysFile = (row: any) => {
|
const handleEdit = (row: any) => {
|
||||||
editSysFileRef.value?.openDialog(row);
|
editRef.value?.openDialog(row);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 文件渲染完成
|
// 文件渲染完成
|
||||||
const renderedHandler = () => {};
|
const handleRendered = () => {};
|
||||||
|
|
||||||
// 文件渲染失败
|
// 文件渲染失败
|
||||||
const errorHandler = () => {};
|
const handleError = () => {};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,4 +1,10 @@
|
|||||||
export const JobScriptCode = `#region using
|
export const JobScriptCode = `// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||||
|
//
|
||||||
|
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||||
|
//
|
||||||
|
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||||
|
|
||||||
|
#region using
|
||||||
|
|
||||||
using Furion;
|
using Furion;
|
||||||
using Furion.Logging;
|
using Furion.Logging;
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-jobDetail-container">
|
<div class="sys-jobDetail-container">
|
||||||
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="900px">
|
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div style="color: #fff">
|
<div style="color: #fff">
|
||||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
||||||
@ -10,7 +10,7 @@
|
|||||||
<el-tabs v-model="state.selectedTabName">
|
<el-tabs v-model="state.selectedTabName">
|
||||||
<el-tab-pane label="作业信息">
|
<el-tab-pane label="作业信息">
|
||||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto" style="height: 500px">
|
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto" style="height: 500px">
|
||||||
<el-row :gutter="35">
|
<el-row :gutter="10">
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||||
<el-form-item label="作业编号" prop="jobId" :rules="[{ required: true, message: '作业编号不能为空', trigger: 'blur' }]">
|
<el-form-item label="作业编号" prop="jobId" :rules="[{ required: true, message: '作业编号不能为空', trigger: 'blur' }]">
|
||||||
<el-input v-model="state.ruleForm.jobId" placeholder="作业编号" :disabled="isEdit" clearable />
|
<el-input v-model="state.ruleForm.jobId" placeholder="作业编号" :disabled="isEdit" clearable />
|
||||||
@ -190,8 +190,8 @@ const openDialog = (row: any) => {
|
|||||||
|
|
||||||
// 延迟拿值防止取不到
|
// 延迟拿值防止取不到
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (monacoEditor == null) initMonacoEditor();
|
if (monacoEditor == null || monacoEditor == undefined) initMonacoEditor();
|
||||||
monacoEditor.setValue(row.id == undefined ? JobScriptCode : state.ruleForm.scriptCode);
|
monacoEditor.setValue(row.id == undefined ? JobScriptCode : state.ruleForm.scriptCode ?? '');
|
||||||
}, 1);
|
}, 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
||||||
<el-row :gutter="35">
|
<el-row :gutter="10">
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||||
<el-form-item label="触发器编号" prop="triggerId" :rules="[{ required: true, message: '触发器编号不能为空', trigger: 'blur' }]">
|
<el-form-item label="触发器编号" prop="triggerId" :rules="[{ required: true, message: '触发器编号不能为空', trigger: 'blur' }]">
|
||||||
<el-input v-model="state.ruleForm.triggerId" placeholder="触发器编号" clearable />
|
<el-input v-model="state.ruleForm.triggerId" placeholder="触发器编号" clearable />
|
||||||
@ -144,7 +144,6 @@
|
|||||||
import { reactive, ref, computed } from 'vue';
|
import { reactive, ref, computed } from 'vue';
|
||||||
import type { WritableComputedRef } from 'vue';
|
import type { WritableComputedRef } from 'vue';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
|
|
||||||
import vcrontab from 'vcrontab-3';
|
import vcrontab from 'vcrontab-3';
|
||||||
|
|
||||||
import { getAPI } from '/@/utils/axios-utils';
|
import { getAPI } from '/@/utils/axios-utils';
|
||||||
@ -186,10 +185,8 @@ const periodValue: WritableComputedRef<number | undefined> = computed({
|
|||||||
// 触发器周期不是周期,返回默认值
|
// 触发器周期不是周期,返回默认值
|
||||||
if (state.ruleForm.triggerType != 'Furion.Schedule.PeriodTrigger') return defaultValue;
|
if (state.ruleForm.triggerType != 'Furion.Schedule.PeriodTrigger') return defaultValue;
|
||||||
if (!state.ruleForm.args) return defaultValue;
|
if (!state.ruleForm.args) return defaultValue;
|
||||||
|
|
||||||
const value: number | undefined = Number(state.ruleForm.args);
|
const value: number | undefined = Number(state.ruleForm.args);
|
||||||
if (Number.isNaN(value)) return defaultValue;
|
if (Number.isNaN(value)) return defaultValue;
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
},
|
},
|
||||||
set(value: number | undefined) {
|
set(value: number | undefined) {
|
||||||
@ -290,7 +287,7 @@ defineExpose({ openDialog });
|
|||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
#vcrontab {
|
#vcrontab {
|
||||||
:deep(.el-select) {
|
:deep(.el-select) {
|
||||||
min-width: 300px;
|
min-width: 270px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-jobCluster-container">
|
<div class="sys-jobCluster-container">
|
||||||
<el-drawer v-model="state.isVisible" title="作业集群" size="40%">
|
<el-drawer v-model="state.isVisible" title="作业集群" size="65%">
|
||||||
<el-table :data="state.jobClusterList" style="width: 100%; margin: 8px" v-loading="state.loading" border>
|
<el-table :data="state.jobClusterList" style="width: 100%" v-loading="state.loading" border>
|
||||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
<el-table-column type="index" label="序号" width="55" align="center" />
|
||||||
<el-table-column prop="clusterId" label="集群编号" header-align="center" show-overflow-tooltip />
|
<el-table-column prop="clusterId" label="集群编号" header-align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="status" label="状态" align="center" show-overflow-tooltip>
|
<el-table-column prop="status" label="状态" align="center" show-overflow-tooltip>
|
||||||
@ -31,6 +31,7 @@ const state = reactive({
|
|||||||
jobClusterList: [] as Array<SysJobCluster>,
|
jobClusterList: [] as Array<SysJobCluster>,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 页面初始化
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
handleQuery();
|
handleQuery();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,23 +1,37 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-job-container">
|
<div class="sys-job-container" v-loading="options.loading">
|
||||||
<el-card shadow="hover" :body-style="{ paddingBottom: '0' }">
|
<el-card shadow="hover" :body-style="{ padding: '5px 5px 0 5px', display: 'flex', width: '100%', height: '100%', alignItems: 'start' }">
|
||||||
<el-form :model="state.queryParams" ref="queryForm" :inline="true">
|
<el-form :model="state.queryParams" ref="queryForm" :show-message="false" :inlineMessage="true" :label-width="'60px'" style="flex: 1 1 0%">
|
||||||
<el-form-item label="作业编号">
|
<el-row :gutter="10">
|
||||||
<el-input v-model="state.queryParams.jobId" placeholder="作业编号" clearable />
|
<el-col class="mb5" :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
|
||||||
</el-form-item>
|
<el-form-item label="作业编号" prop="jobId">
|
||||||
<el-form-item label="描述信息">
|
<el-input v-model="state.queryParams.jobId" placeholder="作业编号" clearable @keyup.enter.native="handleQuery(true)" />
|
||||||
<el-input v-model="state.queryParams.description" placeholder="描述信息" clearable />
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
<el-form-item>
|
<el-col class="mb5" :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
|
||||||
|
<el-form-item label="描述信息" prop="description">
|
||||||
|
<el-input v-model="state.queryParams.description" placeholder="描述信息" clearable @keyup.enter.native="handleQuery(true)" />
|
||||||
|
</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-group>
|
||||||
<el-button type="primary" icon="ele-Search" @click="handleQuery" v-auth="'sysJob:pageJobDetail'"> 查询 </el-button>
|
<el-button type="primary" icon="ele-Search" @click="handleQuery(true)" v-auth="'sysJob:pageJobDetail'" :loading="options.loading"> 查询 </el-button>
|
||||||
<el-button icon="ele-Refresh" @click="resetQuery"> 重置 </el-button>
|
<el-button icon="ele-Refresh" @click="resetQuery" :loading="options.loading"> 重置 </el-button>
|
||||||
</el-button-group>
|
</el-button-group>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
<el-form-item>
|
</el-row>
|
||||||
<el-button-group style="margin: 0px 12px">
|
</el-card>
|
||||||
|
|
||||||
|
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
|
||||||
|
<vxe-grid ref="xGrid" class="xGrid-style" v-bind="options" @sort-change="sortChange">
|
||||||
|
<template #toolbar_buttons>
|
||||||
|
<el-button-group>
|
||||||
<el-tooltip content="增加作业">
|
<el-tooltip content="增加作业">
|
||||||
<el-button icon="ele-CirclePlus" @click="openAddJobDetail" v-auth="'sysJob:addJobDetail'"> </el-button>
|
<el-button icon="ele-CirclePlus" @click="handleAdd" v-auth="'sysJob:addJobDetail'"> </el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip content="启动所有作业">
|
<el-tooltip content="启动所有作业">
|
||||||
<el-button icon="ele-VideoPlay" @click="startAllJob" />
|
<el-button icon="ele-VideoPlay" @click="startAllJob" />
|
||||||
@ -26,7 +40,7 @@
|
|||||||
<el-button icon="ele-VideoPause" @click="pauseAllJob" />
|
<el-button icon="ele-VideoPause" @click="pauseAllJob" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-button-group>
|
</el-button-group>
|
||||||
<el-button-group style="margin: 0px 12px 0px 0px">
|
<el-button-group style="margin: 0 12px">
|
||||||
<el-tooltip content="强制唤醒作业调度器">
|
<el-tooltip content="强制唤醒作业调度器">
|
||||||
<el-button icon="ele-AlarmClock" @click="cancelSleep" />
|
<el-button icon="ele-AlarmClock" @click="cancelSleep" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
@ -36,225 +50,204 @@
|
|||||||
</el-button-group>
|
</el-button-group>
|
||||||
<el-button icon="ele-Coin" @click="openJobCluster" plain> 集群控制 </el-button>
|
<el-button icon="ele-Coin" @click="openJobCluster" plain> 集群控制 </el-button>
|
||||||
<el-button icon="ele-Grid" @click="openJobDashboard" plain> 任务看板 </el-button>
|
<el-button icon="ele-Grid" @click="openJobDashboard" plain> 任务看板 </el-button>
|
||||||
</el-form-item>
|
<el-button-group style="padding-left: 12px">
|
||||||
</el-form>
|
<el-button type="primary" icon="ele-Expand" @click="handleExpand"> 全部展开 </el-button>
|
||||||
|
<el-button type="primary" icon="ele-Fold" @click="handleFold"> 全部折叠 </el-button>
|
||||||
|
</el-button-group>
|
||||||
|
</template>
|
||||||
|
<template #toolbar_tools> </template>
|
||||||
|
<template #empty>
|
||||||
|
<el-empty :image-size="200" />
|
||||||
|
</template>
|
||||||
|
<template #row_content="scope">
|
||||||
|
<vxe-table style="margin: 5px" align="center" :data="(scope.row as JobDetailOutput).jobTriggers">
|
||||||
|
<!-- <vxe-column type="checkbox" width="40" fixed="left"></vxe-column> -->
|
||||||
|
<vxe-column type="seq" width="40" fixed="left"></vxe-column>
|
||||||
|
<vxe-column field="triggerId" title="触发器编号" :minWidth="180" showOverflow="tooltip"></vxe-column>
|
||||||
|
<vxe-column field="triggerType" title="类型" :minWidth="120" showOverflow="tooltip"></vxe-column>
|
||||||
|
<!-- <vxe-column field="assemblyName" title="程序集" :minWidth="120" showOverflow="tooltip"></vxe-column> -->
|
||||||
|
<vxe-column field="args" title="参数" :minWidth="120" showOverflow="tooltip"></vxe-column>
|
||||||
|
<vxe-column field="description" title="描述" :minWidth="120" showOverflow="tooltip"></vxe-column>
|
||||||
|
<vxe-column field="status" title="状态" :minWidth="120" showOverflow="tooltip">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-tag type="warning" effect="plain" v-if="(row as SysJobTrigger).status == 0"> 积压 </el-tag>
|
||||||
|
<el-tag type="info" effect="plain" v-if="(row as SysJobTrigger).status == 1"> 就绪 </el-tag>
|
||||||
|
<el-tag type="success" effect="plain" v-if="(row as SysJobTrigger).status == 2"> 正在运行 </el-tag>
|
||||||
|
<el-tag type="danger" effect="plain" v-if="(row as SysJobTrigger).status == 3"> 暂停 </el-tag>
|
||||||
|
<el-tag type="danger" effect="plain" v-if="(row as SysJobTrigger).status == 4"> 阻塞 </el-tag>
|
||||||
|
<el-tag type="info" effect="plain" v-if="(row as SysJobTrigger).status == 5"> 由失败进入就绪 </el-tag>
|
||||||
|
<el-tag type="danger" effect="plain" v-if="(row as SysJobTrigger).status == 6"> 归档 </el-tag>
|
||||||
|
<el-tag type="danger" effect="plain" v-if="(row as SysJobTrigger).status == 7"> 崩溃 </el-tag>
|
||||||
|
<el-tag type="danger" effect="plain" v-if="(row as SysJobTrigger).status == 8"> 超限 </el-tag>
|
||||||
|
<el-tag type="danger" effect="plain" v-if="(row as SysJobTrigger).status == 9"> 无触发时间 </el-tag>
|
||||||
|
<el-tag type="danger" effect="plain" v-if="(row as SysJobTrigger).status == 10"> 未启动 </el-tag>
|
||||||
|
<el-tag type="danger" effect="plain" v-if="(row as SysJobTrigger).status == 11"> 未知作业触发器 </el-tag>
|
||||||
|
<el-tag type="danger" effect="plain" v-if="(row as SysJobTrigger).status == 12"> 未知作业处理程序 </el-tag>
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
<vxe-column field="startTime" title="起始时间" :minWidth="100" showOverflow="tooltip"></vxe-column>
|
||||||
|
<vxe-column field="endTime" title="结束时间" :minWidth="100" showOverflow="tooltip"></vxe-column>
|
||||||
|
<vxe-column field="lastRunTime" title="最近运行时间" :minWidth="130" showOverflow="tooltip"></vxe-column>
|
||||||
|
<vxe-column field="nextRunTime" title="下一次运行时间" :minWidth="130" showOverflow="tooltip"></vxe-column>
|
||||||
|
<vxe-column field="numberOfRuns" title="触发次数" :minWidth="70" showOverflow="tooltip"></vxe-column>
|
||||||
|
<vxe-column field="maxNumberOfRuns" title="最大触发次数" :minWidth="90" showOverflow="tooltip"></vxe-column>
|
||||||
|
<vxe-column field="numberOfErrors" title="出错次数" :minWidth="70" showOverflow="tooltip"></vxe-column>
|
||||||
|
<vxe-column field="maxNumberOfErrors" title="最大出错次数" :minWidth="90" showOverflow="tooltip"></vxe-column>
|
||||||
|
<vxe-column field="numRetries" title="重试次数" :minWidth="70" showOverflow="tooltip"></vxe-column>
|
||||||
|
<vxe-column field="retryTimeout" title="重试间隔ms" :minWidth="80" showOverflow="tooltip"></vxe-column>
|
||||||
|
<vxe-column field="startNow" title="是否立即启动" :minWidth="90" showOverflow="tooltip">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="(scope.row as SysJobTrigger).startNow == true"> 是 </el-tag>
|
||||||
|
<el-tag type="info" v-else> 否 </el-tag>
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
<vxe-column field="runOnStart" title="是否启动时执行一次" :minWidth="120" showOverflow="tooltip">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="(scope.row as SysJobTrigger).runOnStart == true"> 是 </el-tag>
|
||||||
|
<el-tag type="info" v-else> 否 </el-tag>
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
<vxe-column field="resetOnlyOnce" title="是否重置触发次数" :minWidth="110" showOverflow="tooltip">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="(scope.row as SysJobTrigger).resetOnlyOnce == true"> 是 </el-tag>
|
||||||
|
<el-tag type="info" v-else> 否 </el-tag>
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
<vxe-column title="操作" :minWidth="130" fixed="right">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tooltip content="启动触发器">
|
||||||
|
<el-button size="small" type="primary" icon="ele-VideoPlay" text @click="startTrigger(scope.row)" />
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip content="暂停触发器">
|
||||||
|
<el-button size="small" type="primary" icon="ele-VideoPause" text @click="pauseTrigger(scope.row)" />
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip content="编辑触发器">
|
||||||
|
<el-button size="small" type="primary" icon="ele-Edit" text @click="openEditJobTrigger(scope.row)"> </el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip content="删除触发器">
|
||||||
|
<el-button size="small" type="danger" icon="ele-Delete" text @click="delJobTrigger(scope.row)"> </el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
</vxe-table>
|
||||||
|
</template>
|
||||||
|
<template #row_jobId="{ row }">
|
||||||
|
<div style="display: flex; align-items: center">
|
||||||
|
<el-icon><timer /></el-icon>
|
||||||
|
<span style="margin-left: 5px">{{ (row as JobDetailOutput).jobDetail?.jobId }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #row_concurrent="{ row }">
|
||||||
|
<el-tag type="success" v-if="(row as JobDetailOutput).jobDetail?.concurrent == true"> 并行 </el-tag>
|
||||||
|
<el-tag type="warning" v-else> 串行 </el-tag>
|
||||||
|
</template>
|
||||||
|
<template #row_createType="{ row }">
|
||||||
|
<el-tag type="info" v-if="(row as JobDetailOutput).jobDetail?.createType == JobCreateTypeEnum.NUMBER_0"> 内置 </el-tag>
|
||||||
|
<el-tag type="warning" v-if="(row as JobDetailOutput).jobDetail?.createType == JobCreateTypeEnum.NUMBER_1"> 脚本 </el-tag>
|
||||||
|
<el-tag type="success" v-if="(row as JobDetailOutput).jobDetail?.createType == JobCreateTypeEnum.NUMBER_2"> HTTP请求 </el-tag>
|
||||||
|
</template>
|
||||||
|
<template #row_includeAnnotations="{ row }">
|
||||||
|
<el-tag v-if="(row as JobDetailOutput).jobDetail?.includeAnnotations == true"> 是 </el-tag>
|
||||||
|
<el-tag v-else> 否 </el-tag>
|
||||||
|
</template>
|
||||||
|
<template #row_properties="{ row }">
|
||||||
|
<span v-if="(row as JobDetailOutput).jobDetail?.createType != JobCreateTypeEnum.NUMBER_2"> {{ (row as JobDetailOutput).jobDetail?.properties }} </span>
|
||||||
|
<div v-else style="text-align: center">
|
||||||
|
<el-popover placement="left" :width="400" trigger="hover">
|
||||||
|
<template #reference>
|
||||||
|
<el-tag effect="plain" type="info"> 请求参数 </el-tag>
|
||||||
|
</template>
|
||||||
|
<el-descriptions title="Http 请求参数" :column="1" size="small" :border="true">
|
||||||
|
<el-descriptions-item label="请求地址" label-align="right" label-class-name="job-index-descriptions-label-style">
|
||||||
|
{{ getHttpJobMessage((row as JobDetailOutput).jobDetail?.properties).requestUri }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="请求方法" label-align="right" label-class-name="job-index-descriptions-label-style">
|
||||||
|
{{ getHttpMethodDesc(getHttpJobMessage((row as JobDetailOutput).jobDetail?.properties).httpMethod) }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="请求报文体" label-align="right" label-class-name="job-index-descriptions-label-style">
|
||||||
|
{{ getHttpJobMessage((row as JobDetailOutput).jobDetail?.properties).body }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</el-popover>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #row_buttons="{ row }">
|
||||||
|
<el-tooltip content="执行记录">
|
||||||
|
<el-button size="small" type="primary" icon="ele-Timer" text @click="openJobTriggerRecord(row)"> </el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip content="增加触发器">
|
||||||
|
<el-button size="small" type="primary" icon="ele-CirclePlus" text @click="openAddJobTrigger(row)"> </el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip content="执行作业">
|
||||||
|
<el-button size="small" type="primary" icon="ele-CircleCheck" text @click="runJob(row)" />
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip content="启动作业">
|
||||||
|
<el-button size="small" type="primary" icon="ele-VideoPlay" text @click="startJob(row)" />
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip content="暂停作业">
|
||||||
|
<el-button size="small" type="primary" icon="ele-VideoPause" text @click="pauseJob(row)" />
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip content="取消作业">
|
||||||
|
<el-button size="small" type="primary" icon="ele-CircleClose" text @click="cancelJob(row)" />
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip content="编辑作业">
|
||||||
|
<el-button size="small" type="primary" icon="ele-Edit" text @click="handleEdit(row)" v-auth="'sysJob:updateJobDetail'"> </el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip content="删除作业">
|
||||||
|
<el-button size="small" type="danger" icon="ele-Delete" text @click="handleDelete(row)" v-auth="'sysJob:deleteJobDetail'"> </el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
<template #pager>
|
||||||
|
<vxe-pager
|
||||||
|
:loading="options.loading"
|
||||||
|
v-model:current-page="state.tableParams.page"
|
||||||
|
v-model:page-size="state.tableParams.pageSize"
|
||||||
|
:total="state.tableParams.total"
|
||||||
|
@page-change="pageChange"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</vxe-grid>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
|
<el-drawer v-model="state.isVisibleDrawer" size="60%">
|
||||||
<el-table :data="state.jobData" style="width: 100%" v-loading="state.loading" border>
|
<template #header>
|
||||||
<el-table-column type="expand" fixed>
|
<div style="color: #fff">
|
||||||
<template #default="scope">
|
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Clock /> </el-icon>
|
||||||
<el-table style="margin-left: 48px; width: calc(100% - 48px)" :data="(scope.row as JobDetailOutput).jobTriggers" border size="small">
|
<span> 作业触发器运行记录</span>
|
||||||
<el-table-column type="index" label="序号" width="55" align="center" fixed />
|
</div>
|
||||||
<el-table-column prop="triggerId" label="触发器编号" width="180" header-align="center" fixed show-overflow-tooltip />
|
</template>
|
||||||
<el-table-column prop="triggerType" label="类型" width="200" header-align="center" show-overflow-tooltip />
|
<el-card class="full-table" shadow="hover">
|
||||||
<!-- <el-table-column prop="assemblyName" label="程序集" show-overflow-tooltip /> -->
|
<vxe-grid ref="xRecordGrid" class="xGrid-style" v-bind="recordOptions" @sort-change="recordSortChange">
|
||||||
<el-table-column prop="args" label="参数" header-align="center" show-overflow-tooltip />
|
<template #toolbar_buttons></template>
|
||||||
<el-table-column prop="description" label="描述" width="120" header-align="center" show-overflow-tooltip />
|
<template #toolbar_tools> </template>
|
||||||
<el-table-column prop="status" label="状态" width="120" align="center" show-overflow-tooltip>
|
<template #empty>
|
||||||
<template #default="scope">
|
<el-empty :image-size="200" />
|
||||||
<el-tag type="warning" effect="plain" v-if="(scope.row as SysJobTrigger).status == 0"> 积压 </el-tag>
|
|
||||||
<el-tag type="" effect="plain" v-if="(scope.row as SysJobTrigger).status == 1"> 就绪 </el-tag>
|
|
||||||
<el-tag type="success" effect="plain" v-if="(scope.row as SysJobTrigger).status == 2"> 正在运行 </el-tag>
|
|
||||||
<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 3"> 暂停 </el-tag>
|
|
||||||
<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 4"> 阻塞 </el-tag>
|
|
||||||
<el-tag type="" effect="plain" v-if="(scope.row as SysJobTrigger).status == 5"> 由失败进入就绪 </el-tag>
|
|
||||||
<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 6"> 归档 </el-tag>
|
|
||||||
<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 7"> 崩溃 </el-tag>
|
|
||||||
<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 8"> 超限 </el-tag>
|
|
||||||
<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 9"> 无触发时间 </el-tag>
|
|
||||||
<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 10"> 未启动 </el-tag>
|
|
||||||
<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 11"> 未知作业触发器 </el-tag>
|
|
||||||
<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 12"> 未知作业处理程序 </el-tag>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="startTime" label="起始时间" width="100" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="endTime" label="结束时间" width="100" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="lastRunTime" label="最近运行时间" width="130" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="nextRunTime" label="下一次运行时间" width="130" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="numberOfRuns" label="触发次数" width="100" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="maxNumberOfRuns" label="最大触发次数" width="120" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="numberOfErrors" label="出错次数" width="100" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="maxNumberOfErrors" label="最大出错次数" width="120" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="numRetries" label="重试次数" width="100" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="retryTimeout" label="重试间隔ms" width="100" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="startNow" label="是否立即启动" width="100" align="center" show-overflow-tooltip>
|
|
||||||
<template #default="scope">
|
|
||||||
<el-tag v-if="(scope.row as SysJobTrigger).startNow == true"> 是 </el-tag>
|
|
||||||
<el-tag type="info" v-else> 否 </el-tag>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="runOnStart" label="是否启动时执行一次" width="150" align="center" show-overflow-tooltip>
|
|
||||||
<template #default="scope">
|
|
||||||
<el-tag v-if="(scope.row as SysJobTrigger).runOnStart == true"> 是 </el-tag>
|
|
||||||
<el-tag type="info" v-else> 否 </el-tag>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="resetOnlyOnce" label="是否重置触发次数" width="120" align="center" show-overflow-tooltip>
|
|
||||||
<template #default="scope">
|
|
||||||
<el-tag v-if="(scope.row as SysJobTrigger).resetOnlyOnce == true"> 是 </el-tag>
|
|
||||||
<el-tag type="info" v-else> 否 </el-tag>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="updatedTime" label="更新时间" width="130" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column label="操作" width="140" align="center" show-overflow-tooltip fixed="right">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-tooltip content="启动触发器">
|
|
||||||
<el-button size="small" type="primary" icon="ele-VideoPlay" text @click="startTrigger(scope.row)" />
|
|
||||||
</el-tooltip>
|
|
||||||
<el-tooltip content="暂停触发器">
|
|
||||||
<el-button size="small" type="primary" icon="ele-VideoPause" text @click="pauseTrigger(scope.row)" />
|
|
||||||
</el-tooltip>
|
|
||||||
<el-tooltip content="编辑触发器">
|
|
||||||
<el-button size="small" type="primary" icon="ele-Edit" text @click="openEditJobTrigger(scope.row)"> </el-button>
|
|
||||||
</el-tooltip>
|
|
||||||
<el-tooltip content="删除触发器">
|
|
||||||
<el-button size="small" type="danger" icon="ele-Delete" text @click="delJobTrigger(scope.row)"> </el-button>
|
|
||||||
</el-tooltip>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
<template #row_status="{ row }">
|
||||||
<el-table-column type="index" label="序号" width="55" align="center" fixed />
|
<el-tag type="warning" effect="plain" v-if="(row as SysJobTrigger).status == 0"> 积压 </el-tag>
|
||||||
<el-table-column prop="jobDetail.jobId" label="作业编号" width="180" header-align="center" fixed>
|
<el-tag type="info" effect="plain" v-if="(row as SysJobTrigger).status == 1"> 就绪 </el-tag>
|
||||||
<template #default="scope">
|
<el-tag type="success" effect="plain" v-if="(row as SysJobTrigger).status == 2"> 正在运行 </el-tag>
|
||||||
<div style="display: flex; align-items: center">
|
<el-tag type="danger" effect="plain" v-if="(row as SysJobTrigger).status == 3"> 暂停 </el-tag>
|
||||||
<el-icon><timer /></el-icon>
|
<el-tag type="danger" effect="plain" v-if="(row as SysJobTrigger).status == 4"> 阻塞 </el-tag>
|
||||||
<span style="margin-left: 5px">{{ (scope.row as JobDetailOutput).jobDetail?.jobId }}</span>
|
<el-tag type="info" effect="plain" v-if="(row as SysJobTrigger).status == 5"> 由失败进入就绪 </el-tag>
|
||||||
</div>
|
<el-tag type="danger" effect="plain" v-if="(row as SysJobTrigger).status == 6"> 归档 </el-tag>
|
||||||
|
<el-tag type="danger" effect="plain" v-if="(row as SysJobTrigger).status == 7"> 崩溃 </el-tag>
|
||||||
|
<el-tag type="danger" effect="plain" v-if="(row as SysJobTrigger).status == 8"> 超限 </el-tag>
|
||||||
|
<el-tag type="danger" effect="plain" v-if="(row as SysJobTrigger).status == 9"> 无触发时间 </el-tag>
|
||||||
|
<el-tag type="danger" effect="plain" v-if="(row as SysJobTrigger).status == 10"> 未启动 </el-tag>
|
||||||
|
<el-tag type="danger" effect="plain" v-if="(row as SysJobTrigger).status == 11"> 未知作业触发器 </el-tag>
|
||||||
|
<el-tag type="danger" effect="plain" v-if="(row as SysJobTrigger).status == 12"> 未知作业处理程序 </el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
<template #pager>
|
||||||
<el-table-column prop="jobDetail.groupName" label="组名称" width="100" align="center" show-overflow-tooltip />
|
<vxe-pager
|
||||||
<el-table-column prop="jobDetail.jobType" label="类型" width="200" header-align="center" show-overflow-tooltip />
|
:loading="recordOptions.loading"
|
||||||
<!-- <el-table-column prop="jobDetail.assemblyName" label="程序集" show-overflow-tooltip /> -->
|
v-model:current-page="state.recordTableParams.page"
|
||||||
<el-table-column prop="jobDetail.description" label="描述" header-align="center" show-overflow-tooltip />
|
v-model:page-size="state.recordTableParams.pageSize"
|
||||||
<el-table-column prop="jobDetail.concurrent" label="执行方式" width="90" align="center" show-overflow-tooltip>
|
:total="state.recordTableParams.total"
|
||||||
<template #default="scope">
|
@page-change="recordPageChange"
|
||||||
<el-tag type="success" v-if="(scope.row as JobDetailOutput).jobDetail?.concurrent == true"> 并行 </el-tag>
|
/>
|
||||||
<el-tag type="warning" v-else> 串行 </el-tag>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</vxe-grid>
|
||||||
<el-table-column prop="jobDetail.createType" label="作业创建类型" width="110" align="center" show-overflow-tooltip>
|
|
||||||
<template #default="scope">
|
|
||||||
<el-tag type="info" v-if="(scope.row as JobDetailOutput).jobDetail?.createType == JobCreateTypeEnum.NUMBER_0"> 内置 </el-tag>
|
|
||||||
<el-tag type="warning" v-if="(scope.row as JobDetailOutput).jobDetail?.createType == JobCreateTypeEnum.NUMBER_1"> 脚本 </el-tag>
|
|
||||||
<el-tag type="success" v-if="(scope.row as JobDetailOutput).jobDetail?.createType == JobCreateTypeEnum.NUMBER_2"> HTTP请求 </el-tag>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<!-- <el-table-column prop="jobDetail.includeAnnotations" label="扫描特性触发器" align="center" show-overflow-tooltip>
|
|
||||||
<template #default="scope">
|
|
||||||
<el-tag v-if="(scope.row as JobDetailOutput).jobDetail?.includeAnnotations == true"> 是 </el-tag>
|
|
||||||
<el-tag v-else> 否 </el-tag>
|
|
||||||
</template>
|
|
||||||
</el-table-column> -->
|
|
||||||
<el-table-column prop="jobDetail.updatedTime" label="更新时间" width="130" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="jobDetail.properties" label="额外数据" header-align="center" show-overflow-tooltip>
|
|
||||||
<template #default="scope">
|
|
||||||
<span v-if="(scope.row as JobDetailOutput).jobDetail?.createType != JobCreateTypeEnum.NUMBER_2"> {{ (scope.row as JobDetailOutput).jobDetail?.properties }} </span>
|
|
||||||
<div v-else style="text-align: center">
|
|
||||||
<el-popover placement="left" :width="400" trigger="hover">
|
|
||||||
<template #reference>
|
|
||||||
<el-tag effect="plain" type="info"> 请求参数 </el-tag>
|
|
||||||
</template>
|
|
||||||
<el-descriptions title="Http 请求参数" :column="1" size="small" :border="true">
|
|
||||||
<el-descriptions-item label="请求地址" label-align="right" label-class-name="job-index-descriptions-label-style">
|
|
||||||
{{ getHttpJobMessage((scope.row as JobDetailOutput).jobDetail?.properties).requestUri }}
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="请求方法" label-align="right" label-class-name="job-index-descriptions-label-style">
|
|
||||||
{{ getHttpMethodDesc(getHttpJobMessage((scope.row as JobDetailOutput).jobDetail?.properties).httpMethod) }}
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="请求报文体" label-align="right" label-class-name="job-index-descriptions-label-style">
|
|
||||||
{{ getHttpJobMessage((scope.row as JobDetailOutput).jobDetail?.properties).body }}
|
|
||||||
</el-descriptions-item>
|
|
||||||
</el-descriptions>
|
|
||||||
</el-popover>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="操作" width="270" fixed="right" align="center" show-overflow-tooltip>
|
|
||||||
<template #default="scope">
|
|
||||||
<el-tooltip content="执行记录">
|
|
||||||
<el-button size="small" type="primary" icon="ele-Timer" text @click="openJobTriggerRecord(scope.row)"> </el-button>
|
|
||||||
</el-tooltip>
|
|
||||||
<el-tooltip content="增加触发器">
|
|
||||||
<el-button size="small" type="primary" icon="ele-CirclePlus" text @click="openAddJobTrigger(scope.row)"> </el-button>
|
|
||||||
</el-tooltip>
|
|
||||||
<el-tooltip content="执行作业">
|
|
||||||
<el-button size="small" type="primary" icon="ele-CircleCheck" text @click="runJob(scope.row)" />
|
|
||||||
</el-tooltip>
|
|
||||||
<el-tooltip content="启动作业">
|
|
||||||
<el-button size="small" type="primary" icon="ele-VideoPlay" text @click="startJob(scope.row)" />
|
|
||||||
</el-tooltip>
|
|
||||||
<el-tooltip content="暂停作业">
|
|
||||||
<el-button size="small" type="primary" icon="ele-VideoPause" text @click="pauseJob(scope.row)" />
|
|
||||||
</el-tooltip>
|
|
||||||
<el-tooltip content="取消作业">
|
|
||||||
<el-button size="small" type="primary" icon="ele-CircleClose" text @click="cancelJob(scope.row)" />
|
|
||||||
</el-tooltip>
|
|
||||||
<el-tooltip content="编辑作业">
|
|
||||||
<el-button size="small" type="primary" icon="ele-Edit" text @click="openEditJobDetail(scope.row)" v-auth="'sysJob:updateJobDetail'"> </el-button>
|
|
||||||
</el-tooltip>
|
|
||||||
<el-tooltip content="删除作业">
|
|
||||||
<el-button size="small" type="danger" icon="ele-Delete" text @click="delJobDetail(scope.row)" v-auth="'sysJob:deleteJobDetail'"> </el-button>
|
|
||||||
</el-tooltip>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
<el-pagination
|
|
||||||
v-model:currentPage="state.tableParams.page"
|
|
||||||
v-model:page-size="state.tableParams.pageSize"
|
|
||||||
:total="state.tableParams.total"
|
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
|
||||||
small
|
|
||||||
background
|
|
||||||
@size-change="handleSizeChange"
|
|
||||||
@current-change="handleCurrentChange"
|
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
|
||||||
/>
|
|
||||||
</el-card>
|
|
||||||
|
|
||||||
<el-drawer v-model="state.isVisibleDrawer" title="作业触发器运行记录" size="45%">
|
|
||||||
<el-card shadow="hover" style="margin: 8px; padding-bottom: 15px">
|
|
||||||
<el-table :data="state.triggerRecordData" style="width: 100%" v-loading="state.loading2" border>
|
|
||||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
|
||||||
<el-table-column prop="jobId" label="作业编号" min-width="120" header-align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="triggerId" label="触发器编号" min-width="120" header-align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="numberOfRuns" label="当前运行次数" min-width="100" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="lastRunTime" label="最近运行时间" min-width="130" header-align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="nextRunTime" label="下一次运行时间" min-width="130" header-align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="status" label="触发器状态" align="center" show-overflow-tooltip>
|
|
||||||
<template #default="scope">
|
|
||||||
<el-tag type="warning" effect="plain" v-if="(scope.row as SysJobTrigger).status == 0"> 积压 </el-tag>
|
|
||||||
<el-tag type="" effect="plain" v-if="(scope.row as SysJobTrigger).status == 1"> 就绪 </el-tag>
|
|
||||||
<el-tag type="success" effect="plain" v-if="(scope.row as SysJobTrigger).status == 2"> 正在运行 </el-tag>
|
|
||||||
<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 3"> 暂停 </el-tag>
|
|
||||||
<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 4"> 阻塞 </el-tag>
|
|
||||||
<el-tag type="" effect="plain" v-if="(scope.row as SysJobTrigger).status == 5"> 由失败进入就绪 </el-tag>
|
|
||||||
<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 6"> 归档 </el-tag>
|
|
||||||
<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 7"> 崩溃 </el-tag>
|
|
||||||
<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 8"> 超限 </el-tag>
|
|
||||||
<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 9"> 无触发时间 </el-tag>
|
|
||||||
<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 10"> 未启动 </el-tag>
|
|
||||||
<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 11"> 未知作业触发器 </el-tag>
|
|
||||||
<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 12"> 未知作业处理程序 </el-tag>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="result" label="执行结果" header-align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="elapsedTime" label="耗时" min-width="80" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="createdTime" label="创建时间" min-width="130" align="center" show-overflow-tooltip />
|
|
||||||
</el-table>
|
|
||||||
<el-pagination
|
|
||||||
v-model:currentPage="state.tableParams2.page"
|
|
||||||
v-model:page-size="state.tableParams2.pageSize"
|
|
||||||
:total="state.tableParams2.total"
|
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
|
||||||
small
|
|
||||||
background
|
|
||||||
@size-change="handleSizeChange2"
|
|
||||||
@current-change="handleCurrentChange2"
|
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
|
||||||
/>
|
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
|
|
||||||
@ -267,35 +260,45 @@
|
|||||||
<script lang="ts" setup name="sysJob">
|
<script lang="ts" setup name="sysJob">
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
import { ElMessageBox, ElMessage } from 'element-plus';
|
import { ElMessageBox, ElMessage } from 'element-plus';
|
||||||
|
import { auth } from '/@/utils/authFunction';
|
||||||
|
import { VxeGridInstance, VxePagerEvents, VxePagerDefines } from 'vxe-table';
|
||||||
|
import { useVxeTable } from '/@/hooks/vxeTableOptionsHook';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { Timer } from '@element-plus/icons-vue';
|
import { Timer } from '@element-plus/icons-vue';
|
||||||
|
|
||||||
import EditJobDetail from '/@/views/system/job/component/editJobDetail.vue';
|
import EditJobDetail from '/@/views/system/job/component/editJobDetail.vue';
|
||||||
import EditJobTrigger from '/@/views/system/job/component/editJobTrigger.vue';
|
import EditJobTrigger from '/@/views/system/job/component/editJobTrigger.vue';
|
||||||
import JobCluster from '/@/views/system/job/component/jobCluster.vue';
|
import JobCluster from '/@/views/system/job/component/jobCluster.vue';
|
||||||
|
|
||||||
import { getAPI } from '/@/utils/axios-utils';
|
import { getAPI } from '/@/utils/axios-utils';
|
||||||
import { SysJobApi } from '/@/api-services/api';
|
import { SysJobApi } from '/@/api-services/api';
|
||||||
import { JobCreateTypeEnum, JobDetailOutput, SysJobTrigger } from '/@/api-services/models';
|
import { JobCreateTypeEnum, JobDetailOutput, SysJobTrigger, SysJobTriggerRecord } from '/@/api-services/models';
|
||||||
|
|
||||||
|
const xGrid = ref<VxeGridInstance>();
|
||||||
|
const xRecordGrid = ref<VxeGridInstance>();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const editJobDetailRef = ref<InstanceType<typeof EditJobDetail>>();
|
const editJobDetailRef = ref<InstanceType<typeof EditJobDetail>>();
|
||||||
const editJobTriggerRef = ref<InstanceType<typeof EditJobTrigger>>();
|
const editJobTriggerRef = ref<InstanceType<typeof EditJobTrigger>>();
|
||||||
const editJobClusterRef = ref<InstanceType<typeof JobCluster>>();
|
const editJobClusterRef = ref<InstanceType<typeof JobCluster>>();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
loading: false,
|
|
||||||
jobData: [] as Array<JobDetailOutput>,
|
|
||||||
queryParams: {
|
queryParams: {
|
||||||
jobId: undefined,
|
jobId: undefined,
|
||||||
description: undefined,
|
description: undefined,
|
||||||
},
|
},
|
||||||
tableParams: {
|
tableParams: {
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 20,
|
pageSize: 50,
|
||||||
|
field: 'id', // 默认的排序字段
|
||||||
|
order: 'aes', // 排序方向
|
||||||
|
descStr: 'desc', // 降序排序的关键字符
|
||||||
total: 0 as any,
|
total: 0 as any,
|
||||||
},
|
},
|
||||||
tableParams2: {
|
recordTableParams: {
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 20,
|
pageSize: 50,
|
||||||
|
field: 'id', // 默认的排序字段
|
||||||
|
order: 'desc', // 排序方向
|
||||||
|
descStr: 'desc', // 降序排序的关键字符
|
||||||
total: 0 as any,
|
total: 0 as any,
|
||||||
},
|
},
|
||||||
editJobDetailTitle: '',
|
editJobDetailTitle: '',
|
||||||
@ -304,43 +307,91 @@ const state = reactive({
|
|||||||
isVisibleDrawer: false,
|
isVisibleDrawer: false,
|
||||||
triggerRecordData: [] as any,
|
triggerRecordData: [] as any,
|
||||||
currentJob: {} as any,
|
currentJob: {} as any,
|
||||||
|
visible: false,
|
||||||
|
title: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 表格参数配置
|
||||||
|
const options = useVxeTable<JobDetailOutput>({
|
||||||
|
id: 'sysJob',
|
||||||
|
name: '作业信息',
|
||||||
|
columns: [
|
||||||
|
// { type: 'checkbox', width: 40 },
|
||||||
|
{ type: 'seq', title: '序号', width: 50, fixed: 'left' },
|
||||||
|
{ type: 'expand', width: 40, slots: { content: 'row_content' } },
|
||||||
|
{ field: 'jobDetail.jobId', title: '作业编号', minWidth: 180, showOverflow: 'tooltip', slots: { default: 'row_jobId' } },
|
||||||
|
{ field: 'jobDetail.groupName', title: '组名称', minWidth: 80, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'jobDetail.jobType', title: '类型', minWidth: 180, showOverflow: 'tooltip' },
|
||||||
|
// { field: 'jobDetail.assemblyName', title: '程序集', minWidth: 100, showOverflow: 'tooltip', sortable: true },
|
||||||
|
{ field: 'jobDetail.description', title: '描述', minWidth: 150, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'jobDetail.concurrent', title: '执行方式', minWidth: 80, showOverflow: 'tooltip', slots: { default: 'row_concurrent' } },
|
||||||
|
{ field: 'jobDetail.createType', title: '作业创建类型', minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_createType' } },
|
||||||
|
{ field: 'jobDetail.includeAnnotations', title: '扫描特性触发器', minWidth: 120, showOverflow: 'tooltip', slots: { default: 'row_includeAnnotations' } },
|
||||||
|
{ field: 'jobDetail.updatedTime', title: '更新时间', minWidth: 130, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'jobDetail.properties', title: '额外数据', minWidth: 140, showOverflow: 'tooltip', slots: { default: 'row_properties' } },
|
||||||
|
{ title: '操作', minWidth: 200, showOverflow: true, slots: { default: 'row_buttons' } },
|
||||||
|
],
|
||||||
|
enableExport: auth('sysJob:export'),
|
||||||
|
searchCallback: () => handleQuery(),
|
||||||
|
queryAllCallback: () => fetchData({ pageSize: 99999 }),
|
||||||
|
});
|
||||||
|
|
||||||
|
// 页面初始化
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
handleQuery();
|
await handleQuery();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 查询操作
|
// 查询操作
|
||||||
const handleQuery = async () => {
|
const handleQuery = async (reset = false) => {
|
||||||
state.loading = true;
|
options.loading = true;
|
||||||
let params = Object.assign(state.queryParams, state.tableParams);
|
if (reset) state.tableParams.page = 1;
|
||||||
var res = await getAPI(SysJobApi).apiSysJobPageJobDetailPost(params);
|
var res = await fetchData(null);
|
||||||
state.jobData = res.data.result?.items ?? [];
|
await xGrid.value?.loadData(res.data.result?.items ?? []);
|
||||||
state.tableParams.total = res.data.result?.total;
|
state.tableParams.total = res.data.result?.total;
|
||||||
state.loading = false;
|
options.loading = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取数据
|
||||||
|
const fetchData = async (tableParams: any) => {
|
||||||
|
let params = Object.assign(state.queryParams, state.tableParams, tableParams);
|
||||||
|
return getAPI(SysJobApi).apiSysJobPageJobDetailPost(params);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 重置操作
|
// 重置操作
|
||||||
const resetQuery = () => {
|
const resetQuery = async () => {
|
||||||
state.queryParams.jobId = undefined;
|
state.queryParams.jobId = undefined;
|
||||||
state.queryParams.description = undefined;
|
state.queryParams.description = undefined;
|
||||||
handleQuery();
|
await handleQuery(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 改变页码序号或页面容量
|
||||||
|
const pageChange: VxePagerEvents.PageChange = async ({ currentPage, pageSize }: VxePagerDefines.PageChangeEventParams) => {
|
||||||
|
state.tableParams.page = currentPage;
|
||||||
|
state.tableParams.pageSize = pageSize;
|
||||||
|
await handleQuery();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 列排序
|
||||||
|
const sortChange = async (options: any) => {
|
||||||
|
state.tableParams.field = options.field;
|
||||||
|
state.tableParams.order = options.order;
|
||||||
|
await handleQuery();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开新增作业页面
|
// 打开新增作业页面
|
||||||
const openAddJobDetail = () => {
|
const handleAdd = () => {
|
||||||
state.editJobDetailTitle = '添加作业';
|
state.editJobDetailTitle = '添加作业';
|
||||||
editJobDetailRef.value?.openDialog({ concurrent: true, includeAnnotations: true, groupName: 'default', createType: JobCreateTypeEnum.NUMBER_2 });
|
editJobDetailRef.value?.openDialog({ concurrent: true, includeAnnotations: true, groupName: 'default', createType: JobCreateTypeEnum.NUMBER_2 });
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开编辑作业页面
|
// 打开编辑作业页面
|
||||||
const openEditJobDetail = (row: JobDetailOutput) => {
|
const handleEdit = (row: JobDetailOutput) => {
|
||||||
state.editJobDetailTitle = '编辑作业';
|
state.editJobDetailTitle = '编辑作业';
|
||||||
editJobDetailRef.value?.openDialog(row.jobDetail);
|
editJobDetailRef.value?.openDialog(row.jobDetail);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 删除作业
|
// 删除作业
|
||||||
const delJobDetail = (row: JobDetailOutput) => {
|
const handleDelete = (row: JobDetailOutput) => {
|
||||||
ElMessageBox.confirm(`确定删除作业:【${row.jobDetail?.jobId}】?`, '提示', {
|
ElMessageBox.confirm(`确定删除作业:【${row.jobDetail?.jobId}】?`, '提示', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
@ -388,18 +439,6 @@ const delJobTrigger = (row: SysJobTrigger) => {
|
|||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 改变页面容量
|
|
||||||
const handleSizeChange = (val: number) => {
|
|
||||||
state.tableParams.pageSize = val;
|
|
||||||
handleQuery();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 改变页码序号
|
|
||||||
const handleCurrentChange = (val: number) => {
|
|
||||||
state.tableParams.page = val;
|
|
||||||
handleQuery();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 启动所有作业
|
// 启动所有作业
|
||||||
const startAllJob = async () => {
|
const startAllJob = async () => {
|
||||||
await getAPI(SysJobApi).apiSysJobStartAllJobPost();
|
await getAPI(SysJobApi).apiSysJobStartAllJobPost();
|
||||||
@ -475,10 +514,8 @@ const openJobDashboard = () => {
|
|||||||
// 根据任务属性获取 HttpJobMessage
|
// 根据任务属性获取 HttpJobMessage
|
||||||
const getHttpJobMessage = (properties: string | undefined | null): HttpJobMessage => {
|
const getHttpJobMessage = (properties: string | undefined | null): HttpJobMessage => {
|
||||||
if (properties === undefined || properties === null || properties === '') return {};
|
if (properties === undefined || properties === null || properties === '') return {};
|
||||||
|
|
||||||
const propData = JSON.parse(properties);
|
const propData = JSON.parse(properties);
|
||||||
const httpJobMessageNet = JSON.parse(propData['HttpJob']); // 后端大写开头的 HttpJobMessage
|
const httpJobMessageNet = JSON.parse(propData['HttpJob']); // 后端大写开头的 HttpJobMessage
|
||||||
|
|
||||||
return {
|
return {
|
||||||
requestUri: httpJobMessageNet.RequestUri,
|
requestUri: httpJobMessageNet.RequestUri,
|
||||||
httpMethod: JSON.stringify(httpJobMessageNet.HttpMethod),
|
httpMethod: JSON.stringify(httpJobMessageNet.HttpMethod),
|
||||||
@ -489,40 +526,78 @@ const getHttpJobMessage = (properties: string | undefined | null): HttpJobMessag
|
|||||||
// 获取请求方法的对应描述
|
// 获取请求方法的对应描述
|
||||||
const getHttpMethodDesc = (httpMethodStr: string | undefined | null): string => {
|
const getHttpMethodDesc = (httpMethodStr: string | undefined | null): string => {
|
||||||
if (httpMethodStr === undefined || httpMethodStr === null || httpMethodStr === '') return '';
|
if (httpMethodStr === undefined || httpMethodStr === null || httpMethodStr === '') return '';
|
||||||
|
|
||||||
for (const key in editJobDetailRef.value?.httpMethodDef) {
|
for (const key in editJobDetailRef.value?.httpMethodDef) {
|
||||||
if (editJobDetailRef.value?.httpMethodDef[key] === httpMethodStr) return key;
|
if (editJobDetailRef.value?.httpMethodDef[key] === httpMethodStr) return key;
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//全部展开
|
||||||
|
const handleExpand = () => {
|
||||||
|
xGrid.value?.setAllRowExpand(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
//全部折叠
|
||||||
|
const handleFold = () => {
|
||||||
|
xGrid.value?.clearRowExpand();
|
||||||
|
};
|
||||||
|
|
||||||
// 打开作业触发器运行记录
|
// 打开作业触发器运行记录
|
||||||
const openJobTriggerRecord = (row: any) => {
|
const openJobTriggerRecord = async (row: any) => {
|
||||||
state.currentJob = row;
|
state.currentJob = row;
|
||||||
state.isVisibleDrawer = true;
|
state.isVisibleDrawer = true;
|
||||||
handleQuery2();
|
await handleQueryRecord();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 作业触发器运行记录查询操作
|
// 表格参数配置-触发器
|
||||||
const handleQuery2 = async () => {
|
const recordOptions = useVxeTable<SysJobTriggerRecord>({
|
||||||
state.loading2 = true;
|
id: 'sysJobRecord',
|
||||||
let params = Object.assign({ jobId: state.currentJob.jobDetail.jobId }, state.tableParams2); //state.currentJob.jobTriggers[0].triggerId
|
name: '执行记录',
|
||||||
var res = await getAPI(SysJobApi).apiSysJobPageJobTriggerRecordPost(params);
|
columns: [
|
||||||
state.triggerRecordData = res.data.result?.items ?? [];
|
// { type: 'checkbox', width: 40, fixed: 'left' },
|
||||||
state.tableParams2.total = res.data.result?.total;
|
{ type: 'seq', title: '序号', width: 50, fixed: 'left' },
|
||||||
state.loading2 = false;
|
{ field: 'jobId', title: '作业编号', minWidth: 200, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'triggerId', title: '触发器编号', minWidth: 200, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'numberOfRuns', title: '当前运行次数', minWidth: 100, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'lastRunTime', title: '最近运行时间', minWidth: 130, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'nextRunTime', title: '下一次运行时间', minWidth: 130, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'status', title: '触发器状态', minWidth: 110, showOverflow: 'tooltip', slots: { default: 'row_status' } },
|
||||||
|
{ field: 'result', title: '执行结果', minWidth: 200, showOverflow: 'title' },
|
||||||
|
{ field: 'elapsedTime', title: '耗时(ms)', minWidth: 80, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'createdTime', title: '创建时间', minWidth: 130, showOverflow: 'tooltip' },
|
||||||
|
],
|
||||||
|
searchCallback: () => handleQueryRecord(),
|
||||||
|
queryAllCallback: () => fetchRecordData({ pageSize: 99999 }),
|
||||||
|
});
|
||||||
|
|
||||||
|
// 查询操作
|
||||||
|
const handleQueryRecord = async (reset = false) => {
|
||||||
|
recordOptions.loading = true;
|
||||||
|
if (reset) state.recordTableParams.page = 1;
|
||||||
|
var res = await fetchRecordData(null);
|
||||||
|
await xRecordGrid.value?.loadData(res.data.result?.items ?? []);
|
||||||
|
state.recordTableParams.total = res.data.result?.total;
|
||||||
|
recordOptions.loading = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 作业触发器运行记录-改变页面容量
|
// 获取数据
|
||||||
const handleSizeChange2 = (val: number) => {
|
const fetchRecordData = async (tableParams: any) => {
|
||||||
state.tableParams2.pageSize = val;
|
let params = Object.assign({ jobId: state.currentJob.jobDetail.jobId }, state.recordTableParams, tableParams);
|
||||||
handleQuery2();
|
return getAPI(SysJobApi).apiSysJobPageJobTriggerRecordPost(params);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 作业触发器运行记录-改变页码序号
|
// 改变页码序号或页面容量
|
||||||
const handleCurrentChange2 = (val: number) => {
|
const recordPageChange: VxePagerEvents.PageChange = async ({ currentPage, pageSize }: VxePagerDefines.PageChangeEventParams) => {
|
||||||
state.tableParams2.page = val;
|
state.recordTableParams.page = currentPage;
|
||||||
handleQuery2();
|
state.recordTableParams.pageSize = pageSize;
|
||||||
|
await handleQueryRecord();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 列排序
|
||||||
|
const recordSortChange = async (options: any) => {
|
||||||
|
state.recordTableParams.field = options.field;
|
||||||
|
state.recordTableParams.order = options.order;
|
||||||
|
await handleQueryRecord();
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -532,3 +607,21 @@ const handleCurrentChange2 = (val: number) => {
|
|||||||
width: 80px;
|
width: 80px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
:deep(.el-drawer__body) {
|
||||||
|
padding: 5px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.full-table {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
:deep(.el-card__body) {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-menu-container">
|
<div class="sys-menu-container">
|
||||||
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="700px">
|
<el-dialog v-model="state.isShowDialog" draggable overflow destroy-on-close width="700px">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div style="color: #fff">
|
<div style="color: #fff">
|
||||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
||||||
@ -8,7 +8,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
||||||
<el-row :gutter="35">
|
<el-row :gutter="10">
|
||||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||||
<el-form-item label="上级菜单">
|
<el-form-item label="上级菜单">
|
||||||
<el-cascader
|
<el-cascader
|
||||||
@ -149,9 +149,9 @@
|
|||||||
<script lang="ts" setup name="sysEditMenu">
|
<script lang="ts" setup name="sysEditMenu">
|
||||||
import { computed, reactive, ref } from 'vue';
|
import { computed, reactive, ref } from 'vue';
|
||||||
import IconSelector from '/@/components/iconSelector/index.vue';
|
import IconSelector from '/@/components/iconSelector/index.vue';
|
||||||
|
import other from '/@/utils/other';
|
||||||
|
|
||||||
import { getAPI } from '/@/utils/axios-utils';
|
import { getAPI } from '/@/utils/axios-utils';
|
||||||
import other from '/@/utils/other';
|
|
||||||
import { SysMenuApi } from '/@/api-services/api';
|
import { SysMenuApi } from '/@/api-services/api';
|
||||||
import { SysMenu, UpdateMenuInput } from '/@/api-services/models';
|
import { SysMenu, UpdateMenuInput } from '/@/api-services/models';
|
||||||
|
|
||||||
|
|||||||
@ -1,75 +1,89 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-menu-container">
|
<div class="sys-menu-container" v-loading="options.loading">
|
||||||
<el-card shadow="hover" :body-style="{ paddingBottom: '0' }">
|
<el-card shadow="hover" :body-style="{ padding: '5px 5px 0 5px', display: 'flex', width: '100%', height: '100%', alignItems: 'start' }">
|
||||||
<el-form :model="state.queryParams" ref="queryForm" :inline="true">
|
<el-form :model="state.queryParams" ref="queryForm" :show-message="false" :inlineMessage="true" :label-width="'60px'" style="flex: 1 1 0%">
|
||||||
<el-form-item label="菜单名称">
|
<el-row :gutter="10">
|
||||||
<el-input v-model="state.queryParams.title" placeholder="菜单名称" clearable />
|
<el-col class="mb5" :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
|
||||||
</el-form-item>
|
<el-form-item label="菜单名称" prop="title">
|
||||||
<el-form-item label="类型">
|
<el-input v-model="state.queryParams.title" placeholder="菜单名称" clearable @keyup.enter.native="handleQuery" />
|
||||||
<el-select v-model="state.queryParams.type" placeholder="类型" clearable>
|
</el-form-item>
|
||||||
<el-option label="目录" :value="1" />
|
</el-col>
|
||||||
<el-option label="菜单" :value="2" />
|
<el-col class="mb5" :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
|
||||||
<el-option label="按钮" :value="3" />
|
<el-form-item label="类型" prop="type">
|
||||||
</el-select>
|
<el-select v-model="state.queryParams.type" placeholder="类型" clearable @clear="state.queryParams.type = undefined">
|
||||||
</el-form-item>
|
<el-option label="目录" :value="1" />
|
||||||
<el-form-item>
|
<el-option label="菜单" :value="2" />
|
||||||
<el-button-group>
|
<el-option label="按钮" :value="3" />
|
||||||
<el-button type="primary" icon="ele-Search" @click="handleQuery" v-auth="'sysMenu:list'"> 查询 </el-button>
|
</el-select>
|
||||||
<el-button icon="ele-Refresh" @click="resetQuery"> 重置 </el-button>
|
</el-form-item>
|
||||||
</el-button-group>
|
</el-col>
|
||||||
</el-form-item>
|
</el-row>
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="ele-Plus" @click="openAddMenu" v-auth="'sysMenu:add'"> 新增 </el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
</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" v-auth="'sysMenu:list'" :loading="options.loading"> 查询 </el-button>
|
||||||
|
<el-button icon="ele-Refresh" @click="resetQuery" :loading="options.loading"> 重置 </el-button>
|
||||||
|
</el-button-group>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
|
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
|
||||||
<el-table :data="state.menuData" v-loading="state.loading" row-key="id" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" border>
|
<vxe-grid ref="xGrid" class="xGrid-style" v-bind="options" :tree-config="{}">
|
||||||
<el-table-column label="菜单名称" header-align="center" show-overflow-tooltip>
|
<template #toolbar_buttons>
|
||||||
<template #default="scope">
|
<el-button type="primary" icon="ele-Plus" @click="handleAdd" v-auth="'sysMenu:add'"> 新增 </el-button>
|
||||||
<SvgIcon :name="scope.row.icon" />
|
<el-button-group style="padding-left: 12px">
|
||||||
<span class="ml10">{{ $t(scope.row.title) }}</span>
|
<el-button type="primary" icon="ele-Expand" @click="handleExpand"> 全部展开 </el-button>
|
||||||
</template>
|
<el-button type="primary" icon="ele-Fold" @click="handleFold"> 全部折叠 </el-button>
|
||||||
</el-table-column>
|
</el-button-group>
|
||||||
<el-table-column label="类型" width="70" align="center" show-overflow-tooltip>
|
</template>
|
||||||
<template #default="scope">
|
<template #toolbar_tools> </template>
|
||||||
<el-tag type="warning" v-if="scope.row.type === 1">目录</el-tag>
|
<template #empty>
|
||||||
<el-tag v-else-if="scope.row.type === 2">菜单</el-tag>
|
<el-empty :image-size="200" />
|
||||||
<el-tag type="info" v-else>按钮</el-tag>
|
</template>
|
||||||
</template>
|
<template #row_title="{ row }">
|
||||||
</el-table-column>
|
<SvgIcon :name="row.icon" />
|
||||||
<el-table-column prop="path" label="路由路径" header-align="center" show-overflow-tooltip />
|
<span class="ml10">{{ $t(row.title) }}</span>
|
||||||
<el-table-column prop="component" label="组件路径" align="center" show-overflow-tooltip />
|
</template>
|
||||||
<el-table-column prop="permission" label="权限标识" align="center" show-overflow-tooltip />
|
<template #row_type="{ row }">
|
||||||
<el-table-column prop="orderNo" label="排序" width="70" align="center" show-overflow-tooltip />
|
<el-tag type="warning" v-if="row.type === 1">目录</el-tag>
|
||||||
<el-table-column label="状态" width="80" align="center" show-overflow-tooltip>
|
<el-tag v-else-if="row.type === 2">菜单</el-tag>
|
||||||
<template #default="scope">
|
<el-tag type="info" v-else>按钮</el-tag>
|
||||||
<el-tag type="success" v-if="scope.row.status === 1">启用</el-tag>
|
</template>
|
||||||
<el-tag type="danger" v-else>禁用</el-tag>
|
<template #row_status="{ row }">
|
||||||
</template>
|
<el-tag v-if="row.status === 1" type="success">启用</el-tag>
|
||||||
</el-table-column>
|
<el-tag v-else type="danger">禁用</el-tag>
|
||||||
<el-table-column label="修改记录" width="100" align="center" show-overflow-tooltip>
|
</template>
|
||||||
<template #default="scope">
|
<template #row_record="{ row }">
|
||||||
<ModifyRecord :data="scope.row" />
|
<ModifyRecord :data="row" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
<template #row_buttons="{ row }">
|
||||||
<el-table-column label="操作" width="140" fixed="right" align="center" show-overflow-tooltip>
|
<el-tooltip content="编辑" placement="top">
|
||||||
<template #default="scope">
|
<el-button icon="ele-Edit" text type="primary" v-auth="'sysMenu:update'" @click="handleEdit(row)"> </el-button>
|
||||||
<el-button icon="ele-Edit" size="small" text type="primary" @click="openEditMenu(scope.row)" v-auth="'sysMenu:update'"> 编辑 </el-button>
|
</el-tooltip>
|
||||||
<el-button icon="ele-Delete" size="small" text type="danger" @click="delMenu(scope.row)" v-auth="'sysMenu:delete'"> 删除 </el-button>
|
<el-tooltip content="删除" placement="top">
|
||||||
</template>
|
<el-button icon="ele-Delete" text type="danger" v-auth="'sysMenu:delete'" @click="handleDelete(row)"> </el-button>
|
||||||
</el-table-column>
|
</el-tooltip>
|
||||||
</el-table>
|
</template>
|
||||||
|
</vxe-grid>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<EditMenu ref="editMenuRef" :title="state.editMenuTitle" :menuData="state.menuData" @handleQuery="handleQuery" />
|
<EditMenu ref="editMenuRef" :title="state.title" :menuData="state.menuData" @handleQuery="handleQuery" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup name="sysMenu">
|
<script lang="ts" setup name="sysMenu">
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
import { ElMessageBox, ElMessage } from 'element-plus';
|
import { ElMessageBox, ElMessage } from 'element-plus';
|
||||||
|
import { auth } from '/@/utils/authFunction';
|
||||||
|
import { VxeGridInstance } from 'vxe-table';
|
||||||
|
import { useVxeTable } from '/@/hooks/vxeTableOptionsHook';
|
||||||
|
import SvgIcon from '/@/components/svgIcon/index.vue';
|
||||||
|
|
||||||
import EditMenu from '/@/views/system/menu/component/editMenu.vue';
|
import EditMenu from '/@/views/system/menu/component/editMenu.vue';
|
||||||
import ModifyRecord from '/@/components/table/modifyRecord.vue';
|
import ModifyRecord from '/@/components/table/modifyRecord.vue';
|
||||||
|
|
||||||
@ -77,27 +91,60 @@ import { getAPI } from '/@/utils/axios-utils';
|
|||||||
import { SysMenuApi } from '/@/api-services/api';
|
import { SysMenuApi } from '/@/api-services/api';
|
||||||
import { SysMenu } from '/@/api-services/models';
|
import { SysMenu } from '/@/api-services/models';
|
||||||
|
|
||||||
|
const xGrid = ref<VxeGridInstance>();
|
||||||
const editMenuRef = ref<InstanceType<typeof EditMenu>>();
|
const editMenuRef = ref<InstanceType<typeof EditMenu>>();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
loading: false,
|
|
||||||
menuData: [] as Array<SysMenu>,
|
menuData: [] as Array<SysMenu>,
|
||||||
queryParams: {
|
queryParams: {
|
||||||
title: undefined,
|
title: undefined,
|
||||||
type: undefined,
|
type: undefined,
|
||||||
},
|
},
|
||||||
editMenuTitle: '',
|
title: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 表格参数配置
|
||||||
|
const options = useVxeTable<SysMenu>(
|
||||||
|
{
|
||||||
|
id: 'sysMenu',
|
||||||
|
name: '菜单信息',
|
||||||
|
columns: [
|
||||||
|
// { type: 'checkbox', width: 40, fixed: 'left' },
|
||||||
|
{ type: 'seq', title: '序号', width: 60, fixed: 'left' },
|
||||||
|
{ field: 'title', title: '菜单名称', minWidth: 180, showOverflow: 'tooltip', treeNode: true, slots: { default: 'row_title' } },
|
||||||
|
{ field: 'type', title: '菜单类型', minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_type' } },
|
||||||
|
{ field: 'path', title: '路由路径', minWidth: 150, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'component', title: '组件路径', minWidth: 150, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'permission', title: '权限标识', minWidth: 160, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'orderNo', title: '排序', width: 80, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'status', title: '状态', width: 100, showOverflow: 'tooltip', slots: { default: 'row_status' } },
|
||||||
|
{ field: '', title: '修改记录', width: 100, showOverflow: 'tooltip', slots: { default: 'row_record' } },
|
||||||
|
{ title: '操作', fixed: 'right', width: 100, showOverflow: true, slots: { default: 'row_buttons' } },
|
||||||
|
],
|
||||||
|
enableExport: auth('sysMenu:export'),
|
||||||
|
searchCallback: () => handleQuery(),
|
||||||
|
queryAllCallback: () => fetchData({ pageSize: 99999 }),
|
||||||
|
},
|
||||||
|
{ stripe: false, checkboxConfig: { range: false } }
|
||||||
|
);
|
||||||
|
|
||||||
|
// 页面初始化
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
handleQuery();
|
await handleQuery();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 查询操作
|
// 查询操作
|
||||||
const handleQuery = async () => {
|
const handleQuery = async () => {
|
||||||
state.loading = true;
|
options.loading = true;
|
||||||
var res = await getAPI(SysMenuApi).apiSysMenuListGet(state.queryParams.title, state.queryParams.type);
|
var res = await fetchData(null);
|
||||||
|
xGrid.value?.loadData(res.data.result ?? []);
|
||||||
state.menuData = res.data.result ?? [];
|
state.menuData = res.data.result ?? [];
|
||||||
state.loading = false;
|
options.loading = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取数据
|
||||||
|
const fetchData = async (tableParams: any) => {
|
||||||
|
let params = Object.assign(state.queryParams, tableParams);
|
||||||
|
return getAPI(SysMenuApi).apiSysMenuListGet(params.title, params.type);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 重置操作
|
// 重置操作
|
||||||
@ -108,19 +155,19 @@ const resetQuery = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 打开新增页面
|
// 打开新增页面
|
||||||
const openAddMenu = () => {
|
const handleAdd = () => {
|
||||||
state.editMenuTitle = '添加菜单';
|
state.title = '添加菜单';
|
||||||
editMenuRef.value?.openDialog({ type: 2, isHide: false, isKeepAlive: true, isAffix: false, isIframe: false, status: 1, orderNo: 100 });
|
editMenuRef.value?.openDialog({ type: 2, isHide: false, isKeepAlive: true, isAffix: false, isIframe: false, status: 1, orderNo: 100 });
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开编辑页面
|
// 打开编辑页面
|
||||||
const openEditMenu = (row: any) => {
|
const handleEdit = (row: any) => {
|
||||||
state.editMenuTitle = '编辑菜单';
|
state.title = '编辑菜单';
|
||||||
editMenuRef.value?.openDialog(row);
|
editMenuRef.value?.openDialog(row);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 删除当前行
|
// 删除当前行
|
||||||
const delMenu = (row: any) => {
|
const handleDelete = (row: any) => {
|
||||||
ElMessageBox.confirm(`确定删除菜单:【${row.title}】?`, '提示', {
|
ElMessageBox.confirm(`确定删除菜单:【${row.title}】?`, '提示', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
@ -128,9 +175,19 @@ const delMenu = (row: any) => {
|
|||||||
})
|
})
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
await getAPI(SysMenuApi).apiSysMenuDeletePost({ id: row.id });
|
await getAPI(SysMenuApi).apiSysMenuDeletePost({ id: row.id });
|
||||||
handleQuery();
|
|
||||||
ElMessage.success('删除成功');
|
ElMessage.success('删除成功');
|
||||||
|
await handleQuery();
|
||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 全部展开
|
||||||
|
const handleExpand = () => {
|
||||||
|
xGrid.value?.setAllTreeExpand(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 全部折叠
|
||||||
|
const handleFold = () => {
|
||||||
|
xGrid.value?.clearTreeExpand();
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -62,11 +62,11 @@ const openDialog = (row: any) => {
|
|||||||
|
|
||||||
var receiveUser = JSON.parse(JSON.stringify(row));
|
var receiveUser = JSON.parse(JSON.stringify(row));
|
||||||
state.ruleForm.receiveUserId = receiveUser.userId;
|
state.ruleForm.receiveUserId = receiveUser.userId;
|
||||||
state.ruleForm.receiveUserName = receiveUser.realName;
|
state.ruleForm.receiveUserName = receiveUser.realName;
|
||||||
state.ruleForm.connectionId = receiveUser.connectionId;
|
state.ruleForm.connectionId = receiveUser.connectionId;
|
||||||
|
|
||||||
state.ruleForm.sendUserId = userInfos.value.id;
|
state.ruleForm.sendUserId = userInfos.value.id;
|
||||||
state.ruleForm.sendUserName = userInfos.value.realName;
|
state.ruleForm.sendUserName = userInfos.value.realName;
|
||||||
state.ruleForm.sendTime = formatDate(new Date(), 'YYYY-mm-dd HH:MM:SS');
|
state.ruleForm.sendTime = formatDate(new Date(), 'YYYY-mm-dd HH:MM:SS');
|
||||||
state.isShowDialog = true;
|
state.isShowDialog = true;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,50 +1,65 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-onlineUser-container">
|
<div class="sys-onlineUser-container">
|
||||||
<el-drawer v-model="state.isVisible" title="在线用户列表" size="35%">
|
<el-drawer v-model="state.isVisible" size="35%">
|
||||||
<el-card shadow="hover" :body-style="{ paddingBottom: '0' }" style="margin: 8px">
|
<template #header>
|
||||||
<el-form :model="state.queryParams" ref="queryForm" :inline="true">
|
<div style="color: #fff">
|
||||||
<el-form-item label="账号" prop="userName">
|
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-UserFilled /> </el-icon>
|
||||||
<el-input placeholder="账号" clearable @keyup.enter="handleQuery" v-model="state.queryParams.userName" />
|
<span> 在线用户列表</span>
|
||||||
</el-form-item>
|
</div>
|
||||||
<el-form-item label="姓名" prop="realName">
|
</template>
|
||||||
<el-input placeholder="姓名" clearable @keyup.enter="handleQuery" v-model="state.queryParams.realName" />
|
<el-card shadow="hover" :body-style="{ padding: '5px 5px 0 5px', display: 'flex', width: '100%', height: '100%', alignItems: 'start' }">
|
||||||
</el-form-item>
|
<el-form :model="state.queryParams" ref="queryForm" :show-message="false" :inlineMessage="true" :label-width="'60px'" style="flex: 1 1 0%">
|
||||||
<el-form-item>
|
<el-row :gutter="10">
|
||||||
<el-button-group>
|
<el-col class="mb5" :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
|
||||||
<el-button type="primary" icon="ele-Search" @click="handleQuery"> 查询 </el-button>
|
<el-form-item label="账号" prop="userName">
|
||||||
<el-button icon="ele-Refresh" @click="resetQuery"> 重置 </el-button>
|
<el-input v-model="state.queryParams.userName" placeholder="账号" clearable @keyup.enter.native="handleQuery(true)" />
|
||||||
</el-button-group>
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
|
<el-col class="mb5" :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
|
||||||
|
<el-form-item label="姓名" prop="realName">
|
||||||
|
<el-input v-model="state.queryParams.realName" placeholder="姓名" clearable @keyup.enter.native="handleQuery(true)" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</el-form>
|
</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)" :loading="options.loading"> 查询 </el-button>
|
||||||
|
<el-button icon="ele-Refresh" @click="resetQuery" :loading="options.loading"> 重置 </el-button>
|
||||||
|
</el-button-group>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-card shadow="hover" style="margin: 8px; padding-bottom: 15px">
|
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
|
||||||
<el-table :data="state.onlineUserList" style="width: 100%" v-loading="state.loading" border>
|
<vxe-grid ref="xGrid" class="xGrid-style" v-bind="options" @sort-change="sortChange">
|
||||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
<template #toolbar_buttons> </template>
|
||||||
<el-table-column prop="userName" label="账号" header-align="center" show-overflow-tooltip />
|
<template #toolbar_tools> </template>
|
||||||
<el-table-column prop="realName" label="姓名" header-align="center" show-overflow-tooltip />
|
<template #empty>
|
||||||
<el-table-column prop="ip" label="IP地址" min-width="100" header-align="center" show-overflow-tooltip />
|
<el-empty :image-size="200" />
|
||||||
<el-table-column prop="browser" label="浏览器" header-align="center" show-overflow-tooltip />
|
</template>
|
||||||
<!-- <el-table-column prop="connectionId" label="连接Id" show-overflow-tooltip></el-table-column> -->
|
<template #row_buttons="{ row }">
|
||||||
<el-table-column prop="time" label="登录时间" min-width="120" header-align="center" show-overflow-tooltip />
|
<el-tooltip content="发送消息" placement="top">
|
||||||
<el-table-column label="操作" width="200" fixed="right" align="center" show-overflow-tooltip>
|
<el-button icon="ele-Position" text type="primary" @click="openSendMessage(row)"> </el-button>
|
||||||
<template #default="scope">
|
</el-tooltip>
|
||||||
<el-button icon="ele-Position" size="small" text type="primary" v-auth="'sysOnlineUser:forceOffline'" @click="openSendMessage(scope.row)"> 发送消息 </el-button>
|
<el-tooltip content="强制下线" placement="top">
|
||||||
<el-button icon="ele-CircleCloseFilled" size="small" text type="danger" v-auth="'sysOnlineUser:forceOffline'" @click="forceOffline(scope.row)"> 强制下线 </el-button>
|
<el-button icon="ele-CircleCloseFilled" text type="danger" v-auth="'sysOnlineUser:forceOffline'" @click="forceOffline(row)"> </el-button>
|
||||||
</template>
|
</el-tooltip>
|
||||||
</el-table-column>
|
</template>
|
||||||
</el-table>
|
<template #pager>
|
||||||
<el-pagination
|
<vxe-pager
|
||||||
v-model:currentPage="state.tableParams.page"
|
:loading="options.loading"
|
||||||
v-model:page-size="state.tableParams.pageSize"
|
v-model:current-page="state.tableParams.page"
|
||||||
:total="state.tableParams.total"
|
v-model:page-size="state.tableParams.pageSize"
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
:total="state.tableParams.total"
|
||||||
small
|
@page-change="pageChange"
|
||||||
background
|
/>
|
||||||
@size-change="handleSizeChange"
|
</template>
|
||||||
@current-change="handleCurrentChange"
|
</vxe-grid>
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
|
||||||
/>
|
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
|
|
||||||
@ -56,17 +71,19 @@
|
|||||||
import { onMounted, reactive, ref } from 'vue';
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
import { ElMessageBox, ElNotification } from 'element-plus';
|
import { ElMessageBox, ElNotification } from 'element-plus';
|
||||||
import { throttle } from 'lodash-es';
|
import { throttle } from 'lodash-es';
|
||||||
|
import { signalR } from './signalR';
|
||||||
|
import { VxeGridInstance, VxePagerEvents, VxePagerDefines } from 'vxe-table';
|
||||||
|
import { useVxeTable } from '/@/hooks/vxeTableOptionsHook';
|
||||||
|
|
||||||
import SendMessage from '/@/views/system/onlineUser/component/sendMessage.vue';
|
import SendMessage from '/@/views/system/onlineUser/component/sendMessage.vue';
|
||||||
|
|
||||||
import { getAPI, clearAccessTokens } from '/@/utils/axios-utils';
|
import { getAPI, clearAccessTokens } from '/@/utils/axios-utils';
|
||||||
import { SysOnlineUserApi, SysAuthApi } from '/@/api-services/api';
|
import { SysOnlineUserApi, SysAuthApi } from '/@/api-services/api';
|
||||||
import { SysOnlineUser } from '/@/api-services/models';
|
import { SysOnlineUser } from '/@/api-services/models';
|
||||||
|
|
||||||
import { signalR } from './signalR';
|
const xGrid = ref<VxeGridInstance>();
|
||||||
|
|
||||||
const sendMessageRef = ref<InstanceType<typeof SendMessage>>();
|
const sendMessageRef = ref<InstanceType<typeof SendMessage>>();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
loading: false,
|
|
||||||
isVisible: false,
|
isVisible: false,
|
||||||
queryParams: {
|
queryParams: {
|
||||||
userName: undefined,
|
userName: undefined,
|
||||||
@ -74,8 +91,11 @@ const state = reactive({
|
|||||||
},
|
},
|
||||||
tableParams: {
|
tableParams: {
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 10,
|
pageSize: 50,
|
||||||
total: 1 as any,
|
field: 'id', // 默认的排序字段
|
||||||
|
order: 'aes', // 排序方向
|
||||||
|
descStr: 'desc', // 降序排序的关键字符
|
||||||
|
total: 0 as any,
|
||||||
},
|
},
|
||||||
onlineUserList: [] as Array<SysOnlineUser>, // 在线用户列表
|
onlineUserList: [] as Array<SysOnlineUser>, // 在线用户列表
|
||||||
lastUserState: {
|
lastUserState: {
|
||||||
@ -84,6 +104,27 @@ const state = reactive({
|
|||||||
}, // 最后接收的用户变更状态信息
|
}, // 最后接收的用户变更状态信息
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 表格参数配置
|
||||||
|
const options = useVxeTable<SysOnlineUser>({
|
||||||
|
id: 'sysOnlineUser',
|
||||||
|
name: '在线用户',
|
||||||
|
columns: [
|
||||||
|
// { type: 'checkbox', width: 40, fixed: 'left' },
|
||||||
|
{ type: 'seq', title: '序号', width: 50, fixed: 'left' },
|
||||||
|
{ field: 'userName', title: '账号', minWidth: 110, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'realName', title: '姓名', minWidth: 110, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'ip', title: 'IP地址', minWidth: 100, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'browser', title: '浏览器', minWidth: 160, showOverflow: 'tooltip' },
|
||||||
|
// { field: 'connectionId', title: '连接Id', minWidth: 160, showOverflow: 'tooltip', sortable: true },
|
||||||
|
{ field: 'time', title: '登录时间', minWidth: 120, showOverflow: 'tooltip' },
|
||||||
|
{ title: '操作', fixed: 'right', width: 100, showOverflow: true, slots: { default: 'row_buttons' } },
|
||||||
|
],
|
||||||
|
enableExport: true,
|
||||||
|
searchCallback: () => handleQuery(),
|
||||||
|
queryAllCallback: () => fetchData({ pageSize: 99999 }),
|
||||||
|
});
|
||||||
|
|
||||||
|
// 页面初始化
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
// 在线用户列表
|
// 在线用户列表
|
||||||
signalR.off('OnlineUserList');
|
signalR.off('OnlineUserList');
|
||||||
@ -95,7 +136,6 @@ onMounted(async () => {
|
|||||||
};
|
};
|
||||||
notificationThrottle();
|
notificationThrottle();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 强制下线
|
// 强制下线
|
||||||
signalR.off('ForceOffline');
|
signalR.off('ForceOffline');
|
||||||
signalR.on('ForceOffline', async (data: any) => {
|
signalR.on('ForceOffline', async (data: any) => {
|
||||||
@ -131,13 +171,19 @@ const openDrawer = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 查询操作
|
// 查询操作
|
||||||
const handleQuery = async () => {
|
const handleQuery = async (reset = false) => {
|
||||||
state.loading = true;
|
options.loading = true;
|
||||||
let params = Object.assign(state.queryParams, state.tableParams);
|
if (reset) state.tableParams.page = 1;
|
||||||
var res = await getAPI(SysOnlineUserApi).apiSysOnlineUserPagePost(params);
|
var res = await fetchData(null);
|
||||||
state.onlineUserList = res.data.result?.items ?? [];
|
xGrid.value?.loadData(res.data.result?.items ?? []);
|
||||||
state.tableParams.total = res.data.result?.total;
|
state.tableParams.total = res.data.result?.total;
|
||||||
state.loading = false;
|
options.loading = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取数据
|
||||||
|
const fetchData = async (tableParams: any) => {
|
||||||
|
let params = Object.assign(state.queryParams, state.tableParams, tableParams);
|
||||||
|
return getAPI(SysOnlineUserApi).apiSysOnlineUserPagePost(params);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 重置操作
|
// 重置操作
|
||||||
@ -148,9 +194,9 @@ const resetQuery = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 发送消息
|
// 发送消息
|
||||||
const openSendMessage = (row: any)=>{
|
const openSendMessage = (row: any) => {
|
||||||
sendMessageRef.value?.openDialog(row);
|
sendMessageRef.value?.openDialog(row);
|
||||||
}
|
};
|
||||||
|
|
||||||
// 强制下线
|
// 强制下线
|
||||||
const forceOffline = async (row: any) => {
|
const forceOffline = async (row: any) => {
|
||||||
@ -167,18 +213,38 @@ const forceOffline = async (row: any) => {
|
|||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 改变页面容量
|
// 改变页码序号或页面容量
|
||||||
const handleSizeChange = (val: number) => {
|
const pageChange: VxePagerEvents.PageChange = ({ currentPage, pageSize }: VxePagerDefines.PageChangeEventParams) => {
|
||||||
state.tableParams.pageSize = val;
|
state.tableParams.page = currentPage;
|
||||||
|
state.tableParams.pageSize = pageSize;
|
||||||
handleQuery();
|
handleQuery();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 改变页码序号
|
// 列排序
|
||||||
const handleCurrentChange = (val: number) => {
|
const sortChange = (options: any) => {
|
||||||
state.tableParams.page = val;
|
state.tableParams.field = options.field;
|
||||||
|
state.tableParams.order = options.order;
|
||||||
handleQuery();
|
handleQuery();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 导出对象
|
// 导出对象
|
||||||
defineExpose({ openDrawer });
|
defineExpose({ openDrawer });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
:deep(.el-drawer__body) {
|
||||||
|
padding: 5px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.full-table {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
:deep(.el-card__body) {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@ -20,10 +20,12 @@ connection.serverTimeoutInMilliseconds = 30 * 60 * 1000; // 超时时间30m
|
|||||||
connection.start().then(() => {
|
connection.start().then(() => {
|
||||||
console.log('启动连接');
|
console.log('启动连接');
|
||||||
});
|
});
|
||||||
|
|
||||||
// 断开连接
|
// 断开连接
|
||||||
connection.onclose(async () => {
|
connection.onclose(async () => {
|
||||||
console.log('断开连接');
|
console.log('断开连接');
|
||||||
});
|
});
|
||||||
|
|
||||||
// 重连中
|
// 重连中
|
||||||
connection.onreconnecting(() => {
|
connection.onreconnecting(() => {
|
||||||
ElNotification({
|
ElNotification({
|
||||||
@ -33,6 +35,7 @@ connection.onreconnecting(() => {
|
|||||||
position: 'bottom-right',
|
position: 'bottom-right',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// 重连成功
|
// 重连成功
|
||||||
connection.onreconnected(() => {
|
connection.onreconnected(() => {
|
||||||
console.log('重连成功');
|
console.log('重连成功');
|
||||||
@ -41,7 +44,7 @@ connection.onreconnected(() => {
|
|||||||
connection.on('OnlineUserList', () => {});
|
connection.on('OnlineUserList', () => {});
|
||||||
|
|
||||||
// 接收消息
|
// 接收消息
|
||||||
connection.on("ReceiveMessage", (message: any)=>{
|
connection.on('ReceiveMessage', (message: any) => {
|
||||||
var tmpMsg = `${message.message}<br/>`;
|
var tmpMsg = `${message.message}<br/>`;
|
||||||
tmpMsg += `<p style="color:#808080; font-size:12px">发送人员:${message.sendUserName}<p>`;
|
tmpMsg += `<p style="color:#808080; font-size:12px">发送人员:${message.sendUserName}<p>`;
|
||||||
tmpMsg += `<p style="color:#808080; font-size:12px">发送时间:${message.sendTime}<p>`;
|
tmpMsg += `<p style="color:#808080; font-size:12px">发送时间:${message.sendTime}<p>`;
|
||||||
@ -52,7 +55,7 @@ connection.on("ReceiveMessage", (message: any)=>{
|
|||||||
type: 'info',
|
type: 'info',
|
||||||
position: 'top-right',
|
position: 'top-right',
|
||||||
dangerouslyUseHTMLString: true,
|
dangerouslyUseHTMLString: true,
|
||||||
duration: 0
|
duration: 0,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
||||||
<el-row :gutter="35">
|
<el-row :gutter="10">
|
||||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||||
<el-form-item label="身份标识" prop="accessKey" :rules="[{ required: true, message: '身份标识不能为空', trigger: 'blur' }]">
|
<el-form-item label="身份标识" prop="accessKey" :rules="[{ required: true, message: '身份标识不能为空', trigger: 'blur' }]">
|
||||||
<el-input v-model="state.ruleForm.accessKey" placeholder="身份标识" clearable />
|
<el-input v-model="state.ruleForm.accessKey" placeholder="身份标识" clearable />
|
||||||
@ -69,7 +69,7 @@ const state = reactive({
|
|||||||
});
|
});
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
var res = await getAPI(SysTenantApi).apiSysTenantPagePost({ page: 1, pageSize: 10000 });
|
let res = await getAPI(SysTenantApi).apiSysTenantPagePost({ page: 1, pageSize: 10000 });
|
||||||
state.tenantData = res.data.result?.items ?? [];
|
state.tenantData = res.data.result?.items ?? [];
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -78,7 +78,6 @@ const openDialog = (row: any) => {
|
|||||||
state.ruleForm = JSON.parse(JSON.stringify(row));
|
state.ruleForm = JSON.parse(JSON.stringify(row));
|
||||||
state.isShowDialog = true;
|
state.isShowDialog = true;
|
||||||
ruleFormRef.value?.resetFields();
|
ruleFormRef.value?.resetFields();
|
||||||
|
|
||||||
tenantChange(false);
|
tenantChange(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -78,6 +78,7 @@ const openDialog = () => {
|
|||||||
// 导出对象
|
// 导出对象
|
||||||
defineExpose({ openDialog });
|
defineExpose({ openDialog });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.text-content {
|
.text-content {
|
||||||
h1 {
|
h1 {
|
||||||
|
|||||||
@ -1,125 +1,180 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-open-access-container">
|
<div class="sys-open-access-container" v-loading="options.loading">
|
||||||
<el-card shadow="hover" :body-style="{ paddingBottom: '0' }">
|
<el-card shadow="hover" :body-style="{ padding: '5px 5px 0 5px', display: 'flex', width: '100%', height: '100%', alignItems: 'start' }">
|
||||||
<el-form :model="state.queryParams" ref="queryForm" :inline="true">
|
<el-form :model="state.queryParams" ref="queryForm" :show-message="false" :inlineMessage="true" :label-width="'60px'" style="flex: 1 1 0%">
|
||||||
<el-form-item label="身份标识">
|
<el-row :gutter="10">
|
||||||
<el-input v-model="state.queryParams.accessKey" placeholder="身份标识" clearable />
|
<el-col class="mb5" :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
|
||||||
</el-form-item>
|
<el-form-item label="身份标识" prop="accessKey">
|
||||||
<el-form-item>
|
<el-input v-model="state.queryParams.accessKey" placeholder="身份标识" clearable @keyup.enter.native="handleQuery(true)" />
|
||||||
<el-button-group>
|
</el-form-item>
|
||||||
<el-button type="primary" icon="ele-Search" @click="handleQuery" v-auth="'sysOpenAccess:page'"> 查询 </el-button>
|
</el-col>
|
||||||
<el-button icon="ele-Refresh" @click="resetQuery"> 重置 </el-button>
|
</el-row>
|
||||||
</el-button-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="ele-Plus" @click="openAddOpenAccess" v-auth="'sysOpenAccess:add'"> 新增 </el-button>
|
|
||||||
<el-button icon="ele-QuestionFilled" @click="openHelp"> 说明 </el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
</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="'sysOpenAccess:page'" :loading="options.loading"> 查询 </el-button>
|
||||||
|
<el-button icon="ele-Refresh" @click="resetQuery" :loading="options.loading"> 重置 </el-button>
|
||||||
|
</el-button-group>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
|
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
|
||||||
<el-table :data="state.openAccessData" style="width: 100%" v-loading="state.loading" border>
|
<vxe-grid ref="xGrid" class="xGrid-style" v-bind="options" @sort-change="sortChange">
|
||||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
<template #toolbar_buttons>
|
||||||
<el-table-column prop="accessKey" label="身份标识" header-align="center" show-overflow-tooltip />
|
<el-button type="primary" icon="ele-Plus" @click="handleAdd" v-auth="'sysOpenAccess:add'"> 新增 </el-button>
|
||||||
<el-table-column prop="accessSecret" label="密钥" header-align="center" show-overflow-tooltip />
|
<el-button icon="ele-QuestionFilled" @click="openHelp"> 说明 </el-button>
|
||||||
<el-table-column prop="bindUserAccount" label="绑定用户账号" header-align="center" show-overflow-tooltip />
|
</template>
|
||||||
<el-table-column prop="bindTenantName" label="绑定租户名称" header-align="center" show-overflow-tooltip />
|
<template #toolbar_tools> </template>
|
||||||
<el-table-column label="修改记录" width="100" align="center" show-overflow-tooltip>
|
<template #empty>
|
||||||
<template #default="scope">
|
<el-empty :image-size="200" />
|
||||||
<ModifyRecord :data="scope.row" />
|
</template>
|
||||||
</template>
|
<template #row_record="{ row }">
|
||||||
</el-table-column>
|
<ModifyRecord :data="row" />
|
||||||
<el-table-column label="操作" width="200" fixed="right" align="center" show-overflow-tooltip>
|
</template>
|
||||||
<template #default="scope">
|
<template #row_buttons="{ row }">
|
||||||
<el-button icon="ele-Edit" size="small" text type="primary" @click="openEditOpenAccess(scope.row)" v-auth="'sysOpenAccess:update'" :disabled="scope.row.status === 1"> 编辑 </el-button>
|
<el-tooltip content="编辑" placement="top">
|
||||||
<el-button icon="ele-Delete" size="small" text type="danger" @click="delOpenAccess(scope.row)" v-auth="'sysOpenAccess:delete'" :disabled="scope.row.status === 1"> 删除 </el-button>
|
<el-button icon="ele-Edit" size="small" text type="primary" @click="handleEdit(row)" v-auth="'sysOpenAccess:update'" :disabled="row.status === 1" />
|
||||||
<el-button size="small" text @click="openGenerateSign(scope.row)"> 生成签名 </el-button>
|
</el-tooltip>
|
||||||
</template>
|
<el-tooltip content="删除" placement="top">
|
||||||
</el-table-column>
|
<el-button icon="ele-Delete" size="small" text type="danger" @click="handleDelete(row)" v-auth="'sysOpenAccess:delete'" :disabled="row.status === 1" />
|
||||||
</el-table>
|
</el-tooltip>
|
||||||
<el-pagination
|
<el-tooltip content="生成签名" placement="top">
|
||||||
v-model:currentPage="state.tableParams.page"
|
<el-button icon="ele-EditPen" size="small" text type="warning" @click="handleSign(row)" />
|
||||||
v-model:page-size="state.tableParams.pageSize"
|
</el-tooltip>
|
||||||
:total="state.tableParams.total"
|
</template>
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
<template #pager>
|
||||||
small
|
<vxe-pager
|
||||||
background
|
:loading="options.loading"
|
||||||
@size-change="handleSizeChange"
|
v-model:current-page="state.tableParams.page"
|
||||||
@current-change="handleCurrentChange"
|
v-model:page-size="state.tableParams.pageSize"
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
:total="state.tableParams.total"
|
||||||
/>
|
@page-change="pageChange"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</vxe-grid>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<EditOpenAccess ref="editOpenAccessRef" :title="state.editOpenAccessTitle" @handleQuery="handleQuery" />
|
<EditOpenAccess ref="editRef" :title="state.title" @handleQuery="handleQuery" />
|
||||||
<HelpView ref="helpViewRef" />
|
<HelpView ref="helpRef" />
|
||||||
<GenerateSign ref="generateSignRef" />
|
<GenerateSign ref="signRef" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup name="sysOpenAccess">
|
<script lang="ts" setup name="sysOpenAccess">
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
import { ElMessageBox, ElMessage } from 'element-plus';
|
import { ElMessageBox, ElMessage } from 'element-plus';
|
||||||
|
import { auth } from '/@/utils/authFunction';
|
||||||
|
import { VxeGridInstance, VxePagerEvents, VxePagerDefines } from 'vxe-table';
|
||||||
|
import { useVxeTable } from '/@/hooks/vxeTableOptionsHook';
|
||||||
|
|
||||||
import EditOpenAccess from '/@/views/system/openAccess/component/editOpenAccess.vue';
|
import EditOpenAccess from '/@/views/system/openAccess/component/editOpenAccess.vue';
|
||||||
import HelpView from '/@/views/system/openAccess/component/helpView.vue';
|
import HelpView from '/@/views/system/openAccess/component/helpView.vue';
|
||||||
import ModifyRecord from '/@/components/table/modifyRecord.vue';
|
|
||||||
import GenerateSign from '/@/views/system/openAccess/component/generateSign.vue';
|
import GenerateSign from '/@/views/system/openAccess/component/generateSign.vue';
|
||||||
|
import ModifyRecord from '/@/components/table/modifyRecord.vue';
|
||||||
|
|
||||||
import { getAPI } from '/@/utils/axios-utils';
|
import { getAPI } from '/@/utils/axios-utils';
|
||||||
import { SysOpenAccessApi } from '/@/api-services/api';
|
import { SysOpenAccessApi } from '/@/api-services/api';
|
||||||
import { OpenAccessOutput } from '/@/api-services/models';
|
import { OpenAccessOutput } from '/@/api-services/models';
|
||||||
|
|
||||||
const editOpenAccessRef = ref<InstanceType<typeof EditOpenAccess>>();
|
const xGrid = ref<VxeGridInstance>();
|
||||||
const helpViewRef = ref<InstanceType<typeof HelpView>>();
|
const editRef = ref<InstanceType<typeof EditOpenAccess>>();
|
||||||
const generateSignRef = ref<InstanceType<typeof GenerateSign>>();
|
const helpRef = ref<InstanceType<typeof HelpView>>();
|
||||||
|
const signRef = ref<InstanceType<typeof GenerateSign>>();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
loading: false,
|
|
||||||
openAccessData: [] as Array<OpenAccessOutput>,
|
openAccessData: [] as Array<OpenAccessOutput>,
|
||||||
queryParams: {
|
queryParams: {
|
||||||
accessKey: undefined,
|
accessKey: undefined,
|
||||||
},
|
},
|
||||||
tableParams: {
|
tableParams: {
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 20,
|
pageSize: 50,
|
||||||
|
field: 'id', // 默认的排序字段
|
||||||
|
order: 'aes', // 排序方向
|
||||||
|
descStr: 'desc', // 降序排序的关键字符
|
||||||
total: 0 as any,
|
total: 0 as any,
|
||||||
},
|
},
|
||||||
editOpenAccessTitle: '',
|
title: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 表格参数配置
|
||||||
|
const options = useVxeTable<OpenAccessOutput>({
|
||||||
|
id: 'sysOpenAccess',
|
||||||
|
name: '开发接口身份',
|
||||||
|
columns: [
|
||||||
|
// { type: 'checkbox', width: 40, fixed: 'left' },
|
||||||
|
{ type: 'seq', title: '序号', width: 60, fixed: 'left' },
|
||||||
|
{ field: 'accessKey', title: '身份标识', minWidth: 200, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'accessSecret', title: '密钥', minWidth: 200, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'bindUserAccount', title: '绑定用户账号', minWidth: 200, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'bindTenantName', title: '绑定租户名称', minWidth: 200, showOverflow: 'tooltip' },
|
||||||
|
{ field: '', title: '修改记录', width: 100, showOverflow: 'tooltip', slots: { default: 'row_record' } },
|
||||||
|
{ title: '操作', fixed: 'right', minWidth: 100, showOverflow: true, slots: { default: 'row_buttons' } },
|
||||||
|
],
|
||||||
|
enableExport: auth('sysOpenAccess:export'),
|
||||||
|
searchCallback: () => handleQuery(),
|
||||||
|
queryAllCallback: () => fetchData({ pageSize: 99999 }),
|
||||||
|
});
|
||||||
|
|
||||||
|
// 页面初始化
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
handleQuery();
|
await handleQuery();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 查询操作
|
// 查询操作
|
||||||
const handleQuery = async () => {
|
const handleQuery = async (reset = false) => {
|
||||||
state.loading = true;
|
options.loading = true;
|
||||||
let params = Object.assign(state.queryParams, state.tableParams);
|
if (reset) state.tableParams.page = 1;
|
||||||
var res = await getAPI(SysOpenAccessApi).apiSysOpenAccessPagePost(params);
|
var res = await fetchData(null);
|
||||||
state.openAccessData = res.data.result?.items ?? [];
|
xGrid.value?.loadData(res.data.result?.items ?? []);
|
||||||
state.tableParams.total = res.data.result?.total;
|
state.tableParams.total = res.data.result?.total;
|
||||||
state.loading = false;
|
options.loading = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取数据
|
||||||
|
const fetchData = async (tableParams: any) => {
|
||||||
|
let params = Object.assign(state.queryParams, state.tableParams, tableParams);
|
||||||
|
return getAPI(SysOpenAccessApi).apiSysOpenAccessPagePost(params);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 重置操作
|
// 重置操作
|
||||||
const resetQuery = () => {
|
const resetQuery = () => {
|
||||||
state.queryParams.accessKey = undefined;
|
state.queryParams.accessKey = undefined;
|
||||||
|
handleQuery(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 改变页码序号或页面容量
|
||||||
|
const pageChange: VxePagerEvents.PageChange = ({ currentPage, pageSize }: VxePagerDefines.PageChangeEventParams) => {
|
||||||
|
state.tableParams.page = currentPage;
|
||||||
|
state.tableParams.pageSize = pageSize;
|
||||||
|
handleQuery();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 列排序
|
||||||
|
const sortChange = (options: any) => {
|
||||||
|
state.tableParams.field = options.field;
|
||||||
|
state.tableParams.order = options.order;
|
||||||
handleQuery();
|
handleQuery();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开新增页面
|
// 打开新增页面
|
||||||
const openAddOpenAccess = () => {
|
const handleAdd = () => {
|
||||||
state.editOpenAccessTitle = '添加开放接口身份';
|
state.title = '添加开放接口身份';
|
||||||
editOpenAccessRef.value?.openDialog({ type: 1 });
|
editRef.value?.openDialog({ type: 1 });
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开编辑页面
|
// 打开编辑页面
|
||||||
const openEditOpenAccess = (row: any) => {
|
const handleEdit = (row: any) => {
|
||||||
state.editOpenAccessTitle = '编辑开放接口身份';
|
state.title = '编辑开放接口身份';
|
||||||
editOpenAccessRef.value?.openDialog(row);
|
editRef.value?.openDialog(row);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 删除
|
// 删除
|
||||||
const delOpenAccess = (row: any) => {
|
const handleDelete = (row: any) => {
|
||||||
ElMessageBox.confirm(`确定删除开放接口身份:【${row.accessKey}】?`, '提示', {
|
ElMessageBox.confirm(`确定删除开放接口身份:【${row.accessKey}】?`, '提示', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
@ -133,25 +188,13 @@ const delOpenAccess = (row: any) => {
|
|||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 改变页面容量
|
|
||||||
const handleSizeChange = (val: number) => {
|
|
||||||
state.tableParams.pageSize = val;
|
|
||||||
handleQuery();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 改变页码序号
|
|
||||||
const handleCurrentChange = (val: number) => {
|
|
||||||
state.tableParams.page = val;
|
|
||||||
handleQuery();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 打开说明页面
|
// 打开说明页面
|
||||||
const openHelp = () => {
|
const openHelp = () => {
|
||||||
helpViewRef.value?.openDialog();
|
helpRef.value?.openDialog();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开生成签名
|
// 打开生成签名
|
||||||
const openGenerateSign = (row: any) => {
|
const handleSign = (row: any) => {
|
||||||
generateSignRef.value?.openDialog(row);
|
signRef.value?.openDialog(row);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-plugin-container">
|
<div class="sys-plugin-container">
|
||||||
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="900px">
|
<el-dialog v-model="state.isShowDialog" draggable overflow destroy-on-close width="900px">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div style="color: #fff">
|
<div style="color: #fff">
|
||||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
||||||
@ -10,7 +10,7 @@
|
|||||||
<el-tabs v-model="state.selectedTabName">
|
<el-tabs v-model="state.selectedTabName">
|
||||||
<el-tab-pane label="插件信息">
|
<el-tab-pane label="插件信息">
|
||||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto" style="height: 500px">
|
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto" style="height: 500px">
|
||||||
<el-row :gutter="35">
|
<el-row :gutter="10">
|
||||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||||
<el-form-item label="功能名称" prop="name" :rules="[{ required: true, message: '功能名称不能为空', trigger: 'blur' }]">
|
<el-form-item label="功能名称" prop="name" :rules="[{ required: true, message: '功能名称不能为空', trigger: 'blur' }]">
|
||||||
<el-input v-model="state.ruleForm.name" placeholder="功能名称" clearable />
|
<el-input v-model="state.ruleForm.name" placeholder="功能名称" clearable />
|
||||||
@ -112,7 +112,7 @@ const openDialog = (row: any) => {
|
|||||||
state.isShowDialog = true;
|
state.isShowDialog = true;
|
||||||
ruleFormRef.value?.resetFields();
|
ruleFormRef.value?.resetFields();
|
||||||
|
|
||||||
// 延迟拿值防止取不到
|
// 延迟取值防止取不到
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (monacoEditor == null) initMonacoEditor();
|
if (monacoEditor == null) initMonacoEditor();
|
||||||
}, 1);
|
}, 1);
|
||||||
|
|||||||
@ -1,66 +1,75 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-plugin-container">
|
<div class="sys-plugin-container" v-loading="options.loading">
|
||||||
<el-card shadow="hover" :body-style="{ paddingBottom: '0' }">
|
<el-card shadow="hover" :body-style="{ padding: '5px 5px 0 5px', display: 'flex', width: '100%', height: '100%', alignItems: 'start' }">
|
||||||
<el-form :model="state.queryParams" ref="queryForm" :inline="true">
|
<el-form :model="state.queryParams" ref="queryForm" :show-message="false" :inlineMessage="true" :label-width="'60px'" style="flex: 1 1 0%">
|
||||||
<el-form-item label="功能名称">
|
<el-row :gutter="10">
|
||||||
<el-input v-model="state.queryParams.name" placeholder="功能名称" clearable />
|
<el-col class="mb5" :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
|
||||||
</el-form-item>
|
<el-form-item label="功能名称" pro="name">
|
||||||
<el-form-item>
|
<el-input v-model="state.queryParams.name" placeholder="功能名称" clearable @keyup.enter.native="handleQuery(true)" />
|
||||||
<el-button-group>
|
</el-form-item>
|
||||||
<el-button type="primary" icon="ele-Search" @click="handleQuery" v-auth="'sysPlugin:page'"> 查询 </el-button>
|
</el-col>
|
||||||
<el-button icon="ele-Refresh" @click="resetQuery"> 重置 </el-button>
|
</el-row>
|
||||||
</el-button-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="ele-Plus" @click="openAddPlugin" v-auth="'sysPlugin:add'"> 新增 </el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
</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="'sysPlugin:page'" :loading="options.loading"> 查询 </el-button>
|
||||||
|
<el-button icon="ele-Refresh" @click="resetQuery" :loading="options.loading"> 重置 </el-button>
|
||||||
|
</el-button-group>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
|
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
|
||||||
<el-table :data="state.pluginData" style="width: 100%" v-loading="state.loading" border>
|
<vxe-grid ref="xGrid" class="xGrid-style" v-bind="options" @sort-change="sortChange">
|
||||||
<el-table-column type="index" label="序号" width="55" align="center" fixed />
|
<template #toolbar_buttons>
|
||||||
<el-table-column prop="name" label="功能名称" header-align="center" show-overflow-tooltip />
|
<el-button type="primary" icon="ele-Plus" @click="handleAdd" v-auth="'sysPlugin:add'"> 新增 </el-button>
|
||||||
<el-table-column prop="assemblyName" label="程序集名称" header-align="center" show-overflow-tooltip />
|
</template>
|
||||||
<el-table-column prop="orderNo" label="排序" width="70" align="center" show-overflow-tooltip />
|
<template #toolbar_tools> </template>
|
||||||
<el-table-column label="状态" width="70" align="center" show-overflow-tooltip>
|
<template #empty>
|
||||||
<template #default="scope">
|
<el-empty :image-size="200" />
|
||||||
<el-tag type="success" v-if="scope.row.status === 1">启用</el-tag>
|
</template>
|
||||||
<el-tag type="danger" v-else>禁用</el-tag>
|
<template #row_status="{ row }">
|
||||||
</template>
|
<el-tag v-if="row.status === 1" type="success">启用</el-tag>
|
||||||
</el-table-column>
|
<el-tag v-else type="danger">禁用</el-tag>
|
||||||
<el-table-column label="修改记录" width="100" align="center" show-overflow-tooltip>
|
</template>
|
||||||
<template #default="scope">
|
<template #row_record="{ row }">
|
||||||
<ModifyRecord :data="scope.row" />
|
<ModifyRecord :data="row" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
<template #row_buttons="{ row }">
|
||||||
<el-table-column label="操作" width="140" fixed="right" align="center" show-overflow-tooltip>
|
<el-tooltip content="编辑" placement="top">
|
||||||
<template #default="scope">
|
<el-button icon="ele-Edit" text type="primary" v-auth="'sysPlugin:update'" @click="handleEdit(row)"> </el-button>
|
||||||
<el-button icon="ele-Edit" size="small" text type="primary" @click="openEditPlugin(scope.row)" v-auth="'sysPlugin:update'"> 编辑 </el-button>
|
</el-tooltip>
|
||||||
<el-button icon="ele-Delete" size="small" text type="danger" @click="delPlugin(scope.row)" v-auth="'sysPlugin:delete'"> 删除 </el-button>
|
<el-tooltip content="删除" placement="top">
|
||||||
</template>
|
<el-button icon="ele-Delete" text type="danger" v-auth="'sysPlugin:delete'" @click="handleDelete(row)"> </el-button>
|
||||||
</el-table-column>
|
</el-tooltip>
|
||||||
</el-table>
|
</template>
|
||||||
<el-pagination
|
<template #pager>
|
||||||
v-model:currentPage="state.tableParams.page"
|
<vxe-pager
|
||||||
v-model:page-size="state.tableParams.pageSize"
|
:loading="options.loading"
|
||||||
:total="state.tableParams.total"
|
v-model:current-page="state.tableParams.page"
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
v-model:page-size="state.tableParams.pageSize"
|
||||||
small
|
:total="state.tableParams.total"
|
||||||
background
|
@page-change="pageChange"
|
||||||
@size-change="handleSizeChange"
|
/>
|
||||||
@current-change="handleCurrentChange"
|
</template>
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
</vxe-grid>
|
||||||
/>
|
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<EditPlugin ref="editPluginRef" :title="state.editPluginTitle" @handleQuery="handleQuery" />
|
<EditPlugin ref="editPluginRef" :title="state.title" @handleQuery="handleQuery" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup name="sysPlugin">
|
<script lang="ts" setup name="sysPlugin">
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
import { ElMessageBox, ElMessage } from 'element-plus';
|
import { ElMessageBox, ElMessage } from 'element-plus';
|
||||||
|
import { auth } from '/@/utils/authFunction';
|
||||||
|
import { VxeGridInstance, VxePagerEvents, VxePagerDefines } from 'vxe-table';
|
||||||
|
import { useVxeTable } from '/@/hooks/vxeTableOptionsHook';
|
||||||
|
|
||||||
import EditPlugin from '/@/views/system/plugin/component/editPlugin.vue';
|
import EditPlugin from '/@/views/system/plugin/component/editPlugin.vue';
|
||||||
import ModifyRecord from '/@/components/table/modifyRecord.vue';
|
import ModifyRecord from '/@/components/table/modifyRecord.vue';
|
||||||
|
|
||||||
@ -68,55 +77,97 @@ import { getAPI } from '/@/utils/axios-utils';
|
|||||||
import { SysPluginApi } from '/@/api-services/api';
|
import { SysPluginApi } from '/@/api-services/api';
|
||||||
import { SysPlugin } from '/@/api-services/models';
|
import { SysPlugin } from '/@/api-services/models';
|
||||||
|
|
||||||
|
const xGrid = ref<VxeGridInstance>();
|
||||||
const editPluginRef = ref<InstanceType<typeof EditPlugin>>();
|
const editPluginRef = ref<InstanceType<typeof EditPlugin>>();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
loading: false,
|
|
||||||
pluginData: [] as Array<SysPlugin>,
|
|
||||||
queryParams: {
|
queryParams: {
|
||||||
name: undefined,
|
name: undefined,
|
||||||
},
|
},
|
||||||
tableParams: {
|
tableParams: {
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 20,
|
pageSize: 50,
|
||||||
|
field: 'id', // 默认的排序字段
|
||||||
|
order: 'aes', // 排序方向
|
||||||
|
descStr: 'desc', // 降序排序的关键字符
|
||||||
total: 0 as any,
|
total: 0 as any,
|
||||||
},
|
},
|
||||||
editPluginTitle: '',
|
visible: false,
|
||||||
|
title: '',
|
||||||
|
});
|
||||||
|
//表格参数配置
|
||||||
|
const options = useVxeTable<SysPlugin>({
|
||||||
|
id: 'sysPlugin',
|
||||||
|
name: '插件信息',
|
||||||
|
columns: [
|
||||||
|
// { type: 'checkbox', width: 40, fixed: 'left' },
|
||||||
|
{ type: 'seq', title: '序号', width: 60, fixed: 'left' },
|
||||||
|
{ field: 'name', title: '功能名称', minWidth: 200, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'assemblyName', title: '程序集名称', minWidth: 200, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'orderNo', title: '排序', width: 80, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'status', title: '状态', width: 80, showOverflow: 'tooltip', slots: { default: 'row_status' } },
|
||||||
|
{ field: '', title: '修改记录', width: 100, showOverflow: 'tooltip', slots: { default: 'row_record' } },
|
||||||
|
{ title: '操作', fixed: 'right', width: 100, showOverflow: true, slots: { default: 'row_buttons' } },
|
||||||
|
],
|
||||||
|
enableExport: auth('sysPlugin:export'),
|
||||||
|
searchCallback: () => handleQuery(),
|
||||||
|
queryAllCallback: () => fetchData({ pageSize: 99999 }),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 页面初始化
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
handleQuery();
|
await handleQuery();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 查询操作
|
// 查询操作
|
||||||
const handleQuery = async () => {
|
const handleQuery = async (reset = false) => {
|
||||||
state.loading = true;
|
options.loading = true;
|
||||||
let params = Object.assign(state.queryParams, state.tableParams);
|
if (reset) state.tableParams.page = 1;
|
||||||
var res = await getAPI(SysPluginApi).apiSysPluginPagePost(params);
|
var res = await fetchData(null);
|
||||||
state.pluginData = res.data.result?.items ?? [];
|
xGrid.value?.loadData(res.data.result?.items ?? []);
|
||||||
state.tableParams.total = res.data.result?.total;
|
state.tableParams.total = res.data.result?.total;
|
||||||
state.loading = false;
|
options.loading = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取数据
|
||||||
|
const fetchData = async (tableParams: any) => {
|
||||||
|
let params = Object.assign(state.queryParams, state.tableParams, tableParams);
|
||||||
|
return getAPI(SysPluginApi).apiSysPluginPagePost(params);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 重置操作
|
// 重置操作
|
||||||
const resetQuery = () => {
|
const resetQuery = () => {
|
||||||
state.queryParams.name = undefined;
|
state.queryParams.name = undefined;
|
||||||
|
handleQuery(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 改变页码序号或页面容量
|
||||||
|
const pageChange: VxePagerEvents.PageChange = ({ currentPage, pageSize }: VxePagerDefines.PageChangeEventParams) => {
|
||||||
|
state.tableParams.page = currentPage;
|
||||||
|
state.tableParams.pageSize = pageSize;
|
||||||
|
handleQuery();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 列排序
|
||||||
|
const sortChange = (options: any) => {
|
||||||
|
state.tableParams.field = options.field;
|
||||||
|
state.tableParams.order = options.order;
|
||||||
handleQuery();
|
handleQuery();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开新增页面
|
// 打开新增页面
|
||||||
const openAddPlugin = () => {
|
const handleAdd = () => {
|
||||||
state.editPluginTitle = '添加动态插件';
|
state.title = '添加动态插件';
|
||||||
editPluginRef.value?.openDialog({ orderNo: 100, status: 1 });
|
editPluginRef.value?.openDialog({ status: 1, orderNo: 100 });
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开编辑页面
|
// 打开编辑页面
|
||||||
const openEditPlugin = (row: any) => {
|
const handleEdit = (row: any) => {
|
||||||
state.editPluginTitle = '编辑动态插件';
|
state.title = '编辑动态插件';
|
||||||
editPluginRef.value?.openDialog(row);
|
editPluginRef.value?.openDialog(row);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 删除当前行
|
// 删除
|
||||||
const delPlugin = (row: any) => {
|
const handleDelete = (row: any) => {
|
||||||
ElMessageBox.confirm(`确定删除动态插件:【${row.name}】?`, '提示', {
|
ElMessageBox.confirm(`确定删除动态插件:【${row.name}】?`, '提示', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
@ -129,16 +180,4 @@ const delPlugin = (row: any) => {
|
|||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 改变页面容量
|
|
||||||
const handleSizeChange = (val: number) => {
|
|
||||||
state.tableParams.pageSize = val;
|
|
||||||
handleQuery();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 改变页码序号
|
|
||||||
const handleCurrentChange = (val: number) => {
|
|
||||||
state.tableParams.page = val;
|
|
||||||
handleQuery();
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-print-container">
|
<div class="sys-print-container">
|
||||||
<div class="printDialog">
|
<div class="printDialog">
|
||||||
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" fullscreen>
|
<el-dialog v-model="state.isShowDialog" draggable overflow destroy-on-close fullscreen>
|
||||||
<template #header>
|
<template #header>
|
||||||
<div style="color: #fff">
|
<div style="color: #fff">
|
||||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
||||||
<span> {{ props.title }} </span>
|
<span> {{ props.title }} </span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div style="margin: -16px 0px 0px 0px">
|
<div style="margin: 0px 0px 0px 0px">
|
||||||
<HiprintDesign ref="hiprintDesignRef" />
|
<HiprintDesign ref="hiprintDesignRef" />
|
||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@ -20,7 +20,7 @@
|
|||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-dialog v-model="state.showDialog2" draggable :close-on-click-modal="false" width="600px">
|
<el-dialog v-model="state.showDialog2" draggable overflow destroy-on-close width="600px">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div style="color: #fff">
|
<div style="color: #fff">
|
||||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
||||||
@ -28,7 +28,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
||||||
<el-row :gutter="35">
|
<el-row :gutter="10">
|
||||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||||
<el-form-item label="模板名称" prop="name" :rules="[{ required: true, message: '模板名称不能为空', trigger: 'blur' }]">
|
<el-form-item label="模板名称" prop="name" :rules="[{ required: true, message: '模板名称不能为空', trigger: 'blur' }]">
|
||||||
<el-input v-model="state.ruleForm.name" placeholder="模板名称" clearable />
|
<el-input v-model="state.ruleForm.name" placeholder="模板名称" clearable />
|
||||||
@ -104,6 +104,7 @@ const state = reactive({
|
|||||||
showDialog2: false,
|
showDialog2: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 页面初始化
|
||||||
onMounted(async () => {});
|
onMounted(async () => {});
|
||||||
|
|
||||||
// 打开弹窗
|
// 打开弹窗
|
||||||
@ -168,6 +169,7 @@ defineExpose({ openDialog });
|
|||||||
}
|
}
|
||||||
.el-dialog__body {
|
.el-dialog__body {
|
||||||
max-height: calc(100vh - 80px) !important;
|
max-height: calc(100vh - 80px) !important;
|
||||||
|
height: calc(100vh - 80px) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -70,19 +70,19 @@
|
|||||||
|
|
||||||
<el-row :gutter="8">
|
<el-row :gutter="8">
|
||||||
<el-col :span="4">
|
<el-col :span="4">
|
||||||
<el-card style="height: 100%" shadow="never">
|
<el-card style="height: 100%" shadow="never" :body-style="{ padding: '0px 0 5px 7px' }">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="24" id="hiprintEpContainer" class="rect-printElement-types hiprintEpContainer"> </el-col>
|
<el-col :span="24" id="hiprintEpContainer" class="rect-printElement-types hiprintEpContainer"> </el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="14">
|
<el-col :span="14">
|
||||||
<el-card shadow="never" class="card-design">
|
<el-card shadow="never" class="card-design" :body-style="{ padding: '18px' }">
|
||||||
<div id="hiprint-printTemplate" class="hiprint-printTemplate"></div>
|
<div id="hiprint-printTemplate" class="hiprint-printTemplate"></div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6" class="params_setting_container">
|
<el-col :span="6" class="params_setting_container">
|
||||||
<el-card shadow="never">
|
<el-card shadow="never" :body-style="{ padding: '0px' }">
|
||||||
<el-row class="hinnn-layout-sider">
|
<el-row class="hinnn-layout-sider">
|
||||||
<div id="PrintElementOptionSetting"></div>
|
<div id="PrintElementOptionSetting"></div>
|
||||||
</el-row>
|
</el-row>
|
||||||
@ -181,7 +181,6 @@ const changeMode = () => {
|
|||||||
hiprint.init({
|
hiprint.init({
|
||||||
providers: [provider.f],
|
providers: [provider.f],
|
||||||
});
|
});
|
||||||
|
|
||||||
// 渲染自定义选项
|
// 渲染自定义选项
|
||||||
const hiprintEpContainerEl = document.getElementById('hiprintEpContainer');
|
const hiprintEpContainerEl = document.getElementById('hiprintEpContainer');
|
||||||
if (hiprintEpContainerEl) {
|
if (hiprintEpContainerEl) {
|
||||||
@ -212,7 +211,7 @@ const changeMode = () => {
|
|||||||
});
|
});
|
||||||
hiprintTemplate.value.design('#hiprint-printTemplate');
|
hiprintTemplate.value.design('#hiprint-printTemplate');
|
||||||
// 获取当前放大比例, 当zoom时传true才会有
|
// 获取当前放大比例, 当zoom时传true才会有
|
||||||
state.scaleValue = hiprintTemplate.value.editingPanel.scale || 1;
|
state.scaleValue = hiprintTemplate.value.editingPanel?.scale ?? 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -239,7 +238,7 @@ const changeScale = (currentValue: number, oldValue: number) => {
|
|||||||
let big = false;
|
let big = false;
|
||||||
currentValue <= oldValue ? (big = false) : (big = true);
|
currentValue <= oldValue ? (big = false) : (big = true);
|
||||||
|
|
||||||
let scaleVal = state.scaleValue;
|
let scaleVal = currentValue;
|
||||||
if (big) {
|
if (big) {
|
||||||
if (scaleVal > state.scaleMax) scaleVal = 5;
|
if (scaleVal > state.scaleMax) scaleVal = 5;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -1,66 +1,75 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-print-container">
|
<div class="sys-print-container" v-loading="options.loading">
|
||||||
<el-card shadow="hover" :body-style="{ paddingBottom: '0' }">
|
<el-card shadow="hover" :body-style="{ padding: '5px 5px 0 5px', display: 'flex', width: '100%', height: '100%', alignItems: 'start' }">
|
||||||
<el-form :model="state.queryParams" ref="queryForm" :inline="true">
|
<el-form :model="state.queryParams" ref="queryForm" :show-message="false" :inlineMessage="true" :label-width="'60px'" style="flex: 1 1 0%">
|
||||||
<el-form-item label="模板名称">
|
<el-row :gutter="10">
|
||||||
<el-input v-model="state.queryParams.name" placeholder="模板名称" clearable />
|
<el-col class="mb5" :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
|
||||||
</el-form-item>
|
<el-form-item label="模板名称" prop="name">
|
||||||
<el-form-item>
|
<el-input v-model="state.queryParams.name" placeholder="模板名称" clearable @keyup.enter.native="handleQuery(true)" />
|
||||||
<el-button-group>
|
</el-form-item>
|
||||||
<el-button type="primary" icon="ele-Search" @click="handleQuery" v-auth="'sysPrint:page'"> 查询 </el-button>
|
</el-col>
|
||||||
<el-button icon="ele-Refresh" @click="resetQuery"> 重置 </el-button>
|
</el-row>
|
||||||
</el-button-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="ele-Plus" @click="openAddPrint" v-auth="'sysPrint:add'"> 新增 </el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
</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="'sysPrint:page'" :loading="options.loading"> 查询 </el-button>
|
||||||
|
<el-button icon="ele-Refresh" @click="resetQuery" :loading="options.loading"> 重置 </el-button>
|
||||||
|
</el-button-group>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
|
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
|
||||||
<el-table :data="state.printData" style="width: 100%" v-loading="state.loading" border>
|
<vxe-grid ref="xGrid" class="xGrid-style" v-bind="options" @sort-change="sortChange">
|
||||||
<el-table-column type="index" label="序号" width="55" align="center" fixed />
|
<template #toolbar_buttons>
|
||||||
<el-table-column prop="name" label="名称" header-align="center" show-overflow-tooltip />
|
<el-button type="primary" icon="ele-Plus" @click="handleAdd" v-auth="'sysPrint:add'"> 新增 </el-button>
|
||||||
<!-- <el-table-column prop="template" label="模板" show-overflow-tooltip /> -->
|
</template>
|
||||||
<el-table-column prop="orderNo" label="排序" align="center" show-overflow-tooltip />
|
<template #toolbar_tools> </template>
|
||||||
<el-table-column label="状态" align="center" show-overflow-tooltip>
|
<template #empty>
|
||||||
<template #default="scope">
|
<el-empty :image-size="200" />
|
||||||
<el-tag type="success" v-if="scope.row.status === 1">启用</el-tag>
|
</template>
|
||||||
<el-tag type="danger" v-else>禁用</el-tag>
|
<template #row_status="{ row }">
|
||||||
</template>
|
<el-tag v-if="row.status === 1" type="success">启用</el-tag>
|
||||||
</el-table-column>
|
<el-tag v-else type="danger">禁用</el-tag>
|
||||||
<el-table-column label="修改记录" width="100" align="center" show-overflow-tooltip>
|
</template>
|
||||||
<template #default="scope">
|
<template #row_record="{ row }">
|
||||||
<ModifyRecord :data="scope.row" />
|
<ModifyRecord :data="row" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
<template #row_buttons="{ row }">
|
||||||
<el-table-column label="操作" width="140" fixed="right" align="center" show-overflow-tooltip>
|
<el-tooltip content="编辑" placement="top">
|
||||||
<template #default="scope">
|
<el-button icon="ele-Edit" text type="primary" v-auth="'sysPrint:update'" @click="handleEdit(row)"> </el-button>
|
||||||
<el-button icon="ele-Edit" size="small" text type="primary" @click="openEditPrint(scope.row)" v-auth="'sysPrint:update'"> 编辑 </el-button>
|
</el-tooltip>
|
||||||
<el-button icon="ele-Delete" size="small" text type="danger" @click="delPrint(scope.row)" v-auth="'sysPrint:delete'"> 删除 </el-button>
|
<el-tooltip content="删除" placement="top">
|
||||||
</template>
|
<el-button icon="ele-Delete" text type="danger" v-auth="'sysPrint:delete'" @click="handleDelete(row)"> </el-button>
|
||||||
</el-table-column>
|
</el-tooltip>
|
||||||
</el-table>
|
</template>
|
||||||
<el-pagination
|
<template #pager>
|
||||||
v-model:currentPage="state.tableParams.page"
|
<vxe-pager
|
||||||
v-model:page-size="state.tableParams.pageSize"
|
:loading="options.loading"
|
||||||
:total="state.tableParams.total"
|
v-model:current-page="state.tableParams.page"
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
v-model:page-size="state.tableParams.pageSize"
|
||||||
small
|
:total="state.tableParams.total"
|
||||||
background
|
@page-change="pageChange"
|
||||||
@size-change="handleSizeChange"
|
/>
|
||||||
@current-change="handleCurrentChange"
|
</template>
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
</vxe-grid>
|
||||||
/>
|
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<EditPrint ref="editPrintRef" :title="state.editPrintTitle" @handleQuery="handleQuery" />
|
<EditPrint ref="editPrintRef" :title="state.title" @handleQuery="handleQuery" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup name="sysPrint">
|
<script lang="ts" setup name="sysPrint">
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
import { ElMessageBox, ElMessage } from 'element-plus';
|
import { ElMessageBox, ElMessage } from 'element-plus';
|
||||||
|
import { auth } from '/@/utils/authFunction';
|
||||||
|
import { VxeGridInstance, VxePagerEvents, VxePagerDefines } from 'vxe-table';
|
||||||
|
import { useVxeTable } from '/@/hooks/vxeTableOptionsHook';
|
||||||
|
|
||||||
import EditPrint from '/@/views/system/print/component/editPrint.vue';
|
import EditPrint from '/@/views/system/print/component/editPrint.vue';
|
||||||
import ModifyRecord from '/@/components/table/modifyRecord.vue';
|
import ModifyRecord from '/@/components/table/modifyRecord.vue';
|
||||||
|
|
||||||
@ -68,55 +77,100 @@ import { getAPI } from '/@/utils/axios-utils';
|
|||||||
import { SysPrintApi } from '/@/api-services/api';
|
import { SysPrintApi } from '/@/api-services/api';
|
||||||
import { SysPrint } from '/@/api-services/models';
|
import { SysPrint } from '/@/api-services/models';
|
||||||
|
|
||||||
|
const xGrid = ref<VxeGridInstance>();
|
||||||
const editPrintRef = ref<InstanceType<typeof EditPrint>>();
|
const editPrintRef = ref<InstanceType<typeof EditPrint>>();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
loading: false,
|
|
||||||
printData: [] as Array<SysPrint>,
|
|
||||||
queryParams: {
|
queryParams: {
|
||||||
name: undefined,
|
name: undefined,
|
||||||
},
|
},
|
||||||
tableParams: {
|
tableParams: {
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 10,
|
pageSize: 50,
|
||||||
|
field: 'id', // 默认的排序字段
|
||||||
|
order: 'aes', // 排序方向
|
||||||
|
descStr: 'desc', // 降序排序的关键字符
|
||||||
total: 0 as any,
|
total: 0 as any,
|
||||||
},
|
},
|
||||||
editPrintTitle: '',
|
visible: false,
|
||||||
|
title: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 表格参数配置
|
||||||
|
const options = useVxeTable<SysPrint>({
|
||||||
|
id: 'sysPrint',
|
||||||
|
name: '打印信息',
|
||||||
|
columns: [
|
||||||
|
// { type: 'checkbox', width: 40, fixed: 'left' },
|
||||||
|
{ type: 'seq', title: '序号', width: 60, fixed: 'left' },
|
||||||
|
{ field: 'name', title: '名称', minWidth: 250, showOverflow: 'tooltip' },
|
||||||
|
// { field: 'template', title: '模板', minWidth: 200, showOverflow: 'tooltip', sortable: true },
|
||||||
|
{ field: 'createTime', title: '修改时间', minWidth: 150, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'remark', title: '备注', minWidth: 250, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'orderNo', title: '排序', width: 80, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'status', title: '状态', width: 100, showOverflow: 'tooltip', slots: { default: 'row_status' } },
|
||||||
|
{ field: '', title: '修改记录', width: 100, showOverflow: 'tooltip', slots: { default: 'row_record' } },
|
||||||
|
{ title: '操作', fixed: 'right', width: 100, showOverflow: true, slots: { default: 'row_buttons' } },
|
||||||
|
],
|
||||||
|
enableExport: auth('sysPrint:export'),
|
||||||
|
searchCallback: () => handleQuery(),
|
||||||
|
queryAllCallback: () => fetchData({ pageSize: 99999 }),
|
||||||
|
});
|
||||||
|
|
||||||
|
// 页面初始化
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
handleQuery();
|
await handleQuery();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 查询操作
|
// 查询操作
|
||||||
const handleQuery = async () => {
|
const handleQuery = async (reset = false) => {
|
||||||
state.loading = true;
|
options.loading = true;
|
||||||
let params = Object.assign(state.queryParams, state.tableParams);
|
if (reset) state.tableParams.page = 1;
|
||||||
var res = await getAPI(SysPrintApi).apiSysPrintPagePost(params);
|
var res = await fetchData(null);
|
||||||
state.printData = res.data.result?.items ?? [];
|
xGrid.value?.loadData(res.data.result?.items ?? []);
|
||||||
state.tableParams.total = res.data.result?.total;
|
state.tableParams.total = res.data.result?.total;
|
||||||
state.loading = false;
|
options.loading = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取数据
|
||||||
|
const fetchData = async (tableParams: any) => {
|
||||||
|
let params = Object.assign(state.queryParams, state.tableParams, tableParams);
|
||||||
|
return getAPI(SysPrintApi).apiSysPrintPagePost(params);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 重置操作
|
// 重置操作
|
||||||
const resetQuery = () => {
|
const resetQuery = () => {
|
||||||
state.queryParams.name = undefined;
|
state.queryParams.name = undefined;
|
||||||
|
handleQuery(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 改变页码序号或页面容量
|
||||||
|
const pageChange: VxePagerEvents.PageChange = ({ currentPage, pageSize }: VxePagerDefines.PageChangeEventParams) => {
|
||||||
|
state.tableParams.page = currentPage;
|
||||||
|
state.tableParams.pageSize = pageSize;
|
||||||
|
handleQuery();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 列排序
|
||||||
|
const sortChange = (options: any) => {
|
||||||
|
state.tableParams.field = options.field;
|
||||||
|
state.tableParams.order = options.order;
|
||||||
handleQuery();
|
handleQuery();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开新增页面
|
// 打开新增页面
|
||||||
const openAddPrint = () => {
|
const handleAdd = () => {
|
||||||
state.editPrintTitle = '添加打印模板';
|
state.title = '添加打印模板';
|
||||||
editPrintRef.value?.openDialog({});
|
editPrintRef.value?.openDialog({});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开编辑页面
|
// 打开编辑页面
|
||||||
const openEditPrint = (row: any) => {
|
const handleEdit = (row: any) => {
|
||||||
state.editPrintTitle = '编辑打印模板';
|
state.title = '编辑打印模板';
|
||||||
editPrintRef.value?.openDialog(row);
|
editPrintRef.value?.openDialog(row);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 删除当前行
|
// 删除
|
||||||
const delPrint = (row: any) => {
|
const handleDelete = (row: any) => {
|
||||||
ElMessageBox.confirm(`确定删除打印模板:【${row.name}】?`, '提示', {
|
ElMessageBox.confirm(`确定删除打印模板:【${row.name}】?`, '提示', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
@ -129,16 +183,4 @@ const delPrint = (row: any) => {
|
|||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 改变页面容量
|
|
||||||
const handleSizeChange = (val: number) => {
|
|
||||||
state.tableParams.pageSize = val;
|
|
||||||
handleQuery();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 改变页码序号
|
|
||||||
const handleCurrentChange = (val: number) => {
|
|
||||||
state.tableParams.page = val;
|
|
||||||
handleQuery();
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-region-container">
|
<div class="sys-region-container">
|
||||||
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="700px">
|
<el-dialog v-model="state.isShowDialog" draggable overflow destroy-on-close width="700px">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div style="color: #fff">
|
<div style="color: #fff">
|
||||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
||||||
@ -8,7 +8,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
||||||
<el-row :gutter="35">
|
<el-row :gutter="10">
|
||||||
<!-- <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
<!-- <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||||
<el-form-item label="上级名称">
|
<el-form-item label="上级名称">
|
||||||
<el-cascader
|
<el-cascader
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-card class="box-card" shadow="hover" style="height: 100%" body-style="height:100%; overflow:auto">
|
<el-card class="box-card" shadow="hover" body-style="height:100%; overflow:auto;padding:5px;">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<div class="tree-h-flex">
|
<div class="tree-h-flex">
|
||||||
<div class="tree-h-left">
|
<div class="tree-h-left">
|
||||||
<el-input :prefix-icon="Search" v-model="filterText" placeholder="行政区域名称" />
|
<el-input :prefix-icon="Search" v-model="filterText" clearable placeholder="行政区域名称" />
|
||||||
</div>
|
</div>
|
||||||
<div class="tree-h-right">
|
<div class="tree-h-right">
|
||||||
<el-dropdown @command="handleCommand">
|
<el-dropdown @command="handleCommand">
|
||||||
@ -27,20 +27,22 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div style="margin-bottom: 45px" v-loading="state.loading">
|
<div style="margin-bottom: 45px" v-loading="state.loading">
|
||||||
<el-tree
|
<el-scrollbar>
|
||||||
ref="treeRef"
|
<el-tree
|
||||||
class="filter-tree"
|
ref="treeRef"
|
||||||
:data="state.regionData"
|
class="filter-tree"
|
||||||
node-key="id"
|
:data="state.regionData"
|
||||||
:props="{ children: 'children', label: 'name' }"
|
node-key="id"
|
||||||
:filter-node-method="filterNode"
|
:props="{ children: 'children', label: 'name' }"
|
||||||
@node-click="nodeClick"
|
:filter-node-method="filterNode"
|
||||||
highlight-current
|
@node-click="nodeClick"
|
||||||
check-strictly
|
highlight-current
|
||||||
accordion
|
check-strictly
|
||||||
lazy
|
accordion
|
||||||
:load="loadNode"
|
lazy
|
||||||
/>
|
:load="loadNode"
|
||||||
|
/>
|
||||||
|
</el-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</template>
|
</template>
|
||||||
@ -49,6 +51,7 @@
|
|||||||
import { onMounted, reactive, ref, watch } from 'vue';
|
import { onMounted, reactive, ref, watch } from 'vue';
|
||||||
import type { ElTree } from 'element-plus';
|
import type { ElTree } from 'element-plus';
|
||||||
import { Search, MoreFilled } from '@element-plus/icons-vue';
|
import { Search, MoreFilled } from '@element-plus/icons-vue';
|
||||||
|
import { TreeKey } from 'element-plus/es/components/tree/src/tree.type';
|
||||||
|
|
||||||
import { getAPI } from '/@/utils/axios-utils';
|
import { getAPI } from '/@/utils/axios-utils';
|
||||||
import { SysRegionApi } from '/@/api-services/api';
|
import { SysRegionApi } from '/@/api-services/api';
|
||||||
@ -62,14 +65,14 @@ const state = reactive({
|
|||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
initTreeData();
|
fetchTreeData();
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(filterText, (val) => {
|
watch(filterText, (val) => {
|
||||||
treeRef.value!.filter(val);
|
treeRef.value!.filter(val);
|
||||||
});
|
});
|
||||||
|
|
||||||
const initTreeData = async () => {
|
const fetchTreeData = async () => {
|
||||||
state.loading = true;
|
state.loading = true;
|
||||||
var res = await getAPI(SysRegionApi).apiSysRegionListGet(0);
|
var res = await getAPI(SysRegionApi).apiSysRegionListGet(0);
|
||||||
state.regionData = res.data.result ?? [];
|
state.regionData = res.data.result ?? [];
|
||||||
@ -106,8 +109,9 @@ const handleCommand = async (command: string | number | object) => {
|
|||||||
treeRef.value!.store._getAllNodes()[i].expanded = false;
|
treeRef.value!.store._getAllNodes()[i].expanded = false;
|
||||||
}
|
}
|
||||||
} else if ('refresh' == command) {
|
} else if ('refresh' == command) {
|
||||||
initTreeData();
|
fetchTreeData();
|
||||||
} else if ('rootNode' == command) {
|
} else if ('rootNode' == command) {
|
||||||
|
treeRef.value?.setCurrentKey();
|
||||||
emits('node-click', { id: 0, name: '' });
|
emits('node-click', { id: 0, name: '' });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -118,11 +122,22 @@ const nodeClick = (node: any) => {
|
|||||||
emits('node-click', { id: node.id, name: node.name });
|
emits('node-click', { id: node.id, name: node.name });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 设置当前选中节点
|
||||||
|
const setCurrentKey = (key?: TreeKey | undefined, shouldAutoExpandParent?: boolean | undefined) => {
|
||||||
|
treeRef.value?.setCurrentKey(key, shouldAutoExpandParent);
|
||||||
|
};
|
||||||
|
|
||||||
// 导出对象
|
// 导出对象
|
||||||
defineExpose({ initTreeData, getCheckedKeys });
|
defineExpose({ fetchTreeData, getCheckedKeys, setCurrentKey });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
.box-card {
|
||||||
|
flex: 1;
|
||||||
|
> :deep(.el-card__header) {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
.tree-h-flex {
|
.tree-h-flex {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,68 +1,86 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-region-container">
|
<div class="sys-region-container" v-loading="options.loading">
|
||||||
<el-row :gutter="8" style="width: 100%; flex: 1">
|
<el-row :gutter="5" style="width: 100%; height: 100%">
|
||||||
<el-col :span="6" :xs="24">
|
<el-col :span="6" :xs="24" style="display: flex; height: 100%">
|
||||||
<RegionTree ref="regionTreeRef" @node-click="nodeClick" />
|
<RegionTree ref="regionTreeRef" @node-click="handleNodeChange" />
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="18" :xs="24" style="display: flex; flex-direction: column">
|
<el-col :span="18" :xs="24" style="display: flex; flex-direction: column; height: 100%">
|
||||||
<el-card shadow="hover" :body-style="{ paddingBottom: '0' }">
|
<el-card shadow="hover" :body-style="{ padding: '5px 5px 0 5px', display: 'flex', width: '100%', height: '100%', alignItems: 'start' }">
|
||||||
<el-form :model="state.queryParams" ref="queryForm" :inline="true">
|
<el-form :model="state.queryParams" ref="queryForm" :show-message="false" :inlineMessage="true" :label-width="'60px'" style="flex: 1 1 0%">
|
||||||
<el-form-item label="行政名称">
|
<el-row :gutter="10">
|
||||||
<el-input v-model="state.queryParams.name" placeholder="行政名称" clearable />
|
<el-col class="mb5" :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
|
||||||
</el-form-item>
|
<el-form-item label="行政名称" prop="name">
|
||||||
<el-form-item label="行政代码">
|
<el-input v-model="state.queryParams.name" placeholder="行政名称" clearable @keyup.enter.native="handleQuery(true)" />
|
||||||
<el-input v-model="state.queryParams.code" placeholder="行政代码" clearable />
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
<el-form-item>
|
<el-col class="mb5" :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
|
||||||
<el-button-group>
|
<el-form-item label="行政代码" prop="code">
|
||||||
<el-button type="primary" icon="ele-Search" @click="handleQuery" v-auth="'sysRegion:page'"> 查询 </el-button>
|
<el-input v-model="state.queryParams.code" placeholder="行政代码" clearable @keyup.enter.native="handleQuery(true)" />
|
||||||
<el-button icon="ele-Refresh" @click="resetQuery"> 重置 </el-button>
|
</el-form-item>
|
||||||
</el-button-group>
|
</el-col>
|
||||||
</el-form-item>
|
</el-row>
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="ele-Plus" @click="openAddRegion" v-auth="'sysRegion:add'"> 新增 </el-button>
|
|
||||||
<el-button type="danger" icon="ele-Lightning" @click="handlSync" v-auth="'sysRegion:sync'"> 同步统计局 </el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
</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="'sysRegion:page'" :loading="options.loading"> 查询 </el-button>
|
||||||
|
<el-button icon="ele-Refresh" @click="resetQuery" :loading="options.loading"> 重置 </el-button>
|
||||||
|
</el-button-group>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
|
<el-card class="full-table" shadow="hover" style="margin-top: 5px; flex: 1">
|
||||||
<el-table :data="state.regionData" style="width: 100%" v-loading="state.loading" row-key="id" default-expand-all :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" border>
|
<vxe-grid ref="xGrid" class="xGrid-style" v-bind="options" :tree-config="{ transform: true, parentField: 'pid' }" @sort-change="sortChange">
|
||||||
<el-table-column prop="name" label="行政名称" align="center" show-overflow-tooltip />
|
<template #toolbar_buttons>
|
||||||
<el-table-column prop="code" label="行政代码" align="center" show-overflow-tooltip />
|
<el-button type="primary" icon="ele-Plus" @click="handleAdd" v-auth="'sysRegion:add'"> 新增 </el-button>
|
||||||
<el-table-column prop="cityCode" label="区号" align="center" show-overflow-tooltip />
|
<el-button type="danger" icon="ele-Lightning" @click="handlSync" v-auth="'sysRegion:add'"> 同步统计局 </el-button>
|
||||||
<el-table-column prop="orderNo" label="排序" width="70" align="center" show-overflow-tooltip />
|
<el-button-group style="padding-left: 12px">
|
||||||
<el-table-column prop="remark" label="备注" header-align="center" show-overflow-tooltip />
|
<el-button type="primary" icon="ele-Expand" @click="handleExpand"> 全部展开 </el-button>
|
||||||
<el-table-column label="操作" width="140" fixed="right" align="center" show-overflow-tooltip>
|
<el-button type="primary" icon="ele-Fold" @click="handleFold"> 全部折叠 </el-button>
|
||||||
<template #default="scope">
|
</el-button-group>
|
||||||
<el-button icon="ele-Edit" size="small" text type="primary" @click="openEditRegion(scope.row)" v-auth="'sysRegion:update'"> 编辑 </el-button>
|
</template>
|
||||||
<el-button icon="ele-Delete" size="small" text type="danger" @click="delRegion(scope.row)" v-auth="'sysRegion:delete'"> 删除 </el-button>
|
<template #toolbar_tools> </template>
|
||||||
</template>
|
<template #empty>
|
||||||
</el-table-column>
|
<el-empty :image-size="200" />
|
||||||
</el-table>
|
</template>
|
||||||
<el-pagination
|
<template #row_buttons="{ row }">
|
||||||
v-model:currentPage="state.tableParams.page"
|
<el-tooltip content="编辑" placement="top">
|
||||||
v-model:page-size="state.tableParams.pageSize"
|
<el-button icon="ele-Edit" text type="primary" v-auth="'sysRegion:update'" @click="handleEdit(row)"> </el-button>
|
||||||
:total="state.tableParams.total"
|
</el-tooltip>
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
<el-tooltip content="删除" placement="top">
|
||||||
small
|
<el-button icon="ele-Delete" text type="danger" v-auth="'sysRegion:delete'" @click="handleDelete(row)"> </el-button>
|
||||||
background
|
</el-tooltip>
|
||||||
@size-change="handleSizeChange"
|
</template>
|
||||||
@current-change="handleCurrentChange"
|
<template #pager>
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
<vxe-pager
|
||||||
/>
|
:loading="options.loading"
|
||||||
|
v-model:current-page="state.tableParams.page"
|
||||||
|
v-model:page-size="state.tableParams.pageSize"
|
||||||
|
:total="state.tableParams.total"
|
||||||
|
@page-change="pageChange"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</vxe-grid>
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<EditRegion ref="editRegionRef" :title="state.editRegionTitle" @handleQuery="handleQuery" />
|
<EditRegion ref="editRegionRef" :title="state.title" @handleQuery="handleQuery" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup name="sysRegion">
|
<script lang="ts" setup name="sysRegion">
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
import { nextTick, onMounted, reactive, ref } from 'vue';
|
||||||
import { ElMessageBox, ElMessage, ElNotification } from 'element-plus';
|
import { ElMessageBox, ElMessage, ElNotification } from 'element-plus';
|
||||||
|
import { auth } from '/@/utils/authFunction';
|
||||||
|
import { VxeGridInstance, VxePagerEvents, VxePagerDefines } from 'vxe-table';
|
||||||
|
import { useVxeTable } from '/@/hooks/vxeTableOptionsHook';
|
||||||
|
|
||||||
import RegionTree from '/@/views/system/region/component/regionTree.vue';
|
import RegionTree from '/@/views/system/region/component/regionTree.vue';
|
||||||
import EditRegion from '/@/views/system/region/component/editRegion.vue';
|
import EditRegion from '/@/views/system/region/component/editRegion.vue';
|
||||||
|
|
||||||
@ -70,11 +88,10 @@ import { getAPI } from '/@/utils/axios-utils';
|
|||||||
import { SysRegionApi } from '/@/api-services/api';
|
import { SysRegionApi } from '/@/api-services/api';
|
||||||
import { SysRegion } from '/@/api-services/models';
|
import { SysRegion } from '/@/api-services/models';
|
||||||
|
|
||||||
|
const xGrid = ref<VxeGridInstance>();
|
||||||
const editRegionRef = ref<InstanceType<typeof EditRegion>>();
|
const editRegionRef = ref<InstanceType<typeof EditRegion>>();
|
||||||
const regionTreeRef = ref<InstanceType<typeof RegionTree>>();
|
const regionTreeRef = ref<InstanceType<typeof RegionTree>>();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
loading: false,
|
|
||||||
regionData: [] as Array<SysRegion>, // 列表数据
|
|
||||||
queryParams: {
|
queryParams: {
|
||||||
id: -1,
|
id: -1,
|
||||||
pid: undefined,
|
pid: undefined,
|
||||||
@ -83,24 +100,61 @@ const state = reactive({
|
|||||||
},
|
},
|
||||||
tableParams: {
|
tableParams: {
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 20,
|
pageSize: 50,
|
||||||
|
field: 'id', // 默认的排序字段
|
||||||
|
order: 'aes', // 排序方向
|
||||||
|
descStr: 'desc', // 降序排序的关键字符
|
||||||
total: 0 as any,
|
total: 0 as any,
|
||||||
},
|
},
|
||||||
editRegionTitle: '',
|
visible: false,
|
||||||
|
title: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
// 表格参数配置
|
||||||
handleQuery();
|
const options = useVxeTable<SysRegion>({
|
||||||
|
id: 'sysRegion',
|
||||||
|
name: '区域信息',
|
||||||
|
columns: [
|
||||||
|
// { type: 'checkbox', width: 40, fixed: 'left' },
|
||||||
|
{ type: 'seq', title: '序号', width: 100, fixed: 'left' },
|
||||||
|
{ field: 'name', title: '行政名称', minWidth: 280, showOverflow: 'tooltip', treeNode: true },
|
||||||
|
{ field: 'code', title: '行政代码', minWidth: 120, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'cityCode', title: '区号', minWidth: 100, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'orderNo', title: '排序', minWidth: 80, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'createTime', title: '修改时间', minWidth: 150, showOverflow: 'tooltip' },
|
||||||
|
{ field: 'remark', title: '备注', minWidth: 300, showOverflow: 'tooltip' },
|
||||||
|
{ title: '操作', fixed: 'right', width: 100, showOverflow: true, slots: { default: 'row_buttons' } },
|
||||||
|
],
|
||||||
|
enableExport: auth('sysRegion:export'),
|
||||||
|
searchCallback: () => handleQuery(),
|
||||||
|
queryAllCallback: () => fetchData({ pageSize: 99999 }),
|
||||||
|
});
|
||||||
|
|
||||||
|
// 页面初始化
|
||||||
|
onMounted(async () => {
|
||||||
|
await handleQuery();
|
||||||
|
// 展开表格所有数据,数据量大时请勿开启
|
||||||
|
nextTick(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
xGrid.value?.setAllTreeExpand(true);
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// 查询操作
|
// 查询操作
|
||||||
const handleQuery = async () => {
|
const handleQuery = async (reset = false) => {
|
||||||
state.loading = true;
|
options.loading = true;
|
||||||
let params = Object.assign(state.queryParams, state.tableParams);
|
if (reset) state.tableParams.page = 1;
|
||||||
var res = await getAPI(SysRegionApi).apiSysRegionPagePost(params);
|
var res = await fetchData(null);
|
||||||
state.regionData = res.data.result?.items ?? [];
|
xGrid.value?.loadData(res.data.result?.items ?? []);
|
||||||
state.tableParams.total = res.data.result?.total;
|
state.tableParams.total = res.data.result?.total;
|
||||||
state.loading = false;
|
options.loading = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取数据
|
||||||
|
const fetchData = async (tableParams: any) => {
|
||||||
|
let params = Object.assign(state.queryParams, state.tableParams, tableParams);
|
||||||
|
return getAPI(SysRegionApi).apiSysRegionPagePost(params);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 重置操作
|
// 重置操作
|
||||||
@ -109,23 +163,37 @@ const resetQuery = () => {
|
|||||||
state.queryParams.pid = undefined;
|
state.queryParams.pid = undefined;
|
||||||
state.queryParams.name = undefined;
|
state.queryParams.name = undefined;
|
||||||
state.queryParams.code = undefined;
|
state.queryParams.code = undefined;
|
||||||
|
handleQuery(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 改变页码序号或页面容量
|
||||||
|
const pageChange: VxePagerEvents.PageChange = ({ currentPage, pageSize }: VxePagerDefines.PageChangeEventParams) => {
|
||||||
|
state.tableParams.page = currentPage;
|
||||||
|
state.tableParams.pageSize = pageSize;
|
||||||
|
handleQuery();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 列排序
|
||||||
|
const sortChange = (options: any) => {
|
||||||
|
state.tableParams.field = options.field;
|
||||||
|
state.tableParams.order = options.order;
|
||||||
handleQuery();
|
handleQuery();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开新增页面
|
// 打开新增页面
|
||||||
const openAddRegion = () => {
|
const handleAdd = () => {
|
||||||
state.editRegionTitle = '添加行政区域';
|
state.title = '添加行政区域';
|
||||||
editRegionRef.value?.openDialog({ orderNo: 100 });
|
editRegionRef.value?.openDialog({ orderNo: 100 });
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开编辑页面
|
// 打开编辑页面
|
||||||
const openEditRegion = (row: any) => {
|
const handleEdit = (row: any) => {
|
||||||
state.editRegionTitle = '编辑行政区域';
|
state.title = '编辑行政区域';
|
||||||
editRegionRef.value?.openDialog(row);
|
editRegionRef.value?.openDialog(row);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 删除
|
// 删除
|
||||||
const delRegion = (row: any) => {
|
const handleDelete = (row: any) => {
|
||||||
ElMessageBox.confirm(`确定删除行政区域:【${row.name}】?`, '提示', {
|
ElMessageBox.confirm(`确定删除行政区域:【${row.name}】?`, '提示', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
@ -135,14 +203,14 @@ const delRegion = (row: any) => {
|
|||||||
await getAPI(SysRegionApi).apiSysRegionDeletePost({ id: row.id });
|
await getAPI(SysRegionApi).apiSysRegionDeletePost({ id: row.id });
|
||||||
handleQuery();
|
handleQuery();
|
||||||
// 编辑删除后更新机构数据
|
// 编辑删除后更新机构数据
|
||||||
regionTreeRef.value?.initTreeData();
|
regionTreeRef.value?.fetchTreeData();
|
||||||
ElMessage.success('删除成功');
|
ElMessage.success('删除成功');
|
||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 树组件点击
|
// 树组件点击
|
||||||
const nodeClick = async (node: any) => {
|
const handleNodeChange = async (node: any) => {
|
||||||
state.queryParams.pid = node.id;
|
state.queryParams.pid = node.id;
|
||||||
state.queryParams.name = undefined;
|
state.queryParams.name = undefined;
|
||||||
state.queryParams.code = undefined;
|
state.queryParams.code = undefined;
|
||||||
@ -168,15 +236,13 @@ const handlSync = async () => {
|
|||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 改变页面容量
|
// 全部展开
|
||||||
const handleSizeChange = (val: number) => {
|
const handleExpand = () => {
|
||||||
state.tableParams.pageSize = val;
|
xGrid.value?.setAllTreeExpand(true);
|
||||||
handleQuery();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 改变页码序号
|
// 全部折叠
|
||||||
const handleCurrentChange = (val: number) => {
|
const handleFold = () => {
|
||||||
state.tableParams.page = val;
|
xGrid.value?.clearTreeExpand();
|
||||||
handleQuery();
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,6 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-baseApi-container">
|
<div class="sys-baseApi-container">
|
||||||
<el-drawer v-model="state.isVisible" :title="state.drawerTitle" size="30%">
|
<el-drawer v-model="state.isVisible" size="30%">
|
||||||
|
<template #header>
|
||||||
|
<div style="color: #fff">
|
||||||
|
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Link /> </el-icon>
|
||||||
|
<span>设置基础接口资源【免鉴权授权】</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<el-card class="tree-card" shadow="hover" style="height: calc(100vh - 110px)" body-style="height:100%; overflow:auto">
|
<el-card class="tree-card" shadow="hover" style="height: calc(100vh - 110px)" body-style="height:100%; overflow:auto">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
@ -69,7 +75,6 @@ const state = reactive({
|
|||||||
allApiData: [] as any,
|
allApiData: [] as any,
|
||||||
ownApiList: [] as any,
|
ownApiList: [] as any,
|
||||||
selectRow: [] as any,
|
selectRow: [] as any,
|
||||||
drawerTitle: '',
|
|
||||||
selectedTabName: 0,
|
selectedTabName: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -98,7 +103,6 @@ const initTreeData = async () => {
|
|||||||
// 打开页面
|
// 打开页面
|
||||||
const openDrawer = async () => {
|
const openDrawer = async () => {
|
||||||
state.selectedTabName = 0;
|
state.selectedTabName = 0;
|
||||||
state.drawerTitle = '设置基础接口资源【免鉴权授权】';
|
|
||||||
state.isVisible = true;
|
state.isVisible = true;
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-grantApi-container">
|
<div class="sys-grantApi-container">
|
||||||
<el-drawer v-model="state.isVisible" :title="state.drawerTitle" size="30%">
|
<el-drawer v-model="state.isVisible" size="30%">
|
||||||
|
<template #header>
|
||||||
|
<div style="color: #fff">
|
||||||
|
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Link /> </el-icon>
|
||||||
|
<span>{{ state.drawerTitle }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<el-card class="tree-card" shadow="hover" style="height: calc(100vh - 110px)" body-style="height:100%; overflow:auto">
|
<el-card class="tree-card" shadow="hover" style="height: calc(100vh - 110px)" body-style="height:100%; overflow:auto">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
|
|||||||
@ -153,7 +153,7 @@ const options = useVxeTable<TenantOutput>({
|
|||||||
{ field: 'name', title: '租户名称', minWidth: 160, showOverflow: 'tooltip' },
|
{ field: 'name', title: '租户名称', minWidth: 160, showOverflow: 'tooltip' },
|
||||||
{ field: 'adminAccount', title: '租管账号', minWidth: 120, showOverflow: 'tooltip' },
|
{ field: 'adminAccount', title: '租管账号', minWidth: 120, showOverflow: 'tooltip' },
|
||||||
{ field: 'phone', title: '电话', minWidth: 120, showOverflow: 'tooltip' },
|
{ field: 'phone', title: '电话', minWidth: 120, showOverflow: 'tooltip' },
|
||||||
{ field: 'host', title: '主机', minWidth: 150, showOverflow: 'tooltip' },
|
{ field: 'host', title: '主机', showOverflow: 'tooltip' },
|
||||||
{ field: 'email', title: '邮箱', minWidth: 150, showOverflow: 'tooltip' },
|
{ field: 'email', title: '邮箱', minWidth: 150, showOverflow: 'tooltip' },
|
||||||
{ field: 'tenantType', title: '租户类型', minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_tenantType' } },
|
{ field: 'tenantType', title: '租户类型', minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_tenantType' } },
|
||||||
{ field: 'status', title: '状态', minWidth: 100, slots: { default: 'row_status' } },
|
{ field: 'status', title: '状态', minWidth: 100, slots: { default: 'row_status' } },
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user