😎优化代码

This commit is contained in:
zuohuaijun 2025-01-03 16:14:30 +08:00
parent 0114615004
commit c9144b6784
12 changed files with 84 additions and 71 deletions

View File

@ -14,12 +14,12 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AlibabaCloud.SDK.Dysmsapi20170525" Version="3.1.0" /> <PackageReference Include="AlibabaCloud.SDK.Dysmsapi20170525" Version="3.1.0" />
<PackageReference Include="AlipaySDKNet.Standard" Version="4.9.370" /> <PackageReference Include="AlipaySDKNet.Standard" Version="4.9.376" />
<PackageReference Include="AngleSharp" Version="1.2.0" /> <PackageReference Include="AngleSharp" Version="1.2.0" />
<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="BouncyCastle.Cryptography" Version="2.5.0" Aliases="BouncyCastleV2" /> <PackageReference Include="BouncyCastle.Cryptography" Version="2.5.0" Aliases="BouncyCastleV2" />
<PackageReference Include="Elastic.Clients.Elasticsearch" Version="8.16.3" /> <PackageReference Include="Elastic.Clients.Elasticsearch" Version="8.17.0" />
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.6.20" /> <PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.6.20" />
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.9.6.20" /> <PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.9.6.20" />
<PackageReference Include="Furion.Pure" Version="4.9.6.20" /> <PackageReference Include="Furion.Pure" Version="4.9.6.20" />
@ -49,7 +49,7 @@
<PackageReference Include="SSH.NET" Version="2024.2.0" /> <PackageReference Include="SSH.NET" Version="2024.2.0" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.5.1" /> <PackageReference Include="System.Linq.Dynamic.Core" Version="1.5.1" />
<PackageReference Include="System.Net.Http" Version="4.3.4" /> <PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="TencentCloudSDK.Sms" Version="3.0.1155" /> <PackageReference Include="TencentCloudSDK.Sms" Version="3.0.1156" />
<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>

View File

@ -85,17 +85,11 @@ public class DatabaseLoggingWriter : IDatabaseLoggingWriter, IDisposable
string account = "", realName = "", userId = "", tenantId = ""; string account = "", realName = "", userId = "", tenantId = "";
if (loggingMonitor.authorizationClaims != null) if (loggingMonitor.authorizationClaims != null)
{ {
foreach (var item in loggingMonitor.authorizationClaims) var authDict = (loggingMonitor.authorizationClaims as IEnumerable<dynamic>)!.ToDictionary(u => u.type.ToString(), u => u.value.ToString());
{ account = authDict?.GetValueOrDefault(ClaimConst.Account);
if (item.type == ClaimConst.Account) realName = authDict?.GetValueOrDefault(ClaimConst.RealName);
account = item.value; tenantId = authDict?.GetValueOrDefault(ClaimConst.TenantId);
if (item.type == ClaimConst.RealName) userId = authDict?.GetValueOrDefault(ClaimConst.UserId);
realName = item.value;
if (item.type == ClaimConst.TenantId)
tenantId = item.value;
if (item.type == ClaimConst.UserId)
userId = item.value;
}
} }
// 优先获取 X-Forwarded-For 头部信息携带的IP地址如nginx代理配置转发 // 优先获取 X-Forwarded-For 头部信息携带的IP地址如nginx代理配置转发

View File

@ -4,7 +4,6 @@
// //
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Admin.NET.Core.Service.Alipay;
using Aop.Api; using Aop.Api;
using Aop.Api.Domain; using Aop.Api.Domain;
using Aop.Api.Request; using Aop.Api.Request;
@ -20,24 +19,27 @@ namespace Admin.NET.Core.Service;
[ApiDescriptionSettings(Order = 240)] [ApiDescriptionSettings(Order = 240)]
public class AlipayService : IDynamicApiController, ITransient public class AlipayService : IDynamicApiController, ITransient
{ {
private readonly UserManager _userManager; private readonly IEnumerable<IAlipayNotify> _alipayNotifyList;
private readonly SysConfigService _sysConfigService;
private readonly AlipayOptions _alipayOptions;
private readonly IHttpContextAccessor _httpContext;
private readonly IWebHostEnvironment _webHostEnvironment; private readonly IWebHostEnvironment _webHostEnvironment;
private readonly SysConfigService _sysConfigService;
private readonly IHttpContextAccessor _httpContext;
private readonly AlipayOptions _alipayOptions;
private readonly IAopClient _alipayClient; private readonly IAopClient _alipayClient;
private readonly UserManager _userManager;
public AlipayService(UserManager userManager, public AlipayService(
SysConfigService sysConfigService, UserManager userManager,
IOptions<AlipayOptions> alipayOptions,
IHttpContextAccessor httpContext, IHttpContextAccessor httpContext,
IWebHostEnvironment webHostEnvironment) SysConfigService sysConfigService,
IWebHostEnvironment webHostEnvironment,
IOptions<AlipayOptions> alipayOptions)
{ {
_userManager = userManager; _userManager = userManager;
_httpContext = httpContext;
_sysConfigService = sysConfigService; _sysConfigService = sysConfigService;
_alipayOptions = alipayOptions.Value; _alipayOptions = alipayOptions.Value;
_httpContext = httpContext;
_webHostEnvironment = webHostEnvironment; _webHostEnvironment = webHostEnvironment;
_alipayNotifyList = App.GetServices<IAlipayNotify>();
// 初始化支付宝客户端 // 初始化支付宝客户端
string path = App.WebHostEnvironment.ContentRootPath; string path = App.WebHostEnvironment.ContentRootPath;
@ -93,7 +95,7 @@ public class AlipayService : IDynamicApiController, ITransient
// 循环执行扫码后需要执行的业务逻辑需要至少一个继承方法返回true否则抛出异常 // 循环执行扫码后需要执行的业务逻辑需要至少一个继承方法返回true否则抛出异常
var pass = false; var pass = false;
foreach (var notify in App.GetServices<IAlipayNotify>()) foreach (var notify in _alipayNotifyList)
if (notify.ScanCallback(type, userId, info)) pass = true; if (notify.ScanCallback(type, userId, info)) pass = true;
if (!pass) throw Oops.Oh("未处理的授权逻辑"); if (!pass) throw Oops.Oh("未处理的授权逻辑");
@ -145,7 +147,7 @@ public class AlipayService : IDynamicApiController, ITransient
// 循环执行业务逻辑,若都未处理(回调全部返回false)则交易失败 // 循环执行业务逻辑,若都未处理(回调全部返回false)则交易失败
var isError = true; var isError = true;
foreach (var notify in App.GetServices<IAlipayNotify>()) foreach (var notify in _alipayNotifyList)
if (notify.TopUpCallback(type, tradeNo)) isError = false; if (notify.TopUpCallback(type, tradeNo)) isError = false;
if (isError) throw Oops.Oh("交易失败"); if (isError) throw Oops.Oh("交易失败");
} }

View File

@ -5,7 +5,6 @@
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Aop.Api.Domain; using Aop.Api.Domain;
using Newtonsoft.Json;
namespace Admin.NET.Core.Service; namespace Admin.NET.Core.Service;

View File

@ -6,7 +6,7 @@
using Aop.Api.Response; using Aop.Api.Response;
namespace Admin.NET.Core.Service.Alipay; namespace Admin.NET.Core.Service;
/// <summary> /// <summary>
/// 支付宝回调接口 /// 支付宝回调接口

View File

@ -14,8 +14,8 @@ public class SysRoleService : IDynamicApiController, ITransient
{ {
private readonly UserManager _userManager; private readonly UserManager _userManager;
private readonly SqlSugarRepository<SysRole> _sysRoleRep; private readonly SqlSugarRepository<SysRole> _sysRoleRep;
private readonly SysRoleOrgService _sysRoleOrgService;
private readonly SysRoleMenuService _sysRoleMenuService; private readonly SysRoleMenuService _sysRoleMenuService;
private readonly SysRoleOrgService _sysRoleOrgService;
private readonly SysRoleTableService _sysRoleTableService; private readonly SysRoleTableService _sysRoleTableService;
private readonly SysRoleApiService _sysRoleApiService; private readonly SysRoleApiService _sysRoleApiService;
private readonly SysOrgService _sysOrgService; private readonly SysOrgService _sysOrgService;
@ -25,8 +25,8 @@ public class SysRoleService : IDynamicApiController, ITransient
public SysRoleService(UserManager userManager, public SysRoleService(UserManager userManager,
SqlSugarRepository<SysRole> sysRoleRep, SqlSugarRepository<SysRole> sysRoleRep,
SysRoleOrgService sysRoleOrgService,
SysRoleMenuService sysRoleMenuService, SysRoleMenuService sysRoleMenuService,
SysRoleOrgService sysRoleOrgService,
SysRoleTableService sysRoleTableService, SysRoleTableService sysRoleTableService,
SysRoleApiService sysRoleApiService, SysRoleApiService sysRoleApiService,
SysOrgService sysOrgService, SysOrgService sysOrgService,
@ -36,8 +36,8 @@ public class SysRoleService : IDynamicApiController, ITransient
{ {
_userManager = userManager; _userManager = userManager;
_sysRoleRep = sysRoleRep; _sysRoleRep = sysRoleRep;
_sysRoleOrgService = sysRoleOrgService;
_sysRoleMenuService = sysRoleMenuService; _sysRoleMenuService = sysRoleMenuService;
_sysRoleOrgService = sysRoleOrgService;
_sysRoleTableService = sysRoleTableService; _sysRoleTableService = sysRoleTableService;
_sysRoleApiService = sysRoleApiService; _sysRoleApiService = sysRoleApiService;
_sysOrgService = sysOrgService; _sysOrgService = sysOrgService;

View File

@ -49,7 +49,7 @@ public static class SqlSugarFilter
{ {
// 若仅本人数据,则直接返回 // 若仅本人数据,则直接返回
var maxDataScope = SetDataScopeFilter(db); var maxDataScope = SetDataScopeFilter(db);
if (maxDataScope == 0 || maxDataScope == (int)DataScopeEnum.Self) return; if (maxDataScope is 0 or (int)DataScopeEnum.Self) return;
var userId = App.User?.FindFirst(ClaimConst.UserId)?.Value; var userId = App.User?.FindFirst(ClaimConst.UserId)?.Value;
if (string.IsNullOrWhiteSpace(userId)) return; if (string.IsNullOrWhiteSpace(userId)) return;

View File

@ -88,6 +88,11 @@ public class ExcelHelper
using var package = new ExcelPackage((ExportData(list, filename) as XlsxFileResult)!.Stream); using var package = new ExcelPackage((ExportData(list, filename) as XlsxFileResult)!.Stream);
var worksheet = package.Workbook.Worksheets[0]; var worksheet = package.Workbook.Worksheets[0];
// 创建一个隐藏的sheet用于添加下拉列表
var dropdownSheet = package.Workbook.Worksheets.Add("下拉数据");
dropdownSheet.Hidden = eWorkSheetHidden.Hidden;
var sysDictTypeService = App.GetService<SysDictTypeService>();
foreach (var prop in typeof(T).GetProperties()) foreach (var prop in typeof(T).GetProperties())
{ {
var propType = prop.PropertyType; var propType = prop.PropertyType;
@ -107,10 +112,10 @@ public class ExcelHelper
var dataList = addListValidationFun?.Invoke(worksheet, prop)?.ToList(); var dataList = addListValidationFun?.Invoke(worksheet, prop)?.ToList();
if (dataList == null) if (dataList == null)
{ {
// 填充枚举项为下列列表
if (propType.IsEnum()) if (propType.IsEnum())
{ {
// 填充枚举项为下列列表 dataList = propType.EnumToList()?.Select(it => it.Describe).ToList();
dataList = propType.EnumToList()?.Select(u => u.Describe).ToList();
} }
else else
{ {
@ -119,25 +124,29 @@ public class ExcelHelper
if (dict != null) if (dict != null)
{ {
// 填充字典值value为下列列表 // 填充字典值value为下列列表
dataList = App.GetService<SysDictTypeService>().GetDataList(new GetDataDictTypeInput dataList = sysDictTypeService.GetDataList(new GetDataDictTypeInput { Code = dict.DictTypeCode }).Result?.Select(u => u.Value).ToList();
{ Code = dict.DictTypeCode }).Result?.Select(u => u.Value).ToList();
} }
} }
} }
if (dataList != null) AddListValidation(columnIndex, dataList);
}
void AddListValidation(int columnIndex, List<string> dataList) if (dataList != null)
{ {
var validation = worksheet.DataValidations.AddListValidation(worksheet.Cells[2, columnIndex, 99999, columnIndex].Address); AddListValidation(columnIndex, dataList);
dataList.ForEach(e => validation!.Formula.Values.Add(e)); dropdownSheet.Cells[1, columnIndex, dataList.Count, columnIndex].LoadFromCollection(dataList);
validation.ShowErrorMessage = true; }
validation.ErrorTitle = "无效输入";
validation.Error = "请从列表中选择一个有效的选项";
} }
package.Save(); package.Save();
package.Stream.Position = 0; package.Stream.Position = 0;
return new XlsxFileResult(stream: package.Stream, fileDownloadName: $"{filename}-{DateTime.Now:yyyy-MM-dd_HHmmss}"); return new XlsxFileResult(stream: package.Stream, fileDownloadName: $"{filename}-{DateTime.Now:yyyy-MM-dd_HHmmss}");
void AddListValidation(int columnIndex, List<string> dataList)
{
var validation = worksheet.DataValidations.AddListValidation(worksheet.Cells[2, columnIndex, 999999, columnIndex].Address);
validation!.Formula.ExcelFormula = "=下拉数据!" + worksheet.Cells[1, columnIndex, dataList.Count, columnIndex].Address;
validation.ShowErrorMessage = true;
validation.ErrorTitle = "无效输入";
validation.Error = "请从列表中选择一个有效的选项";
}
} }
} }

View File

@ -22,4 +22,9 @@ public class GoViewLoginInput
/// </summary> /// </summary>
[Required(ErrorMessage = "密码不能为空")] [Required(ErrorMessage = "密码不能为空")]
public string Password { get; set; } public string Password { get; set; }
/// <summary>
/// 租户
/// </summary>
public long? TenantId { get; set; }
} }

View File

@ -34,6 +34,9 @@ public class GoViewSysService : IDynamicApiController
[DisplayName("GoView 登录")] [DisplayName("GoView 登录")]
public async Task<GoViewLoginOutput> Login(GoViewLoginInput input) public async Task<GoViewLoginOutput> Login(GoViewLoginInput input)
{ {
// 设置默认租户
input.TenantId ??= SqlSugarConst.DefaultTenantId;
_sysCacheService.Set($"{CacheConst.KeyConfig}{ConfigConst.SysCaptcha}", false); _sysCacheService.Set($"{CacheConst.KeyConfig}{ConfigConst.SysCaptcha}", false);
input.Password = CryptogramUtil.SM2Encrypt(input.Password); input.Password = CryptogramUtil.SM2Encrypt(input.Password);

View File

@ -2,7 +2,7 @@
"name": "admin.net.pro", "name": "admin.net.pro",
"type": "module", "type": "module",
"version": "2.4.33", "version": "2.4.33",
"lastBuildTime": "2025.01.02", "lastBuildTime": "2025.01.03",
"description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架", "description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架",
"author": "zuohuaijun", "author": "zuohuaijun",
"license": "MIT", "license": "MIT",
@ -24,7 +24,7 @@
"@vue-office/docx": "^1.6.2", "@vue-office/docx": "^1.6.2",
"@vue-office/excel": "^1.7.14", "@vue-office/excel": "^1.7.14",
"@vue-office/pdf": "^2.0.9", "@vue-office/pdf": "^2.0.9",
"@vueuse/core": "^12.0.0", "@vueuse/core": "^12.3.0",
"@wangeditor/editor": "^5.1.23", "@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-vue": "^5.1.12", "@wangeditor/editor-for-vue": "^5.1.12",
"animate.css": "^4.1.1", "animate.css": "^4.1.1",
@ -74,11 +74,11 @@
"vue-router": "^4.5.0", "vue-router": "^4.5.0",
"vue-signature-pad": "^3.0.2", "vue-signature-pad": "^3.0.2",
"vue3-tree-org": "^4.2.2", "vue3-tree-org": "^4.2.2",
"vxe-pc-ui": "^4.3.55", "vxe-pc-ui": "^4.3.58",
"vxe-table": "^4.10.0", "vxe-table": "^4.10.0",
"vxe-table-plugin-element": "^4.0.4", "vxe-table-plugin-element": "^4.0.4",
"vxe-table-plugin-export-xlsx": "^4.0.7", "vxe-table-plugin-export-xlsx": "^4.0.7",
"xe-utils": "^3.6.0", "xe-utils": "^3.7.0",
"xlsx-js-style": "^1.2.0" "xlsx-js-style": "^1.2.0"
}, },
"devDependencies": { "devDependencies": {
@ -93,7 +93,7 @@
"@vitejs/plugin-vue": "^5.2.1", "@vitejs/plugin-vue": "^5.2.1",
"@vitejs/plugin-vue-jsx": "^4.1.1", "@vitejs/plugin-vue-jsx": "^4.1.1",
"@vue/compiler-sfc": "^3.5.13", "@vue/compiler-sfc": "^3.5.13",
"code-inspector-plugin": "^0.18.3", "code-inspector-plugin": "^0.19.0",
"eslint": "^9.17.0", "eslint": "^9.17.0",
"eslint-plugin-vue": "^9.32.0", "eslint-plugin-vue": "^9.32.0",
"globals": "^15.14.0", "globals": "^15.14.0",
@ -103,7 +103,7 @@
"sass": "^1.83.0", "sass": "^1.83.0",
"terser": "^5.37.0", "terser": "^5.37.0",
"typescript": "^5.7.2", "typescript": "^5.7.2",
"vite": "^6.0.6", "vite": "^6.0.7",
"vite-plugin-cdn-import": "^1.0.1", "vite-plugin-cdn-import": "^1.0.1",
"vite-plugin-compression2": "^1.3.3", "vite-plugin-compression2": "^1.3.3",
"vite-plugin-vue-setup-extend": "^0.4.0", "vite-plugin-vue-setup-extend": "^0.4.0",

View File

@ -6,12 +6,14 @@
</template> </template>
<script setup lang="ts" name="wngEditor"> <script setup lang="ts" name="wngEditor">
// https://www.wangeditor.com/v5/for-frame.html#vue3
import '@wangeditor/editor/dist/css/style.css';
import { reactive, shallowRef, watch, onBeforeUnmount } from 'vue'; import { reactive, shallowRef, watch, onBeforeUnmount } from 'vue';
import { ElMessage } from 'element-plus';
import { IDomEditor } from '@wangeditor/editor'; import { IDomEditor } from '@wangeditor/editor';
import { Toolbar, Editor } from '@wangeditor/editor-for-vue'; import { Toolbar, Editor } from '@wangeditor/editor-for-vue';
import { ElMessage } from 'element-plus'; // https://www.wangeditor.com/v5/for-frame.html#vue3
import '@wangeditor/editor/dist/css/style.css';
import { getAPI } from '/@/utils/axios-utils'; import { getAPI } from '/@/utils/axios-utils';
import { SysFileApi } from '/@/api-services/api'; import { SysFileApi } from '/@/api-services/api';
@ -46,8 +48,6 @@ const props = defineProps({
// / // /
const emit = defineEmits(['update:getHtml', 'update:getText']); const emit = defineEmits(['update:getHtml', 'update:getText']);
//
const baseUrl = reactive(window.__env__.VITE_API_URL) + '/';
// //
const editorRef = shallowRef(); const editorRef = shallowRef();
@ -58,20 +58,20 @@ const state = reactive({
MENU_CONF: { MENU_CONF: {
uploadImage: { uploadImage: {
fieldName: 'file', fieldName: 'file',
customUpload(file: any, insertFn: any) { customUpload(file: File) {
const uploadFun = async () => { getAPI(SysFileApi)
const rps = await getAPI(SysFileApi).apiSysFileUploadFilesPostForm([file]); .apiSysFileUploadFilePostForm(file)
if (rps.data.type == 'success' && rps.data.result != null) { .then(({ data }) => {
insertFn(baseUrl + rps.data.result[0].url, rps.data.result[0].fileName, baseUrl + rps.data.result[0].url); if (data.type == 'success' && data.result) {
editorRef.value.insertNode({ type: 'image', src: data.result.url, alt: data.result.fileName, href: data.result.url, children: [{ text: '' }] });
} else { } else {
ElMessage.error('上传失败!'); ElMessage.error('上传失败!');
} }
}; });
uploadFun();
}, },
}, },
insertImage: { insertImage: {
checkImage(src: string, alt: string, href: string): boolean | string | undefined { checkImage(src: string): boolean | string | undefined {
if (src.indexOf('http') !== 0) { if (src.indexOf('http') !== 0) {
return '图片网址必须以 http/https 开头'; return '图片网址必须以 http/https 开头';
} }
@ -87,17 +87,20 @@ const state = reactive({
const handleCreated = (editor: IDomEditor) => { const handleCreated = (editor: IDomEditor) => {
editorRef.value = editor; editorRef.value = editor;
}; };
// //
const handleChange = (editor: IDomEditor) => { const handleChange = (editor: IDomEditor) => {
emit('update:getHtml', editor.getHtml()); emit('update:getHtml', editor.getHtml());
emit('update:getText', editor.getText()); emit('update:getText', editor.getText());
}; };
// //
onBeforeUnmount(() => { onBeforeUnmount(() => {
const editor = editorRef.value; const editor = editorRef.value;
if (editor == null) return; if (editor == null) return;
editor.destroy(); editor.destroy();
}); });
// //
// https://gitee.com/lyt-top/vue-next-admin/issues/I4LM7I // https://gitee.com/lyt-top/vue-next-admin/issues/I4LM7I
watch( watch(
@ -111,6 +114,7 @@ watch(
deep: true, deep: true,
} }
); );
// //
watch( watch(
() => props.getHtml, () => props.getHtml,
@ -122,6 +126,7 @@ watch(
} }
); );
</script> </script>
<style lang="less"> <style lang="less">
.editor-container { .editor-container {
overflow-y: hidden; overflow-y: hidden;
@ -131,10 +136,6 @@ watch(
z-index: 10 !important; z-index: 10 !important;
} }
} }
.w-e-text-container {
//
//z-index: 3 !important;
}
.w-e-toolbar { .w-e-toolbar {
// //
flex-wrap: wrap; flex-wrap: wrap;