mirror of
https://github.com/nsnail/NetAdmin.git
synced 2025-04-22 22:22:51 +08:00
parent
366ca0d237
commit
608a1ded5c
@ -4,7 +4,6 @@
|
||||
不包含
|
||||
不排序
|
||||
不等于
|
||||
管理模块
|
||||
丧偶
|
||||
中专
|
||||
中共党员
|
||||
@ -26,6 +25,7 @@
|
||||
发送失败
|
||||
同步数据库结构
|
||||
外国人居留证
|
||||
外部错误
|
||||
大专
|
||||
大于
|
||||
大于等于
|
||||
@ -39,7 +39,6 @@
|
||||
已校验
|
||||
已读
|
||||
并且
|
||||
意外错误
|
||||
成功
|
||||
或者
|
||||
手机
|
||||
@ -50,6 +49,7 @@
|
||||
无效操作
|
||||
无效输入
|
||||
日期范围
|
||||
未处理异常
|
||||
未婚
|
||||
未读
|
||||
本人数据
|
||||
@ -68,6 +68,7 @@
|
||||
空闲
|
||||
等于
|
||||
等待发送
|
||||
管理模块
|
||||
系统模块
|
||||
绑定手机号码
|
||||
结果非预期
|
||||
|
@ -60,7 +60,6 @@ XML注释文件不存在
|
||||
用户名长度4位以上
|
||||
用户头像不能为空
|
||||
用户编号不存在
|
||||
用户编号不能为空
|
||||
目标设备不能为空
|
||||
短信验证请求不能为空
|
||||
站内信不存在
|
||||
|
@ -1371,6 +1371,22 @@ public class AllTests(WebApplicationFactory<Startup> factory, ITestOutputHelper
|
||||
return default;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[InlineData(default)]
|
||||
[Theory]
|
||||
public Task SetEnabledAsync(SetDeptEnabledReq req)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[InlineData(default)]
|
||||
[Theory]
|
||||
public Task SetEnabledAsync(SetRoleEnabledReq req)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[InlineData(default)]
|
||||
[Theory]
|
||||
|
@ -7,6 +7,8 @@ namespace NetAdmin.Domain.DbMaps.Sys;
|
||||
/// 计划作业执行记录表
|
||||
/// </summary>
|
||||
[Index($"{Chars.FLG_DB_INDEX_PREFIX}{nameof(JobId)}_{nameof(TimeId)}", $"{nameof(JobId)},{nameof(TimeId)}", true)]
|
||||
[Index(Chars.FLG_DB_INDEX_PREFIX + nameof(CreatedTime), nameof(CreatedTime), false)]
|
||||
[Index(Chars.FLG_DB_INDEX_PREFIX + nameof(JobId), nameof(JobId), false)]
|
||||
[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_JobRecord))]
|
||||
public record Sys_JobRecord : LiteImmutableEntity
|
||||
{
|
||||
|
@ -6,8 +6,9 @@ namespace NetAdmin.Domain.DbMaps.Sys;
|
||||
/// <summary>
|
||||
/// 请求日志表
|
||||
/// </summary>
|
||||
[Index(Chars.FLG_DB_INDEX_PREFIX + nameof(ApiId), nameof(ApiId), false)]
|
||||
[Index(Chars.FLG_DB_INDEX_PREFIX + nameof(CreatedTime), nameof(CreatedTime), false)]
|
||||
[Index(Chars.FLG_DB_INDEX_PREFIX + nameof(ApiId), nameof(ApiId), false)]
|
||||
[Index(Chars.FLG_DB_INDEX_PREFIX + nameof(CreatedTime), nameof(CreatedTime), false)]
|
||||
[Index(Chars.FLG_DB_INDEX_PREFIX + nameof(HttpStatusCode), nameof(HttpStatusCode), false)]
|
||||
[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_RequestLog))]
|
||||
public record Sys_RequestLog : ImmutableEntity, IFieldCreatedClient
|
||||
{
|
||||
|
@ -0,0 +1,23 @@
|
||||
using NetAdmin.Domain.DbMaps.Dependency;
|
||||
using NetAdmin.Domain.DbMaps.Dependency.Fields;
|
||||
using NetAdmin.Domain.DbMaps.Sys;
|
||||
|
||||
namespace NetAdmin.Domain.Dto.Sys.Dept;
|
||||
|
||||
/// <summary>
|
||||
/// 请求:启用/禁用部门
|
||||
/// </summary>
|
||||
public sealed record SetDeptEnabledReq : Sys_Dept
|
||||
{
|
||||
/// <inheritdoc cref="IFieldEnabled.Enabled" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public override bool Enabled { get; init; }
|
||||
|
||||
/// <inheritdoc cref="EntityBase{T}.Id" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public override long Id { get; init; }
|
||||
|
||||
/// <inheritdoc cref="IFieldVersion.Version" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public override long Version { get; init; }
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
using NetAdmin.Domain.DbMaps.Dependency;
|
||||
using NetAdmin.Domain.DbMaps.Dependency.Fields;
|
||||
using NetAdmin.Domain.DbMaps.Sys;
|
||||
|
||||
namespace NetAdmin.Domain.Dto.Sys.Role;
|
||||
|
||||
/// <summary>
|
||||
/// 请求:启用/禁用角色
|
||||
/// </summary>
|
||||
public sealed record SetRoleEnabledReq : Sys_Role
|
||||
{
|
||||
/// <inheritdoc cref="IFieldEnabled.Enabled" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public override bool Enabled { get; init; }
|
||||
|
||||
/// <inheritdoc cref="EntityBase{T}.Id" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public override long Id { get; init; }
|
||||
|
||||
/// <inheritdoc cref="IFieldVersion.Version" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public override long Version { get; init; }
|
||||
}
|
@ -15,7 +15,6 @@ public sealed record SetUserEnabledReq : Sys_User
|
||||
|
||||
/// <inheritdoc cref="EntityBase{T}.Id" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
[Required(ErrorMessageResourceType = typeof(Ln), ErrorMessageResourceName = nameof(Ln.用户编号不能为空))]
|
||||
public override long Id { get; init; }
|
||||
|
||||
/// <inheritdoc cref="IFieldVersion.Version" />
|
||||
|
@ -15,9 +15,9 @@ public enum ErrorCodes
|
||||
,
|
||||
|
||||
/// <summary>
|
||||
/// 意外错误
|
||||
/// 未处理异常
|
||||
/// </summary>
|
||||
[ResourceDescription<Ln>(nameof(Ln.意外错误))]
|
||||
[ResourceDescription<Ln>(nameof(Ln.未处理异常))]
|
||||
Unhandled = 9000
|
||||
|
||||
,
|
||||
@ -43,4 +43,12 @@ public enum ErrorCodes
|
||||
/// </summary>
|
||||
[ResourceDescription<Ln>(nameof(Ln.无效操作))]
|
||||
InvalidOperation = 9300
|
||||
|
||||
,
|
||||
|
||||
/// <summary>
|
||||
/// 外部错误
|
||||
/// </summary>
|
||||
[ResourceDescription<Ln>(nameof(Ln.外部错误))]
|
||||
ExternalError = 9400
|
||||
}
|
@ -3,6 +3,7 @@ namespace NetAdmin.Infrastructure.Enums;
|
||||
/// <summary>
|
||||
/// 日志等级
|
||||
/// </summary>
|
||||
[Export]
|
||||
public enum LogLevels
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -4,14 +4,9 @@ namespace NetAdmin.Infrastructure.Exceptions;
|
||||
/// NetAdmin异常基类
|
||||
/// </summary>
|
||||
#pragma warning disable RCS1194
|
||||
public abstract class NetAdminException : Exception
|
||||
public abstract class NetAdminException(string message, Exception innerException) : Exception(message, innerException)
|
||||
#pragma warning restore RCS1194
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NetAdminException" /> class.
|
||||
/// </summary>
|
||||
protected NetAdminException() { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NetAdminException" /> class.
|
||||
/// </summary>
|
||||
@ -21,12 +16,6 @@ public abstract class NetAdminException : Exception
|
||||
Code = code;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NetAdminException" /> class.
|
||||
/// </summary>
|
||||
protected NetAdminException(string message, Exception innerException) //
|
||||
: base(message, innerException) { }
|
||||
|
||||
/// <summary>
|
||||
/// 错误码
|
||||
/// </summary>
|
||||
|
@ -0,0 +1,12 @@
|
||||
namespace NetAdmin.Infrastructure.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// 外部错误异常
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 外部接口调用未得到预期的结果
|
||||
/// </remarks>
|
||||
#pragma warning disable RCS1194
|
||||
public sealed class NetAdminExternalErrorException(string message, Exception innerException = null)
|
||||
#pragma warning restore RCS1194
|
||||
: NetAdminException(ErrorCodes.ExternalError, message, innerException) { }
|
@ -3,6 +3,9 @@ namespace NetAdmin.Infrastructure.Exceptions;
|
||||
/// <summary>
|
||||
/// 加锁失败异常
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 并发执行时锁竞争失败
|
||||
/// </remarks>
|
||||
#pragma warning disable RCS1194
|
||||
public sealed class NetAdminGetLockerException : NetAdminException;
|
||||
public sealed class NetAdminGetLockerException() : NetAdminInvalidOperationException(null) { }
|
||||
#pragma warning restore RCS1194
|
@ -8,6 +8,5 @@ namespace NetAdmin.Infrastructure.Exceptions;
|
||||
/// </remarks>
|
||||
#pragma warning disable RCS1194
|
||||
public sealed class NetAdminInvalidInputException(string message = null, Exception innerException = null)
|
||||
: NetAdminException(ErrorCodes.InvalidInput, message, innerException)
|
||||
#pragma warning restore RCS1194
|
||||
{ }
|
||||
#pragma warning restore RCS1194
|
||||
: NetAdminException(ErrorCodes.InvalidInput, message, innerException) { }
|
@ -6,19 +6,7 @@ namespace NetAdmin.Infrastructure.Exceptions;
|
||||
/// <remarks>
|
||||
/// 非正常的业务流程或逻辑
|
||||
/// </remarks>
|
||||
#pragma warning disable RCS1194, DesignedForInheritance
|
||||
public class NetAdminInvalidOperationException : NetAdminException
|
||||
#pragma warning restore DesignedForInheritance, RCS1194
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NetAdminInvalidOperationException" /> class.
|
||||
/// </summary>
|
||||
public NetAdminInvalidOperationException(string message, Exception innerException = null) //
|
||||
: this(ErrorCodes.InvalidOperation, message, innerException) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NetAdminInvalidOperationException" /> class.
|
||||
/// </summary>
|
||||
protected NetAdminInvalidOperationException(ErrorCodes errorCode, string message, Exception innerException) //
|
||||
: base(errorCode, message, innerException) { }
|
||||
}
|
||||
#pragma warning disable DesignedForInheritance, RCS1194
|
||||
public class NetAdminInvalidOperationException(string message, Exception innerException = null)
|
||||
#pragma warning restore RCS1194, DesignedForInheritance
|
||||
: NetAdminException(ErrorCodes.InvalidOperation, message, innerException) { }
|
@ -6,25 +6,7 @@ namespace NetAdmin.Infrastructure.Exceptions;
|
||||
/// <remarks>
|
||||
/// 运行结果是非预期的,例如事务失败回滚
|
||||
/// </remarks>
|
||||
#pragma warning disable RCS1194, DesignedForInheritance
|
||||
public class NetAdminUnexpectedException : NetAdminException
|
||||
#pragma warning restore DesignedForInheritance, RCS1194
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NetAdminUnexpectedException" /> class.
|
||||
/// </summary>
|
||||
public NetAdminUnexpectedException(string message) //
|
||||
: this(ErrorCodes.Unexpected, message) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NetAdminUnexpectedException" /> class.
|
||||
/// </summary>
|
||||
public NetAdminUnexpectedException() //
|
||||
: this(string.Empty) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NetAdminUnexpectedException" /> class.
|
||||
/// </summary>
|
||||
protected NetAdminUnexpectedException(ErrorCodes errorCode, string message) //
|
||||
: base(errorCode, message) { }
|
||||
}
|
||||
#pragma warning disable RCS1194
|
||||
public sealed class NetAdminUnexpectedException(string message, Exception innerException = null)
|
||||
#pragma warning restore RCS1194
|
||||
: NetAdminException(ErrorCodes.Unexpected, message, innerException);
|
@ -8,8 +8,8 @@ namespace NetAdmin.Infrastructure.Exceptions;
|
||||
/// </remarks>
|
||||
#pragma warning disable RCS1194
|
||||
public sealed class NetAdminValidateException(Dictionary<string, string[]> validateResults)
|
||||
: NetAdminException(ErrorCodes.InvalidInput)
|
||||
#pragma warning restore RCS1194
|
||||
#pragma warning restore RCS1194
|
||||
: NetAdminInvalidOperationException(null)
|
||||
{
|
||||
/// <summary>
|
||||
/// 验证结果
|
||||
|
@ -37,6 +37,6 @@ public static class HttpResponseMessageExtensions
|
||||
Header = me?.ToString()
|
||||
, RequestHeader = me?.RequestMessage?.Headers
|
||||
, Body = bodyHandle is null ? body : bodyHandle(body)
|
||||
}.ToJson();
|
||||
}.Json();
|
||||
}
|
||||
}
|
@ -24,6 +24,11 @@ public static class GlobalStatic
|
||||
#endif
|
||||
;
|
||||
|
||||
/// <summary>
|
||||
/// 日志保存跳过的API编号
|
||||
/// </summary>
|
||||
public static string[] LogSavingSkipApiIds => ["api/probe/health.check", "api/adm/device.log/create"];
|
||||
|
||||
/// <summary>
|
||||
/// 系统内部密钥
|
||||
/// </summary>
|
||||
|
@ -16,4 +16,9 @@ public interface IDeptModule : ICrudModule<CreateDeptReq, QueryDeptRsp // 创建
|
||||
/// 编辑部门
|
||||
/// </summary>
|
||||
Task<QueryDeptRsp> EditAsync(EditDeptReq req);
|
||||
|
||||
/// <summary>
|
||||
/// 启用/禁用部门
|
||||
/// </summary>
|
||||
Task SetEnabledAsync(SetDeptEnabledReq req);
|
||||
}
|
@ -16,4 +16,9 @@ public interface IRoleModule : ICrudModule<CreateRoleReq, QueryRoleRsp // 创建
|
||||
/// 编辑角色
|
||||
/// </summary>
|
||||
Task<QueryRoleRsp> EditAsync(EditRoleReq req);
|
||||
|
||||
/// <summary>
|
||||
/// 启用/禁用角色
|
||||
/// </summary>
|
||||
Task SetEnabledAsync(SetRoleEnabledReq req);
|
||||
}
|
@ -119,6 +119,13 @@ public sealed class DeptService(BasicRepository<Sys_Dept, long> rpo) //
|
||||
.ConfigureAwait(false)).Adapt<IEnumerable<QueryDeptRsp>>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task SetEnabledAsync(SetDeptEnabledReq req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
return UpdateAsync(req, [nameof(req.Enabled)]);
|
||||
}
|
||||
|
||||
private ISelect<Sys_Dept> QueryInternal(QueryReq<QueryDeptReq> req, bool asTreeCte = false)
|
||||
{
|
||||
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter)
|
||||
|
@ -75,8 +75,8 @@ public sealed class JobService(BasicRepository<Sys_Job, long> rpo, IJobRecordSer
|
||||
.Set(a => a.RequestBody == req.RequestBody)
|
||||
.Set(a => a.RequestUrl == req.RequestUrl)
|
||||
.Set(a => a.UserId == req.UserId)
|
||||
.Where(a => a.Id == req.Id)
|
||||
.Where(a => a.Version == req.Version);
|
||||
.Set(a => a.Summary == req.Summary)
|
||||
.Where(a => a.Id == req.Id);
|
||||
|
||||
#if DBTYPE_SQLSERVER
|
||||
return (await update.ExecuteUpdatedAsync().ConfigureAwait(false)).FirstOrDefault()?.Adapt<QueryJobRsp>();
|
||||
@ -276,11 +276,22 @@ public sealed class JobService(BasicRepository<Sys_Job, long> rpo, IJobRecordSer
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<int> ReleaseStuckTaskAsync()
|
||||
public async Task<int> ReleaseStuckTaskAsync()
|
||||
{
|
||||
return UpdateAsync( //
|
||||
new Sys_Job { Status = JobStatues.Idle }, [nameof(Sys_Job.Status)], null
|
||||
, a => a.Status == JobStatues.Running && a.LastExecTime < DateTime.Now.AddSeconds(-Numbers.SECS_TIMEOUT_JOB));
|
||||
var ret1 = await UpdateAsync( // 运行中,运行时间超过超时设定;置为空闲状态
|
||||
new Sys_Job { Status = JobStatues.Idle }, [nameof(Sys_Job.Status)], null
|
||||
, a => a.Status == JobStatues.Running &&
|
||||
a.LastExecTime < DateTime.Now.AddSeconds(-Numbers.SECS_TIMEOUT_JOB)
|
||||
, true)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var ret2 = await UpdateAsync( // 空闲中,下次执行时间在当前时间减去超时时间以前;将下次执行时间调整到现在
|
||||
new Sys_Job { NextExecTime = DateTime.Now, NextTimeId = DateTime.Now.TimeUnixUtc() }
|
||||
, [nameof(Sys_Job.NextExecTime), nameof(Sys_Job.NextTimeId)], null
|
||||
, a => a.Status == JobStatues.Idle && a.NextExecTime < DateTime.Now.AddSeconds(-Numbers.SECS_TIMEOUT_JOB)
|
||||
, true)
|
||||
.ConfigureAwait(false);
|
||||
return ret1 + ret2;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -123,6 +123,13 @@ public sealed class RoleService(BasicRepository<Sys_Role, long> rpo) //
|
||||
return ret.Adapt<IEnumerable<QueryRoleRsp>>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task SetEnabledAsync(SetRoleEnabledReq req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
return UpdateAsync(req, [nameof(req.Enabled)]);
|
||||
}
|
||||
|
||||
private ISelect<Sys_Role> QueryInternal(QueryReq<QueryRoleReq> req)
|
||||
{
|
||||
var ret = Rpo.Select.IncludeMany(a => a.Depts.Select(b => new Sys_Dept { Id = b.Id }))
|
||||
|
@ -63,4 +63,10 @@ public sealed class DeptCache(IDistributedCache cache, IDeptService service) //
|
||||
{
|
||||
return Service.QueryAsync(req);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task SetEnabledAsync(SetDeptEnabledReq req)
|
||||
{
|
||||
return Service.SetEnabledAsync(req);
|
||||
}
|
||||
}
|
@ -63,4 +63,10 @@ public sealed class RoleCache(IDistributedCache cache, IRoleService service) //
|
||||
{
|
||||
return Service.QueryAsync(req);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task SetEnabledAsync(SetRoleEnabledReq req)
|
||||
{
|
||||
return Service.SetEnabledAsync(req);
|
||||
}
|
||||
}
|
@ -91,4 +91,12 @@ public sealed class DeptController(IDeptCache cache) : ControllerBase<IDeptCache
|
||||
{
|
||||
return Cache.QueryAsync(req);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启用/禁用部门
|
||||
/// </summary>
|
||||
public Task SetEnabledAsync(SetDeptEnabledReq req)
|
||||
{
|
||||
return Cache.SetEnabledAsync(req);
|
||||
}
|
||||
}
|
@ -90,4 +90,12 @@ public sealed class RoleController(IRoleCache cache) : ControllerBase<IRoleCache
|
||||
{
|
||||
return Cache.QueryAsync(req);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启用/禁用角色
|
||||
/// </summary>
|
||||
public Task SetEnabledAsync(SetRoleEnabledReq req)
|
||||
{
|
||||
return Cache.SetEnabledAsync(req);
|
||||
}
|
||||
}
|
@ -20,8 +20,10 @@ public sealed class OperationLogger : IEventSubscriber
|
||||
return;
|
||||
}
|
||||
|
||||
// 跳过心跳请求
|
||||
if (operationEvent.Data.ApiId.Equals("api/probe/health.check", StringComparison.OrdinalIgnoreCase)) {
|
||||
// 跳过指定的请求
|
||||
if (Array.Exists( //
|
||||
GlobalStatic.LogSavingSkipApiIds
|
||||
, x => x.Equals(operationEvent.Data.ApiId, StringComparison.OrdinalIgnoreCase))) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -81,4 +81,15 @@ export default {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 启用/禁用部门
|
||||
*/
|
||||
setEnabled: {
|
||||
url: `${config.API_URL}/api/sys/dept/set.enabled`,
|
||||
name: `启用/禁用部门`,
|
||||
post: async function (data = {}, config = {}) {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
}
|
@ -92,4 +92,15 @@ export default {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 启用/禁用角色
|
||||
*/
|
||||
setEnabled: {
|
||||
url: `${config.API_URL}/api/sys/role/set.enabled`,
|
||||
name: `启用/禁用角色`,
|
||||
post: async function (data = {}, config = {}) {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
}
|
@ -14,8 +14,8 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
<el-table-column :label="$t('地区')" prop="key" width="400"></el-table-column>
|
||||
<el-table-column :label="$t('代码')" prop="value"></el-table-column>
|
||||
<el-table-column :label="$t('地区')" prop="key" width="400" />
|
||||
<el-table-column :label="$t('代码')" prop="value" />
|
||||
</sc-table-select>
|
||||
</template>
|
||||
<style scoped></style>
|
||||
|
@ -1,17 +1,17 @@
|
||||
<template>
|
||||
<el-table-column :label="label" :min-width="minWidth" :prop="prop" :sortable="customSort ? `custom` : true" align="center">
|
||||
<template #default="scope">
|
||||
<el-table-column v-bind:="$attrs">
|
||||
<template #default="{ row }">
|
||||
<template v-for="(item, i) in options" :key="i">
|
||||
<div v-if="tool.getNestedProperty(scope.row, prop) === item.value" class="indicator">
|
||||
<div v-if="tool.getNestedProperty(row, this.$attrs.prop) === item.value">
|
||||
<sc-status-indicator
|
||||
:pulse="item.pulse"
|
||||
:style="item.type ? '' : `background: #${Math.abs(this.$TOOL.crypto.hashCode(item.value)).toString(16).substring(0, 6)}`"
|
||||
:type="item.type" />
|
||||
<span v-if="!$slots.default"> {{ item.text }}</span>
|
||||
<slot :row="scope.row" :text="item.text"></slot>
|
||||
<span v-if="!$slots.default"> {{ item.text }}</span>
|
||||
<slot :row="row" :text="item.text"></slot>
|
||||
</div>
|
||||
</template>
|
||||
<slot :row="scope.row" name="info"></slot>
|
||||
<slot :row="row" name="info"></slot>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
@ -21,11 +21,7 @@ import tool from '@/utils/tool'
|
||||
export default {
|
||||
emits: [],
|
||||
props: {
|
||||
minWidth: { type: Number, default: 80 },
|
||||
options: { type: Array },
|
||||
prop: { type: String },
|
||||
label: { type: String },
|
||||
customSort: { type: Boolean, default: true },
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
|
@ -18,9 +18,9 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
<el-table-column :label="$t('用户编号')" prop="id"></el-table-column>
|
||||
<el-table-column :label="$t('用户名')" prop="userName"></el-table-column>
|
||||
<el-table-column :label="$t('手机号')" prop="mobile"></el-table-column>
|
||||
<el-table-column :label="$t('用户编号')" prop="id" />
|
||||
<el-table-column :label="$t('用户名')" prop="userName" />
|
||||
<el-table-column :label="$t('手机号')" prop="mobile" />
|
||||
</sc-table-select>
|
||||
</template>
|
||||
<style scoped></style>
|
||||
|
@ -6,12 +6,7 @@
|
||||
:props="item.options.props"
|
||||
:table-width="60"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
v-for="(_item, _index) in item.options.column"
|
||||
:key="_index"
|
||||
:label="_item.label"
|
||||
:prop="_item.prop"
|
||||
:width="_item.width"></el-table-column>
|
||||
<el-table-column v-for="(_item, _index) in item.options.column" :key="_index" :label="_item.label" :prop="_item.prop" :width="_item.width" />
|
||||
</sc-table-select>
|
||||
</template>
|
||||
|
||||
|
@ -46,7 +46,7 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
<el-table-column min-width="1"></el-table-column>
|
||||
<el-table-column min-width="1" />
|
||||
<template #empty>
|
||||
<el-empty :description="emptyText" :image-size="100"></el-empty>
|
||||
</template>
|
||||
|
@ -36,7 +36,7 @@
|
||||
@select-all="selectAll"
|
||||
max-height="30rem"
|
||||
ref="table">
|
||||
<el-table-column v-if="multiple" type="selection" width="45"></el-table-column>
|
||||
<el-table-column v-if="multiple" type="selection" width="45" />
|
||||
<el-table-column v-else type="index" width="45">
|
||||
<template #default="scope"
|
||||
><span>{{ scope.$index + (currentPage - 1) * pageSize + 1 }}</span></template
|
||||
|
@ -484,6 +484,15 @@ textarea {
|
||||
.mt-4 {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.mr-2 {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.mr-4 {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.mt-8 {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
@ -510,11 +519,4 @@ textarea {
|
||||
|
||||
.justify-content-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.indicator {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.5rem;
|
||||
}
|
@ -165,6 +165,18 @@
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
.el-table {
|
||||
.el-link:after {
|
||||
border-bottom: 1px solid var(--el-link-text-color);
|
||||
bottom: 0;
|
||||
content: '';
|
||||
height: 0;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.el-table th.is-sortable {
|
||||
transition: 0.1s;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" :title="titleMap[mode]" :width="800" @closed="$emit('closed')" destroy-on-close>
|
||||
<el-dialog v-model="visible" :title="`${titleMap[mode]}:${form?.id ?? '...'}`" :width="800" @closed="$emit('closed')" destroy-on-close>
|
||||
<el-form :model="form" :rules="rules" label-position="top" ref="form">
|
||||
<el-row class="items-center justify-content-center">
|
||||
<el-col v-if="mode === 'edit'" :lg="10">
|
||||
|
@ -16,8 +16,8 @@
|
||||
row-key="id"
|
||||
show-summary
|
||||
stripe>
|
||||
<el-table-column :label="$t('接口路径')" prop="id"></el-table-column>
|
||||
<el-table-column :label="$t('接口名称')" prop="name"></el-table-column>
|
||||
<el-table-column :label="$t('接口路径')" prop="id" />
|
||||
<el-table-column :label="$t('接口名称')" prop="name" />
|
||||
<na-col-indicator
|
||||
:label="$t('请求方式')"
|
||||
:options="
|
||||
@ -25,10 +25,11 @@
|
||||
return { value: x[0].toUpperCase(), text: x[1][1] }
|
||||
})
|
||||
"
|
||||
align="center"
|
||||
prop="method"
|
||||
width="100">
|
||||
</na-col-indicator>
|
||||
<el-table-column :label="$t('接口描述')" prop="summary"></el-table-column>
|
||||
sortable="custom"
|
||||
width="100" />
|
||||
<el-table-column :label="$t('接口描述')" prop="summary" />
|
||||
</sc-table>
|
||||
</el-main>
|
||||
</el-container>
|
||||
|
12
src/frontend/admin/src/views/sys/cache/index.vue
vendored
12
src/frontend/admin/src/views/sys/cache/index.vue
vendored
@ -5,7 +5,7 @@
|
||||
<el-row :gutter="15">
|
||||
<el-col :lg="4">
|
||||
<el-card shadow="never">
|
||||
<sc-statistic :value="statistics.version" groupSeparator title="Redis 版本"></sc-statistic>
|
||||
<sc-statistic :value="statistics.version" group-separator title="Redis 版本"></sc-statistic>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :lg="4">
|
||||
@ -13,7 +13,7 @@
|
||||
<sc-statistic
|
||||
:suffix="$t('天')"
|
||||
:value="parseInt(statistics.upTime / 86400)"
|
||||
groupSeparator
|
||||
group-separator
|
||||
title="Redis 运行时间"></sc-statistic>
|
||||
</el-card>
|
||||
</el-col>
|
||||
@ -21,7 +21,7 @@
|
||||
<el-card shadow="never">
|
||||
<sc-statistic
|
||||
:value="statistics.upTime ? (statistics.usedCpu / statistics.upTime).toFixed(2) : 0"
|
||||
groupSeparator
|
||||
group-separator
|
||||
suffix="%"
|
||||
title="CPU 使用率"></sc-statistic>
|
||||
</el-card>
|
||||
@ -31,13 +31,13 @@
|
||||
<sc-statistic
|
||||
:title="$t('内存使用量')"
|
||||
:value="(statistics.usedMemory / 1024 / 1024).toFixed(2)"
|
||||
groupSeparator
|
||||
group-separator
|
||||
suffix="MiB"></sc-statistic>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :lg="4">
|
||||
<el-card shadow="never">
|
||||
<sc-statistic :title="$t('缓存数量')" :value="statistics.dbSize" groupSeparator></sc-statistic>
|
||||
<sc-statistic :title="$t('缓存数量')" :value="statistics.dbSize" group-separator></sc-statistic>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :lg="4">
|
||||
@ -45,7 +45,7 @@
|
||||
<sc-statistic
|
||||
:title="$t('缓存命中率')"
|
||||
:value="((statistics.keyspaceHits / (statistics.keyspaceMisses + statistics.keyspaceHits)) * 100).toFixed(2)"
|
||||
groupSeparator
|
||||
group-separator
|
||||
suffix="%"></sc-statistic>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
@ -1,31 +1,39 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header style="height: auto; padding: 0 1rem">
|
||||
<sc-select-filter
|
||||
:data="[
|
||||
{
|
||||
title: $t('启用状态'),
|
||||
key: 'enabled',
|
||||
options: [
|
||||
{ label: $t('全部'), value: '' },
|
||||
{ label: $t('启用'), value: true },
|
||||
{ label: $t('禁用'), value: false },
|
||||
],
|
||||
},
|
||||
]"
|
||||
:label-width="6"
|
||||
@on-change="filterChange"
|
||||
ref="selectFilter"></sc-select-filter>
|
||||
</el-header>
|
||||
<el-header>
|
||||
<div class="left-panel">
|
||||
<na-search
|
||||
:controls="[
|
||||
{
|
||||
type: 'select',
|
||||
field: ['dy', 'enabled'],
|
||||
options: [
|
||||
{ label: '启用', value: true },
|
||||
{ label: '禁用', value: false },
|
||||
],
|
||||
placeholder: '是否启用',
|
||||
style: 'width:10rem',
|
||||
},
|
||||
]"
|
||||
:controls="[]"
|
||||
:vue="this"
|
||||
@reset="Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = ['']))"
|
||||
@search="onSearch"
|
||||
ref="search" />
|
||||
</div>
|
||||
<div class="right-panel">
|
||||
<na-button-add :vue="this"></na-button-add>
|
||||
<na-button-add :vue="this" />
|
||||
<el-button :disabled="selection.length === 0" @click="batchDel" icon="el-icon-delete" plain type="danger"></el-button>
|
||||
</div>
|
||||
</el-header>
|
||||
<el-main class="nopadding">
|
||||
<sc-table
|
||||
v-loading="loading"
|
||||
:apiObj="$API.sys_config.pagedQuery"
|
||||
:context-menus="['id', 'userRegisterConfirm', 'enabled', 'createdTime']"
|
||||
:params="query"
|
||||
@ -38,11 +46,11 @@
|
||||
ref="table"
|
||||
row-key="id"
|
||||
stripe>
|
||||
<el-table-column align="center" type="selection"></el-table-column>
|
||||
<el-table-column :label="$t('配置编号')" align="center" prop="id" width="170"></el-table-column>
|
||||
<el-table-column type="selection" />
|
||||
<el-table-column :label="$t('配置编号')" align="center" prop="id" width="170" />
|
||||
<el-table-column :label="$t('用户注册')" align="center">
|
||||
<el-table-column :label="$t('默认部门')" align="center" prop="userRegisterDept.name" width="150"></el-table-column>
|
||||
<el-table-column :label="$t('默认角色')" align="center" prop="userRegisterRole.name" width="150"></el-table-column>
|
||||
<el-table-column :label="$t('默认部门')" align="center" prop="userRegisterDept.name" width="150" />
|
||||
<el-table-column :label="$t('默认角色')" align="center" prop="userRegisterRole.name" width="150" />
|
||||
<el-table-column :label="$t('人工审核')" align="center" prop="userRegisterConfirm" width="100">
|
||||
<template #default="scope">
|
||||
<el-switch v-model="scope.row.userRegisterConfirm" @change="changeSwitch($event, scope.row)"></el-switch>
|
||||
@ -54,7 +62,7 @@
|
||||
<el-switch v-model="scope.row.enabled" @change="changeSwitch($event, scope.row)"></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('创建时间')" align="center" prop="createdTime" width="170"></el-table-column>
|
||||
<el-table-column :label="$t('创建时间')" align="center" prop="createdTime" width="170" />
|
||||
<na-col-operation
|
||||
:buttons="
|
||||
naColOperation.buttons.concat({
|
||||
@ -85,47 +93,84 @@ import table from '@/config/table'
|
||||
import tool from '@/utils/tool'
|
||||
|
||||
export default {
|
||||
inject: ['reload'],
|
||||
computed: {
|
||||
table() {
|
||||
return table
|
||||
},
|
||||
naColOperation() {
|
||||
return naColOperation
|
||||
},
|
||||
},
|
||||
components: {
|
||||
saveDialog,
|
||||
},
|
||||
computed: {
|
||||
naColOperation() {
|
||||
return naColOperation
|
||||
},
|
||||
table() {
|
||||
return table
|
||||
},
|
||||
},
|
||||
created() {},
|
||||
data() {
|
||||
return {
|
||||
dialog: {
|
||||
save: false,
|
||||
info: false,
|
||||
save: false,
|
||||
},
|
||||
selection: [],
|
||||
loading: false,
|
||||
query: {
|
||||
dynamicFilter: {
|
||||
filters: [],
|
||||
},
|
||||
filter: {},
|
||||
},
|
||||
selection: [],
|
||||
}
|
||||
},
|
||||
mounted() {},
|
||||
inject: ['reload'],
|
||||
methods: {
|
||||
//搜索
|
||||
async batchDel() {
|
||||
let loading
|
||||
try {
|
||||
await this.$confirm(`确定删除选中的 ${this.selection.length} 项吗?`, '提示', {
|
||||
type: 'warning',
|
||||
})
|
||||
loading = this.$loading()
|
||||
const res = await this.$API.sys_config.bulkDelete.post({
|
||||
items: this.selection,
|
||||
})
|
||||
this.$refs.table.refresh()
|
||||
this.$message.success(`删除 ${res.data} 项`)
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
loading?.close()
|
||||
},
|
||||
async changeSwitch(event, row) {
|
||||
try {
|
||||
await this.$API.sys_config.edit.post(row)
|
||||
this.$refs.table.refresh()
|
||||
this.$message.success(`操作成功`)
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
},
|
||||
filterChange(data) {
|
||||
Object.entries(data).forEach(([key, value]) => {
|
||||
this.$refs.search.form.dy[key] = value === 'true' ? true : value === 'false' ? false : value
|
||||
this.$refs.search.search()
|
||||
})
|
||||
},
|
||||
|
||||
async rowDel(row) {
|
||||
try {
|
||||
const res = await this.$API.sys_config.delete.post({ id: row.id })
|
||||
this.$message.success(`删除 ${res.data} 项`)
|
||||
this.$refs.table.refresh()
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
},
|
||||
onSearch(form) {
|
||||
if (Array.isArray(form.dy.createdTime)) {
|
||||
const start = new Date(form.dy.createdTime[0])
|
||||
const end = new Date(form.dy.createdTime[1])
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: 'createdTime',
|
||||
operator: 'dateRange',
|
||||
value: [
|
||||
tool.dateFormat(start.setDate(start.getDate() + 1)).substring(0, 10),
|
||||
tool.dateFormat(end.setDate(end.getDate() + 1)).substring(0, 10),
|
||||
],
|
||||
value: form.dy.createdTime,
|
||||
})
|
||||
}
|
||||
|
||||
@ -139,51 +184,9 @@ export default {
|
||||
|
||||
this.$refs.table.upData()
|
||||
},
|
||||
|
||||
//表格内开关事件
|
||||
async changeSwitch(event, row) {
|
||||
try {
|
||||
await this.$API.sys_config.edit.post(row)
|
||||
this.$message.success(`操作成功`)
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
this.$refs.table.refresh()
|
||||
},
|
||||
//删除明细
|
||||
async rowDel(row) {
|
||||
try {
|
||||
const res = await this.$API.sys_config.delete.post({ id: row.id })
|
||||
this.$refs.table.refresh()
|
||||
this.$message.success(`删除 ${res.data} 项`)
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
},
|
||||
//批量删除
|
||||
async batchDel() {
|
||||
const confirmRes = await this.$confirm(`确定删除选中的 ${this.selection.length} 项吗?`, '提示', {
|
||||
type: 'warning',
|
||||
confirmButtonText: '删除',
|
||||
confirmButtonClass: 'el-button--danger',
|
||||
}).catch(() => {})
|
||||
|
||||
if (!confirmRes) {
|
||||
return false
|
||||
}
|
||||
|
||||
try {
|
||||
await this.$API.sys_config.bulkDelete.post({
|
||||
items: this.selection,
|
||||
})
|
||||
this.$refs.table.removeKeys(this.selection.map((x) => x.id))
|
||||
this.$message.success('操作成功')
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
<style scoped></style>
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<sc-dialog v-model="visible" :title="titleMap[mode]" @closed="$emit('closed')" destroy-on-close>
|
||||
<sc-dialog v-model="visible" :title="`${titleMap[mode]}:${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close>
|
||||
<div v-loading="loading">
|
||||
<el-tabs v-if="!loading" tab-position="top">
|
||||
<el-tab-pane :label="$t('基本信息')">
|
||||
@ -112,4 +112,8 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
<style scoped>
|
||||
.el-collapse {
|
||||
border-top: none;
|
||||
}
|
||||
</style>
|
@ -1,5 +1,22 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header style="height: auto; padding: 0 1rem">
|
||||
<sc-select-filter
|
||||
:data="[
|
||||
{
|
||||
title: $t('启用状态'),
|
||||
key: 'enabled',
|
||||
options: [
|
||||
{ label: $t('全部'), value: '' },
|
||||
{ label: $t('启用'), value: true },
|
||||
{ label: $t('禁用'), value: false },
|
||||
],
|
||||
},
|
||||
]"
|
||||
:label-width="6"
|
||||
@on-change="filterChange"
|
||||
ref="selectFilter"></sc-select-filter>
|
||||
</el-header>
|
||||
<el-header>
|
||||
<div class="left-panel">
|
||||
<na-search
|
||||
@ -10,27 +27,20 @@
|
||||
placeholder: '部门编号 / 部门名称 / 备注',
|
||||
style: 'width:25rem',
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
field: ['dy', 'enabled'],
|
||||
options: [
|
||||
{ label: '启用', value: true },
|
||||
{ label: '禁用', value: false },
|
||||
],
|
||||
placeholder: '状态',
|
||||
style: 'width:15rem',
|
||||
},
|
||||
]"
|
||||
:vue="this"
|
||||
@search="onSearch" />
|
||||
@reset="Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = ['']))"
|
||||
@search="onSearch"
|
||||
ref="search" />
|
||||
</div>
|
||||
<div class="right-panel">
|
||||
<na-button-add :vue="this"></na-button-add>
|
||||
<na-button-add :vue="this" />
|
||||
<el-button :disabled="selection.length === 0" @click="batchDel" icon="el-icon-delete" plain type="danger"></el-button>
|
||||
</div>
|
||||
</el-header>
|
||||
<el-main class="nopadding">
|
||||
<sc-table
|
||||
v-loading="loading"
|
||||
:apiObj="$API.sys_dept.query"
|
||||
:context-menus="['id', 'name', 'sort', 'enabled', 'createdTime', 'summary']"
|
||||
:default-sort="{ prop: 'sort', order: 'descending' }"
|
||||
@ -48,19 +58,17 @@
|
||||
remote-sort
|
||||
row-key="id"
|
||||
stripe>
|
||||
<el-table-column type="selection" width="50"></el-table-column>
|
||||
<el-table-column :label="$t('部门编号')" prop="id" sortable="custom"></el-table-column>
|
||||
<el-table-column :label="$t('部门名称')" prop="name" sortable="custom"></el-table-column>
|
||||
<el-table-column :label="$t('排序')" align="right" prop="sort" sortable="custom"></el-table-column>
|
||||
<na-col-indicator
|
||||
:label="$t('状态')"
|
||||
:options="[
|
||||
{ text: '启用', type: 'success', value: true },
|
||||
{ text: '禁用', type: 'danger', value: false, pulse: true },
|
||||
]"
|
||||
prop="enabled"></na-col-indicator>
|
||||
<el-table-column :label="$t('创建时间')" align="right" prop="createdTime" sortable="custom"></el-table-column>
|
||||
<el-table-column :label="$t('备注')" prop="summary"></el-table-column>
|
||||
<el-table-column type="selection" width="50" />
|
||||
<el-table-column :label="$t('部门编号')" prop="id" sortable="custom" />
|
||||
<el-table-column :label="$t('部门名称')" prop="name" sortable="custom" />
|
||||
<el-table-column :label="$t('排序')" align="right" prop="sort" sortable="custom" />
|
||||
<el-table-column :label="$t('启用')" align="center" prop="enabled" sortable="custom" width="80">
|
||||
<template #default="scope">
|
||||
<el-switch v-model="scope.row.enabled" @change="changeSwitch($event, scope.row)"></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('备注')" prop="summary" />
|
||||
<el-table-column :label="$t('创建时间')" align="right" prop="createdTime" sortable="custom" />
|
||||
<na-col-operation
|
||||
:buttons="
|
||||
naColOperation.buttons.concat({
|
||||
@ -89,44 +97,44 @@ import naColOperation from '@/config/naColOperation'
|
||||
import table from '@/config/table'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
table() {
|
||||
return table
|
||||
},
|
||||
naColOperation() {
|
||||
return naColOperation
|
||||
},
|
||||
},
|
||||
components: {
|
||||
saveDialog,
|
||||
},
|
||||
inject: ['reload'],
|
||||
computed: {
|
||||
naColOperation() {
|
||||
return naColOperation
|
||||
},
|
||||
table() {
|
||||
return table
|
||||
},
|
||||
},
|
||||
created() {},
|
||||
data() {
|
||||
return {
|
||||
dialog: {
|
||||
save: false,
|
||||
},
|
||||
loading: false,
|
||||
query: {
|
||||
dynamicFilter: {
|
||||
filters: [],
|
||||
},
|
||||
filter: {},
|
||||
},
|
||||
dialog: {
|
||||
save: false,
|
||||
},
|
||||
selection: [],
|
||||
}
|
||||
},
|
||||
inject: ['reload'],
|
||||
methods: {
|
||||
//删除
|
||||
async rowDel(row) {
|
||||
async changeSwitch(event, row) {
|
||||
try {
|
||||
const res = await this.$API.sys_dept.delete.post({ id: row.id })
|
||||
await this.$API.sys_dept.setEnabled.post(row)
|
||||
this.$refs.table.refresh()
|
||||
this.$message.success(`删除 ${res.data} 项`)
|
||||
this.$message.success(`操作成功`)
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
},
|
||||
//批量删除
|
||||
async batchDel() {
|
||||
let loading
|
||||
try {
|
||||
@ -144,8 +152,21 @@ export default {
|
||||
}
|
||||
loading?.close()
|
||||
},
|
||||
|
||||
//搜索
|
||||
filterChange(data) {
|
||||
Object.entries(data).forEach(([key, value]) => {
|
||||
this.$refs.search.form.dy[key] = value === 'true' ? true : value === 'false' ? false : value
|
||||
this.$refs.search.search()
|
||||
})
|
||||
},
|
||||
async rowDel(row) {
|
||||
try {
|
||||
const res = await this.$API.sys_dept.delete.post({ id: row.id })
|
||||
this.$message.success(`删除 ${res.data} 项`)
|
||||
this.$refs.table.refresh()
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
},
|
||||
onSearch(form) {
|
||||
if (Array.isArray(form.dy.createdTime)) {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
@ -166,6 +187,8 @@ export default {
|
||||
this.$refs.table.upData()
|
||||
},
|
||||
},
|
||||
mounted() {},
|
||||
watch: {},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<sc-dialog v-model="visible" :title="titleMap[mode]" :width="500" @closed="$emit('closed')" destroy-on-close>
|
||||
<sc-dialog v-model="visible" :title="`${titleMap[mode]}:${form?.id ?? '...'}`" :width="500" @closed="$emit('closed')" destroy-on-close>
|
||||
<div v-loading="loading">
|
||||
<el-tabs tab-position="top">
|
||||
<el-tab-pane :label="$t('基本信息')">
|
||||
|
@ -37,10 +37,10 @@
|
||||
remote-sort
|
||||
row-key="id"
|
||||
stripe>
|
||||
<el-table-column type="selection" width="50"></el-table-column>
|
||||
<el-table-column :label="$t('项名')" prop="key" sortable="custom"></el-table-column>
|
||||
<el-table-column :label="$t('项值')" prop="value" sortable="custom"></el-table-column>
|
||||
<el-table-column :label="$t('创建时间')" align="right" prop="createdTime" sortable="custom"></el-table-column>
|
||||
<el-table-column type="selection" width="50" />
|
||||
<el-table-column :label="$t('项名')" prop="key" sortable="custom" />
|
||||
<el-table-column :label="$t('项值')" prop="value" sortable="custom" />
|
||||
<el-table-column :label="$t('创建时间')" align="right" prop="createdTime" sortable="custom" />
|
||||
<na-col-operation
|
||||
:buttons="
|
||||
naColOperation.buttons.concat({
|
||||
@ -51,7 +51,7 @@
|
||||
type: 'danger',
|
||||
})
|
||||
"
|
||||
:vue="this"></na-col-operation>
|
||||
:vue="this" />
|
||||
</sc-table>
|
||||
</el-main>
|
||||
</el-container>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<sc-dialog v-model="visible" :title="titleMap[mode]" :width="400" @closed="$emit('closed')" destroy-on-close>
|
||||
<sc-dialog v-model="visible" :title="`${titleMap[mode]}:${form?.id ?? '...'}`" :width="800" @closed="$emit('closed')" destroy-on-close>
|
||||
<div v-loading="loading">
|
||||
<el-tabs tab-position="top">
|
||||
<el-tab-pane :label="$t('基本信息')">
|
||||
@ -41,9 +41,9 @@ export default {
|
||||
return {
|
||||
mode: 'add',
|
||||
titleMap: {
|
||||
view: '查看字典',
|
||||
add: '新增字典',
|
||||
edit: '编辑字典',
|
||||
view: '查看字典项',
|
||||
add: '新增字典项',
|
||||
edit: '编辑字典项',
|
||||
},
|
||||
visible: false,
|
||||
loading: false,
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<sc-dialog v-model="visible" :title="titleMap[mode]" :width="400" @closed="$emit('closed')" destroy-on-close>
|
||||
<sc-dialog v-model="visible" :title="`${titleMap[mode]}:${form?.id ?? '...'}`" :width="800" @closed="$emit('closed')" destroy-on-close>
|
||||
<el-form v-loading="loading" :model="form" :rules="rules" label-width="10rem" ref="dialogForm">
|
||||
<el-form-item :label="$t('字典名称')" prop="name">
|
||||
<el-input v-model="form.name" :placeholder="$t('字典显示名称')" clearable></el-input>
|
||||
|
@ -13,6 +13,15 @@
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
title: $t('启用状态'),
|
||||
key: 'enabled',
|
||||
options: [
|
||||
{ label: $t('全部'), value: '' },
|
||||
{ label: $t('启用'), value: true },
|
||||
{ label: $t('禁用'), value: false },
|
||||
],
|
||||
},
|
||||
]"
|
||||
:label-width="6"
|
||||
@on-change="filterChange"
|
||||
@ -37,16 +46,6 @@
|
||||
placeholder: $t('请求方式'),
|
||||
style: 'width:10rem',
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
field: ['dy', 'enabled'],
|
||||
options: [
|
||||
{ label: '启用', value: true },
|
||||
{ label: '禁用', value: false },
|
||||
],
|
||||
placeholder: '状态',
|
||||
style: 'width:10rem',
|
||||
},
|
||||
]"
|
||||
:vue="this"
|
||||
@reset="Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = ['']))"
|
||||
@ -88,7 +87,7 @@
|
||||
remote-sort
|
||||
row-key="id"
|
||||
stripe>
|
||||
<el-table-column type="selection"></el-table-column>
|
||||
<el-table-column type="selection" />
|
||||
<el-table-column :label="$t('作业编号')" prop="id" sortable="custom" width="150" />
|
||||
<el-table-column :label="$t('作业名称')" prop="jobName" show-overflow-tooltip sortable="custom" />
|
||||
<el-table-column :label="$t('执行计划')" align="center" prop="executionCron" sortable="custom" width="150" />
|
||||
@ -98,8 +97,10 @@
|
||||
{ text: '空闲', type: 'success', value: 'idle' },
|
||||
{ text: '运行', type: 'warning', value: 'running' },
|
||||
]"
|
||||
align="center"
|
||||
prop="status"
|
||||
width="100"></na-col-indicator>
|
||||
sortable="custom"
|
||||
width="100" />
|
||||
<na-col-indicator
|
||||
:label="$t('请求方式')"
|
||||
:options="
|
||||
@ -107,19 +108,19 @@
|
||||
return { value: x[0], text: x[1][1] }
|
||||
})
|
||||
"
|
||||
align="center"
|
||||
prop="httpMethod"
|
||||
sortable="custom"
|
||||
width="100" />
|
||||
<el-table-column :label="$t('上次执行')" align="center">
|
||||
<el-table-column :label="$t('状态')" align="center" prop="lastExecTime" sortable="custom" width="150">
|
||||
<template #default="scope">
|
||||
<div class="indicator">
|
||||
<sc-status-indicator :type="scope.row.lastStatusCode === 'ok' ? 'success' : 'danger'" />
|
||||
<span>{{
|
||||
this.$GLOBAL.enums.httpStatusCodes[scope.row.lastStatusCode]
|
||||
? this.$GLOBAL.enums.httpStatusCodes[scope.row.lastStatusCode][1]
|
||||
: scope.row.lastStatusCode
|
||||
}}</span>
|
||||
</div>
|
||||
<sc-status-indicator :type="scope.row.lastStatusCode === 'ok' ? 'success' : 'danger'" />
|
||||
{{
|
||||
this.$GLOBAL.enums.httpStatusCodes[scope.row.lastStatusCode]
|
||||
? this.$GLOBAL.enums.httpStatusCodes[scope.row.lastStatusCode][1]
|
||||
: scope.row.lastStatusCode
|
||||
}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('时间')" align="right" prop="lastExecTime" sortable="custom" width="100">
|
||||
@ -231,7 +232,7 @@ export default {
|
||||
methods: {
|
||||
filterChange(data) {
|
||||
Object.entries(data).forEach(([key, value]) => {
|
||||
this.$refs.search.form.dy[key] = value
|
||||
this.$refs.search.form.dy[key] = value === 'true' ? true : value === 'false' ? false : value
|
||||
})
|
||||
this.$refs.search.search()
|
||||
},
|
||||
@ -240,10 +241,10 @@ export default {
|
||||
try {
|
||||
await this.$API.sys_job.setEnabled.post(row)
|
||||
this.$message.success(`操作成功`)
|
||||
this.$refs.table.refresh()
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
this.$refs.table.refresh()
|
||||
},
|
||||
async execute(row) {
|
||||
try {
|
||||
|
@ -36,6 +36,9 @@
|
||||
]"
|
||||
:vue="this"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
<div class="right-panel"></div>
|
||||
@ -44,13 +47,10 @@
|
||||
<sc-table
|
||||
v-loading="loading"
|
||||
:apiObj="$API.sys_job.recordPagedQuery"
|
||||
:context-menus="['id', 'duration', 'httpMethod', 'requestUrl', 'httpStatusCode', 'createdTime']"
|
||||
:default-sort="{ prop: 'createdTime', order: 'descending' }"
|
||||
:params="query"
|
||||
@selection-change="
|
||||
(items) => {
|
||||
selection = items
|
||||
}
|
||||
"
|
||||
:vue="this"
|
||||
ref="table"
|
||||
remote-filter
|
||||
remote-sort
|
||||
@ -71,18 +71,18 @@
|
||||
return { value: x[0], text: x[1][1] }
|
||||
})
|
||||
"
|
||||
align="center"
|
||||
prop="httpMethod"
|
||||
sortable="custom"
|
||||
width="100" />
|
||||
<el-table-column :label="$t('响应状态码')" align="center" prop="httpStatusCode" sortable="custom" width="200">
|
||||
<template #default="scope">
|
||||
<div class="indicator">
|
||||
<sc-status-indicator :type="scope.row.httpStatusCode === 'ok' ? 'success' : 'danger'" />
|
||||
<span>{{
|
||||
this.$GLOBAL.enums.httpStatusCodes[scope.row.httpStatusCode]
|
||||
? this.$GLOBAL.enums.httpStatusCodes[scope.row.httpStatusCode][1]
|
||||
: scope.row.httpStatusCode
|
||||
}}</span>
|
||||
</div>
|
||||
<sc-status-indicator :type="scope.row.httpStatusCode === 'ok' ? 'success' : 'danger'" />
|
||||
{{
|
||||
this.$GLOBAL.enums.httpStatusCodes[scope.row.httpStatusCode]
|
||||
? this.$GLOBAL.enums.httpStatusCodes[scope.row.httpStatusCode][1]
|
||||
: scope.row.httpStatusCode
|
||||
}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('请求的网络地址')" prop="requestUrl" sortable="custom" />
|
||||
@ -110,19 +110,25 @@ export default {
|
||||
components: {
|
||||
saveDialog,
|
||||
},
|
||||
inject: ['reload'],
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
query: {
|
||||
dynamicFilter: {
|
||||
filters: [],
|
||||
filters: [
|
||||
{
|
||||
field: 'createdTime',
|
||||
operator: 'dateRange',
|
||||
value: [tool.dateFormat(new Date(), 'yyyy-MM-dd'), tool.dateFormat(new Date(), 'yyyy-MM-dd')],
|
||||
},
|
||||
],
|
||||
},
|
||||
filter: {},
|
||||
},
|
||||
dialog: {
|
||||
save: false,
|
||||
},
|
||||
selection: [],
|
||||
}
|
||||
},
|
||||
watch: {},
|
||||
@ -142,6 +148,10 @@ export default {
|
||||
this.$refs.search.form.root.keywords = this.keywords
|
||||
this.$refs.search.keepKeywords = this.keywords
|
||||
}
|
||||
this.$refs.search.form.dy.createdTime = this.$refs.search.keepCreatedTime = [
|
||||
`${tool.dateFormat(new Date(), 'yyyy-MM-dd')} 00:00:00`,
|
||||
`${tool.dateFormat(new Date(), 'yyyy-MM-dd')} 00:00:00`,
|
||||
]
|
||||
},
|
||||
created() {
|
||||
if (this.keywords) {
|
||||
@ -149,52 +159,13 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//表格内开关事件
|
||||
async changeSwitch(event, row) {
|
||||
try {
|
||||
await this.$API.sys_job.setEnabled.post(row)
|
||||
this.$message.success(`操作成功`)
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
this.$refs.table.refresh()
|
||||
},
|
||||
//删除
|
||||
async rowDel(row) {
|
||||
try {
|
||||
const res = await this.$API.sys_job.delete.post({ id: row.id })
|
||||
this.$refs.table.refresh()
|
||||
this.$message.success(`删除 ${res.data} 项`)
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
},
|
||||
//批量删除
|
||||
async batchDel() {
|
||||
let loading
|
||||
try {
|
||||
await this.$confirm(`确定删除选中的 ${this.selection.length} 项吗?`, '提示', {
|
||||
type: 'warning',
|
||||
})
|
||||
loading = this.$loading()
|
||||
const res = await this.$API.sys_job.bulkDelete.post({
|
||||
items: this.selection,
|
||||
})
|
||||
this.$refs.table.refresh()
|
||||
this.$message.success(`删除 ${res.data} 项`)
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
loading?.close()
|
||||
},
|
||||
|
||||
//搜索
|
||||
onSearch(form) {
|
||||
if (Array.isArray(form.dy.createdTime)) {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: 'createdTime',
|
||||
operator: 'dateRange',
|
||||
value: form.dy.createdTime,
|
||||
value: form.dy.createdTime.map((x) => x.replace(/ 00:00:00$/, '')),
|
||||
})
|
||||
}
|
||||
|
||||
@ -220,6 +191,13 @@ export default {
|
||||
filters: filters,
|
||||
})
|
||||
}
|
||||
if (typeof form.dy.httpMethod === 'string' && form.dy.httpMethod.trim() !== '') {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: 'httpMethod',
|
||||
operator: 'eq',
|
||||
value: form.dy.httpMethod,
|
||||
})
|
||||
}
|
||||
|
||||
this.$refs.table.upData()
|
||||
},
|
||||
|
@ -1,5 +1,11 @@
|
||||
<template>
|
||||
<sc-dialog v-model="visible" :title="titleMap[mode]" :width="800" @closed="$emit('closed')" destroy-on-close full-screen>
|
||||
<sc-dialog
|
||||
v-model="visible"
|
||||
:title="`${titleMap[mode]}:${form?.id ?? '...'}`"
|
||||
:width="800"
|
||||
@closed="$emit('closed')"
|
||||
destroy-on-close
|
||||
full-screen>
|
||||
<el-form
|
||||
v-loading="loading"
|
||||
:disabled="mode === 'view'"
|
||||
|
@ -1,5 +1,11 @@
|
||||
<template>
|
||||
<sc-dialog v-model="visible" :title="titleMap[mode]" :width="800" @closed="$emit('closed')" destroy-on-close full-screen>
|
||||
<sc-dialog
|
||||
v-model="visible"
|
||||
:title="`${titleMap[mode]}:${form?.id ?? '...'}`"
|
||||
:width="800"
|
||||
@closed="$emit('closed')"
|
||||
destroy-on-close
|
||||
full-screen>
|
||||
<el-tabs v-model="tabIndex" tab-position="top">
|
||||
<el-tab-pane :label="$t('基本信息')" :name="0">
|
||||
<el-form
|
||||
@ -24,6 +30,9 @@
|
||||
<el-form-item :label="$t('作业名称')" prop="jobName">
|
||||
<el-input v-model="form.jobName" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('备注')" prop="summary">
|
||||
<el-input v-model="form.summary" clearable type="textarea" />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="mode === 'view'" :label="$t('上次执行时间')" prop="lastExecTime">
|
||||
<el-input v-model="form.lastExecTime" clearable />
|
||||
</el-form-item>
|
||||
@ -42,6 +51,7 @@
|
||||
:theme="this.$TOOL.data.get('APP_DARK') ? 'github_dark' : 'github'"
|
||||
lang="json"
|
||||
style="height: 5rem; width: 100%" />
|
||||
<el-button @click="form.requestHeader = jsonFormat(form.requestHeader)" type="text">JSON格式化</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('请求体')" prop="requestBody">
|
||||
<v-ace-editor
|
||||
@ -49,6 +59,7 @@
|
||||
:theme="this.$TOOL.data.get('APP_DARK') ? 'github_dark' : 'github'"
|
||||
lang="json"
|
||||
style="height: 10rem; width: 100%" />
|
||||
<el-button @click="form.requestBody = jsonFormat(form.requestBody)" type="text">JSON格式化</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('请求的网络地址')" prop="requestUrl">
|
||||
<el-input v-model="form.requestUrl" clearable />
|
||||
@ -109,6 +120,7 @@
|
||||
<script>
|
||||
import scEditor from '@/components/scEditor/index.vue'
|
||||
import Record from '@/views/sys/job/record/index.vue'
|
||||
import vkbeautify from 'vkbeautify/index'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@ -191,6 +203,17 @@ export default {
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
jsonFormat(obj) {
|
||||
try {
|
||||
obj = this.vkbeautify().json(obj, 2)
|
||||
} catch {
|
||||
this.$message.error(this.$t('非JSON格式'))
|
||||
}
|
||||
return obj
|
||||
},
|
||||
vkbeautify() {
|
||||
return vkbeautify
|
||||
},
|
||||
//显示
|
||||
async open(mode = 'add', data, tabIndex = 0) {
|
||||
this.visible = true
|
||||
|
@ -1,17 +1,30 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header style="height: auto; padding: 0 1rem">
|
||||
<sc-select-filter
|
||||
:data="[
|
||||
{
|
||||
title: $t('登录结果'),
|
||||
key: 'loginResult',
|
||||
options: [
|
||||
{ label: $t('全部'), value: '' },
|
||||
{ label: $t('成功'), value: true },
|
||||
{ label: $t('失败'), value: false },
|
||||
],
|
||||
},
|
||||
]"
|
||||
:label-width="6"
|
||||
@on-change="filterChange"
|
||||
ref="selectFilter"></sc-select-filter>
|
||||
</el-header>
|
||||
<el-header>
|
||||
<div class="left-panel">
|
||||
<na-search
|
||||
:controls="[
|
||||
{
|
||||
type: 'select',
|
||||
field: ['dy', 'httpStatusCode'],
|
||||
options: [
|
||||
{ label: '成功', value: '200,299' },
|
||||
{ label: '失败', value: '300,999' },
|
||||
],
|
||||
placeholder: '登录结果',
|
||||
type: 'input',
|
||||
field: ['dy', 'id'],
|
||||
placeholder: '日志编号',
|
||||
style: 'width:15rem',
|
||||
},
|
||||
{
|
||||
@ -28,13 +41,18 @@
|
||||
},
|
||||
]"
|
||||
:vue="this"
|
||||
@reset="Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = ['']))"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
<div class="right-panel"></div>
|
||||
</el-header>
|
||||
<el-main class="nopadding">
|
||||
<sc-table
|
||||
v-loading="loading"
|
||||
:apiObj="$API.sys_log.pagedQuery"
|
||||
:context-menus="['id', 'httpStatusCode', 'extraData', 'createdClientIp', 'os', 'createdUserAgent', 'createdTime']"
|
||||
:context-opers="['view']"
|
||||
@ -43,26 +61,26 @@
|
||||
:vue="this"
|
||||
@row-click="rowClick"
|
||||
ref="table"
|
||||
remoteFilter
|
||||
remoteSort
|
||||
remote-filter
|
||||
remote-sort
|
||||
row-key="id"
|
||||
stripe>
|
||||
<el-table-column :label="$t('日志编号')" prop="id" sortable="custom" width="150"></el-table-column>
|
||||
<el-table-column :label="$t('日志编号')" prop="id" sortable="custom" width="150" />
|
||||
<el-table-column :label="$t('创建时间')" prop="createdTime" sortable="custom" width="170" />
|
||||
<el-table-column :label="$t('结果')" align="center" prop="httpStatusCode" sortable="custom" width="80">
|
||||
<template #default="scope">
|
||||
<sc-status-indicator :type="scope.row.httpStatusCode === 200 ? 'success' : 'danger'" />
|
||||
{{ scope.row.httpStatusCode === 200 ? '成功' : '失败' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('登录名')" prop="extraData" sortable="custom" width="200"></el-table-column>
|
||||
<el-table-column :label="$t('登录名')" prop="extraData" sortable="custom" width="200" />
|
||||
<el-table-column :label="$t('客户端IP')" prop="createdClientIp" sortable="custom" width="200">
|
||||
<template #default="scope">
|
||||
<na-ip :ip="scope.row.createdClientIp"></na-ip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('操作系统')" prop="os" width="150"></el-table-column>
|
||||
<el-table-column :label="$t('用户代理')" prop="createdUserAgent" show-overflow-tooltip sortable="custom"></el-table-column>
|
||||
<el-table-column :label="$t('创建时间')" align="right" prop="createdTime" sortable="custom" width="170"></el-table-column>
|
||||
<el-table-column :label="$t('操作系统')" prop="os" width="150" />
|
||||
<el-table-column :label="$t('用户代理')" prop="createdUserAgent" show-overflow-tooltip sortable="custom" />
|
||||
</sc-table>
|
||||
</el-main>
|
||||
</el-container>
|
||||
@ -84,9 +102,16 @@ export default {
|
||||
inject: ['reload'],
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
query: {
|
||||
dynamicFilter: {
|
||||
filters: [],
|
||||
filters: [
|
||||
{
|
||||
field: 'createdTime',
|
||||
operator: 'dateRange',
|
||||
value: [tool.dateFormat(new Date(), 'yyyy-MM-dd'), tool.dateFormat(new Date(), 'yyyy-MM-dd')],
|
||||
},
|
||||
],
|
||||
},
|
||||
filter: {},
|
||||
},
|
||||
@ -97,6 +122,10 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
this.$refs.search.form.dy.apiId = 'api/sys/user/login.by.pwd'
|
||||
this.$refs.search.form.dy.createdTime = this.$refs.search.keepCreatedTime = [
|
||||
`${tool.dateFormat(new Date(), 'yyyy-MM-dd')} 00:00:00`,
|
||||
`${tool.dateFormat(new Date(), 'yyyy-MM-dd')} 00:00:00`,
|
||||
]
|
||||
},
|
||||
created() {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
@ -106,13 +135,26 @@ export default {
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
filterChange(data) {
|
||||
Object.entries(data).forEach(([key, value]) => {
|
||||
this.$refs.search.form.dy[key] = value === 'true' ? true : value === 'false' ? false : value
|
||||
})
|
||||
this.$refs.search.search()
|
||||
},
|
||||
//搜索
|
||||
onSearch(form) {
|
||||
if (this.query.dynamicFilter.filters.findIndex((x) => x.field === 'apiId') < 0) {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: 'apiId',
|
||||
operator: 'eq',
|
||||
value: 'api/sys/user/login.by.pwd',
|
||||
})
|
||||
}
|
||||
if (Array.isArray(form.dy.createdTime)) {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: 'createdTime',
|
||||
operator: 'dateRange',
|
||||
value: form.dy.createdTime,
|
||||
value: form.dy.createdTime.map((x) => x.replace(/ 00:00:00$/, '')),
|
||||
})
|
||||
}
|
||||
if (form.dy.httpStatusCode) {
|
||||
@ -129,6 +171,13 @@ export default {
|
||||
value: form.dy.apiId,
|
||||
})
|
||||
}
|
||||
if (form.dy.id) {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: 'id',
|
||||
operator: 'eq',
|
||||
value: form.dy.id,
|
||||
})
|
||||
}
|
||||
if (form.dy.extraData) {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: 'extraData',
|
||||
@ -143,6 +192,22 @@ export default {
|
||||
value: form.dy.createdClientIp,
|
||||
})
|
||||
}
|
||||
if (typeof form.dy.loginResult === 'boolean') {
|
||||
this.query.dynamicFilter.filters.push(
|
||||
form.dy.loginResult
|
||||
? {
|
||||
field: 'httpStatusCode',
|
||||
operator: 'range',
|
||||
value: '200,299',
|
||||
}
|
||||
: {
|
||||
field: 'httpStatusCode',
|
||||
operator: 'range',
|
||||
value: '300,999',
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
this.$refs.table.upData()
|
||||
},
|
||||
|
||||
|
@ -68,14 +68,12 @@
|
||||
remoteSort
|
||||
row-key="id"
|
||||
stripe>
|
||||
<el-table-column :label="$t('日志编号')" align="center" prop="id" sortable="custom" width="150"></el-table-column>
|
||||
<el-table-column :label="$t('日志编号')" prop="id" sortable="custom" width="150"> </el-table-column
|
||||
><el-table-column :label="$t('创建时间')" prop="createdTime" sortable="custom" width="170" />
|
||||
<el-table-column :label="$t('响应码')" align="center" prop="httpStatusCode" sortable="custom" width="100">
|
||||
<template #default="scope">
|
||||
<div class="indicator">
|
||||
<sc-status-indicator
|
||||
:style="`background: #${Math.abs(this.$TOOL.crypto.hashCode(scope.row.httpStatusCode)).toString(16).substring(0, 6)}`" />
|
||||
<span> {{ scope.row.httpStatusCode }}</span>
|
||||
</div>
|
||||
<template #default="{ row }">
|
||||
<sc-status-indicator :type="row.httpStatusCode >= 200 && row.httpStatusCode < 300 ? 'success' : 'danger'" />
|
||||
{{ row.httpStatusCode }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('请求服务')" align="center">
|
||||
@ -87,11 +85,9 @@
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('方法')" align="center" prop="method" sortable="custom" width="100">
|
||||
<template #default="scope">
|
||||
<div class="indicator">
|
||||
<sc-status-indicator
|
||||
:style="`background: #${Math.abs(this.$TOOL.crypto.hashCode(scope.row.method)).toString(16).substring(0, 6)}`" />
|
||||
<span> {{ scope.row.method }}</span>
|
||||
</div>
|
||||
<sc-status-indicator
|
||||
:style="`background: #${Math.abs(this.$TOOL.crypto.hashCode(scope.row.method)).toString(16).substring(0, 6)}`" />
|
||||
{{ scope.row.method }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
@ -113,8 +109,7 @@
|
||||
<na-ip :ip="scope.row.createdClientIp"></na-ip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('操作系统')" align="center" prop="os" width="150"></el-table-column>
|
||||
<el-table-column :label="$t('创建时间')" align="right" prop="createdTime" sortable="custom" width="170"></el-table-column>
|
||||
<el-table-column :label="$t('操作系统')" align="center" prop="os" width="150" />
|
||||
</sc-table>
|
||||
</el-main>
|
||||
</el-container>
|
||||
@ -126,6 +121,7 @@
|
||||
import naInfo from '@/components/naInfo/index.vue'
|
||||
import tool from '@/utils/tool'
|
||||
import ScTable from '@/components/scTable/index.vue'
|
||||
import ScStatusIndicator from '@/components/scMini/scStatusIndicator.vue'
|
||||
|
||||
export default {
|
||||
inject: ['reload'],
|
||||
@ -135,6 +131,7 @@ export default {
|
||||
},
|
||||
},
|
||||
components: {
|
||||
ScStatusIndicator,
|
||||
ScTable,
|
||||
naInfo,
|
||||
},
|
||||
|
@ -57,7 +57,7 @@
|
||||
remote-sort
|
||||
row-key="id"
|
||||
stripe>
|
||||
<el-table-column type="selection"></el-table-column>
|
||||
<el-table-column type="selection" />
|
||||
<el-table-column :label="$t('消息编号')" prop="id" sortable="custom" width="150" />
|
||||
<na-col-avatar :label="$t('用户名')" prop="createdUserName" />
|
||||
<na-col-indicator
|
||||
@ -67,9 +67,10 @@
|
||||
return { value: x[0], text: x[1][1] }
|
||||
})
|
||||
"
|
||||
align="center"
|
||||
prop="msgType"
|
||||
width="100">
|
||||
</na-col-indicator>
|
||||
sortable="custom"
|
||||
width="100" />
|
||||
<el-table-column :label="$t('消息主题')" prop="title" show-overflow-tooltip sortable="custom" />
|
||||
<el-table-column :label="$t('消息摘要')" prop="summary" show-overflow-tooltip sortable="custom" />
|
||||
<el-table-column :label="$t('创建时间')" align="right" prop="createdTime" sortable="custom" width="170" />
|
||||
|
@ -1,5 +1,11 @@
|
||||
<template>
|
||||
<sc-dialog v-model="visible" :title="titleMap[mode]" :width="800" @closed="$emit('closed')" destroy-on-close full-screen>
|
||||
<sc-dialog
|
||||
v-model="visible"
|
||||
:title="`${titleMap[mode]}:${form?.id ?? '...'}`"
|
||||
:width="800"
|
||||
@closed="$emit('closed')"
|
||||
destroy-on-close
|
||||
full-screen>
|
||||
<el-form
|
||||
v-loading="loading"
|
||||
:disabled="mode === 'view'"
|
||||
|
@ -1,5 +1,22 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header style="height: auto; padding: 0 1rem">
|
||||
<sc-select-filter
|
||||
:data="[
|
||||
{
|
||||
title: $t('启用状态'),
|
||||
key: 'enabled',
|
||||
options: [
|
||||
{ label: $t('全部'), value: '' },
|
||||
{ label: $t('启用'), value: true },
|
||||
{ label: $t('禁用'), value: false },
|
||||
],
|
||||
},
|
||||
]"
|
||||
:label-width="6"
|
||||
@on-change="filterChange"
|
||||
ref="selectFilter"></sc-select-filter>
|
||||
</el-header>
|
||||
<el-header>
|
||||
<div class="left-panel">
|
||||
<na-search
|
||||
@ -10,16 +27,6 @@
|
||||
placeholder: '角色编号 / 角色名称 / 备注',
|
||||
style: 'width:20rem',
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
field: ['dy', 'enabled'],
|
||||
options: [
|
||||
{ label: '启用', value: true },
|
||||
{ label: '禁用', value: false },
|
||||
],
|
||||
placeholder: '状态',
|
||||
style: 'width:15rem',
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
field: ['dy', 'ignorePermissionControl'],
|
||||
@ -42,15 +49,18 @@
|
||||
},
|
||||
]"
|
||||
:vue="this"
|
||||
@search="onSearch" />
|
||||
@reset="Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = ['']))"
|
||||
@search="onSearch"
|
||||
ref="search" />
|
||||
</div>
|
||||
<div class="right-panel">
|
||||
<na-button-add :vue="this"></na-button-add>
|
||||
<na-button-add :vue="this" />
|
||||
<el-button :disabled="selection.length === 0" @click="batchDel" icon="el-icon-delete" plain type="danger"></el-button>
|
||||
</div>
|
||||
</el-header>
|
||||
<el-main class="nopadding">
|
||||
<sc-table
|
||||
v-loading="loading"
|
||||
:apiObj="$API.sys_role.pagedQuery"
|
||||
:context-menus="['id', 'name', 'sort', 'enabled', 'ignorePermissionControl', 'dataScope', 'displayDashboard', 'createdTime']"
|
||||
:default-sort="{ prop: 'sort', order: 'descending' }"
|
||||
@ -66,24 +76,24 @@
|
||||
remote-sort
|
||||
row-key="id"
|
||||
stripe>
|
||||
<el-table-column type="selection" width="50"></el-table-column>
|
||||
<el-table-column :label="$t('角色编号')" prop="id" sortable="custom"></el-table-column>
|
||||
<el-table-column :label="$t('角色名称')" prop="name" sortable="custom"></el-table-column>
|
||||
<el-table-column :label="$t('排序')" align="right" prop="sort" sortable="custom"></el-table-column>
|
||||
<na-col-indicator
|
||||
:label="$t('状态')"
|
||||
:options="[
|
||||
{ text: '启用', type: 'success', value: true },
|
||||
{ text: '禁用', type: 'danger', value: false, pulse: true },
|
||||
]"
|
||||
prop="enabled"></na-col-indicator>
|
||||
<el-table-column type="selection" />
|
||||
<el-table-column :label="$t('角色编号')" prop="id" sortable="custom" />
|
||||
<el-table-column :label="$t('角色名称')" prop="name" sortable="custom" />
|
||||
<el-table-column :label="$t('排序')" align="right" prop="sort" sortable="custom" />
|
||||
<el-table-column :label="$t('启用')" align="center" prop="enabled" sortable="custom" width="80">
|
||||
<template #default="scope">
|
||||
<el-switch v-model="scope.row.enabled" @change="changeSwitch($event, scope.row)"></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<na-col-indicator
|
||||
:label="$t('无限权限')"
|
||||
:options="[
|
||||
{ text: '是', type: 'success', value: true, pulse: true },
|
||||
{ text: '否', type: 'danger', value: false },
|
||||
]"
|
||||
prop="ignorePermissionControl"></na-col-indicator>
|
||||
align="center"
|
||||
prop="ignorePermissionControl"
|
||||
sortable="custom"></na-col-indicator>
|
||||
<na-col-indicator
|
||||
:label="$t('数据范围')"
|
||||
:options="
|
||||
@ -102,9 +112,11 @@
|
||||
{ text: '是', type: 'success', value: true },
|
||||
{ text: '否', type: 'danger', value: false },
|
||||
]"
|
||||
prop="displayDashboard"></na-col-indicator>
|
||||
align="center"
|
||||
prop="displayDashboard"
|
||||
sortable="custom" />
|
||||
|
||||
<el-table-column :label="$t('创建时间')" align="right" prop="createdTime" sortable="custom"></el-table-column>
|
||||
<el-table-column :label="$t('创建时间')" align="right" prop="createdTime" sortable="custom" />
|
||||
<na-col-operation
|
||||
:buttons="
|
||||
naColOperation.buttons.concat({
|
||||
@ -115,7 +127,7 @@
|
||||
type: 'danger',
|
||||
})
|
||||
"
|
||||
:vue="this"></na-col-operation>
|
||||
:vue="this" />
|
||||
</sc-table>
|
||||
</el-main>
|
||||
</el-container>
|
||||
@ -133,44 +145,44 @@ import naColOperation from '@/config/naColOperation'
|
||||
import table from '@/config/table'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
table() {
|
||||
return table
|
||||
},
|
||||
naColOperation() {
|
||||
return naColOperation
|
||||
},
|
||||
},
|
||||
components: {
|
||||
saveDialog,
|
||||
},
|
||||
inject: ['reload'],
|
||||
computed: {
|
||||
naColOperation() {
|
||||
return naColOperation
|
||||
},
|
||||
table() {
|
||||
return table
|
||||
},
|
||||
},
|
||||
created() {},
|
||||
data() {
|
||||
return {
|
||||
dialog: {
|
||||
save: false,
|
||||
},
|
||||
loading: false,
|
||||
query: {
|
||||
dynamicFilter: {
|
||||
filters: [],
|
||||
},
|
||||
filter: {},
|
||||
},
|
||||
dialog: {
|
||||
save: false,
|
||||
},
|
||||
selection: [],
|
||||
}
|
||||
},
|
||||
inject: ['reload'],
|
||||
methods: {
|
||||
//删除
|
||||
async rowDel(row) {
|
||||
async changeSwitch(event, row) {
|
||||
try {
|
||||
const res = await this.$API.sys_role.delete.post({ id: row.id })
|
||||
await this.$API.sys_role.setEnabled.post(row)
|
||||
this.$refs.table.refresh()
|
||||
this.$message.success(`删除 ${res.data} 项`)
|
||||
this.$message.success(`操作成功`)
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
},
|
||||
//批量删除
|
||||
async batchDel() {
|
||||
let loading
|
||||
try {
|
||||
@ -188,8 +200,21 @@ export default {
|
||||
}
|
||||
loading?.close()
|
||||
},
|
||||
|
||||
//搜索
|
||||
filterChange(data) {
|
||||
Object.entries(data).forEach(([key, value]) => {
|
||||
this.$refs.search.form.dy[key] = value === 'true' ? true : value === 'false' ? false : value
|
||||
this.$refs.search.search()
|
||||
})
|
||||
},
|
||||
async rowDel(row) {
|
||||
try {
|
||||
const res = await this.$API.sys_role.delete.post({ id: row.id })
|
||||
this.$message.success(`删除 ${res.data} 项`)
|
||||
this.$refs.table.refresh()
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
},
|
||||
onSearch(form) {
|
||||
if (Array.isArray(form.dy.createdTime)) {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
@ -222,10 +247,11 @@ export default {
|
||||
value: form.dy.displayDashboard,
|
||||
})
|
||||
}
|
||||
|
||||
this.$refs.table.upData()
|
||||
},
|
||||
},
|
||||
mounted() {},
|
||||
watch: {},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<sc-dialog v-model="visible" :title="titleMap[mode]" :width="800" @closed="$emit('closed')" destroy-on-close>
|
||||
<sc-dialog v-model="visible" :title="`${titleMap[mode]}:${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close full-screen>
|
||||
<div v-loading="loading">
|
||||
<el-tabs tab-position="top">
|
||||
<el-tab-pane :label="$t('基本信息')">
|
||||
|
@ -1,5 +1,22 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header style="height: auto; padding: 0 1rem">
|
||||
<sc-select-filter
|
||||
:data="[
|
||||
{
|
||||
title: $t('启用状态'),
|
||||
key: 'enabled',
|
||||
options: [
|
||||
{ label: $t('全部'), value: '' },
|
||||
{ label: $t('启用'), value: true },
|
||||
{ label: $t('禁用'), value: false },
|
||||
],
|
||||
},
|
||||
]"
|
||||
:label-width="6"
|
||||
@on-change="filterChange"
|
||||
ref="selectFilter"></sc-select-filter>
|
||||
</el-header>
|
||||
<el-header>
|
||||
<div class="left-panel">
|
||||
<na-search
|
||||
@ -26,19 +43,11 @@
|
||||
placeholder: '所属部门',
|
||||
style: 'width:15rem',
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
field: ['dy', 'enabled'],
|
||||
options: [
|
||||
{ label: '启用', value: true },
|
||||
{ label: '禁用', value: false },
|
||||
],
|
||||
placeholder: '是否启用',
|
||||
style: 'width:10rem',
|
||||
},
|
||||
]"
|
||||
:vue="this"
|
||||
@search="onSearch" />
|
||||
@reset="Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = ['']))"
|
||||
@search="onSearch"
|
||||
ref="search" />
|
||||
</div>
|
||||
<div class="right-panel">
|
||||
<na-button-add :vue="this" />
|
||||
@ -63,11 +72,11 @@
|
||||
remote-sort
|
||||
row-key="id"
|
||||
stripe>
|
||||
<el-table-column type="selection"></el-table-column>
|
||||
<el-table-column :label="$t('用户编号')" prop="id" sortable="custom" width="150"></el-table-column>
|
||||
<el-table-column type="selection" />
|
||||
<el-table-column :label="$t('用户编号')" prop="id" sortable="custom" width="150" />
|
||||
<na-col-avatar :label="$t('用户名')" prop="userName" />
|
||||
<el-table-column :label="$t('手机号')" align="center" prop="mobile" sortable="custom" width="120"></el-table-column>
|
||||
<el-table-column :label="$t('邮箱')" prop="email" sortable="custom"></el-table-column>
|
||||
<el-table-column :label="$t('手机号')" align="center" prop="mobile" sortable="custom" width="120" />
|
||||
<el-table-column :label="$t('邮箱')" prop="email" sortable="custom" />
|
||||
<na-col-tags :label="$t('所属角色')" @click="(item) => openDialog('sys_role', item.id, 'roleSave')" field="name" prop="roles" />
|
||||
<na-col-tags :label="$t('所属部门')" @click="(item) => openDialog('sys_dept', item.id, 'deptSave')" field="name" prop="dept" />
|
||||
<el-table-column :label="$t('启用')" align="center" prop="enabled" sortable="custom" width="80">
|
||||
@ -75,8 +84,8 @@
|
||||
<el-switch v-model="scope.row.enabled" @change="changeSwitch($event, scope.row)"></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('创建时间')" align="right" prop="createdTime" sortable="custom"></el-table-column>
|
||||
<na-col-operation :vue="this"></na-col-operation>
|
||||
<el-table-column :label="$t('创建时间')" align="right" prop="createdTime" sortable="custom" />
|
||||
<na-col-operation :vue="this" />
|
||||
</sc-table>
|
||||
</el-main>
|
||||
</el-container>
|
||||
@ -98,13 +107,23 @@ import table from '@/config/table'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
saveDialog,
|
||||
roleSaveDialog,
|
||||
deptSaveDialog,
|
||||
roleSaveDialog,
|
||||
saveDialog,
|
||||
},
|
||||
inject: ['reload'],
|
||||
computed: {
|
||||
table() {
|
||||
return table
|
||||
},
|
||||
},
|
||||
created() {},
|
||||
data() {
|
||||
return {
|
||||
dialog: {
|
||||
deptSave: false,
|
||||
roleSave: false,
|
||||
save: false,
|
||||
},
|
||||
loading: false,
|
||||
query: {
|
||||
dynamicFilter: {
|
||||
@ -112,32 +131,25 @@ export default {
|
||||
},
|
||||
filter: {},
|
||||
},
|
||||
dialog: {
|
||||
roleSave: false,
|
||||
deptSave: false,
|
||||
save: false,
|
||||
},
|
||||
selection: [],
|
||||
}
|
||||
},
|
||||
watch: {},
|
||||
computed: {
|
||||
table() {
|
||||
return table
|
||||
},
|
||||
},
|
||||
mounted() {},
|
||||
created() {},
|
||||
inject: ['reload'],
|
||||
methods: {
|
||||
//表格内开关事件
|
||||
async changeSwitch(event, row) {
|
||||
try {
|
||||
await this.$API.sys_user.setEnabled.post(row)
|
||||
this.$refs.table.refresh()
|
||||
this.$message.success(`操作成功`)
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
this.$refs.table.refresh()
|
||||
},
|
||||
filterChange(data) {
|
||||
Object.entries(data).forEach(([key, value]) => {
|
||||
this.$refs.search.form.dy[key] = value === 'true' ? true : value === 'false' ? false : value
|
||||
this.$refs.search.search()
|
||||
})
|
||||
},
|
||||
async openDialog(api, id, dialog) {
|
||||
this.loading = true
|
||||
@ -149,8 +161,6 @@ export default {
|
||||
await this.$nextTick()
|
||||
this.$refs[`${dialog}Dialog`].open('view', res.data[0])
|
||||
},
|
||||
|
||||
//搜索
|
||||
onSearch(form) {
|
||||
if (Array.isArray(form.dy.createdTime)) {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
@ -171,6 +181,8 @@ export default {
|
||||
this.$refs.table.upData()
|
||||
},
|
||||
},
|
||||
mounted() {},
|
||||
watch: {},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -1,5 +1,11 @@
|
||||
<template>
|
||||
<sc-dialog v-model="visible" :title="titleMap[mode]" :width="800" @closed="$emit('closed')" append-to-body destroy-on-close>
|
||||
<sc-dialog
|
||||
v-model="visible"
|
||||
:title="`${titleMap[mode]}:${form?.id ?? '...'}`"
|
||||
:width="800"
|
||||
@closed="$emit('closed')"
|
||||
append-to-body
|
||||
destroy-on-close>
|
||||
<el-form
|
||||
v-loading="loading"
|
||||
:disabled="mode === 'view'"
|
||||
|
Loading…
x
Reference in New Issue
Block a user