移动系统liao
2025-06-23 4de81e21e02e4bd30fc60bfd9c2ea9dce02abdb5
增加部分客户逻辑和模型
4个文件已修改
1个文件已删除
6个文件已添加
710 ■■■■■ 已修改文件
Admin.NET/Admin.NET.Application/Configuration/Swagger.json 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/Admin.NET.Core/Service/Auth/SysAuthService.cs 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/FZCTB.NET.API.Application/Auth/AuthService.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/FZCTB.NET.API.Application/FZCTB.NET.API.Application.csproj 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/FZCTB.NET.API.Application/User/CustomerService.cs 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/FZCZTB.NET.SYSService/CustomerSYS/CustomerManager.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/FZCZTB.NET.SYSService/CustomerSYS/CustomerManagerS.cs 339 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/FZCZTB.NET.SYSService/FZCZTB.NET.SYSService.csproj 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/FZCZTB.NET.SYSService/FZCZTSYSServiceConfig.json 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/FZCZTB.NET.SYSService/MSM/SMSConfigMd.cs 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/FZCZTB.NET.SYSService/MSM/ZCSMSService.cs 213 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/Admin.NET.Application/Configuration/Swagger.json
@@ -31,6 +31,13 @@
        "Description": "非政府采购交易平台",
        "Version": "1.0.0",
        "Order": 10000
      },
      {
        "Group": "FZCAPISYS",
        "Title": "前端系统",
        "Description": "非政府采购交易平台",
        "Version": "1.0.0",
        "Order": 10000
      }
    ],
    "DefaultGroupName": "Default", // 默认分组名
Admin.NET/Admin.NET.Core/Service/Auth/SysAuthService.cs
Admin.NET/FZCTB.NET.API.Application/Auth/AuthService.cs
New file
@@ -0,0 +1,18 @@
using Furion.DynamicApiController;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FZCTB.NET.API.Application.Auth
{
    /// <summary>
    /// 鉴权服务
    /// </summary>
    [ApiDescriptionSettings("FZCAPISYS", Order = 149)]
    public class AuthService: IDynamicApiController
    {
    }
}
Admin.NET/FZCTB.NET.API.Application/FZCTB.NET.API.Application.csproj
@@ -10,6 +10,7 @@
    <ProjectReference Include="..\Admin.NET.Application\Admin.NET.Application.csproj" />
    <ProjectReference Include="..\Admin.NET.Core\Admin.NET.Core.csproj" />
    <ProjectReference Include="..\FZCZTB.NET.MD\FZCZTB.NET.MD.csproj" />
    <ProjectReference Include="..\FZCZTB.NET.SYSService\FZCZTB.NET.SYSService.csproj" />
  </ItemGroup>
</Project>
Admin.NET/FZCTB.NET.API.Application/User/CustomerService.cs
New file
@@ -0,0 +1,47 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Admin.NET.Core.Service;
using Furion.DynamicApiController;
using FZCZTB.NET.MD.CutomerMd;
using FZCZTB.NET.SYSService.CustomerSYS;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FZCTB.NET.API.Application.User;
/// <summary>
/// 客户处里
/// </summary>
public class CustomerService: IDynamicApiController
{
  private  readonly CustomerManagerS _customerManager;
    private readonly SysCacheService _sysCacheService;
    /// <summary>
    ///
    /// </summary>
    public CustomerService(SysCacheService cacheService, CustomerManagerS managerS)
    {
        _sysCacheService= cacheService;
         _customerManager = managerS;
    }
    /// <summary>
    /// 用户注册
    /// </summary>
    /// <returns></returns>
    public async Task<bool>  CustomerRegistration(CustomerDto param )
    {
        //_customerManager.
         await Task.CompletedTask;
        return true;
    }
}
Admin.NET/FZCZTB.NET.SYSService/CustomerSYS/CustomerManager.cs
File was deleted
Admin.NET/FZCZTB.NET.SYSService/CustomerSYS/CustomerManagerS.cs
New file
@@ -0,0 +1,339 @@
using Admin.NET.Core;
using Admin.NET.Core.Service;
using Furion.DependencyInjection;
using FZCZTB.NET.MD.CutomerMd;
using Mapster;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FZCZTB.NET.SYSService.CustomerSYS
{
    /// <summary>
    /// customermanger 服务
    /// </summary>
    public class CustomerManagerS: IScoped
    {
        private readonly SqlSugarRepository<FBS_ExRole> _fBS_ExRoleRep;
        private readonly SqlSugarRepository<FBS_Customer> _fBS_CustomerRep;
        private readonly SysCacheService _sysCacheService;
        public CustomerManagerS(SysCacheService sysCacheService,
            SqlSugarRepository<FBS_ExRole> fBS_ExRoleRep,
            SqlSugarRepository<FBS_Customer> fBS_CustomerRep)
        {
            _sysCacheService = sysCacheService;
            _fBS_ExRoleRep = fBS_ExRoleRep;
            _fBS_CustomerRep = fBS_CustomerRep;
        }
        /// <summary>
        /// 返回当前可用的用户角色 再注册和登录时需要返回编码
        /// </summary>
        /// <returns></returns>
        public async Task< List<ExRoleVM>> GetExRole()
        {
           return await _fBS_ExRoleRep.AsQueryable().Where(x=>x.Status== StatusEnum.Enable)
            .Select<ExRoleVM>().WithCache(20).ToListAsync();
        }
        /// <summary>
        /// 返回当前可用的用户角色 再注册和登录时需要返回编码
        /// </summary>
        /// <returns></returns>
        public async Task<CustomerDto> GetCustomer(int id)
        {
            return (await _fBS_CustomerRep.GetFirstAsync(x => x.Id == id && x.Status == StatusEnum.Enable)).Adapt<CustomerDto>();
        }
        /// <summary>
        /// 返回当前可用的用户角色 再注册和登录时需要返回编码
        /// </summary>
        /// <returns></returns>
        public async Task<CustomerDto> UpDataCustomer(int id)
        {
            return (await _fBS_CustomerRep.GetFirstAsync(x => x.Id == id && x.Status == StatusEnum.Enable)).Adapt<CustomerDto>();
        }
    }
    /// <summary>
    /// 客户主分类角色基础输入参数
    /// </summary>
    public class ExRoleVM
    {
        /// <summary>
        /// 主键Id
        /// </summary>
        public virtual long? Id { get; set; }
        /// <summary>
        /// 名称
        /// </summary>
        [Required(ErrorMessage = "名称不能为空")]
        public virtual string Name { get; set; }
        /// <summary>
        /// 编码
        /// </summary>
        public virtual string? Code { get; set; }
        /// <summary>
        /// 排序
        /// </summary>
        [Required(ErrorMessage = "排序不能为空")]
        public virtual int? OrderNo { get; set; }
        /// <summary>
        /// 数据范围
        /// </summary>
        [Dict(nameof(DataScopeEnum), AllowNullValue = true)]
        [Required(ErrorMessage = "数据范围不能为空")]
        public virtual DataScopeEnum? DataScope { get; set; }
        /// <summary>
        /// 备注
        /// </summary>
        public virtual string? Remark { get; set; }
        /// <summary>
        /// 状态
        /// </summary>
        [Dict(nameof(StatusEnum), AllowNullValue = true)]
        [Required(ErrorMessage = "状态不能为空")]
        public virtual StatusEnum? Status { get; set; }
    }
    /// <summary>
    /// 客户表输出参数
    /// </summary>
    public class CustomerDto
    {
        /// <summary>
        /// 主键Id
        /// </summary>
        public long Id { get; set; }
        /// <summary>
        /// 账号
        /// </summary>
        public string Account { get; set; }
        /// <summary>
        /// 密码
        /// </summary>
        public string Password { get; set; }
        /// <summary>
        /// 真实姓名
        /// </summary>
        public string RealName { get; set; }
        /// <summary>
        /// 昵称
        /// </summary>
        public string? NickName { get; set; }
        /// <summary>
        /// 头像
        /// </summary>
        public string? Avatar { get; set; }
        /// <summary>
        /// 性别
        /// </summary>
        public GenderEnum Sex { get; set; }
        /// <summary>
        /// 年龄
        /// </summary>
        public int Age { get; set; }
        /// <summary>
        /// 出生日期
        /// </summary>
        public DateTime? Birthday { get; set; }
        /// <summary>
        /// 民族
        /// </summary>
        public string? Nation { get; set; }
        /// <summary>
        /// 手机号码
        /// </summary>
        public string? Phone { get; set; }
        /// <summary>
        /// 证件类型
        /// </summary>
        public CardTypeEnum CardType { get; set; }
        /// <summary>
        /// 身份证号
        /// </summary>
        public string? IdCardNum { get; set; }
        /// <summary>
        /// 身份证
        /// </summary>
        public string? IdCardPath { get; set; }
        /// <summary>
        /// 邮箱
        /// </summary>
        public string? Email { get; set; }
        /// <summary>
        /// 地址
        /// </summary>
        public string? Address { get; set; }
        /// <summary>
        /// 文化程度
        /// </summary>
        public CultureLevelEnum CultureLevel { get; set; }
        /// <summary>
        /// 政治面貌
        /// </summary>
        public string? PoliticalOutlook { get; set; }
        /// <summary>
        /// 毕业院校
        /// </summary>
        public string? College { get; set; }
        /// <summary>
        /// 办公电话
        /// </summary>
        public string? OfficePhone { get; set; }
        /// <summary>
        /// 紧急联系人
        /// </summary>
        public string? EmergencyContact { get; set; }
        /// <summary>
        /// 紧急联系人电话
        /// </summary>
        public string? EmergencyPhone { get; set; }
        /// <summary>
        /// 紧急联系人地址
        /// </summary>
        public string? EmergencyAddress { get; set; }
        /// <summary>
        /// 个人简介
        /// </summary>
        public string? Introduction { get; set; }
        /// <summary>
        /// 排序
        /// </summary>
        public int OrderNo { get; set; }
        /// <summary>
        /// 状态
        /// </summary>
        public StatusEnum Status { get; set; }
        /// <summary>
        /// 备注
        /// </summary>
        public string? Remark { get; set; }
        /// <summary>
        /// 职级
        /// </summary>
        public string? PosLevel { get; set; }
        /// <summary>
        /// 职称
        /// </summary>
        public string? PosTitle { get; set; }
        /// <summary>
        /// 擅长领域
        /// </summary>
        public string? Expertise { get; set; }
        /// <summary>
        /// 办公区域
        /// </summary>
        public string? OfficeZone { get; set; }
        /// <summary>
        /// 办公室
        /// </summary>
        public string? Office { get; set; }
        /// <summary>
        /// 入职日期
        /// </summary>
        public DateTime? JoinDate { get; set; }
        /// <summary>
        /// 最新登录Ip
        /// </summary>
        public string? LastLoginIp { get; set; }
        /// <summary>
        /// 最新登录地点
        /// </summary>
        public string? LastLoginAddress { get; set; }
        /// <summary>
        /// 最新登录时间
        /// </summary>
        public DateTime? LastLoginTime { get; set; }
        /// <summary>
        /// 最新登录设备
        /// </summary>
        public string? LastLoginDevice { get; set; }
        /// <summary>
        /// 电子签名
        /// </summary>
        public string? Signature { get; set; }
        /// <summary>
        /// 租户Id
        /// </summary>
        public long? TenantId { get; set; }
        /// <summary>
        /// 注册用户角色
        /// </summary>
        public  string? ExRoleCode {  get; set; }
    }
}
Admin.NET/FZCZTB.NET.SYSService/FZCZTB.NET.SYSService.csproj
@@ -8,6 +8,7 @@
  <ItemGroup>
    <ProjectReference Include="..\Admin.NET.Core\Admin.NET.Core.csproj" />
    <ProjectReference Include="..\FZCZTB.NET.MD\FZCZTB.NET.MD.csproj" />
  </ItemGroup>
</Project>
Admin.NET/FZCZTB.NET.SYSService/FZCZTSYSServiceConfig.json
New file
@@ -0,0 +1,24 @@
{
  "SMSConfigMd": {
    "LingKaiXinxiSets": { //凌凯短信配置
      "Url": "https://mb345.com/ws/BatchSend2.aspx",
      "Number": "XP010534",
      "AccountPassPassword": "123321",
      "VerifyTimeOut": 60,  //秒
      "Templates": [
        {
          "Id": "0",
          "SignName": "【政采咨询网】", //需要加入的公司标签
          "TemplateCode": "VCode",
          "Content": "您的验证码为:${code},请勿泄露于他人!"
        },
        {
          "Id": "1",
          "SignName": "【政采咨询网】",
          "TemplateCode": "RegistrationOK   ",
          "Content": "注册成功,感谢您的注册,请妥善保管您的账户信息"
        }
      ]
    }
  }
}
Admin.NET/FZCZTB.NET.SYSService/MSM/SMSConfigMd.cs
New file
@@ -0,0 +1,48 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Admin.NET.Core;
using Furion.ConfigurableOptions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FZCZTB.NET.SYSService.MSM;
public class SMSConfigOptions : IConfigurableOptions
{
    /// <summary>
    /// 凌凯信息配置
    /// </summary>
    public LingKaiXinxiSets lingKai {  get; set; }
}
public class LingKaiXinxiSets
{
   /// <summary>
   /// d地址
   /// </summary>
    public string Url { get; set; }
    /// <summary>
    /// 账号
    /// </summary>
    public string Number { get; set; }
    /// <summary>
    /// 密码
    /// </summary>
    public string AccountPassPassword { get; set; }
    /// <summary>
    /// 超时时间
    /// </summary>
    public int VerifyTimeOut {  get; set; }
    /// <summary>
    /// Templates
    /// </summary>
    public List<SmsTemplate> Templates { get; set; }
}
Admin.NET/FZCZTB.NET.SYSService/MSM/ZCSMSService.cs
New file
@@ -0,0 +1,213 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Admin.NET.Core.Service;
using Admin.NET.Core;
using Furion.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using Dm.util;
using Aop.Api.Domain;
using Furion.FriendlyException;
using Furion.DataValidation;
using static QRCoder.PayloadGenerator;
using System.Net;
using Org.BouncyCastle.Asn1.Ocsp;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using Furion.DynamicApiController;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using Yitter.IdGenerator;
using Lazy.Captcha.Core;
using Furion;
namespace FZCZTB.NET.SYSService.MSM;
/// <summary>
/// 政采短信服务
/// </summary>
[AllowAnonymous]
[ApiDescriptionSettings("FZCAPISYS",Order = 149)]
public class ZCSMSService : IDynamicApiController,ITransient
{
    private readonly SMSConfigOptions _smsOptions;
    private readonly SysCacheService _sysCacheService;
    private readonly ICaptcha _captcha;
    public ZCSMSService(IOptions<SMSConfigOptions> smsOptions,
          SysCacheService sysCacheService,
          ICaptcha captcha
          )
    {
        _smsOptions = smsOptions.Value;
        _sysCacheService = _sysCacheService;
         _captcha = captcha;
    }
    /// <summary>
    /// 根据藏用模版格式化短信内容 会自动贴上标签
    /// </summary>
    /// <param name="Code"> 需要替换的内容,用于替换末班内容的code部分</param>
    /// <param name="Key"></param>
    [NonAction]
    public string FormartMessage(string? Code, string Key = "VCode")
    {
     var Temp=     _smsOptions.lingKai.Templates.Where(x => x.TemplateCode == Key).FirstOrDefault();
        if ( Temp != null )
        {
            if(Code != null)
            {
                    return Temp.Content.replace("${code}", Code) + Temp.SignName;
            }
            else
                return Temp.Content+Temp.SignName;
        }
        if (Code == null)
            Oops.Oh("短信内容为空");
        return Code;
    }
    /// <summary>
    /// 发送短信
    /// </summary>
    /// <param name="Content">要替换的内容</param>
    [NonAction]
    public async Task SendSMSAsync(string Content,string Phone)
    {
        if (!Phone.TryValidate(ValidationTypes.PhoneNumber).IsValid) throw Oops.Oh("请正确填写手机号码");
       if( string.IsNullOrEmpty(Content)) throw Oops.Oh("请填写正确的手机号码");
        string postdata1 = "CorpID=" + _smsOptions.lingKai.Number + "&Pwd=" + _smsOptions.lingKai.AccountPassPassword + "&Mobile=" + Phone + "&Content="+ Content + "&SendTime=";
        string code = (string)await HttpPost(_smsOptions.lingKai.Url, postdata1);
        var data = Convert.ToInt64(code);
        if (data > 0)
        {
             return ;
        }
        Oops.Oh($"发送短信失败,错误码{data}");
    }
    /// <summary>
    /// 获取验证码 🔖
    /// </summary>
    /// <returns></returns>
    [AllowAnonymous]
    [SuppressMonitor]
    [DisplayName("获取验证码")]
    public dynamic GetCaptcha()
    {
        var codeId = YitIdHelper.NextId().ToString();
        var captcha = _captcha.Generate(codeId);
        var expirySeconds = App.GetOptions<CaptchaOptions>()?.ExpirySeconds ?? 60;
        return new { Id = codeId, Img = captcha.Base64, ExpirySeconds = expirySeconds };
    }
    /// <summary>
    /// 校验短信验证码
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [AllowAnonymous]
    [DisplayName("校验短信验证码")]
    public bool VerifyCode(SmsVerifyCodeInput input)
    {
        var verifyCode = _sysCacheService.Get<string>($"{CacheConst.KeyPhoneVerCode}{input.Phone}");
        if (string.IsNullOrWhiteSpace(verifyCode)) throw Oops.Oh("验证码不存在或已失效,请重新获取!");
        if (verifyCode != input.Code) throw Oops.Oh("验证码错误!");
        return true;
    }
    /// <summary>
    /// 发送验证短信,要要验证码 需要输入校验,避免电脑攻击
    /// </summary>
    /// <param name="phoneNumber"> 电话号码</param>
    /// <param name="VerifyCode">图片校验数据</param>
    ///   <param name="VerifyCodeId">检验的ID</param>
    /// <returns></returns>
    [AllowAnonymous]
    [DisplayName("发送验证码")]
    public async Task SendSMS([Required] string phoneNumber , [Required] string  VerifyCode, [Required] string  VerifyCodeId)
    {
        if (!phoneNumber.TryValidate(ValidationTypes.PhoneNumber).IsValid) throw Oops.Oh("请正确填写手机号码");
        // 校验验证码
        if (!_captcha.Validate(VerifyCodeId, VerifyCode)) throw Oops.Oh(ErrorCodeEnum.D0008);
        _captcha.Generate(VerifyCodeId);
        // 生成随机验证码
        var random = new Random();
        var verifyCode = random.Next(100000, 999999);
        var templateParam = new
        {
            code = verifyCode
        };
       var code=   FormartMessage(verifyCode.toString());
        await SendSMSAsync(code, phoneNumber);
        _sysCacheService.Set($"{CacheConst.KeyPhoneVerCode}{phoneNumber}", verifyCode, TimeSpan.FromSeconds(_smsOptions.lingKai.VerifyTimeOut));
        await Task.CompletedTask;
    }
    /// <summary>
    /// 发送验证码
    /// </summary>
    /// <param name="Url"> 链接</param>
    /// <param name="postDataStr"> 验证码</param>
    /// <returns></returns>
    private  async Task<string> HttpPost(string Url, string postDataStr)
    {
        //HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
        //request.Method = "POST";
        //request.ContentType = "application/x-www-form-urlencoded;charset=gb2312";
        //byte[] postData = Encoding.GetEncoding("gb2312").GetBytes(postDataStr);
        //request.ContentLength = postData.Length;
        //Stream myRequestStream = request.GetRequestStream();
        //myRequestStream.Write(postData, 0, postData.Length);
        //myRequestStream.Close();
        //HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();
        //Stream myResponseStream = response.GetResponseStream();
        //StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("gb2312"));
        //string retString = myStreamReader.ReadToEnd();
        //myStreamReader.Close();
        //myResponseStream.Close();
        //return retString;
        // 创建 HttpClient 实例
        using var httpClient = new HttpClient();
        // 准备要发送的内容,设置编码和内容类型
        var content = new StringContent(postDataStr, Encoding.GetEncoding("gb2312"), "application/x-www-form-urlencoded");
        // 发送 POST 请求
        var response = await httpClient.PostAsync(Url, content);
        // 确保请求成功,若失败则抛出异常
        response.EnsureSuccessStatusCode();
        // 读取响应内容
        return await response.Content.ReadAsStringAsync();
    }
}