sunpengfei
2025-08-08 345de08ba60e93aa448083cf70ccccbd4cfdd0e3
pref:优化
4个文件已添加
10个文件已修改
330 ■■■■■ 已修改文件
FlexJobApi.Core/Enums/Common/EnumErrorCodeType.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Core/FlexJobApi.Core.xml 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Core/FlexJobApiCoreStartup.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Core/Models/FlexJobServer/Tasks/Queries/GetTaskInfosQuery.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Core/Models/UserServer/Auths/Commands/BindPhoneNumberCommand.cs 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Core/Models/UserServer/Auths/Commands/SmsLoginCommand.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Core/Models/UserServer/Auths/Commands/WxmpLoginCommand.cs 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Core/Utils/WxmpUtils/WxmpOptions.cs 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Core/Utils/WxmpUtils/WxmpSnsJscode2sessionCallback.cs 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Core/Utils/WxmpUtils/WxmpUtils.cs 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.FlexJobServer.Application/Tasks/Queries/TaskInfoQueryHandler.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.UserServer.Application/Auths/Commands/LoginCommandHandler.cs 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.UserServer.Application/FlexJobApi.UserServer.Application.xml 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Web.Entry/appsettings.json 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Core/Enums/Common/EnumErrorCodeType.cs
@@ -16,6 +16,11 @@
        [ErrorCodeItemMetadata("{0}")]
        s400 = 400,
        /// <summary>
        /// 当前登录用户已失效
        /// </summary>
        [ErrorCodeItemMetadata("当前登录用户已失效")]
        s401 = 401,
        /// <summary>
        /// {0}不存在
        /// </summary>
        [ErrorCodeItemMetadata("{0}不存在")]
FlexJobApi.Core/FlexJobApi.Core.xml
@@ -1749,6 +1749,11 @@
            参数错误
            </summary>
        </member>
        <member name="F:FlexJobApi.Core.EnumErrorCodeType.s401">
            <summary>
            当前登录用户已失效
            </summary>
        </member>
        <member name="F:FlexJobApi.Core.EnumErrorCodeType.s404">
            <summary>
            {0}不存在
@@ -3355,27 +3360,27 @@
            推荐状态
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.GetTaskInfosQueryResult.Count">
        <member name="P:FlexJobApi.Core.GetTaskInfosQueryResult.ObjectData">
            <summary>
            统计
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.GetTaskInfosQueryResultCount.WaitAssignCount">
        <member name="P:FlexJobApi.Core.GetTaskInfosQueryResultObjectData.WaitAssignCount">
            <summary>
            待安排数量
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.GetTaskInfosQueryResultCount.CompletedAssignCount">
        <member name="P:FlexJobApi.Core.GetTaskInfosQueryResultObjectData.CompletedAssignCount">
            <summary>
            已安排数量
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.GetTaskInfosQueryResultCount.InProcessReleaseCount">
        <member name="P:FlexJobApi.Core.GetTaskInfosQueryResultObjectData.InProcessReleaseCount">
            <summary>
            发布中数量
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.GetTaskInfosQueryResultCount.StoppedReleaseCount">
        <member name="P:FlexJobApi.Core.GetTaskInfosQueryResultObjectData.StoppedReleaseCount">
            <summary>
            已停止数量
            </summary>
@@ -3529,6 +3534,21 @@
            <param name="logier"></param>
            <returns></returns>
        </member>
        <member name="T:FlexJobApi.Core.BindPhoneNumberCommand">
            <summary>
            绑定手机号
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.BindPhoneNumberCommand.PhoneNumber">
            <summary>
            手机号码
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.BindPhoneNumberCommand.VerifyCode">
            <summary>
            验证码
            </summary>
        </member>
        <member name="T:FlexJobApi.Core.PasswordLoginCommand">
            <summary>
            密码登录
@@ -3612,6 +3632,11 @@
        <member name="P:FlexJobApi.Core.WxmpLoginCommand.Code">
            <summary>
            用户登录凭证
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.WxmpLoginCommand.Type">
            <summary>
            用户类型
            </summary>
        </member>
        <member name="T:FlexJobApi.Core.GetAliyunOSSAcsQuery">
@@ -6257,6 +6282,31 @@
            <param name="singularName"></param>
            <returns></returns>
        </member>
        <member name="T:FlexJobApi.Core.WxmpOptions">
            <summary>
            微信小程序配置
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.WxmpOptionsItem.Code">
            <summary>
            编号
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.WxmpOptionsItem.AppId">
            <summary>
            小程序ID
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.WxmpOptionsItem.AppSecret">
            <summary>
            小程序密钥
            </summary>
        </member>
        <member name="T:FlexJobApi.Core.WxmpUtils">
            <summary>
            微信小程序工具
            </summary>
        </member>
        <member name="T:FlexJobApi.Core.XmlDoc">
            <summary>
            注释文档
FlexJobApi.Core/FlexJobApiCoreStartup.cs
@@ -52,6 +52,7 @@
            services.AddHttpRemote();
            services.AddSingleton<ResourceHttpUtils>();
            services.AddSingleton<AliyunSmsUtils>();
            services.AddSingleton<WxmpUtils>();
            services.AddScoped<SmsUtils>();
            services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblies(App.Assemblies.ToArray()));
FlexJobApi.Core/Models/FlexJobServer/Tasks/Queries/GetTaskInfosQuery.cs
@@ -79,10 +79,10 @@
        /// <summary>
        /// 统计
        /// </summary>
        public GetTaskInfosQueryResultCount Count { get; set; }
        public GetTaskInfosQueryResultObjectData ObjectData { get; set; }
    }
    public class GetTaskInfosQueryResultCount
    public class GetTaskInfosQueryResultObjectData
    {
        /// <summary>
        /// 待安排数量
FlexJobApi.Core/Models/UserServer/Auths/Commands/BindPhoneNumberCommand.cs
New file
@@ -0,0 +1,26 @@
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlexJobApi.Core
{
    /// <summary>
    /// 绑定手机号
    /// </summary>
    [Resource([EnumResourceController.Auth])]
    public class BindPhoneNumberCommand : IRequest<bool>
    {
        /// <summary>
        /// 手机号码
        /// </summary>
        public string PhoneNumber { get; set; }
        /// <summary>
        /// 验证码
        /// </summary>
        public string VerifyCode { get; set; }
    }
}
FlexJobApi.Core/Models/UserServer/Auths/Commands/SmsLoginCommand.cs
@@ -17,13 +17,11 @@
        /// <summary>
        /// 手机号码
        /// </summary>
        [Required]
        public string PhoneNumber { get; set; }
        /// <summary>
        /// 验证码
        /// </summary>
        [Required]
        public string VerifyCode { get; set; }
        /// <summary>
FlexJobApi.Core/Models/UserServer/Auths/Commands/WxmpLoginCommand.cs
@@ -1,4 +1,5 @@
using System;
using MediatR;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
@@ -10,12 +11,18 @@
    /// <summary>
    /// 微信小程序登录
    /// </summary>
    public class WxmpLoginCommand
    [Resource([EnumResourceController.Auth], AllowAnonymous = true)]
    public class WxmpLoginCommand : IRequest<LoginCommandCallback>
    {
        /// <summary>
        /// 用户登录凭证
        /// </summary>
        [Required]
        public string Code { get; set; }
        /// <summary>
        /// 用户类型
        /// </summary>
        public EnumUserType Type { get; set; }
    }
}
FlexJobApi.Core/Utils/WxmpUtils/WxmpOptions.cs
New file
@@ -0,0 +1,40 @@
using Furion.ConfigurableOptions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlexJobApi.Core
{
    /// <summary>
    /// 微信小程序配置
    /// </summary>
    public class WxmpOptions : IConfigurableOptions
    {
        public WxmpOptions()
        {
            Items = [];
        }
        public List<WxmpOptionsItem> Items { get; set; }
    }
    public class WxmpOptionsItem
    {
        /// <summary>
        /// 编号
        /// </summary>
        public string Code { get; set; }
        /// <summary>
        /// 小程序ID
        /// </summary>
        public string AppId { get; set; }
        /// <summary>
        /// 小程序密钥
        /// </summary>
        public string AppSecret { get; set; }
    }
}
FlexJobApi.Core/Utils/WxmpUtils/WxmpSnsJscode2sessionCallback.cs
New file
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlexJobApi.Core
{
    public class WxmpSnsJscode2sessionCallback
    {
        public string session_key { get; set; }
        public string unionid { get; set; }
        public string errmsg { get; set; }
        public string openid { get; set; }
        public int errcode { get; set; }
    }
}
FlexJobApi.Core/Utils/WxmpUtils/WxmpUtils.cs
New file
@@ -0,0 +1,49 @@
using Furion.FriendlyException;
using Furion.HttpRemote;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace FlexJobApi.Core
{
    /// <summary>
    /// 微信小程序工具
    /// </summary>
    public class WxmpUtils
    {
        private readonly IOptions<WxmpOptions> options;
        private readonly IHttpRemoteService httpRemoteService;
        public WxmpUtils(
            IOptions<WxmpOptions> options,
            IHttpRemoteService httpRemoteService)
        {
            this.options = options;
            this.httpRemoteService = httpRemoteService;
        }
        public async Task<WxmpSnsJscode2sessionCallback> SnsJscode2sessionAsync(EnumUserType userType, string code, CancellationToken cancellationToken = default)
        {
            var option = options.Value.Items.FirstOrDefault(it => it.Code == userType.ToString());
            if (option == null || option.AppId.IsNull() || option.AppSecret.IsNull())
                throw Oops.Oh(EnumErrorCodeType.s400, "登录失败,缺失配置:WxmpOptions");
            if (code.IsNull())
                throw Oops.Oh(EnumErrorCodeType.s400, "请填写WxmpCode");
            var callback = await httpRemoteService.GetAsAsync<WxmpSnsJscode2sessionCallback>("https://api.weixin.qq.com/sns/jscode2session",
                builder => builder.WithQueryParameters(new Dictionary<string, string>
                {
                    { "appid", option.AppId },
                    { "secret", option.AppSecret },
                    { "js_code", code },
                    { "grant_type", "authorization_code" }
                }));
            if (callback == null || callback.errcode != 0)
                throw Oops.Oh(EnumErrorCodeType.s510, $"登录失败:{callback.errmsg},请联系管理员");
            return callback;
        }
    }
}
FlexJobApi.FlexJobServer.Application/Tasks/Queries/TaskInfoQueryHandler.cs
@@ -82,7 +82,7 @@
                q = q.Where(it => it.GenderLimit == request.GenderLimit);
            }
            var count = new GetTaskInfosQueryResultCount
            var count = new GetTaskInfosQueryResultObjectData
            {
                WaitAssignCount = await q.CountAsync(it => it.Status == EnumTaskStatus.Wait),
                CompletedAssignCount = await q.CountAsync(it => it.Status == EnumTaskStatus.Complete),
@@ -141,7 +141,7 @@
                        SettlementStatus = t.SettlementStatus
                    };
            var result = await request.PageModel.GetPagedListAsync<GetTaskInfosQueryResult, GetTaskInfosQueryResultItem>(s, cancellationToken);
            result.Count = count;
            result.ObjectData = count;
            return result;
        }
    }
FlexJobApi.UserServer.Application/Auths/Commands/LoginCommandHandler.cs
@@ -19,12 +19,16 @@
    /// </summary>
    public class LoginCommandHandler(
        IRepository<User> rep,
        SmsUtils smsUtils) :
        SmsUtils smsUtils,
        WxmpUtils wxmpUtils) :
        IRequestHandler<PasswordLoginCommand, LoginCommandCallback>,
        IRequestHandler<SmsLoginCommand, LoginCommandCallback>
        IRequestHandler<SmsLoginCommand, LoginCommandCallback>,
        IRequestHandler<WxmpLoginCommand, LoginCommandCallback>,
        IRequestHandler<BindPhoneNumberCommand, bool>
    {
        private readonly IRepository<User> rep = rep;
        private readonly SmsUtils smsUtils = smsUtils;
        private readonly WxmpUtils wxmpUtils = wxmpUtils;
        /// <summary>
        /// 密码登录
@@ -62,6 +66,19 @@
            var user = await rep.AsQueryable().AsNoTracking()
                .Where(it => it.UserName == request.PhoneNumber && it.Type == request.Type)
                .FirstOrDefaultAsync(cancellationToken);
            if (user == null && request.Type == EnumUserType.Personal)
            {
                user = new User
                {
                    Type = request.Type,
                    UserName = request.PhoneNumber,
                    PhoneNumber = request.PhoneNumber,
                    IsCheckPhoneNumber = true,
                    Level = 1,
                    Status = EnumUserStatus.Normal
                };
                await rep.InsertAsync(user);
            }
            if (user == null)
                throw Oops.Oh(EnumUserErrorCodeType.u1000);
            if (user.Status == EnumUserStatus.Disabled)
@@ -70,6 +87,62 @@
        }
        /// <summary>
        /// 微信小程序登录
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<LoginCommandCallback> Handle(WxmpLoginCommand request, CancellationToken cancellationToken)
        {
            var snsJscode2session = await wxmpUtils.SnsJscode2sessionAsync(request.Type, request.Code, cancellationToken);
            var user = await rep.AsQueryable().AsNoTracking()
                .Where(it => it.WxmpOpenId == snsJscode2session.openid && it.Type == request.Type)
                .FirstOrDefaultAsync(cancellationToken);
            if (user == null && request.Type == EnumUserType.Personal)
            {
                user = new User
                {
                    Type = request.Type,
                    UserName = snsJscode2session.openid,
                    WxmpOpenId = snsJscode2session.openid,
                    Level = 1,
                    Status = EnumUserStatus.Normal
                };
                await rep.InsertAsync(user);
            }
            if (user == null)
                throw Oops.Oh(EnumUserErrorCodeType.u1000);
            if (user.Status == EnumUserStatus.Disabled)
                throw Oops.Oh(EnumUserErrorCodeType.u1001);
            return GetCurrentLogier(user, EnumClientType.Wxmp);
        }
        /// <summary>
        /// 绑定手机号
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<bool> Handle(BindPhoneNumberCommand request, CancellationToken cancellationToken)
        {
            await smsUtils.CheckVerifyCode(new CheckVerifyCodeModel
            {
                PhoneNumber = request.PhoneNumber,
                VerifyCode = request.VerifyCode,
                TemplateCode = EnumSmsTemplateCode.LoginOrRegister
            });
            var logier = JwtUtils.GetCurrentLogier();
            var user = await rep.AsQueryable()
                .FirstOrDefaultAsync(it => it.Id == logier.Id);
            if (user == null)
                throw Oops.Oh(EnumErrorCodeType.s404, "当前账号不存在");
            user.UserName = request.PhoneNumber;
            user.PhoneNumber = request.PhoneNumber;
            user.IsCheckPhoneNumber = true;
            return true;
        }
        /// <summary>
        /// 获取当前登录用户
        /// </summary>
        /// <param name="user"></param>
FlexJobApi.UserServer.Application/FlexJobApi.UserServer.Application.xml
@@ -9,7 +9,7 @@
            登录命令处理器
            </summary>
        </member>
        <member name="M:FlexJobApi.UserServer.Application.LoginCommandHandler.#ctor(Furion.DatabaseAccessor.IRepository{FlexJobApi.Core.User},FlexJobApi.Core.SmsUtils)">
        <member name="M:FlexJobApi.UserServer.Application.LoginCommandHandler.#ctor(Furion.DatabaseAccessor.IRepository{FlexJobApi.Core.User},FlexJobApi.Core.SmsUtils,FlexJobApi.Core.WxmpUtils)">
            <summary>
            登录命令处理器
            </summary>
@@ -30,6 +30,22 @@
            <param name="cancellationToken"></param>
            <returns></returns>
        </member>
        <member name="M:FlexJobApi.UserServer.Application.LoginCommandHandler.Handle(FlexJobApi.Core.WxmpLoginCommand,System.Threading.CancellationToken)">
            <summary>
            微信小程序登录
            </summary>
            <param name="request"></param>
            <param name="cancellationToken"></param>
            <returns></returns>
        </member>
        <member name="M:FlexJobApi.UserServer.Application.LoginCommandHandler.Handle(FlexJobApi.Core.BindPhoneNumberCommand,System.Threading.CancellationToken)">
            <summary>
            绑定手机号
            </summary>
            <param name="request"></param>
            <param name="cancellationToken"></param>
            <returns></returns>
        </member>
        <member name="M:FlexJobApi.UserServer.Application.LoginCommandHandler.GetCurrentLogier(FlexJobApi.Core.User,FlexJobApi.Core.EnumClientType)">
            <summary>
            获取当前登录用户
FlexJobApi.Web.Entry/appsettings.json
@@ -16,6 +16,20 @@
    "Access": "Redis",
    "Configuration": "118.178.252.28:5390,password=Bole123!"
  },
  "Wxmp": {
    "Items": [
      {
        "Code": "Personal",
        "AppId": "wxb9e0baf4f87aa0de",
        "AppSecret": "24abded2cd32b677b1f14ea9ec5767f0"
      },
      {
        "Code": "Enterprise",
        "AppId": "wx3669dd12a0915f7d ",
        "AppSecret": "c03a62ad6822f1c925532c34183e7f7f"
      }
    ]
  },
  "Aliyun": {
    "OSS": {
      "AccessKeyId": "LTAI4GAdJ88mUMMFBHHiyDmS",
@@ -31,7 +45,7 @@
    }
  },
  "SMS": {
    "Enable": false,
    "Enable": true,
    "AccessKeyId": "LTAI5tMS7qz1duiyncCqxB8H",
    "AccessSecret": "TEHSXK6f6Njg0v0MSFkrjURofdjuKQ",
    "Version": "2017-05-25",