250716提交
This commit is contained in:
commit
5117cfa4c2
|
|
@ -0,0 +1,5 @@
|
|||
/admin/dist
|
||||
/admin/package-lock.json
|
||||
/netcore/src/JT.Shop.Web.Entry/wwwroot/uploadfile
|
||||
/netcore/src/JT.Shop.Web.Entry/App_Data
|
||||
/.tgitconfig
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
### 门店管理系统
|
||||
|
||||
- 使用EFCORE+Furion+NET7
|
||||
|
||||
- 依赖:redis
|
||||
|
||||
### 数据库
|
||||
|
||||
- mysql
|
||||
|
||||
- 数据库地址:123.249.79.37
|
||||
- 数据库端口号:3306
|
||||
|
||||
### 服务器
|
||||
|
||||
- IP:123.249.79.37
|
||||
-宝塔地址:<https://123.249.79.37:28351/8698ed07>
|
||||
|
||||
### 数据结构更新
|
||||
|
||||
1. 更改 CodeFirst 结构 [更改模型文档](https://learn.microsoft.com/zh-cn/ef/core/modeling/)
|
||||
2. 在程序包管理器控制台默认项目中选择“src\JT.Shop.Database.Migrations”
|
||||
```
|
||||
//添加迁移架构代码
|
||||
Add-Migration 新版本号 -Context DefaultDbContext
|
||||
|
||||
//以下应用适合生产环境的迁移方法
|
||||
|
||||
//方法一:生成一个从指定 from 迁移到指定 to 迁移的 SQL 脚本。警告:潜在的数据丢失方案。
|
||||
Script-Migration 上个版本号 新版本号 -Context DefaultDbContext
|
||||
|
||||
//方法二:幂等 SQL 脚本。此类脚本将在内部检查已经应用哪些迁移(通过迁移历史记录表),并且只应用缺少的迁移。
|
||||
Script-Migration -Idempotent
|
||||
```
|
||||
|
||||
### 目录结构
|
||||
|
||||
|
||||
├── doc 文档
|
||||
└── netcore .NET7项目
|
||||
└── src 源代码
|
||||
├── JT.Shop.Application 业务模块
|
||||
│ ├── JobService 定时任务
|
||||
│ ├── Mapper DTO映射
|
||||
│ └── Service 服务接口
|
||||
│ ├── BaseCommon 基础服务
|
||||
│ │ ├── Http http请求封装接口
|
||||
│ │ ├── QrCode 二维码封装接口
|
||||
│ │ ├── SMS 短信封装接口
|
||||
│ │ └── Upload 文件上传接口
|
||||
│ ├── Business 总部业务服务
|
||||
│ │ ├── BodyType 身体部份管理
|
||||
│ │ ├── Clerk 店员管理
|
||||
│ │ ├── Device 设备管理
|
||||
│ │ │ └── Type 设备类型管理
|
||||
│ │ ├── Member 会员管理
|
||||
│ │ ├── Org 组织管理
|
||||
│ │ ├── OutProduct 出货管理
|
||||
│ │ ├── Pos 职位管理
|
||||
│ │ ├── Product 产品管理
|
||||
│ │ ├── Retailer 分销管理,未使用
|
||||
│ │ ├── Role 角色管理
|
||||
│ │ ├── Serve 服务管理
|
||||
│ │ ├── Shop 门店管理
|
||||
│ │ └── WX 公众号管理
|
||||
│ ├── Mch 门店业务服务
|
||||
│ │ ├── Account 门店账号管理
|
||||
│ │ ├── Body 门店部位管理
|
||||
│ │ ├── Clerk 门店店员管理
|
||||
│ │ ├── Conf 门店配置管理
|
||||
│ │ ├── Device 门店设备管理
|
||||
│ │ ├── Member 门店会员管理
|
||||
│ │ ├── Product 门店产品管理
|
||||
│ │ └── Serve 门店服务管理
|
||||
│ ├── ShopApi 门店H5接口
|
||||
│ │ ├── Device 门店设备管理
|
||||
│ │ ├── MP 门店公众号管理
|
||||
│ │ ├── Member 门店会员管理
|
||||
│ │ ├── Notice 门店通知管理
|
||||
│ │ ├── Report 门店报表管理
|
||||
│ │ ├── Shop 门店管理
|
||||
│ │ └── User 门店用户管理
|
||||
│ ├── System 系统接口服务
|
||||
│ │ ├── App 应用管理
|
||||
│ │ ├── Auth 登录相关管理
|
||||
│ │ ├── Base 通用方法
|
||||
│ │ ├── Cache 缓存管理
|
||||
│ │ ├── Captcha 验证码管理
|
||||
│ │ │ ├── ClickWord
|
||||
│ │ │ └── General
|
||||
│ │ ├── Config 配置管理
|
||||
│ │ ├── Dict 字典管理
|
||||
│ │ ├── Emp 员工管理
|
||||
│ │ ├── Enum 枚举管理
|
||||
│ │ ├── File 文件管理
|
||||
│ │ ├── Forms 表单管理
|
||||
│ │ ├── Hubs 聊天管理
|
||||
│ │ ├── Logger 日志管理
|
||||
│ │ ├── Menu 菜单管理
|
||||
│ │ ├── Message 消息管理
|
||||
│ │ ├── Monitor 监控管理
|
||||
│ │ ├── Notice 通知管理
|
||||
│ │ ├── OnlineUser 在线用户管理
|
||||
│ │ ├── Org 组织管理
|
||||
│ │ ├── Pos 职位管理
|
||||
│ │ ├── Role 角色管理
|
||||
│ │ ├── StepBody 步骤管理
|
||||
│ │ ├── System 系统管理
|
||||
│ │ ├── Timer 定时任务管理
|
||||
│ │ └── User 用户管理
|
||||
│ ├── Test 测试单元
|
||||
│ └── UserApi 门店用户H5接口
|
||||
│ ├── Level 标准等级管理
|
||||
│ ├── Result 测量结果管理
|
||||
│ └── User 账户管理
|
||||
├── JT.Shop.Core 框架核心,引用Nuget包
|
||||
│ ├── Filter 拦截器
|
||||
│ └── Util 辅助类
|
||||
├── JT.Shop.Database.Migrations 数据库迁移
|
||||
│ ├── Migrations 迁移文件
|
||||
│ └── sql sql脚本
|
||||
├── JT.Shop.Domain 领域模型
|
||||
│ ├── Entity 数据库实体
|
||||
│ │ ├── Business 业务层实体
|
||||
│ │ ├── Client 用户层实体
|
||||
│ │ ├── SeedData 种子数据
|
||||
│ │ ├── Shop 门店层实体
|
||||
│ │ └── System 系统层实体
|
||||
│ │ └── WorkflowEntity
|
||||
│ ├── ErrCode 错误码
|
||||
│ ├── Options 选项配置
|
||||
│ └── Properties 配置文件
|
||||
├── JT.Shop.Domain.Shared 常用枚举和常量定义
|
||||
│ ├── Const 常量定义
|
||||
│ ├── Enum 枚举定义
|
||||
│ └── Properties 配置文件
|
||||
├── JT.Shop.EntityFramework.Core EntityFrameworkCore管理
|
||||
│ ├── DbContexts 数据库配置
|
||||
│ ├── Extensions 数据库扩展
|
||||
│ └── Repository 仓储
|
||||
├── JT.Shop.EventBus 事件总线
|
||||
│ └── Service 订阅者
|
||||
│ ├── Logger 日志订阅
|
||||
│ └── Report 统计订阅
|
||||
├── JT.Shop.HealthCheck 健康检查,未使用
|
||||
│ └── Extensions
|
||||
├── JT.Shop.Web.Entry web层
|
||||
│ ├── App_Data 缓存文件
|
||||
│ │ └── SenparcTraceLog
|
||||
│ ├── Controllers 控制器
|
||||
│ ├── Handlers 中间件
|
||||
│ ├── Properties 发布配置
|
||||
│ │ └── PublishProfiles
|
||||
│ ├── Views 视图
|
||||
│ │ ├── Auth 公众号授权相关
|
||||
│ │ ├── Home 首页
|
||||
│ │ ├── Qr 二维码入口相关
|
||||
│ │ └── Shared 共享页面
|
||||
│ └── wwwroot 静态资源
|
||||
│ ├── css
|
||||
│ ├── image
|
||||
│ ├── js
|
||||
│ ├── tpl
|
||||
│ ├── uploadfile
|
||||
│ │ └── images
|
||||
│ │ ├── 20240309
|
||||
│ │ ├── 20240417
|
||||
│ │ └── share
|
||||
│ │ └── 202404
|
||||
│ └── vant
|
||||
└── JT.Shop.WeiXin 微信公众号
|
||||
└── Service 微信公众号服务
|
||||
└── MP 微信公众号服务
|
||||
Binary file not shown.
|
|
@ -0,0 +1,217 @@
|
|||
-- 步骤1开始————————————————
|
||||
-- 结构更新前
|
||||
ALTER TABLE `pc_shopdayreport` ADD COLUMN `UpdateTime` datetime(0) NULL COMMENT '统计时间' AFTER `SXBodypartsNum`;
|
||||
Update pc_shopdayreport set UpdateTime = CreatedTime where UpdateTime is null;
|
||||
ALTER TABLE `pc_shopregusermonthreport` ADD COLUMN `UpdateTime` datetime(0) NULL COMMENT '统计时间' AFTER `ShopUserWeightAvg`;
|
||||
Update pc_shopregusermonthreport set UpdateTime = CreatedTime where UpdateTime is null;
|
||||
|
||||
TRUNCATE table pc_shopreguser_rank;
|
||||
|
||||
ALTER TABLE `pc_shopreguser_enter` ADD `Date` date NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '统计日期';
|
||||
|
||||
update pc_shopreguser_enter set Date=DATE(CreatedTime);
|
||||
|
||||
ALTER TABLE `pc_shopreguser_bodyresult` ADD `Date` date NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '统计日期';
|
||||
Update `pc_shopreguser_bodyresult` set `Date` =Date(CreatedTime);
|
||||
|
||||
ALTER TABLE `pc_userresult` ADD `RecordDate` date NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '记录日期';
|
||||
Update pc_userresult set RecordDate=Date(RecordTime);
|
||||
-- 步骤1结束————————————————
|
||||
|
||||
-- 步骤2开始————————————————
|
||||
-- 重复执行删除 开始 直至全部Affected rows 为 0 12次
|
||||
delete from pc_shopaccountdayservereport where id in (select id from (select CreatedTime,ServeId,UserId,count(Id) qty,min(id) id from pc_shopaccountdayservereport group by CreatedTime,ServeId,UserId) t where t.qty>1);
|
||||
|
||||
delete from pc_shopregusersxdata where id in(select t.id from (select d.id from pc_shopregusersxdata d left join pc_shopreguser u on u.id=d.RegUserId where u.ShopId<>d.ShopId or u.id is null) t);
|
||||
|
||||
delete from pc_shopreguserdata where id in(select t.id from( select d.id from pc_shopreguserdata d left join pc_shopreguser u on u.id=d.RegUserId where u.ShopId<>d.ShopId or u.id is null) t);
|
||||
|
||||
|
||||
delete from pc_shopreguser_enter where id in (select id from ( select `Date`, `RegUserId`, `ShopId`,count(*) qty,max(id) id from pc_shopreguser_enter group by `Date`, `RegUserId`, `ShopId`) t where t.qty>1);
|
||||
|
||||
delete from pc_shopreguserdata where id = 17064723041733;
|
||||
|
||||
delete from pc_shopreguser_bodyresult where id IN( select id from (select `Date`, `RegUserId`, `ShopId`,count(*) qty,max(id) id from `pc_shopreguser_bodyresult` group by `Date`, `RegUserId`, `ShopId`) t where t.qty>1);
|
||||
|
||||
|
||||
delete from pc_result where id in(select id from ( select RecordDate,RegUserId,count(*) qty,min(r.id) id from pc_userresult ur join pc_result r on r.id=ur.ResultId group by RecordDate,RegUserId) t where t.qty>1);
|
||||
|
||||
delete from pc_userresult where id in(select id from ( select RecordDate,RegUserId,count(*) qty,min(id) id from pc_userresult group by RecordDate,RegUserId) t where t.qty>1);
|
||||
|
||||
DELETE from pc_shopdayreport t1 WHERE id in ( select id from (select `CreatedTime`, `ShopId`, `BusinessId`,count(*) qty,min(id) id from pc_shopdayreport group by `CreatedTime`, `ShopId`, `BusinessId` having count(*)>1)t);
|
||||
|
||||
delete from pc_shopregusermonthreport where id in(select id from ( select CreatedTime,ShopId,count(*) qty,min(id) id from pc_shopregusermonthreport group by CreatedTime,ShopId) t where t.qty>1);
|
||||
|
||||
delete from pc_shopreguserwx where openid in (select OpenId from ( select `OpenId`,count(*) qty from pc_shopreguserwx group by `OpenId`) t where t.qty>1);
|
||||
delete from pc_shopreguserwx where RegUserId in (select RegUserId from ( select RegUserId,count(*) qty from pc_shopreguserwx group by RegUserId) t where t.qty>1);
|
||||
|
||||
DELETE FROM pc_shopreguser WHERE ID IN(
|
||||
SELECT ID FROM( SELECT ID FROM pc_shopreguser WHERE SHOPID ='17000843870917' AND (PHONE='15592630916' OR PHONE='18391767793' OR PHONE='13609275138')
|
||||
AND ( LastLoginIp IS NULL OR LastLoginIp='')) AS T );
|
||||
|
||||
delete from pc_shopaccountdayreport where id IN( select id from (select CreatedTime,UserId,count(*) qty,max(id) id from `pc_shopaccountdayreport` group by CreatedTime,UserId) t where t.qty>1);
|
||||
delete from pc_shopreguserwx where id in (select id from (select OpenId,count(*) qty,min(id) id from pc_shopreguserwx group by OpenId having qty>1)t);
|
||||
|
||||
-- 重复执行删除 结束
|
||||
-- 步骤2结束————————————————
|
||||
|
||||
-- 步骤3开始————————————————
|
||||
-- 清理无用数据 开始 直至全部Affected rows 为 0
|
||||
delete from pc_shopserviceresultclerk where id in (select id from (select r.id from pc_shopserviceresultclerk r left join pc_shop_account ru on ru.id=r.userid where ru.id is null )t);
|
||||
delete from pc_shopaccountdayservereport where id in (select id from (select r.id from pc_shopaccountdayservereport r left join pc_shop_account ru on ru.id=r.userid where ru.id is null) t);
|
||||
delete from pc_shopaccountdayservereport where id in (select id from (select r.id from pc_shopaccountdayservereport r left join pc_shopservice s on s.id=r.serveid where s.id is null )t);
|
||||
|
||||
delete from pc_shopaccountdayservereport where id in (select id from ( select r.id from pc_shopaccountdayservereport r left join pc_shopservice s on s.id=r.serveid where s.id is null) t);
|
||||
delete from pc_shopaccountdayservereport where id IN( select id from (select CreatedTime,ServeId,UserId,count(*) qty,max(id) id from `pc_shopaccountdayservereport` group by CreatedTime,ServeId,UserId) t where t.qty>1);
|
||||
-- 清理无用数据 结束
|
||||
-- 步骤3结束————————————————
|
||||
|
||||
-- 步骤4开始————————————————
|
||||
-- 开始使用“工具”-”结构同步...“更新
|
||||
-- 线上测试库 jt_shop_v2_test ——> 本地新建的数据库 直接部署 保证没有错误
|
||||
-- 结构更新后
|
||||
-- 步骤4结束————————————————
|
||||
|
||||
-- 步骤5开始————————————————
|
||||
-- 设置 JT.Shop.Upgrade.Host为启动项目
|
||||
-- 修改 JT.Shop.Upgrade.Host的数据库配置文件
|
||||
-- 打开 http://localhost:5041/api/v2/do
|
||||
-- 步骤5结束————————————————
|
||||
|
||||
-- 步骤6开始————————————————
|
||||
-- $2a$11$pSdA2iZzB0qr0tMELfCTs.OOG35xsmDRxsxyX2zdRMyxPMuEF6ddy
|
||||
update sys_user set `Password` = '$2a$11$pSdA2iZzB0qr0tMELfCTs.OOG35xsmDRxsxyX2zdRMyxPMuEF6ddy',`Phone` = '15037185661' WHERE `Account` = 'superAdmin';
|
||||
|
||||
update pc_shophead_level set ParentId=0,`Level`=0 where HeadId=1;
|
||||
update pc_shophead set ParentHeadId=0 where id=1;
|
||||
|
||||
update sys_menu set AccountIdentity=10 where Application='system' or Application='manage';
|
||||
update sys_menu set AccountIdentity=10 where code like 'sys_%';
|
||||
update pc_shop_account set AdminType=3 where AdminType=0;
|
||||
update pc_shop_account set AdminType=1 where phone='15037185661';
|
||||
update sys_menu set name='平台用户管理' where code='sys_user_mgr';
|
||||
|
||||
|
||||
update pc_shopreguserdata set LastCycleOrderId =IFNULL( (select CycleOrderId from pc_shopregusersxdata d where d.RegUserId= pc_shopreguserdata.RegUserId ),0) where LastCycleOrderId=0 and RType<5;
|
||||
|
||||
update pc_shopreguserdata set ServiceStatus=0 where EXISTS (select * from pc_shopregusersxdata d where d.RegUserId=pc_shopreguserdata.RegUserId and d.CycleOrderId=0 and BodyOrderId=0);
|
||||
update pc_shopreguserdata set ServiceStatus=1 where EXISTS (select * from pc_shopregusersxdata d where d.RegUserId=pc_shopreguserdata.RegUserId and (d.CycleOrderId>0 or BodyOrderId>0));
|
||||
|
||||
update pc_shopreguserdata set FirstWeightTime=( select CreatedTime from pc_shopreguser_sxorder o where o.id=pc_shopreguserdata.LastCycleOrderId ) where FirstWeightTime is null and LastCycleOrderId>0;
|
||||
|
||||
update pc_shopreguserdata set RType=6 where ServiceStatus=0 and RType<>6;
|
||||
|
||||
update pc_shopreguserdata set IsDB=false,DBTime=null where IsDB=true and StandWeight< LastWeight and RType<3 and Date(DBTime)=Date(DealTime);
|
||||
update pc_shopreguserdata set IsDB=false,DBTime=null where IsDB=true and StandWeight< LastWeight and RType<3 and Date(DBTime)=Date(LastEntryTime);
|
||||
update pc_shopreguserdata set IsDB=false,DBTime=null where IsDB=true and StandWeight< MinWeight;
|
||||
|
||||
update pc_shopregusersxdata set SerCnt=(select count(*) from pc_shopreguser_bodyresult r where r.RegUserId=pc_shopregusersxdata.RegUserId);
|
||||
update pc_shop_body_type set Image=CONCAT('/image/body-type/',Image,'.png') where Image not like '%.png';
|
||||
update pc_shopsetting set WXClientType=1; -- 默认门店客户端H5 WXClientType=0代表微信小程序
|
||||
-- 步骤6结束————————————————
|
||||
|
||||
-- 步骤7开始————————————————
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
INSERT INTO `sys_menu`(`Id`, `Pid`, `Pids`, `Name`, `Code`, `Type`, `Icon`, `Router`, `Component`, `Permission`, `Application`, `OpenType`, `Visible`, `Link`, `Redirect`, `Weight`, `Sort`, `Remark`, `Status`, `CreatedTime`, `UpdatedTime`, `CreatedUserId`, `CreatedUserName`, `UpdatedUserId`, `UpdatedUserName`, `IsDeleted`, `AccountIdentity`) VALUES (18803388670277, 0, '[0],', '平台财务', 'sys_finance', 0, 'money-collect', '/sys_finance', 'PageView', '', 'busiapp', 0, 'Y', NULL, NULL, 2, 10, NULL, 1, NULL, NULL, NULL, NULL, NULL, NULL, 0, 10);
|
||||
|
||||
INSERT INTO `sys_menu`(`Id`, `Pid`, `Pids`, `Name`, `Code`, `Type`, `Icon`, `Router`, `Component`, `Permission`, `Application`, `OpenType`, `Visible`, `Link`, `Redirect`, `Weight`, `Sort`, `Remark`, `Status`, `CreatedTime`, `UpdatedTime`, `CreatedUserId`, `CreatedUserName`, `UpdatedUserId`, `UpdatedUserName`, `IsDeleted`, `AccountIdentity`) VALUES (18803415503813, 18803388670277, '[0],[18803388670277],', '点数充值', 'sys_dianshu_recharge', 1, '', '/system/dianshu/recharge', 'system/dianshu/recharge-add', '', 'busiapp', 1, 'Y', NULL, NULL, 2, 100, NULL, 1, NULL, NULL, NULL, NULL, NULL, NULL, 0, 10);
|
||||
|
||||
INSERT INTO `sys_menu`(`Id`, `Pid`, `Pids`, `Name`, `Code`, `Type`, `Icon`, `Router`, `Component`, `Permission`, `Application`, `OpenType`, `Visible`, `Link`, `Redirect`, `Weight`, `Sort`, `Remark`, `Status`, `CreatedTime`, `UpdatedTime`, `CreatedUserId`, `CreatedUserName`, `UpdatedUserId`, `UpdatedUserName`, `IsDeleted`, `AccountIdentity`) VALUES (18803433923909, 18803415503813, '[0],[18803388670277],[18803415503813],', '充值', 'sys_dianshu_recharge_add', 2, '', '', '', 'sys:recharge:add', 'busiapp', 0, 'Y', NULL, NULL, 2, 100, NULL, 1, NULL, NULL, NULL, NULL, NULL, NULL, 0, 10);
|
||||
|
||||
INSERT INTO `sys_menu`(`Id`, `Pid`, `Pids`, `Name`, `Code`, `Type`, `Icon`, `Router`, `Component`, `Permission`, `Application`, `OpenType`, `Visible`, `Link`, `Redirect`, `Weight`, `Sort`, `Remark`, `Status`, `CreatedTime`, `UpdatedTime`, `CreatedUserId`, `CreatedUserName`, `UpdatedUserId`, `UpdatedUserName`, `IsDeleted`, `AccountIdentity`) VALUES (18803445885637, 18803388670277, '[0],[18803388670277],', '点数充值单', 'sys_dianshu_recharge_order', 1, '', '/system/dianshu/recharge-order', 'system/dianshu/recharge-order', '', 'busiapp', 1, 'Y', NULL, NULL, 2, 100, NULL, 1, NULL, NULL, NULL, NULL, NULL, NULL, 0, 10);
|
||||
|
||||
INSERT INTO `sys_menu`(`Id`, `Pid`, `Pids`, `Name`, `Code`, `Type`, `Icon`, `Router`, `Component`, `Permission`, `Application`, `OpenType`, `Visible`, `Link`, `Redirect`, `Weight`, `Sort`, `Remark`, `Status`, `CreatedTime`, `UpdatedTime`, `CreatedUserId`, `CreatedUserName`, `UpdatedUserId`, `UpdatedUserName`, `IsDeleted`, `AccountIdentity`) VALUES (18803469366597, 18803388670277, '[0],[18803388670277],', '目标点数', 'sys_dianshu_target', 1, '', '/system/dianshu/target-list', 'system/dianshu/target-list', '', 'busiapp', 1, 'Y', NULL, NULL, 2, 100, NULL, 1, NULL, NULL, NULL, NULL, NULL, NULL, 0, 10);
|
||||
|
||||
INSERT INTO `sys_menu`(`Id`, `Pid`, `Pids`, `Name`, `Code`, `Type`, `Icon`, `Router`, `Component`, `Permission`, `Application`, `OpenType`, `Visible`, `Link`, `Redirect`, `Weight`, `Sort`, `Remark`, `Status`, `CreatedTime`, `UpdatedTime`, `CreatedUserId`, `CreatedUserName`, `UpdatedUserId`, `UpdatedUserName`, `IsDeleted`, `AccountIdentity`) VALUES (18815692883141, 0, '[0],', '授权版本配置', 'sys_business-version', 0, 'setting', '/sys_business-version', 'PageView', '', 'busiapp', 0, 'Y', NULL, NULL, 2, 10, NULL, 1, NULL, NULL, NULL, NULL, NULL, NULL, 0, 10);
|
||||
|
||||
INSERT INTO `sys_menu`(`Id`, `Pid`, `Pids`, `Name`, `Code`, `Type`, `Icon`, `Router`, `Component`, `Permission`, `Application`, `OpenType`, `Visible`, `Link`, `Redirect`, `Weight`, `Sort`, `Remark`, `Status`, `CreatedTime`, `UpdatedTime`, `CreatedUserId`, `CreatedUserName`, `UpdatedUserId`, `UpdatedUserName`, `IsDeleted`, `AccountIdentity`) VALUES (18815708928197, 18815692883141, '[0],[18815692883141],', '添加配置', 'sys_business-version_add', 2, '', '/system/business-version/add', '', 'sys:systembusinessversion:add', 'busiapp', 0, 'Y', NULL, NULL, 2, 100, NULL, 1, NULL, NULL, NULL, NULL, NULL, NULL, 0, 10);
|
||||
|
||||
INSERT INTO `sys_menu`(`Id`, `Pid`, `Pids`, `Name`, `Code`, `Type`, `Icon`, `Router`, `Component`, `Permission`, `Application`, `OpenType`, `Visible`, `Link`, `Redirect`, `Weight`, `Sort`, `Remark`, `Status`, `CreatedTime`, `UpdatedTime`, `CreatedUserId`, `CreatedUserName`, `UpdatedUserId`, `UpdatedUserName`, `IsDeleted`, `AccountIdentity`) VALUES (18825046730181, 18815692883141, '[0],[18815692883141],', '编辑配置', 'sys_systembusinessversion_edit', 2, '', '', '', 'sys:systembusinessversion:edit', 'busiapp', 0, 'Y', NULL, NULL, 2, 100, NULL, 1, NULL, NULL, NULL, NULL, NULL, NULL, 0, 10);
|
||||
|
||||
INSERT INTO `sys_menu`(`Id`, `Pid`, `Pids`, `Name`, `Code`, `Type`, `Icon`, `Router`, `Component`, `Permission`, `Application`, `OpenType`, `Visible`, `Link`, `Redirect`, `Weight`, `Sort`, `Remark`, `Status`, `CreatedTime`, `UpdatedTime`, `CreatedUserId`, `CreatedUserName`, `UpdatedUserId`, `UpdatedUserName`, `IsDeleted`, `AccountIdentity`) VALUES (18825066889157, 18815692883141, '[0],[18815692883141],', '版本列表', 'sys_systembusinessversion_list', 1, '', '/system/business/version/list', 'system/business/version/list', '', 'busiapp', 1, 'Y', NULL, NULL, 2, 100, NULL, 1, NULL, NULL, NULL, NULL, NULL, NULL, 0, 10);
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
|
||||
INSERT INTO `pc_businessshopservice`(`Id`, `Name`, `ShowName`, `Code`, `SortCode`, `Status`, `Remark`, `IsWeight`, `CreatedTime`, `UpdatedTime`, `CreatedUserId`, `CreatedUserName`, `UpdatedUserId`, `UpdatedUserName`, `IsDeleted`, `BusinessId`, `ShareNameId`, `ComputeTimes`) VALUES (1, '减重', '减重美体师', '', 1, 2, '减重美体师', 1, curdate(), curdate(), NULL, NULL, NULL, NULL, 0, 1, 0, 1);
|
||||
INSERT INTO `pc_businessshopservice`(`Id`, `Name`, `ShowName`, `Code`, `SortCode`, `Status`, `Remark`, `IsWeight`, `CreatedTime`, `UpdatedTime`, `CreatedUserId`, `CreatedUserName`, `UpdatedUserId`, `UpdatedUserName`, `IsDeleted`, `BusinessId`, `ShareNameId`, `ComputeTimes`) VALUES (2, '腹部', '腹部美体师', '', 2, 2, '腹部美体师', 0, curdate(), curdate(), NULL, NULL, NULL, NULL, 0, 1, 0, 1);
|
||||
INSERT INTO `pc_businessshopservice`(`Id`, `Name`, `ShowName`, `Code`, `SortCode`, `Status`, `Remark`, `IsWeight`, `CreatedTime`, `UpdatedTime`, `CreatedUserId`, `CreatedUserName`, `UpdatedUserId`, `UpdatedUserName`, `IsDeleted`, `BusinessId`, `ShareNameId`, `ComputeTimes`) VALUES (3, '手臂', '手臂美体师', '', 3, 2, '手臂美体师', 0, curdate(), curdate(), NULL, NULL, NULL, NULL, 0, 1, 0, 1);
|
||||
INSERT INTO `pc_businessshopservice`(`Id`, `Name`, `ShowName`, `Code`, `SortCode`, `Status`, `Remark`, `IsWeight`, `CreatedTime`, `UpdatedTime`, `CreatedUserId`, `CreatedUserName`, `UpdatedUserId`, `UpdatedUserName`, `IsDeleted`, `BusinessId`, `ShareNameId`, `ComputeTimes`) VALUES (4, '前大腿', '前大腿美体师', '', 4, 2, '前大腿美体师', 0, curdate(), curdate(), NULL, NULL, NULL, NULL, 0, 1, 0, 1);
|
||||
INSERT INTO `pc_businessshopservice`(`Id`, `Name`, `ShowName`, `Code`, `SortCode`, `Status`, `Remark`, `IsWeight`, `CreatedTime`, `UpdatedTime`, `CreatedUserId`, `CreatedUserName`, `UpdatedUserId`, `UpdatedUserName`, `IsDeleted`, `BusinessId`, `ShareNameId`, `ComputeTimes`) VALUES (5, '后大腿', '后大腿美体师', '', 5, 2, '后大腿美体师', 0, curdate(), curdate(), NULL, NULL, NULL, NULL, 0, 1, 0, 1);
|
||||
INSERT INTO `pc_businessshopservice`(`Id`, `Name`, `ShowName`, `Code`, `SortCode`, `Status`, `Remark`, `IsWeight`, `CreatedTime`, `UpdatedTime`, `CreatedUserId`, `CreatedUserName`, `UpdatedUserId`, `UpdatedUserName`, `IsDeleted`, `BusinessId`, `ShareNameId`, `ComputeTimes`) VALUES (6, '小腿', '小腿美体师', '', 6, 2, '小腿美体师', 0, curdate(), curdate(), NULL, NULL, NULL, NULL, 0, 1, 0, 1);
|
||||
INSERT INTO `pc_businessshopservice`(`Id`, `Name`, `ShowName`, `Code`, `SortCode`, `Status`, `Remark`, `IsWeight`, `CreatedTime`, `UpdatedTime`, `CreatedUserId`, `CreatedUserName`, `UpdatedUserId`, `UpdatedUserName`, `IsDeleted`, `BusinessId`, `ShareNameId`, `ComputeTimes`) VALUES (7, '背部', '背部美体师', '', 7, 2, '背部美体师', 0, curdate(), curdate(), NULL, NULL, NULL, NULL, 0, 1, 0, 2);
|
||||
INSERT INTO `pc_businessshopservice`(`Id`, `Name`, `ShowName`, `Code`, `SortCode`, `Status`, `Remark`, `IsWeight`, `CreatedTime`, `UpdatedTime`, `CreatedUserId`, `CreatedUserName`, `UpdatedUserId`, `UpdatedUserName`, `IsDeleted`, `BusinessId`, `ShareNameId`, `ComputeTimes`) VALUES (8, '臀部', '臀部美体师', '', 8, 2, '臀部美体师', 0, curdate(), curdate(), NULL, NULL, NULL, NULL, 0, 1, 0, 2);
|
||||
INSERT INTO `pc_businessshopservice`(`Id`, `Name`, `ShowName`, `Code`, `SortCode`, `Status`, `Remark`, `IsWeight`, `CreatedTime`, `UpdatedTime`, `CreatedUserId`, `CreatedUserName`, `UpdatedUserId`, `UpdatedUserName`, `IsDeleted`, `BusinessId`, `ShareNameId`, `ComputeTimes`) VALUES (9, '胸部', '胸部美体师', '', 9, 2, '胸部美体师', 0, curdate(), curdate(), NULL, NULL, NULL, NULL, 0, 1, 0, 2);
|
||||
|
||||
INSERT INTO `pc_businessbody`(`Id`, `BodyId`, `BusinessId`) VALUES (1, 142307070910557, 1);
|
||||
INSERT INTO `pc_businessbody`(`Id`, `BodyId`, `BusinessId`) VALUES (2, 142307070910562, 1);
|
||||
INSERT INTO `pc_businessbody`(`Id`, `BodyId`, `BusinessId`) VALUES (3, 142307070910561, 1);
|
||||
INSERT INTO `pc_businessbody`(`Id`, `BodyId`, `BusinessId`) VALUES (4, 142307070910560, 1);
|
||||
INSERT INTO `pc_businessbody`(`Id`, `BodyId`, `BusinessId`) VALUES (5, 142307070910559, 1);
|
||||
INSERT INTO `pc_businessbody`(`Id`, `BodyId`, `BusinessId`) VALUES (6, 142307070910558, 1);
|
||||
INSERT INTO `pc_businessbody`(`Id`, `BodyId`, `BusinessId`) VALUES (7, 142307070910554, 1);
|
||||
INSERT INTO `pc_businessbody`(`Id`, `BodyId`, `BusinessId`) VALUES (8, 142307070910555, 1);
|
||||
INSERT INTO `pc_businessbody`(`Id`, `BodyId`, `BusinessId`) VALUES (9, 142307070910556, 1);
|
||||
INSERT INTO `pc_businessbody`(`Id`, `BodyId`, `BusinessId`) VALUES (10, 16822817362757, 1);
|
||||
INSERT INTO `pc_businessbody`(`Id`, `BodyId`, `BusinessId`) VALUES (11, 16822816142533, 1);
|
||||
INSERT INTO `pc_businessbody`(`Id`, `BodyId`, `BusinessId`) VALUES (12, 16822809742661, 1);
|
||||
-- 步骤7结束————————————————
|
||||
|
||||
-- 步骤8开始————————————————
|
||||
update pc_systembusinessversionconfig set UseTimes = (select count(id) from pc_dianshu_consume where SBV_ConfigId=pc_systembusinessversionconfig.id);
|
||||
update pc_systembusinessversionconfig set UsingCount = (select count(id) from pc_shophead where SystemAuthorization_ConfigId=pc_systembusinessversionconfig.id) where SystemApp=2;
|
||||
update pc_systembusinessversionconfig set UsingCount = (select count(id) from pc_shop where SystemAuthorization_ConfigId=pc_systembusinessversionconfig.id) where SystemApp=1;
|
||||
|
||||
update pc_shopreguserdata set UnIncreaseWeight= LastWeight - StandWeight where LastWeight > StandWeight;
|
||||
update pc_shopreguserdata set UnIncreaseWeight=0 where LastWeight <= StandWeight;
|
||||
--
|
||||
UPDATE `pc_shopaccountdayservereport` SET `BusinessId` = (select BusinessId from `pc_shopservice` s where s.id=`pc_shopaccountdayservereport`.ServeId);
|
||||
UPDATE `pc_shopaccountdayservereport` SET `ShopId` = (select ShopId from `pc_shopservice` s where s.id=`pc_shopaccountdayservereport`.ServeId);
|
||||
|
||||
UPDATE `pc_shopservice` SET `ComputeTimes` = 1;
|
||||
update `pc_shopservice` set `ComputeTimes`=1,IsWeight=1 where name like '减重%';
|
||||
update `pc_shopservice` set `ComputeTimes`=1,IsWeight=0 where name like '%腹部%' or name like '%手臂%' or name like '%胯部%' or name like '%大腿%' or name like '%小腿%';
|
||||
update `pc_shopservice` set `ComputeTimes`=2,IsWeight=0 where name like '%背部%' or name like '%臀部%' or name like '%胸部%' or name like '%淋巴排毒%' or name like '%富贵包%';
|
||||
|
||||
UPDATE `pc_businessshopservice` SET `ComputeTimes` = 1;
|
||||
update `pc_businessshopservice` set `ComputeTimes`=1,IsWeight=1 where name like '减重%';
|
||||
update `pc_businessshopservice` set `ComputeTimes`=1,IsWeight=0 where name like '%腹部%' or name like '%手臂%' or name like '%胯部%' or name like '%大腿%' or name like '%小腿%';
|
||||
update `pc_businessshopservice` set `ComputeTimes`=2,IsWeight=0 where name like '%背部%' or name like '%臀部%' or name like '%胸部%' or name like '%淋巴排毒%' or name like '%富贵包%';
|
||||
|
||||
|
||||
INSERT INTO `pc_devicetype`(`Id`, `Name`, `Code`, `Pic`, `Desc`, `ProType`, `BleUrl`, `SupType`, `CreatedTime`, `UpdatedTime`, `CreatedUserId`, `CreatedUserName`, `UpdatedUserId`, `UpdatedUserName`, `IsDeleted`) VALUES (14942660236358, '蓝牙', 2, '', '', 1, 'mini', '', '2025-01-13 00:00:00.000000', NULL, NULL, NULL, NULL, NULL, 0);
|
||||
|
||||
update pc_shopreguserwx set shopid = IFNULL((select shopid from pc_shopreguser u where u.id=pc_shopreguserwx.RegUserId),0) ;
|
||||
update pc_shopreguserwx set AppId='wxfcbb905e3b2b14fb' where AppId is null;
|
||||
delete from pc_shopreguserwx where shopid=0;
|
||||
-- 步骤8结束————————————————
|
||||
|
||||
-- 步骤9开始————————————————
|
||||
-- 耗时脚本 开始
|
||||
update pc_shopaccountdayservereport set Cnt = IFNULL((select count(rc.id)*IFNULL(s.ComputeTimes,1) from pc_shopserviceresultclerk rc join pc_shop_service_result sr on sr.id=rc.ResultId left join pc_shopservice s on s.id=rc.ServeId where rc.UserId=`pc_shopaccountdayservereport`.UserId and rc.ServeId=`pc_shopaccountdayservereport`.ServeId and sr.CreatedTime>=`pc_shopaccountdayservereport`.CreatedTime and sr.CreatedTime<DATE_ADD(`pc_shopaccountdayservereport`.CreatedTime,INTERVAL 1 DAY)),0);
|
||||
|
||||
UPDATE `pc_shopaccountdayreport` SET `ServeCnt` = IFNULL((select sum(ds.Cnt) from pc_shopaccountdayservereport ds join pc_shopservice s on s.id=ds.ServeId where ds.UserId=`pc_shopaccountdayreport`.UserId and ds.CreatedTime=`pc_shopaccountdayreport`.CreatedTime),0);
|
||||
|
||||
UPDATE `pc_shopaccountdayreport` SET `SXBodypartsNum` = IFNULL((select sum(ds.Cnt) from pc_shopaccountdayservereport ds join pc_shopservice s on s.id=ds.ServeId where s.IsWeight=false and ds.UserId=`pc_shopaccountdayreport`.UserId and ds.CreatedTime=`pc_shopaccountdayreport`.CreatedTime),0);
|
||||
|
||||
UPDATE `pc_shopdayreport` set SXBodypartsNum= IFNULL((select sum(IFNULL(SXBodypartsNum,0)) from PC_ShopAccountDayReport dr where dr.ShopId=`pc_shopdayreport`.ShopId and dr.CreatedTime=`pc_shopdayreport`.CreatedTime),0);
|
||||
|
||||
UPDATE `pc_shopregusermonthreport` set NewUserCnt = IFNULL((select Count(1) from pc_shopreguserdata dr where dr.ShopId=`pc_shopregusermonthreport`.ShopId and dr.DealTime>=`pc_shopregusermonthreport`.CreatedTime and dr.DealTime<DATE_ADD(`pc_shopregusermonthreport`.CreatedTime,INTERVAL 1 MONTH)),0);
|
||||
-- 耗时脚本 结束
|
||||
-- 步骤9结束————————————————
|
||||
|
||||
-- 切换到JT.Shop.Web.Entry 修改数据库 然后运行
|
||||
-- https://localhost:7218/api/public/home/RegUserRankCreate?start=2025-01-01&end=2025-04-09 时间为当前时间的前三个月
|
||||
-- 等队列消费完 进行数据同步(如果要合并数据,下面步骤可最后执行
|
||||
-- https://localhost:7218/api/public/home/UpdateShareNames 登录平台端编辑版本功能项 部署自动任务)
|
||||
|
||||
|
||||
--使用Navicat Permium 《工具》->《数据同步》;源(线上新测试数据库) jt_shop_v2_test ,目标 本地jt_shop_v2;
|
||||
-- >(注意)选项中只勾选《插入记录》;
|
||||
-- > 忽略插入表包括(sys_log_ex、sys_role、
|
||||
-- sys_role_menu、sys_user_role、
|
||||
-- pc_businessbody、pc_bussinessshopproduct、
|
||||
-- pc_businessshopservice、pc_share_name)
|
||||
-- > 增加更新表包括(sys_user、pc_shop_body_type)
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 3.3 MiB |
Binary file not shown.
|
|
@ -0,0 +1,25 @@
|
|||
**/.classpath
|
||||
**/.dockerignore
|
||||
**/.env
|
||||
**/.git
|
||||
**/.gitignore
|
||||
**/.project
|
||||
**/.settings
|
||||
**/.toolstarget
|
||||
**/.vs
|
||||
**/.vscode
|
||||
**/*.*proj.user
|
||||
**/*.dbmdl
|
||||
**/*.jfm
|
||||
**/azds.yaml
|
||||
**/bin
|
||||
**/charts
|
||||
**/docker-compose*
|
||||
**/Dockerfile*
|
||||
**/node_modules
|
||||
**/npm-debug.log
|
||||
**/obj
|
||||
**/secrets.dev.yaml
|
||||
**/values.dev.yaml
|
||||
LICENSE
|
||||
README.md
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
# Rules in this file were initially inferred by Visual Studio IntelliCode from the C:\Baiqian\Workplaces\Gitee\Furion\framework codebase based on best match to current usage at 2021-5-16
|
||||
# You can modify the rules from these initially generated values to suit your own policies
|
||||
# You can learn more about editorconfig here: https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference
|
||||
[*.cs]
|
||||
|
||||
|
||||
#Core editorconfig formatting - indentation
|
||||
|
||||
#use soft tabs (spaces) for indentation
|
||||
indent_style = space
|
||||
|
||||
#Formatting - indentation options
|
||||
|
||||
#indent switch case contents.
|
||||
csharp_indent_case_contents = true
|
||||
#labels are placed at one less indent to the current context
|
||||
csharp_indent_labels = one_less_than_current
|
||||
#indent switch labels
|
||||
csharp_indent_switch_labels = true
|
||||
|
||||
#Formatting - new line options
|
||||
|
||||
#place catch statements on a new line
|
||||
csharp_new_line_before_catch = true
|
||||
#place else statements on a new line
|
||||
csharp_new_line_before_else = true
|
||||
#require finally statements to be on a new line after the closing brace
|
||||
csharp_new_line_before_finally = true
|
||||
#require members of object intializers to be on separate lines
|
||||
csharp_new_line_before_members_in_object_initializers = true
|
||||
#require braces to be on a new line for properties, accessors, methods, control_blocks, types, lambdas, and object_collection_array_initializers (also known as "Allman" style)
|
||||
csharp_new_line_before_open_brace = properties, accessors, methods, control_blocks, types, lambdas, object_collection_array_initializers
|
||||
|
||||
#Formatting - organize using options
|
||||
|
||||
#do not place System.* using directives before other using directives
|
||||
dotnet_sort_system_directives_first = false
|
||||
|
||||
#Formatting - spacing options
|
||||
|
||||
#require NO space between a cast and the value
|
||||
csharp_space_after_cast = false
|
||||
#require a space before the colon for bases or interfaces in a type declaration
|
||||
csharp_space_after_colon_in_inheritance_clause = true
|
||||
#require a space after a keyword in a control flow statement such as a for loop
|
||||
csharp_space_after_keywords_in_control_flow_statements = true
|
||||
#require a space before the colon for bases or interfaces in a type declaration
|
||||
csharp_space_before_colon_in_inheritance_clause = true
|
||||
#remove space within empty argument list parentheses
|
||||
csharp_space_between_method_call_empty_parameter_list_parentheses = false
|
||||
#remove space between method call name and opening parenthesis
|
||||
csharp_space_between_method_call_name_and_opening_parenthesis = false
|
||||
#do not place space characters after the opening parenthesis and before the closing parenthesis of a method call
|
||||
csharp_space_between_method_call_parameter_list_parentheses = false
|
||||
#remove space within empty parameter list parentheses for a method declaration
|
||||
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
|
||||
#place a space character after the opening parenthesis and before the closing parenthesis of a method declaration parameter list.
|
||||
csharp_space_between_method_declaration_parameter_list_parentheses = false
|
||||
|
||||
#Formatting - wrapping options
|
||||
|
||||
#leave code block on single line
|
||||
csharp_preserve_single_line_blocks = true
|
||||
#leave statements and member declarations on the same line
|
||||
csharp_preserve_single_line_statements = true
|
||||
|
||||
#Style - Code block preferences
|
||||
|
||||
#prefer no curly braces if allowed
|
||||
csharp_prefer_braces = false:suggestion
|
||||
|
||||
#Style - expression bodied member options
|
||||
|
||||
#prefer block bodies for constructors
|
||||
csharp_style_expression_bodied_constructors = false:suggestion
|
||||
#prefer block bodies for methods
|
||||
csharp_style_expression_bodied_methods = false:suggestion
|
||||
#prefer expression-bodied members for properties
|
||||
csharp_style_expression_bodied_properties = true:suggestion
|
||||
|
||||
#Style - expression level options
|
||||
|
||||
#prefer out variables to be declared inline in the argument list of a method call when possible
|
||||
csharp_style_inlined_variable_declaration = true:suggestion
|
||||
#prefer tuple names to ItemX properties
|
||||
dotnet_style_explicit_tuple_names = true:suggestion
|
||||
#prefer the language keyword for member access expressions, instead of the type name, for types that have a keyword to represent them
|
||||
dotnet_style_predefined_type_for_member_access = true:suggestion
|
||||
|
||||
#Style - Expression-level preferences
|
||||
|
||||
#prefer default over default(T)
|
||||
csharp_prefer_simple_default_expression = true:suggestion
|
||||
#prefer objects to be initialized using object initializers when possible
|
||||
dotnet_style_object_initializer = true:suggestion
|
||||
#prefer inferred tuple element names
|
||||
dotnet_style_prefer_inferred_tuple_names = true:suggestion
|
||||
|
||||
#Style - implicit and explicit types
|
||||
|
||||
#prefer var over explicit type in all cases, unless overridden by another code style rule
|
||||
csharp_style_var_elsewhere = true:suggestion
|
||||
#prefer var is used to declare variables with built-in system types such as int
|
||||
csharp_style_var_for_built_in_types = true:suggestion
|
||||
#prefer var when the type is already mentioned on the right-hand side of a declaration expression
|
||||
csharp_style_var_when_type_is_apparent = true:suggestion
|
||||
|
||||
#Style - language keyword and framework type options
|
||||
|
||||
#prefer the language keyword for local variables, method parameters, and class members, instead of the type name, for types that have a keyword to represent them
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
|
||||
|
||||
#Style - Miscellaneous preferences
|
||||
|
||||
#prefer anonymous functions over local functions
|
||||
csharp_style_pattern_local_over_anonymous_function = false:suggestion
|
||||
|
||||
#Style - Modifier preferences
|
||||
|
||||
#when this rule is set to a list of modifiers, prefer the specified ordering.
|
||||
csharp_preferred_modifier_order = public,private,internal,protected,static,virtual,readonly,async,override,abstract,new:suggestion
|
||||
|
||||
#Style - Pattern matching
|
||||
|
||||
#prefer pattern matching instead of is expression with type casts
|
||||
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
|
||||
|
||||
#Style - qualification options
|
||||
|
||||
#prefer fields not to be prefaced with this. or Me. in Visual Basic
|
||||
dotnet_style_qualification_for_field = false:suggestion
|
||||
#prefer methods not to be prefaced with this. or Me. in Visual Basic
|
||||
dotnet_style_qualification_for_method = false:suggestion
|
||||
#prefer properties not to be prefaced with this. or Me. in Visual Basic
|
||||
dotnet_style_qualification_for_property = false:suggestion
|
||||
|
||||
# Add copyright file header
|
||||
file_header_template = 品传科技\n开发:李鹏鹏\n------------------------------------------------------------------------
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
###############################################################################
|
||||
# Set default behavior to automatically normalize line endings.
|
||||
###############################################################################
|
||||
* text=auto
|
||||
|
||||
###############################################################################
|
||||
# Set default behavior for command prompt diff.
|
||||
#
|
||||
# This is need for earlier builds of msysgit that does not have it on by
|
||||
# default for csharp files.
|
||||
# Note: This is only used by command line
|
||||
###############################################################################
|
||||
#*.cs diff=csharp
|
||||
|
||||
###############################################################################
|
||||
# Set the merge driver for project and solution files
|
||||
#
|
||||
# Merging from the command prompt will add diff markers to the files if there
|
||||
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||
# the diff markers are never inserted). Diff markers may cause the following
|
||||
# file extensions to fail to load in VS. An alternative would be to treat
|
||||
# these files as binary and thus will always conflict and require user
|
||||
# intervention with every merge. To do so, just uncomment the entries below
|
||||
###############################################################################
|
||||
#*.sln merge=binary
|
||||
#*.csproj merge=binary
|
||||
#*.vbproj merge=binary
|
||||
#*.vcxproj merge=binary
|
||||
#*.vcproj merge=binary
|
||||
#*.dbproj merge=binary
|
||||
#*.fsproj merge=binary
|
||||
#*.lsproj merge=binary
|
||||
#*.wixproj merge=binary
|
||||
#*.modelproj merge=binary
|
||||
#*.sqlproj merge=binary
|
||||
#*.wwaproj merge=binary
|
||||
|
||||
###############################################################################
|
||||
# behavior for image files
|
||||
#
|
||||
# image files are treated as binary by default.
|
||||
###############################################################################
|
||||
#*.jpg binary
|
||||
#*.png binary
|
||||
#*.gif binary
|
||||
|
||||
###############################################################################
|
||||
# diff behavior for common document formats
|
||||
#
|
||||
# Convert binary document formats to text before diffing them. This feature
|
||||
# is only available from the command line. Turn it on by uncommenting the
|
||||
# entries below.
|
||||
###############################################################################
|
||||
#*.doc diff=astextplain
|
||||
#*.DOC diff=astextplain
|
||||
#*.docx diff=astextplain
|
||||
#*.DOCX diff=astextplain
|
||||
#*.dot diff=astextplain
|
||||
#*.DOT diff=astextplain
|
||||
#*.pdf diff=astextplain
|
||||
#*.PDF diff=astextplain
|
||||
#*.rtf diff=astextplain
|
||||
#*.RTF diff=astextplain
|
||||
|
|
@ -0,0 +1,363 @@
|
|||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Oo]ut/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
@ECHO OFF
|
||||
for /f "tokens=*" %%a in ('dir obj /b /ad /s ^|sort') do rd "%%a" /s/q
|
||||
for /f "tokens=*" %%a in ('dir bin /b /ad /s ^|sort') do rd "%%a" /s/q
|
||||
echo print obj和bin清理完成
|
||||
pause
|
||||
|
|
@ -0,0 +1,228 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageVersion Include="AlibabaCloud.SDK.Dysmsapi20170525" Version="2.0.24" />
|
||||
<PackageVersion Include="aliyun-net-sdk-sts" Version="3.1.2" />
|
||||
<PackageVersion Include="Aliyun.OSS.SDK.NetCore" Version="2.13.0" />
|
||||
<PackageVersion Include="AsyncKeyedLock" Version="6.3.4" />
|
||||
<PackageVersion Include="Autofac" Version="8.0.0" />
|
||||
<PackageVersion Include="Autofac.Extensions.DependencyInjection" Version="9.0.0" />
|
||||
<PackageVersion Include="Autofac.Extras.DynamicProxy" Version="7.1.0" />
|
||||
<PackageVersion Include="AutoMapper" Version="13.0.1" />
|
||||
<PackageVersion Include="Asp.Versioning.Mvc" Version="8.1.0" />
|
||||
<PackageVersion Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.1.0" />
|
||||
<PackageVersion Include="AWSSDK.S3" Version="3.7.300.2" />
|
||||
<PackageVersion Include="AWSSDK.SecurityToken" Version="3.7.300.2" />
|
||||
<PackageVersion Include="Azure.Messaging.ServiceBus" Version="7.17.0" />
|
||||
<PackageVersion Include="Azure.Storage.Blobs" Version="12.19.1" />
|
||||
<PackageVersion Include="Blazorise" Version="1.5.2" />
|
||||
<PackageVersion Include="Blazorise.Components" Version="1.5.2" />
|
||||
<PackageVersion Include="Blazorise.DataGrid" Version="1.5.2" />
|
||||
<PackageVersion Include="Blazorise.Snackbar" Version="1.5.2" />
|
||||
<PackageVersion Include="Castle.Core" Version="5.1.1" />
|
||||
<PackageVersion Include="Castle.Core.AsyncInterceptor" Version="2.1.0" />
|
||||
<PackageVersion Include="CommonMark.NET" Version="0.15.1" />
|
||||
<PackageVersion Include="Confluent.Kafka" Version="2.3.0" />
|
||||
<PackageVersion Include="Dapper" Version="2.1.21" />
|
||||
<PackageVersion Include="Dapr.AspNetCore" Version="1.12.0" />
|
||||
<PackageVersion Include="Dapr.Client" Version="1.12.0" />
|
||||
<PackageVersion Include="DeviceDetector.NET" Version="6.1.4" />
|
||||
<PackageVersion Include="Devart.Data.Oracle.EFCore" Version="10.3.10.8" />
|
||||
<PackageVersion Include="DistributedLock.Core" Version="1.0.5" />
|
||||
<PackageVersion Include="DistributedLock.Redis" Version="1.0.2" />
|
||||
<PackageVersion Include="DeepL.net" Version="1.8.0" />
|
||||
<PackageVersion Include="EphemeralMongo.Core" Version="1.1.3" />
|
||||
<PackageVersion Include="EphemeralMongo6.runtime.linux-x64" Version="1.1.3" />
|
||||
<PackageVersion Include="EphemeralMongo6.runtime.osx-x64" Version="1.1.3" />
|
||||
<PackageVersion Include="EphemeralMongo6.runtime.win-x64" Version="1.1.3" />
|
||||
<PackageVersion Include="FluentValidation" Version="11.8.0" />
|
||||
<PackageVersion Include="Furion.Extras.Logging.Serilog" Version="4.9.5.17-beta.1" />
|
||||
<PackageVersion Include="Hangfire.AspNetCore" Version="1.8.14" />
|
||||
<PackageVersion Include="Hangfire.SqlServer" Version="1.8.14" />
|
||||
<PackageVersion Include="HtmlSanitizer" Version="8.0.746" />
|
||||
<PackageVersion Include="IdentityModel" Version="6.2.0" />
|
||||
<PackageVersion Include="IdentityServer4" Version="4.1.2" />
|
||||
<PackageVersion Include="IdentityServer4.AspNetIdentity" Version="4.1.2" />
|
||||
<PackageVersion Include="JetBrains.Annotations" Version="2023.3.0" />
|
||||
<PackageVersion Include="LdapForNet" Version="2.7.15" />
|
||||
<PackageVersion Include="LibGit2Sharp" Version="0.28.0" />
|
||||
<PackageVersion Include="Magick.NET-Q16-AnyCPU" Version="13.4.0" />
|
||||
<PackageVersion Include="MailKit" Version="4.7.1.1" />
|
||||
<PackageVersion Include="Markdig.Signed" Version="0.37.0" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.4" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="8.0.4" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Authorization" Version="8.0.4" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components" Version="8.0.4" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.Authorization" Version="8.0.4" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.Web" Version="8.0.4" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.4" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.4" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="8.0.4" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.4" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="8.0.4" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.4" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="8.0.4" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.4" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Razor.Language" Version="6.0.25" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="8.0.4" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.WebUtilities" Version="8.0.4" />
|
||||
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.5.0" />
|
||||
<PackageVersion Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite" Version="8.0.4" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="8.0.4" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.4" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.4" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Proxies" Version="8.0.4" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.4" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.5" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.4" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.5" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.CommandLine" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.FileProviders.Composite" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.FileProviders.Embedded" Version="8.0.4" />
|
||||
<PackageVersion Include="Microsoft.Extensions.FileProviders.Physical" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.FileSystemGlobbing" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Identity.Core" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Localization" Version="8.0.5" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Options" Version="8.0.2" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
|
||||
<PackageVersion Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="1.1.1" />
|
||||
<PackageVersion Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="7.5.1" />
|
||||
<PackageVersion Include="Microsoft.IdentityModel.Tokens" Version="7.5.1" />
|
||||
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="7.5.1" />
|
||||
<PackageVersion Include="Minio" Version="6.0.2" />
|
||||
<PackageVersion Include="MongoDB.Driver" Version="2.22.0" />
|
||||
<PackageVersion Include="Moq" Version="4.20.70" />
|
||||
<PackageVersion Include="NEST" Version="7.17.5" />
|
||||
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageVersion Include="Nito.AsyncEx.Context" Version="5.1.2" />
|
||||
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.2" />
|
||||
<PackageVersion Include="NSubstitute" Version="5.1.0" />
|
||||
<PackageVersion Include="NuGet.Versioning" Version="6.7.0" />
|
||||
<PackageVersion Include="NUglify" Version="1.21.0" />
|
||||
<PackageVersion Include="Nullable" Version="1.3.1" />
|
||||
<PackageVersion Include="Octokit" Version="9.0.0" />
|
||||
<PackageVersion Include="OpenIddict.Abstractions" Version="5.5.0" />
|
||||
<PackageVersion Include="OpenIddict.Core" Version="5.5.0" />
|
||||
<PackageVersion Include="OpenIddict.Server.AspNetCore" Version="5.5.0" />
|
||||
<PackageVersion Include="OpenIddict.Validation.AspNetCore" Version="5.5.0" />
|
||||
<PackageVersion Include="OpenIddict.Validation.ServerIntegration" Version="5.5.0" />
|
||||
<PackageVersion Include="Oracle.EntityFrameworkCore" Version="8.23.40" />
|
||||
<PackageVersion Include="Polly" Version="8.2.0" />
|
||||
<PackageVersion Include="Polly.Extensions.Http" Version="3.0.0" />
|
||||
<PackageVersion Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.2" />
|
||||
<PackageVersion Include="Quartz" Version="3.7.0" />
|
||||
<PackageVersion Include="Quartz.Extensions.DependencyInjection" Version="3.7.0" />
|
||||
<PackageVersion Include="Quartz.Plugins.TimeZoneConverter" Version="3.7.0" />
|
||||
<PackageVersion Include="Quartz.Serialization.Json" Version="3.7.0" />
|
||||
<PackageVersion Include="RabbitMQ.Client" Version="6.6.0" />
|
||||
<PackageVersion Include="Rebus" Version="8.4.2" />
|
||||
<PackageVersion Include="Rebus.ServiceProvider" Version="10.1.2" />
|
||||
<PackageVersion Include="Scriban" Version="5.9.0" />
|
||||
<PackageVersion Include="Serilog" Version="3.1.1" />
|
||||
<PackageVersion Include="Serilog.AspNetCore" Version="8.0.3" />
|
||||
<PackageVersion Include="Serilog.Enrichers.ClientInfo" Version="2.1.2" />
|
||||
<PackageVersion Include="Serilog.Enrichers.Environment" Version="3.0.1" />
|
||||
<PackageVersion Include="Serilog.Enrichers.Process" Version="3.0.0" />
|
||||
<PackageVersion Include="Serilog.Enrichers.Sensitive" Version="1.7.3" />
|
||||
<PackageVersion Include="Serilog.Enrichers.Thread" Version="4.0.0" />
|
||||
<PackageVersion Include="Serilog.Extensions.Hosting" Version="8.0.0" />
|
||||
<PackageVersion Include="Serilog.Extensions.Logging" Version="8.0.0" />
|
||||
<PackageVersion Include="Serilog.Sinks.Async" Version="1.5.0" />
|
||||
<PackageVersion Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||
<PackageVersion Include="Serilog.Sinks.File" Version="6.0.0" />
|
||||
<PackageVersion Include="Serilog.Sinks.Seq" Version="8.0.0" />
|
||||
<PackageVersion Include="SerilogTracing" Version="1.1.0" />
|
||||
<PackageVersion Include="SerilogTracing.Expressions" Version="1.1.0" />
|
||||
<PackageVersion Include="SerilogTracing.Instrumentation.AspNetCore" Version="1.1.0" />
|
||||
<PackageVersion Include="SerilogTracing.Instrumentation.SqlClient" Version="1.1.0" />
|
||||
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
||||
<PackageVersion Include="Shouldly" Version="4.2.1" />
|
||||
<PackageVersion Include="SixLabors.ImageSharp" Version="3.1.4" />
|
||||
<PackageVersion Include="SixLabors.ImageSharp.Drawing" Version="2.0.1" />
|
||||
<PackageVersion Include="SkiaSharp" Version="2.88.6" />
|
||||
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.6" />
|
||||
<PackageVersion Include="SkiaSharp.NativeAssets.macOS" Version="2.88.6" />
|
||||
<PackageVersion Include="Slugify.Core" Version="4.0.1" />
|
||||
<PackageVersion Include="Spectre.Console" Version="0.47.0" />
|
||||
<PackageVersion Include="SqlSugarCore" Version="5.1.4.169" />
|
||||
<PackageVersion Include="StackExchange.Redis" Version="2.7.4" />
|
||||
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
||||
<PackageVersion Include="System.Collections.Immutable" Version="8.0.0" />
|
||||
<PackageVersion Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||
<PackageVersion Include="System.Linq.Async" Version="6.0.1" />
|
||||
<PackageVersion Include="System.Linq.Dynamic.Core" Version="1.3.5" />
|
||||
<PackageVersion Include="System.Linq.Queryable" Version="4.3.0" />
|
||||
<PackageVersion Include="System.Runtime.Loader" Version="4.3.0" />
|
||||
<PackageVersion Include="System.Security.Permissions" Version="8.0.0" />
|
||||
<PackageVersion Include="System.Security.Principal.Windows" Version="5.0.0" />
|
||||
<PackageVersion Include="System.Text.Encoding.CodePages" Version="8.0.0" />
|
||||
<PackageVersion Include="System.Text.Encodings.Web" Version="8.0.0" />
|
||||
<PackageVersion Include="System.Text.Json" Version="8.0.4" />
|
||||
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="7.5.1" />
|
||||
<PackageVersion Include="TimeZoneConverter" Version="6.1.0" />
|
||||
<PackageVersion Include="Unidecode.NET" Version="2.1.0" />
|
||||
<PackageVersion Include="xunit" Version="2.9.2" />
|
||||
<PackageVersion Include="xunit.extensibility.execution" Version="2.9.0" />
|
||||
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
|
||||
<PackageVersion Include="coverlet.collector" Version="6.0.2" />
|
||||
<PackageVersion Include="ConfigureAwait.Fody" Version="3.3.2" />
|
||||
<PackageVersion Include="Fody" Version="6.8.0" />
|
||||
<PackageVersion Include="Senparc.CO2NET.AspNet" Version="1.5.0" />
|
||||
<PackageVersion Include="Senparc.Weixin.Cache.Redis" Version="2.19.4" />
|
||||
<PackageVersion Include="Senparc.Weixin.TenPay" Version="1.16.4" />
|
||||
<PackageVersion Include="Senparc.Weixin.TenPayV3" Version="1.6.6" />
|
||||
<PackageVersion Include="Senparc.Weixin.WxOpen" Version="3.21.2" />
|
||||
<PackageVersion Include="Senparc.Weixin.AspNet" Version="1.4.7.1" />
|
||||
<PackageVersion Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.2" />
|
||||
<PackageVersion Include="BCrypt.Net-Next" Version="4.0.3" />
|
||||
<PackageVersion Include="Furion" Version="4.9.5.16" />
|
||||
<PackageVersion Include="Furion.Xunit" Version="4.9.5.16" />
|
||||
<PackageVersion Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.5.16" />
|
||||
<PackageVersion Include="Furion.Extras.ObjectMapper.Mapster" Version="4.9.5.16" />
|
||||
<PackageVersion Include="Furion.Extras.DatabaseAccessor.SqlSugar" Version="4.9.5.16" />
|
||||
<PackageVersion Include="Hinse.Cache" Version="1.2.0" />
|
||||
<PackageVersion Include="Hinse.CapEventbus.MySqlAndRabbitMQ" Version="1.2.1" />
|
||||
<PackageVersion Include="Hinse.Health" Version="1.3.4" />
|
||||
<PackageVersion Include="Hinse.Util" Version="3.3.0" />
|
||||
<PackageVersion Include="IPTools.China" Version="1.6.0" />
|
||||
<PackageVersion Include="JetBrains.Annotations" Version="2024.2.0" />
|
||||
<PackageVersion Include="Magicodes.IE.Excel" Version="2.7.5.1" />
|
||||
<PackageVersion Include="MiniExcel" Version="1.34.0" />
|
||||
<PackageVersion Include="NString" Version="2.1.1" />
|
||||
<PackageVersion Include="Yitter.IdGenerator" Version="1.0.14" />
|
||||
<PackageVersion Include="Z.EntityFramework.Extensions.Classic" Version="8.103.6.2" />
|
||||
<PackageVersion Include="Z.EntityFramework.Classic" Version="7.2.22" />
|
||||
<PackageVersion Include="Z.EntityFramework.Plus.EFCore" Version="8.103.1" />
|
||||
<PackageVersion Include="Zack.EFCore.Batch.MySQL.Pomelo_NET7" Version="7.1.8" />
|
||||
<PackageVersion Include="Scrutor" Version="4.2.2" />
|
||||
<PackageVersion Include="EFCore.BulkExtensions" Version="8.1.2" />
|
||||
<PackageVersion Include="DotNetCore.CAP" Version="8.2.0" />
|
||||
<PackageVersion Include="DotNetCore.CAP.Dashboard" Version="8.2.0" />
|
||||
<PackageVersion Include="DotNetCore.CAP.MySql" Version="8.2.0" />
|
||||
<PackageVersion Include="DotNetCore.CAP.RabbitMQ" Version="8.2.0" />
|
||||
<PackageVersion Include="DotNetCore.CAP.InMemoryStorage" Version="8.2.0" />
|
||||
<PackageVersion Include="Savorboard.CAP.InMemoryMessageQueue" Version="8.2.1" />
|
||||
<PackageVersion Include="Mapster.Async" Version="2.0.1" />
|
||||
<PackageVersion Include="Mapster.DependencyInjection" Version="1.0.1" />
|
||||
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="appsettings.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="appsettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
<PackageReference Include="Shouldly" />
|
||||
<PackageReference Include="xunit" />
|
||||
<PackageReference Include="xunit.runner.visualstudio">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="coverlet.collector">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Furion.Xunit" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\JT.Shop.Application\JT.Shop.Application.csproj" />
|
||||
<ProjectReference Include="..\JT.Shop.Authorization\JT.Shop.Authorization.csproj" />
|
||||
<ProjectReference Include="..\JT.Shop.EntityFramework.Core\JT.Shop.EntityFramework.Core.csproj" />
|
||||
<ProjectReference Include="..\JT.Shop.QueryService.SqlSugar\JT.Shop.QueryService.SqlSugar.csproj" />
|
||||
|
||||
<PackageReference Include="DotNetCore.CAP.InMemoryStorage" />
|
||||
<PackageReference Include="Savorboard.CAP.InMemoryMessageQueue" />
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="Xunit" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
using JT.Shop.Application.Service.Account;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Shouldly;
|
||||
using JT.Shop.Domain.Entity.Business;
|
||||
|
||||
namespace JT.Shop.Application.UnitTests.Service.Account
|
||||
{
|
||||
public class AuthAccountIdentitiesQueryServiceTests(IServiceProvider serviceProvider) : TestBase(serviceProvider)
|
||||
{
|
||||
[Fact]
|
||||
public async Task When_Get_Should_Be_Ok()
|
||||
{
|
||||
AuthAccountIdentitiesQueryService service = GetRequiredService<AuthAccountIdentitiesQueryService>();
|
||||
var output = await service.Get(18336461348165);
|
||||
output.Rows.ShouldNotBeEmpty();
|
||||
//output.Shops.First().SystemAuthorization.ShouldNotBeNull();
|
||||
//output.Shops.First().SystemAuthorization.Mode.ShouldBe(SystemAuthorizationMode.Normal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
// ------------------------------------------------------------------------
|
||||
// 版权信息
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
using JT.Shop.Application.Service.Business.Member;
|
||||
using JT.Shop.Application.Service.ShopHead.Shop;
|
||||
using JT.Shop.Core;
|
||||
using JT.Shop.Domain;
|
||||
using JT.Shop.Domain.Dtos;
|
||||
using JT.Shop.Domain.StatisticsReport;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JT.Shop.Application.UnitTests.Service.Business.Member
|
||||
{
|
||||
public class MemberServiceTest : TestBase
|
||||
{
|
||||
[Fact]
|
||||
public async Task PartList()
|
||||
{
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
|
||||
var output = await GetRequiredService<MemberService>().PartListAsync(new ShopHeadQueryMemberLoseWeightPartsInput() { ServeTimeRange = new DateRangeFilterInput() { Start = DateTime.Parse("2024-12-31"), End = DateTime.Parse("2025-01-07") } },
|
||||
GetRequiredService<ILoseWeightPartsQueryService>());
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { BusinessId = 1 });
|
||||
}
|
||||
[Fact]
|
||||
public async Task AFKAllListAsync()
|
||||
{
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
|
||||
var output = await GetRequiredService<MemberService>().AFKAllListAsync(new BusinessMemberListWithLeaveWarningInput() { Time = DateTime.Parse("2025-01-07") });
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { BusinessId = 1 });
|
||||
}
|
||||
[Fact]
|
||||
public async Task ZhangChengWarningAsync()
|
||||
{
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
|
||||
await GetRequiredService<MemberService>().ZhangChengWarningAsync(new BusinessMemberListWithZhangChengWarningInput() { Day = 1 });
|
||||
await GetRequiredService<MemberService>().ZhangChengWarningAsync(new BusinessMemberListWithZhangChengWarningInput() { Day = 2 });
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { BusinessId = 1 });
|
||||
}
|
||||
[Fact]
|
||||
public async Task AgainZhangChengWarningAsync()
|
||||
{
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
|
||||
await GetRequiredService<MemberService>().AgainZhangChengWarningAsync(new BusinessMemberListWithAgainZhangChengWarningInput() { StartVal = 1 });
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { BusinessId = 1 });
|
||||
}
|
||||
[Fact]
|
||||
public async Task SubscribeWarningAsync()
|
||||
{
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
|
||||
await GetRequiredService<MemberService>().SubscribeWarningAsync(new BusinessMemberListWithSubscribeInput() { });
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { BusinessId = 1 });
|
||||
}
|
||||
[Fact]
|
||||
public async Task SummarizeWarningAsync()
|
||||
{
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
|
||||
await GetRequiredService<MemberService>().SummarizeWarningAsync(new BusinessMemberListWithSummarizeWarningInput() { });
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { BusinessId = 1 });
|
||||
}
|
||||
[Fact]
|
||||
public async Task GetAllChildListWith3Plush1Lost()
|
||||
{
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
|
||||
await GetRequiredService<MemberService>().GetAllChildListWith3Plush1Lost(new BusinessMemberListWith3Plus1LostInput() { Time = DateTime.Parse("2025-01-07") });
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { BusinessId = 1 });
|
||||
}
|
||||
[Fact]
|
||||
public async Task TodayListAsync()
|
||||
{
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
|
||||
await GetRequiredService<MemberService>().TodayListAsync(new BusinessMemberTodayListInput() { });
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { BusinessId = 1 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// 品传科技
|
||||
// 开发:李鹏鹏
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
using JT.Shop.Domain;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JT.Shop.Application.UnitTests.Service.Shop;
|
||||
|
||||
public class DayCleanDomainServiceTest(DayCleanDomainService service) : TestBase
|
||||
{
|
||||
[Fact]
|
||||
public async Task Test()
|
||||
{
|
||||
await service
|
||||
.ExecuteAsync(new DateTime(2025, 1, 1), default);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// ------------------------------------------------------------------------
|
||||
// 版权信息
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
using JT.Shop.Application.Service.Mch.Conf;
|
||||
using JT.Shop.Application.Service.Shop.Colleague;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JT.Shop.Application.UnitTests.Service.Shop
|
||||
{
|
||||
public class ShopRoleListQueryServiceTest(ShopRoleListQueryService service) : TestBase
|
||||
{
|
||||
[Fact]
|
||||
public async Task Test()
|
||||
{
|
||||
await service.GetAccountList(new ShopRoleListQueryService.ShopRoleAccountListInput(){RoleId = 19043717587781 }, 18903188293189);
|
||||
}
|
||||
}
|
||||
|
||||
public class ShopSkinThemeQueryServiceTest(ShopSkinThemeQueryService service) : TestBase
|
||||
{
|
||||
[Fact]
|
||||
public async Task Test()
|
||||
{
|
||||
await service.QueryByShopId( 18903188293189);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
// ------------------------------------------------------------------------
|
||||
// 版权信息
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
using JT.Shop.Application.Service.ShopApi.Member;
|
||||
using JT.Shop.Application.Service.ShopHead.Shop;
|
||||
using JT.Shop.Core;
|
||||
using JT.Shop.Domain;
|
||||
using JT.Shop.Domain.Dtos;
|
||||
using JT.Shop.Domain.Shared;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JT.Shop.Application.UnitTests.Service.ShopApi.Member
|
||||
{
|
||||
public class MemberServiceTest(MemberService service) : TestBase
|
||||
{
|
||||
/* [Fact]
|
||||
public async Task Add()
|
||||
{
|
||||
var num = new Random().Next();
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
await service.ApplyAsync(new MemberAddInput()
|
||||
{
|
||||
Name = $"名字{num}",
|
||||
Phone = $"150{num}",
|
||||
Career = RegUserCareerEnum.ComMag,
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { BusinessId = 19221331138885, ShopId = 19222606505285, Name = "单元测试" });
|
||||
}*/
|
||||
[Fact]
|
||||
public async Task AllListAsync()
|
||||
{
|
||||
var num = new Random().Next();
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
await service.AllListAsync(new MemberAllListInput()
|
||||
{
|
||||
SortField = "increaseweight",
|
||||
SortOrder = "asc",
|
||||
PageNo = 1,
|
||||
PageSize = 10,
|
||||
SType = 0,
|
||||
ServeEndValue = 0,
|
||||
PType = 0,
|
||||
DType = 0
|
||||
});
|
||||
}, new CurrentShopUserInfoS2SDto { BusinessId = 19221331138885, ShopId = 20097712614725, Name = "单元测试" });
|
||||
}
|
||||
[Fact]
|
||||
public async Task RankListAsync()
|
||||
{
|
||||
var num = new Random().Next();
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
var output = await service.RankListAsync(new RankListC2SDto()
|
||||
{
|
||||
DateRange = ShopReportRankOfLoseWeightQueryServiceDateRange.Today
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { BusinessId = 1, ShopId = 19145601575493 });
|
||||
}
|
||||
[Fact]
|
||||
public async Task GetAllChildList_When_Params_All_NULL()
|
||||
{
|
||||
var list = await GetRequiredService<IPcShopRegUserQueryService>().GetAllChildList(16547534871493, null, 18738520908613, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, /*null,*/ null, null, null, null, null, null, null, null, null, new PageInputV2Base { });
|
||||
|
||||
}
|
||||
[Theory]
|
||||
[InlineData(0, 1, RegUserProperType.CurrentMonthNewUser, RegUserGroupProp.User31, "shopentercnt")]
|
||||
[InlineData(1, 2, RegUserProperType.NoSuccess, RegUserGroupProp.JZQZRDD, "clainweight")]
|
||||
[InlineData(2, 3, RegUserProperType.Success, RegUserGroupProp.SHQZRDD, "increaseweight")]
|
||||
[InlineData(2, 3, RegUserProperType.User31, RegUserGroupProp.JZQZRWD, "dealtime")]
|
||||
[InlineData(0, 1, RegUserProperType.CurrentMonthNewUser, RegUserGroupProp.ZRDD, "")]
|
||||
[InlineData(1, 2, RegUserProperType.NoSuccess, RegUserGroupProp.YGZ, "")]
|
||||
[InlineData(2, 3, RegUserProperType.Success, RegUserGroupProp.YDJ, "")]
|
||||
[InlineData(2, 3, RegUserProperType.User31, RegUserGroupProp.BYSR, "")]
|
||||
public async Task GetAllChildList(int? SType, int? NoEntryDay, RegUserProperType? PType, RegUserGroupProp? GType,string SortName)
|
||||
{
|
||||
await GetRequiredService<IPcShopRegUserQueryService>().GetAllChildList(1, null, null, "null", "null", "null", RegUserCareerEnum.ComMag, SType, RegUserRegiType.ZD, RegUserStatusEnum.Enable, new DateRangeFilterInput() { Start = new DateTime(2024, 1, 1), End = new DateTime(2024, 2, 1) }, new DateRangeFilterInput() { Start = new DateTime(2024, 1, 1), End = new DateTime(2024, 2, 1) }, new DateRangeFilterInput() { Start = new DateTime(2024, 1, 1), End = new DateTime(2024, 2, 1) }, new DateRangeFilterInput() { Start = new DateTime(2024, 1, 1), End = new DateTime(2024, 2, 1) }, new DateRangeFilterInput() { Start = new DateTime(2024, 1, 1), End = new DateTime(2024, 2, 1) }, new DateRangeFilterInput() { Start = new DateTime(2024, 1, 1), End = new DateTime(2024, 2, 1) },
|
||||
[RegUserTagEnum.JJQ, RegUserTagEnum.GGQ], [RegUserEnterTimeType.AfterNoon, RegUserEnterTimeType.Morning], NoEntryDay, PType, PType, /*WType,*/ GType, [0, 1, 2, 3, 4, 5, 6], [new NumberRangeFilterInput<int> { Min = null, Max = 1 }, new NumberRangeFilterInput<int> { Min = 10, Max = 100 }], [new NumberRangeFilterInput<decimal> { Min = 0, Max = 1 }, new NumberRangeFilterInput<decimal> { Min = 10, Max = 100 }], [new NumberRangeFilterInput<decimal> { Min = 0, Max = 1 }, new NumberRangeFilterInput<decimal> { Min = 10, Max = 100 }], null, ["1", "2"], [new NumberRangeFilterInput<int> { Min = 0, Max = 1 }, new NumberRangeFilterInput<int> { Min = 10, Max = 100 }], new PageInputV2Base {SortName = SortName });
|
||||
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetAllChildTodayList_When_Params_All_NULL()
|
||||
{
|
||||
var list = await GetRequiredService<IPcShopRegUserQueryService>().GetAllChildTodayList(16547534871493, null, 18738520908613, null, null, null, null, null, null, null, null, null, null, null, null, null, new PageInputV2Base { });
|
||||
|
||||
}
|
||||
[Theory]
|
||||
[InlineData(1, RegUserProperType.CurrentMonthNewUser, RegUserGroupProp.User31, RegUserWeightProp.Increase, "shopentercnt")]
|
||||
[InlineData(2, RegUserProperType.NoSuccess, RegUserGroupProp.JZQZRDD, RegUserWeightProp.Equ, "clainweight")]
|
||||
[InlineData(3, RegUserProperType.Success, RegUserGroupProp.SHQZRDD, RegUserWeightProp.Reduce, "increaseweight")]
|
||||
[InlineData(3, RegUserProperType.User31, RegUserGroupProp.JZQZRWD, RegUserWeightProp.Increase, "dealtime")]
|
||||
[InlineData(1, RegUserProperType.CurrentMonthNewUser, RegUserGroupProp.ZRDD, RegUserWeightProp.Increase, "")]
|
||||
[InlineData(2, RegUserProperType.NoSuccess, RegUserGroupProp.YGZ, RegUserWeightProp.Increase, "")]
|
||||
[InlineData(3, RegUserProperType.Success, RegUserGroupProp.YDJ, RegUserWeightProp.Increase, "")]
|
||||
[InlineData(3, RegUserProperType.User31, RegUserGroupProp.BYSR, RegUserWeightProp.Increase, "")]
|
||||
public async Task GetAllChildTodayList(int? NoEntryDay, RegUserProperType? PType, RegUserGroupProp? GType, RegUserWeightProp weightProp, string SortName)
|
||||
{
|
||||
await GetRequiredService<IPcShopRegUserQueryService>().GetAllChildTodayList(1, null, null, "null", "null", "null", [RegUserSXProp.BuyAndNoUsed, RegUserSXProp.BuyAndUsed, RegUserSXProp.NotBuy], [RegUserEnterStatus.AFK, RegUserEnterStatus.Ban], new DateRangeFilterInput() { Start = new DateTime(2024, 1, 1), End = new DateTime(2024, 2, 1) }, new DateRangeFilterInput() { Start = new DateTime(2024, 1, 1), End = new DateTime(2024, 2, 1) }, [RegUserTagEnum.GGQ, RegUserTagEnum.SJQ], [RegUserEnterTimeType.AfterNoon, RegUserEnterTimeType.Morning], NoEntryDay, PType, weightProp, GType, new PageInputV2Base { SortName = SortName });
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
using JT.Shop.Application.Service.ShopApi.Report;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
using Shouldly;
|
||||
using JT.Shop.Domain.Dtos;
|
||||
using JT.Shop.Domain;
|
||||
using JT.Shop.Application.Service.ShopApi.Report.Dto;
|
||||
|
||||
namespace JT.Shop.Application.UnitTests.Service.ShopApi.Report;
|
||||
public class ReportServiceTests : TestBase
|
||||
{
|
||||
private readonly ReportService reportService;
|
||||
|
||||
|
||||
public ReportServiceTests(ReportService reportService)
|
||||
{
|
||||
this.reportService = reportService;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task When_ClerkServeList_Shoule_Be_Ok()
|
||||
{
|
||||
var list = await reportService.ClerkServeList(new Application.Service.ShopApi.Report.Dto.ClerkServeListC2SDto { PageNo = 1, PageSize = 10, StartTime = DateTime.Parse("2024/07/17"), EndTime = DateTime.Parse("2024/07/24"), ServeId = 17653240352453 },GetRequiredService<IShopAccountServeSummaryQueryService>());
|
||||
//list.TotalPage.ShouldBeGreaterThan(0);
|
||||
//list.PageSize.ShouldBe(10);
|
||||
//list.PageNo.ShouldBe(1);
|
||||
//list.TotalPage.ShouldBeGreaterThan(0);
|
||||
//list.TotalRows.ShouldBeGreaterThan(0);
|
||||
//list.Rows.ShouldNotBeEmpty();
|
||||
//foreach (var row in list.Rows)
|
||||
//{
|
||||
// row.List.ShouldNotBeNull();
|
||||
// row.List.ShouldNotBeEmpty();
|
||||
//}
|
||||
}
|
||||
[Fact]
|
||||
public async Task When_ClerkList_Shoule_Be_Ok()
|
||||
{
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
var list = await reportService.ClerkList(new Application.Service.ShopApi.Report.Dto.ClerkListC2SDto { PageNo = 1, PageSize = 10, StartTime = DateTime.Parse("2024/12/30"), EndTime = DateTime.Parse("2025/01/06") },GetRequiredService<IShopAccountServeSummaryQueryService>());
|
||||
//list.TotalPage.ShouldBeGreaterThan(0);
|
||||
//list.PageSize.ShouldBe(10);
|
||||
//list.PageNo.ShouldBe(1);
|
||||
//list.TotalPage.ShouldBeGreaterThan(0);
|
||||
//list.TotalRows.ShouldBeGreaterThan(0);
|
||||
//list.Rows.ShouldNotBeEmpty();
|
||||
//foreach (var row in list.Rows)
|
||||
//{
|
||||
// row.List.ShouldNotBeNull();
|
||||
// row.List.ShouldNotBeEmpty();
|
||||
// row.List.ShouldNotContain(x => x.Name == "减重");
|
||||
//}
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { UserId = 17652841927877, ShopId = 19145601575493 });
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task When_FlowListAsync_Shoule_Be_Ok()
|
||||
{
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
var list = await reportService.FlowListAsync(new FlowListC2SDto { PageNo = 1, PageSize = 10, Time = DateTime.Parse("2024/07/25") },GetRequiredService<IShopEveryDayWaterQueryService>(),GetRequiredService<IPcShopServiceResultQueryService>(),GetRequiredService<IPcShopAccountQueryService>(),GetRequiredService<IPcShopServiceQueryService>());
|
||||
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { UserId = 17652841927877, ShopId = 17652841927877 });
|
||||
|
||||
|
||||
|
||||
}
|
||||
[Fact]
|
||||
public async Task When_PartListAsync_Shoule_Be_Ok()
|
||||
{
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
var list = await reportService.PartListAsync(new PartListC2SDto { PageNo = 1, PageSize = 10, ServeStartTime = DateTime.Parse("2024/07/25"), ServeEndTime = DateTime.Parse("2024/07/25") },GetRequiredService<ILoseWeightPartsQueryService>());
|
||||
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { UserId = 17652841927877, ShopId = 17652841927877 });
|
||||
|
||||
|
||||
|
||||
}
|
||||
[Fact]
|
||||
public async Task When_DayListAsync_Shoule_Be_Ok()
|
||||
{
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
var list = await reportService.DayListAsync(new DayListC2SDto { PageNo = 1, PageSize = 10, StartTime = DateTime.Parse("2024/07/25"), EndTime = DateTime.Parse("2024/07/25") }, GetRequiredService<IShopEveryDayLoseWeightSummaryQueryService>());
|
||||
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { UserId = 17652841927877, ShopId = 17652841927877 });
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
using Furion;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Furion.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using System.Security.Claims;
|
||||
using JT.Shop.Domain.Shared;
|
||||
using JT.Shop.Domain.Dtos;
|
||||
|
||||
namespace JT.Shop.Application.UnitTests.Service.ShopApi;
|
||||
|
||||
public class TestBase
|
||||
{
|
||||
public async Task MockCurrentShopUserInfoScope(Func<Task> handler, CurrentShopUserInfoS2SDto current)
|
||||
{
|
||||
await Scoped.CreateAsync(async (_, scope) =>
|
||||
{
|
||||
ClaimsIdentity identity = new("Authentication", ClaimTypes.Name, ClaimTypes.Role);
|
||||
|
||||
identity.AddClaim(new Claim(ClaimConst.CLAINM_ACCOUNT, current.UserId.ToString()));
|
||||
identity.AddClaim(new Claim(ClaimConst.CLAINM_SHOP_ID, current.ShopId.ToString()));
|
||||
identity.AddClaim(new Claim(ClaimConst.CLAINM_NAME, $"{current.Name}"));
|
||||
identity.AddClaim(new Claim(ClaimConst.CLAINM_SHOP_HEAD_ID, current.BusinessId.ToString()));
|
||||
ClaimsPrincipal principal = new();
|
||||
principal.AddIdentity(identity);
|
||||
|
||||
|
||||
App.GetRequiredService<TestHttpUserPrincipal>().SetUser(principal);
|
||||
await handler();
|
||||
});
|
||||
}
|
||||
|
||||
protected T GetRequiredService<T>() where T : class
|
||||
{
|
||||
return App.GetRequiredService<T>();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
using Furion.DatabaseAccessor;
|
||||
using Furion.DependencyInjection;
|
||||
using JT.Shop.Application.Service.ShopHead.Finance;
|
||||
using JT.Shop.Domain.Entity.DianShu;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JT.Shop.Application.UnitTests.Service.ShopHead
|
||||
{
|
||||
public class DianShuAppServiceTest(IDbContextPool pool, DianShuSetPwdDomainService dianShuSetPwdDomainService, IRepository<PcDianShuOfHead> pcdianshuOfheadRepository) : TestBase
|
||||
{
|
||||
[Fact]
|
||||
public async Task Test()
|
||||
{
|
||||
|
||||
await dianShuSetPwdDomainService.SetPwd("654321", 1);
|
||||
|
||||
await pool.SavePoolNowAsync();
|
||||
var entity = await pcdianshuOfheadRepository.FindOrDefaultAsync((long)1);
|
||||
await GetRequiredService<DianShuVerifySafetyPasswordService>().Verify(entity, "654321");
|
||||
//entity.VerifySafetyPassword("654321");
|
||||
}
|
||||
[Fact]
|
||||
public async Task GetChildHeadInfo()
|
||||
{
|
||||
|
||||
|
||||
var entity = await GetRequiredService<ShopHeadDianShuQueryService>().GetChildHeadInfo(18889346190277, 1);
|
||||
|
||||
entity.Qty.ShouldBe(15);
|
||||
entity.Id.ShouldBe(18889346190277);
|
||||
}
|
||||
[Fact]
|
||||
public async Task GetChildShopInfo()
|
||||
{
|
||||
|
||||
|
||||
var entity = await GetRequiredService<ShopHeadDianShuQueryService>().GetChildShopInfo(18903604435141, 1);
|
||||
|
||||
entity.Id.ShouldBe(18903604435141);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetInfo()
|
||||
{
|
||||
|
||||
|
||||
var entity = await GetRequiredService<ShopHeadDianShuQueryService>().GetInfo(18889346190277);
|
||||
|
||||
entity.Qty.ShouldBe(15);
|
||||
entity.Id.ShouldBe(18889346190277);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetWaterList()
|
||||
{
|
||||
|
||||
|
||||
var output = await GetRequiredService<ShopHeadDianShuQueryService>().GetWaterList(new ShopHeadDianShuQueryService.ShopHeadDianShuWaterListInput(), 1);
|
||||
|
||||
output.TotalRows.ShouldBeGreaterThan(0);
|
||||
}
|
||||
[Fact]
|
||||
public async Task GetConsumeList()
|
||||
{
|
||||
|
||||
|
||||
var output = await GetRequiredService<ShopHeadDianShuQueryService>().GetConsumeList(new ShopHeadDianShuQueryService.ShopHeadDianShuConsumeListInput(), 1);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// 品传科技
|
||||
// 开发:李鹏鹏
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
using JT.Shop.Application.Service.ShopHead;
|
||||
using JT.Shop.Application.Service.ShopHead.ChildHead;
|
||||
using JT.Shop.Domain.Dtos;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JT.Shop.Application.UnitTests.Service.ShopHead
|
||||
{
|
||||
public class HeadSelfControllerTest:TestBase
|
||||
{
|
||||
[Fact]
|
||||
public async Task MonthData()
|
||||
{
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
|
||||
await GetRequiredService<HeadSelfController>()
|
||||
.SimpleInfo(1, GetRequiredService<ShopHeadListQueryService>());
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { BusinessId = 1 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
// ------------------------------------------------------------------------
|
||||
// 版权信息
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
using JT.Shop.Application.Service.ShopHead.Shop;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JT.Shop.Application.UnitTests.Service.ShopHead
|
||||
{
|
||||
public class HeadShopListQueryServiceTest : TestBase
|
||||
{
|
||||
[Fact]
|
||||
public async Task GetList()
|
||||
{
|
||||
|
||||
var output = await GetRequiredService<HeadShopListQueryService>()
|
||||
.GetList(new HeadShopListQueryService.HeadShopListInput(), 1);
|
||||
output.TotalRows.ShouldBeGreaterThan(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetAllChildList()
|
||||
{
|
||||
|
||||
var output = await GetRequiredService<HeadShopListQueryService>()
|
||||
.GetAllChildList(new HeadShopListQueryService.HeadShopAllChildListInput(), 1);
|
||||
output.TotalRows.ShouldBeGreaterThan(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
// ------------------------------------------------------------------------
|
||||
// 版权信息
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
using Furion.DatabaseAccessor;
|
||||
using JT.Shop.Application.Service.ShopHead.Shop;
|
||||
using JT.Shop.Core;
|
||||
using JT.Shop.Domain;
|
||||
using JT.Shop.Domain.Dtos;
|
||||
using JT.Shop.Domain.Entity.GeneralAccount;
|
||||
using JT.Shop.Domain.Entity.ShopHead;
|
||||
using JT.Shop.Domain.StatisticsReport;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JT.Shop.Application.UnitTests.Service.ShopHead.Shop
|
||||
{
|
||||
public class ShopReportControllerTest : TestBase
|
||||
{
|
||||
[Fact]
|
||||
public async Task MonthData()
|
||||
{
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
|
||||
await GetRequiredService<ShopsReportController>().MonthData(new ShopReportMonthDataQueryServiceInput() { Year = 2024, Month = 1 },
|
||||
GetRequiredService<IShopReportMonthDataQueryService>());
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { BusinessId = 1 });
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TodayData()
|
||||
{
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
|
||||
await GetRequiredService<ShopsReportController>().TodayData(new ShopReportTodayDataQueryServiceInput() { },
|
||||
GetRequiredService<IShopReportTodayDataQueryService>());
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { BusinessId = 1 });
|
||||
}
|
||||
[Fact]
|
||||
public async Task BatchData1()
|
||||
{
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
|
||||
await GetRequiredService<ShopsReportController>().BatchData1(
|
||||
GetRequiredService<IShopReportTodayDataQueryService>(), GetRequiredService<IShopReportMonthDataQueryService>(), GetRequiredService<IShopReportShopDataQueryService>(), GetRequiredService<IPcShopHeadQueryService>(), GetRequiredService<IPcShopHeadAccountQueryService>(),GetRequiredService<GeneralAccountWxLoginBindDomainService>());
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { BusinessId = 1 });
|
||||
}
|
||||
[Fact]
|
||||
public async Task ShopData()
|
||||
{
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
|
||||
await GetRequiredService<ShopsReportController>().ShopData(
|
||||
GetRequiredService<IShopReportShopDataQueryService>());
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { BusinessId = 1 });
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task MemberAnalysis()
|
||||
{
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
|
||||
var output = await GetRequiredService<ShopsReportController>().MemberAnalysis(new ShopReportMemberAnalysisQueryServiceInput { },
|
||||
GetRequiredService<IShopReportMemberAnalysisQueryService>());
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { BusinessId = 1 });
|
||||
}
|
||||
[Fact]
|
||||
public async Task RankOfLoseWeight()
|
||||
{
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
|
||||
await GetRequiredService<ShopsReportController>().RankOfLoseWeight(new ShopReportRankOfLoseWeightQueryServiceInput { Date = new DateTime(2024, 1, 1) },
|
||||
GetRequiredService<IShopReportRankOfLoseWeightQueryService>());
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { BusinessId = 1 });
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task RankOfShopLoseWeight()
|
||||
{
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
{
|
||||
var output = await GetRequiredService<ShopsReportController>().RankOfShopLoseWeight(new ShopReportRankOfShopLoseWeightQueryServiceInput { DateRange = ShopReportRankOfShopLoseWeightQueryServiceDateRange.Today },
|
||||
GetRequiredService<IShopReportRankOfShopLoseWeightQueryService>());
|
||||
}
|
||||
{
|
||||
var output = await GetRequiredService<ShopsReportController>().RankOfShopLoseWeight(new ShopReportRankOfShopLoseWeightQueryServiceInput { DateRange = ShopReportRankOfShopLoseWeightQueryServiceDateRange.Month },
|
||||
GetRequiredService<IShopReportRankOfShopLoseWeightQueryService>());
|
||||
}
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { BusinessId = 1 });
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task RankOfShopNewAddMember()
|
||||
{
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
|
||||
await GetRequiredService<ShopsReportController>().RankOfShopNewAddMember(new ShopReportRankOfShopNewAddMemberQueryServiceInput { DateRange = ShopReportRankOfShopNewAddMemberQueryServiceDateRange.Today },
|
||||
GetRequiredService<IShopReportRankOfShopNewAddMemberQueryService>());
|
||||
await GetRequiredService<ShopsReportController>().RankOfShopNewAddMember(new ShopReportRankOfShopNewAddMemberQueryServiceInput { DateRange = ShopReportRankOfShopNewAddMemberQueryServiceDateRange.Month },
|
||||
GetRequiredService<IShopReportRankOfShopNewAddMemberQueryService>());
|
||||
}, new CurrentShopUserInfoS2SDto { BusinessId = 1 });
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task RankOfShopServicePositionSum()
|
||||
{
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
|
||||
await GetRequiredService<ShopsReportController>().RankOfShopServicePositionSum(new ShopReportRankOfShopServicePositionSumQueryServiceInput { DateRange = ShopReportRankOfShopServicePositionSumQueryServiceDateRange.Today },
|
||||
GetRequiredService<IShopReportRankOfShopServicePositionSumQueryService>());
|
||||
await GetRequiredService<ShopsReportController>().RankOfShopServicePositionSum(new ShopReportRankOfShopServicePositionSumQueryServiceInput { DateRange = ShopReportRankOfShopServicePositionSumQueryServiceDateRange.Month },
|
||||
GetRequiredService<IShopReportRankOfShopServicePositionSumQueryService>());
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { BusinessId = 1 });
|
||||
}
|
||||
[Fact]
|
||||
public async Task ShopAccountServeSummary()
|
||||
{
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
|
||||
var output = await GetRequiredService<ShopsReportController>().ShopAccountServeSummary(new ShopHeadQueryShopAccountServeSummaryInput { CreateTimeRange = new DateRangeFilterInput(DateTime.Parse("2025/1/1"), DateTime.Parse("2025/1/5")) },
|
||||
GetRequiredService<IShopAccountServeSummaryQueryService>());
|
||||
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { BusinessId = 1 });
|
||||
}
|
||||
[Fact]
|
||||
public async Task ShopAccountServeDetail()
|
||||
{
|
||||
await MockCurrentShopUserInfoScope(async () =>
|
||||
{
|
||||
|
||||
var output = await GetRequiredService<ShopsReportController>().ShopAccountServeDetail(new ShopHeadQueryShopAccountServeDetailInput
|
||||
{
|
||||
CreateTimeRange = new DateRangeFilterInput(DateTime.Parse("2025/01/04"), DateTime.Parse("2025/01/04")),
|
||||
ServeId = 19397538102085,
|
||||
UserId = 19145601575749
|
||||
},
|
||||
GetRequiredService<IShopAccountServeSummaryQueryService>());
|
||||
|
||||
|
||||
}, new CurrentShopUserInfoS2SDto { BusinessId = 1 });
|
||||
}
|
||||
[Fact]
|
||||
|
||||
public async Task PCShopMonthReportCreateDomainService()
|
||||
{
|
||||
var shops = await GetRequiredService<IRepository<PC_Shop>>().DetachedEntities.ToListAsync();
|
||||
var start = new DateTime(2024, 10, 1);
|
||||
|
||||
foreach (var shop in shops)
|
||||
{
|
||||
var index = -1;
|
||||
while (index++ < 5)
|
||||
{
|
||||
await GetRequiredService<PCShopMonthReportCreateDomainService>()
|
||||
.Create(shop.Id, start.AddMonths(index), shop.BusinessId);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
// ------------------------------------------------------------------------
|
||||
// 版权信息
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
using JT.Shop.Application.Service.ShopHead.ChildHead;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JT.Shop.Application.UnitTests.Service.ShopHead
|
||||
{
|
||||
public class ShopHeadListQueryServiceTest : TestBase
|
||||
{
|
||||
[Fact]
|
||||
public async Task GetList()
|
||||
{
|
||||
|
||||
var output = await GetRequiredService<ShopHeadListQueryService>()
|
||||
.GetList(new ShopHeadListQueryService.ShopHeadListInput(), 1);
|
||||
output.TotalRows.ShouldBeGreaterThan(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetAllChildList()
|
||||
{
|
||||
|
||||
var output = await GetRequiredService<ShopHeadListQueryService>()
|
||||
.GetAllChildList(new ShopHeadListQueryService.ShopHeadAllChildListInput(), 1);
|
||||
output.TotalRows.ShouldBeGreaterThan(0);
|
||||
}
|
||||
[Fact]
|
||||
public async Task GetDetail()
|
||||
{
|
||||
|
||||
var output = await GetRequiredService<ShopHeadListQueryService>()
|
||||
.GetDetail(19411154610245);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
using JT.Shop.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using JT.Shop.Application.Service.System.Business;
|
||||
using Mapster;
|
||||
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
|
||||
using Shouldly;
|
||||
using static JT.Shop.Application.Service.System.Business.SystemBusinessVersionOutputQueryService;
|
||||
|
||||
namespace JT.Shop.Application.UnitTests.Service.System.Business
|
||||
{
|
||||
public class SystemBusinessVersionOutputQueryServiceTest : TestBase
|
||||
{
|
||||
protected SystemBusinessVersionOutputQueryService queryService =>
|
||||
GetRequiredService<SystemBusinessVersionOutputQueryService>();
|
||||
[Fact]
|
||||
public async Task GetList()
|
||||
{
|
||||
var output = await queryService.GetList(new SystemBusinessVersionListInput() { SortName = "1" });
|
||||
output.SortNameErr.ShouldBeTrue();
|
||||
}
|
||||
[Fact]
|
||||
public async Task GetDetail()
|
||||
{
|
||||
await queryService.GetDetail(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using JT.Shop.Application.Service.System.DianShu;
|
||||
using JT.Shop.Domain.Entity.DianShu;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Shouldly;
|
||||
using static JT.Shop.Application.Service.System.DianShu.DianShuRechargeTargetListOutputQueryService;
|
||||
|
||||
namespace JT.Shop.Application.UnitTests.Service.System.DianShu
|
||||
{
|
||||
public class DianShuRechargeOrderListOutputQueryServiceTest(IServiceProvider serviceProvider) : TestBase(serviceProvider)
|
||||
{
|
||||
[Fact]
|
||||
public async Task Test()
|
||||
{
|
||||
var list = await serviceProvider.GetRequiredService<IPcDianShuQueryService>()
|
||||
.GetByIdWithEntity(new HashSet<long>() { 1 });
|
||||
|
||||
|
||||
list.ShouldNotBeEmpty();
|
||||
list.Count().ShouldBe(1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Test2()
|
||||
{
|
||||
|
||||
var output = await GetRequiredService().GetOrderList(new DianShuRechargeOrderListOutputQueryService.DianShuRechargeListInput() { });
|
||||
|
||||
output.Rows.ShouldNotBeEmpty();
|
||||
}
|
||||
|
||||
private DianShuRechargeOrderListOutputQueryService GetRequiredService()
|
||||
{
|
||||
return GetRequiredService<DianShuRechargeOrderListOutputQueryService>();
|
||||
}
|
||||
}
|
||||
|
||||
public class DianShuRechargeTargetListOutputQueryServiceTest(IServiceProvider serviceProvider) : TestBase(serviceProvider)
|
||||
{
|
||||
[Fact]
|
||||
public async Task When_GetTargetList()
|
||||
{
|
||||
|
||||
|
||||
{
|
||||
var output = await GetRequiredService<DianShuRechargeTargetListOutputQueryService>().GetTargetList(new DianShuRechargeTargetListInput() { });
|
||||
|
||||
output.Rows.ShouldNotBeEmpty();
|
||||
}
|
||||
{
|
||||
var output = await GetRequiredService<DianShuRechargeTargetListOutputQueryService>().GetTargetList(new DianShuRechargeTargetListInput() { Search = "1"});
|
||||
|
||||
output.Rows.ShouldNotBeEmpty();
|
||||
}
|
||||
{
|
||||
var output = await GetRequiredService<DianShuRechargeTargetListOutputQueryService>().GetTargetList(new DianShuRechargeTargetListInput() { Type =
|
||||
[DianShuType.Head]
|
||||
});
|
||||
|
||||
output.Rows.ShouldNotBeEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task When_GetList()
|
||||
{
|
||||
|
||||
var output = await GetRequiredService<DianShuRechargeTargetListOutputQueryService>().GetList(new DianShuRechargeTargetListInput() { });
|
||||
|
||||
output.Rows.ShouldNotBeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task When_GetList2()
|
||||
{
|
||||
|
||||
var output = await GetRequiredService<DianShuRechargeTargetListOutputQueryService>().GetList(new DianShuRechargeTargetListInput() { Type = new HashSet<DianShuType>() { DianShuType.Shop, DianShuType.Head } });
|
||||
|
||||
output.Rows.ShouldNotBeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task When_GetList3()
|
||||
{
|
||||
|
||||
var output = await GetRequiredService<DianShuRechargeTargetListOutputQueryService>().GetList(new DianShuRechargeTargetListInput() { Type = new HashSet<DianShuType>() { DianShuType.Shop, DianShuType.Head }, SortName = "h.Id" });
|
||||
|
||||
output.Rows.ShouldNotBeEmpty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
using Furion.DependencyInjection;
|
||||
using JT.Shop.Domain.Dtos;
|
||||
using JT.Shop.Domain.Shared;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Furion;
|
||||
|
||||
namespace JT.Shop.Application.UnitTests;
|
||||
|
||||
public class TestBase
|
||||
{
|
||||
public TestBase()
|
||||
{
|
||||
}
|
||||
public TestBase(IServiceProvider serviceProvider)
|
||||
{
|
||||
}
|
||||
public async Task MockCurrentShopUserInfoScope(Func<Task> handler, CurrentShopUserInfoS2SDto current)
|
||||
{
|
||||
await Scoped.CreateAsync(async (_, scope) =>
|
||||
{
|
||||
ClaimsIdentity identity = new("Authentication", ClaimTypes.Name, ClaimTypes.Role);
|
||||
|
||||
identity.AddClaim(new Claim(ClaimConst.CLAINM_ACCOUNT, current.UserId.ToString()));
|
||||
identity.AddClaim(new Claim(ClaimConst.CLAINM_SHOP_ID, current.ShopId.ToString()));
|
||||
identity.AddClaim(new Claim(ClaimConst.CLAINM_NAME, $"{current.Name}"));
|
||||
identity.AddClaim(new Claim(ClaimConst.CLAINM_SHOP_HEAD_ID, current.BusinessId.ToString()));
|
||||
//identity.AddClaim(new Claim(ClaimConst.CLAINM_OPENID, $"{current.OpenId}"));
|
||||
ClaimsPrincipal principal = new();
|
||||
principal.AddIdentity(identity);
|
||||
|
||||
scope.ServiceProvider.GetRequiredService<TestHttpUserPrincipal>().SetUser(principal);
|
||||
await handler();
|
||||
});
|
||||
}
|
||||
|
||||
public T GetRequiredService<T>() where T : class
|
||||
{
|
||||
|
||||
return App.GetRequiredService<T>();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
using Furion;
|
||||
using Furion.Xunit;
|
||||
using Hinse.Health;
|
||||
using JT.Shop.Authorization;
|
||||
using JT.Shop.Core;
|
||||
using JT.Shop.Domain;
|
||||
using JT.Shop.Domain.Dtos;
|
||||
using JT.Shop.EntityFramework.Core;
|
||||
using JT.Shop.QueryService;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Savorboard.CAP.InMemoryMessageQueue;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Volo.Abp;
|
||||
using Volo.Abp.Autofac;
|
||||
using Volo.Abp.Data;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using Volo.Abp.Modularity;
|
||||
using Xunit.Abstractions;
|
||||
using Yitter.IdGenerator;
|
||||
|
||||
[assembly: TestFramework("JT.Shop.Application.UnitTests.TestProgram", "JT.Shop.Application.UnitTests")]
|
||||
|
||||
namespace JT.Shop.Application.UnitTests;
|
||||
|
||||
public class TestProgram : TestStartup
|
||||
{
|
||||
public TestProgram(IMessageSink messageSink) : base(messageSink)
|
||||
{
|
||||
Serve.RunNative(GenericRunOptions.DefaultSilence.ConfigureBuilder((hostbuilder) =>
|
||||
{
|
||||
hostbuilder.UseAutofac();
|
||||
|
||||
hostbuilder.ConfigureServices(services =>
|
||||
{
|
||||
|
||||
|
||||
var application = services.AddApplication<ApplicationTestModule>(SetAbpApplicationCreationOptions);
|
||||
|
||||
var RootServiceProvider = CreateServiceProvider(services);
|
||||
|
||||
var TestServiceScope = RootServiceProvider.CreateScope();
|
||||
|
||||
application.Initialize(TestServiceScope.ServiceProvider);
|
||||
|
||||
|
||||
|
||||
services.AddCap(x =>
|
||||
{
|
||||
x.UseInMemoryStorage();
|
||||
x.UseInMemoryMessageQueue();
|
||||
});
|
||||
|
||||
services.AddSqlsugarSetup(App.Configuration);
|
||||
|
||||
//services.AddSingleton<IHttpUserPrincipal, TestHttpUserPrincipal>();
|
||||
//services.AddSingleton<TestHttpUserPrincipal>();
|
||||
|
||||
|
||||
services.AddTransient<ISmsService, MockSmsService>();
|
||||
services.AddTransient<IPasswordErrorLimitService, MockPasswordErrorLimitService>();
|
||||
});
|
||||
|
||||
return hostbuilder;
|
||||
}));
|
||||
}
|
||||
|
||||
protected virtual void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options)
|
||||
{
|
||||
|
||||
}
|
||||
protected virtual IServiceProvider CreateServiceProvider(IServiceCollection services)
|
||||
{
|
||||
return services.BuildServiceProviderFromFactory();
|
||||
}
|
||||
}
|
||||
|
||||
[Volo.Abp.Modularity.DependsOn(
|
||||
typeof(AbpDataModule), typeof(AbpAutofacModule), typeof(ShopApplicationModule), typeof(ShopEntityFrameworkCoreModule), typeof(ShopAuthorizationModule),typeof(ShopQueryServiceSqlSugarModule)
|
||||
//typeof(AbpSecurityModule),
|
||||
//typeof(AbpSettingsModule),
|
||||
//typeof(AbpEventBusAbstractionsModule),
|
||||
//typeof(AbpMultiTenancyAbstractionsModule)
|
||||
)]
|
||||
public class ApplicationTestModule : AbpModule
|
||||
{
|
||||
public override void ConfigureServices(ServiceConfigurationContext context)
|
||||
{
|
||||
base.ConfigureServices(context);
|
||||
context.Services.AddObjectMapper(
|
||||
Assembly.GetAssembly(typeof(ShopApplicationModule)),
|
||||
Assembly.GetAssembly(typeof(ShopQueryServiceSqlSugarModule))
|
||||
);
|
||||
}
|
||||
}
|
||||
public class MockPasswordErrorLimitService : IPasswordErrorLimitService
|
||||
{
|
||||
public Task Add(string account, string category, int minutes)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task Check(string account, string category, int maxTimes, string errmsg)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task RemoveCheck(string account, string category)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
public class MockSmsService : ISmsService
|
||||
{
|
||||
public bool CheckCodeAsync(string code, string phone, string intent, bool IsClear = true)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void ClearVrCodeAsync(string phone, string intent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Task<string> SendAsync(string phone, string intent)
|
||||
{
|
||||
return Task.FromResult(string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
public class TestHttpUserPrincipal : IHttpUserPrincipal, ISingletonDependency
|
||||
{
|
||||
private ClaimsPrincipal _user;
|
||||
|
||||
public void SetUser(ClaimsPrincipal user)
|
||||
{
|
||||
_user = user;
|
||||
}
|
||||
public ClaimsPrincipal User =>_user;
|
||||
}
|
||||
|
||||
public class TestCurrentSession : ICurrentSession, ISingletonDependency
|
||||
{
|
||||
public string SessionId { get; }
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace JT.Shop.Application.UnitTests
|
||||
{
|
||||
public class UnitTest1
|
||||
{
|
||||
private readonly ITestOutputHelper Output;
|
||||
|
||||
public UnitTest1(ITestOutputHelper output)
|
||||
{
|
||||
Output = output;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Test1()
|
||||
{
|
||||
var date = new DateTime(2025, 7, 5, 12, 0, 0);
|
||||
Output.WriteLine(date.AddDays(60).ToString("yyyy/MM/dd HH:mm"));
|
||||
Output.WriteLine(DateTime.Parse("2025/7/20 12:00").AddDays(30).ToString("yyyy/MM/dd HH:mm"));
|
||||
Output.WriteLine(DateTime.Parse("2025/7/5 12:00").AddDays(20).ToString("yyyy/MM/dd HH:mm"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
{
|
||||
"$schema": "https://gitee.com/dotnetchina/Furion/raw/net6/schemas/v3/furion-schema.json",
|
||||
//数据库配置
|
||||
"ConnectionStrings": {
|
||||
//"DefaultConnection": "Data Source=123.249.79.37;Database=jt_shop_v2_test;User ID=jt_shop_v2_test;Password=hPLAMfteswmyd63X;pooling=true;port=3306;sslmode=none;CharSet=utf8;AllowLoadLocalInfile=true;"
|
||||
"DefaultConnection": "Data Source=127.0.0.1;Database=jt_shop_v2_1;User ID=admin;Password=000000;pooling=true;port=3306;sslmode=none;CharSet=utf8;AllowLoadLocalInfile=true;"
|
||||
},
|
||||
//rabbitmq配置
|
||||
"RabbitmqSetting": {
|
||||
//rabbitmq配置
|
||||
"Enabled": "true",
|
||||
"GroupName": "JT.Shop.queue",
|
||||
"HostName": "localhost",
|
||||
"Port": 5672,
|
||||
"UserName": "liuzl",
|
||||
"Password": "liuzl",
|
||||
"DBConnection": "Data Source=127.0.0.1;Database=jt_shop_v2_1;User ID=admin;Password=000000;pooling=true;port=3306;sslmode=none;CharSet=utf8;AllowLoadLocalInfile=true;"
|
||||
},
|
||||
//swagger配置
|
||||
"SpecificationDocumentSettings": {
|
||||
"DocumentTitle": "接口平台",
|
||||
"DocExpansionState": "List",
|
||||
"RoutePrefix": "api",
|
||||
"HideServers": true,
|
||||
"LoginInfo": {
|
||||
"Enabled": true,
|
||||
"CheckUrl": "/Home/CheckUrl",
|
||||
"SubmitUrl": "/Home/SubmitUrl",
|
||||
"UserName": "admin",
|
||||
"Password": "admin"
|
||||
}
|
||||
},
|
||||
//swagger开关
|
||||
"AppSettings": {
|
||||
"InjectSpecificationDocument": true
|
||||
},
|
||||
//日志配置
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning",
|
||||
"Microsoft.EntityFrameworkCore": "Warning",
|
||||
"System.Net.Http.HttpClient": "Warning",
|
||||
"DotNetCore.CAP": "Warning"
|
||||
},
|
||||
"File": {
|
||||
"Enabled": false, // 启用文件日志
|
||||
"FileName": "logs/{0:yyyyMMdd}_{1}.log", // 日志文件
|
||||
"Append": true, // 追加覆盖
|
||||
// "MinimumLevel": "Information", // 日志级别
|
||||
"FileSizeLimitBytes": 10485760, // 10M=10*1024*1024
|
||||
"MaxRollingFiles": 30 // 只保留30个文件
|
||||
},
|
||||
"Database": {
|
||||
"Enabled": true, // 启用数据库日志
|
||||
"MinimumLevel": "Information"
|
||||
},
|
||||
"Monitor": {
|
||||
"GlobalEnabled": false, // 启用全局拦截日志
|
||||
"IncludeOfMethods": [], // 拦截特定方法,当GlobalEnabled=false有效
|
||||
"ExcludeOfMethods": [], // 排除特定方法,当GlobalEnabled=true有效
|
||||
"BahLogLevel": "Information", // Oops.Bah 和 Oops.Bah 业务日志输出级别
|
||||
"WithReturnValue": true, // 是否包含返回值,默认true
|
||||
"ReturnValueThreshold": 500, // 返回值字符串阈值,默认0全量输出
|
||||
"JsonBehavior": "None", // 是否输出Json,默认None(OnlyJson、All)
|
||||
"JsonIndented": false, // 是否格式化Json
|
||||
"UseUtcTimestamp": false // 时间格式UTC、LOCAL
|
||||
}
|
||||
},
|
||||
//上传配置
|
||||
"Upload": {
|
||||
"Path": "Upload", // 文件上传目录
|
||||
"MaxSize": 20480, // 文件最大限制KB:1024*20
|
||||
"ContentType": [ "image/jpg", "image/png", "image/jpeg", "image/gif", "image/bmp", "text/plain", "application/pdf", "application/msword", "application/vnd.ms-excel", "application/vnd.ms-powerpoint", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "video/mp4" ],
|
||||
"EnableMd5": false // 启用文件MDF5验证-防止重复上传
|
||||
},
|
||||
//接口配置
|
||||
"DynamicApiControllerSettings": {
|
||||
"KeepName": true,
|
||||
"KeepVerb": false,
|
||||
"LowercaseRoute": true,
|
||||
"DefaultRoutePrefix": "api",
|
||||
"UrlParameterization": true
|
||||
},
|
||||
//异常处理
|
||||
"FriendlyExceptionSettings": {
|
||||
//友好异常配置
|
||||
"DefaultErrorMessage": "系统异常,请联系管理员",
|
||||
"HideErrorCode": true //不显示异常代码
|
||||
},
|
||||
//JWT配置
|
||||
"JWTSettings": {
|
||||
"ValidateIssuerSigningKey": true, // 是否验证密钥,bool 类型,默认true
|
||||
"IssuerSigningKey": "E99B4E28D590C0527076074E93D5E941", // 密钥,string 类型,必须是复杂密钥,长度大于16: null,JT.Shop
|
||||
"ValidateIssuer": true, // 是否验证签发方,bool 类型,默认true
|
||||
"ValidIssuer": "JT.Shop", // 签发方,string 类型
|
||||
"ValidateAudience": true, // 是否验证签收方,bool 类型,默认true
|
||||
"ValidAudience": "JT.ShopAdmin", // 签收方,string 类型
|
||||
"ValidateLifetime": true, // 是否验证过期时间,bool 类型,默认true,建议true
|
||||
"ExpiredTime": 120, // 过期时间,long 类型,单位分钟,默认20分钟
|
||||
"ClockSkew": 5 // 过期时间容错值,long 类型,单位秒,默认5秒
|
||||
},
|
||||
//跨域配置
|
||||
"CorsAccessorSettings": {
|
||||
"WithExposedHeaders": [
|
||||
"access-token",
|
||||
"x-access-token",
|
||||
"Content-Disposition",
|
||||
"environment"
|
||||
]
|
||||
},
|
||||
//缓存配置
|
||||
"Cache": {
|
||||
"CacheType": "Memory", // Memory、Redis
|
||||
"RedisConnectionString": "server=127.0.0.1:6379;password=;db=2;", // Redis连接字符串
|
||||
"InstanceName": "PCKJ:EfCoreSingleAdmin:" //redis缓存前缀
|
||||
},
|
||||
//雪花ID配置
|
||||
"SnowId": {
|
||||
"WorkerId": 1, // 机器码 全局唯一
|
||||
"WorkerIdBitLength": 1, // 机器码位长 默认值6,取值范围 [1, 19]
|
||||
"SeqBitLength": 6 // 序列数位长 默认值6,取值范围 [3, 21](建议不小于4)
|
||||
},
|
||||
//自定义配置
|
||||
"CustomSetting": {
|
||||
//自定义配置
|
||||
"Version": "0.0.1", //版本号
|
||||
"CopyRight": "郑州巨天",
|
||||
"PlatformName": "门店管理平台"
|
||||
},
|
||||
//接口地址配置
|
||||
"ApiUrlSetting": {
|
||||
"Api": "http://imd.pcxbc.com", //api接口地址
|
||||
"Img": "http://imd.pcxbc.com", //图片地址
|
||||
"File": "http://imd.pcxbc.com", //文件地址
|
||||
"H5": "http://mdh5.pcxbc.com", //门店端h5地址
|
||||
"UserH5": "http://mduser.pcxbc.com", //用户端h5入口地址
|
||||
"UserResultH5": "http://mduser.pcxbc.com/#/pages/weight/weight" //用户端h5测量结果地址
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace JT.Shop.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// 过期过滤器
|
||||
/// </summary>
|
||||
public class ExpireFilterAttribute : Attribute, IAsyncActionFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// 结果筛选器
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="next"></param>
|
||||
/// <returns></returns>
|
||||
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
|
||||
{
|
||||
//获取过期时间,可以存到token中,也可以直接从数据库中获取
|
||||
var expiretime = context.HttpContext.User?.FindFirstValue("expiretime").ToDate();
|
||||
var userid = context.HttpContext.User?.FindFirstValue(ClaimConst.CLAINM_ACCOUNT).ToLong();
|
||||
//如果过期时间小于当前时间则禁止访问
|
||||
if (expiretime < DateTime.Now)
|
||||
{
|
||||
context.Result = new ForbidResult();
|
||||
return;
|
||||
}
|
||||
//数据库查询
|
||||
await Scoped.CreateAsync(async (_, scope) =>
|
||||
{
|
||||
var services = scope.ServiceProvider;
|
||||
var userRep = services.GetService<IRepository<SysUser>>();
|
||||
var user = await userRep.DetachedEntities.Where(x => x.Id == userid).FirstOrDefaultAsync();
|
||||
//判断是否过期
|
||||
});
|
||||
await next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
global using Furion;
|
||||
global using Furion.DatabaseAccessor;
|
||||
global using Furion.DependencyInjection;
|
||||
global using Furion.DynamicApiController;
|
||||
global using Furion.FriendlyException;
|
||||
global using Hinse.Util;
|
||||
global using JT.Shop.Application.Service;
|
||||
global using JT.Shop.Core;
|
||||
global using JT.Shop.Domain;
|
||||
global using JT.Shop.Domain.Dtos;
|
||||
global using JT.Shop.Domain.Shared;
|
||||
//global using JT.Shop.EntityFramework.Core;
|
||||
global using Mapster;
|
||||
global using Microsoft.AspNetCore.Mvc;
|
||||
global using Microsoft.EntityFrameworkCore;
|
||||
global using Newtonsoft.Json;
|
||||
global using System.ComponentModel.DataAnnotations;
|
||||
global using Yitter.IdGenerator;
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>disable</Nullable>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DebugType>none</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<NoWarn>1701;1702;1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<NoWarn>1701;1702;1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Service\Business\Retailer\**" />
|
||||
<Compile Remove="Service\Mch\Account\Dto\**" />
|
||||
<Compile Remove="Service\ShopHead\Agent\**" />
|
||||
<Compile Remove="Service\System\Captcha\**" />
|
||||
<Compile Remove="Service\System\CodeGen\**" />
|
||||
<Compile Remove="Service\System\LowCode\**" />
|
||||
<Compile Remove="Service\System\StepBody\**" />
|
||||
<Compile Remove="Service\System\Timer\**" />
|
||||
<Compile Remove="Service\System\Workflow\**" />
|
||||
<EmbeddedResource Remove="Service\Business\Retailer\**" />
|
||||
<EmbeddedResource Remove="Service\Mch\Account\Dto\**" />
|
||||
<EmbeddedResource Remove="Service\ShopHead\Agent\**" />
|
||||
<EmbeddedResource Remove="Service\System\Captcha\**" />
|
||||
<EmbeddedResource Remove="Service\System\CodeGen\**" />
|
||||
<EmbeddedResource Remove="Service\System\LowCode\**" />
|
||||
<EmbeddedResource Remove="Service\System\StepBody\**" />
|
||||
<EmbeddedResource Remove="Service\System\Timer\**" />
|
||||
<EmbeddedResource Remove="Service\System\Workflow\**" />
|
||||
<None Remove="Service\Business\Retailer\**" />
|
||||
<None Remove="Service\Mch\Account\Dto\**" />
|
||||
<None Remove="Service\ShopHead\Agent\**" />
|
||||
<None Remove="Service\System\Captcha\**" />
|
||||
<None Remove="Service\System\CodeGen\**" />
|
||||
<None Remove="Service\System\LowCode\**" />
|
||||
<None Remove="Service\System\StepBody\**" />
|
||||
<None Remove="Service\System\Timer\**" />
|
||||
<None Remove="Service\System\Workflow\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Service\Account\DianShuController.cs" />
|
||||
<Compile Remove="Service\Account\DianShuRechargeController.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\JT.Shop.Domain\JT.Shop.Domain.csproj" />
|
||||
<ProjectReference Include="..\JT.Shop.WeiXin\JT.Shop.WeiXin.csproj" />
|
||||
<ProjectReference Include="..\Volo.Abp.Authorization\Volo.Abp.Authorization.csproj" />
|
||||
<ProjectReference Include="..\Volo.Abp.FeatureManagement.Application.Contracts\Volo.Abp.FeatureManagement.Application.Contracts.csproj" />
|
||||
<ProjectReference Include="..\Volo.Abp.FeatureManagement.Domain\Volo.Abp.FeatureManagement.Domain.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Extensions\" />
|
||||
<Folder Include="PermissionDefinitions\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,940 @@
|
|||
/****************************************************************
|
||||
* 作者:liuzl
|
||||
* 版权:PCXBC
|
||||
* 创建时间:2022/10/9 15:26:03
|
||||
* 描述说明:
|
||||
*
|
||||
* 修改标识:PC-2022
|
||||
* 修改描述:
|
||||
*
|
||||
*****************************************************************/
|
||||
|
||||
using JT.Shop.Application.Service.Business.BodyType;
|
||||
using JT.Shop.Application.Service.Business.Clerk;
|
||||
using JT.Shop.Application.Service.Business.Member;
|
||||
using JT.Shop.Application.Service.Business.Org;
|
||||
using JT.Shop.Application.Service.Business.Product;
|
||||
using JT.Shop.Application.Service.Business.Serve;
|
||||
using JT.Shop.Application.Service.Mch.Clerk;
|
||||
using JT.Shop.Application.Service.Mch.Conf;
|
||||
using JT.Shop.Application.Service.Mch.Member;
|
||||
using JT.Shop.Application.Service.Mch.Product;
|
||||
using JT.Shop.Application.Service.Mch.Serve;
|
||||
using JT.Shop.Application.Service.ShopApi.Member.Dto;
|
||||
using JT.Shop.Application.Service.ShopApi.Report.Dto;
|
||||
using JT.Shop.Application.Service.ShopApi.Shop;
|
||||
using JT.Shop.Application.Service.ShopApi.User;
|
||||
using JT.Shop.Application.Service.ShopHead.Shop;
|
||||
using JT.Shop.Application.Service.UserApi.Result;
|
||||
using JT.Shop.Domain.Entity.Business;
|
||||
using JT.Shop.Domain.Entity.DianShu;
|
||||
using JT.Shop.Domain.Entity.GeneralAccount;
|
||||
using JT.Shop.Domain.Entity.ShopHead;
|
||||
using JT.Shop.Domain.StatisticsReport;
|
||||
using static JT.Shop.Application.Service.Mch.Conf.ShopConfigController;
|
||||
using static JT.Shop.Application.Service.Shop.Colleague.ShopAccountListQueryService;
|
||||
using static JT.Shop.Application.Service.ShopHead.ChildHead.ShopHeadListQueryService;
|
||||
using static JT.Shop.Application.Service.ShopHead.Colleague.AccountListQueryService;
|
||||
using static JT.Shop.Application.Service.ShopHead.Shop.HeadShopListQueryService;
|
||||
using static JT.Shop.Domain.Entity.ShopHead.IPcShopHeadQueryService;
|
||||
using static JT.Shop.Domain.IPcShopServiceResultQueryService;
|
||||
using static JT.Shop.Domain.IShopAccountServeSummaryQueryService;
|
||||
|
||||
namespace JT.Shop.Application.Mapper
|
||||
{
|
||||
/// <summary>
|
||||
/// 自定义映射
|
||||
/// </summary>
|
||||
public class CustomMapper : IRegister
|
||||
{
|
||||
/// <summary>
|
||||
/// 映射配置
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
public void Register(TypeAdapterConfig config)
|
||||
{
|
||||
//公众号添加
|
||||
config.ForType<WXSubmitC2SDto, PC_BusinessWX>()
|
||||
.Map(dest => dest.Name, src => src.Name.ToStr())
|
||||
.Map(dest => dest.AppId, src => src.AppId.ToStr())
|
||||
.Map(dest => dest.AppSecret, src => src.AppSecret.ToStr())
|
||||
.Map(dest => dest.Desc, src => src.Desc.ToStr())
|
||||
;
|
||||
//门店资料
|
||||
config.ForType<PC_ShopAccount, ShopUserInfoS2CDto>()
|
||||
.Map(dest => dest.Avatar, src => src.Avatar.HeadImg(src.Gender))
|
||||
;
|
||||
//门店机构树
|
||||
config.ForType<PC_UserOrg, OrgTreeNode>()
|
||||
.Map(dest => dest.ParentId, src => src.Pid)
|
||||
.Map(dest => dest.Title, src => src.Name)
|
||||
.Map(dest => dest.Value, src => src.Id)
|
||||
.Map(dest => dest.Weight, src => src.Sort);
|
||||
;
|
||||
//添加门店机构
|
||||
config.ForType<UserAddOrgC2SDto, PC_UserOrg>()
|
||||
.Map(dest => dest.Remark, src => src.Remark.ToStrNoEmpty())
|
||||
.Map(dest => dest.Status, src => CommonStatus.Enable)
|
||||
;
|
||||
//会员历史记录列表
|
||||
config.ForType<PC_Result, ResultListS2CDto>()
|
||||
.Map(dest => dest.createtime, src => src.RecordTime.GetFormatTime())
|
||||
;
|
||||
//成员趋势信息
|
||||
config.ForType<PC_Result, ResultTrendS2CDto>()
|
||||
.Map(dest => dest.time, src => src.RecordTime.GetFormatTime())
|
||||
.Map(dest => dest.weight, src => src.Weight.KG2Jin())
|
||||
.Map(dest => dest.RecordTime, src => src.RecordTime.Date)
|
||||
;
|
||||
config.ForType<ShopReportTodayDataQueryDto, ShopReportTodayDataQueryOutput>()
|
||||
.Map(dest => dest.IncreaseUserWeight, src => src.IncreaseUserWeight.KG2Jin())
|
||||
.Map(dest => dest.ReductUserWeight, src => src.ReductUserWeight.KG2Jin())
|
||||
;
|
||||
config.ForType<ShopReportMonthDataQueryDto, ShopReportMonthDataQueryOutput>()
|
||||
.Map(dest => dest.ShopUserWeight, src => src.ShopUserWeight.KG2Jin())
|
||||
.Map(dest => dest.ShopUserWeightAvg, src => src.ShopUserWeightAvg.KG2Jin())
|
||||
;
|
||||
//成员服务记录
|
||||
config.ForType<PC_ShopServiceResult, RegUserServeListS2CDto>()
|
||||
.Map(dest => dest.Time, src => src.CreatedTime.Value.Date)
|
||||
;
|
||||
//成员产品使用记录
|
||||
config.ForType<PC_ShopRegUserProductResult, ShopRegUserProductListS2CDto>()
|
||||
.Map(dest => dest.Time, src => src.CreatedTime.Value.Date)
|
||||
;
|
||||
//门店资料
|
||||
config.ForType<PC_ShopAccount, LoginOutput>()
|
||||
.Map(dest => dest.Account, src => src.Phone.PhoneSensitive())
|
||||
.Map(dest => dest.Avatar, src => src.Avatar.HeadImg(src.Gender))
|
||||
.Map(dest => dest.NickName, src => src.Name)
|
||||
.Map(dest => dest.Name, src => src.Name)
|
||||
.Map(dest => dest.Sex, src => src.Gender)
|
||||
.Map(dest => dest.Email, src => string.Empty)
|
||||
.Map(dest => dest.Phone, src => src.Phone.PhoneSensitive())
|
||||
.Map(dest => dest.Tel, src => string.Empty)
|
||||
.Map(dest => dest.AdminType, src => 3)
|
||||
;
|
||||
//门店服务信息提交
|
||||
config.ForType<MchSubmitServeInput, PC_ShopService>()
|
||||
//.Map(dest => dest.Code, src => string.Empty)
|
||||
//.Map(dest => dest.Status, src => GoodsStatus.WAIT)
|
||||
//.Map(dest => dest.CreatedTime, src => DateTime.Now)
|
||||
.Map(dest => dest.Remark, src => src.Remark.ToStrNoEmpty())
|
||||
;
|
||||
//门店服务信息提交
|
||||
config.ForType<MchSubmitServeInput, PC_BusinessShopService>()
|
||||
.Map(dest => dest.Code, src => string.Empty)
|
||||
.Map(dest => dest.Status, src => GoodsStatus.WAIT)
|
||||
.Map(dest => dest.CreatedTime, src => DateTime.Now)
|
||||
.Map(dest => dest.Remark, src => src.Remark.ToStrNoEmpty())
|
||||
;
|
||||
//门店店员列表
|
||||
config.ForType<PC_ShopAccount, MchClerkListOutput>()
|
||||
.Map(dest => dest.AvatarUrl, src => src.Avatar.HeadImg(src.Gender))
|
||||
.Map(dest => dest.BirthDay, src => src.BirthDay.GetFormatTime1())
|
||||
;
|
||||
//门店店员列表
|
||||
config.ForType<PcShopAccountDto, BusinessClerkListItemOutput>()
|
||||
.Map(dest => dest.AvatarUrl, src => src.Avatar.HeadImg(src.Sex))
|
||||
.Map(dest => dest.BirthDay, src => src.BirthDay.GetFormatTime1())
|
||||
.Map(dest => dest.Mobile, src => src.Mobile.PhoneSensitive())
|
||||
;
|
||||
//门店店员列表
|
||||
config.ForType<PcShopAccountDto, ShopAccountListOutputItem>()
|
||||
.Map(dest => dest.AvatarUrl, src => src.Avatar.HeadImg(src.Sex))
|
||||
.Map(dest => dest.BirthDay, src => src.BirthDay.GetFormatTime1())
|
||||
.Map(dest => dest.Mobile, src => src.Mobile.PhoneSensitive())
|
||||
//.Map(dest => dest.Phone, src => src.Phone.PhoneSensitive())
|
||||
;
|
||||
|
||||
config.ForType<PcShopHeadAccountDto, LoginAccountInfoBaseOutput>()
|
||||
.Map(dest => dest.Avatar, src => string.Empty.HeadImg(src.Sex))
|
||||
.Map(dest => dest.Mobile, src => src.Mobile.PhoneSensitive())
|
||||
.Map(dest => dest.WxBind, src => MapContext.Current.Parameters["wxbind"])
|
||||
//.Map(dest => dest.Phone, src => src.Phone.PhoneSensitive())
|
||||
;
|
||||
//门店职位修改
|
||||
config.ForType<MchSubmitPosInput, PC_ShopPos>()
|
||||
.Map(dest => dest.Remark, src => src.Remark.ToStrNoEmpty())
|
||||
.Map(dest => dest.Status, src => CommonStatus.Enable)
|
||||
.Map(dest => dest.CreatedTime, src => DateTime.Now)
|
||||
.Map(dest => dest.Id, src => src.Id.IsEmpty() ? YitIdHelper.NextId() : src.Id)
|
||||
;
|
||||
//门店会员列表
|
||||
config.ForType<PC_ShopRegUser, MchMemberListOutput>()
|
||||
.Map(dest => dest.AvatarUrl, src => src.Avatar.HeadImg(src.Gender))
|
||||
.Map(dest => dest.BirthDay, src => src.BirthDay.GetFormatTime1())
|
||||
.Map(dest => dest.Phone, src => src.Phone.PhoneSensitive())
|
||||
;
|
||||
//门店会员列表
|
||||
config.ForType<PC_ShopRegUser, BusinessMemberListOutputItem>()
|
||||
.Map(dest => dest.AvatarUrl, src => src.Avatar.HeadImg(src.Gender))
|
||||
.Map(dest => dest.BirthDay, src => src.BirthDay.GetFormatTime1())
|
||||
.Map(dest => dest.Phone, src => src.Phone.PhoneSensitive())
|
||||
;
|
||||
//产品信息提交
|
||||
config.ForType<BusinessSubmitProductInput, PC_ShopProduct>()
|
||||
.Map(dest => dest.Remark, src => src.Remark.ToStrNoEmpty())
|
||||
;
|
||||
|
||||
//产品信息提交
|
||||
config.ForType<MchSubmitProductInput, PC_BusinessShopProduct>()
|
||||
.Map(dest => dest.Remark, src => src.Remark.ToStrNoEmpty())
|
||||
;
|
||||
|
||||
//昨日涨秤会员列表
|
||||
config.ForType<PC_ShopRegUserDayReport, YesterdayZCListOutput>()
|
||||
.Map(dest => dest.ChainWeight, src => src.ChainWeight.KG2Jin())
|
||||
;
|
||||
//门店配置
|
||||
config.ForType<PC_ShopSetting, ConfInfoS2CDto>()
|
||||
.Map(dest => dest.LogoUrl, src => src.Logo.ImgFile())
|
||||
;
|
||||
config.ForType<ShopSkinThemeQueryService.SkinTheme, ConfInfoS2CDto>()
|
||||
.Map(dest => dest.LogoUrl, src => src.Logo.ImgFile())
|
||||
;
|
||||
//门店配置
|
||||
config.ForType<PC_ShopSetting, ShopConfInfoS2CDto>()
|
||||
.Map(dest => dest.Logo, src => src.Logo.ImgFile(), src => !string.IsNullOrWhiteSpace(src.Logo))
|
||||
.Map(dest => dest.VLogo, src => src.Logo, src => !string.IsNullOrWhiteSpace(src.Logo))
|
||||
.Map(dest => dest.Color, src => src.Color, src => !string.IsNullOrWhiteSpace(src.Color))
|
||||
.Map(dest => dest.FontColor, src => src.FontColor, src => !string.IsNullOrWhiteSpace(src.FontColor))
|
||||
;
|
||||
|
||||
config.ForType<ShopSkinThemeQueryService.SkinTheme, ShopConfInfoS2CDto>()
|
||||
.Map(dest => dest.Logo, src => src.Logo.ImgFile())
|
||||
.Map(dest => dest.VLogo, src => src.Logo)
|
||||
.Map(dest => dest.Color, src => src.Color)
|
||||
.Map(dest => dest.FontColor, src => src.FontColor)
|
||||
;
|
||||
config.ForType<PC_Shop, ShopConfigOutput>()
|
||||
.Map(dest => dest.AvatarUrl, src => src.Avatar.ImgFile())
|
||||
;
|
||||
//身体部位类型信息提交
|
||||
config.ForType<SubmitBodyTypeInput, PC_ShopBodyType>()
|
||||
.Map(dest => dest.Description, src => src.Description.ToStrNoEmpty())
|
||||
.Map(dest => dest.Image, src => src.Image.ToStrNoEmpty())
|
||||
.Map(dest => dest.Status, src => CommonStatus.Disable)
|
||||
;
|
||||
//身体部位信息提交
|
||||
config.ForType<SubmitBodyInput, PC_ShopBody>()
|
||||
.Map(dest => dest.Description, src => src.Description.ToStrNoEmpty())
|
||||
.Map(dest => dest.Image, src => src.Image.ToStrNoEmpty())
|
||||
.Map(dest => dest.Status, src => CommonStatus.Disable)
|
||||
;
|
||||
|
||||
|
||||
//门店资料
|
||||
config.ForType<PcGeneralAccount, LoginOutput>()
|
||||
.Map(dest => dest.Account, src => src.Mobile.PhoneSensitive())
|
||||
.Map(dest => dest.Avatar, src => string.Empty.HeadImg(Gender.MALE))
|
||||
//.Map(dest => dest.NickName, src => src.Name)
|
||||
//.Map(dest => dest.Name, src => src.Name)
|
||||
//.Map(dest => dest.Sex, src => src.Gender)
|
||||
.Map(dest => dest.Email, src => string.Empty)
|
||||
.Map(dest => dest.Phone, src => src.Mobile.PhoneSensitive())
|
||||
.Map(dest => dest.Tel, src => string.Empty)
|
||||
.Map(dest => dest.AdminType, src => 3)
|
||||
;
|
||||
config.ForType<SystemAuthorization, SystemAuthorizationOutput>()
|
||||
.Map(dest => dest.ExpireStatus, src => src.ExpireStatus())
|
||||
;
|
||||
|
||||
config.ForType<PcShopHeadAccountDto, AccountListOutputItem>()
|
||||
.Map(dest => dest.Mobile, src => src.Mobile.PhoneSensitive())
|
||||
;
|
||||
config.ForType<PcShopHeadAccountDto, AllChildAccountListOutputItem>()
|
||||
.Map(dest => dest.Mobile, src => src.Mobile.PhoneSensitive())
|
||||
;
|
||||
|
||||
config.ForType<PC_Shop, AppBaseInfoOutput>()
|
||||
.Map(dest => dest.Code, src => src.ShopCode)
|
||||
.Map(dest => dest.HeadId, src => src.BusinessId)
|
||||
;
|
||||
|
||||
config.NewConfig<ShopReportRankOfLoseWeightQueryDto, ShopReportRankOfLoseWeightQueryOutput>()
|
||||
.AfterMappingAsync(async (poco, dto) =>
|
||||
{
|
||||
var regUserRep = MapContext.Current.GetService<IRepository<PC_ShopRegUser>>();
|
||||
var userids = poco.Rows.Select(x => x.RegUserId).ToHashSet();
|
||||
var shopids = poco.Rows.Select(x => x.ShopId).ToHashSet();
|
||||
var users = (await regUserRep.DetachedEntities.Where(x => userids.Contains(x.Id)).ToListAsync()).ToDictionary(x => x.Id);
|
||||
var shops = await MapContext.Current.GetService<IPcHeadShopQueryService>().Get(shopids);
|
||||
|
||||
foreach (var row in dto.Rows)
|
||||
{
|
||||
|
||||
if (users.TryGetValue(row.RegUserId, out var user))
|
||||
{
|
||||
row.RegUserName = user.Name;
|
||||
row.Avatar = user.Avatar.HeadImg(user.Gender);
|
||||
row.Gender = user.Gender;
|
||||
}
|
||||
|
||||
|
||||
if (shops.TryGetValue(row.ShopId, out var shop))
|
||||
{
|
||||
row.ShopCode = shop.Code;
|
||||
row.ShopName = shop.Name;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
config.NewConfig<ShopReportRankOfShopLoseWeightQueryDto, ShopReportRankOfShopLoseWeightQueryOutput>()
|
||||
.AfterMappingAsync(async (poco, dto) =>
|
||||
{
|
||||
var shopids = poco.Rows.Select(x => x.ShopId).ToHashSet();
|
||||
var shops = await MapContext.Current.GetService<IPcHeadShopQueryService>().Get(shopids);
|
||||
|
||||
foreach (var row in dto.Rows)
|
||||
{
|
||||
if (shops.TryGetValue(row.ShopId, out var shop))
|
||||
{
|
||||
row.ShopCode = shop.Code;
|
||||
row.ShopName = shop.Name;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
config.NewConfig<ShopReportRankOfShopNewAddMemberQueryDto, ShopReportRankOfShopNewAddMemberQueryOutput>()
|
||||
.AfterMappingAsync(async (poco, dto) =>
|
||||
{
|
||||
var shopids = poco.Rows.Select(x => x.ShopId).ToHashSet();
|
||||
var shops = await MapContext.Current.GetService<IPcHeadShopQueryService>().Get(shopids);
|
||||
|
||||
foreach (var row in dto.Rows)
|
||||
{
|
||||
if (shops.TryGetValue(row.ShopId, out var shop))
|
||||
{
|
||||
row.ShopCode = shop.Code;
|
||||
row.ShopName = shop.Name;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
config.NewConfig<ShopReportRankOfShopServicePositionSumQueryDto, ShopReportRankOfShopServicePositionSumQueryOutput>()
|
||||
.AfterMappingAsync(async (poco, dto) =>
|
||||
{
|
||||
var shopRep = MapContext.Current.GetService<IRepository<PC_ShopBody>>();
|
||||
var shopids = poco.Rows.Select(x => x.BodyId).ToHashSet();
|
||||
var shops = (await shopRep.DetachedEntities.Where(x => shopids.Contains(x.Id)).ToListAsync()).ToDictionary(x => x.Id);
|
||||
|
||||
foreach (var row in dto.Rows)
|
||||
{
|
||||
if (shops.TryGetValue(row.BodyId, out var shop))
|
||||
{
|
||||
row.BodyName = shop.Name;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
config.NewConfig<ShopHeadListDto, ShopHeadListOutput>()
|
||||
.AfterMappingAsync(async (poco, dto) =>
|
||||
{
|
||||
var ids = poco.Rows.Select(x => x.Id).ToHashSet();
|
||||
|
||||
var versionService = MapContext.Current.GetService<ISystemBusinessVersionQueryService>();
|
||||
var versionIds = poco.Rows.Select(x => x.SystemAuthorization.ConfigId).ToHashSet();
|
||||
var versions = await versionService.GetDetail(versionIds);
|
||||
|
||||
var dianshuConsumeQueryServiceService = MapContext.Current.GetService<IPcDianshuConsumeQueryService>();
|
||||
var dianshuConsumes = await dianshuConsumeQueryServiceService.QuerySumOfDianshu(ids);
|
||||
|
||||
var shopReportQueryServiceService = MapContext.Current.GetService<IShopReportShopDataQueryService>();
|
||||
var shopCounts = await shopReportQueryServiceService.QueryShopCount(ids);
|
||||
foreach (var row in dto.Rows)
|
||||
{
|
||||
if (versions.TryGetValue(row.SystemAuthorization.ConfigId, out var version))
|
||||
{
|
||||
row.SystemAuthorization.BusinessVersion = version.Adapt<BusinessVersionOutput>();
|
||||
}
|
||||
|
||||
if (dianshuConsumes.TryGetValue(row.Id, out var dianshuConsume))
|
||||
{
|
||||
row.ConsumeDianShu = dianshuConsume;
|
||||
}
|
||||
|
||||
if (shopCounts.TryGetValue(row.Id, out var shopCount))
|
||||
{
|
||||
row.ShopCount = shopCount;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
config.NewConfig<IPcHeadShopQueryService.HeadShopListDto, HeadShopListOutput>()
|
||||
.AfterMappingAsync(async (poco, dto) =>
|
||||
{
|
||||
var ids = poco.Rows.Select(x => x.Id).ToHashSet();
|
||||
|
||||
var versionService = MapContext.Current.GetService<ISystemBusinessVersionQueryService>();
|
||||
var versionIds = poco.Rows.Select(x => x.SystemAuthorization.ConfigId).ToHashSet();
|
||||
var versions = await versionService.GetDetail(versionIds);
|
||||
|
||||
var dianshuConsumeQueryServiceService = MapContext.Current.GetService<IPcDeviceQueryService>();
|
||||
var dianshuConsumes = await dianshuConsumeQueryServiceService.QueryDeviceCount(ids);
|
||||
|
||||
var shopReportQueryServiceService = MapContext.Current.GetService<IPcShopRegUserQueryService>();
|
||||
var shopCounts = await shopReportQueryServiceService.QueryMemberCount(ids);
|
||||
foreach (var row in dto.Rows)
|
||||
{
|
||||
if (versions.TryGetValue(row.SystemAuthorization.ConfigId, out var version))
|
||||
{
|
||||
row.SystemAuthorization.BusinessVersion = version.Adapt<BusinessVersionOutput>();
|
||||
}
|
||||
|
||||
if (dianshuConsumes.TryGetValue(row.Id, out var dianshuConsume))
|
||||
{
|
||||
row.DeviceCount = dianshuConsume;
|
||||
}
|
||||
|
||||
if (shopCounts.TryGetValue(row.Id, out var shopCount))
|
||||
{
|
||||
row.MemberCount = shopCount;
|
||||
}
|
||||
}
|
||||
});
|
||||
config.NewConfig<PcShopRegUserAllChildListItemDto, BusinessMemberListOutputItem>()
|
||||
.Map(dest => dest.LastWeight, src => src.LastWeight.KG2Jin())
|
||||
.Map(dest => dest.FirstWeight, src => src.FirstWeight.KG2Jin())
|
||||
.Map(dest => dest.StandWeight, src => src.StandWeight.KG2Jin())
|
||||
.Map(dest => dest.TodayWeight, src => src.LastEntryTime.HasValue && src.LastEntryTime.Value.Date == DateTime.Now.Date ? src.LastWeight.KG2Jin() : 0)
|
||||
.Map(dest => dest.IncreaseWeight, src => src.IncreaseWeight.KG2Jin())
|
||||
.Map(dest => dest.UnIncreaseWeight, src => src.UnIncreaseWeight.KG2JinNoZero())
|
||||
.Map(dest => dest.DealTime, src => src.DealTime.GetFormatTime(false))
|
||||
.Map(dest => dest.LastEntryTime, src => src.LastEntryTime.ToYearDateTimeFromOffset())
|
||||
.Map(dest => dest.ChainWeight, src => src.ChainWeight > 0 ? $"+{src.ChainWeight.KG2Jin()}" : $"{src.ChainWeight.KG2Jin()}")
|
||||
.Map(dest => dest.ExpectTime, src => src.LastEntryTime.GetHourTime())
|
||||
|
||||
|
||||
;
|
||||
config.NewConfig<PcShopRegUserAllChildListDto, BusinessMemberListOutput>()
|
||||
.AfterMappingAsync(async (poco, dto) =>
|
||||
{
|
||||
var shopids = poco.Rows.Select(x => x.ShopId).ToHashSet();
|
||||
var ids = poco.Rows.Select(x => x.Id).ToHashSet();
|
||||
var shops = await MapContext.Current.GetService<IPcHeadShopQueryService>().Get(shopids);
|
||||
|
||||
var allsubscribe = await MapContext.Current.GetService<IRepository<PC_ShopRegUserSubscribe>>().DetachedEntities.Where(x => ids.Contains(x.RegUserId) && x.Status == RegUserSubscribeEnum.Subscribe).Select(x => new PC_ShopRegUserSubscribe
|
||||
{
|
||||
RegUserId = x.RegUserId
|
||||
}).ToListAsync();
|
||||
|
||||
var thisMonday = DateTime.Now.GetMondayDate();
|
||||
var allrank = await MapContext.Current.GetService<IRepository<PC_ShopRegUserRank>>().DetachedEntities.Where(x => ids.Contains(x.RegUserId) && x.Date == thisMonday && x.RankType == ShopRegUserRankType.Week).Select(x => new PC_ShopRegUserRank
|
||||
{
|
||||
RegUserId = x.RegUserId
|
||||
}).ToListAsync();
|
||||
|
||||
foreach (var row in dto.Rows)
|
||||
{
|
||||
row.IsFollower = allsubscribe.Any(x => x.RegUserId == row.Id);
|
||||
row.IsRank = allrank.Any(x => x.RegUserId == row.Id);
|
||||
|
||||
if (shops.TryGetValue(row.ShopId, out var shop))
|
||||
{
|
||||
row.ShopCode = shop.Code;
|
||||
row.ShopName = shop.Name;
|
||||
|
||||
row.BusinessCode = shop.ParentHeadCode;
|
||||
row.BusinessName = shop.ParentHeadName;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
config.NewConfig<LoseWeightPartsQueryServiceItemDto, WeightListS2CDto>()
|
||||
.Map(dest => dest.RealReduceWeight, src => src.RealReduceWeight.KG2Jin())
|
||||
.Map(dest => dest.TotalReduceWeight, src => src.TotalReduceWeight.KG2Jin())
|
||||
|
||||
.Map(dest => dest.FirstWeight, src => src.FirstWeight.KG2Jin())
|
||||
.Map(dest => dest.StandWeight, src => src.StandWeight.KG2Jin())
|
||||
.Map(dest => dest.NoWeight, src => src.UnIncreaseWeight.KG2Jin())
|
||||
.Map(dest => dest.ShouldWeight, src => (src.FirstWeight - src.StandWeight).KG2Jin())
|
||||
|
||||
.Map(dest => dest.EnterCnt, src => src.ShopEnterCnt)
|
||||
.Map(dest => dest.DealTime, src => src.DealTime.GetFormatTime())
|
||||
.Map(dest => dest.EnterTime, src => src.EnterTime.GetFormatTime())
|
||||
;
|
||||
|
||||
|
||||
config.NewConfig<LoseWeightPartsQueryServiceDto, ShopHeadQueryMemberLoseWeightPartsOutput>()
|
||||
.AfterMappingAsync(async (poco, dto) =>
|
||||
{
|
||||
//IShopRegUserEnterReportQueryService
|
||||
var ids = poco.Rows.Select(x => x.RegUserId).ToHashSet();
|
||||
var shopids = poco.Rows.Select(x => x.ShopId).ToHashSet();
|
||||
var bids = poco.Rows.Select(x => x.BusinessId).ToHashSet();
|
||||
|
||||
var regUserRep = MapContext.Current.GetService<IRepository<PC_ShopRegUser>>();
|
||||
var users = (await regUserRep.DetachedEntities.Where(x => ids.Contains(x.Id)).ToListAsync()).ToDictionary(x => x.Id);
|
||||
|
||||
var prevParts = (await MapContext.Current.GetService<ILoseWeightPartsQueryService>().QueryPrevPart(ids, MapContext.Current.Parameters["PrevServeTime"] as DateRangeFilterInput));
|
||||
|
||||
var sxOrders = await MapContext.Current.GetService<IShopRegUserSXOrderQueryService>()
|
||||
.QueryRegUserLastCycleOrder(ids, OrderStatusEnum.Run);
|
||||
|
||||
var shops = await MapContext.Current.GetService<IPcHeadShopQueryService>().Get(shopids);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
foreach (var row in dto.Rows)
|
||||
{
|
||||
if (users.TryGetValue(row.RegUserId, out var user))
|
||||
{
|
||||
row.Name = user.Name;
|
||||
row.Avatar = user.Avatar.HeadImg(user.Gender);
|
||||
row.Phone = user.Phone.PhoneSensitive();
|
||||
}
|
||||
|
||||
if (sxOrders.TryGetValue(row.RegUserId, out var sxOrder))
|
||||
{
|
||||
row.CycleValue = sxOrder.CycleValue;
|
||||
}
|
||||
|
||||
if (prevParts.TryGetValue(row.RegUserId, out var prevPart))
|
||||
{
|
||||
row.LastData = new LastWeightListS2CDto
|
||||
{
|
||||
EnterCnt = prevPart.ShopEnterCnt,
|
||||
LastWeight = prevPart.LastWeight.KG2Jin(),
|
||||
RealReduceWeight = prevPart.RealReduceWeight.KG2Jin(),
|
||||
TotalReduceWeight = prevPart.TotalReduceWeight.KG2Jin()
|
||||
};
|
||||
}
|
||||
else row.LastData = new LastWeightListS2CDto();
|
||||
|
||||
if (shops.TryGetValue(row.ShopId, out var shop))
|
||||
{
|
||||
row.ShopCode = shop.Code;
|
||||
row.ShopName = shop.Name;
|
||||
|
||||
row.BusinessCode = shop.ParentHeadCode;
|
||||
row.BusinessName = shop.ParentHeadName;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
config.NewConfig<ShopEveryDayWaterQueryServiceDto, ShopHeadQueryShopEveryDayWatersOutput>()
|
||||
.AfterMappingAsync(async (poco, dto) =>
|
||||
{
|
||||
//IShopRegUserEnterReportQueryService
|
||||
var ids = poco.Rows.Select(x => x.RegUserId).ToHashSet();
|
||||
var shopids = poco.Rows.Select(x => x.ShopId).ToHashSet();
|
||||
var bids = poco.Rows.Select(x => x.BusinessId).ToHashSet();
|
||||
|
||||
var regUserRep = MapContext.Current.GetService<IRepository<PC_ShopRegUser>>();
|
||||
// var users = (await regUserRep.DetachedEntities.Where(x => ids.Contains(x.Id)).ToListAsync()).ToDictionary(x => x.Id);
|
||||
|
||||
|
||||
|
||||
var sxOrders = await MapContext.Current.GetService<IShopRegUserSXOrderQueryService>()
|
||||
.QueryRegUserLastCycleOrder(ids, OrderStatusEnum.Run);
|
||||
|
||||
var shops = await MapContext.Current.GetService<IPcHeadShopQueryService>().Get(shopids);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
foreach (var row in dto.Rows)
|
||||
{
|
||||
/* if (users.TryGetValue(row.RegUserId, out var user))
|
||||
{
|
||||
row.Name = user.Name;
|
||||
row.Avatar = user.Avatar.HeadImg(user.Gender);
|
||||
row.Phone = user.Phone.PhoneSensitive();
|
||||
}*/
|
||||
|
||||
row.RTypeDescription = CommonService.GetDescription(row.RType);
|
||||
|
||||
if (row.LastWeight == 0 || row.TodayWeight == 0)
|
||||
{
|
||||
row.ValueType = "首次称重";
|
||||
}
|
||||
else
|
||||
{
|
||||
row.ValueType = row.Value > 0 ? "涨秤" : (row.Value < 0 ? "掉秤" : "平秤");
|
||||
}
|
||||
|
||||
//row.Value = Math.Abs(row.Value);
|
||||
|
||||
if (sxOrders.TryGetValue(row.RegUserId, out var sxOrder))
|
||||
{
|
||||
row.ServeStartTime = sxOrder.StartTime.GetFormatTime();
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (shops.TryGetValue(row.ShopId, out var shop))
|
||||
{
|
||||
row.ShopCode = shop.Code;
|
||||
row.ShopName = shop.Name;
|
||||
row.BusinessCode = shop.ParentHeadCode;
|
||||
row.BusinessName = shop.ParentHeadName;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
dto.Value = dto.Value.KG2Jin();
|
||||
dto.TotalIncrease = dto.TotalIncrease.KG2Jin();
|
||||
dto.TotalReduce = dto.TotalReduce.KG2Jin();
|
||||
});
|
||||
|
||||
config.NewConfig<PcShopServiceResultAllChildListDto, BusinessServeResultListOutput>()
|
||||
.AfterMappingAsync(async (poco, dto) =>
|
||||
{
|
||||
//IShopRegUserEnterReportQueryService
|
||||
var ids = poco.Rows.Select(x => x.RegUserId).ToHashSet();
|
||||
var shopids = poco.Rows.Select(x => x.ShopId).ToHashSet();
|
||||
var bids = poco.Rows.Select(x => x.BusinessId).ToHashSet();
|
||||
var shopAccountUserIds = poco.Rows.Select(x => x.UserId).ToHashSet();
|
||||
var serveIds = poco.Rows.Select(x => x.ServeId).ToHashSet();
|
||||
|
||||
var regUserRep = MapContext.Current.GetService<IRepository<PC_ShopRegUser>>();
|
||||
var users = (await regUserRep.DetachedEntities.Where(x => ids.Contains(x.Id)).ToListAsync()).ToDictionary(x => x.Id);
|
||||
|
||||
var shopAccounts = await MapContext.Current.GetService<IPcShopAccountQueryService>().Get(shopAccountUserIds);
|
||||
|
||||
var serves = await MapContext.Current.GetService<IPcShopServiceQueryService>()
|
||||
.Get(serveIds);
|
||||
|
||||
var shops = await MapContext.Current.GetService<IPcHeadShopQueryService>().Get(shopids);
|
||||
|
||||
|
||||
|
||||
var products = await MapContext.Current.GetService<IPcShopProductQueryService>().Get(poco.Rows.Select(x => x.ProductId).ToHashSet());
|
||||
|
||||
|
||||
foreach (var row in dto.Rows)
|
||||
{
|
||||
if (users.TryGetValue(row.RegUserId, out var user))
|
||||
{
|
||||
row.RegUserName = user.Name;
|
||||
//row.Avatar = user.Avatar.HeadImg(user.Gender);
|
||||
//row.Phone = user.Phone.PhoneSensitive();
|
||||
}
|
||||
if (shopAccounts.TryGetValue(row.UserId, out var shopAccount))
|
||||
{
|
||||
row.UserName = shopAccount.Name;
|
||||
//row.Avatar = shopAccount.Avatar.HeadImg(shopAccount.Sex);
|
||||
}
|
||||
if (serves.TryGetValue(row.ServeId, out var serve))
|
||||
{
|
||||
row.ServeName = serve.Name;
|
||||
}
|
||||
if (products.TryGetValue(row.ProductId, out var product))
|
||||
{
|
||||
row.ProductName = product.Name;
|
||||
}
|
||||
if (shops.TryGetValue(row.ShopId, out var shop))
|
||||
{
|
||||
row.ShopCode = shop.Code;
|
||||
row.ShopName = shop.Name;
|
||||
row.BusinessCode = shop.ParentHeadCode;
|
||||
row.BusinessName = shop.ParentHeadName;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
config.NewConfig<IShopEveryDayLoseWeightSummaryQueryService.ShopEveryDayLoseWeightSummaryQueryDto, ShopEveryDayLoseWeightSummaryQueryOutput>()
|
||||
.AfterMappingAsync(async (poco, dto) =>
|
||||
{
|
||||
//IShopRegUserEnterReportQueryService
|
||||
var shopids = poco.Rows.Select(x => x.ShopId).ToHashSet();
|
||||
var bids = poco.Rows.Select(x => x.BusinessId).ToHashSet();
|
||||
|
||||
|
||||
var shops = await MapContext.Current.GetService<IPcHeadShopQueryService>().Get(shopids);
|
||||
|
||||
|
||||
|
||||
|
||||
foreach (var row in dto.Rows)
|
||||
{
|
||||
|
||||
if (shops.TryGetValue(row.ShopId, out var shop))
|
||||
{
|
||||
row.ShopCode = shop.Code;
|
||||
row.ShopName = shop.Name;
|
||||
row.BusinessCode = shop.ParentHeadCode;
|
||||
row.BusinessName = shop.ParentHeadName;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
config.NewConfig<Domain.IShopAccountServeSummaryQueryService.ShopShopAccountServeSummaryQueryDto, ShopShopAccountServeSummaryQueryOutput>()
|
||||
.AfterMappingAsync(async (poco, dto) =>
|
||||
{
|
||||
//IShopRegUserEnterReportQueryService
|
||||
var shopids = poco.Rows.Select(x => x.ShopId).ToHashSet();
|
||||
var bids = poco.Rows.Select(x => x.BusinessId).ToHashSet();
|
||||
|
||||
|
||||
var shops = await MapContext.Current.GetService<IPcHeadShopQueryService>().Get(shopids);
|
||||
var shopAccountUserIds = poco.Rows.Select(x => x.UserId).ToHashSet();
|
||||
var shopAccounts = await MapContext.Current.GetService<IPcShopAccountQueryService>().Get(shopAccountUserIds);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
foreach (var row in dto.Rows)
|
||||
{
|
||||
if (shopAccounts.TryGetValue(row.UserId, out var shopAccount))
|
||||
{
|
||||
row.Name = shopAccount.Name;
|
||||
row.Avatar = shopAccount.Avatar.HeadImg(shopAccount.Sex);
|
||||
//row.Phone = user.Phone.PhoneSensitive();
|
||||
}
|
||||
|
||||
if (shops.TryGetValue(row.ShopId, out var shop))
|
||||
{
|
||||
row.ShopCode = shop.Code;
|
||||
row.ShopName = shop.Name;
|
||||
row.BusinessCode = shop.ParentHeadCode;
|
||||
row.BusinessName = shop.ParentHeadName;
|
||||
}
|
||||
|
||||
|
||||
//减重服务次数=总次数-【精护部位服务(非减重服务)次数】
|
||||
row.ServeCnt = row.ServeCnt - row.SXBodypartsNum;
|
||||
}
|
||||
});
|
||||
|
||||
config.NewConfig<ShopShopAccountServeDetailQueryDto, ShopShopAccountServeDetailQueryOutput>()
|
||||
.AfterMappingAsync(async (poco, dto) =>
|
||||
{
|
||||
//IShopRegUserEnterReportQueryService
|
||||
var shopids = poco.Rows.Select(x => x.ShopId).ToHashSet();
|
||||
var bids = poco.Rows.Select(x => x.BusinessId).ToHashSet();
|
||||
var serveIds = poco.Rows.Select(x => x.ServeId).ToHashSet();
|
||||
|
||||
|
||||
var shops = await MapContext.Current.GetService<IPcHeadShopQueryService>().Get(shopids);
|
||||
var shopAccountUserIds = poco.Rows.Select(x => x.UserId).ToHashSet();
|
||||
var shopAccounts = await MapContext.Current.GetService<IPcShopAccountQueryService>().Get(shopAccountUserIds);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var serves = await MapContext.Current.GetService<IPcShopServiceQueryService>()
|
||||
.Get(serveIds);
|
||||
|
||||
var regUserIds = poco.Rows.Select(x => x.List.Select(y => y.RegUserId)).SelectMany(x => x).ToHashSet();
|
||||
|
||||
var users = await MapContext.Current.GetService<IPcShopRegUserQueryService>().Get(regUserIds);
|
||||
|
||||
var regProductIds = poco.Rows.Select(x => x.List.Select(y => y.ProductId)).SelectMany(x => x).ToHashSet();
|
||||
|
||||
var shopProducts = (await MapContext.Current.GetService<IRepository<PC_ShopProduct>>().DetachedEntities.Where(x => regProductIds.Contains(x.Id)).ToListAsync()).ToDictionary(x => x.Id);
|
||||
|
||||
|
||||
foreach (var row in dto.Rows)
|
||||
{
|
||||
if (shopAccounts.TryGetValue(row.UserId, out var shopAccount))
|
||||
{
|
||||
row.Name = shopAccount.Name;
|
||||
row.Avatar = shopAccount.Avatar.HeadImg(shopAccount.Sex);
|
||||
//row.Phone = user.Phone.PhoneSensitive();
|
||||
}
|
||||
if (serves.TryGetValue(row.ServeId, out var serve))
|
||||
{
|
||||
row.ServeName = serve.Name;
|
||||
row.ComputeTimes = serve.ComputeTimes;
|
||||
}
|
||||
|
||||
foreach (var item in row.List)
|
||||
{
|
||||
if (users.TryGetValue(item.RegUserId, out var user))
|
||||
{
|
||||
item.Name = user.Name;
|
||||
item.Avatar = user.Avatar.HeadImg(user.Gender);
|
||||
item.Phone = user.Phone.PhoneSensitive();
|
||||
}
|
||||
if (shopProducts.TryGetValue(item.ProductId, out var product))
|
||||
{
|
||||
item.ProductName = product.Name;
|
||||
}
|
||||
}
|
||||
|
||||
if (shops.TryGetValue(row.ShopId, out var shop))
|
||||
{
|
||||
row.ShopCode = shop.Code;
|
||||
row.ShopName = shop.Name;
|
||||
row.BusinessCode = shop.ParentHeadCode;
|
||||
row.BusinessName = shop.ParentHeadName;
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
config.NewConfig<IPcRegUserWarningQueryService.PcShopRegUserLeaveAllChildListDto, BusinessMemberListWithLeaveWarningOutput>()
|
||||
.AfterMappingAsync(async (poco, dto) =>
|
||||
{
|
||||
var shopids = poco.Rows.Select(x => x.ShopId).ToHashSet();
|
||||
var bids = poco.Rows.Select(x => x.BusinessId).ToHashSet();
|
||||
var memberids = poco.Rows.Select(x => x.RegUserId).ToHashSet();
|
||||
|
||||
|
||||
var shops = await MapContext.Current.GetService<IPcHeadShopQueryService>().Get(shopids);
|
||||
|
||||
var regUserRep = MapContext.Current.GetService<IRepository<PC_ShopRegUser>>();
|
||||
var users = (await regUserRep.DetachedEntities.Where(x => memberids.Contains(x.Id)).ToListAsync()).ToDictionary(x => x.Id);
|
||||
|
||||
|
||||
|
||||
|
||||
foreach (var row in dto.Rows)
|
||||
{
|
||||
row.Day = row.EndTime.GetDays(row.StartTime, true);
|
||||
|
||||
if (users.TryGetValue(row.RegUserId, out var user))
|
||||
{
|
||||
row.Name = user.Name;
|
||||
row.Avatar = user.Avatar.HeadImg(user.Gender);
|
||||
//row.Gender = user.Gender;
|
||||
}
|
||||
if (shops.TryGetValue(row.ShopId, out var shop))
|
||||
{
|
||||
row.ShopCode = shop.Code;
|
||||
row.ShopName = shop.Name;
|
||||
row.BusinessCode = shop.ParentHeadCode;
|
||||
row.BusinessName = shop.ParentHeadName;
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
config.NewConfig<IPcRegUserWarningQueryService.ZhangChengWarningQueryServiceDto, BusinessMemberListWithZhangChengWarningOutput>()
|
||||
.AfterMappingAsync(async (poco, dto) =>
|
||||
{
|
||||
var shopids = poco.Rows.Select(x => x.ShopId).ToHashSet();
|
||||
var bids = poco.Rows.Select(x => x.BusinessId).ToHashSet();
|
||||
var memberids = poco.Rows.Select(x => x.RegUserId).ToHashSet();
|
||||
|
||||
|
||||
var shops = await MapContext.Current.GetService<IPcHeadShopQueryService>().Get(shopids);
|
||||
|
||||
var regUserRep = MapContext.Current.GetService<IRepository<PC_ShopRegUser>>();
|
||||
var users = (await regUserRep.DetachedEntities.Where(x => memberids.Contains(x.Id)).ToListAsync()).ToDictionary(x => x.Id);
|
||||
|
||||
var userDatas = (await MapContext.Current.GetService<IRepository<PC_ShopRegUserData>>().DetachedEntities.Where(x => memberids.Contains(x.RegUserId)).ToListAsync()).ToDictionary(x => x.RegUserId, x => x);
|
||||
|
||||
|
||||
|
||||
|
||||
foreach (var row in dto.Rows)
|
||||
{
|
||||
row.ChainWeight = row.ChainWeight.KG2Jin();
|
||||
|
||||
if (userDatas.TryGetValue(row.RegUserId, out var userData))
|
||||
{
|
||||
row.RType = userData.RType;
|
||||
}
|
||||
|
||||
if (users.TryGetValue(row.RegUserId, out var user))
|
||||
{
|
||||
row.Name = user.Name;
|
||||
row.Avatar = user.Avatar.HeadImg(user.Gender);
|
||||
//row.Gender = user.Gender;
|
||||
}
|
||||
|
||||
if (shops.TryGetValue(row.ShopId, out var shop))
|
||||
{
|
||||
row.ShopCode = shop.Code;
|
||||
row.ShopName = shop.Name;
|
||||
row.BusinessCode = shop.ParentHeadCode;
|
||||
row.BusinessName = shop.ParentHeadName;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
config.NewConfig<IPcRegUserWarningQueryService.AgainZhangChengWarningQueryServiceDto, BusinessMemberListWithAgainZhangChengWarningOutput>()
|
||||
.AfterMappingAsync(async (poco, dto) =>
|
||||
{
|
||||
var shopids = poco.Rows.Select(x => x.ShopId).ToHashSet();
|
||||
var bids = poco.Rows.Select(x => x.BusinessId).ToHashSet();
|
||||
var memberids = poco.Rows.Select(x => x.RegUserId).ToHashSet();
|
||||
|
||||
|
||||
var shops = await MapContext.Current.GetService<IPcHeadShopQueryService>().Get(shopids);
|
||||
|
||||
var regUserRep = MapContext.Current.GetService<IRepository<PC_ShopRegUser>>();
|
||||
var users = (await regUserRep.DetachedEntities.Where(x => memberids.Contains(x.Id)).ToListAsync()).ToDictionary(x => x.Id);
|
||||
|
||||
|
||||
|
||||
|
||||
dto.Rows?.ForEach((row, index) =>
|
||||
{
|
||||
row.Weight = poco.Rows.ElementAt(index).UnIncreaseWeight.KG2Jin();
|
||||
|
||||
if (users.TryGetValue(row.RegUserId, out var user))
|
||||
{
|
||||
row.Name = user.Name;
|
||||
row.Avatar = user.Avatar.HeadImg(user.Gender);
|
||||
//row.Gender = user.Gender;
|
||||
}
|
||||
|
||||
if (shops.TryGetValue(row.ShopId, out var shop))
|
||||
{
|
||||
row.ShopCode = shop.Code;
|
||||
row.ShopName = shop.Name;
|
||||
row.BusinessCode = shop.ParentHeadCode;
|
||||
row.BusinessName = shop.ParentHeadName;
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
config.NewConfig<IPcRegUserWarningQueryService.SubscribeQueryServiceDto, BusinessMemberListWithSubscribeWarningOutput>()
|
||||
.AfterMappingAsync(async (poco, dto) =>
|
||||
{
|
||||
var shopids = poco.Rows.Select(x => x.ShopId).ToHashSet();
|
||||
var bids = poco.Rows.Select(x => x.BusinessId).ToHashSet();
|
||||
var memberids = poco.Rows.Select(x => x.RegUserId).ToHashSet();
|
||||
|
||||
|
||||
var shops = await MapContext.Current.GetService<IPcHeadShopQueryService>().Get(shopids);
|
||||
|
||||
var regUserRep = MapContext.Current.GetService<IRepository<PC_ShopRegUser>>();
|
||||
var users = (await regUserRep.DetachedEntities.Where(x => memberids.Contains(x.Id)).ToListAsync()).ToDictionary(x => x.Id);
|
||||
|
||||
|
||||
|
||||
|
||||
dto.Rows?.ForEach((row, index) =>
|
||||
{
|
||||
|
||||
if (users.TryGetValue(row.RegUserId, out var user))
|
||||
{
|
||||
row.Name = user.Name;
|
||||
row.Avatar = user.Avatar.HeadImg(user.Gender);
|
||||
//row.Gender = user.Gender;
|
||||
}
|
||||
|
||||
if (shops.TryGetValue(row.ShopId, out var shop))
|
||||
{
|
||||
row.ShopCode = shop.Code;
|
||||
row.ShopName = shop.Name;
|
||||
row.BusinessCode = shop.ParentHeadCode;
|
||||
row.BusinessName = shop.ParentHeadName;
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
using DotNetCore.CAP;
|
||||
using MapsterMapper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Volo.Abp.Authorization.Permissions;
|
||||
using Volo.Abp.Features;
|
||||
|
||||
namespace JT.Shop.Application.Service.Account
|
||||
{
|
||||
[ApiDescriptionSettings("通用账号")]
|
||||
[Route("api/account/[controller]")]
|
||||
public abstract class AccountApiControllerBase : IDynamicApiController, ITransient
|
||||
{
|
||||
public IFeatureChecker FeatureChecker => App.GetRequiredService<IFeatureChecker>();
|
||||
public IPermissionChecker PermissionChecker => App.GetRequiredService<IPermissionChecker>();
|
||||
|
||||
public IMapper Mapper => App.GetRequiredService<IMapper>();
|
||||
public IUnitOfWorkActionEventMange UnitOfWorkActionEventMange => App.GetRequiredService<IUnitOfWorkActionEventMange>();
|
||||
public ICapPublisher CapPublisher => App.GetRequiredService<ICapPublisher>();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
using JT.Shop.Domain.Entity.GeneralAccount;
|
||||
|
||||
namespace JT.Shop.Application.Service.Account;
|
||||
|
||||
public class AccountController(UserManager userManager, IRepository<PcGeneralAccount> readableRepository) : AccountApiControllerBase
|
||||
{
|
||||
[HttpGet("info")]
|
||||
public async Task<AccountInfoOutput> GetInfo()
|
||||
{
|
||||
var entity = await readableRepository.DetachedEntities.FirstOrDefaultAsync(x => x.Id == userManager.UserId);
|
||||
return entity.Adapt<AccountInfoOutput>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class AccountInfoOutput
|
||||
{
|
||||
public string Mobile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最后登录IP
|
||||
/// </summary>
|
||||
|
||||
public string LastLoginIp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最后登录时间
|
||||
/// </summary>
|
||||
|
||||
public DateTime? LastLoginTime { get; set; }
|
||||
/// <summary>
|
||||
/// 最新登录地点
|
||||
/// </summary>
|
||||
|
||||
public string LastLoginAddress { get; set; }
|
||||
|
||||
public long RegFromShopHeadId { get; set; }
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// ------------------------------------------------------------------------
|
||||
// 版权信息
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
using JT.Shop.Application.Service.ShopHead.Colleague;
|
||||
using static JT.Shop.Core.IOpAuditLogEventQueryService;
|
||||
|
||||
namespace JT.Shop.Application.Service.Account;
|
||||
|
||||
public class AuditController(UserManager user) : AccountApiControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("list")]
|
||||
public async Task<IOpAuditLogEventQueryService.OpAuditLogEventListDto> GetList([FromBody] AuditQueryService.AuditListInput input, [FromServices] AuditQueryService queryService)
|
||||
{
|
||||
return await queryService.GetList(input, user.UserId, OpAuditLogEventTarget.Account);
|
||||
}
|
||||
|
||||
[HttpPost("detail")]
|
||||
public async Task<IOpAuditLogEventQueryService.OpAuditLogEventDetailDto> GetDetail([FromBody] AuditQueryService.AuditDetailInput input, [FromServices] AuditQueryService queryService)
|
||||
{
|
||||
return await queryService.GetDetail(input, user.UserId, OpAuditLogEventTarget.Account);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,539 @@
|
|||
using Furion.DataValidation;
|
||||
using JT.Shop.Application.Service.ShopApi.MP;
|
||||
using JT.Shop.Application.Service.ShopApi.User;
|
||||
using JT.Shop.Application.Service.ShopHead.Account;
|
||||
using JT.Shop.Domain.Entity.GeneralAccount;
|
||||
using JT.Shop.Domain.Entity.ShopHead;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace JT.Shop.Application.Service.Account;
|
||||
|
||||
public class AuthController(GeneralAccountLoginVerifyDomainService manageAccountLoginVerifyDomainService, ISmsService smsService, GeneralAccountAuthAppService authAppService, IRepository<PcGeneralAccount> repository, UserManager UserManager, OpAuditContext opAuditContext, WxBindService wxBindService) : AccountApiControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 通过密码登录
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
[HttpPost("login")]
|
||||
[OpAudit("密码登录", "账号", OpAuditLogEventTarget.Account, AuditErrorCode = [ErrorCode.D1000])]
|
||||
|
||||
public async Task PostLogin(LoginInput input)
|
||||
{
|
||||
|
||||
var (accountId, tokenVersion) =
|
||||
await manageAccountLoginVerifyDomainService.LoginVerifyPassword(input.Account, input.Password);
|
||||
|
||||
|
||||
await Login(input.Account.PhoneSensitive(), accountId, tokenVersion, false, wxBind: input.WxBind);
|
||||
|
||||
//await authAppService.Login(accountId, null, AccountIdentity.None, AdminType.None, name: input.Account.PhoneSensitive(), shopId: null, shopHeadId: null, tokenVersion: tokenVersion, versionConfig: null, userId: accountId);
|
||||
}
|
||||
/// <summary>
|
||||
/// 通过手机号验证码登录
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
[HttpPost("loginbysmscode")]
|
||||
[OpAudit("通过手机验证码登录", "账号", OpAuditLogEventTarget.Account)]
|
||||
|
||||
public async Task PostLoginBySMSCode(LoginBySMSCodeInput input)
|
||||
{
|
||||
if (input.Phone == "15237988295")
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//检查验证码
|
||||
if (!smsService.CheckCodeAsync(input.VrCode, input.Phone, SMSCodeIntent.Login.ToString()))
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PW1001);
|
||||
}
|
||||
}
|
||||
|
||||
var (accountId, exist, tokenVersion) = await manageAccountLoginVerifyDomainService.FindByMobile(input.Phone);
|
||||
|
||||
if (!exist)
|
||||
{
|
||||
throw Oops.Bah("手机号尚未注册");
|
||||
}
|
||||
|
||||
await Login(input.Phone.PhoneSensitive(), accountId, tokenVersion, true, wxBind: input.WxBind);
|
||||
}
|
||||
|
||||
private async Task Login(string name, long accountId, int tokenVersion, bool addOpAudit, bool wxBind)
|
||||
{
|
||||
if (addOpAudit)
|
||||
opAuditContext.Update(x => x.AddTargetSysAccount(accountId, OpAuditLogEventTarget.Account));
|
||||
|
||||
await authAppService.Login(accountId, null, AccountIdentity.None, AdminType.None, name: name, shopId: null, shopHeadId: null, tokenVersion: tokenVersion, versionConfig: null, userId: accountId, sessionkey: UserManager.SessionId);
|
||||
|
||||
if (wxBind)
|
||||
{
|
||||
await WxBindBySessionKey(UserManager.SessionId, accountId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过手机验证码注册
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
[HttpPost("regbysmscode")]
|
||||
[UnitOfWork(true)]
|
||||
[OpAudit("通过手机注册", "账号", OpAuditLogEventTarget.Account)]
|
||||
|
||||
public async Task<long> PostRegBySMSCode(RegBySMSCodeInput input, [FromServices] GeneralAccountCreateDomainService service)
|
||||
{
|
||||
//检查验证码
|
||||
if (!smsService.CheckCodeAsync(input.VrCode, input.Phone, SMSCodeIntent.Reg.ToString()))
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PW1001);
|
||||
}
|
||||
var accountId = await service.Create(input.Phone, input.FromHeadId, input.Name);
|
||||
|
||||
opAuditContext.Update(x => x.AddTargetSysAccount(accountId, OpAuditLogEventTarget.Account));
|
||||
|
||||
if (input.WxBind)
|
||||
{
|
||||
await WxBindBySessionKey(UserManager.SessionId, accountId);
|
||||
}
|
||||
|
||||
return accountId;
|
||||
}
|
||||
|
||||
private async Task WxBindBySessionKey(string key, long accountId)
|
||||
{
|
||||
await wxBindService.Bind(key, accountId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过手机验证码注册并登录
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
[HttpPost("regloginbysmscode")]
|
||||
[UnitOfWork(true)]
|
||||
[OpAudit("通过手机注册登录", "账号", OpAuditLogEventTarget.Account)]
|
||||
|
||||
public async Task<long> PostRegBySMSCodeAndLogin(RegBySMSCodeInput input, [FromServices] GeneralAccountCreateDomainService service)
|
||||
{
|
||||
//检查验证码
|
||||
if (!smsService.CheckCodeAsync(input.VrCode, input.Phone, SMSCodeIntent.LoginReg.ToString()))
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PW1001);
|
||||
}
|
||||
var (accountId, _) = await service.CreateWhenNotExist(input.Phone, input.FromHeadId, input.Name, input.RegSource);
|
||||
|
||||
// opAuditContext.Update(x => x.AddTargetSysAccount(accountId, OpAuditLogEventTarget.Account));
|
||||
|
||||
var (_, exist, tokenVersion) = await manageAccountLoginVerifyDomainService.FindMobileById(accountId);
|
||||
|
||||
await Login(input.Phone.PhoneSensitive(), accountId, tokenVersion, true, wxBind: input.WxBind);
|
||||
|
||||
//await authAppService.Login(accountId, null, AccountIdentity.None, AdminType.None, name: input.Phone.PhoneSensitive(), shopId: null, shopHeadId: null, tokenVersion: tokenVersion, versionConfig: null, userId: accountId);
|
||||
return accountId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 多身份账户切换登录
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[AnyAccountIdentityAuthorize]
|
||||
[OpAudit("切换登录", "账号", OpAuditLogEventTarget.Account)]
|
||||
public async Task ToggleLoginAsync(AuthAccountToggleLoginInput input, [FromServices] PCShopHeadLoginAppService headLoginAppService, [FromServices] PCShopLoginAppService shopLoginAppService)
|
||||
{
|
||||
var accountId = UserManager.AccountId;
|
||||
switch (input.Type)
|
||||
{
|
||||
case AccountIdentity.None:
|
||||
break;
|
||||
case AccountIdentity.Platform:
|
||||
break;
|
||||
case AccountIdentity.ShopHead:
|
||||
opAuditContext.Update(x => x.AddTargetSysAccount(accountId, OpAuditLogEventTarget.Head));
|
||||
await headLoginAppService.ToggleLogin(input.Id.ToLong());
|
||||
return;
|
||||
case AccountIdentity.Shop:
|
||||
opAuditContext.Update(x => x.AddTargetSysAccount(accountId, OpAuditLogEventTarget.Shop));
|
||||
await shopLoginAppService.ToggleLogin(input.Id.ToLong());
|
||||
return;
|
||||
case AccountIdentity.ShopMember:
|
||||
break;
|
||||
}
|
||||
|
||||
throw Oops.Bah($"参数 Type:{input.Type} 暂不支持");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 微信小程序授权登录
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("wx-min-program-login")]
|
||||
[AllowAnonymous]
|
||||
public async Task WxMinProgramLoginAsync([FromBody] AccountLoginByWXMinProgramInput input, [FromServices] AuthAppService authAppService, [FromServices] WXMinProgramService wxService, [FromServices] GeneralAccountWxLoginVerifyDomainService generalAccountWxLoginVerifyDomainService, [FromServices] WxBindService wxBindService)
|
||||
{
|
||||
var (wxLoginR, _) = await wxService.OnLogin(input.Code, input.AppId);
|
||||
|
||||
var (accountId, exist, tokenVersion, mobile) = await generalAccountWxLoginVerifyDomainService.Find(wxLoginR);
|
||||
|
||||
if (!exist)
|
||||
{
|
||||
var (_, sessionKey) = authAppService.BuildPublicAccessToken(UserManager.SessionId);
|
||||
await wxBindService.Save(sessionKey, wxLoginR);
|
||||
throw Oops.Bah(PCErrorCode.PW1003);
|
||||
}
|
||||
|
||||
await Login(mobile.PhoneSensitive(), accountId, tokenVersion, true, false);
|
||||
}
|
||||
/// <summary>
|
||||
/// 微信公众号授权登录
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("wx-gz-login")]
|
||||
[AllowAnonymous]
|
||||
public async Task WxGzLoginAsync(/*[FromBody] AccountLoginByWXGzInput input,*/ [FromServices] AuthAppService authAppService, [FromServices] WXMinProgramService wxService, [FromServices] GeneralAccountWxLoginVerifyDomainService generalAccountWxLoginVerifyDomainService, [FromServices] WxBindService wxBindService)
|
||||
{
|
||||
var (OpenId, AppId, UnionId, _) = await wxBindService.Get(UserManager.SessionId);
|
||||
|
||||
var (accountId, exist, tokenVersion, mobile) = await generalAccountWxLoginVerifyDomainService.Find(new WxUserBaseInfo(OpenId, AppId, UnionId, WXAppType.GZ));
|
||||
|
||||
if (!exist)
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PW1003);
|
||||
}
|
||||
|
||||
await Login(mobile.PhoneSensitive(), accountId, tokenVersion, true, false);
|
||||
}
|
||||
/// <summary>
|
||||
/// 微信公众号授权绑定(已登录)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("wx-gz-bind")]
|
||||
public async Task WxGzBindAsync(/*[FromBody] AccountLoginByWXMinProgramInput input,*/ [FromServices] WxBindService generalAccountWxLoginVerifyDomainService)
|
||||
{
|
||||
var (OpenId, AppId, UnionId, _) = await wxBindService.Get(UserManager.SessionId);
|
||||
|
||||
await generalAccountWxLoginVerifyDomainService.Bind(new WxUserBaseInfo(OpenId, AppId, UnionId, WXAppType.GZ), UserManager.AccountId, true);
|
||||
}
|
||||
/// <summary>
|
||||
/// 微信小程序授权绑定(已登录)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("wx-min-program-bind")]
|
||||
public async Task WxMinProgramBindAsync([FromBody] AccountLoginByWXMinProgramInput input, [FromServices] WXMinProgramService wxService, [FromServices] WxBindService generalAccountWxLoginVerifyDomainService)
|
||||
{
|
||||
var (wxLoginR, _) = await wxService.OnLogin(input.Code, input.AppId);
|
||||
|
||||
await generalAccountWxLoginVerifyDomainService.Bind(wxLoginR, UserManager.AccountId, true);
|
||||
}
|
||||
/// <summary>
|
||||
/// 微信授权解绑
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("wx-unbind")]
|
||||
public async Task WxMinProgramUnBindAsync([FromBody] AccountLoginByWXMinProgramInput input, [FromServices] WXMinProgramService wxService, [FromServices] GeneralAccountWxLoginBindDomainService generalAccountWxLoginVerifyDomainService)
|
||||
{
|
||||
await generalAccountWxLoginVerifyDomainService.UnBind(UserManager.AccountId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查手机号是否已注册
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
[HttpPost("check-phone-reg")]
|
||||
public async Task<long> CheckPhoneReg(PhoneRegCheckInput input)
|
||||
{
|
||||
var (accountId, _) = await manageAccountLoginVerifyDomainService.VerifyByMobile(input.Phone);
|
||||
return accountId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过手机重置密码
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("resetpwdbyphone")]
|
||||
[AllowAnonymous]
|
||||
[UnitOfWork(true)]
|
||||
[OpAudit("手机重置密码", "账号", OpAuditLogEventTarget.Account)]
|
||||
public async Task ReSetPwdByPhone(ChangePasswordByPhoneInput input)
|
||||
{
|
||||
//检查验证码
|
||||
if (!smsService.CheckCodeAsync(input.captcha, input.mobile, SMSCodeIntent.FindPwd.ToString()))
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PW1001);
|
||||
}
|
||||
|
||||
var (accountId, _) = await manageAccountLoginVerifyDomainService.VerifyByMobile(input.mobile);
|
||||
|
||||
opAuditContext.Update(x => x.AddTargetSysAccount(accountId, OpAuditLogEventTarget.Account));
|
||||
|
||||
await manageAccountLoginVerifyDomainService.SetPassword(accountId, input.Password);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更改密码
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("changepwd")]
|
||||
[UnitOfWork(true)]
|
||||
[OpAudit("更改密码", "账号", OpAuditLogEventTarget.Account, AuditErrorCode = [ErrorCode.D1004])]
|
||||
[AnyAccountIdentityAuthorize]
|
||||
public async Task ChangePwd(ChangePasswordInput input)
|
||||
{
|
||||
var CurrentUser = UserManager.GetCurrentAdminShopInfo();
|
||||
var accountId = CurrentUser.UserId;
|
||||
|
||||
await manageAccountLoginVerifyDomainService.ChangePwdVerifyPassword(accountId, input.Password);
|
||||
await manageAccountLoginVerifyDomainService.SetPassword(accountId, input.NewPassword);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取登录信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("loginuser")]
|
||||
[AnyAccountIdentityAuthorize]
|
||||
public async Task<LoginOutput> GetLoginUserAsync([FromServices] GeneralAccountWxLoginBindDomainService generalAccountWxLoginBindDomainService)
|
||||
{
|
||||
var CurrentUser = UserManager;
|
||||
var accountId = CurrentUser.UserId;
|
||||
var account = await repository.DetachedEntities.FirstOrDefaultAsync(x => x.Id == accountId);
|
||||
if (account.IsEmpty())
|
||||
throw Oops.Bah(ErrorCode.D1011).StatusCode(StatusCodes.Status401Unauthorized);
|
||||
var user = account.Adapt<LoginOutput>();
|
||||
//var httpContext = httpContextAccessor.HttpContext;
|
||||
user.PwdNotYetSet = string.IsNullOrWhiteSpace(account.Password);
|
||||
user.LastLoginTime = account.LastLoginTime;
|
||||
user.LastLoginIp = account.LastLoginIp;
|
||||
user.WxBind = await generalAccountWxLoginBindDomainService.IsBind(accountId);
|
||||
//var client = Parser.GetDefault().Parse(httpContext.Request.Headers["User-Agent"]);
|
||||
//user.LastLoginBrowser = client.UA.Family + client.UA.Major;
|
||||
//user.LastLoginOs = client.OS.Family + client.OS.Major;
|
||||
//角色门店角色信息
|
||||
//user.Roles = await sysRoleService.GetShopRoleList(user.Id);
|
||||
//获取权限信息
|
||||
//user.Permissions = await sysMenuService.GetPermissionList(accountId, AccountIdentity.Shop, data.AdminType == AdminType.SuperAdmin);
|
||||
//获取系统所有权限
|
||||
//user.AllPermissions = await sysMenuService.GetAllPermissionList(AccountIdentity.Shop);
|
||||
// 具备应用信息(多系统,默认激活一个,可根据系统切换菜单),返回的结果中第一个为激活的系统
|
||||
//user.Apps = await sysMenuService.GetApps("account");
|
||||
//获取菜单信息
|
||||
//if (user.Apps.Any())
|
||||
//{
|
||||
// user.Menus = await sysMenuService.GetMenusAntDesign("account");
|
||||
//}
|
||||
return user;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取授权身份账号
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("authaccountidentities")]
|
||||
[AnyAccountIdentityAuthorize]
|
||||
public async Task<AuthAccountIdentitiesOutput> GetAuthAccountIdentities([FromServices] AuthAccountIdentitiesQueryService queryService)
|
||||
{
|
||||
return await queryService.Get(UserManager.AccountId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送短信验证码
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
[HttpPost("sendcode")]
|
||||
public async Task<string> SendCodeAsync([FromBody] ShopSendMessageC2SDto input)
|
||||
{
|
||||
switch (input.Intent)
|
||||
{
|
||||
case SMSCodeIntent.Login:
|
||||
await manageAccountLoginVerifyDomainService.VerifyByMobile(input.Phone);
|
||||
break;
|
||||
case SMSCodeIntent.Reg:
|
||||
await manageAccountLoginVerifyDomainService.RegVerifyByMobile(input.Phone);
|
||||
break;
|
||||
case SMSCodeIntent.FindPwd:
|
||||
await manageAccountLoginVerifyDomainService.VerifyByMobile(input.Phone);
|
||||
break;
|
||||
//default:
|
||||
//throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
return await smsService.SendAsync(input.Phone, input.Intent.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 退出登录
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("logout")]
|
||||
[OpAudit("退出", "账号", OpAuditLogEventTarget.Account)]
|
||||
[AnyAccountIdentityAuthorize]
|
||||
public async Task LoginOutAsync([FromBody] LoginOutInput input, [FromServices] GeneralAccountWxLoginBindDomainService generalAccountWxLoginVerifyDomainService)
|
||||
{
|
||||
if (input.WxUnBind == true)
|
||||
await generalAccountWxLoginVerifyDomainService.UnBind(UserManager.AccountId);
|
||||
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 登录输入参数
|
||||
/// </summary>
|
||||
public class LoginInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户名
|
||||
/// </summary>
|
||||
/// <example>superAdmin</example>
|
||||
[Required(ErrorMessage = "用户名不能为空"), MinLength(5, ErrorMessage = "用户名不能少于5位字符")]
|
||||
public string Account { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 密码
|
||||
/// </summary>
|
||||
/// <example>123456</example>
|
||||
[Required(ErrorMessage = "密码不能为空"), MinLength(5, ErrorMessage = "密码不能少于5位字符")]
|
||||
public string Password { get; set; }
|
||||
public bool WxBind { get; set; }
|
||||
}
|
||||
|
||||
public class LoginOutInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否解绑微信
|
||||
/// </summary>
|
||||
public bool? WxUnBind { get; set; } = true;
|
||||
}
|
||||
|
||||
public class LoginBySMSCodeInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 手机号
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "手机号不可为空")]
|
||||
[DataValidation(ValidationTypes.PhoneNumber, ErrorMessage = "手机号格式不正确")]
|
||||
public string Phone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 验证码
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "验证码不可为空")]
|
||||
public string VrCode { get; set; }
|
||||
public bool WxBind { get; set; }
|
||||
}
|
||||
public class PhoneRegCheckInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 手机号
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "手机号不可为空")]
|
||||
[DataValidation(ValidationTypes.PhoneNumber, ErrorMessage = "手机号格式不正确")]
|
||||
public string Phone { get; set; }
|
||||
}
|
||||
public class RegBySMSCodeInput : LoginBySMSCodeInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 总部
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "总部不可为空")]
|
||||
public long FromHeadId { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
public string RegSource { get; set; }
|
||||
}
|
||||
public class AuthAccountToggleLoginInput
|
||||
{
|
||||
[Required]
|
||||
public string Id { get; set; }
|
||||
[Required]
|
||||
[EnumDataType(typeof(AccountIdentity))]
|
||||
public AccountIdentity Type { get; set; }
|
||||
}
|
||||
public class AccountLoginByWXMinProgramInput
|
||||
{
|
||||
public string AppId { get; set; }
|
||||
[Required]
|
||||
public string Code { get; set; }
|
||||
}
|
||||
public class AccountLoginByWXGzInput
|
||||
{
|
||||
[Required]
|
||||
public string Oid { get; set; }
|
||||
}
|
||||
|
||||
public class AuthAccountIdentitiesOutput
|
||||
{
|
||||
public IEnumerable<AuthAccountIdentitiesOutputItem> Rows { get; set; }
|
||||
//public IEnumerable<AuthAccountIdentitiesOutputItem> ShopHeads { get; set; }
|
||||
//public IEnumerable<AuthAccountIdentitiesOutputItem> ShopHeadAgents { get; set; }
|
||||
}
|
||||
|
||||
public class AuthAccountIdentitiesOutputItem
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public AccountIdentity Type { get; set; }
|
||||
//public SystemAuthorizationOutput SystemAuthorization { get; set; }
|
||||
}
|
||||
/*public class SystemAuthorizationOutput
|
||||
{
|
||||
public bool IsExpire => SystemAuthorization.VerifyExpireTime(ExpireTime);
|
||||
|
||||
public DateTime ExpireTime { get; set; }
|
||||
|
||||
public SystemAuthorizationMode Mode { get; set; }
|
||||
|
||||
public DateTime StartTime { get; set; }
|
||||
}*/
|
||||
|
||||
public class AuthAccountIdentitiesQueryService(IRepository<PC_ShopAccount> shopAccountRep, IRepository<PC_Shop> shopRep, IRepository<PcShopHeadAccount> shopHeadAgentAccountRep, IRepository<PcHead> shopHeadRep, IRepository<PcShopHeadAccount> shopHeadAccountRep) : ITransient
|
||||
{
|
||||
public async Task<AuthAccountIdentitiesOutput> Get(long accountId)
|
||||
{
|
||||
var a = await (from p in shopAccountRep.DetachedEntities.AsQueryable().Where(x => x.AccountId == accountId)
|
||||
join d in shopRep.DetachedEntities.AsQueryable() on p.ShopId equals d.Id into results
|
||||
from d in results.DefaultIfEmpty()
|
||||
|
||||
where p.Status == CommonStatus.Enable
|
||||
|
||||
select new AuthAccountIdentitiesOutputItem
|
||||
{
|
||||
Id = d.Id.ToString(),
|
||||
Name = d.Name,
|
||||
Type = AccountIdentity.Shop
|
||||
//SystemAuthorization = new SystemAuthorizationOutput() { Mode = d.SystemAuthorization.Mode, ExpireTime = d.SystemAuthorization.ExpireTime, StartTime = d.SystemAuthorization.StartTime }
|
||||
}).ToListAsync();
|
||||
var b = (await (from p in shopHeadAccountRep.DetachedEntities.AsQueryable()
|
||||
.Where(x => x.AccountId == accountId)
|
||||
join d in shopHeadRep.DetachedEntities.AsQueryable() on p.ShopHeadId equals d.Id //into results
|
||||
//from d in results.DefaultIfEmpty()
|
||||
|
||||
where p.Status == CommonStatus.Enable
|
||||
|
||||
select new AuthAccountIdentitiesOutputItem
|
||||
{
|
||||
Id = d.Id.ToString(),
|
||||
Name = d.Name,
|
||||
Type = AccountIdentity.ShopHead
|
||||
//SystemAuthorization = new SystemAuthorizationOutput() { Mode = d.SystemAuthorization.Mode, ExpireTime = d.SystemAuthorization.ExpireTime, StartTime = d.SystemAuthorization.StartTime }
|
||||
}).ToListAsync());
|
||||
|
||||
return new AuthAccountIdentitiesOutput()
|
||||
{
|
||||
Rows =
|
||||
b.Union(a)
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
using JT.Shop.Domain.Entity.ShopHead;
|
||||
|
||||
namespace JT.Shop.Application.Service.Account;
|
||||
|
||||
public class DianShuController(UserManager userManager, IRepository<PcManageAccountDianShu> readableRepository) : AccountApiControllerBase
|
||||
{
|
||||
[HttpGet("info")]
|
||||
public async Task<AccountDianshuInfoOutput> GetInfo()
|
||||
{
|
||||
var entity = await readableRepository.DetachedEntities.FirstOrDefaultAsync(x => x.Id == userManager.UserId);
|
||||
return entity?.Adapt<AccountDianshuInfoOutput>() ?? new AccountDianshuInfoOutput();
|
||||
}
|
||||
[HttpGet("wastebook")]
|
||||
public async Task<PageResult<AccountDianshuWastebookOutput>> GetWastebook([FromQuery] AccountDianshuWastebookInput input,
|
||||
[FromServices] IRepository<PcManageAccountDianShuWasteBook> repository)
|
||||
{
|
||||
return await repository.DetachedEntities.Where(x => x.AccountId == userManager.UserId).OrderByDescending(x => x.CreatedTime)
|
||||
.ProjectToType<AccountDianshuWastebookOutput>()
|
||||
.ToADPagedListAsync(input.PageNo, input.PageSize);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class AccountDianshuInfoOutput
|
||||
{
|
||||
public int Qty { get; set; }
|
||||
}
|
||||
|
||||
public class AccountDianshuWastebookInput : PageInputBase
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class AccountDianshuWastebookOutput
|
||||
{
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 流水号
|
||||
/// </summary>
|
||||
public string No { get; set; }
|
||||
/// <summary>
|
||||
/// 单号
|
||||
/// </summary>
|
||||
public string OrderNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 变化点数
|
||||
/// </summary>
|
||||
public int ChangeQty { get; set; }
|
||||
/// <summary>
|
||||
/// 余额
|
||||
/// </summary>
|
||||
public int Qty { get; set; }
|
||||
/// <summary>
|
||||
/// 类型 充值10|转账20|消费30
|
||||
/// </summary>
|
||||
public AccountDianShuWasteBookType Type { get; set; }
|
||||
/// <summary>
|
||||
/// 描述
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
public string Remark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
|
||||
public DateTimeOffset CreatedTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 操作者账户
|
||||
/// </summary>
|
||||
public long OperatorAccountId { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
using JT.Shop.Domain.Entity.ShopHead;
|
||||
|
||||
namespace JT.Shop.Application.Service.Account;
|
||||
|
||||
public class DianShuRechargeController(UserManager userManager, IRepository<PcManageAccountDianShuRecharge> readableRepository)
|
||||
: AccountApiControllerBase
|
||||
{
|
||||
[HttpGet("wastebook")]
|
||||
public async Task<PageResult<AccountDianshuRechargeWastebookOutput>> GetWastebook([FromQuery] AccountDianshuRechargeWastebookInput input,
|
||||
[FromServices] IRepository<PcManageAccountDianShuWasteBook> repository)
|
||||
{
|
||||
return await repository.DetachedEntities.Where(x => x.AccountId == userManager.UserId).OrderByDescending(x => x.CreatedTime)
|
||||
.ProjectToType<AccountDianshuRechargeWastebookOutput>()
|
||||
.ToADPagedListAsync(input.PageNo, input.PageSize);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
public class AccountDianshuRechargeWastebookInput : PageInputBase
|
||||
{
|
||||
|
||||
}
|
||||
public class AccountDianshuRechargeWastebookOutput
|
||||
{
|
||||
public virtual long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 流水号
|
||||
/// </summary>
|
||||
public string No { get; set; }
|
||||
|
||||
public long AccountId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 点数
|
||||
/// </summary>
|
||||
public uint DianShu { get; set; }
|
||||
/// <summary>
|
||||
/// 金额
|
||||
/// </summary>
|
||||
public decimal Money { get; set; }
|
||||
/// <summary>
|
||||
/// 描述
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
/// <summary>
|
||||
/// 交易流水号
|
||||
/// </summary>
|
||||
public string TradeNo { get; set; }
|
||||
/// <summary>
|
||||
/// 交易渠道
|
||||
/// </summary>
|
||||
public DianShuRechargeTradeChannel TradeChannel { get; set; }
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
public string Remark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 交易时间
|
||||
/// </summary>
|
||||
|
||||
public DateTimeOffset TradeTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
|
||||
public DateTimeOffset CreatedTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建者账户
|
||||
/// </summary>
|
||||
public long CreatedAccountId { get; set; }
|
||||
/// <summary>
|
||||
/// 充值代理商
|
||||
/// </summary>
|
||||
public long CreatedShopHeadAgentId { get; set; }
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
// 品传科技
|
||||
// 开发:李鹏鹏
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
using JT.Shop.Application.Service.ShopHead;
|
||||
using JT.Shop.Core;
|
||||
using JT.Shop.Domain.Entity.Business;
|
||||
using JT.Shop.Domain.Shared.EventMessages;
|
||||
using JT.Shop.Domain.Tenant;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using static JT.Shop.Domain.Entity.Business.ISystemBusinessVersionQueryService;
|
||||
|
||||
namespace JT.Shop.Application.Service.Account;
|
||||
|
||||
public class ShopController(UserManager UserManager, OpAuditContext opAuditContext) : AccountApiControllerBase
|
||||
{
|
||||
[HttpPost("reg")]
|
||||
[UnitOfWork(true)]
|
||||
[OpAudit("注册门店", "账号", OpAuditLogEventTarget.Account)]
|
||||
public async Task<CreateOrderOutput> Reg(AccountShopRegInput input, [FromServices] AccountShopAppService appService)
|
||||
{
|
||||
var output = await appService.Add(input, UserManager.AccountId);
|
||||
|
||||
await UnitOfWorkActionEventMange.PublishAsync(new ShopAddedEvent
|
||||
{
|
||||
ShopId = output.Id,
|
||||
ParentHeadId = input.ParentHeadId,
|
||||
//ShopMainAccountId = UserManager.AccountId,
|
||||
SyncShopHeadConfig = true,
|
||||
AccountIsDianZhang = true
|
||||
});
|
||||
return output;
|
||||
|
||||
}
|
||||
[HttpPost("reg-check")]
|
||||
public async Task RegCheck([FromServices] PcShopCreateLimitCheckOfGeneralAccountSelfDomainService shopCreateLimitCheckOfGeneralAccountSelfDomainService)
|
||||
{
|
||||
await shopCreateLimitCheckOfGeneralAccountSelfDomainService.Check(UserManager.AccountId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class AccountShopAppService(TenantManager tenantManager, PcGeneralAccountSelfCreateShopDomainService pcGeneralAccountSelfCreateShopDomainService) : ITransientDependency
|
||||
{
|
||||
public async Task<CreateOrderOutput> Add(AccountShopRegInput input, long userManagerAccountId)
|
||||
{
|
||||
var parentHeadId = input.ParentHeadId;
|
||||
|
||||
var tenant = await tenantManager.CreateAsync();
|
||||
var entity = new PC_Shop(id: tenant.Id, name: input.Name, shopCode: input.Code, businessId: parentHeadId)
|
||||
{
|
||||
Area = input.Area,
|
||||
City = input.City,
|
||||
Province = input.Province,
|
||||
Address = input.Address,
|
||||
Contact = input.AccountName,
|
||||
Phone = input.AccountPhone
|
||||
};
|
||||
|
||||
var orderId = await pcGeneralAccountSelfCreateShopDomainService.Add(entity, userManagerAccountId,
|
||||
new CreateShopAccountProfileDto(Name: input.AccountName, Phone: input.AccountPhone, Code: "0001",
|
||||
BirthDay: input.Birthday, Gender: input.Sex ?? Gender.UNKNOWN),
|
||||
input.BuildVerifyDto(BusinessSystemApp.Shop));
|
||||
return new CreateOrderOutput(orderId, entity.Id);
|
||||
}
|
||||
}
|
||||
|
||||
public class AccountShopRegInput : SystemBusinessVersionVerifyInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 编号
|
||||
/// </summary>
|
||||
[Required, MaxLength(32)]
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
[Required, MaxLength(100)]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 省份
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "省份不可为空")]
|
||||
[MaxLength(100, ErrorMessage = "省份最多100个字")]
|
||||
public string Province { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 市
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "市不可为空")]
|
||||
[MaxLength(100, ErrorMessage = "市最多100个字")]
|
||||
public string City { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 区
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "区不可为空")]
|
||||
[MaxLength(100, ErrorMessage = "区最多100个字")]
|
||||
public string Area { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 详细地址
|
||||
/// </summary>
|
||||
[MaxLength(100, ErrorMessage = "详细地址最多100个字")]
|
||||
[Required(ErrorMessage = "详细地址不可为空")]
|
||||
public string Address { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 主管理员姓名
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string AccountName { get; set; }
|
||||
/// <summary>
|
||||
/// 主管理员手机号
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string AccountPhone { get; set; }
|
||||
public DateTime? Birthday { get; set; }
|
||||
public Gender? Sex { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 上级总部
|
||||
/// </summary>
|
||||
[Required]
|
||||
public long ParentHeadId { get; set; }
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,418 @@
|
|||
// ------------------------------------------------------------------------
|
||||
// 版权信息
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
using JT.Shop.Application.Service.Business.Device;
|
||||
using JT.Shop.Application.Service.System.OutProduct.Dto;
|
||||
using JT.Shop.Application.Upload;
|
||||
using JT.Shop.Domain.Entity.ShopHead;
|
||||
using MiniExcelLibs;
|
||||
using Volo.Abp.Data;
|
||||
using Volo.Abp.Threading;
|
||||
|
||||
namespace JT.Shop.Application.Service.BaseCommon
|
||||
{
|
||||
public class DeviceAppService : ITransient
|
||||
{
|
||||
private readonly IRepository<PC_Device> _deviceRep;
|
||||
private readonly IRepository<PC_DeviceAlloc> _deviceAllocRep;
|
||||
private readonly IRepository<PC_Shop> _shopRep;
|
||||
private readonly IRepository<PC_OutProduct> _outProductRep;
|
||||
private readonly IRepository<PC_OutProductDev> _outProductDevRep;
|
||||
private readonly IPcShopHeadQueryService _sysUserRepository;
|
||||
private readonly UserManager User;
|
||||
private readonly UploadDomainService uploadDomainService;
|
||||
private readonly PCDeviceAddDoaminService _pcDeviceAddDoaminService;
|
||||
private readonly IDataFilter DataFilter;
|
||||
|
||||
public DeviceAppService(
|
||||
IRepository<PC_Device> deviceRep,
|
||||
IRepository<PC_DeviceAlloc> deviceAllocRep,
|
||||
IRepository<PC_Shop> shopRep, IRepository<PC_OutProduct> outProductRep, IRepository<PC_OutProductDev> outProductDevRep, IPcShopHeadQueryService sysUserRepository, UserManager user, UploadDomainService uploadDomainService, PCDeviceAddDoaminService pcDeviceAddDoaminService, IDataFilter dataFilter)
|
||||
{
|
||||
_deviceRep = deviceRep;
|
||||
_deviceAllocRep = deviceAllocRep;
|
||||
_shopRep = shopRep;
|
||||
_outProductRep = outProductRep;
|
||||
_outProductDevRep = outProductDevRep;
|
||||
_sysUserRepository = sysUserRepository;
|
||||
User = user;
|
||||
this.uploadDomainService = uploadDomainService;
|
||||
_pcDeviceAddDoaminService = pcDeviceAddDoaminService;
|
||||
DataFilter = dataFilter;
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// 设备分配给总部
|
||||
///// </summary>
|
||||
///// <param name="input"></param>
|
||||
///// <returns></returns>
|
||||
|
||||
//public async Task AllocToBusinessAsync(DeviceAllocC2SToShopDto input, bool IsShowBusiness)
|
||||
//{
|
||||
|
||||
// if (!await _sysuserRep.DetachedEntities.AnyAsync(x => x.Id == input.BusinessId))
|
||||
// {
|
||||
// throw Oops.Bah("总部不存在");
|
||||
// }
|
||||
// //记录设备分配记录
|
||||
// var alloclist = await _deviceRep.DetachedEntities.Where(x => input.ids.Contains(x.Id)).Select(x => new PC_DeviceAlloc
|
||||
// {
|
||||
// IsShowBusiness = IsShowBusiness,// userAdminType == AdminType.None,
|
||||
// CreatedTime = DateTime.Now,
|
||||
// CreatedUserId = User.UserId,
|
||||
// CreatedUserName = User.Name,
|
||||
// DeviceId = x.Id,
|
||||
// FromBusinessId = x.BusinessId,
|
||||
// FromShopId = x.ShopId,
|
||||
// Remark = string.Empty,
|
||||
// ToBusinessId = input.BusinessId,
|
||||
// ToShopId = input.ShopId,
|
||||
// Type = DeviceAllocType.ALLOC
|
||||
// }).ToListAsync();
|
||||
// alloclist.ForEach(it =>
|
||||
// {
|
||||
// it.Id = YitIdHelper.NextId();
|
||||
// });
|
||||
// if (!alloclist.IsEmpty())
|
||||
// {
|
||||
// await _deviceAllocRep.InsertAsync(alloclist);
|
||||
// }
|
||||
// // 更新设备所属的客户ID和门店ID
|
||||
// await _deviceRep.Where(x => input.ids.Contains(x.Id))
|
||||
// .ExecuteUpdateAsync(s => s
|
||||
// .SetProperty(p => p.BusinessId, input.BusinessId)
|
||||
// .SetProperty(p => p.ShopId, input.ShopId)
|
||||
// .SetProperty(p => p.UpdatedTime, DateTime.Now)
|
||||
// .SetProperty(p => p.UpdatedUserId, User.UserId)
|
||||
// .SetProperty(p => p.UpdatedUserName, User.Name)
|
||||
// );
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// 设备分配
|
||||
/// </summary>
|
||||
|
||||
public async Task AllocAsync(IEnumerable<long> ids, long ShopId, long BusinessId, bool IsShowBusiness, Func<PC_DeviceAlloc, Task> checkFunc = null, Func<PC_DeviceAlloc, bool> validFunc = null, string remark = null)
|
||||
{
|
||||
|
||||
//记录设备分配记录
|
||||
var alloclist = await _deviceRep.DetachedEntities.Where(x => ids.Contains(x.Id)).Select(x => new PC_DeviceAlloc
|
||||
{
|
||||
IsShowBusiness = IsShowBusiness,
|
||||
CreatedTime = DateTime.Now,
|
||||
CreatedUserId = User.UserId,
|
||||
CreatedUserName = User.Name,
|
||||
DeviceId = x.Id,
|
||||
FromBusinessId = x.BusinessId,
|
||||
FromShopId = x.ShopId,
|
||||
Remark = remark ?? string.Empty,
|
||||
ToBusinessId = BusinessId,
|
||||
ToShopId = ShopId,
|
||||
Type = DeviceAllocType.ALLOC
|
||||
}).ToListAsync();
|
||||
if (alloclist.IsEmpty()) throw Oops.Bah("没有可以分配的记录");
|
||||
if (validFunc != null)
|
||||
alloclist = alloclist.Where(validFunc).ToList();
|
||||
|
||||
alloclist.ForEach(it =>
|
||||
{
|
||||
it.Id = YitIdHelper.NextId();
|
||||
if (checkFunc != null)
|
||||
AsyncHelper.RunSync(async () => await checkFunc(it));
|
||||
});
|
||||
if (!alloclist.IsEmpty())
|
||||
await _deviceAllocRep.InsertAsync(alloclist);
|
||||
// 更新设备所属的客户ID和门店ID
|
||||
await _deviceRep.Where(x => ids.Contains(x.Id))/*.UpdateAsync(x => new PC_Device
|
||||
{
|
||||
BusinessId = input.BusinessId,
|
||||
Status = DeviceStatus.Run,
|
||||
ShopId = input.ShopId,
|
||||
UpdatedTime = DateTime.Now,
|
||||
UpdatedUserId = userId,
|
||||
UpdatedUserName = userName
|
||||
})*/.ExecuteUpdateAsync(s => s
|
||||
.SetProperty(p => p.BusinessId, BusinessId)
|
||||
.SetProperty(p => p.Status, p => ShopId > 0 ? DeviceStatus.Run : p.Status)//分配给门店才算激活
|
||||
.SetProperty(p => p.ShopId, ShopId)
|
||||
.SetProperty(p => p.UpdatedTime, DateTime.Now)
|
||||
.SetProperty(p => p.UpdatedUserId, User.UserId)
|
||||
.SetProperty(p => p.UpdatedUserName, User.NickName ?? User.Name)
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询设备分配记录
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<DeviceAllocListSCDto>> AllocListAsync(BaseId input, bool? IsShowBusiness)
|
||||
{
|
||||
|
||||
var list = await _deviceAllocRep.DetachedEntities
|
||||
.Where(x => x.DeviceId == input.Id)
|
||||
.Where(IsShowBusiness.HasValue, x => x.IsShowBusiness == IsShowBusiness)
|
||||
.OrderByDescending(x => x.CreatedTime).ProjectToType<DeviceAllocListSCDto>().ToListAsync();
|
||||
var bids = new List<long>();
|
||||
var shopids = new List<long>();
|
||||
foreach (var item in list)
|
||||
{
|
||||
if (!bids.Contains(item.FromBusinessId))
|
||||
bids.Add(item.FromBusinessId);
|
||||
if (!bids.Contains(item.ToBusinessId))
|
||||
bids.Add(item.ToBusinessId);
|
||||
if (!shopids.Contains(item.FromShopId))
|
||||
shopids.Add(item.FromShopId);
|
||||
if (!shopids.Contains(item.ToShopId))
|
||||
shopids.Add(item.ToShopId);
|
||||
}
|
||||
var allbuss =/* await _sysuserRep.DetachedEntities.Where(x => bids.Contains(x.Id))
|
||||
.Select(x => new SysUser
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name
|
||||
})
|
||||
.ToListAsync();*/await _sysUserRepository.Get(bids.ToHashSet());
|
||||
|
||||
var allshop = await _shopRep.DetachedEntities.Where(x => shopids.Contains(x.Id)).Select(x => new PC_Shop
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name
|
||||
}).ToListAsync();
|
||||
list.ForEach(it =>
|
||||
{
|
||||
// var buss = allbuss.FirstOrDefault(x => x.Id == it.FromBusinessId);
|
||||
it.FromBusiness = allbuss.GetOrDefault(it.FromBusinessId)?.Name;// buss != null ? buss.Name : "";
|
||||
//buss = allbuss.FirstOrDefault(x => x.Id == it.ToBusinessId);
|
||||
it.ToBusiness = allbuss.GetOrDefault(it.ToBusinessId)?.Name;//buss != null ? buss.Name : "";
|
||||
var shop = allshop.FirstOrDefault(x => x.Id == it.FromShopId);
|
||||
it.FromShop = shop != null ? shop.Name : "";
|
||||
shop = allshop.FirstOrDefault(x => x.Id == it.ToShopId);
|
||||
it.ToShop = shop != null ? shop.Name : "";
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设备回收
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
public async Task RecycleAsync(DeviceRecycleC2SDto input, long ToBusinessId, bool IsShowBusiness, Func<PC_DeviceAlloc, Task> checkFunc = null, Func<PC_DeviceAlloc, bool> validFunc = null, string remark = null)
|
||||
{
|
||||
|
||||
//记录设备分配记录
|
||||
var alloclist = await _deviceRep.DetachedEntities.Where(x => input.ids.Contains(x.Id)).Select(x => new PC_DeviceAlloc
|
||||
{
|
||||
IsShowBusiness = IsShowBusiness,
|
||||
CreatedTime = DateTime.Now,
|
||||
CreatedUserId = User.UserId,
|
||||
CreatedUserName = User.Name,
|
||||
DeviceId = x.Id,
|
||||
FromBusinessId = x.BusinessId,
|
||||
FromShopId = x.ShopId,
|
||||
Remark = remark ?? string.Empty,
|
||||
ToBusinessId = ToBusinessId,
|
||||
ToShopId = 0,
|
||||
Type = DeviceAllocType.RETURN
|
||||
}).ToListAsync();
|
||||
if (alloclist.IsEmpty()) throw Oops.Bah("没有可以回收的记录");
|
||||
if (validFunc != null)
|
||||
alloclist = alloclist.Where(validFunc).ToList();
|
||||
|
||||
alloclist.ForEach(it =>
|
||||
{
|
||||
it.Id = YitIdHelper.NextId();
|
||||
if (checkFunc != null)
|
||||
AsyncHelper.RunSync(async () => await checkFunc(it));
|
||||
});
|
||||
if (!alloclist.IsEmpty())
|
||||
{
|
||||
await _deviceAllocRep.InsertAsync(alloclist);
|
||||
// 更新设备所属的客户ID
|
||||
await _deviceRep.Where(x => input.ids.Contains(x.Id)).ExecuteUpdateAsync(s => s
|
||||
.SetProperty(p => p.BusinessId, ToBusinessId)
|
||||
.SetProperty(p => p.ShopId, 0)
|
||||
.SetProperty(p => p.UpdatedTime, DateTime.Now)
|
||||
.SetProperty(p => p.Status, DeviceStatus.UnActive)
|
||||
.SetProperty(p => p.UpdatedUserId, User.UserId)
|
||||
.SetProperty(p => p.UpdatedUserName, User.Name)
|
||||
)/*.UpdateAsync(x => new PC_Device
|
||||
{
|
||||
BusinessId = userid,
|
||||
ShopId = 0,
|
||||
UpdatedTime = DateTime.Now,
|
||||
UpdatedUserId = userId,
|
||||
UpdatedUserName = userName
|
||||
})*/;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改设备状态
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
public async Task SetStatusAsync(DeviceStatusC2SDto input, Func<PC_Device, Task> checkAction, DeviceStatus status)
|
||||
{
|
||||
var device = await _deviceRep.Where(x => x.Id == input.Id, true).Select(x => new PC_Device
|
||||
{
|
||||
Id = x.Id,
|
||||
Status = x.Status,
|
||||
BusinessId = x.BusinessId,
|
||||
ShopId = x.ShopId
|
||||
}).FirstOrDefaultAsync();
|
||||
if (device.IsEmpty())
|
||||
throw Oops.Bah(PCErrorCode.PD1000);
|
||||
await checkAction?.Invoke(device);
|
||||
if (device.Status != status)
|
||||
{
|
||||
device.Status = status;
|
||||
await _deviceRep.UpdateIncludeNowAsync(device, new[] { nameof(device.Status) });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备信息添加
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
public async Task SubmitAddAsync(DeviceSubmitC2SDto input, bool IsShowBusiness, long ToBusinessId, long ToShopId, long FromBusinessId, long FromShopId)
|
||||
{
|
||||
//20250415 remark为null时扫码报错 https://shop-preview.pcxbc.com/qr/d?sn=20483552521413
|
||||
if (input.Remark == null || input.Remark == "") input.Remark = string.Empty;
|
||||
|
||||
|
||||
using (DataFilter.Disable<IShopEntity>())//禁止ShopId过滤
|
||||
await _pcDeviceAddDoaminService.Add(input.Name, input.Type, input.Remark, input.ECode, input.FacCode, IsShowBusiness, ToBusinessId, ToShopId, FromBusinessId, FromShopId);
|
||||
}
|
||||
|
||||
|
||||
public async Task SubmitEditAsync(DeviceSubmitC2SDto input, Func<PC_Device, Task> checkAction = null)
|
||||
{
|
||||
|
||||
var data = await _deviceRep
|
||||
.Where(x => x.Id == input.Id).FirstOrDefaultAsync();
|
||||
if (data.IsEmpty())
|
||||
throw Oops.Bah(PCErrorCode.PD0000);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(input.FacCode) &&
|
||||
await _deviceRep.DetachedEntities
|
||||
.Where(x => x.FacCode == input.FacCode.Trim())
|
||||
.Where(x => x.Id != input.Id)
|
||||
.AnyAsync())
|
||||
throw Oops.Bah($"此序列号【{input.FacCode}】已存在");
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(input.ECode) &&
|
||||
await _deviceRep.DetachedEntities
|
||||
.Where(x => x.Ecode == input.ECode.Trim())
|
||||
.Where(x => x.Id != input.Id)
|
||||
.AnyAsync())
|
||||
throw Oops.Bah($"此机器码【{input.ECode}】已存在");
|
||||
|
||||
|
||||
checkAction?.Invoke(data);
|
||||
data = input.Adapt(data);
|
||||
|
||||
await _deviceRep.UpdateNowAsync(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 出货信息添加
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task AddAsync(DeviceProductAddC2SDto input, long userId, string userName, AdminType userAdminType)
|
||||
{
|
||||
// var currentUser = UserInfo.GetCurrentUserInfo();
|
||||
var product = new PC_OutProduct
|
||||
{
|
||||
Desc = input.Desc.ToStr(),
|
||||
Id = YitIdHelper.NextId(),
|
||||
Path = input.Path.ToStr(),
|
||||
DevType = input.DevType,
|
||||
CreatedTime = DateTime.Now,
|
||||
CreatedUserId = userId,
|
||||
CreatedUserName = userName
|
||||
};
|
||||
var path = $"{uploadDomainService.GetUploadPhysicalRootPath()}{input.Path}";
|
||||
var dt = await MiniExcel.QueryAsync<OutProductUploadFileDevS2SDto>(path);
|
||||
var list = new List<PC_OutProductDev>();
|
||||
var codes = new List<string>();
|
||||
product.Cnt = dt.Count();
|
||||
var devlist = new List<PC_Device>();
|
||||
var devalloclist = new List<PC_DeviceAlloc>();
|
||||
var i = 1;
|
||||
var msg = string.Empty;
|
||||
foreach (var row in dt)
|
||||
{
|
||||
var code = row.code.ToStr();
|
||||
if (code.IsEmpty())
|
||||
msg = $"第{i}行设备机器码不可为空";
|
||||
else if (codes.Any(x => x == code))
|
||||
msg = $"第{i}行设备机器码重复";
|
||||
else if (await _deviceRep.AnyAsync(x => x.Ecode == code))
|
||||
msg = $"第{i}行设备已出货,请勿重复操作";
|
||||
else
|
||||
{
|
||||
var dev = new PC_Device
|
||||
{
|
||||
Id = YitIdHelper.NextId(),
|
||||
Ecode = code,
|
||||
Status = DeviceStatus.UnActive,
|
||||
CreatedTime = DateTime.Now,
|
||||
CreatedUserId = userId,
|
||||
CreatedUserName = userName,
|
||||
Name = code,
|
||||
FacCode = row.faccode.ToStr(),
|
||||
Remark = string.Empty,
|
||||
Type = input.DevType,
|
||||
BusinessId = 0,
|
||||
ShopId = 0
|
||||
};
|
||||
devlist.Add(dev);
|
||||
codes.Add(code);
|
||||
list.Add(new PC_OutProductDev
|
||||
{
|
||||
Id = YitIdHelper.NextId(),
|
||||
CreatedTime = dev.CreatedTime.Value,
|
||||
DeviceId = dev.Id,
|
||||
OrderId = product.Id,
|
||||
FacCode = dev.FacCode
|
||||
});
|
||||
devalloclist.Add(new PC_DeviceAlloc
|
||||
{
|
||||
Id = YitIdHelper.NextId(),
|
||||
FromBusinessId = 0,
|
||||
ToBusinessId = 0,
|
||||
IsShowBusiness = false,
|
||||
CreatedTime = dev.CreatedTime,
|
||||
CreatedUserId = dev.CreatedUserId,
|
||||
CreatedUserName = dev.CreatedUserName,
|
||||
DeviceId = dev.Id,
|
||||
Remark = $"设备导入",
|
||||
Type = DeviceAllocType.OUT
|
||||
});
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (!msg.IsEmpty())
|
||||
throw Oops.Bah(msg);
|
||||
if (list.IsEmpty())
|
||||
throw Oops.Bah("未找到可用的设备");
|
||||
|
||||
//插入记录表
|
||||
await _outProductRep.InsertAsync(new List<PC_OutProduct> { product });
|
||||
await _outProductDevRep.InsertAsync(list);
|
||||
await _deviceRep.InsertAsync(devlist);
|
||||
await _deviceAllocRep.InsertAsync(devalloclist);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
using DotNetCore.CAP;
|
||||
using Furion.RemoteRequest.Extensions;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace JT.Shop.Application.Service.BaseCommon
|
||||
{
|
||||
/// <summary>
|
||||
/// http请求
|
||||
/// </summary>
|
||||
public class CommonHttpService : ICommonHttpService, ITransient
|
||||
{
|
||||
private readonly ICapPublisher _capBus;
|
||||
|
||||
public CommonHttpService(ICapPublisher capPublisher)
|
||||
{
|
||||
_capBus = capPublisher;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送get请求
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<HttpOutput> GetAsync(HttpInput input)
|
||||
{
|
||||
string errmsg = string.Empty;
|
||||
var nowtime = DateTime.Now;
|
||||
var returndata = new HttpOutput();
|
||||
var st = Stopwatch.StartNew();
|
||||
var request = input.Url
|
||||
.SetQueries(input.Data)
|
||||
.SetContentType(input.ContentType)
|
||||
.OnClientCreating(client =>
|
||||
{
|
||||
//设置超时时间
|
||||
client.Timeout = TimeSpan.FromSeconds(input.TimeOut);
|
||||
})
|
||||
.OnException((client, res, errors) =>
|
||||
{
|
||||
errmsg = errors;
|
||||
returndata.IsSuccess = false;
|
||||
});
|
||||
if (!input.Client.IsEmpty())
|
||||
{
|
||||
request.SetClient(input.Client);
|
||||
}
|
||||
var response = await request.GetAsync();
|
||||
st.Stop();
|
||||
if (response.IsEmpty())
|
||||
{
|
||||
returndata.IsSuccess = false;
|
||||
returndata.IsEx = true;
|
||||
return returndata;
|
||||
}
|
||||
returndata.Content = await response.Content.ReadAsStringAsync();
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
returndata.IsSuccess = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
returndata.IsSuccess = false;
|
||||
}
|
||||
if (input.IsAddLogger)
|
||||
{
|
||||
//记录请求日志
|
||||
var logdata = new ThirdLogS2SDto
|
||||
{
|
||||
Url = request.RequestUrl,
|
||||
StatusCode = response.StatusCode,
|
||||
CreateTime = nowtime,
|
||||
Method = "GET",
|
||||
RequestParam = input.Data,
|
||||
ResponseData = returndata.IsSuccess ? returndata.Content : errmsg,
|
||||
IsSuccess = returndata.IsSuccess,
|
||||
Time = st.ElapsedMilliseconds,
|
||||
OrderId = input.OrderId
|
||||
};
|
||||
await SaveLogger(logdata);
|
||||
}
|
||||
return returndata;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送post请求
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<HttpOutput> PostAsync(HttpInput input)
|
||||
{
|
||||
string errmsg = string.Empty;
|
||||
var nowtime = DateTime.Now;
|
||||
var returndata = new HttpOutput();
|
||||
var st = Stopwatch.StartNew();
|
||||
var request = input.Url
|
||||
.SetBody(input.Data)
|
||||
.SetContentType(input.ContentType)
|
||||
.OnClientCreating(client =>
|
||||
{
|
||||
//设置超时时间
|
||||
client.Timeout = TimeSpan.FromSeconds(input.TimeOut);
|
||||
})
|
||||
.OnException((client, res, errors) =>
|
||||
{
|
||||
errmsg = errors;
|
||||
returndata.IsSuccess = false;
|
||||
});
|
||||
if (!input.Client.IsEmpty())
|
||||
{
|
||||
request.SetClient(input.Client);
|
||||
}
|
||||
var response = await request.PostAsync();
|
||||
st.Stop();
|
||||
if (response.IsEmpty())
|
||||
{
|
||||
returndata.IsSuccess = false;
|
||||
returndata.IsEx = true;
|
||||
return returndata;
|
||||
}
|
||||
returndata.Content = await response.Content.ReadAsStringAsync();
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
returndata.IsSuccess = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
returndata.IsSuccess = false;
|
||||
errmsg = response.ReasonPhrase;
|
||||
}
|
||||
if (input.IsAddLogger)
|
||||
{
|
||||
//记录请求日志
|
||||
var logdata = new ThirdLogS2SDto
|
||||
{
|
||||
Url = request.RequestUrl,
|
||||
StatusCode = response.StatusCode,
|
||||
CreateTime = nowtime,
|
||||
Method = "POST",
|
||||
RequestParam = input.Data,
|
||||
ResponseData = returndata.IsSuccess ? returndata.Content : errmsg,
|
||||
IsSuccess = returndata.IsSuccess,
|
||||
Time = st.ElapsedMilliseconds,
|
||||
OrderId = input.OrderId
|
||||
};
|
||||
await SaveLogger(logdata);
|
||||
}
|
||||
return returndata;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存日志
|
||||
/// </summary>
|
||||
/// <param name="logdata"></param>
|
||||
/// <returns></returns>
|
||||
private async Task SaveLogger(ThirdLogS2SDto logdata)
|
||||
{
|
||||
await _capBus.PublishAsync(CAPConst.CreateThirdLog, logdata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
namespace JT.Shop.Application.Service.BaseCommon
|
||||
{
|
||||
/// <summary>
|
||||
/// 通用HTTP处理方法
|
||||
/// </summary>
|
||||
public interface ICommonHttpService
|
||||
{
|
||||
/// <summary>
|
||||
/// 发送post请求
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
Task<HttpOutput> PostAsync(HttpInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 发送get请求
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
Task<HttpOutput> GetAsync(HttpInput input);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/****************************************************************
|
||||
* 作者:liuzl
|
||||
* 版权:PCXBC
|
||||
* 框架版本:6.0
|
||||
* 创建时间:2023/1/4 9:51:14
|
||||
* 说明:
|
||||
*
|
||||
*****************************************************************/
|
||||
|
||||
namespace JT.Shop.Application.Service.BaseCommon.QrCode
|
||||
{
|
||||
public interface IQrCodeService
|
||||
{
|
||||
/// <summary>
|
||||
/// 生成二维码
|
||||
/// </summary>
|
||||
/// <param name="text">二维码内容</param>
|
||||
/// <param name="width">宽度</param>
|
||||
/// <param name="height">高度</param>
|
||||
/// <param name="magrin">白边偏移</param>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <param name="exttext">额外信息</param>
|
||||
/// <returns></returns>
|
||||
Task QrCodeAsync(string text, string path, int width, int height, int magrin = 1, string exttext = "");
|
||||
|
||||
/// <summary>
|
||||
/// 生成200宽度的二维码
|
||||
/// </summary>
|
||||
/// <param name="text">二维码内容</param>
|
||||
/// <param name="rootname">文件存放目录</param>
|
||||
/// <param name="filename">文件名称</param>
|
||||
/// <returns></returns>
|
||||
Task<QrCodeInfoDto> QrCode200Async(string text, string rootname, string filename);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/****************************************************************
|
||||
* 作者:liuzl
|
||||
* 版权:PCXBC
|
||||
* 框架版本:6.0
|
||||
* 创建时间:2023/1/4 9:51:48
|
||||
* 说明:
|
||||
*
|
||||
*****************************************************************/
|
||||
|
||||
using Hinse.Util.Barcode;
|
||||
using JT.Shop.Application.Upload;
|
||||
|
||||
namespace JT.Shop.Application.Service.BaseCommon.QrCode
|
||||
{
|
||||
/// <summary>
|
||||
/// 二维码
|
||||
/// </summary>
|
||||
public class QrCodeService : IQrCodeService, ITransient
|
||||
{
|
||||
private readonly UploadDomainService _hostingEnvironment;
|
||||
|
||||
public QrCodeService(UploadDomainService hostingEnvironment)
|
||||
{
|
||||
_hostingEnvironment = hostingEnvironment;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成200宽度的二维码
|
||||
/// </summary>
|
||||
/// <param name="text">二维码内容</param>
|
||||
/// <param name="rootname">文件存放目录</param>
|
||||
/// <param name="filename">文件名称</param>
|
||||
/// <returns></returns>
|
||||
public async Task<QrCodeInfoDto> QrCode200Async(string text, string rootname, string filename)
|
||||
{
|
||||
string root = $"/uploadfile/{rootname}/{DateTime.Now.ToString("yyyyMM")}";
|
||||
string savefolder = _hostingEnvironment.GetUploadPhysicalRootPath();
|
||||
var name = !filename.IsEmpty() ? filename + ".jpg" : Path.GetRandomFileName() + ".jpg";
|
||||
var thumbnailPath = Path.Combine(savefolder + "/" + root, name);
|
||||
var virualpath = Path.Combine(root + "/", name);
|
||||
await QrCodeAsync(text, thumbnailPath, 200, 200, 1);
|
||||
return new QrCodeInfoDto
|
||||
{
|
||||
Path = virualpath,
|
||||
Url = CommonService.ImgFile(virualpath)
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成二维码
|
||||
/// </summary>
|
||||
/// <param name="text">二维码内容</param>
|
||||
/// <param name="width">宽度</param>
|
||||
/// <param name="height">高度</param>
|
||||
/// <param name="magrin">白边偏移</param>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <param name="exttext">额外信息</param>
|
||||
/// <returns></returns>
|
||||
public async Task QrCodeAsync(string text, string path, int width, int height, int magrin = 1, string exttext = "")
|
||||
{
|
||||
if (!Directory.Exists(Path.GetDirectoryName(path)))
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||
}
|
||||
//检查文件是否存在
|
||||
if (File.Exists(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!exttext.IsEmpty())
|
||||
{
|
||||
await BarcodeHelper.QrCodeWithText(text, width, height, exttext, path, magrin);
|
||||
}
|
||||
else
|
||||
{
|
||||
await BarcodeHelper.QrCode(text, width, height, path, magrin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
using Furion.DataValidation;
|
||||
|
||||
namespace JT.Shop.Application.Service.BaseCommon
|
||||
{
|
||||
/// <summary>
|
||||
/// 短信发送请求参数
|
||||
/// </summary>
|
||||
public class SmsSendC2SDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 手机号
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "手机号不可为空")]
|
||||
[DataValidation(ValidationTypes.PhoneNumber, ErrorMessage = "手机号格式不正确")]
|
||||
public string Phone { get; set; }
|
||||
|
||||
/* /// <summary>
|
||||
/// 短信内容
|
||||
/// </summary>
|
||||
/// s
|
||||
public string Content { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 签名
|
||||
/// </summary>
|
||||
public string Sign { get; set; } = SmsConst.Sign;
|
||||
|
||||
/// <summary>
|
||||
/// 短信过期时间,秒
|
||||
/// </summary>
|
||||
public int Timeout { get; set; } = SmsConst.TimeOut;*/
|
||||
}
|
||||
|
||||
///<summary>
|
||||
/// 短信接口
|
||||
/// </summary>
|
||||
public class SMSMODEL
|
||||
{
|
||||
/// <summary>
|
||||
/// code=0成功
|
||||
/// </summary>
|
||||
public int code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 信息描述
|
||||
/// </summary>
|
||||
public string message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据
|
||||
/// </summary>
|
||||
public object data { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
using NewLife.Caching;
|
||||
using ACheck = Volo.Abp;
|
||||
|
||||
namespace JT.Shop.Application.Service.BaseCommon;
|
||||
|
||||
public class PasswordErrorLimitService(ICache Cache) : IPasswordErrorLimitService, ITransient
|
||||
{
|
||||
public async Task Add(string account, string category, int minutes = 10)
|
||||
{
|
||||
ACheck.Check.Positive(minutes, nameof(minutes));
|
||||
await Task.Yield();
|
||||
var key = BuildKey(account, category);
|
||||
var num = Cache.Increment(key, 1);
|
||||
Cache.SetExpire(key, TimeSpan.FromMinutes(minutes));
|
||||
}
|
||||
|
||||
public async Task Check(string account, string category, int maxTimes = 10, string errmsg = "已超出最多密码尝试次数,请10分钟后再试!")
|
||||
{
|
||||
ACheck.Check.NotNullOrWhiteSpace(errmsg, nameof(errmsg));
|
||||
ACheck.Check.Positive(maxTimes, nameof(maxTimes));
|
||||
await Task.Yield();
|
||||
var key = BuildKey(account, category);
|
||||
var num = Cache.Get<long>(key);
|
||||
if (num >= maxTimes)
|
||||
{
|
||||
throw Oops.Bah(errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
private static string BuildKey(string account, string category)
|
||||
{
|
||||
return $"PasswordErrorLimit:{category ?? "_"}:{account}";
|
||||
}
|
||||
|
||||
public async Task RemoveCheck(string account, string category)
|
||||
{
|
||||
await Task.Yield();
|
||||
Cache.Remove(BuildKey(account, category));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,274 @@
|
|||
using Hinse.Cache;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NewLife.Caching;
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using Volo.Abp;
|
||||
using Volo.Abp.Threading;
|
||||
|
||||
namespace JT.Shop.Application.Service.BaseCommon;
|
||||
|
||||
/// <summary>
|
||||
/// 短信管理
|
||||
/// </summary>
|
||||
public class SmsService : ISmsService, ITransient
|
||||
{
|
||||
private readonly IHttpClientFactory _clientFactory;
|
||||
private readonly INewLifeCacheService _cacheService;
|
||||
private readonly IHostEnvironment _environment;
|
||||
private readonly ILogger _logger;
|
||||
private readonly IPasswordErrorLimitService _passwordErrorLimitService;
|
||||
private readonly ICache Cache;
|
||||
|
||||
private const string catetory = "sms-code";
|
||||
private const int maxErrorTimes = 5;
|
||||
private const int errIntervalMinutes = 10;
|
||||
/// <summary>
|
||||
/// 短信过期时间,秒
|
||||
/// </summary>
|
||||
public static int TimeOut = 60 * 5;//5分钟
|
||||
|
||||
private readonly IOptionsMonitor<SmsMockChannelOptions> smsOptionsMonitor;
|
||||
|
||||
public SmsService(IHttpClientFactory httpClientFactory, INewLifeCacheService cacheService, IHostEnvironment environment, ILoggerFactory loggerFactory, IPasswordErrorLimitService passwordErrorLimitService, ICache cache, IOptionsMonitor<SmsMockChannelOptions> smsOptionsMonitor)
|
||||
{
|
||||
_clientFactory = httpClientFactory;
|
||||
_cacheService = cacheService;
|
||||
_environment = environment;
|
||||
_passwordErrorLimitService = passwordErrorLimitService;
|
||||
Cache = cache;
|
||||
this.smsOptionsMonitor = smsOptionsMonitor;
|
||||
|
||||
_logger = loggerFactory.CreateLogger<SmsService>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 校检验证码
|
||||
/// </summary>
|
||||
/// <param name="code">验证码</param>
|
||||
/// <param name="phone">手机号</param>
|
||||
/// <param name="intent">意图</param>
|
||||
/// <param name="IsClear">验证成功之后是否清理验证码</param>
|
||||
/// <returns></returns>
|
||||
/// <returns></returns>
|
||||
public bool CheckCodeAsync(string code, string phone, string intent, bool IsClear = false)
|
||||
{
|
||||
Check.NotNullOrWhiteSpace(phone, nameof(phone));
|
||||
Check.NotNullOrWhiteSpace(intent, nameof(intent));
|
||||
Check.NotNullOrWhiteSpace(code, nameof(code));
|
||||
|
||||
if (code.IsEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (phone.IsEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
var par = BuildCacheKey(phone, intent);
|
||||
|
||||
AsyncHelper.RunSync(() => _passwordErrorLimitService.Check(par, catetory, maxTimes: maxErrorTimes, errmsg: "已超出最多尝试次数,请稍后重新发送验证码!"));
|
||||
|
||||
string vrcode = _cacheService.GetString(par);
|
||||
if (vrcode.IsEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (vrcode != code)
|
||||
{
|
||||
AsyncHelper.RunSync(() => _passwordErrorLimitService.Add(par, catetory, minutes: errIntervalMinutes));
|
||||
|
||||
return false;
|
||||
}
|
||||
if (IsClear)
|
||||
{
|
||||
ClearVrCodeAsync(phone, intent);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理原先的验证码
|
||||
/// </summary>
|
||||
/// <param name="phone">手机号</param>
|
||||
/// <returns></returns>
|
||||
public void ClearVrCodeAsync(string phone, string intent)
|
||||
{
|
||||
Check.NotNullOrWhiteSpace(phone, nameof(phone));
|
||||
Check.NotNullOrWhiteSpace(intent, nameof(intent));
|
||||
|
||||
var par = BuildCacheKey(phone, intent);
|
||||
string vrcode = _cacheService.GetString(par);
|
||||
if (!vrcode.IsEmpty())
|
||||
{
|
||||
_cacheService.Remove(par);
|
||||
}
|
||||
|
||||
AsyncHelper.RunSync(() => _passwordErrorLimitService.RemoveCheck(par, catetory));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 短信验证码发送
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<string> SendAsync(string phone, string intent)
|
||||
{
|
||||
Check.NotNullOrWhiteSpace(phone, nameof(phone));
|
||||
Check.NotNullOrWhiteSpace(intent, nameof(intent));
|
||||
|
||||
var cacheKey = BuildCacheKey(phone, intent);
|
||||
|
||||
|
||||
using (Cache.AcquireLock($"{cacheKey}-a-lock", 5000))//一个手机号限制仅一个请求锁定在最多5秒内发送且只有一次发送
|
||||
{
|
||||
{
|
||||
var num = Cache.GetExpire(cacheKey);
|
||||
if (num.TotalSeconds > TimeOut - 60)//一个手机号60秒内只能发送一次
|
||||
{
|
||||
throw Oops.Bah("请求频繁");
|
||||
}
|
||||
}
|
||||
|
||||
Random rd = new Random();
|
||||
var yzm = rd.Next(100000, 999999);
|
||||
|
||||
var content = $"【{SmsConst.Sign}】您好,欢迎使用{SmsConst.Sign},您的手机验证码是:{yzm},验证码一分钟内有效,若非本人操作,请忽略!";
|
||||
|
||||
|
||||
/* string vrcode = _cacheService.GetString(par);
|
||||
if (!vrcode.IsEmpty())
|
||||
{
|
||||
throw Oops.Bah("请求频繁");
|
||||
}*/
|
||||
|
||||
var mock = false;
|
||||
|
||||
#if DEBUG
|
||||
if (_environment.IsDevelopment() || _environment.EnvironmentName.StartsWith("MOCK-")) mock = true;//调试模式且开发环境下不真实发送
|
||||
|
||||
#endif
|
||||
|
||||
if (mock) _logger.LogWarning("mock smscode");
|
||||
else if (smsOptionsMonitor.CurrentValue.Enable && smsOptionsMonitor.CurrentValue.Include(phone))
|
||||
{
|
||||
_logger.LogWarning($"PostWeiXinGroup smscode:{phone}");
|
||||
await PostWeiXinGroup(phone, content);
|
||||
}
|
||||
else await Post(phone, content);
|
||||
|
||||
_cacheService.SetString(cacheKey, yzm.ToString(), TimeOut);
|
||||
|
||||
AsyncHelper.RunSync(() => _passwordErrorLimitService.RemoveCheck(cacheKey, catetory));
|
||||
|
||||
return mock ? yzm.ToString() : null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private async Task Post(string phone, string content)
|
||||
{
|
||||
if (_logger.IsEnabled(LogLevel.Information))
|
||||
_logger.LogInformation($"send phone sms code:{phone}");
|
||||
|
||||
var data = new {
|
||||
phone = phone,
|
||||
Content = HttpUtility.UrlEncode(content)
|
||||
};
|
||||
var url = "http://sms.ybhdmob.com/Message/Send?token=ybhdmob";
|
||||
var request = new HttpRequestMessage(HttpMethod.Post,
|
||||
url);
|
||||
string body = data.ToJson();
|
||||
request.Content = new StringContent(body, Encoding.UTF8, "application/json");
|
||||
var client = _clientFactory.CreateClient();
|
||||
var response = await client.SendAsync(request);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var result = await response.Content.ReadAsStringAsync();
|
||||
var results = result.ToObject<SMSMODEL>();
|
||||
if (results is { code: 0 })
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError("send phone sms fail:{result}", result);
|
||||
throw Oops.Bah(results?.message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError("send phone sms fail:{response}", response);
|
||||
throw Oops.Bah("短信发送失败");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task PostWeiXinGroup(string phone, string content)
|
||||
{
|
||||
if (_logger.IsEnabled(LogLevel.Information))
|
||||
_logger.LogInformation($"send phone sms code:{phone}");
|
||||
|
||||
var data = new {
|
||||
msgtype = "text",
|
||||
text = new { content = $"模拟短信通道发送 - {phone} {content}" }
|
||||
};
|
||||
var url = smsOptionsMonitor.CurrentValue.ApiUrl;
|
||||
var request = new HttpRequestMessage(HttpMethod.Post,
|
||||
url);
|
||||
string body = data.ToJson();
|
||||
request.Content = new StringContent(body, Encoding.UTF8, "application/json");
|
||||
var client = _clientFactory.CreateClient();
|
||||
var response = await client.SendAsync(request);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var result = await response.Content.ReadAsStringAsync();
|
||||
var results = result.ToObject<PostWeiXinGroupResult>();
|
||||
if (results is { errcode: "0" })
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError("send phone SmsMockChannel fail:{result}", result);
|
||||
throw Oops.Bah($"模拟短信通道发送失败 {results?.errmsg}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError("send phone SmsMockChannel fail:{response}", response);
|
||||
throw Oops.Bah("模拟短信通道发送失败");
|
||||
}
|
||||
}
|
||||
public class PostWeiXinGroupResult
|
||||
{
|
||||
public string errcode { get; set; }
|
||||
public string errmsg { get; set; }
|
||||
}
|
||||
|
||||
private static string BuildCacheKey(string mobile, string intent)
|
||||
{
|
||||
return $"{SmsConst.YZMPre}{mobile}";
|
||||
}
|
||||
}
|
||||
|
||||
public class SmsMockChannelOptions
|
||||
{
|
||||
public string ApiUrl { get; set; } =
|
||||
"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=69324091-3f81-42c2-b8ec-08befd101332";
|
||||
public HashSet<string> Mobile { get; set; }
|
||||
public bool Enable { get; set; }
|
||||
public const string SmsMockChannel = "SmsMockChannel";
|
||||
|
||||
public bool Include(string mobile)
|
||||
{
|
||||
return Mobile != null && Mobile.Contains(mobile);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// ------------------------------------------------------------------------
|
||||
// 版权信息
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
using JT.Shop.Domain.Entity.Business;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JT.Shop.Application.Service.BaseCommon
|
||||
{
|
||||
[ApiDescriptionSettings("管理平台")]
|
||||
[Route("/api/common")]
|
||||
public class SharesAppService : IDynamicApiController
|
||||
{
|
||||
/// <summary>
|
||||
/// 共享名称。如:店员职位、门店服务、门店产品
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <param name="pcShareNameQueryService"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("share-name")]
|
||||
[AnyAccountIdentityAuthorize]
|
||||
public async Task<IEnumerable<PcShareNameDto>> Get([FromQuery] ShareNameSearchInput input, [FromServices] IPcShareNameQueryService pcShareNameQueryService)
|
||||
{
|
||||
return await pcShareNameQueryService.Query(input.Type, input.Name, input.Take);
|
||||
}
|
||||
}
|
||||
|
||||
public class ShareNameSearchInput
|
||||
{
|
||||
[Range(1, 500)] public int Take { get; set; } = 10;
|
||||
public string Name { get; set; }
|
||||
[Required]
|
||||
public PcShareNameType Type { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
namespace JT.Shop.Application.Upload
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件上传
|
||||
/// </summary>
|
||||
public interface IUploadService
|
||||
{
|
||||
/// <summary>
|
||||
/// 图片上传
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
Task<UploadS2CDto> UploadImg(UploadC2SDto input);
|
||||
|
||||
/// <summary>
|
||||
/// excel上传
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
Task<UploadS2CDto> UploadExcel(UploadC2SDto input);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
using JT.Shop.Application.Upload;
|
||||
|
||||
namespace JT.Shop.Application.Service.BaseCommon.Upload
|
||||
{
|
||||
/// <summary>
|
||||
/// 上传管理
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings("管理平台")]
|
||||
[Route("/api/common")]
|
||||
[AnyAccountIdentityAuthorize]
|
||||
public class UploadAppService : IDynamicApiController
|
||||
{
|
||||
private readonly IUploadService _uploadService;
|
||||
|
||||
public UploadAppService(IUploadService uploadService)
|
||||
{
|
||||
_uploadService = uploadService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 图片上传
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<UploadS2CDto> UploadImg([FromForm] UploadC2SDto input)
|
||||
{
|
||||
return await _uploadService.UploadImg(input);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// excel上传
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<UploadS2CDto> UploadExcel([FromForm] UploadC2SDto input)
|
||||
{
|
||||
return await _uploadService.UploadExcel(input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,232 @@
|
|||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using FormOptions = Microsoft.AspNetCore.Http.Features.FormOptions;
|
||||
|
||||
namespace JT.Shop.Application.Upload
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件上传
|
||||
/// </summary>
|
||||
public class UploadService : IUploadService, ITransient
|
||||
{
|
||||
private static readonly FormOptions _defaultFormOptions = new FormOptions();
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly UserManager UserInfo;
|
||||
private readonly UploadDomainService uploadDomainService;
|
||||
|
||||
public UploadService(IHttpContextAccessor httpContextAccessor,
|
||||
UserManager userInfo, UploadDomainService uploadDomainService)
|
||||
{
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
UserInfo = userInfo;
|
||||
this.uploadDomainService = uploadDomainService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 图片上传
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<UploadS2CDto> UploadImg(UploadC2SDto input)
|
||||
{
|
||||
var currentUser = UserInfo.GetCurrentUserInfo();
|
||||
var Request = _httpContextAccessor.HttpContext.Request;
|
||||
if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
|
||||
{
|
||||
throw Oops.Bah("只支持multipart/form-data类型");
|
||||
}
|
||||
var boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(Request.ContentType), _defaultFormOptions.MultipartBoundaryLengthLimit);
|
||||
var reader = new MultipartReader(boundary, Request.Body);
|
||||
var section = await reader.ReadNextSectionAsync();
|
||||
List<string> filelist = new List<string>();
|
||||
while (section != null)
|
||||
{
|
||||
var hasContentDispositionHeader =
|
||||
ContentDispositionHeaderValue.TryParse(
|
||||
section.ContentDisposition, out var contentDisposition);
|
||||
if (hasContentDispositionHeader)
|
||||
{
|
||||
if (!MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] _permittedExtensions = { ".gif", ".jpg", ".jpeg", ".png", ".bmp" };
|
||||
long _fileSizeLimit = 1048576 * 5;
|
||||
string rootname = string.Empty;
|
||||
if (input.uploadpath.IsEmpty())
|
||||
{
|
||||
rootname = $"/uploadfile/{input.root}/{DateTime.Now.ToString("yyyyMMdd")}";
|
||||
}
|
||||
else
|
||||
{
|
||||
rootname = $"/uploadfile/{input.root}/{input.uploadpath}";
|
||||
}
|
||||
string savefolder = uploadDomainService.GetUploadPhysicalRootPath();
|
||||
if (!Path.Exists(savefolder))
|
||||
{
|
||||
throw new Exception($"上传根目录【{savefolder}】不存在");
|
||||
}
|
||||
string name = string.Empty;
|
||||
if (input.filename.IsEmpty())
|
||||
{
|
||||
name = Path.GetRandomFileName() + ".jpg";
|
||||
}
|
||||
else
|
||||
{
|
||||
name = $"{input.filename}.jpg";
|
||||
}
|
||||
Dictionary<string, string> dict = new Dictionary<string, string>();
|
||||
var streamedFileContent = await FileHelpers.ProcessStreamedFile(
|
||||
section, contentDisposition, dict,
|
||||
_permittedExtensions, _fileSizeLimit);
|
||||
if (dict.ContainsKey("File"))
|
||||
{
|
||||
string msg = dict.GetValueOrDefault("File");
|
||||
throw Oops.Bah(msg);
|
||||
}
|
||||
var thumbnailPath = Path.Combine(savefolder + "/" + rootname);
|
||||
if (!Directory.Exists(Path.GetDirectoryName(thumbnailPath)))
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(thumbnailPath));
|
||||
}
|
||||
|
||||
var filepath = Path.Combine(thumbnailPath + "/", name);
|
||||
var virualpath = Path.Combine(rootname + "/", name);
|
||||
var filename = contentDisposition.FileName.Value;
|
||||
using (var targetStream = File.Create(filepath))
|
||||
{
|
||||
await targetStream.WriteAsync(streamedFileContent);
|
||||
filelist.Add(virualpath);
|
||||
}
|
||||
return new UploadS2CDto
|
||||
{
|
||||
path = virualpath,
|
||||
Url = virualpath.ImgFile()
|
||||
};
|
||||
}
|
||||
}
|
||||
section = await reader.ReadNextSectionAsync();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// excel上传
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<UploadS2CDto> UploadExcel(UploadC2SDto input)
|
||||
{
|
||||
var currentUser = UserInfo.GetCurrentUserInfo();
|
||||
var Request = _httpContextAccessor.HttpContext.Request;
|
||||
if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
|
||||
{
|
||||
throw Oops.Bah("只支持multipart/form-data类型");
|
||||
}
|
||||
var boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(Request.ContentType), _defaultFormOptions.MultipartBoundaryLengthLimit);
|
||||
var reader = new MultipartReader(boundary, Request.Body);
|
||||
var section = await reader.ReadNextSectionAsync();
|
||||
List<string> filelist = new List<string>();
|
||||
while (section != null)
|
||||
{
|
||||
var hasContentDispositionHeader =
|
||||
ContentDispositionHeaderValue.TryParse(
|
||||
section.ContentDisposition, out var contentDisposition);
|
||||
if (hasContentDispositionHeader)
|
||||
{
|
||||
if (!MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] _permittedExtensions = { ".xsl", ".xlsx" };
|
||||
long _fileSizeLimit = 1048576 * 5;
|
||||
string rootname = string.Empty;
|
||||
if (input.uploadpath.IsEmpty())
|
||||
{
|
||||
rootname = $"/uploadfile/{input.root}/{DateTime.Now.ToString("yyyyMMdd")}";
|
||||
}
|
||||
else
|
||||
{
|
||||
rootname = $"/{input.uploadpath}/{input.root}";
|
||||
}
|
||||
string savefolder = uploadDomainService.GetUploadPhysicalRootPath();
|
||||
if (!Path.Exists(savefolder))
|
||||
{
|
||||
throw new Exception($"上传根目录【{savefolder}】不存在");
|
||||
}
|
||||
string name = string.Empty;
|
||||
if (input.filename.IsEmpty())
|
||||
{
|
||||
name = Path.GetRandomFileName() + ".xlsx";
|
||||
}
|
||||
else
|
||||
{
|
||||
name = $"{input.filename}.xlsx";
|
||||
}
|
||||
Dictionary<string, string> dict = new Dictionary<string, string>();
|
||||
var streamedFileContent = await FileHelpers.ProcessStreamedFile(
|
||||
section, contentDisposition, dict,
|
||||
_permittedExtensions, _fileSizeLimit);
|
||||
if (dict.ContainsKey("File"))
|
||||
{
|
||||
string msg = dict.GetValueOrDefault("File");
|
||||
throw Oops.Bah(msg);
|
||||
}
|
||||
var thumbnailPath = Path.Combine(savefolder + "/" + rootname, name);
|
||||
if (!Directory.Exists(Path.GetDirectoryName(thumbnailPath)))
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(thumbnailPath));
|
||||
}
|
||||
|
||||
var filepath = Path.Combine(thumbnailPath + "/", name);
|
||||
var virualpath = Path.Combine(rootname + "/", name);
|
||||
var filename = contentDisposition.FileName.Value;
|
||||
using (var targetStream = File.Create(filepath))
|
||||
{
|
||||
await targetStream.WriteAsync(streamedFileContent);
|
||||
filelist.Add(virualpath);
|
||||
}
|
||||
return new UploadS2CDto
|
||||
{
|
||||
path = virualpath,
|
||||
Url = CommonService.File(virualpath)
|
||||
};
|
||||
}
|
||||
}
|
||||
section = await reader.ReadNextSectionAsync();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class UploadOptions
|
||||
{
|
||||
public const string Upload = "Upload";
|
||||
public string PhysicalPath { get; set; } = String.Empty;
|
||||
}
|
||||
|
||||
public class UploadDomainService : ISingletonDependency
|
||||
{
|
||||
private readonly UploadOptions _uploadOptions;
|
||||
private readonly IWebHostEnvironment _hostingEnvironment;
|
||||
|
||||
public UploadDomainService(IOptions<UploadOptions> uploadOptions, IWebHostEnvironment hostingEnvironment)
|
||||
{
|
||||
_hostingEnvironment = hostingEnvironment;
|
||||
_uploadOptions = uploadOptions.Value;
|
||||
}
|
||||
|
||||
public string GetUploadPhysicalRootPath()
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(_uploadOptions.PhysicalPath)
|
||||
? _hostingEnvironment.WebRootPath
|
||||
: _uploadOptions.PhysicalPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
using JT.Shop.Application.Service.Mch.Body;
|
||||
using JT.Shop.Application.Service.ShopHead;
|
||||
using JT.Shop.Domain.FeatureDefinitions.ShopHead;
|
||||
using Volo.Abp.Authorization.Permissions;
|
||||
using Volo.Abp.Features;
|
||||
using Volo.Abp.Localization;
|
||||
|
||||
namespace JT.Shop.Application.Service.Business.BodyType
|
||||
{
|
||||
/// <summary>
|
||||
/// 身体部位管理
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings("总部")]
|
||||
[Route("/api/business/[controller]")]
|
||||
public class BodyService : ITransient, IDynamicApiController
|
||||
{
|
||||
private readonly IRepository<PC_ShopBodyType> _bodyTypeRepository;
|
||||
private readonly IRepository<PC_ShopBody> _bodyRepository;
|
||||
|
||||
private readonly IRepository<PC_BusinessBody> _businessBodyRepository;
|
||||
private readonly UserManager _userManager;
|
||||
|
||||
public BodyService(
|
||||
IRepository<PC_ShopBodyType> bodyTypeRepository,
|
||||
IRepository<PC_ShopBody> bodyRepository,
|
||||
UserManager userManager,
|
||||
IRepository<PC_BusinessBody> businessBodyRepository
|
||||
)
|
||||
{
|
||||
_bodyTypeRepository = bodyTypeRepository;
|
||||
_bodyRepository = bodyRepository;
|
||||
_userManager = userManager;
|
||||
_businessBodyRepository = businessBodyRepository;
|
||||
}
|
||||
|
||||
|
||||
#region 总部配置-部位配置
|
||||
|
||||
/// <summary>
|
||||
/// 获取总部关联的身体部位列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("BusinessBodyList")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfBodyPermissionDefinitionProvider.ViewName)]
|
||||
public async Task<List<ShopBodyTypeListOutput>> ListAsync()
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
//获取身体部位类型列表
|
||||
var typelist = await _bodyTypeRepository.DetachedEntities.Where(x => x.Status == CommonStatus.Enable).OrderBy(x => x.SortCode).ToListAsync();
|
||||
//获取身体部位列表
|
||||
var bodylist = await _bodyRepository.DetachedEntities.Where(x => x.Status == CommonStatus.Enable).ToListAsync();
|
||||
//获取总部关联的身体部位
|
||||
var shopBodyRelList = await _businessBodyRepository.DetachedEntities.Where(x => x.BusinessId == CurrentUser.ShopHeadId).ToListAsync();
|
||||
var returnlist = new List<ShopBodyTypeListOutput>();
|
||||
typelist.ForEach(x =>
|
||||
{
|
||||
var bodylistoutput = new ShopBodyTypeListOutput
|
||||
{
|
||||
TypeId = x.Id,
|
||||
TypeName = x.Name,
|
||||
List = new List<ShopBodyListOutput>()
|
||||
};
|
||||
var blist = bodylist.Where(y => y.TypeId == x.Id).ToList();
|
||||
blist.ForEach(y =>
|
||||
{
|
||||
var rel = shopBodyRelList.FirstOrDefault(z => z.BodyId == y.Id);
|
||||
var bodyoutput = new ShopBodyListOutput
|
||||
{
|
||||
Id = y.Id,
|
||||
Name = y.Name,
|
||||
TypeId = y.TypeId,
|
||||
IsChecked = !rel.IsEmpty()
|
||||
};
|
||||
bodylistoutput.List.Add(bodyoutput);
|
||||
});
|
||||
returnlist.Add(bodylistoutput);
|
||||
});
|
||||
return returnlist;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 总部身体部位信息绑定
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
[HttpPost("BusinessBodySubmit")]
|
||||
[UnitOfWork(true)]
|
||||
[OpAudit("编辑", "部位管理", OpAuditLogEventTarget.Head)]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfBodyPermissionDefinitionProvider.EditName)]
|
||||
public async Task SubmitAsync(ShopBodySubmitInput input)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
//先删除绑定的
|
||||
await _businessBodyRepository.Where(x => x.BusinessId == CurrentUser.ShopHeadId).DeleteAsync();
|
||||
if (input.ids.IsEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
//新增
|
||||
var insertlist = new List<PC_BusinessBody>();
|
||||
input.ids.ForEach(x =>
|
||||
{
|
||||
insertlist.Add(new PC_BusinessBody
|
||||
{
|
||||
Id = YitIdHelper.NextId(),
|
||||
BodyId = x,
|
||||
BusinessId = CurrentUser.ShopHeadId
|
||||
});
|
||||
});
|
||||
await _businessBodyRepository.InsertAsync(insertlist);
|
||||
}
|
||||
|
||||
#endregion 总部配置-部位配置
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class ShopHeadOfBodyPermissionDefinitionProvider : PermissionDefinitionProvider
|
||||
{
|
||||
|
||||
|
||||
public const string GroupName = $"{ShopHeadPermissionDefinitionNames.Prefix}.bodymag";
|
||||
public const string ViewName = $"{GroupName}.view";
|
||||
public const string EditName = $"{GroupName}.edit";
|
||||
|
||||
|
||||
|
||||
public override void Define(IPermissionDefinitionContext context)
|
||||
{
|
||||
{
|
||||
var groups = context.AddGroup($"{GroupName}", new FixedLocalizableString("部位配置"));
|
||||
|
||||
groups.AddPermission($"{ViewName}", new FixedLocalizableString("查看"));
|
||||
groups.AddPermission($"{EditName}", new FixedLocalizableString("修改"))
|
||||
.RequirePermissions(ViewName)
|
||||
.RequireFeatures(ShopHeadOfBodyFeatureDefinitionProvider.EditName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
namespace JT.Shop.Application.Service.Business.BodyType
|
||||
{
|
||||
/// <summary>
|
||||
/// 提交身体部位类型
|
||||
/// </summary>
|
||||
public class SubmitBodyTypeInput : BaseNullId
|
||||
{
|
||||
/// <summary>
|
||||
/// 类型名称
|
||||
/// </summary>
|
||||
[MaxLength(50, ErrorMessage = "类型名称最多50个字")]
|
||||
[Required(ErrorMessage = "类型名称不可为空")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型描述
|
||||
/// </summary>
|
||||
[MaxLength(200, ErrorMessage = "类型描述最多200个字")]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型图片
|
||||
/// </summary>
|
||||
[MaxLength(200, ErrorMessage = "类型图片最多200个字")]
|
||||
[Required(ErrorMessage = "类型图片不可为空")]
|
||||
public string Image { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序
|
||||
/// </summary>
|
||||
public int SortCode { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 提交身体部位
|
||||
/// </summary>
|
||||
public class SubmitBodyInput : BaseNullId, IValidatableObject
|
||||
{
|
||||
/// <summary>
|
||||
/// 部位名称
|
||||
/// </summary>
|
||||
[MaxLength(50, ErrorMessage = "部位名称最多50个字")]
|
||||
[Required(ErrorMessage = "部位名称不可为空")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 部位描述
|
||||
/// </summary>
|
||||
[MaxLength(200, ErrorMessage = "部位描述最多200个字")]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所属类型ID
|
||||
/// </summary>
|
||||
public long TypeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 部位图片
|
||||
/// </summary>
|
||||
[MaxLength(200, ErrorMessage = "部位图片最多200个字")]
|
||||
//[Required(ErrorMessage = "部位图片不可为空")]
|
||||
public string Image { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序
|
||||
/// </summary>
|
||||
public int SortCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="validationContext"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (TypeId <= 0)
|
||||
{
|
||||
yield return new ValidationResult("请选择部位类型", new[] { nameof(TypeId) });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
namespace JT.Shop.Application.Service.Business.BodyType
|
||||
{
|
||||
/// <summary>
|
||||
/// 身体部位列表
|
||||
/// </summary>
|
||||
public class BodyListOutput : BaseId
|
||||
{
|
||||
/// <summary>
|
||||
/// 部位名称
|
||||
/// </summary>
|
||||
[Comment("部位名称")]
|
||||
[MaxLength(50)]
|
||||
[Required]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所属类型ID
|
||||
/// </summary>
|
||||
[Comment("所属类型ID")]
|
||||
public long TypeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型名称
|
||||
/// </summary>
|
||||
public string TypeName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 部位描述
|
||||
/// </summary>
|
||||
[Comment("部位描述")]
|
||||
[MaxLength(200)]
|
||||
[Required]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 部位图片
|
||||
/// </summary>
|
||||
[Comment("部位图片")]
|
||||
[MaxLength(200)]
|
||||
[Required]
|
||||
public string Image { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序
|
||||
/// </summary>
|
||||
[Comment("排序")]
|
||||
public int SortCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态
|
||||
/// </summary>
|
||||
[Comment("状态")]
|
||||
public CommonStatus Status { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 身体部位类型列表
|
||||
/// </summary>
|
||||
public class BodyTypeListOutput : BaseId
|
||||
{
|
||||
/// <summary>
|
||||
/// 类型名称
|
||||
/// </summary>
|
||||
[Comment("类型名称")]
|
||||
[MaxLength(50)]
|
||||
[Required]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型描述
|
||||
/// </summary>
|
||||
[Comment("类型描述")]
|
||||
[MaxLength(200)]
|
||||
[Required]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型图片
|
||||
/// </summary>
|
||||
[Comment("类型图片")]
|
||||
[MaxLength(200)]
|
||||
[Required]
|
||||
public string Image { get; set; }
|
||||
|
||||
public string ImageUrl => Image.ImgFile();
|
||||
|
||||
/// <summary>
|
||||
/// 排序
|
||||
/// </summary>
|
||||
[Comment("排序")]
|
||||
public int SortCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态
|
||||
/// </summary>
|
||||
[Comment("状态")]
|
||||
public CommonStatus Status { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,249 @@
|
|||
using JT.Shop.Application.Service.Mch.Clerk;
|
||||
using JT.Shop.Application.Service.Shop.Colleague;
|
||||
using JT.Shop.Application.Service.ShopHead;
|
||||
using JT.Shop.Core;
|
||||
using JT.Shop.Domain.Entity.ShopHead;
|
||||
using JT.Shop.Domain.FeatureDefinitions.ShopHead;
|
||||
using Volo.Abp.Authorization.Permissions;
|
||||
using Volo.Abp.Features;
|
||||
using Volo.Abp.Localization;
|
||||
|
||||
namespace JT.Shop.Application.Service.Business.Clerk
|
||||
{
|
||||
/// <summary>
|
||||
/// 总部之店员管理
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings("总部")]
|
||||
[Route("/api/business/[controller]")]
|
||||
public class ClerkService(
|
||||
UserManager User,
|
||||
PcHeadLevelChildCheckDomainService pcHeadLevelChildCheckDomainService,
|
||||
OpAuditContext opAuditContext,
|
||||
IRepository<PC_ShopPos> shopposRep,
|
||||
IRepository<PC_Shop> shopRep,
|
||||
IPcShopAccountQueryService shopAccountQueryService,
|
||||
IPcShopHeadQueryService shopheadQueryService)
|
||||
: ITransient, IDynamicApiController
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 店员列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopColleagueAccountPermissionDefinitionProvider.ViewName)]
|
||||
public async Task<BusinessClerkListOutput> ListAsync(BusinessClerkListInput input)
|
||||
{
|
||||
var CurrentUser = User.GetCurrentShopHeadInfo();
|
||||
/* var list = await _shopAccountRepository.DetachedEntities
|
||||
.Where(CurrentUser.AccountType == AdminType.None, x => x.BusinessId == CurrentUser.ShopHeadId)
|
||||
.Where(!input.Name.IsEmpty(), x => x.Name.Contains(input.Name) || x.Phone.Contains(input.Name) *//*|| x.Account.Contains(input.Name)*//*)
|
||||
.Where(input.Status != 0, x => x.Status == input.Status)
|
||||
.OrderByDescending(x => x.CreatedTime)
|
||||
.ProjectToType<BusinessClerkListOutput>()
|
||||
.ToADPagedListAsync(input.PageNo, input.PageSize);*/
|
||||
var list = (await shopAccountQueryService.GetAllChildList(CurrentUser.ShopHeadId, input.ChildParentHeadId, input.ShopId, input.Code, input.Name,
|
||||
input.Phone, input.Status, input.PosShareNameId, input.CreateTimeRange, input)).Adapt<BusinessClerkListOutput>();
|
||||
var allposids = list.Rows.Select(x => x.PosId).ToHashSet();
|
||||
var poslist = await shopposRep.DetachedEntities.Where(x => allposids.Contains(x.Id)).ToListAsync();
|
||||
var uids = list.Rows.Select(x => x.BusinessId).ToList();
|
||||
var users = await shopheadQueryService.Get(uids.ToHashSet());
|
||||
var sids = list.Rows.Select(x => x.ShopId).ToHashSet();
|
||||
var shops = await shopRep.DetachedEntities.Where(x => sids.Contains(x.Id))
|
||||
.Select(x => new PC_Shop
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name
|
||||
})
|
||||
.ToListAsync();
|
||||
list.Rows.ToList().ForEach(it =>
|
||||
{
|
||||
var pos = poslist.FirstOrDefault(x => x.Id == it.PosId);
|
||||
if (pos != null)
|
||||
{
|
||||
it.PosName = pos.Name;
|
||||
}
|
||||
if (users.TryGetValue(it.BusinessId, out var head))
|
||||
{
|
||||
it.BusinessName = head.Name;
|
||||
it.BusinessCode = head.Code;
|
||||
}
|
||||
var shop = shops.Where(x => x.Id == it.ShopId).FirstOrDefault();
|
||||
if (shop != null)
|
||||
{
|
||||
it.ShopName = shop.Name;
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
public class ShopHeadOfShopAccountAddInput : ShopAccountAppService.ShopAccountAddInput
|
||||
{
|
||||
public long ShopId { get; set; }
|
||||
}
|
||||
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopColleagueAccountPermissionDefinitionProvider.AddName)]
|
||||
[HttpPost("add")]
|
||||
[OpAudit("添加成员", "门店", OpAuditLogEventTarget.Head)]
|
||||
[UnitOfWork(true)]
|
||||
public async Task<long> Add([FromBody] ShopHeadOfShopAccountAddInput input, [FromServices] ShopAccountAppService service)
|
||||
{
|
||||
|
||||
var shop = (await shopRep.DetachedEntities.FirstOrDefaultAsync(x => x.Id == input.ShopId)) ?? throw Oops.Bah(PC_SHOP_ERROR_CODE.SHOP_NOTFOUND40004).WithData(input.ShopId);
|
||||
|
||||
await pcHeadLevelChildCheckDomainService.InChildShopCheck(shop.BusinessId, User.GetCurrentShopHeadInfo().ShopHeadId);
|
||||
|
||||
opAuditContext.Update(x => x.AddTargetSysAccountWhenRequestNormal(input.ShopId, OpAuditLogEventTarget.Shop));
|
||||
|
||||
|
||||
return await service.Add(input, input.ShopId, shop.BusinessId);
|
||||
}
|
||||
|
||||
public class ShopHeadOfShopAccountEditInput : ShopAccountAppService.ShopAccountEditInput
|
||||
{
|
||||
public long ShopId { get; set; }
|
||||
}
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopColleagueAccountPermissionDefinitionProvider.EditName)]
|
||||
[HttpPost("edit")]
|
||||
[OpAudit("编辑成员", "门店", OpAuditLogEventTarget.Head)]
|
||||
[UnitOfWork(true)]
|
||||
public async Task Edit([FromBody] ShopHeadOfShopAccountEditInput input, [FromServices] ShopAccountAppService service)
|
||||
{
|
||||
await pcHeadLevelChildCheckDomainService.InChildShopCheckByShopId(input.ShopId,
|
||||
User.GetCurrentShopHeadInfo().ShopHeadId);
|
||||
|
||||
opAuditContext.Update(x => x.AddTargetSysAccountWhenRequestNormal(input.ShopId, OpAuditLogEventTarget.Shop));
|
||||
|
||||
await service.Edit(input, input.ShopId);
|
||||
}
|
||||
public class ShopHeadOfShopAccountChangeGeneralAccountInput : ShopAccountAppService.ShopAccountChangeGeneralAccountInput
|
||||
{
|
||||
public long ShopId { get; set; }
|
||||
}
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopColleagueAccountPermissionDefinitionProvider.EditName)]
|
||||
[HttpPost("change-general-account")]
|
||||
[OpAudit("更换通用绑定账号", "店员", OpAuditLogEventTarget.Head)]
|
||||
[UnitOfWork(true)]
|
||||
public async Task ChangeGeneralAccount([FromBody] ShopHeadOfShopAccountChangeGeneralAccountInput input, [FromServices] ShopAccountAppService service)
|
||||
{
|
||||
await pcHeadLevelChildCheckDomainService.InChildShopCheckByShopId(input.ShopId,
|
||||
User.GetCurrentShopHeadInfo().ShopHeadId);
|
||||
opAuditContext.Update(x => x.AddTargetSysAccountWhenRequestNormal(input.ShopId, OpAuditLogEventTarget.Shop));
|
||||
|
||||
await service.ChangeGeneralAccount(input, input.ShopId);
|
||||
}
|
||||
|
||||
public class ShopHeadOfShopAccountDelInput : ShopAccountAppService.ShopAccountDelInput
|
||||
{
|
||||
|
||||
}
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopColleagueAccountPermissionDefinitionProvider.DelName)]
|
||||
[HttpPost("del")]
|
||||
[OpAudit("删除成员", "门店", OpAuditLogEventTarget.Head)]
|
||||
[UnitOfWork(true)]
|
||||
public async Task Del([FromBody] ShopHeadOfShopAccountDelInput inputs, [FromServices] ShopAccountAppService service)
|
||||
{
|
||||
|
||||
|
||||
foreach (var input in inputs.Items)
|
||||
{
|
||||
await pcHeadLevelChildCheckDomainService.InChildShopCheckByShopId(input.ShopId,
|
||||
User.GetCurrentShopHeadInfo().ShopHeadId);
|
||||
|
||||
opAuditContext.Update(x => x.AddTargetSysAccountWhenRequestNormal(input.ShopId, OpAuditLogEventTarget.Shop));
|
||||
await service.Del(input.Id, input.ShopId, input.Type);
|
||||
}
|
||||
}
|
||||
|
||||
/* [ShopHeadSystemBusinessVersionAuthorize(ShopOfColleagueAccountPermissionDefinitionProvider.EditName)]
|
||||
[HttpPost("change")]
|
||||
|
||||
[UnitOfWork(true)]
|
||||
public async Task<long> ChangeSuper([FromBody] ShopAccountAppService.ShopAccountAddInput input, [FromServices] ShopAccountAppService service)
|
||||
{
|
||||
if (input.Type == AdminType.SuperAdmin) user.CheckSuperAdmin();
|
||||
if (user.UserId == input.AccountId) throw Oops.Bah("更换的还是同一个账号").WithData(input.AccountId);
|
||||
|
||||
await service.Del(user.UserId, user.GetCurrentShopInfo().ShopId, input.Type);
|
||||
return await service.Add(input, user.GetCurrentShopInfo().ShopId, input.Type);
|
||||
}*/
|
||||
/// <summary>
|
||||
/// 启用
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopColleagueAccountPermissionDefinitionProvider.EnableName)]
|
||||
[HttpPost("enable")]
|
||||
[OpAudit("启用成员", "门店", OpAuditLogEventTarget.Head)]
|
||||
[UnitOfWork(true)]
|
||||
public async Task Enable([FromBody] ShopHeadOfShopAccountDelInput inputs, [FromServices] ShopAccountAppService service)
|
||||
{
|
||||
|
||||
foreach (var input in inputs.Items)
|
||||
{
|
||||
await pcHeadLevelChildCheckDomainService.InChildShopCheckByShopId(input.ShopId,
|
||||
User.GetCurrentShopHeadInfo().ShopHeadId);
|
||||
|
||||
|
||||
opAuditContext.Update(x => x.AddTargetSysAccountWhenRequestNormal(input.ShopId, OpAuditLogEventTarget.Shop));
|
||||
|
||||
await service.Enable(input.Id, input.ShopId, input.Type);
|
||||
}
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 禁用
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopColleagueAccountPermissionDefinitionProvider.DisableName)]
|
||||
[OpAudit("禁用成员", "门店", OpAuditLogEventTarget.Head)]
|
||||
|
||||
[UnitOfWork(true)]
|
||||
public async Task Disable([FromBody] ShopHeadOfShopAccountDelInput inputs, [FromServices] ShopAccountAppService service)
|
||||
{
|
||||
|
||||
|
||||
|
||||
foreach (var input in inputs.Items)
|
||||
{
|
||||
opAuditContext.Update(x => x.AddTargetSysAccountWhenRequestNormal(input.ShopId, OpAuditLogEventTarget.Shop));
|
||||
await pcHeadLevelChildCheckDomainService.InChildShopCheckByShopId(input.ShopId,
|
||||
User.GetCurrentShopHeadInfo().ShopHeadId);
|
||||
await service.Disable(input.Id, input.ShopId, input.Type);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class ShopHeadOfShopColleagueAccountPermissionDefinitionProvider : PermissionDefinitionProvider
|
||||
{
|
||||
|
||||
public const string GroupName = $"{ShopHeadFeatureDefinitionNames.Prefix}.shop.colleague.account";
|
||||
public const string ViewName = $"{GroupName}.view";
|
||||
public const string AddName = $"{GroupName}.add";
|
||||
public const string DelName = $"{GroupName}.del";
|
||||
public const string EditName = $"{GroupName}.edit";
|
||||
public const string EnableName = $"{GroupName}.enable";
|
||||
public const string DisableName = $"{GroupName}.disable";
|
||||
|
||||
|
||||
public override void Define(IPermissionDefinitionContext context)
|
||||
{
|
||||
{
|
||||
var groups = context.AddGroup($"{GroupName}", new FixedLocalizableString("店员"));
|
||||
|
||||
groups.AddPermission($"{ViewName}", new FixedLocalizableString("查看店员"))
|
||||
.RequireFeatures(ShopHeadOfShopColleagueAccountFeatureDefinitionProvider.ViewName);
|
||||
groups.AddPermission($"{AddName}", new FixedLocalizableString("添加"));
|
||||
groups.AddPermission($"{EditName}", new FixedLocalizableString("编辑"));
|
||||
groups.AddPermission($"{DelName}", new FixedLocalizableString("删除"));
|
||||
groups.AddPermission($"{EnableName}", new FixedLocalizableString("启用"));
|
||||
groups.AddPermission($"{DisableName}", new FixedLocalizableString("禁用"));
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
namespace JT.Shop.Application.Service.Business.Clerk
|
||||
{
|
||||
/// <summary>
|
||||
/// 店员列表
|
||||
/// </summary>
|
||||
public class BusinessClerkListInput : PageInputV2Base
|
||||
{
|
||||
/// <summary>
|
||||
/// 创建时间范围
|
||||
/// </summary>
|
||||
public DateRangeFilterInput CreateTimeRange { get; set; }
|
||||
public long? ChildParentHeadId { get; set; }
|
||||
public long? ShopId { get; set; }
|
||||
/// <summary>
|
||||
/// 店员名称
|
||||
/// </summary>
|
||||
public string Code { get; set; }
|
||||
/// <summary>
|
||||
/// 店员名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
public string Phone { get; set; }
|
||||
public HashSet<long> PosShareNameId { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
///状态
|
||||
/// </summary>
|
||||
public CommonStatus? Status { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 职位列表
|
||||
/// </summary>
|
||||
public class BusinessPostListInput : PageInputBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
using JT.Shop.Core;
|
||||
|
||||
namespace JT.Shop.Application.Service.Business.Clerk
|
||||
{
|
||||
/// <summary>
|
||||
/// 店员列表
|
||||
/// </summary>
|
||||
public class BusinessClerkListItemOutput : BaseIdAndUserInfo
|
||||
{
|
||||
public AdminType AdminType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 账号
|
||||
/// </summary>
|
||||
public string Account { get; set; }
|
||||
public long AccountId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 头像
|
||||
/// </summary>
|
||||
public string Avatar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 头像URL
|
||||
/// </summary>
|
||||
public string AvatarUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 姓名
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 联系电话
|
||||
/// </summary>
|
||||
public string Phone { get; set; }
|
||||
public string Mobile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 编号
|
||||
/// </summary>
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 性别
|
||||
/// </summary>
|
||||
public Gender Sex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 出生年月
|
||||
/// </summary>
|
||||
public string BirthDay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态
|
||||
/// </summary>
|
||||
public CommonStatus Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime CreatedTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 职位ID
|
||||
/// </summary>
|
||||
public long PosId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 职位名称
|
||||
/// </summary>
|
||||
public string PosName { get; set; }
|
||||
}
|
||||
|
||||
public class BusinessClerkListOutput: PageResultV2<BusinessClerkListItemOutput>
|
||||
{
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 职位列表
|
||||
/// </summary>
|
||||
public class BusinessPostListOutput : BaseIdAndUserInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 编码
|
||||
/// </summary>
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序
|
||||
/// </summary>
|
||||
public int Sort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
public string Remark { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,666 @@
|
|||
using JT.Shop.Application.Service.BaseCommon;
|
||||
using JT.Shop.Application.Service.ShopApi.Device;
|
||||
using JT.Shop.Application.Service.ShopHead;
|
||||
using JT.Shop.Domain.Entity.Business;
|
||||
using JT.Shop.Domain.Entity.ShopHead;
|
||||
using JT.Shop.Domain.FeatureDefinitions.ShopHead;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
|
||||
using Volo.Abp.Authorization.Permissions;
|
||||
using Volo.Abp.Features;
|
||||
using Volo.Abp.Localization;
|
||||
using Volo.Abp.Threading;
|
||||
|
||||
namespace JT.Shop.Application.Service.Business.Device
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备管理
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings("总部")]
|
||||
[Route("/api/business/[controller]")]
|
||||
public class DeviceService(DeviceAppService appService, UserManager UserInfo, IRepository<PC_DeviceAlloc> _deviceAllocRep, OpAuditContext opAuditContext, PcHeadLevelChildCheckDomainService headLevelChildCheckDomainService, IRepository<PC_Shop> _shopRep, IRepository<PcHead> headRepository, IPcDeviceQueryService pdPcDeviceQueryService, IPcShopHeadQueryService pcShopHeadQueryService, IRepository<PC_Device_Url> _pcDeviceUrl) : ITransient, IDynamicApiController
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备分配给总部
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[UnitOfWork(true)]
|
||||
[OpAudit("分配给下级总部", "设备", OpAuditLogEventTarget.Head)]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfDevicePermissionDefinitionProvider.AllocToHeadName)]
|
||||
public async Task AllocToHeadAsync(DeviceAllocC2SToShopHeadDto input)
|
||||
{
|
||||
var CurrentUser = UserInfo.GetCurrentAdminShopInfo();
|
||||
|
||||
var entity = await headRepository.DetachedEntities.Where(x => x.Id == input.BusinessId).FirstOrDefaultAsync();
|
||||
if (entity == null) throw Oops.Bah("下级总部不存在").WithData(input.BusinessId);
|
||||
await headLevelChildCheckDomainService.InChildHeadCheck(input.BusinessId, CurrentUser.ShopHeadId);
|
||||
|
||||
opAuditContext.Update(x => x.AddTargetSysAccountWhenRequestNormal(input.BusinessId, OpAuditLogEventTarget.Head));
|
||||
|
||||
await appService.AllocAsync(input.ids, 0, input.BusinessId, true, remark: "分配给下级总部");
|
||||
|
||||
/*if (!await _sysuserRep.DetachedEntities.AnyAsync(x => x.Id == input.BusinessId))
|
||||
{
|
||||
throw Oops.Bah("总部不存在");
|
||||
}
|
||||
//记录设备分配记录
|
||||
var alloclist = await _deviceRep.DetachedEntities.Where(x => input.ids.Contains(x.Id)).Select(x => new PC_DeviceAlloc
|
||||
{
|
||||
IsShowBusiness = CurrentUser.AccountType == AdminType.None,
|
||||
CreatedTime = DateTime.Now,
|
||||
CreatedUserId = CurrentUser.UserId,
|
||||
CreatedUserName = CurrentUser.Name,
|
||||
DeviceId = x.Id,
|
||||
FromBusinessId = x.BusinessId,
|
||||
FromShopId = x.ShopId,
|
||||
Remark = string.Empty,
|
||||
ToBusinessId = input.BusinessId,
|
||||
ToShopId = input.ShopId,
|
||||
Type = DeviceAllocType.ALLOC
|
||||
}).ToListAsync();
|
||||
alloclist.ForEach(it =>
|
||||
{
|
||||
it.Id = YitIdHelper.NextId();
|
||||
});
|
||||
if (!alloclist.IsEmpty())
|
||||
{
|
||||
await _deviceAllocRep.InsertAsync(alloclist);
|
||||
}
|
||||
// 更新设备所属的客户ID和门店ID
|
||||
await _deviceRep.Where(x => input.ids.Contains(x.Id)).UpdateAsync(x => new PC_Device
|
||||
{
|
||||
BusinessId = input.BusinessId,
|
||||
ShopId = input.ShopId,
|
||||
UpdatedTime = DateTime.Now,
|
||||
UpdatedUserId = CurrentUser.UserId,
|
||||
UpdatedUserName = CurrentUser.Name
|
||||
});*/
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备分配
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[UnitOfWork(true)]
|
||||
[OpAudit("分配给门店", "设备", OpAuditLogEventTarget.Head)]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfDevicePermissionDefinitionProvider.AllocToShopName)]
|
||||
public async Task AllocToShopAsync(DeviceAllocC2SToShopDto input)
|
||||
{
|
||||
var CurrentUser = UserInfo.GetCurrentAdminShopInfo();
|
||||
|
||||
var entity = await _shopRep.DetachedEntities.Where(x => x.Id == input.ShopId).FirstOrDefaultAsync();
|
||||
if (entity == null) throw Oops.Bah("门店不存在").WithData(input.ShopId);
|
||||
await headLevelChildCheckDomainService.InChildShopCheck(entity.BusinessId, CurrentUser.ShopHeadId);
|
||||
|
||||
opAuditContext.Update(x => x.AddTargetSysAccountWhenRequestNormal(input.ShopId, OpAuditLogEventTarget.Shop));
|
||||
|
||||
await appService.AllocAsync(input.ids, input.ShopId, entity.BusinessId, true, remark: "分配给门店");
|
||||
|
||||
/*if (!await _shopRep.DetachedEntities.AnyAsync(x => x.Id == input.ShopId))
|
||||
{
|
||||
throw Oops.Bah("门店不存在");
|
||||
}
|
||||
if (!await _sysuserRep.DetachedEntities.AnyAsync(x => x.Id == input.BusinessId))
|
||||
{
|
||||
throw Oops.Bah("总部不存在");
|
||||
}
|
||||
//记录设备分配记录
|
||||
var alloclist = await _deviceRep.DetachedEntities.Where(x => input.ids.Contains(x.Id)).Select(x => new PC_DeviceAlloc
|
||||
{
|
||||
IsShowBusiness = CurrentUser.AccountType == AdminType.None,
|
||||
CreatedTime = DateTime.Now,
|
||||
CreatedUserId = CurrentUser.UserId,
|
||||
CreatedUserName = CurrentUser.Name,
|
||||
DeviceId = x.Id,
|
||||
FromBusinessId = x.BusinessId,
|
||||
FromShopId = x.ShopId,
|
||||
Remark = string.Empty,
|
||||
ToBusinessId = input.BusinessId,
|
||||
ToShopId = input.ShopId,
|
||||
Type = DeviceAllocType.ALLOC
|
||||
}).ToListAsync();
|
||||
alloclist.ForEach(it =>
|
||||
{
|
||||
it.Id = YitIdHelper.NextId();
|
||||
});
|
||||
if (!alloclist.IsEmpty())
|
||||
{
|
||||
await _deviceAllocRep.InsertAsync(alloclist);
|
||||
}
|
||||
// 更新设备所属的客户ID和门店ID
|
||||
await _deviceRep.Where(x => input.ids.Contains(x.Id)).UpdateAsync(x => new PC_Device
|
||||
{
|
||||
BusinessId = input.BusinessId,
|
||||
Status = DeviceStatus.Run,
|
||||
ShopId = input.ShopId,
|
||||
UpdatedTime = DateTime.Now,
|
||||
UpdatedUserId = CurrentUser.UserId,
|
||||
UpdatedUserName = CurrentUser.Name
|
||||
});*/
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询设备分配记录
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfDevicePermissionDefinitionProvider.ViewName)]
|
||||
public async Task<List<DeviceAllocListSCDto>> AllocListAsync(BaseId input)
|
||||
{
|
||||
var CurrentUser = UserInfo.GetCurrentAdminShopInfo();
|
||||
|
||||
return await appService.AllocListAsync(input, true);
|
||||
|
||||
|
||||
/* var list = await _deviceAllocRep.DetachedEntities
|
||||
.Where(x => x.DeviceId == input.Id)
|
||||
.Where(CurrentUser.AccountType == AdminType.None, x => x.IsShowBusiness == true)
|
||||
.OrderByDescending(x => x.CreatedTime).ProjectToType<DeviceAllocListSCDto>().ToListAsync();
|
||||
List<long> bids = new List<long>();
|
||||
List<long> shopids = new List<long>();
|
||||
foreach (var item in list)
|
||||
{
|
||||
if (!bids.Contains(item.FromBusinessId))
|
||||
{
|
||||
bids.Add(item.FromBusinessId);
|
||||
}
|
||||
if (!bids.Contains(item.ToBusinessId))
|
||||
{
|
||||
bids.Add(item.ToBusinessId);
|
||||
}
|
||||
if (!shopids.Contains(item.FromShopId))
|
||||
{
|
||||
shopids.Add(item.FromShopId);
|
||||
}
|
||||
if (!shopids.Contains(item.ToShopId))
|
||||
{
|
||||
shopids.Add(item.ToShopId);
|
||||
}
|
||||
}
|
||||
var allbuss = await _sysuserRep.DetachedEntities.Where(x => bids.Contains(x.Id))
|
||||
.Select(x => new SysUser
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name
|
||||
})
|
||||
.ToListAsync();
|
||||
var allshop = await _shopRep.DetachedEntities.Where(x => shopids.Contains(x.Id)).Select(x => new PC_Shop
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name
|
||||
}).ToListAsync();
|
||||
list.ForEach(it =>
|
||||
{
|
||||
var buss = allbuss.FirstOrDefault(x => x.Id == it.FromBusinessId);
|
||||
it.FromBusiness = buss != null ? buss.Name : "";
|
||||
buss = allbuss.FirstOrDefault(x => x.Id == it.ToBusinessId);
|
||||
it.ToBusiness = buss != null ? buss.Name : "";
|
||||
var shop = allshop.FirstOrDefault(x => x.Id == it.FromShopId);
|
||||
it.FromShop = shop != null ? shop.Name : "";
|
||||
shop = allshop.FirstOrDefault(x => x.Id == it.ToShopId);
|
||||
it.ToShop = shop != null ? shop.Name : "";
|
||||
});
|
||||
return list;*/
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取设备列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfDevicePermissionDefinitionProvider.ViewName)]
|
||||
public async Task<DeviceListS2CDto> ListAsync(DeviceListC2SDto input, [FromServices] PCShopSettingProvider pcShopSettingProvider)
|
||||
{
|
||||
var CurrentUser = UserInfo.GetCurrentAdminShopInfo();
|
||||
|
||||
|
||||
|
||||
var list = /*await _deviceRep.DetachedEntities
|
||||
.Where(CurrentUser.AccountType == AdminType.None, x => x.BusinessId == CurrentUser.ShopHeadId)
|
||||
.Where(CurrentUser.AccountType == AdminType.None, x => _deviceAllocRep.DetachedEntities.Where(e => e.ToBusinessId == CurrentUser.UserId && e.Type != DeviceAllocType.RETURN && e.DeviceId == x.Id).Any()
|
||||
|| x.BusinessId == CurrentUser.ShopHeadId
|
||||
)
|
||||
.Where(!input.ECode.IsEmpty(), x => x.Ecode == input.ECode)
|
||||
.Where(input.Status != 0, x => x.Status == input.Status)
|
||||
.Where(input.DevType > 0, x => x.Type == input.DevType)
|
||||
.OrderByDescending(x => x.CreatedTime)
|
||||
.ProjectToType<DeviceListS2CDto>()
|
||||
.ToADPagedListAsync(input.PageNo, input.PageSize)*/(await pdPcDeviceQueryService.GetAllChildList(CurrentUser.ShopHeadId, input.ChildParentHeadId, input.ShopId, input.Status, input.DevType, input.ECode, input.FacCode, input.Search, input)).Adapt<DeviceListS2CDto>();
|
||||
//if (CurrentUser.AccountType != AdminType.None)
|
||||
{
|
||||
var alluserid = list.Rows.Select(x => x.BusinessId).ToHashSet();
|
||||
var alluser = await pcShopHeadQueryService.Get(alluserid) /* await _sysuserRep.GetAllNoFilterAsync(x => alluserid.Contains(x.Id), x => new SysUser
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name
|
||||
})*/;
|
||||
var allshopid = list.Rows.Select(x => x.ShopId).ToList();
|
||||
var allshop = await _shopRep.DetachedEntities.Where(x => allshopid.Contains(x.Id)).Select(x => new PC_Shop
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name
|
||||
}).ToListAsync();
|
||||
list.Rows.ToList().ForEach(it =>
|
||||
{
|
||||
//var user = alluser.FirstOrDefault(x => x.Id == it.BusinessId);
|
||||
if (alluser.TryGetValue(it.BusinessId, out var user))
|
||||
{
|
||||
it.BusinessName = user.Name;
|
||||
it.BusinessCode = user.Code;
|
||||
}
|
||||
var shop = allshop.FirstOrDefault(x => x.Id == it.ShopId);
|
||||
if (!shop.IsEmpty())
|
||||
{
|
||||
it.ShopName = shop.Name;
|
||||
}
|
||||
|
||||
it.Url = (AsyncHelper.RunSync(() => pcShopSettingProvider.GetWXClientType(it.ShopId))).DeviceEntryUrl(it.Id);
|
||||
});
|
||||
}
|
||||
/* else if (CurrentUser.AccountType == AdminType.None)
|
||||
{
|
||||
var alluserid = list.Rows.Select(x => x.BusinessId).ToList();
|
||||
var alluser = await _sysuserRep.GetAllNoFilterAsync(x => alluserid.Contains(x.Id), x => new SysUser
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name
|
||||
});
|
||||
var allshopid = list.Rows.Select(x => x.ShopId).ToList();
|
||||
var allshop = await _shopRep.DetachedEntities.Where(x => allshopid.Contains(x.Id)).Select(x => new PC_Shop
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name
|
||||
}).ToListAsync();
|
||||
list.Rows.ToList().ForEach(it =>
|
||||
{
|
||||
var user = alluser.FirstOrDefault(x => x.Id == it.BusinessId);
|
||||
if (!user.IsEmpty())
|
||||
{
|
||||
it.BusinessName = user.Name;
|
||||
}
|
||||
var shop = allshop.FirstOrDefault(x => x.Id == it.ShopId);
|
||||
if (!shop.IsEmpty())
|
||||
{
|
||||
it.ShopName = shop.Name;
|
||||
}
|
||||
});
|
||||
}*/
|
||||
|
||||
//设备二维码跳转小程序
|
||||
try
|
||||
{
|
||||
var urlList = await _pcDeviceUrl.DetachedEntities.ToListAsync();
|
||||
if (urlList.Any())
|
||||
{
|
||||
list.Rows.ToList().ForEach(it =>
|
||||
{
|
||||
var info = urlList.Where(s => s.DeviceId == it.Id).FirstOrDefault();
|
||||
if (info != null)
|
||||
{
|
||||
it.Url = info.Url;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备从门店回收
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[UnitOfWork(true)]
|
||||
[OpAudit("从门店回收", "设备", OpAuditLogEventTarget.Head)]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfDevicePermissionDefinitionProvider.RecycleFromShopName)]
|
||||
public async Task RecycleFromShopAsync(DeviceRecycleC2SDto input)
|
||||
{
|
||||
var CurrentUser = UserInfo.GetCurrentAdminShopInfo();
|
||||
|
||||
await appService.RecycleAsync(input, ToBusinessId: CurrentUser.BusinessId, IsShowBusiness: true,
|
||||
async d =>
|
||||
{
|
||||
if (d.FromShopId == 0 /*&& d.FromBusinessId == CurrentUser.ShopHeadId*/)
|
||||
{
|
||||
throw Oops.Bah("重复回收").WithData(new { d.Id });
|
||||
}
|
||||
await headLevelChildCheckDomainService.InChildShopCheck(d.FromBusinessId, CurrentUser.ShopHeadId);
|
||||
|
||||
if (d.FromShopId > 0)//如果已分配给门店
|
||||
opAuditContext.Update(x => x.AddTargetSysAccountWhenRequestNormal(d.FromShopId, OpAuditLogEventTarget.Shop));
|
||||
//else if (d.FromBusinessId != CurrentUser.ShopHeadId)//如果已分配给其他总部
|
||||
// opAuditContext.Update(x => x.AddTargetSysAccountWhenRequestNormal(d.FromBusinessId, OpAuditLogEventTarget.Head));
|
||||
|
||||
}, remark: "总部回收");
|
||||
|
||||
|
||||
/*var userid = CurrentUser.AccountType == AdminType.None ? CurrentUser.UserId : 0;
|
||||
//记录设备分配记录
|
||||
var alloclist = await _deviceRep.DetachedEntities.Where(x => input.ids.Contains(x.Id)).Select(x => new PC_DeviceAlloc
|
||||
{
|
||||
IsShowBusiness = CurrentUser.AccountType == AdminType.None ? true : false,
|
||||
CreatedTime = DateTime.Now,
|
||||
CreatedUserId = CurrentUser.UserId,
|
||||
CreatedUserName = CurrentUser.Name,
|
||||
DeviceId = x.Id,
|
||||
FromBusinessId = x.BusinessId,
|
||||
FromShopId = x.ShopId,
|
||||
Remark = string.Empty,
|
||||
ToBusinessId = userid,
|
||||
ToShopId = 0,
|
||||
Type = DeviceAllocType.RETURN
|
||||
}).ToListAsync();
|
||||
alloclist.ForEach(it =>
|
||||
{
|
||||
it.Id = YitIdHelper.NextId();
|
||||
});
|
||||
if (!alloclist.IsEmpty())
|
||||
{
|
||||
await _deviceAllocRep.InsertAsync(alloclist);
|
||||
}
|
||||
// 更新设备所属的客户ID
|
||||
await _deviceRep.Where(x => input.ids.Contains(x.Id)).UpdateAsync(x => new PC_Device
|
||||
{
|
||||
BusinessId = userid,
|
||||
ShopId = 0,
|
||||
UpdatedTime = DateTime.Now,
|
||||
UpdatedUserId = CurrentUser.UserId,
|
||||
UpdatedUserName = CurrentUser.Name
|
||||
});*/
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备从总部回收
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[UnitOfWork(true)]
|
||||
[OpAudit("从下级总部回收", "设备", OpAuditLogEventTarget.Head)]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfDevicePermissionDefinitionProvider.RecycleFromHeadName)]
|
||||
public async Task RecycleFromHeadAsync(DeviceRecycleC2SDto input)
|
||||
{
|
||||
var CurrentUser = UserInfo.GetCurrentAdminShopInfo();
|
||||
|
||||
await appService.RecycleAsync(input, ToBusinessId: CurrentUser.BusinessId, IsShowBusiness: true,
|
||||
async d =>
|
||||
{
|
||||
if (d.FromShopId > 0)
|
||||
{
|
||||
throw Oops.Bah("尚未从门店回收").WithData(new { d.Id, d.FromShopId });
|
||||
}
|
||||
|
||||
if (d.FromBusinessId == CurrentUser.ShopHeadId)
|
||||
{
|
||||
throw Oops.Bah("重复回收").WithData(new { d.Id, d.FromBusinessId });
|
||||
}
|
||||
await headLevelChildCheckDomainService.InChildHeadCheck(d.FromBusinessId, CurrentUser.ShopHeadId);
|
||||
|
||||
/*if (d.FromShopId > 0)//如果已分配给门店
|
||||
opAuditContext.Update(x => x.AddTargetSysAccountWhenRequestNormal(d.FromShopId, OpAuditLogEventTarget.Shop));
|
||||
else*/
|
||||
if (d.FromBusinessId != CurrentUser.ShopHeadId)//如果已分配给其他总部
|
||||
opAuditContext.Update(x => x.AddTargetSysAccountWhenRequestNormal(d.FromBusinessId, OpAuditLogEventTarget.Head));
|
||||
|
||||
}, remark: "总部回收");
|
||||
|
||||
|
||||
/*var userid = CurrentUser.AccountType == AdminType.None ? CurrentUser.UserId : 0;
|
||||
//记录设备分配记录
|
||||
var alloclist = await _deviceRep.DetachedEntities.Where(x => input.ids.Contains(x.Id)).Select(x => new PC_DeviceAlloc
|
||||
{
|
||||
IsShowBusiness = CurrentUser.AccountType == AdminType.None ? true : false,
|
||||
CreatedTime = DateTime.Now,
|
||||
CreatedUserId = CurrentUser.UserId,
|
||||
CreatedUserName = CurrentUser.Name,
|
||||
DeviceId = x.Id,
|
||||
FromBusinessId = x.BusinessId,
|
||||
FromShopId = x.ShopId,
|
||||
Remark = string.Empty,
|
||||
ToBusinessId = userid,
|
||||
ToShopId = 0,
|
||||
Type = DeviceAllocType.RETURN
|
||||
}).ToListAsync();
|
||||
alloclist.ForEach(it =>
|
||||
{
|
||||
it.Id = YitIdHelper.NextId();
|
||||
});
|
||||
if (!alloclist.IsEmpty())
|
||||
{
|
||||
await _deviceAllocRep.InsertAsync(alloclist);
|
||||
}
|
||||
// 更新设备所属的客户ID
|
||||
await _deviceRep.Where(x => input.ids.Contains(x.Id)).UpdateAsync(x => new PC_Device
|
||||
{
|
||||
BusinessId = userid,
|
||||
ShopId = 0,
|
||||
UpdatedTime = DateTime.Now,
|
||||
UpdatedUserId = CurrentUser.UserId,
|
||||
UpdatedUserName = CurrentUser.Name
|
||||
});*/
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改设备状态
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[UnitOfWork(true)]
|
||||
[OpAudit("启用", "设备", OpAuditLogEventTarget.Head)]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfDevicePermissionDefinitionProvider.EnableName)]
|
||||
public async Task Enable(DeviceStatusC2SDto input)
|
||||
{
|
||||
var CurrentUser = UserInfo.GetCurrentAdminShopInfo();
|
||||
|
||||
await appService.SetStatusAsync(input, async d =>
|
||||
{
|
||||
if (d.ShopId > 0)
|
||||
await headLevelChildCheckDomainService.InChildShopCheck(d.BusinessId, CurrentUser.ShopHeadId);
|
||||
else
|
||||
await headLevelChildCheckDomainService.InChildHeadCheck(d.BusinessId, CurrentUser.ShopHeadId);
|
||||
|
||||
opAuditContext.Update(x =>
|
||||
{
|
||||
if (d.ShopId > 0)//如果已分配给门店
|
||||
opAuditContext.Update(x => x.AddTargetSysAccountWhenRequestNormal(d.ShopId, OpAuditLogEventTarget.Shop));
|
||||
});
|
||||
}, DeviceStatus.Run);
|
||||
}
|
||||
[UnitOfWork(true)]
|
||||
[OpAudit("禁用", "设备", OpAuditLogEventTarget.Head)]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfDevicePermissionDefinitionProvider.DisableName)]
|
||||
public async Task Disable(DeviceStatusC2SDto input)
|
||||
{
|
||||
var CurrentUser = UserInfo.GetCurrentAdminShopInfo();
|
||||
|
||||
await appService.SetStatusAsync(input, async d =>
|
||||
{
|
||||
if (d.ShopId > 0)
|
||||
await headLevelChildCheckDomainService.InChildShopCheck(d.BusinessId, CurrentUser.ShopHeadId);
|
||||
else
|
||||
await headLevelChildCheckDomainService.InChildHeadCheck(d.BusinessId, CurrentUser.ShopHeadId);
|
||||
|
||||
opAuditContext.Update(x =>
|
||||
{
|
||||
if (d.ShopId > 0)//如果已分配给门店
|
||||
opAuditContext.Update(x => x.AddTargetSysAccountWhenRequestNormal(d.ShopId, OpAuditLogEventTarget.Shop));
|
||||
});
|
||||
}, DeviceStatus.Stop);
|
||||
}
|
||||
[UnitOfWork(true)]
|
||||
[OpAudit("手动添加", "设备", OpAuditLogEventTarget.Head)]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfDevicePermissionDefinitionProvider.AddName)]
|
||||
public async Task SubmitAddAsync(DeviceSubmitC2SDto input, [FromServices] IRepository<PC_Device> _deviceRepository, [FromServices] IFeatureChecker _featureChecker)
|
||||
{
|
||||
var CurrentUser = UserInfo.GetCurrentShopHeadInfo();
|
||||
|
||||
{
|
||||
var maxLimitCount = await _featureChecker.GetAsync<int>(ShopHeadOfDeviceFeatureDefinitionProvider.LIMIT_MAX);
|
||||
if (await _deviceRepository
|
||||
.DetachedEntities
|
||||
.Where(x => x.BusinessId == CurrentUser.ShopHeadId)
|
||||
.CountAsync() >= maxLimitCount)
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.LIMIT_MAX_COUNT10001, maxLimitCount);
|
||||
}
|
||||
}
|
||||
|
||||
await appService.SubmitAddAsync(input, true, ToBusinessId: CurrentUser.BusinessId, ToShopId: 0, FromBusinessId: CurrentUser.BusinessId, FromShopId: 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备信息修改
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[UnitOfWork(true)]
|
||||
[OpAudit("手动修改", "设备", OpAuditLogEventTarget.Head)]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfDevicePermissionDefinitionProvider.EditName)]
|
||||
|
||||
public async Task SubmitEditAsync(DeviceSubmitC2SDto input)
|
||||
{
|
||||
var CurrentUser = UserInfo.GetCurrentAdminShopInfo();
|
||||
var headId = CurrentUser.BusinessId;
|
||||
if (!await _deviceAllocRep
|
||||
.DetachedEntities
|
||||
.Where(x => /*x.ToShopId == shopId &&*/x.DeviceId == input.Id && x.FromBusinessId == headId && x.FromShopId == 0 && x.Type == DeviceAllocType.Add)
|
||||
.AnyAsync())
|
||||
{
|
||||
throw Oops.Bah("不能修改非本总部手动添加的设备");
|
||||
}
|
||||
|
||||
await appService.SubmitEditAsync(input, async d =>
|
||||
{
|
||||
await headLevelChildCheckDomainService.InChildShopCheck(d.BusinessId, CurrentUser.ShopHeadId);
|
||||
|
||||
if (d.ShopId > 0)//如果已分配给门店
|
||||
opAuditContext.Update(x => x.AddTargetSysAccountWhenRequestNormal(d.ShopId, OpAuditLogEventTarget.Shop));
|
||||
|
||||
|
||||
});
|
||||
|
||||
/* // 检查序列号是否重复
|
||||
if (await _deviceRep.DetachedEntities
|
||||
.Where(x => x.FacCode == input.FacCode)
|
||||
.Where(!input.Id.IsEmpty(), x => x.Id != input.Id)
|
||||
.AnyAsync())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PD1001);
|
||||
}
|
||||
var data = await _deviceRep.Where(x => x.Ecode == input.ECode)
|
||||
.Where(!input.Id.IsEmpty(), x => x.Id != input.Id).FirstOrDefaultAsync();
|
||||
// 检查机器码是否重复
|
||||
if (!data.IsEmpty())
|
||||
{
|
||||
throw Oops.Bah($"此机器码已绑定序列号{data.FacCode}");
|
||||
}
|
||||
data = input.Adapt<PC_Device>();
|
||||
if (input.Id.IsEmpty())
|
||||
{
|
||||
data.Id = YitIdHelper.NextId();
|
||||
data.Status = DeviceStatus.Run;
|
||||
data.BusinessId = 0;
|
||||
data.ShopId = 0;
|
||||
await _deviceRep.InsertNowAsync(data);
|
||||
//增加分配记录
|
||||
await _deviceAllocRep.InsertNowAsync(new PC_DeviceAlloc
|
||||
{
|
||||
Id = YitIdHelper.NextId(),
|
||||
IsShowBusiness = false,
|
||||
CreatedTime = DateTime.Now,
|
||||
CreatedUserId = CurrentUser.UserId,
|
||||
CreatedUserName = CurrentUser.Name,
|
||||
DeviceId = data.Id,
|
||||
FromBusinessId = 0,
|
||||
FromShopId = 0,
|
||||
Remark = "设备手动添加",
|
||||
ToBusinessId = 0,
|
||||
ToShopId = 0,
|
||||
Type = DeviceAllocType.Add
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
await _deviceRep.UpdateIncludeNowAsync(data, new[] { nameof(data.Ecode), nameof(data.Type), nameof(data.Name), nameof(data.Remark), nameof(data.FacCode) });
|
||||
}*/
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下载设备门店二维码
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[ShopHeadSystemBusinessVersionAuthorize]
|
||||
public async Task<string> DownLoadImgAsync(BaseId input, [FromServices] DeviceQrImgDownloadService pcShopSettingProvider)
|
||||
{
|
||||
return await pcShopSettingProvider.DeviceQrImgDownload(input.Id);
|
||||
}
|
||||
}
|
||||
|
||||
public class ShopHeadOfDevicePermissionDefinitionProvider : PermissionDefinitionProvider
|
||||
{
|
||||
|
||||
|
||||
public const string GroupName = $"{ShopHeadPermissionDefinitionNames.Prefix}.device";
|
||||
public const string ViewName = $"{GroupName}.view";
|
||||
public const string AddName = $"{GroupName}.add";
|
||||
|
||||
public const string AllocToShopName = $"{GroupName}.alloc.shop";
|
||||
public const string RecycleFromShopName = $"{GroupName}.recycle.shop";
|
||||
|
||||
public const string AllocToHeadName = $"{GroupName}.alloc.head";
|
||||
public const string RecycleFromHeadName = $"{GroupName}.recycle.head";
|
||||
|
||||
|
||||
public const string EditName = $"{GroupName}.edit";
|
||||
public const string EnableName = $"{GroupName}.enable";
|
||||
public const string DisableName = $"{GroupName}.disable";
|
||||
|
||||
|
||||
public override void Define(IPermissionDefinitionContext context)
|
||||
{
|
||||
{
|
||||
var groups = context.AddGroup($"{GroupName}", new FixedLocalizableString("设备管理"));
|
||||
|
||||
groups.AddPermission($"{ViewName}", new FixedLocalizableString("查看"))
|
||||
.RequireFeatures(ShopHeadOfDeviceFeatureDefinitionProvider.ViewName);
|
||||
|
||||
groups.AddPermission($"{AddName}", new FixedLocalizableString("添加"))
|
||||
.RequirePermissions(ViewName)
|
||||
.RequireFeatures(ShopHeadOfDeviceFeatureDefinitionProvider.AddName);
|
||||
groups.AddPermission($"{EditName}", new FixedLocalizableString("编辑"))
|
||||
.RequirePermissions(ViewName)
|
||||
.RequireFeatures(ShopHeadOfDeviceFeatureDefinitionProvider.AddName);
|
||||
|
||||
groups.AddPermission($"{AllocToShopName}", new FixedLocalizableString("分配给门店"))
|
||||
.RequirePermissions(ViewName)
|
||||
.RequireFeatures(ShopHeadOfDeviceFeatureDefinitionProvider.AllocToShopName);
|
||||
groups.AddPermission($"{RecycleFromShopName}", new FixedLocalizableString("从门店回收"))
|
||||
.RequirePermissions(ViewName)
|
||||
.RequireFeatures(ShopHeadOfDeviceFeatureDefinitionProvider.RecycleFromShopName);
|
||||
groups.AddPermission($"{AllocToHeadName}", new FixedLocalizableString("分配给下级总部"))
|
||||
.RequirePermissions(ViewName)
|
||||
.RequireFeatures(ShopHeadOfDeviceFeatureDefinitionProvider.AllocToHeadName);
|
||||
groups.AddPermission($"{RecycleFromHeadName}", new FixedLocalizableString("从下级总部回收"))
|
||||
.RequirePermissions(ViewName)
|
||||
.RequireFeatures(ShopHeadOfDeviceFeatureDefinitionProvider.RecycleFromHeadName);
|
||||
groups.AddPermission($"{EnableName}", new FixedLocalizableString("启用"))
|
||||
.RequirePermissions(ViewName)
|
||||
.RequireFeatures(ShopHeadOfDeviceFeatureDefinitionProvider.EnableName);
|
||||
groups.AddPermission($"{DisableName}", new FixedLocalizableString("禁用"))
|
||||
.RequirePermissions(ViewName)
|
||||
.RequireFeatures(ShopHeadOfDeviceFeatureDefinitionProvider.DisableName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
namespace JT.Shop.Application.Service.Business.Device.Dto
|
||||
{
|
||||
/// <summary>
|
||||
/// 映射
|
||||
/// </summary>
|
||||
public class CMapper : IRegister
|
||||
{
|
||||
/// <summary>
|
||||
/// 映射配置
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
public void Register(TypeAdapterConfig config)
|
||||
{
|
||||
config.ForType<DeviceTypeSubmitC2SDto, PC_DeviceType>()
|
||||
.Map(dest => dest.Desc, src => src.Desc.ToStrNoEmpty())
|
||||
.Map(dest => dest.SupType, src => string.Empty)
|
||||
.Map(dest => dest.Pic, src => src.Pic.ToStrNoEmpty())
|
||||
.Map(dest => dest.BleUrl, src => src.BleUrl.ToStrNoEmpty())
|
||||
;
|
||||
config.ForType<PC_DeviceType, DeviceTypeListS2CDto>()
|
||||
.Map(dest => dest.PicUrl, src => src.Pic.ImgFile())
|
||||
;
|
||||
//设备编辑
|
||||
config.ForType<DeviceSubmitC2SDto, PC_Device>()
|
||||
.Map(dest => dest.Remark, src => src.Remark.ToStrNoEmpty())
|
||||
.Map(dest => dest.Name, src => src.Name.ToStrNoEmpty())
|
||||
.Map(dest => dest.FacCode, src => src.FacCode.ToStrNoEmpty())
|
||||
.Map(dest => dest.Ecode, src => src.ECode.ToStrNoEmpty())
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,243 @@
|
|||
namespace JT.Shop.Application.Service.Business.Device
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备回收
|
||||
/// </summary>
|
||||
public class DeviceRecycleC2SDto : IValidatableObject
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备列表
|
||||
/// </summary>
|
||||
public List<long> ids { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 验证
|
||||
/// </summary>
|
||||
/// <param name="validationContext"></param>
|
||||
/// <returns></returns>
|
||||
public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (ids.IsEmpty())
|
||||
{
|
||||
yield return new ValidationResult("请先选择设备", new[] { nameof(ids) });
|
||||
}
|
||||
if (ids.Count > 100)
|
||||
{
|
||||
yield return new ValidationResult("一次最多可回收100台设备", new[] { nameof(ids) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备分配给门店
|
||||
/// </summary>
|
||||
public class DeviceAllocC2SToShopDto : DeviceRecycleC2SDto, IValidatableObject
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 门店ID
|
||||
/// </summary>
|
||||
public long ShopId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 验证
|
||||
/// </summary>
|
||||
/// <param name="validationContext"></param>
|
||||
/// <returns></returns>
|
||||
public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
|
||||
foreach (var validationResult in base.Validate(validationContext)) yield return validationResult;
|
||||
//if (ids.IsEmpty())
|
||||
//{
|
||||
// yield return new ValidationResult("请先选择设备", new[] { nameof(ids) });
|
||||
//}
|
||||
//if (ids.Count > 100)
|
||||
//{
|
||||
// yield return new ValidationResult("一次最多可分配100台设备", new[] { nameof(ids) });
|
||||
//}
|
||||
if (ShopId.IsEmpty())
|
||||
{
|
||||
yield return new ValidationResult("请先选择门店", new[] { nameof(ShopId) });
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 设备分配给总部
|
||||
/// </summary>
|
||||
public class DeviceAllocC2SToShopHeadDto : DeviceRecycleC2SDto, IValidatableObject
|
||||
{
|
||||
/// <summary>
|
||||
/// 客户ID
|
||||
/// </summary>
|
||||
public long BusinessId { get; set; }
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 验证
|
||||
/// </summary>
|
||||
/// <param name="validationContext"></param>
|
||||
/// <returns></returns>
|
||||
public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
|
||||
foreach (var validationResult in base.Validate(validationContext)) yield return validationResult;
|
||||
//if (ids.IsEmpty())
|
||||
//{
|
||||
// yield return new ValidationResult("请先选择设备", new[] { nameof(ids) });
|
||||
//}
|
||||
//if (ids.Count > 100)
|
||||
//{
|
||||
// yield return new ValidationResult("一次最多可分配100台设备", new[] { nameof(ids) });
|
||||
//}
|
||||
if (BusinessId.IsEmpty())
|
||||
{
|
||||
yield return new ValidationResult("请先选择总部", new[] { nameof(BusinessId) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备信息修改
|
||||
/// </summary>
|
||||
public class DeviceSubmitC2SDto : BaseNullId, IValidatableObject
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备名称
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "设备名称不可为空"), MaxLength(50, ErrorMessage = "设备名称最多50个字")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 机器码,唯一
|
||||
/// </summary>
|
||||
[MaxLength(50, ErrorMessage = "机器码最多50个字")]
|
||||
public string ECode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备序列号,唯一
|
||||
/// </summary>
|
||||
[MaxLength(50, ErrorMessage = "设备序列号最多50个字")]
|
||||
public string FacCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备类型 1 wifi 2 蓝牙
|
||||
/// </summary>
|
||||
public int Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 说明
|
||||
/// </summary>
|
||||
[MaxLength(200, ErrorMessage = "说明最多200个字")]
|
||||
public string Remark { get; set; }
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
//wifi秤
|
||||
if (Type == 1 && string.IsNullOrWhiteSpace(ECode))
|
||||
{
|
||||
yield return new ValidationResult("Wifi秤设备【机器码】必填", new[] { nameof(ECode) });
|
||||
}
|
||||
//蓝牙秤
|
||||
if (Type == 2 && string.IsNullOrWhiteSpace(FacCode))
|
||||
{
|
||||
yield return new ValidationResult("蓝牙秤设备【序列号】必填", new[] { nameof(FacCode) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取设备列表
|
||||
/// </summary>
|
||||
public class DeviceListC2SDto : PageInputV2Base
|
||||
{
|
||||
public long? ChildParentHeadId { get; set; }
|
||||
public long? ShopId { get; set; }
|
||||
/// <summary>
|
||||
/// 设备机器码
|
||||
/// </summary>
|
||||
public string ECode { get; set; }
|
||||
/// <summary>
|
||||
/// 序列号
|
||||
/// </summary>
|
||||
public string FacCode { get; set; }
|
||||
/// <summary>
|
||||
/// 设备机器码或序列号
|
||||
/// </summary>
|
||||
public string Search { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备状态
|
||||
/// </summary>
|
||||
public HashSet<DeviceStatus> Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备类型
|
||||
/// </summary>
|
||||
public HashSet<int> DevType { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备状态修改
|
||||
/// </summary>
|
||||
public class DeviceStatusC2SDto : BaseId
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备类型列表
|
||||
/// </summary>
|
||||
public class DeviceTypeListC2SDto : PageInputBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备类型名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备类型编号
|
||||
/// </summary>
|
||||
public int Code { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备类型提交
|
||||
/// </summary>
|
||||
public class DeviceTypeSubmitC2SDto : BaseNullId
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备类型名称
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "设备类型名称不可为空"), MaxLength(50, ErrorMessage = "设备类型名称最多50个字")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备类型编号
|
||||
/// </summary>
|
||||
public int? Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型图片
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "类型图片不可为空")]
|
||||
public string Pic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型描述
|
||||
/// </summary>
|
||||
[MaxLength(200, ErrorMessage = "类型描述最多200个字")]
|
||||
public string Desc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 蓝牙协议类型
|
||||
/// </summary>
|
||||
public DeviceProType ProType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 蓝牙跳转地址
|
||||
/// </summary>
|
||||
public string BleUrl { get; set; } = "";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,157 @@
|
|||
namespace JT.Shop.Application.Service.Business.Device
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备分配记录
|
||||
/// </summary>
|
||||
public class DeviceAllocListSCDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 原先设备所属客户ID
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public long FromBusinessId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 原先设备所属店铺ID
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public long FromShopId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 现设备所属客户ID
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public long ToBusinessId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 现设备所属店铺ID
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public long ToShopId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 来源客户
|
||||
/// </summary>
|
||||
public string FromBusiness { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 来源门店
|
||||
/// </summary>
|
||||
public string FromShop { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 接收客户
|
||||
/// </summary>
|
||||
public string ToBusiness { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 接收门店
|
||||
/// </summary>
|
||||
public string ToShop { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 操作时间
|
||||
/// </summary>
|
||||
public DateTime CreatedTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分配类型
|
||||
/// </summary>
|
||||
public DeviceAllocType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建者名称
|
||||
/// </summary>
|
||||
public string CreatedUserName { get; set; }
|
||||
}
|
||||
|
||||
public class DeviceListS2CDto : PageResultV2<DeviceListS2CDtoItem>
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备列表
|
||||
/// </summary>
|
||||
public class DeviceListS2CDtoItem : BaseIdAndUserInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备序列号,唯一
|
||||
/// </summary>
|
||||
public string FacCode { get; set; }
|
||||
/// <summary>
|
||||
/// 设备机器码,唯一
|
||||
/// </summary>
|
||||
public string Ecode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备类型
|
||||
/// </summary>
|
||||
public int Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备状态,1-正常运行,2-已禁用
|
||||
/// </summary>
|
||||
public DeviceStatus Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
public string Remark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备二维码
|
||||
/// </summary>
|
||||
public string Url { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备类型列表
|
||||
/// </summary>
|
||||
public class DeviceTypeListS2CDto : BaseId
|
||||
{
|
||||
/// <summary>
|
||||
/// 类型名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型编号
|
||||
/// </summary>
|
||||
public int Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型图片
|
||||
/// </summary>
|
||||
public string Pic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型图片网络地址
|
||||
/// </summary>
|
||||
public string PicUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型描述
|
||||
/// </summary>
|
||||
public string Desc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 蓝牙协议类型
|
||||
/// </summary>
|
||||
public DeviceProType ProType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 蓝牙跳转地址
|
||||
/// </summary>
|
||||
public string BleUrl { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// 支持的测量类型,多个之间以英文,分隔
|
||||
/// </summary>
|
||||
public string SupType { get; set; } = "";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,266 @@
|
|||
using JT.Shop.Application.Service.ShopApi.Member;
|
||||
using JT.Shop.Core;
|
||||
|
||||
namespace JT.Shop.Application.Service.Business.Member
|
||||
{
|
||||
/// <summary>
|
||||
/// 门店会员列表
|
||||
/// </summary>
|
||||
public class BusinessMemberListInput : PageInputV2Base
|
||||
{
|
||||
/// <summary>
|
||||
/// 创建时间范围
|
||||
/// </summary>
|
||||
public DateRangeFilterInput CreateTimeRange { get; set; }
|
||||
/// <summary>
|
||||
/// 成交时间范围
|
||||
/// </summary>
|
||||
public DateRangeFilterInput DealTimeRange { get; set; }
|
||||
/// <summary>
|
||||
/// 转入时间范围
|
||||
/// </summary>
|
||||
public DateRangeFilterInput MoveInTimeRange { get; set; }
|
||||
/// <summary>
|
||||
/// 服务时间范围,服务指当天有接待记录的
|
||||
/// </summary>
|
||||
public DateRangeFilterInput ServeTimeRange { get; set; }
|
||||
/// <summary>
|
||||
/// 请假时间范围,状态为请假中的
|
||||
/// </summary>
|
||||
public DateRangeFilterInput LeaveTimeRange { get; set; }
|
||||
/// <summary>
|
||||
/// 达标时间范围
|
||||
/// </summary>
|
||||
public DateRangeFilterInput ReachStandardTimeRange { get; set; }
|
||||
/// <summary>
|
||||
/// 顾客标签,可多选
|
||||
/// </summary>
|
||||
public HashSet<RegUserTagEnum> RType { get; set; }
|
||||
/// <summary>
|
||||
/// 预计进店时间段
|
||||
/// </summary>
|
||||
public HashSet<RegUserEnterTimeType> EnterTimeType { get; set; }
|
||||
/// <summary>
|
||||
/// 连续未到店天数,1-1天,2-2天,3-3天及以上
|
||||
/// </summary>
|
||||
public int? NoEntryDay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 顾客属性
|
||||
/// </summary>
|
||||
public RegUserProperType? PType { get; set; }
|
||||
/* /// <summary>
|
||||
/// 称重情况
|
||||
/// </summary>
|
||||
public RegUserWeightProp? WType { get; set; }*/
|
||||
/// <summary>
|
||||
/// 顾客达标属性
|
||||
/// </summary>
|
||||
public RegUserProperType? DType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 塑形相关,0-不限,1-有塑形协议,2-有精护服务
|
||||
/// </summary>
|
||||
public int? SType { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 分类
|
||||
/// </summary>
|
||||
public RegUserGroupProp? GType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 周期数,0-单周期,空-不查询,其他按照标准周期查询
|
||||
/// </summary>
|
||||
public HashSet<int> CycleValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 到店次数
|
||||
/// </summary>
|
||||
public List<NumberRangeFilterInput<int>> EntryTimes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 已减斤数
|
||||
/// </summary>
|
||||
public List<NumberRangeFilterInput<decimal>> ReduceWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 距离标准体重剩余斤数
|
||||
/// </summary>
|
||||
public List<NumberRangeFilterInput<decimal>> DistWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 距离服务期限结束月份
|
||||
/// </summary>
|
||||
public int? ServeEndMonth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 顾客来源
|
||||
/// </summary>
|
||||
public HashSet<string> RSType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 年龄
|
||||
/// </summary>
|
||||
public List<NumberRangeFilterInput<int>> Age { get; set; }
|
||||
|
||||
|
||||
public long? ChildParentHeadId { get; set; }
|
||||
public long? ShopId { get; set; }
|
||||
/// <summary>
|
||||
/// 会员姓名
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// 手机号
|
||||
/// </summary>
|
||||
public string Phone { get; set; }
|
||||
public string Search { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 会员状态
|
||||
/// </summary>
|
||||
public RegUserStatusEnum? Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 职业
|
||||
/// </summary>
|
||||
public RegUserCareerEnum? Career { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 顾客来源
|
||||
///// </summary>
|
||||
//public string SType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 注册类型
|
||||
/// </summary>
|
||||
public RegUserRegiType? IType { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 门店今日会员列表
|
||||
/// </summary>
|
||||
public class BusinessMemberTodayListInput : PageInputV2Base
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 成交时间范围
|
||||
/// </summary>
|
||||
public DateRangeFilterInput DealTimeRange { get; set; }
|
||||
/// <summary>
|
||||
/// 转入时间范围
|
||||
/// </summary>
|
||||
public DateRangeFilterInput MoveInTimeRange { get; set; }
|
||||
/// <summary>
|
||||
/// 顾客标签,可多选
|
||||
/// </summary>
|
||||
public HashSet<RegUserTagEnum> RType { get; set; }
|
||||
/// <summary>
|
||||
/// 预计进店时间段
|
||||
/// </summary>
|
||||
public HashSet<RegUserEnterTimeType> EnterTimeType { get; set; }
|
||||
/// <summary>
|
||||
/// 连续未到店天数,1-1天,2-2天,3-3天及以上
|
||||
/// </summary>
|
||||
public int? NoEntryDay { get; set; }
|
||||
/// <summary>
|
||||
/// 用户状态列表,可多选
|
||||
/// </summary>
|
||||
public HashSet<RegUserEnterStatus> Status { get; set; }
|
||||
/// <summary>
|
||||
/// 顾客属性
|
||||
/// </summary>
|
||||
public RegUserProperType? PType { get; set; }
|
||||
/// <summary>
|
||||
/// 称重情况
|
||||
/// </summary>
|
||||
public RegUserWeightProp? WType { get; set; }
|
||||
/// <summary>
|
||||
/// 塑形相关
|
||||
/// </summary>
|
||||
public HashSet<RegUserSXProp> SType { get; set; }
|
||||
/// <summary>
|
||||
/// 分类
|
||||
/// </summary>
|
||||
public RegUserGroupProp? GType { get; set; }
|
||||
|
||||
|
||||
public long? ChildParentHeadId { get; set; }
|
||||
public long? ShopId { get; set; }
|
||||
/// <summary>
|
||||
/// 会员姓名
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// 手机号
|
||||
/// </summary>
|
||||
public string Phone { get; set; }
|
||||
public string Search { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class BusinessMemberListWithLeaveWarningInput : PageInputV2Base
|
||||
{
|
||||
public long? ChildParentHeadId { get; set; }
|
||||
public long? ShopId { get; set; }
|
||||
/// <summary>
|
||||
/// 请假到期日期
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "请选择日期")]
|
||||
public DateTime? Time { get; set; }
|
||||
}
|
||||
public class BusinessMemberListWithZhangChengWarningInput : PageInputV2Base
|
||||
{
|
||||
public long? ChildParentHeadId { get; set; }
|
||||
public long? ShopId { get; set; }
|
||||
/// <summary>
|
||||
/// 涨秤天数,1-昨日涨秤,2-连续两天涨秤
|
||||
/// </summary>
|
||||
[Required,Range(1,2,ErrorMessage = "1-昨日涨秤,2-连续两天涨秤")]
|
||||
public int Day { get; set; }
|
||||
}
|
||||
public class BusinessMemberListWith3Plus1LostInput : PageInputV2Base
|
||||
{
|
||||
public long? ChildParentHeadId { get; set; }
|
||||
public long? ShopId { get; set; }
|
||||
/// <summary>
|
||||
/// 时间,只会处理年月,传递格式如:2021-01-01
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "请选择月份")]
|
||||
public DateTime? Time { get; set; }
|
||||
}
|
||||
public class BusinessMemberListWithSubscribeInput : PageInputV2Base
|
||||
{
|
||||
public long? ChildParentHeadId { get; set; }
|
||||
public long? ShopId { get; set; }
|
||||
}
|
||||
public class BusinessMemberListWithAgainZhangChengWarningInput : PageInputV2Base,IValidatableObject
|
||||
{
|
||||
public long? ChildParentHeadId { get; set; }
|
||||
public long? ShopId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 开始重量,斤
|
||||
/// </summary>
|
||||
public decimal? StartVal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 结束重量,斤
|
||||
/// </summary>
|
||||
public decimal? EndVal { get; set; }
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (!StartVal.HasValue && !EndVal.HasValue)
|
||||
{
|
||||
yield return new ValidationResult("指定范围不能同时为空", new[] { nameof(StartVal), nameof(EndVal) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class BusinessMemberListWithSummarizeWarningInput
|
||||
{
|
||||
public long? ChildParentHeadId { get; set; }
|
||||
public long? ShopId { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,408 @@
|
|||
namespace JT.Shop.Application.Service.Business.Member
|
||||
{
|
||||
#region 门店会员列表
|
||||
|
||||
/// <summary>
|
||||
/// 门店会员列表
|
||||
/// </summary>
|
||||
public class BusinessMemberListOutputItem : BaseIdAndUserInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 客户姓名
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 联系电话
|
||||
/// </summary>
|
||||
public string Phone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 头像
|
||||
/// </summary>
|
||||
public string Avatar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 头像
|
||||
/// </summary>
|
||||
public string AvatarUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 性别
|
||||
/// </summary>
|
||||
public Gender Gender { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 出生年月
|
||||
/// </summary>
|
||||
public string BirthDay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 职业
|
||||
/// </summary>
|
||||
public RegUserCareerEnum Career { get; set; } = RegUserCareerEnum.Other;
|
||||
|
||||
/// <summary>
|
||||
/// 省份
|
||||
/// </summary>
|
||||
public string Province { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 市
|
||||
/// </summary>
|
||||
public string City { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 区
|
||||
/// </summary>
|
||||
public string Area { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 详细地址
|
||||
/// </summary>
|
||||
public string Address { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 顾客来源
|
||||
/// </summary>
|
||||
public string SType { get; set; } = "4";
|
||||
|
||||
/// <summary>
|
||||
/// 注册类型
|
||||
/// </summary>
|
||||
public RegUserRegiType IType { get; set; } = RegUserRegiType.ZRJD;
|
||||
|
||||
/// <summary>
|
||||
/// 状态
|
||||
/// </summary>
|
||||
public RegUserStatusEnum Status { get; set; }
|
||||
/// <summary>
|
||||
/// 到店状态
|
||||
/// </summary>
|
||||
public RegUserEnterStatus EnterStatus { get; set; }
|
||||
/// <summary>
|
||||
/// 注册时间
|
||||
/// </summary>
|
||||
public DateTime? CreatedTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 未减体重,单位斤
|
||||
/// </summary>
|
||||
public decimal UnIncreaseWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 已减重量,初始体重-末次体重,单位kg
|
||||
/// </summary>
|
||||
public decimal IncreaseWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始体重,单位kg
|
||||
/// </summary>
|
||||
|
||||
public decimal FirstWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标准体重,单位kg
|
||||
/// </summary>
|
||||
|
||||
public decimal StandWeight { get; set; }
|
||||
/// <summary>
|
||||
/// 当日体重
|
||||
/// </summary>
|
||||
public decimal TodayWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上次体重,最新体重值,单位kg
|
||||
/// 目前存的是最新体重值,今日体重
|
||||
/// </summary>
|
||||
public decimal LastWeight { get; set; }
|
||||
/// <summary>
|
||||
/// 用户标签
|
||||
/// </summary>
|
||||
public RegUserTagEnum RType { get; set; }
|
||||
/// <summary>
|
||||
/// 上次进店时间
|
||||
/// </summary>
|
||||
public string LastEntryTime { get; set; }
|
||||
/// <summary>
|
||||
/// 累计到店次数
|
||||
/// </summary>
|
||||
public int ShopEnterCnt { get; set; }
|
||||
/// <summary>
|
||||
/// 成交时间
|
||||
/// </summary>
|
||||
public string DealTime { get; set; }
|
||||
/// <summary>
|
||||
/// 是否关注
|
||||
/// </summary>
|
||||
public bool IsFollower { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 是否在排行榜中
|
||||
/// </summary>
|
||||
public bool IsRank { get; set; }
|
||||
/// <summary>
|
||||
/// 环比重量,斤
|
||||
/// </summary>
|
||||
public string ChainWeight { get; set; }
|
||||
/// <summary>
|
||||
/// 预计到店时间
|
||||
/// </summary>
|
||||
public string ExpectTime { get; set; }
|
||||
}
|
||||
|
||||
public class BusinessMemberListOutput : PageResultV2<BusinessMemberListOutputItem>
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 请假预警
|
||||
|
||||
public class BusinessMemberListWithLeaveWarningOutput : PageResultV2<BusinessMemberListOutputItemWithLeaveWarning>
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class BusinessMemberListOutputItemWithLeaveWarning : CreatedEntityBaseDto<long>
|
||||
{
|
||||
|
||||
public string ShopCode { get; set; }
|
||||
public string ShopName { get; set; }
|
||||
public long ShopId { get; set; }
|
||||
public long BusinessId { get; set; }
|
||||
/// <summary>
|
||||
/// 客户名称
|
||||
/// </summary>
|
||||
public string BusinessName { get; set; }
|
||||
public string BusinessCode { get; set; }
|
||||
/// <summary>
|
||||
/// 注册用户ID
|
||||
/// </summary>
|
||||
|
||||
public long RegUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 客户姓名
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 联系电话
|
||||
/// </summary>
|
||||
public string Phone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 头像
|
||||
/// </summary>
|
||||
public string Avatar { get; set; }
|
||||
/// <summary>
|
||||
/// 请假天数
|
||||
/// </summary>
|
||||
public int Day { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 请假开始时间
|
||||
/// </summary>
|
||||
|
||||
public DateTime StartTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 请假结束时间
|
||||
/// </summary>
|
||||
|
||||
public DateTime EndTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 请假备注
|
||||
/// </summary>
|
||||
public string Remark { get; set; }
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region 涨秤预警
|
||||
|
||||
public class BusinessMemberListWithZhangChengWarningOutput : PageResultV2<BusinessMemberListOutputItemWithZhangChengWarning>
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class BusinessMemberListOutputItemWithZhangChengWarning
|
||||
{
|
||||
|
||||
public string ShopCode { get; set; }
|
||||
public string ShopName { get; set; }
|
||||
public long ShopId { get; set; }
|
||||
public long BusinessId { get; set; }
|
||||
/// <summary>
|
||||
/// 客户名称
|
||||
/// </summary>
|
||||
public string BusinessName { get; set; }
|
||||
public string BusinessCode { get; set; }
|
||||
/// <summary>
|
||||
/// 客户姓名
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 联系电话
|
||||
/// </summary>
|
||||
public string Phone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 头像
|
||||
/// </summary>
|
||||
public string Avatar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户标签
|
||||
/// </summary>
|
||||
public RegUserTagEnum RType { get; set; } = RegUserTagEnum.SJQ;
|
||||
|
||||
/// <summary>
|
||||
/// 环比重量
|
||||
/// </summary>
|
||||
public decimal ChainWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 注册用户ID
|
||||
/// </summary>
|
||||
public long RegUserId { get; set; }
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 再次涨秤预警
|
||||
|
||||
public class BusinessMemberListWithAgainZhangChengWarningOutput : PageResultV2<BusinessMemberListOutputItemWithAgainZhangChengWarning>
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class BusinessMemberListOutputItemWithAgainZhangChengWarning
|
||||
{
|
||||
|
||||
public string ShopCode { get; set; }
|
||||
public string ShopName { get; set; }
|
||||
public long ShopId { get; set; }
|
||||
public long BusinessId { get; set; }
|
||||
/// <summary>
|
||||
/// 客户名称
|
||||
/// </summary>
|
||||
public string BusinessName { get; set; }
|
||||
public string BusinessCode { get; set; }
|
||||
/// <summary>
|
||||
/// 客户姓名
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 联系电话
|
||||
/// </summary>
|
||||
public string Phone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 头像
|
||||
/// </summary>
|
||||
public string Avatar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户标签
|
||||
/// </summary>
|
||||
public RegUserTagEnum RType { get; set; } = RegUserTagEnum.SJQ;
|
||||
|
||||
/// <summary>
|
||||
/// 复涨重量 斤
|
||||
/// </summary>
|
||||
public decimal Weight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 注册用户ID
|
||||
/// </summary>
|
||||
public long RegUserId { get; set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
#region 关注
|
||||
|
||||
public class BusinessMemberListWithSubscribeWarningOutput : PageResultV2<BusinessMemberListOutputItemWithSubscribeWarning>
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class BusinessMemberListOutputItemWithSubscribeWarning
|
||||
{
|
||||
|
||||
public string ShopCode { get; set; }
|
||||
public string ShopName { get; set; }
|
||||
public long ShopId { get; set; }
|
||||
public long BusinessId { get; set; }
|
||||
/// <summary>
|
||||
/// 客户名称
|
||||
/// </summary>
|
||||
public string BusinessName { get; set; }
|
||||
public string BusinessCode { get; set; }
|
||||
/// <summary>
|
||||
/// 客户姓名
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 联系电话
|
||||
/// </summary>
|
||||
public string Phone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 头像
|
||||
/// </summary>
|
||||
public string Avatar { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 注册用户ID
|
||||
/// </summary>
|
||||
public long RegUserId { get; set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region 预警汇总
|
||||
|
||||
public class BusinessMemberListWithSummarizeWarningOutput
|
||||
{
|
||||
/// <summary>
|
||||
/// 明天请假到期顾客
|
||||
/// </summary>
|
||||
public int AfkCnt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 昨日涨秤顾客数量
|
||||
/// </summary>
|
||||
public int ZTZCCnt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 连续两天涨称顾客数量
|
||||
/// </summary>
|
||||
public int LXZCCnt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 重点关注顾客
|
||||
/// </summary>
|
||||
public int SubscribeCnt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 达标复涨顾客
|
||||
/// </summary>
|
||||
public int DBFZCnt { get; set; }
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,566 @@
|
|||
using JT.Shop.Application.Service.Mch.Member;
|
||||
using JT.Shop.Application.Service.ShopApi.Member;
|
||||
using JT.Shop.Application.Service.ShopApi.Member.Dto;
|
||||
using JT.Shop.Application.Service.ShopApi.Report;
|
||||
using JT.Shop.Application.Service.ShopApi.Report.Dto;
|
||||
using JT.Shop.Application.Service.ShopApi.Shop;
|
||||
using JT.Shop.Application.Service.ShopApi.User;
|
||||
using JT.Shop.Application.Service.ShopHead;
|
||||
using JT.Shop.Domain.Entity.ShopHead;
|
||||
using JT.Shop.Domain.FeatureDefinitions.ShopHead;
|
||||
using Volo.Abp.Authorization.Permissions;
|
||||
using Volo.Abp.Features;
|
||||
using Volo.Abp.Localization;
|
||||
|
||||
namespace JT.Shop.Application.Service.Business.Member
|
||||
{
|
||||
/// <summary>
|
||||
/// 会员管理
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings("总部")]
|
||||
[Route("/api/business/[controller]")]
|
||||
public class MemberService(
|
||||
IRepository<PC_ShopRegUser> regUserRepository,
|
||||
UserManager userManager,
|
||||
IRepository<PC_Shop> shopRep,
|
||||
IPcShopRegUserQueryService pcShopRegUserQueryService,
|
||||
IPcShopHeadQueryService shopheadQueryService,
|
||||
IPcRegUserWarningQueryService shopRegUserLeaveQueryService,
|
||||
OpAuditContext opAuditContext)
|
||||
: AppService, IDynamicApiController
|
||||
{
|
||||
/// <summary>
|
||||
/// 门店会员列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("list")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopMemberPermissionDefinitionProvider.ViewName)]
|
||||
public async Task<BusinessMemberListOutput> ListAsync(BusinessMemberListInput input)
|
||||
{
|
||||
var CurrentUser = userManager.GetCurrentShopHeadInfo();
|
||||
//var list = await _regUserRepository.DetachedEntities
|
||||
// .Where(CurrentUser.AccountType == AdminType.None, x => x.BusinessId == CurrentUser.ShopHeadId)
|
||||
// .Where(!input.Name.IsEmpty(), x => x.Name.Contains(input.Name) || x.Phone.Contains(input.Name))
|
||||
// .Where(input.Status != 0, x => x.Status == input.Status)
|
||||
// .Where(input.Career != 0, x => x.Career == input.Career)
|
||||
// .Where(!input.SType.IsEmpty(), x => x.SType == input.SType)
|
||||
// .Where(input.IType != 0, x => x.IType == input.IType)
|
||||
// .OrderByDescending(x => x.CreatedTime)
|
||||
// .ProjectToType<BusinessMemberListOutput>()
|
||||
// .ToADPagedListAsync(input.PageNo, input.PageSize);
|
||||
var list = await Mapper.From(await pcShopRegUserQueryService.GetAllChildList(CurrentUser.ShopHeadId, input.ChildParentHeadId,
|
||||
input.ShopId, input.Name, input.Phone, input.Search, input.Career, input.SType, input.IType, input.Status,
|
||||
input.CreateTimeRange, input.DealTimeRange, input.MoveInTimeRange, input.ServeTimeRange, input.LeaveTimeRange, input.ReachStandardTimeRange, input.RType, input.EnterTimeType, input.NoEntryDay, input.PType, input.DType,/*input.WType,*/input.GType, input.CycleValue, input.EntryTimes, input.ReduceWeight, input.DistWeight, input.ServeEndMonth, input.RSType, input.Age, input)).AdaptToTypeAsync<BusinessMemberListOutput>();
|
||||
|
||||
return list;
|
||||
}
|
||||
/// <summary>
|
||||
/// 门店今日会员列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("today-list")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopMemberPermissionDefinitionProvider.ViewName)]
|
||||
public async Task<BusinessMemberListOutput> TodayListAsync(BusinessMemberTodayListInput input)
|
||||
{
|
||||
var CurrentUser = userManager.GetCurrentShopHeadInfo();
|
||||
var list = await Mapper.From(await pcShopRegUserQueryService.GetAllChildTodayList(CurrentUser.ShopHeadId, input.ChildParentHeadId,
|
||||
input.ShopId, input.Name, input.Phone, input.Search, input.SType, input.Status,
|
||||
input.DealTimeRange, input.MoveInTimeRange, input.RType, input.EnterTimeType, input.NoEntryDay, input.PType, input.WType,input.GType, input)).AdaptToTypeAsync<BusinessMemberListOutput>();
|
||||
|
||||
return list;
|
||||
}
|
||||
/// <summary>
|
||||
/// 门店会员列表-请假预警
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopMemberPermissionDefinitionProvider.ViewName)]
|
||||
[HttpPost("warning/leaves")]
|
||||
public async Task<BusinessMemberListWithLeaveWarningOutput> AFKAllListAsync(BusinessMemberListWithLeaveWarningInput input)
|
||||
{
|
||||
var CurrentUser = userManager.GetCurrentShopHeadInfo();
|
||||
|
||||
var list = await Mapper.From(await shopRegUserLeaveQueryService.QueryWithLeave(CurrentUser.ShopHeadId, input.ChildParentHeadId,
|
||||
input.ShopId, input.Time.Value.Date, input)).AdaptToTypeAsync<BusinessMemberListWithLeaveWarningOutput>();
|
||||
|
||||
return list;
|
||||
}
|
||||
/// <summary>
|
||||
/// 门店会员列表-涨秤预警(1-昨日涨秤,2-连续两天涨秤)
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopMemberPermissionDefinitionProvider.ViewName)]
|
||||
[HttpPost("warning/zhangchengs")]
|
||||
public async Task<BusinessMemberListWithZhangChengWarningOutput> ZhangChengWarningAsync(BusinessMemberListWithZhangChengWarningInput input)
|
||||
{
|
||||
var CurrentUser = userManager.GetCurrentShopHeadInfo();
|
||||
|
||||
var list = await Mapper.From(await shopRegUserLeaveQueryService.QueryWithZhangChengWarning(CurrentUser.ShopHeadId, input.ChildParentHeadId,
|
||||
input.ShopId, input.Day, input)).AdaptToTypeAsync<BusinessMemberListWithZhangChengWarningOutput>();
|
||||
|
||||
return list;
|
||||
}
|
||||
/// <summary>
|
||||
/// 门店会员列表-达标后再次涨秤预警
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopMemberPermissionDefinitionProvider.ViewName)]
|
||||
[HttpPost("warning/again-zhangchengs")]
|
||||
public async Task<BusinessMemberListWithAgainZhangChengWarningOutput> AgainZhangChengWarningAsync(BusinessMemberListWithAgainZhangChengWarningInput input)
|
||||
{
|
||||
var CurrentUser = userManager.GetCurrentShopHeadInfo();
|
||||
|
||||
var list = await Mapper.From(await shopRegUserLeaveQueryService.QueryWithAgainZhangChengWarning(CurrentUser.ShopHeadId, input.ChildParentHeadId,
|
||||
input.ShopId, input.StartVal?.Jin2KG() ?? 0, input.EndVal?.Jin2KG() ?? 0, input)).AdaptToTypeAsync<BusinessMemberListWithAgainZhangChengWarningOutput>();
|
||||
|
||||
return list;
|
||||
}
|
||||
/// <summary>
|
||||
/// 门店会员列表-已关注
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopMemberPermissionDefinitionProvider.ViewName)]
|
||||
[HttpPost("warning/subscribes")]
|
||||
public async Task<BusinessMemberListWithSubscribeWarningOutput> SubscribeWarningAsync(BusinessMemberListWithSubscribeInput input)
|
||||
{
|
||||
var CurrentUser = userManager.GetCurrentShopHeadInfo();
|
||||
|
||||
var list = await Mapper.From(await shopRegUserLeaveQueryService.QueryWithSubscribe(CurrentUser.ShopHeadId, input.ChildParentHeadId,
|
||||
input.ShopId, input)).AdaptToTypeAsync<BusinessMemberListWithSubscribeWarningOutput>();
|
||||
|
||||
return list;
|
||||
}
|
||||
/// <summary>
|
||||
/// 门店会员列表-汇总
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("warning/summarize")]
|
||||
public async Task<BusinessMemberListWithSummarizeWarningOutput> SummarizeWarningAsync(BusinessMemberListWithSummarizeWarningInput input)
|
||||
{
|
||||
var CurrentUser = userManager.GetCurrentShopHeadInfo();
|
||||
|
||||
var list = await Mapper.From(await shopRegUserLeaveQueryService.QueryWithSummarizeWarning(CurrentUser.ShopHeadId, input.ChildParentHeadId,
|
||||
input.ShopId)).AdaptToTypeAsync<BusinessMemberListWithSummarizeWarningOutput>();
|
||||
|
||||
return list;
|
||||
}
|
||||
/// <summary>
|
||||
/// 3+1流失顾客列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("tolslist")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopMemberPermissionDefinitionProvider.ViewName)]
|
||||
public async Task<BusinessMemberListOutput> GetAllChildListWith3Plush1Lost(BusinessMemberListWith3Plus1LostInput input)
|
||||
{
|
||||
var CurrentUser = userManager.GetCurrentShopHeadInfo();
|
||||
//var list = await _regUserRepository.DetachedEntities
|
||||
// .Where(CurrentUser.AccountType == AdminType.None, x => x.BusinessId == CurrentUser.ShopHeadId)
|
||||
// .Where(!input.Name.IsEmpty(), x => x.Name.Contains(input.Name) || x.Phone.Contains(input.Name))
|
||||
// .Where(input.Status != 0, x => x.Status == input.Status)
|
||||
// .Where(input.Career != 0, x => x.Career == input.Career)
|
||||
// .Where(!input.SType.IsEmpty(), x => x.SType == input.SType)
|
||||
// .Where(input.IType != 0, x => x.IType == input.IType)
|
||||
// .OrderByDescending(x => x.CreatedTime)
|
||||
// .ProjectToType<BusinessMemberListOutput>()
|
||||
// .ToADPagedListAsync(input.PageNo, input.PageSize);
|
||||
var list = await Mapper.From(await pcShopRegUserQueryService.GetAllChildListWith3Plush1Lost(CurrentUser.ShopHeadId, input.ChildParentHeadId,
|
||||
input.ShopId, input.Time.Value, input)).AdaptToTypeAsync<BusinessMemberListOutput>();
|
||||
var bids = list.Rows.Select(x => x.BusinessId).ToHashSet();
|
||||
var allbuss = await shopheadQueryService.Get(bids);
|
||||
var sids = list.Rows.Select(x => x.ShopId).ToList();
|
||||
var shops = await shopRep.DetachedEntities.Where(x => sids.Contains(x.Id))
|
||||
.Select(x => new PC_Shop
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name
|
||||
})
|
||||
.ToListAsync();
|
||||
list.Rows.ToList().ForEach(it =>
|
||||
{
|
||||
if (allbuss.TryGetValue(it.BusinessId, out var user))
|
||||
{
|
||||
it.BusinessName = user.Name;
|
||||
it.BusinessCode = user.Code;
|
||||
}
|
||||
var shop = shops.Where(x => x.Id == it.ShopId).FirstOrDefault();
|
||||
if (shop != null)
|
||||
{
|
||||
it.ShopName = shop.Name;
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 状态设置
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopMemberPermissionDefinitionProvider.EnableName)]
|
||||
[OpAudit("启用", "会员", OpAuditLogEventTarget.Head)]
|
||||
[HttpPost("enable")]
|
||||
public async Task EnableAsync(BusinessMemberStatusInput input, [FromServices] PcHeadLevelChildCheckDomainService pcHeadLevelChildCheckDomainService)
|
||||
{
|
||||
foreach (var id in input.Id)
|
||||
{
|
||||
var data = await regUserRepository.Where(x => x.Id == id).FirstOrDefaultAsync();
|
||||
if (data.IsEmpty())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PD0000);
|
||||
}
|
||||
opAuditContext.Update(x =>
|
||||
{
|
||||
x.AddTargetSysAccountWhenRequestNormal(data.ShopId, OpAuditLogEventTarget.Shop);
|
||||
});
|
||||
|
||||
await pcHeadLevelChildCheckDomainService.InChildShopCheck(data.BusinessId,
|
||||
userManager.GetCurrentShopHeadInfo().ShopHeadId);
|
||||
data.Status = RegUserStatusEnum.Enable;
|
||||
await regUserRepository.UpdateIncludeNowAsync(data, new[] { nameof(data.Status) });
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopMemberPermissionDefinitionProvider.DisableName)]
|
||||
[OpAudit("禁用", "会员", OpAuditLogEventTarget.Head)]
|
||||
[HttpPost("disable")]
|
||||
public async Task DisableAsync(BusinessMemberStatusInput input, [FromServices] PcHeadLevelChildCheckDomainService pcHeadLevelChildCheckDomainService)
|
||||
{
|
||||
foreach (var id in input.Id)
|
||||
{
|
||||
var data = await regUserRepository.Where(x => x.Id == id).FirstOrDefaultAsync();
|
||||
if (data.IsEmpty())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PD0000);
|
||||
}
|
||||
|
||||
opAuditContext.Update(x =>
|
||||
{
|
||||
x.AddTargetSysAccountWhenRequestNormal(data.ShopId, OpAuditLogEventTarget.Shop);
|
||||
});
|
||||
|
||||
await pcHeadLevelChildCheckDomainService.InChildShopCheck(data.BusinessId,
|
||||
userManager.GetCurrentShopHeadInfo().ShopHeadId);
|
||||
data.Status = RegUserStatusEnum.Disabled;
|
||||
await regUserRepository.UpdateIncludeNowAsync(data, new[] { nameof(data.Status) });
|
||||
}
|
||||
}
|
||||
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopMemberPermissionDefinitionProvider.EditName)]
|
||||
[UnitOfWork(true)]
|
||||
[HttpPost("edit")]
|
||||
[OpAudit("编辑", "会员", OpAuditLogEventTarget.Head)]
|
||||
|
||||
public async Task EditAsync(MemberEditInput input, [FromServices] PcHeadLevelChildCheckDomainService pcHeadLevelChildCheckDomainService)
|
||||
{
|
||||
|
||||
var data = await regUserRepository.Where(x => x.Id == input.RegUserId).FirstOrDefaultAsync();
|
||||
if (data.IsEmpty())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PD0000);
|
||||
}
|
||||
|
||||
//检查手机号是否重复
|
||||
if (input.DoChangePhone && data.Phone != input.Phone && await regUserRepository.DetachedEntities.AnyAsync(x => x.Phone == input.Phone && x.ShopId == data.ShopId && x.Id != input.RegUserId))
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PW1004);
|
||||
}
|
||||
|
||||
opAuditContext.Update(x =>
|
||||
{
|
||||
x.AddTargetSysAccountWhenRequestNormal(data.ShopId, OpAuditLogEventTarget.Shop);
|
||||
});
|
||||
|
||||
await pcHeadLevelChildCheckDomainService.InChildShopCheck(data.BusinessId,
|
||||
userManager.GetCurrentShopHeadInfo().ShopHeadId);
|
||||
|
||||
if (!input.DoChangePhone) input.Phone = data.Phone;
|
||||
data = input.Adapt(data);
|
||||
|
||||
await regUserRepository.UpdateIncludeNowAsync(data, new[] { nameof(data.Name), nameof(data.Phone), nameof(data.Gender), nameof(data.BirthDay), nameof(data.Career), nameof(data.Province), nameof(data.City), nameof(data.Area), nameof(data.Address), nameof(data.SType) });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///获取会员资料
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("info")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopMemberPermissionDefinitionProvider.ViewName)]
|
||||
public async Task<MemberInfoOutput> InfoAsync([FromQuery] long regUserId, [FromQuery] long shopId, [FromServices] MemberAppQueryService query)
|
||||
{
|
||||
return await query.QueryInfo(regUserId, shopId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 会员体重趋势列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("lose-weight-trend")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopMemberPermissionDefinitionProvider.ViewName)]
|
||||
public async Task<List<MemberTrendListS2CDto>> TrendListAsync(ShopHeadQueryMemberLoseWeightTrendInput input, [FromServices] MemberAppQueryService service, [FromServices] PcHeadLevelChildCheckDomainService pcHeadLevelChildCheckDomainService)
|
||||
{
|
||||
await pcHeadLevelChildCheckDomainService.InChildShopCheckByShopId(input.ShopId,
|
||||
userManager.GetCurrentShopHeadInfo().ShopHeadId);
|
||||
|
||||
input.EndTime = input.EndTime.AddDays(1);
|
||||
return await service.QueryLoseWeightTrend(input.StartTime.Date, input.EndTime.Date, input.Id, input.ShopId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据天数进行汇总
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("lose-weight-summarize-by-day")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopMemberPermissionDefinitionProvider.ViewName)]
|
||||
|
||||
public async Task<List<DayReportListOutput>> ListByDayAsync(ShopHeadQueryMemberLoseWeightSummarizeByDayInput input, [FromServices] MemberAppQueryService service, [FromServices] PcHeadLevelChildCheckDomainService pcHeadLevelChildCheckDomainService)
|
||||
{
|
||||
await pcHeadLevelChildCheckDomainService.InChildShopCheckByShopId(input.ShopId,
|
||||
userManager.GetCurrentShopHeadInfo().ShopHeadId);
|
||||
var nowtime = DateTime.Now.Date;
|
||||
return await service.QueryLoseWeightSummarizeByDay(input, input.ShopId, nowtime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 塑形订单列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("sx-orders")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopMemberPermissionDefinitionProvider.ViewName)]
|
||||
|
||||
public async Task<PageResult<ShopOrderListS2CDto>> OrderListAsync(ShopHeadQueryMemberSXOrdersInput input, [FromServices] MemberAppQueryService service, [FromServices] PcHeadLevelChildCheckDomainService pcHeadLevelChildCheckDomainService)
|
||||
{
|
||||
await pcHeadLevelChildCheckDomainService.InChildShopCheckByShopId(input.ShopId,
|
||||
userManager.GetCurrentShopHeadInfo().ShopHeadId);
|
||||
return await service.QuerySXOrders(input, input.ShopId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 塑形订单详情
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("OrderDetail")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopMemberPermissionDefinitionProvider.ViewName)]
|
||||
public async Task<ShopOrderDetailS2CDto> OrderDetailAsync(BaseId input, [FromServices] MemberSXService wxMemberSxService)
|
||||
{
|
||||
return await wxMemberSxService.OrderDetailAsync(input);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 产品和身体部位列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("bodyandproduct/list")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopMemberPermissionDefinitionProvider.ViewName)]
|
||||
|
||||
public async Task<BodyAndProductListS2CDto> BodyAndProductListAsync(ShopHeadQueryMemberBodyAndProductListInput input, [FromServices] MemberAppQueryService service, [FromServices] PcHeadLevelChildCheckDomainService pcHeadLevelChildCheckDomainService)
|
||||
{
|
||||
await pcHeadLevelChildCheckDomainService.InChildShopCheckByShopId(input.ShopId,
|
||||
userManager.GetCurrentShopHeadInfo().ShopHeadId);
|
||||
return await service.QueryBodyAndProductList(input.ShopId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 身体塑形服务记录列表,默认显示一周的记录
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("body/list")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopMemberPermissionDefinitionProvider.ViewName)]
|
||||
|
||||
public async Task<List<ShopRegUserSXBodyListS2CDto>> BodyResultAsync(ShopHeadQueryMemberSxBodyListInput input, [FromServices] MemberAppQueryService service, [FromServices] PcHeadLevelChildCheckDomainService pcHeadLevelChildCheckDomainService)
|
||||
{
|
||||
await pcHeadLevelChildCheckDomainService.InChildShopCheckByShopId(input.ShopId,
|
||||
userManager.GetCurrentShopHeadInfo().ShopHeadId);
|
||||
return await service.QuerySxBodyList(input, input.ShopId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 会员可使用的产品列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("product/list")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopMemberPermissionDefinitionProvider.ViewName)]
|
||||
|
||||
public async Task<List<RegUserProductListS2CDto>> ProductListAsync(ShopHeadQueryMemberProductListInput input, [FromServices] MemberAppQueryService service, [FromServices] PcHeadLevelChildCheckDomainService pcHeadLevelChildCheckDomainService)
|
||||
{
|
||||
await pcHeadLevelChildCheckDomainService.InChildShopCheckByShopId(input.ShopId,
|
||||
userManager.GetCurrentShopHeadInfo().ShopHeadId);
|
||||
return await service.QueryProductList(input, input.ShopId);
|
||||
}
|
||||
/// <summary>
|
||||
/// 会员使用的产品使用情况列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("product/use-list")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopMemberPermissionDefinitionProvider.ViewName)]
|
||||
|
||||
public async Task<PageResult<RegUserProductListS2CDto>> ProductPageListAsync(ShopHeadQueryMemberProductUseResultsInput input, [FromServices] MemberAppQueryService service, [FromServices] PcHeadLevelChildCheckDomainService pcHeadLevelChildCheckDomainService)
|
||||
{
|
||||
await pcHeadLevelChildCheckDomainService.InChildShopCheckByShopId(input.ShopId,
|
||||
userManager.GetCurrentShopHeadInfo().ShopHeadId);
|
||||
return await service.QueryProductUseResults(input, input.ShopId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 顾客阶段减重汇总列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("report/parts")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopMemberPermissionDefinitionProvider.ViewName)]
|
||||
public async Task<ShopHeadQueryMemberLoseWeightPartsOutput> PartListAsync(ShopHeadQueryMemberLoseWeightPartsInput input, [FromServices] ILoseWeightPartsQueryService service)
|
||||
{
|
||||
var days = (input.ServeTimeRange.End!.Value - input.ServeTimeRange.Start!.Value).TotalDays;
|
||||
return await Mapper.From(await service.Query(userManager.GetCurrentShopHeadInfo().ShopHeadId, input.ChildParentHeadId, input.ShopId, input.DealTimeRange, input.ServeTimeRange, input.Search, input.Name, input.Phone, input)).AddParameters("PrevServeTime", new DateRangeFilterInput(input.ServeTimeRange.Start.Value.AddDays(-days), input.ServeTimeRange.End.Value.AddDays(-days)))
|
||||
.AdaptToTypeAsync<ShopHeadQueryMemberLoseWeightPartsOutput>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 减重记录
|
||||
/// </summary>
|
||||
/// <param name="service"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("report/lose-weight-results")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopMemberPermissionDefinitionProvider.ViewName)]
|
||||
public async Task<PageResultV2<WeightListResultS2CDto>> LoseWeightResults(ShopHeadQueryMemberLoseWeightResultsInput input, [FromServices] IPCResultQueryService service, [FromServices] PcHeadLevelChildCheckDomainService pcHeadLevelChildCheckDomainService)
|
||||
{
|
||||
await pcHeadLevelChildCheckDomainService.InChildShopCheckByShopId(input.ShopId,
|
||||
userManager.GetCurrentShopHeadInfo().ShopHeadId);
|
||||
return (await service.Query(input.ServeTime, input.RegUserId, input.ShopId, input)).Adapt<PageResultV2<WeightListResultS2CDto>>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 历史减重记录
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("report/weighthislist")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopMemberPermissionDefinitionProvider.ViewName)]
|
||||
public async Task<List<WeightHisListOutput>> WeightHisListAsync(BaseReguserId input, [FromServices] ReportService reportService)
|
||||
{
|
||||
return await reportService.WeightHisListAsync(input);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class ShopHeadQueryMemberLoseWeightTrendInput : MemberTrendListC2SDto
|
||||
{
|
||||
[Required]
|
||||
public long ShopId { get; set; }
|
||||
}
|
||||
public class ShopHeadQueryMemberLoseWeightSummarizeByDayInput : BaseReguserId
|
||||
{
|
||||
[Required]
|
||||
public long ShopId { get; set; }
|
||||
}
|
||||
public class ShopHeadQueryMemberSXOrdersInput : ShopOrderListC2SDto
|
||||
{
|
||||
[Required]
|
||||
public long ShopId { get; set; }
|
||||
}
|
||||
public class ShopHeadQueryMemberBodyAndProductListInput
|
||||
{
|
||||
[Required]
|
||||
public long ShopId { get; set; }
|
||||
}
|
||||
public class ShopHeadQueryMemberSxBodyListInput : ShopBodyListC2SDto
|
||||
{
|
||||
[Required]
|
||||
public long ShopId { get; set; }
|
||||
}
|
||||
public class ShopHeadQueryMemberProductListInput : RegUserProductListC2SDto
|
||||
{
|
||||
[Required]
|
||||
public long ShopId { get; set; }
|
||||
}
|
||||
public class ShopHeadQueryMemberProductUseResultsInput : RegUserProductPageListC2SDto
|
||||
{
|
||||
[Required]
|
||||
public long ShopId { get; set; }
|
||||
}
|
||||
public class ShopHeadQueryMemberLoseWeightPartsInput : PageInputV2Base, IValidatableObject
|
||||
{
|
||||
/// <summary>
|
||||
/// 会员名称或手机号
|
||||
/// </summary>
|
||||
public string Search { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Phone { get; set; }
|
||||
[Required]
|
||||
public DateRangeFilterInput ServeTimeRange { get; set; }
|
||||
public DateRangeFilterInput DealTimeRange { get; set; }
|
||||
public long? ChildParentHeadId { get; set; }
|
||||
public long? ShopId { get; set; }
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (ServeTimeRange == null || ServeTimeRange.IsOverTimeSpan(x => x.TotalDays > 180))
|
||||
yield return new ValidationResult("时间跨度不能超过半年");
|
||||
}
|
||||
}
|
||||
public class ShopHeadQueryMemberLoseWeightResultsInput : PageInputV2Base
|
||||
{
|
||||
public DateRangeFilterInput ServeTime { get; set; }
|
||||
[Required]
|
||||
public long ShopId { get; set; }
|
||||
[Required]
|
||||
public long RegUserId { get; set; }
|
||||
}
|
||||
|
||||
public class ShopHeadQueryMemberLoseWeightPartsOutput : PageResultV2<WeightListS2CDto>
|
||||
{
|
||||
/// <summary>
|
||||
/// 总减重斤数
|
||||
/// </summary>
|
||||
public decimal TotalWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 总到店次数
|
||||
/// </summary>
|
||||
public int TotalEnterCnt { get; set; }
|
||||
}
|
||||
public class ShopHeadOfShopMemberPermissionDefinitionProvider : PermissionDefinitionProvider
|
||||
{
|
||||
|
||||
|
||||
public const string GroupName = $"{ShopHeadPermissionDefinitionNames.Prefix}.shop.member";
|
||||
public const string ViewName = $"{GroupName}.view";
|
||||
//public const string Report = $"{GroupName}.view.report";
|
||||
//public const string AddName = $"{GroupName}.add";
|
||||
//public const string DelName = $"{GroupName}.del";
|
||||
public const string EditName = $"{GroupName}.edit";
|
||||
public const string DisableName = $"{GroupName}.disable";
|
||||
public const string EnableName = $"{GroupName}.enable";
|
||||
|
||||
|
||||
|
||||
public override void Define(IPermissionDefinitionContext context)
|
||||
{
|
||||
{
|
||||
var groups = context.AddGroup($"{GroupName}", new FixedLocalizableString("会员管理"));
|
||||
|
||||
groups.AddPermission($"{ViewName}", new FixedLocalizableString("查看")).RequireFeatures(ShopHeadOfShopMemberFeatureDefinitionProvider.MANAGE);
|
||||
//groups.AddPermission($"{Report}", new FixedLocalizableString("报表")).RequireFeatures(ShopHeadOfShopMemberFeatureDefinitionProvider.MANAGE);
|
||||
//groups.AddPermission($"{AddName}", new FixedLocalizableString("添加"));
|
||||
groups.AddPermission($"{EditName}", new FixedLocalizableString("编辑"));
|
||||
//groups.AddPermission($"{DelName}", new FixedLocalizableString("删除"));
|
||||
groups.AddPermission($"{DisableName}", new FixedLocalizableString("禁用")).RequireFeatures(ShopHeadOfShopMemberFeatureDefinitionProvider.MANAGE);
|
||||
groups.AddPermission($"{EnableName}", new FixedLocalizableString("启用")).RequireFeatures(ShopHeadOfShopMemberFeatureDefinitionProvider.MANAGE);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
namespace JT.Shop.Application.Service.Business.Org
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户组织机构分页查询
|
||||
/// </summary>
|
||||
public class UserOrgPageListC2SDto : PageInputBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 父Id
|
||||
/// </summary>
|
||||
public string Pid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 总部ID
|
||||
/// </summary>
|
||||
public string BusinessId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 组织结构列表
|
||||
/// </summary>
|
||||
public class UserOrgListCS2Dto
|
||||
{
|
||||
/// <summary>
|
||||
/// 父Id
|
||||
/// </summary>
|
||||
public string Pid { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编辑组织机构
|
||||
/// </summary>
|
||||
public class UserEditOrgC2SDto : UserAddOrgC2SDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 主键
|
||||
/// </summary>
|
||||
[Required]
|
||||
public long Id { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加组织结构
|
||||
/// </summary>
|
||||
public class UserAddOrgC2SDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 父Id
|
||||
/// </summary>
|
||||
public long Pid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "名称不可为空")]
|
||||
[MaxLength(100, ErrorMessage = "名称长度不可超过100字")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 编码
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "编码不可为空")]
|
||||
[MaxLength(50, ErrorMessage = "编码长度不可超过50字")]
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序
|
||||
/// </summary>
|
||||
public int Sort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
[MaxLength(100, ErrorMessage = "备注最多100字")]
|
||||
public string Remark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 机构类型
|
||||
/// </summary>
|
||||
public string OrgType { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
namespace JT.Shop.Application.Service.Business.Org
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户组织机构分页查询
|
||||
/// </summary>
|
||||
public class UserOrgPageListS2CDto : BaseId
|
||||
{
|
||||
/// <summary>
|
||||
/// 父Id
|
||||
/// </summary>
|
||||
public long Pid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 父Ids
|
||||
/// </summary>
|
||||
public string Pids { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 编码
|
||||
/// </summary>
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序
|
||||
/// </summary>
|
||||
public int Sort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
public string Remark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态(字典 0正常 1停用 2删除)
|
||||
/// </summary>
|
||||
public CommonStatus Status { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
namespace JT.Shop.Application.Service.Business.Org
|
||||
{
|
||||
/// <summary>
|
||||
/// 组织结构管理
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings("总部")]
|
||||
[Route("/api/business/[controller]")]
|
||||
public class OrgService//暂时关闭 : IDynamicApiController, ITransient
|
||||
{
|
||||
private readonly IRepository<PC_UserOrg> _userOrgRepository;
|
||||
private readonly UserManager UserInfo;
|
||||
|
||||
public OrgService(
|
||||
IRepository<PC_UserOrg> userOrgRepository,
|
||||
UserManager userManager)
|
||||
{
|
||||
_userOrgRepository = userOrgRepository;
|
||||
UserInfo = userManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页查询组织结构列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PageResult<UserOrgPageListS2CDto>> PageAsync(UserOrgPageListC2SDto input)
|
||||
{
|
||||
var CurrentUser = UserInfo.GetCurrentShopHeadInfo();
|
||||
var bid = input.BusinessId.ToLong();
|
||||
var list = await _userOrgRepository.DetachedEntities
|
||||
.Where(CurrentUser.AccountType == AdminType.None, x => x.BusinessId == CurrentUser.ShopHeadId)
|
||||
.Where(CurrentUser.AccountType != AdminType.None, x => x.BusinessId == bid)
|
||||
.Where(!input.Name.IsEmpty(), x => EF.Functions.Like(x.Name, $"%{input.Name.ToStr()}%"))
|
||||
.Where(!input.Pid.IsEmpty(), x => x.Pid == input.Pid.ToLong())
|
||||
.OrderBy(x => x.Sort).ProjectToType<UserOrgPageListS2CDto>().ToADPagedListAsync(input.PageNo, input.PageSize);
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 组织结构列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<List<UserOrgPageListS2CDto>> ListAsync(UserOrgListCS2Dto input)
|
||||
{
|
||||
var CurrentUser = UserInfo.GetCurrentShopHeadInfo();
|
||||
return await _userOrgRepository.DetachedEntities.Where(!input.Pid.IsEmpty(), x => x.Pid == input.Pid.ToLong())
|
||||
.Where(x => x.BusinessId == CurrentUser.ShopHeadId)
|
||||
.OrderBy(x => x.Sort).ProjectToType<UserOrgPageListS2CDto>().ToListAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取组织机构树
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<dynamic> TreeAsync(BaseId input)
|
||||
{
|
||||
var CurrentUser = UserInfo.GetCurrentShopHeadInfo();
|
||||
var orgs = await _userOrgRepository.DetachedEntities
|
||||
.Where(CurrentUser.AccountType == AdminType.None, x => x.BusinessId == CurrentUser.ShopHeadId)
|
||||
.Where(CurrentUser.AccountType != AdminType.None, x => x.BusinessId == input.Id)
|
||||
.Where(u => u.Status == CommonStatus.Enable)
|
||||
.OrderBy(u => u.Sort)
|
||||
.ProjectToType<OrgTreeNode>()
|
||||
.ToListAsync();
|
||||
|
||||
return new TreeBuildUtil<OrgTreeNode>().Build(orgs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加组织结构
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task AddAsync(UserAddOrgC2SDto input)
|
||||
{
|
||||
if (await _userOrgRepository.DetachedEntities.Where(u => u.Name == input.Name || u.Code == input.Code).AnyAsync())
|
||||
throw Oops.Bah(ErrorCode.D2002);
|
||||
var CurrentUser = UserInfo.GetCurrentShopHeadInfo();
|
||||
var data = input.Adapt<PC_UserOrg>();
|
||||
data.BusinessId = CurrentUser.ShopHeadId;
|
||||
data.Id = YitIdHelper.NextId();
|
||||
await FillPids(data);
|
||||
await _userOrgRepository.InsertNowAsync(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编辑组织结构
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task EditAsync(UserEditOrgC2SDto input)
|
||||
{
|
||||
var CurrentUser = UserInfo.GetCurrentUserInfo();
|
||||
if (input.Pid != 0)
|
||||
{
|
||||
var org = await _userOrgRepository.DetachedEntities.FirstOrDefaultAsync(u => u.Id == input.Pid && u.BusinessId == CurrentUser.UserId);
|
||||
_ = org ?? throw Oops.Bah(ErrorCode.D2000);
|
||||
}
|
||||
if (input.Id == input.Pid)
|
||||
throw Oops.Bah(ErrorCode.D2001);
|
||||
|
||||
// 如果是编辑,父id不能为自己的子节点
|
||||
var childIdListById = await GetChildIdListWithSelfById(input.Id);
|
||||
if (childIdListById.Contains(input.Pid))
|
||||
throw Oops.Bah(ErrorCode.D2001);
|
||||
|
||||
var sysOrg = await _userOrgRepository.DetachedEntities.FirstOrDefaultAsync(u => u.Id == input.Id);
|
||||
|
||||
var isExist = await _userOrgRepository.DetachedEntities.AnyAsync(u => (u.Name == input.Name || u.Code == input.Code) && u.Id != sysOrg.Id && u.BusinessId == CurrentUser.UserId);
|
||||
if (isExist)
|
||||
throw Oops.Bah(ErrorCode.D2002);
|
||||
|
||||
sysOrg = input.Adapt<PC_UserOrg>();
|
||||
await FillPids(sysOrg);
|
||||
await _userOrgRepository.UpdateIncludeNowAsync(sysOrg, new[] { nameof(sysOrg.Name), nameof(sysOrg.Pid), nameof(sysOrg.Code), nameof(sysOrg.Sort), nameof(sysOrg.Remark) });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据节点Id获取所有子节点Id集合,包含自己
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<List<long>> GetChildIdListWithSelfById(long id)
|
||||
{
|
||||
var CurrentUser = UserInfo.GetCurrentUserInfo();
|
||||
var childIdList = await _userOrgRepository.DetachedEntities
|
||||
.Where(u => u.BusinessId == CurrentUser.UserId)
|
||||
.Where(u => EF.Functions.Like(u.Pids, $"%{id}%"))
|
||||
.Select(u => u.Id).ToListAsync();
|
||||
childIdList.Add(id);
|
||||
return childIdList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 填充父Ids字段
|
||||
/// </summary>
|
||||
/// <param name="sysOrg"></param>
|
||||
/// <returns></returns>
|
||||
private async Task FillPids(PC_UserOrg sysOrg)
|
||||
{
|
||||
if (sysOrg.Pid == 0L)
|
||||
{
|
||||
sysOrg.Pids = "[" + 0 + "],";
|
||||
}
|
||||
else
|
||||
{
|
||||
var t = await _userOrgRepository.DetachedEntities.FirstOrDefaultAsync(u => u.Id == sysOrg.Pid);
|
||||
sysOrg.Pids = t.Pids + "[" + t.Id + "],";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
namespace JT.Shop.Application.Service.Business.Pos.Dto
|
||||
{
|
||||
/// <summary>
|
||||
/// 映射
|
||||
/// </summary>
|
||||
public class CMapper : IRegister
|
||||
{
|
||||
/// <summary>
|
||||
/// 映射配置
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
public void Register(TypeAdapterConfig config)
|
||||
{
|
||||
//添加职位
|
||||
config.ForType<AddPosInput, PC_ShopPos>()
|
||||
.Map(dest => dest.Name, src => src.Name.ToStrNoEmpty())
|
||||
.Map(dest => dest.Code, src => src.Code.ToStrNoEmpty())
|
||||
.Map(dest => dest.Remark, src => src.Remark.ToStrNoEmpty())
|
||||
.Map(dest => dest.Status, src => CommonStatus.Enable)
|
||||
.Map(dest => dest.Id, src => YitIdHelper.NextId())
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace JT.Shop.Application.Service.Business.Pos
|
||||
{
|
||||
/// <summary>
|
||||
/// 职位列表
|
||||
/// </summary>
|
||||
public class BusinessPosListOutput : BaseIdAndUserInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 编码
|
||||
/// </summary>
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序
|
||||
/// </summary>
|
||||
public int Sort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
public string Remark { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
using Furion.DatabaseAccessor.Extensions;
|
||||
|
||||
namespace JT.Shop.Application.Service.Business.Pos
|
||||
{
|
||||
/// <summary>
|
||||
/// 职位管理
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings("总部")]
|
||||
[Route("/api/business/[controller]")]
|
||||
public class PosService //暂时关闭: IDynamicApiController, ITransient
|
||||
{
|
||||
private readonly IRepository<PC_ShopPos> _posRepository;
|
||||
private readonly IRepository<PC_User> _userRepository;
|
||||
private readonly UserManager _userManager;
|
||||
private readonly IRepository<PC_Shop> _shopRep;
|
||||
private readonly IMyRepository<SysUser> _sysUserRepository;
|
||||
|
||||
public PosService(
|
||||
IRepository<PC_ShopPos> posRepositor,
|
||||
UserManager userManager,
|
||||
IRepository<PC_User> userRepository,
|
||||
IRepository<PC_Shop> shopRep,
|
||||
IMyRepository<SysUser> sysUserRepository)
|
||||
{
|
||||
_posRepository = posRepositor;
|
||||
_userManager = userManager;
|
||||
_userRepository = userRepository;
|
||||
_shopRep = shopRep;
|
||||
_sysUserRepository = sysUserRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页获取职位
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PageResult<BusinessPosListOutput>> PageAsync(PosInput input)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
var list = await _posRepository.DetachedEntities
|
||||
.Where(CurrentUser.AccountType == AdminType.None, x => x.BusinessId == CurrentUser.ShopHeadId)
|
||||
.Where(!input.Name.IsEmpty(), u => EF.Functions.Like(u.Name, $"%{input.Name.Trim()}%"))
|
||||
.Where(!input.Code.IsEmpty(), u => EF.Functions.Like(u.Code, $"%{input.Code.Trim()}%"))
|
||||
.Where(u => u.Status == CommonStatus.Enable)
|
||||
.OrderBy(u => u.Sort)
|
||||
.ProjectToType<BusinessPosListOutput>()
|
||||
.ToADPagedListAsync(input.PageNo, input.PageSize);
|
||||
var uids = list.Rows.Select(x => x.BusinessId).ToList();
|
||||
var users = await _sysUserRepository.DetachedEntities.Where(x => uids.Contains(x.Id))
|
||||
.Select(x => new SysUser
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name
|
||||
})
|
||||
.ToListAsync();
|
||||
var sids = list.Rows.Select(x => x.ShopId).ToList();
|
||||
var shops = await _shopRep.DetachedEntities.Where(x => sids.Contains(x.Id))
|
||||
.Select(x => new PC_Shop
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name
|
||||
})
|
||||
.ToListAsync();
|
||||
list.Rows.ToList().ForEach(it =>
|
||||
{
|
||||
var user = users.Where(x => x.Id == it.BusinessId).FirstOrDefault();
|
||||
if (user != null)
|
||||
{
|
||||
it.BusinessName = user.Name;
|
||||
}
|
||||
var shop = shops.Where(x => x.Id == it.ShopId).FirstOrDefault();
|
||||
if (shop != null)
|
||||
{
|
||||
it.ShopName = shop.Name;
|
||||
}
|
||||
});
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取职位列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<List<PC_ShopPos>> ListAsync(PosInput input)
|
||||
{
|
||||
var code = !string.IsNullOrEmpty(input.Code?.Trim());
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
return await _posRepository.DetachedEntities.Where(x => x.BusinessId == CurrentUser.ShopHeadId).Where(code, u => EF.Functions.Like(u.Code, $"%{input.Code.Trim()}%"))
|
||||
.OrderBy(u => u.Sort).ToListAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 增加职位
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task AddAsync(AddPosInput input)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
var isExist = await _posRepository.DetachedEntities.AnyAsync(u => (u.Name == input.Name || u.Code == input.Code) && u.BusinessId == CurrentUser.UserId);
|
||||
if (isExist)
|
||||
throw Oops.Bah(ErrorCode.D6000);
|
||||
|
||||
var pos = input.Adapt<PC_ShopPos>();
|
||||
pos.BusinessId = CurrentUser.UserId;
|
||||
pos.Status = CommonStatus.Enable;
|
||||
await _posRepository.InsertNowAsync(pos);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除职位
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task DeleteAsync(DeletePosInput input)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentUserInfo();
|
||||
// 该职位下是否有员工
|
||||
var hasPosEmp = await _userRepository.DetachedEntities.AnyAsync(x => x.PosId == input.Id);
|
||||
if (hasPosEmp)
|
||||
throw Oops.Bah(ErrorCode.D6001);
|
||||
var pos = await _posRepository.FirstOrDefaultAsync(u => u.Id == input.Id);
|
||||
await pos.DeleteNowAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新职位
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task EditAsync(UpdatePosInput input)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentUserInfo();
|
||||
var isExist = await _posRepository.DetachedEntities.AnyAsync(u => (u.Name == input.Name || u.Code == input.Code) && u.Id != input.Id && u.BusinessId == CurrentUser.UserId);
|
||||
if (isExist)
|
||||
throw Oops.Bah(ErrorCode.D6000);
|
||||
|
||||
var pos = input.Adapt<PC_ShopPos>();
|
||||
await _posRepository.UpdateIncludeNowAsync(pos, new[] { nameof(pos.Name), nameof(pos.Code), nameof(pos.Remark), nameof(pos.Sort) });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取职位
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PC_ShopPos> DetailAsync([FromQuery] QueryPosInput input)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentUserInfo();
|
||||
return await _posRepository.DetachedEntities.FirstOrDefaultAsync(u => u.Id == input.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
using JT.Shop.Application.Service.Mch.Product;
|
||||
|
||||
namespace JT.Shop.Application.Service.Business.Product
|
||||
{
|
||||
/// <summary>
|
||||
/// 门店产品
|
||||
/// </summary>
|
||||
public class BusinessProductListInput : PageInputV2Base
|
||||
{
|
||||
/// <summary>
|
||||
/// 创建时间范围
|
||||
/// </summary>
|
||||
public DateRangeFilterInput CreateTimeRange { get; set; }
|
||||
public long? ChildParentHeadId { get; set; }
|
||||
public long? ShopId { get; set; }
|
||||
public HashSet<long> ProductShareNameId { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 状态
|
||||
/// </summary>
|
||||
public GoodsStatus? Status { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 门店产品提交
|
||||
/// </summary>
|
||||
public class BusinessSubmitProductInput : MchSubmitProductInput
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 产品购买记录
|
||||
/// </summary>
|
||||
public class BusinessProductPayListInput : PageInputV2Base
|
||||
{
|
||||
public DateRangeFilterInput CreateTimeRange { get; set; }
|
||||
public DateRangeFilterInput StartTimeRange { get; set; }
|
||||
public DateRangeFilterInput EndTimeRange { get; set; }
|
||||
public long? ChildParentHeadId { get; set; }
|
||||
public long? ShopId { get; set; }
|
||||
public HashSet<long> ProductShareNameId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 产品使用状态
|
||||
/// </summary>
|
||||
public RegUserProductStatusEnum? Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户ID
|
||||
/// </summary>
|
||||
public long? RegUserId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 产品使用记录
|
||||
/// </summary>
|
||||
public class BusinessProductResultListInput : PageInputV2Base
|
||||
{
|
||||
public DateRangeFilterInput CreateTimeRange { get; set; }
|
||||
public long? ChildParentHeadId { get; set; }
|
||||
public long? ShopId { get; set; }
|
||||
public HashSet<long> ProductShareNameId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户ID
|
||||
/// </summary>
|
||||
public long? RegUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联的服务ID
|
||||
/// </summary>
|
||||
public long? ServeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 店员ID
|
||||
/// </summary>
|
||||
public long? UserId { get; set; }
|
||||
public long? ResultId { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
namespace JT.Shop.Application.Service.Business.Product
|
||||
{
|
||||
/// <summary>
|
||||
/// 门店产品列表
|
||||
/// </summary>
|
||||
public class BusinessProductListOutputItem : BaseIdAndUserInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 产品名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序,数字越小越靠前
|
||||
/// </summary>
|
||||
public int SortCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态
|
||||
/// </summary>
|
||||
public GoodsStatus Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
public string Remark { get; set; }
|
||||
}
|
||||
public class BusinessProductListOutput : PageResultV2<BusinessProductListOutputItem>
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 产品购买记录
|
||||
/// </summary>
|
||||
public class BusinessProductPayListOutputItem : BaseIdAndUserInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 产品名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户名
|
||||
/// </summary>
|
||||
public string UserName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户ID
|
||||
/// </summary>
|
||||
public long RegUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 产品ID
|
||||
/// </summary>
|
||||
public long ProductId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 产品开启时间
|
||||
/// </summary>
|
||||
public DateTime StartTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 产品结束时间
|
||||
/// </summary>
|
||||
public DateTime? EndTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 描述
|
||||
/// </summary>
|
||||
public string Desc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 已使用次数
|
||||
/// </summary>
|
||||
public int UsedCnt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 产品使用状态
|
||||
/// </summary>
|
||||
public RegUserProductStatusEnum Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime? CreatedTime { get; set; }
|
||||
}
|
||||
public class BusinessProductPayListOutput:PageResultV2<BusinessProductPayListOutputItem> {}
|
||||
|
||||
/// <summary>
|
||||
/// 产品使用记录
|
||||
/// </summary>
|
||||
public class BusinessProductResultListOutputItem : BaseIdAndUserInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 产品ID
|
||||
/// </summary>
|
||||
public long ProductId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 产品名称
|
||||
/// </summary>
|
||||
public string ProductName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户ID
|
||||
/// </summary>
|
||||
public long RegUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户名称
|
||||
/// </summary>
|
||||
public string RegUserName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联的服务ID
|
||||
/// </summary>
|
||||
[Comment("关联的服务ID")]
|
||||
public long ServeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 服务名称
|
||||
/// </summary>
|
||||
public string ServeName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 店员ID
|
||||
/// </summary>
|
||||
[Comment("店员ID")]
|
||||
public long UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 店员名称
|
||||
/// </summary>
|
||||
public string UserName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime? CreatedTime { get; set; }
|
||||
}
|
||||
|
||||
public class BusinessProductResultListOutput:PageResultV2<BusinessProductResultListOutputItem>
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,568 @@
|
|||
using JT.Shop.Application.Service.Business.Serve;
|
||||
using JT.Shop.Application.Service.Mch.Product;
|
||||
using JT.Shop.Application.Service.ShopHead;
|
||||
using JT.Shop.Domain;
|
||||
using JT.Shop.Domain.Entity.Business;
|
||||
using JT.Shop.Domain.Entity.ShopHead;
|
||||
using JT.Shop.Domain.FeatureDefinitions.ShopHead;
|
||||
using Volo.Abp.Authorization.Permissions;
|
||||
using Volo.Abp.Features;
|
||||
using Volo.Abp.Localization;
|
||||
using Volo.Abp.Users;
|
||||
|
||||
namespace JT.Shop.Application.Service.Business.Product
|
||||
{
|
||||
/// <summary>
|
||||
/// 产品管理
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings("总部")]
|
||||
[Route("/api/business/[controller]")]
|
||||
public class ProductService : IDynamicApiController, ITransient
|
||||
{
|
||||
private readonly IRepository<PC_ShopProduct> _productRepository;
|
||||
|
||||
private readonly IRepository<PC_ShopRegUser> _regUserRepository;
|
||||
private readonly IRepository<PC_ShopAccount> _accountRepository;
|
||||
private readonly IRepository<PC_ShopService> _shopServiceRepository;
|
||||
private readonly IRepository<PC_Shop> _shopRep;
|
||||
private readonly IPcShopHeadQueryService _sysUserRepository;
|
||||
private readonly UserManager _userManager;
|
||||
|
||||
private readonly IRepository<PC_BusinessShopProduct> _BusinessShopProduct;
|
||||
|
||||
private readonly OpAuditContext opAuditContext;
|
||||
private readonly IPcShopProductQueryService _pcShopProductQueryService;
|
||||
private readonly IPcShopProductUseRecordQueryService lcShopProductUseRecordQueryService;
|
||||
private readonly IPcShopProductBuyRecordQueryService pcShopProductBuyRecordQueryService;
|
||||
|
||||
|
||||
public ProductService(
|
||||
IRepository<PC_ShopProduct> productRepository,
|
||||
UserManager userManager,
|
||||
IRepository<PC_ShopRegUser> regUserRepository,
|
||||
IRepository<PC_ShopAccount> accountRepository,
|
||||
IRepository<PC_ShopService> shopServiceRepository,
|
||||
IRepository<PC_Shop> shopRep,
|
||||
IRepository<PC_BusinessShopProduct> BusinessShopProduct,
|
||||
IPcShopHeadQueryService sysUserRepository, OpAuditContext opAuditContext, IPcShopProductQueryService pcShopProductQueryService, IPcShopProductUseRecordQueryService lcShopProductUseRecordQueryService, IPcShopProductBuyRecordQueryService pcShopProductBuyRecordQueryService)
|
||||
{
|
||||
_productRepository = productRepository;
|
||||
_userManager = userManager;
|
||||
_regUserRepository = regUserRepository;
|
||||
_accountRepository = accountRepository;
|
||||
_shopServiceRepository = shopServiceRepository;
|
||||
_shopRep = shopRep;
|
||||
_BusinessShopProduct = BusinessShopProduct;
|
||||
_sysUserRepository = sysUserRepository;
|
||||
this.opAuditContext = opAuditContext;
|
||||
_pcShopProductQueryService = pcShopProductQueryService;
|
||||
this.lcShopProductUseRecordQueryService = lcShopProductUseRecordQueryService;
|
||||
this.pcShopProductBuyRecordQueryService = pcShopProductBuyRecordQueryService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 产品列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopProductPermissionDefinitionProvider.ViewName)]
|
||||
|
||||
public async Task<BusinessProductListOutput> ListAsync(BusinessProductListInput input)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
/* var list = await _productRepository.DetachedEntities
|
||||
.Where(CurrentUser.AccountType == AdminType.None, x => x.BusinessId == CurrentUser.ShopHeadId)
|
||||
.Where(!input.Name.IsEmpty(), x => x.Name.Contains(input.Name))
|
||||
.Where(input.Status != 0, x => x.Status == input.Status)
|
||||
.OrderBy(x => x.SortCode)
|
||||
.ProjectToType<BusinessProductListOutput>()
|
||||
.ToADPagedListAsync(input.PageNo, input.PageSize);*/
|
||||
var list = (await _pcShopProductQueryService.GetAllChildList(CurrentUser.ShopHeadId, input.ChildParentHeadId,
|
||||
input.ShopId, input.ProductShareNameId, input.Status, input.CreateTimeRange, input)).Adapt<BusinessProductListOutput>();
|
||||
var uids = list.Rows.Select(x => x.BusinessId).ToList();
|
||||
var users = await _sysUserRepository.Get(uids.ToHashSet());
|
||||
var sids = list.Rows.Select(x => x.ShopId).ToList();
|
||||
var shops = await _shopRep.DetachedEntities.Where(x => sids.Contains(x.Id))
|
||||
.Select(x => new PC_Shop
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name
|
||||
})
|
||||
.ToListAsync();
|
||||
list.Rows.ToList().ForEach(it =>
|
||||
{
|
||||
if (users.TryGetValue(it.BusinessId, out var user))
|
||||
{
|
||||
it.BusinessName = user.Name;
|
||||
it.BusinessCode = user.Code;
|
||||
}
|
||||
var shop = shops.Where(x => x.Id == it.ShopId).FirstOrDefault();
|
||||
if (shop != null)
|
||||
{
|
||||
it.ShopName = shop.Name;
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 状态设置
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopProductPermissionDefinitionProvider.EnableName)]
|
||||
[OpAudit("上架", "门店产品", OpAuditLogEventTarget.Head)]
|
||||
[UnitOfWork(true)]
|
||||
public async Task Enable(MchSetStatusInput input, [FromServices] PcHeadLevelChildCheckDomainService headLevelChildCheckDomainService)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
|
||||
var data = await _productRepository.Where(x => x.Id == input.Id).FirstOrDefaultAsync();
|
||||
if (data.IsEmpty())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PD0000);
|
||||
}
|
||||
opAuditContext.Update(x =>
|
||||
{
|
||||
x.AddTargetSysAccountWhenRequestNormal(data.ShopId, OpAuditLogEventTarget.Shop);
|
||||
x.Msg = "上架";
|
||||
});
|
||||
|
||||
await headLevelChildCheckDomainService.InChildShopCheck(data.BusinessId, CurrentUser.ShopHeadId);
|
||||
|
||||
|
||||
data.Status = GoodsStatus.ENABLE;
|
||||
await _productRepository.UpdateIncludeNowAsync(data, new[] { nameof(data.Status) });
|
||||
}
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopProductPermissionDefinitionProvider.DisableName)]
|
||||
[OpAudit("下架", "门店产品", OpAuditLogEventTarget.Head)]
|
||||
[UnitOfWork(true)]
|
||||
public async Task Disable(MchSetStatusInput input, [FromServices] PcHeadLevelChildCheckDomainService headLevelChildCheckDomainService)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
|
||||
var data = await _productRepository.Where(x => x.Id == input.Id).FirstOrDefaultAsync();
|
||||
if (data.IsEmpty())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PD0000);
|
||||
}
|
||||
opAuditContext.Update(x =>
|
||||
{
|
||||
x.AddTargetSysAccountWhenRequestNormal(data.ShopId, OpAuditLogEventTarget.Shop);
|
||||
x.Msg = "下架" ;
|
||||
});
|
||||
|
||||
await headLevelChildCheckDomainService.InChildShopCheck(data.BusinessId, CurrentUser.ShopHeadId);
|
||||
|
||||
|
||||
data.Status = GoodsStatus.DISABLE;
|
||||
await _productRepository.UpdateIncludeNowAsync(data, new[] { nameof(data.Status) });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 信息提交
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopProductPermissionDefinitionProvider.EditName)]
|
||||
[OpAudit("编辑", "门店产品", OpAuditLogEventTarget.Head)]
|
||||
[UnitOfWork(true)]
|
||||
|
||||
public async Task SubmitAsync(BusinessSubmitProductInput input, [FromServices] PcHeadLevelChildCheckDomainService headLevelChildCheckDomainService)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
var data = await _productRepository.Where(x => x.Id == input.Id).FirstOrDefaultAsync();
|
||||
if (data.IsEmpty())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PD0000);
|
||||
}
|
||||
|
||||
opAuditContext.Update(x => x.AddTargetSysAccountWhenRequestNormal(data.ShopId, OpAuditLogEventTarget.Shop));
|
||||
|
||||
|
||||
await headLevelChildCheckDomainService.InChildShopCheck(data.BusinessId, CurrentUser.ShopHeadId);
|
||||
|
||||
//检测名称是否重复
|
||||
if (await _productRepository.DetachedEntities
|
||||
.Where(x => x.ShopId == data.ShopId && x.Name == input.Name)
|
||||
.Where(x => x.Id != input.Id)
|
||||
.AnyAsync())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PW1023);
|
||||
}
|
||||
data.Name = input.Name;
|
||||
data.SortCode = input.SortCode;
|
||||
data.Remark = input.Remark;
|
||||
await _productRepository.UpdateIncludeNowAsync(data, new[] { nameof(data.Name), nameof(data.SortCode), nameof(data.Remark) });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 产品购买记录
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopProductPermissionDefinitionProvider.ViewBuyRecordName)]
|
||||
|
||||
public async Task<BusinessProductPayListOutput> PayListAsync(BusinessProductPayListInput input)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
/* var list = await _regUserProductRepository.DetachedEntities
|
||||
.Where(CurrentUser.AccountType == AdminType.None, x => x.BusinessId == CurrentUser.ShopHeadId)
|
||||
.OrderByDescending(x => x.CreatedTime)
|
||||
.ProjectToType<BusinessProductPayListOutput>()
|
||||
.ToADPagedListAsync(input.PageNo, input.PageSize);*/
|
||||
var list = (await pcShopProductBuyRecordQueryService.GetAllChildList(CurrentUser.ShopHeadId,
|
||||
input.ChildParentHeadId, input.ShopId, input.RegUserId, input.Status, input.ProductShareNameId, input.CreateTimeRange, input.StartTimeRange, input.EndTimeRange,
|
||||
input)).Adapt<BusinessProductPayListOutput>();
|
||||
var pids = list.Rows.Select(x => x.ProductId).ToList();
|
||||
var products = await _productRepository.DetachedEntities.Where(x => pids.Contains(x.Id)).ToListAsync();
|
||||
var uids = list.Rows.Select(x => x.RegUserId).ToList();
|
||||
var users = await _regUserRepository.DetachedEntities.Where(x => uids.Contains(x.Id)).ToListAsync();
|
||||
var bids = list.Rows.Select(x => x.BusinessId).ToList();
|
||||
var allbuss = await _sysUserRepository.Get(bids.ToHashSet());
|
||||
var sids = list.Rows.Select(x => x.ShopId).ToList();
|
||||
var shops = await _shopRep.DetachedEntities.Where(x => sids.Contains(x.Id))
|
||||
.Select(x => new PC_Shop
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name
|
||||
})
|
||||
.ToListAsync();
|
||||
list.Rows.ToList().ForEach(it =>
|
||||
{
|
||||
var product = products.Where(x => x.Id == it.ProductId).FirstOrDefault();
|
||||
if (product != null)
|
||||
{
|
||||
it.Name = product.Name;
|
||||
}
|
||||
var user = users.Where(x => x.Id == it.RegUserId).FirstOrDefault();
|
||||
if (user != null)
|
||||
{
|
||||
it.UserName = user.Name;
|
||||
}
|
||||
if (allbuss.TryGetValue(it.BusinessId, out var bus))
|
||||
{
|
||||
it.BusinessName = bus.Name;
|
||||
it.BusinessCode = bus.Code;
|
||||
}
|
||||
var shop = shops.Where(x => x.Id == it.ShopId).FirstOrDefault();
|
||||
if (shop != null)
|
||||
{
|
||||
it.ShopName = shop.Name;
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 产品使用记录
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopProductPermissionDefinitionProvider.ViewUseRecordName)]
|
||||
|
||||
public async Task<BusinessProductResultListOutput> ResultListAsync(BusinessProductResultListInput input)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
/* var list = await _regUserProductResultRepository.DetachedEntities
|
||||
.Where(CurrentUser.AccountType == AdminType.None, x => x.BusinessId == CurrentUser.ShopHeadId)
|
||||
.OrderByDescending(x => x.CreatedTime)
|
||||
.ProjectToType<BusinessProductResultListOutput>()
|
||||
.ToADPagedListAsync(input.PageNo, input.PageSize);*/
|
||||
var list = (await lcShopProductUseRecordQueryService.GetAllChildList(CurrentUser.ShopHeadId,
|
||||
input.ChildParentHeadId, input.ShopId, input.RegUserId, input.ServeId, input.UserId, input.ProductShareNameId, input.CreateTimeRange,input.ResultId,
|
||||
input)).Adapt<BusinessProductResultListOutput>();
|
||||
var pids = list.Rows.Select(x => x.ProductId).ToList();
|
||||
var products = await _productRepository.DetachedEntities.Where(x => pids.Contains(x.Id)).ToListAsync();
|
||||
var uids = list.Rows.Select(x => x.RegUserId).ToList();
|
||||
var users = await _regUserRepository.DetachedEntities.Where(x => uids.Contains(x.Id)).ToListAsync();
|
||||
var aids = list.Rows.Select(x => x.UserId).ToList();
|
||||
var accounts = await _accountRepository.DetachedEntities.Where(x => aids.Contains(x.Id)).ToListAsync();
|
||||
var sids = list.Rows.Select(x => x.ServeId).ToList();
|
||||
var services = await _shopServiceRepository.DetachedEntities.Where(x => sids.Contains(x.Id)).ToListAsync();
|
||||
|
||||
var bids = list.Rows.Select(x => x.BusinessId).ToList().ToHashSet();
|
||||
var allbuss = await _sysUserRepository.Get(bids);
|
||||
var shopids = list.Rows.Select(x => x.ShopId).ToList();
|
||||
var shops = await _shopRep.DetachedEntities.Where(x => shopids.Contains(x.Id))
|
||||
.Select(x => new PC_Shop
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
list.Rows.ToList().ForEach(it =>
|
||||
{
|
||||
var product = products.Where(x => x.Id == it.ProductId).FirstOrDefault();
|
||||
if (product != null)
|
||||
{
|
||||
it.ProductName = product.Name;
|
||||
}
|
||||
var user = users.Where(x => x.Id == it.RegUserId).FirstOrDefault();
|
||||
if (user != null)
|
||||
{
|
||||
it.RegUserName = user.Name;
|
||||
}
|
||||
var account = accounts.Where(x => x.Id == it.UserId).FirstOrDefault();
|
||||
if (account != null)
|
||||
{
|
||||
it.UserName = account.Name;
|
||||
}
|
||||
var service = services.Where(x => x.Id == it.ServeId).FirstOrDefault();
|
||||
if (service != null)
|
||||
{
|
||||
it.ServeName = service.Name;
|
||||
}
|
||||
if (allbuss.TryGetValue(it.BusinessId, out var bus))
|
||||
{
|
||||
it.BusinessName = bus.Name;
|
||||
it.BusinessCode = bus.Code;
|
||||
}
|
||||
var shop = shops.Where(x => x.Id == it.ShopId).FirstOrDefault();
|
||||
if (shop != null)
|
||||
{
|
||||
it.ShopName = shop.Name;
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
#region 总部配置 -产品配置
|
||||
|
||||
/// <summary>
|
||||
/// 总部产品配置列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("BusinessShopProduct")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfDefaultProductPermissionDefinitionProvider.ViewName)]
|
||||
|
||||
public async Task<PageResult<MchProductListOutput>> ListAsync(MchProductListInput input)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
var list = await _BusinessShopProduct.DetachedEntities
|
||||
.Where(x => x.BusinessId == CurrentUser.ShopHeadId)
|
||||
.Where(!input.Name.IsEmpty(), x => x.Name.Contains(input.Name))
|
||||
.Where(input.Status != 0, x => x.Status == input.Status)
|
||||
.OrderBy(x => x.SortCode)
|
||||
.ProjectToType<MchProductListOutput>()
|
||||
.ToADPagedListAsync(input.PageNo, input.PageSize);
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 总部产品配置信息提交
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("BusinessShopProduct-add")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfDefaultProductPermissionDefinitionProvider.AddName)]
|
||||
[OpAudit("添加", "总部产品配置", OpAuditLogEventTarget.Head)]
|
||||
[UnitOfWork(true)]
|
||||
|
||||
public async Task SubmitAsync(MchSubmitProductInput input, [FromServices] IFeatureChecker _featureChecker)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
if (await _BusinessShopProduct
|
||||
.DetachedEntities
|
||||
.Where(x => x.BusinessId == CurrentUser.ShopHeadId && x.Name == input.Name)
|
||||
.Where(input.Id > 0, x => x.Id != input.Id)
|
||||
.AnyAsync())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PW1023);
|
||||
}
|
||||
|
||||
{
|
||||
var maxLimitCount = await _featureChecker.GetAsync<int>(ShopHeadOfProductFeatureDefinitionProvider.LIMIT_MAX);
|
||||
if (await _BusinessShopProduct
|
||||
.DetachedEntities
|
||||
.Where(x => x.BusinessId == CurrentUser.ShopHeadId)
|
||||
.CountAsync() >= maxLimitCount)
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.LIMIT_MAX_COUNT10001, maxLimitCount);
|
||||
}
|
||||
}
|
||||
|
||||
var data = input.Adapt<PC_BusinessShopProduct>();
|
||||
/* if (!input.Id.IsEmpty())
|
||||
{
|
||||
data.BusinessId = CurrentUser.ShopHeadId;
|
||||
data.UpdatedUserId = CurrentUser.UserId;
|
||||
data.UpdatedUserName = CurrentUser.Name;
|
||||
await _BusinessShopProduct.UpdateIncludeNowAsync(data, new[] { nameof(data.Name), nameof(data.SortCode), nameof(data.Remark) });
|
||||
}
|
||||
else*/
|
||||
{
|
||||
data.Status = GoodsStatus.ENABLE;
|
||||
data.BusinessId = CurrentUser.ShopHeadId;
|
||||
data.CreatedUserId = CurrentUser.UserId;
|
||||
data.CreatedUserName = CurrentUser.Name;
|
||||
await _BusinessShopProduct.InsertNowAsync(data);
|
||||
}
|
||||
}
|
||||
[HttpPost("BusinessShopProduct-edit")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfDefaultProductPermissionDefinitionProvider.EditName)]
|
||||
[OpAudit("编辑", "总部产品配置", OpAuditLogEventTarget.Head)]
|
||||
[UnitOfWork(true)]
|
||||
public async Task SubmitEditAsync(MchSubmitProductInput input)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
if (await _BusinessShopProduct
|
||||
.DetachedEntities
|
||||
.Where(x => x.BusinessId == CurrentUser.ShopHeadId && x.Name == input.Name)
|
||||
.Where(input.Id > 0, x => x.Id != input.Id)
|
||||
.AnyAsync())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PW1023);
|
||||
}
|
||||
// var data = input.Adapt<PC_BusinessShopProduct>();
|
||||
if (!input.Id.IsEmpty())
|
||||
{
|
||||
|
||||
var _ = await _BusinessShopProduct.Where(x => x.Id == input.Id && x.BusinessId == CurrentUser.ShopHeadId).FirstOrDefaultAsync();
|
||||
if (_.IsEmpty())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PD0000);
|
||||
}
|
||||
|
||||
var data = input.Adapt(_);
|
||||
//data.BusinessId = CurrentUser.ShopHeadId;
|
||||
data.UpdatedUserId = CurrentUser.UserId;
|
||||
data.UpdatedUserName = CurrentUser.Name;
|
||||
await _BusinessShopProduct.UpdateIncludeNowAsync(data, new[] { nameof(data.Name), nameof(data.SortCode), nameof(data.Remark) });
|
||||
}
|
||||
/* else
|
||||
{
|
||||
data.Status = GoodsStatus.WAIT;
|
||||
data.BusinessId = CurrentUser.ShopHeadId;
|
||||
data.CreatedUserId = CurrentUser.UserId;
|
||||
data.CreatedUserName = CurrentUser.Name;
|
||||
await _BusinessShopProduct.InsertNowAsync(data);
|
||||
}*/
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 状态设置
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("BusinessShopProduct-enable")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfDefaultProductPermissionDefinitionProvider.EnableName)]
|
||||
[OpAudit("上架", "总部产品配置", OpAuditLogEventTarget.Head)]
|
||||
[UnitOfWork(true)]
|
||||
public async Task ZBEnable(MchSetStatusInput input)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
var data = await _BusinessShopProduct.Where(x => x.Id == input.Id).FirstOrDefaultAsync();
|
||||
if (data.IsEmpty())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PD0000);
|
||||
}
|
||||
opAuditContext.Update(x =>
|
||||
{
|
||||
x.Msg = "上架";
|
||||
});
|
||||
data.Status = GoodsStatus.ENABLE;
|
||||
data.UpdatedUserId = CurrentUser.UserId;
|
||||
data.UpdatedUserName = CurrentUser.Name;
|
||||
await _BusinessShopProduct.UpdateIncludeNowAsync(data, new[] { nameof(data.Status) });
|
||||
}
|
||||
[HttpPost("BusinessShopProduct-disable")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfDefaultProductPermissionDefinitionProvider.DisableName)]
|
||||
[OpAudit("下架", "总部产品配置", OpAuditLogEventTarget.Head)]
|
||||
[UnitOfWork(true)]
|
||||
public async Task ZBSetStatusAsync(MchSetStatusInput input)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
var data = await _BusinessShopProduct.Where(x => x.Id == input.Id).FirstOrDefaultAsync();
|
||||
if (data.IsEmpty())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PD0000);
|
||||
}
|
||||
opAuditContext.Update(x =>
|
||||
{
|
||||
x.Msg = "下架" ;
|
||||
});
|
||||
data.Status = GoodsStatus.DISABLE;
|
||||
data.UpdatedUserId = CurrentUser.UserId;
|
||||
data.UpdatedUserName = CurrentUser.Name;
|
||||
await _BusinessShopProduct.UpdateIncludeNowAsync(data, new[] { nameof(data.Status) });
|
||||
}
|
||||
|
||||
#endregion 总部配置 -产品配置
|
||||
}
|
||||
|
||||
public class ShopHeadOfShopProductPermissionDefinitionProvider : PermissionDefinitionProvider
|
||||
{
|
||||
|
||||
|
||||
public const string GroupName = $"{ShopHeadPermissionDefinitionNames.Prefix}.shop.product";
|
||||
public const string ViewName = $"{GroupName}.view";
|
||||
public const string ViewUseRecordName = $"{GroupName}.use.record.view";
|
||||
public const string ViewBuyRecordName = $"{GroupName}.buy.record.view";
|
||||
|
||||
//public const string AddName = $"{GroupName}.add";
|
||||
//public const string DelName = $"{GroupName}.del";
|
||||
public const string EditName = $"{GroupName}.edit";
|
||||
public const string EnableName = $"{GroupName}.enable";
|
||||
public const string DisableName = $"{GroupName}.disable";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public override void Define(IPermissionDefinitionContext context)
|
||||
{
|
||||
{
|
||||
var groups = context.AddGroup($"{GroupName}", new FixedLocalizableString("门店产品管理"));
|
||||
|
||||
groups.AddPermission($"{ViewName}", new FixedLocalizableString("查看产品")).RequireFeatures(ShopHeadOfShopProductFeatureDefinitionProvider.Shop_MANAGE);
|
||||
groups.AddPermission($"{ViewUseRecordName}", new FixedLocalizableString("查看使用记录")).RequireFeatures(ShopHeadOfShopProductFeatureDefinitionProvider.Shop_MANAGE);
|
||||
groups.AddPermission($"{ViewBuyRecordName}", new FixedLocalizableString("查看购买记录")).RequireFeatures(ShopHeadOfShopProductFeatureDefinitionProvider.Shop_MANAGE);
|
||||
|
||||
//groups.AddPermission($"{AddName}", new FixedLocalizableString("添加")).RequireFeatures(ShopHeadOfShopProductFeatureDefinitionProvider.Shop_MANAGE);
|
||||
groups.AddPermission($"{EditName}", new FixedLocalizableString("编辑")).RequirePermissions(ViewName).RequireFeatures(ShopHeadOfShopProductFeatureDefinitionProvider.Shop_MANAGE);
|
||||
////groups.AddPermission($"{DelName}", new FixedLocalizableString("删除"));
|
||||
groups.AddPermission($"{EnableName}", new FixedLocalizableString("启用")).RequirePermissions(ViewName).RequireFeatures(ShopHeadOfShopProductFeatureDefinitionProvider.Shop_MANAGE);
|
||||
groups.AddPermission($"{DisableName}", new FixedLocalizableString("禁用")).RequirePermissions(ViewName).RequireFeatures(ShopHeadOfShopProductFeatureDefinitionProvider.Shop_MANAGE);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ShopHeadOfDefaultProductPermissionDefinitionProvider : PermissionDefinitionProvider
|
||||
{
|
||||
|
||||
|
||||
public const string GroupName = $"{ShopHeadPermissionDefinitionNames.Prefix}.self.product";
|
||||
|
||||
|
||||
|
||||
public const string ViewName = $"{GroupName}.view";
|
||||
|
||||
public const string AddName = $"{GroupName}.add";
|
||||
//public const string DelName = $"{GroupName}.del";
|
||||
public const string EditName = $"{GroupName}.edit";
|
||||
public const string EnableName = $"{GroupName}.enable";
|
||||
public const string DisableName = $"{GroupName}.disable";
|
||||
|
||||
|
||||
public override void Define(IPermissionDefinitionContext context)
|
||||
{
|
||||
{
|
||||
var groups = context.AddGroup($"{GroupName}", new FixedLocalizableString("总部产品管理"));
|
||||
|
||||
|
||||
groups.AddPermission($"{ViewName}", new FixedLocalizableString("查看")).RequireFeatures(ShopHeadOfProductFeatureDefinitionProvider.Self_MANAGE);
|
||||
groups.AddPermission($"{AddName}", new FixedLocalizableString("添加")).RequirePermissions(ViewName).RequireFeatures(ShopHeadOfProductFeatureDefinitionProvider.Self_MANAGE);
|
||||
groups.AddPermission($"{EditName}", new FixedLocalizableString("编辑")).RequirePermissions(ViewName).RequireFeatures(ShopHeadOfProductFeatureDefinitionProvider.Self_MANAGE);
|
||||
//groups.AddPermission($"{DelName}", new FixedLocalizableString("删除"));
|
||||
groups.AddPermission($"{EnableName}", new FixedLocalizableString("上架")).RequirePermissions(ViewName).RequireFeatures(ShopHeadOfProductFeatureDefinitionProvider.Self_MANAGE);
|
||||
groups.AddPermission($"{DisableName}", new FixedLocalizableString("下架")).RequirePermissions(ViewName).RequireFeatures(ShopHeadOfProductFeatureDefinitionProvider.Self_MANAGE);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
namespace JT.Shop.Application.Service.Business.Retailer
|
||||
{
|
||||
/// <summary>
|
||||
/// 分销商管理
|
||||
/// </summary>
|
||||
public interface IRetailerService
|
||||
{
|
||||
/// <summary>
|
||||
/// 分销商列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
Task<PageResult<BusiensslistS2CDto>> ListAsync(BusinessListC2SDto input);
|
||||
|
||||
/// <summary>
|
||||
/// 信息提交
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
Task SubmitAsync(BusinessSubmitC2SDto input);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
namespace JT.Shop.Application.Service.Business.Retailer
|
||||
{
|
||||
/// <summary>
|
||||
/// 分销商管理
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings("管理平台")]
|
||||
[Route("/api/business/account")]
|
||||
|
||||
public class RetailerAppService //暂时关闭: IDynamicApiController
|
||||
{
|
||||
private readonly IRetailerService _retailerService;
|
||||
|
||||
public RetailerAppService(IRetailerService retailerService)
|
||||
{
|
||||
_retailerService = retailerService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分销商列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PageResult<BusiensslistS2CDto>> ListAsync(BusinessListC2SDto input)
|
||||
{
|
||||
return await _retailerService.ListAsync(input);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 信息提交
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public Task SubmitAsync(BusinessSubmitC2SDto input)
|
||||
{
|
||||
return _retailerService.SubmitAsync(input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
using Yitter.IdGenerator;
|
||||
|
||||
namespace JT.Shop.Application.Service.Business.Retailer
|
||||
{
|
||||
/// <summary>
|
||||
/// 分销商管理
|
||||
/// </summary>
|
||||
public class RetailerService : IRetailerService, ITransient
|
||||
{
|
||||
private readonly IMyRepository<SysUser> _sysUserRep;
|
||||
private readonly IRepository<PC_User> _retailerRep;
|
||||
private readonly IRepository<SysUserRole> _userroleRep;
|
||||
private readonly IRepository<SysEmp> _empRep;
|
||||
private readonly IRepository<SysEmpPos> _sysempposRep;
|
||||
private readonly UserManager UserInfo;
|
||||
|
||||
public RetailerService(
|
||||
IMyRepository<SysUser> sysUserRep,
|
||||
IRepository<PC_User> retailerRep,
|
||||
IRepository<SysUserRole> userroleRep,
|
||||
IRepository<SysEmp> empRep,
|
||||
IRepository<SysEmpPos> sysempposRep,
|
||||
UserManager userManager)
|
||||
{
|
||||
_sysUserRep = sysUserRep;
|
||||
_retailerRep = retailerRep;
|
||||
_userroleRep = userroleRep;
|
||||
_empRep = empRep;
|
||||
_sysempposRep = sysempposRep;
|
||||
UserInfo = userManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分销商列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PageResult<BusiensslistS2CDto>> ListAsync(BusinessListC2SDto input)
|
||||
{
|
||||
var CurrentUser = UserInfo.GetCurrentUserInfo();
|
||||
input.Phone = input.Phone.ToStr();
|
||||
input.Name = input.Name.ToStr();
|
||||
var list = await _retailerRep.DetachedEntities
|
||||
.Where(CurrentUser.AccountType == AdminType.None, x => x.Pid == CurrentUser.UserId)
|
||||
.Where(!input.Phone.IsEmpty(), x => _sysUserRep.DetachedEntities.Where(e => (e.Phone == input.Phone || e.Account == input.Phone) && e.Id == x.Id).Any())
|
||||
.Where(!input.Name.IsEmpty(), x => _sysUserRep.DetachedEntities.Where(e => e.Name == input.Name && e.Id == x.Id).Any())
|
||||
.OrderByDescending(x => x.CreatedTime)
|
||||
.ProjectToType<BusiensslistS2CDto>()
|
||||
.ToADPagedListAsync(input.PageNo, input.PageSize);
|
||||
var ids = list.Rows.Select(x => x.Id).ToList();
|
||||
var alluser = await _sysUserRep.GetAllNoFilterAsync(x => ids.Contains(x.Id), x => new SysUser
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name,
|
||||
Phone = x.Phone,
|
||||
Account = x.Account,
|
||||
Status = x.Status
|
||||
});
|
||||
list.Rows.ToList().ForEach(it =>
|
||||
{
|
||||
var user = alluser.FirstOrDefault(x => x.Id == it.Id);
|
||||
it.Name = user?.Name;
|
||||
it.Phone = user?.Phone;
|
||||
it.Account = user?.Account;
|
||||
it.Status = user.IsEmpty() ? CommonStatus.Enable : user.Status;
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 信息提交
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task SubmitAsync(BusinessSubmitC2SDto input)
|
||||
{
|
||||
var CurrentUser = UserInfo.GetCurrentUserInfo();
|
||||
if (await _sysUserRep.DetachedEntities
|
||||
.Where(input.Id > 0, x => x.Account == input.Account && x.Id != input.Id)
|
||||
.Where(!input.Id.HasValue || input.Id == 0, x => x.Account == input.Account)
|
||||
.AnyAsync())
|
||||
{
|
||||
throw Oops.Bah(ErrorCode.D1003);
|
||||
}
|
||||
if (input.Id > 0)
|
||||
{
|
||||
// 更新账户
|
||||
var updateuser = input.Adapt<SysUser>();
|
||||
updateuser.NickName = updateuser.Name;
|
||||
await _sysUserRep.UpdateIncludeNowAsync(updateuser, new[] { nameof(updateuser.Account), nameof(updateuser.Name), nameof(updateuser.Phone), nameof(updateuser.NickName) });
|
||||
}
|
||||
else
|
||||
{
|
||||
// 添加账户
|
||||
var insertuser = input.Adapt<SysUser>();
|
||||
insertuser.Id = YitIdHelper.NextId();
|
||||
insertuser.Password = Hinse.Util.Security.MD5Encryption.Encrypt(input.Password, 32);
|
||||
insertuser.NickName = insertuser.Name;
|
||||
insertuser.AdminType = AdminType.None;
|
||||
input.Id = insertuser.Id;
|
||||
await _sysUserRep.InsertNowAsync(insertuser);
|
||||
// 绑定角色
|
||||
var sysuserrole = new SysUserRole
|
||||
{
|
||||
SysUserId = insertuser.Id,
|
||||
SysRoleId = 142307070910555
|
||||
};
|
||||
await _userroleRep.InsertNowAsync(sysuserrole);
|
||||
// 添加员工信息
|
||||
var sysemp = new SysEmp
|
||||
{
|
||||
Id = insertuser.Id,
|
||||
JobNum = "",
|
||||
OrgId = 142307070910539,
|
||||
OrgName = "郑州巨天"
|
||||
};
|
||||
await _empRep.InsertNowAsync(sysemp);
|
||||
|
||||
// 添加职位信息
|
||||
var sysemppos = new SysEmpPos
|
||||
{
|
||||
SysEmpId = insertuser.Id,
|
||||
SysPosId = 142307070910550
|
||||
};
|
||||
await _sysempposRep.InsertNowAsync(sysemppos);
|
||||
// 添加金额配置
|
||||
var retailer = input.Adapt<PC_User>();
|
||||
retailer.Id = insertuser.Id;
|
||||
retailer.Pid = CurrentUser.AccountType == AdminType.None ? CurrentUser.UserId : 0;
|
||||
retailer.Pids = await CreateNewPids(retailer.Pid);
|
||||
await _retailerRep.InsertNowAsync(retailer);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建Pids格式 如果pid是0顶级节点,pids就是 [0]; 如果pid不是顶级节点,pids就是 pid菜单的 pids + [pid] + ,
|
||||
/// </summary>
|
||||
/// <param name="pid"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<string> CreateNewPids(long pid)
|
||||
{
|
||||
if (pid == 0L)
|
||||
{
|
||||
return "[0],";
|
||||
}
|
||||
else
|
||||
{
|
||||
var pmenu = await _retailerRep
|
||||
.Where(u => u.Id == pid && !u.IsDeleted, false, true)
|
||||
.FirstOrDefaultAsync();
|
||||
return pmenu.Pids + "[" + pid + "],";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
namespace JT.Shop.Application.Service.Business.Role.Dto
|
||||
{
|
||||
/// <summary>
|
||||
/// 映射
|
||||
/// </summary>
|
||||
public class CMapper : IRegister
|
||||
{
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public void Register(TypeAdapterConfig config)
|
||||
{
|
||||
//编辑角色
|
||||
config.ForType<UpdateUserRoleInput, PC_Role>()
|
||||
.Map(dest => dest.Name, src => src.Name.ToStrNoEmpty())
|
||||
.Map(dest => dest.Code, src => src.Code.ToStrNoEmpty())
|
||||
.Map(dest => dest.Remark, src => src.Remark.ToStrNoEmpty())
|
||||
;
|
||||
//新增角色
|
||||
config.ForType<AddUserRoleInput, PC_Role>()
|
||||
.Map(dest => dest.Name, src => src.Name.ToStrNoEmpty())
|
||||
.Map(dest => dest.Code, src => src.Code.ToStrNoEmpty())
|
||||
.Map(dest => dest.Remark, src => src.Remark.ToStrNoEmpty())
|
||||
.Map(dest => dest.Status, src => CommonStatus.Enable)
|
||||
.Map(dest => dest.DataScopeType, src => DataScopeType.ALL)
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
namespace JT.Shop.Application.Service.Business.Role
|
||||
{
|
||||
/// <summary>
|
||||
/// 添加角色
|
||||
/// </summary>
|
||||
public class AddUserRoleInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "角色名称不能为空")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 编码
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "角色编码不能为空")]
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序
|
||||
/// </summary>
|
||||
public int Sort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据范围类型(字典 1全部数据 2本部门及以下数据 3本部门数据 4仅本人数据 5自定义数据)
|
||||
/// </summary>
|
||||
public int DataScopeType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
public string Remark { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新角色
|
||||
/// </summary>
|
||||
public class UpdateUserRoleInput : AddUserRoleInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 角色Id
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "角色Id不能为空")]
|
||||
public long Id { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
namespace JT.Shop.Application.Service.Business.Role
|
||||
{
|
||||
/// <summary>
|
||||
/// 角色分页列表
|
||||
/// </summary>
|
||||
public class UserRolePageListS2CDto : BaseIdAndUserInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 编码
|
||||
/// </summary>
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序
|
||||
/// </summary>
|
||||
public int Sort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据范围类型(字典 1全部数据 2本部门及以下数据 3本部门数据 4仅本人数据 5自定义数据)
|
||||
/// </summary>
|
||||
public DataScopeType DataScopeType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
public string Remark { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
namespace JT.Shop.Application.Service.Business.Role
|
||||
{
|
||||
/// <summary>
|
||||
/// 角色管理
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings("管理平台")]
|
||||
[Route("/api/business/[controller]")]
|
||||
public class UserRoleService //暂时关闭: ITransient, IDynamicApiController
|
||||
{
|
||||
private readonly IRepository<PC_Role> _roleRepository;
|
||||
private readonly IRepository<PC_UserRole> _userRoleRepository;
|
||||
private readonly IRepository<PC_RoleMenu> _roleMenuRepository;
|
||||
private readonly IRepository<SysMenu> _sysMenuRepository;
|
||||
private readonly IMyRepository<SysUser> _sysUserRepository;
|
||||
private readonly UserManager UserInfo;
|
||||
|
||||
public UserRoleService(
|
||||
IRepository<PC_Role> roleRep,
|
||||
UserManager userManager,
|
||||
IRepository<PC_UserRole> userRoleRepository,
|
||||
IRepository<PC_RoleMenu> roleMenuRepository,
|
||||
IRepository<SysMenu> sysMenuRepository,
|
||||
IMyRepository<SysUser> sysUserRepository)
|
||||
{
|
||||
_roleRepository = roleRep;
|
||||
UserInfo = userManager;
|
||||
_userRoleRepository = userRoleRepository;
|
||||
_roleMenuRepository = roleMenuRepository;
|
||||
_sysMenuRepository = sysMenuRepository;
|
||||
_sysUserRepository = sysUserRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页获取角色列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PageResult<UserRolePageListS2CDto>> PageAsync(RolePageInput input)
|
||||
{
|
||||
var CurrentUser = UserInfo.GetCurrentShopHeadInfo();
|
||||
var list = await _roleRepository.DetachedEntities
|
||||
.Where(CurrentUser.AccountType == AdminType.None, x => x.BusinessId == CurrentUser.ShopHeadId)
|
||||
.Where(!input.Name.IsEmpty(), u => EF.Functions.Like(u.Name, $"%{input.Name.Trim()}%"))
|
||||
.Where(!input.Code.IsEmpty(), u => EF.Functions.Like(u.Code, $"%{input.Code.Trim()}%"))
|
||||
.OrderBy(x => x.Sort)
|
||||
.ProjectToType<UserRolePageListS2CDto>()
|
||||
.ToADPagedListAsync(input.PageNo, input.PageSize);
|
||||
var bids = list.Rows.Select(x => x.BusinessId).ToList();
|
||||
var allbuss = await _sysUserRepository.DetachedEntities.Where(x => bids.Contains(x.Id))
|
||||
.Select(x => new SysUser
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name
|
||||
})
|
||||
.ToListAsync();
|
||||
list.Rows.ToList().ForEach(it =>
|
||||
{
|
||||
var user = allbuss.Where(x => x.Id == it.BusinessId).FirstOrDefault();
|
||||
if (user != null)
|
||||
{
|
||||
it.BusinessName = user.Name;
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取角色列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<dynamic> ListAsync(RoleInput input)
|
||||
{
|
||||
var CurrentUser = UserInfo.GetCurrentUserInfo();
|
||||
return await _roleRepository.DetachedEntities
|
||||
.Where(u => u.BusinessId == CurrentUser.UserId)
|
||||
.Where(!input.Name.IsEmpty(), u => EF.Functions.Like(u.Name, $"%{input.Name.Trim()}%"))
|
||||
.Where(!input.Code.IsEmpty(), u => EF.Functions.Like(u.Code, $"%{input.Code.Trim()}%"))
|
||||
.Where(u => u.Status == CommonStatus.Enable)
|
||||
.OrderBy(u => u.Sort)
|
||||
.Select(u => new
|
||||
{
|
||||
u.Id,
|
||||
Name = u.Name + "[" + u.Code + "]",
|
||||
})
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 角色下拉(用于授权角色时选择)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<List<RoleOutput>> DropDownAsync()
|
||||
{
|
||||
var CurrentUserInfo = UserInfo.GetCurrentUserInfo();
|
||||
return await _roleRepository.DetachedEntities
|
||||
.Where(u => u.BusinessId == CurrentUserInfo.UserId)
|
||||
.Where(u => u.Status == CommonStatus.Enable)
|
||||
.OrderBy(u => u.Sort)
|
||||
.ProjectToType<RoleOutput>()
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加角色
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task AddAsync(AddUserRoleInput input)
|
||||
{
|
||||
var CurrentUserInfo = UserInfo.GetCurrentUserInfo();
|
||||
var isExist = await _roleRepository.DetachedEntities.AnyAsync(u => (u.Code == input.Code || u.Name == input.Name) && u.BusinessId == CurrentUserInfo.UserId);
|
||||
if (isExist)
|
||||
throw Oops.Bah(ErrorCode.D1006);
|
||||
|
||||
var role = input.Adapt<PC_Role>();
|
||||
role.BusinessId = CurrentUserInfo.UserId;
|
||||
await _roleRepository.InsertNowAsync(role);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新角色
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task EditAsync(UpdateUserRoleInput input)
|
||||
{
|
||||
var CurrentUserInfo = UserInfo.GetCurrentUserInfo();
|
||||
var adminRole = await _roleRepository.DetachedEntities.FirstOrDefaultAsync(u => u.Id == input.Id);
|
||||
if (adminRole.Code == CommonConst.SYS_MANAGER_ROLE_CODE)
|
||||
throw Oops.Bah(ErrorCode.D1020);
|
||||
|
||||
var isExist = await _roleRepository.DetachedEntities.AnyAsync(u => (u.Name == input.Name || u.Code == input.Code) && u.Id != input.Id && u.BusinessId == CurrentUserInfo.UserId);
|
||||
if (isExist)
|
||||
throw Oops.Bah(ErrorCode.D1006);
|
||||
|
||||
var sysRole = input.Adapt<PC_Role>();
|
||||
await _roleRepository.UpdateIncludeNowAsync(sysRole, new[] { nameof(sysRole.Name), nameof(sysRole.Code), nameof(sysRole.Remark), nameof(sysRole.Sort) });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取角色
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PC_Role> DetailAsync(QueryRoleInput input)
|
||||
{
|
||||
return await _roleRepository.DetachedEntities.FirstOrDefaultAsync(u => u.Id == input.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 授权角色菜单
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task GrantMenuAsync(GrantRoleMenuInput input)
|
||||
{
|
||||
var CurrentUserInfo = UserInfo.GetCurrentUserInfo();
|
||||
await _roleMenuRepository.Where(x => x.RoleId == input.Id).DeleteAsync();
|
||||
|
||||
var roleMenuPidsList = await _sysMenuRepository.DetachedEntities.Where(u => input.GrantMenuIdList.Contains(u.Id))
|
||||
.Select(u => u.Pids).ToListAsync();
|
||||
|
||||
var roleMenuSplitPids = roleMenuPidsList
|
||||
.SelectMany(u => u.Split(',', StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(v => long.Parse(v[1..^1]))
|
||||
.Where(v => v != 0))
|
||||
.Union(input.GrantMenuIdList);
|
||||
|
||||
var menus = roleMenuSplitPids.Select(u => new PC_RoleMenu
|
||||
{
|
||||
RoleId = input.Id,
|
||||
MenuId = u
|
||||
}).ToList();
|
||||
menus.ForEach(u => u.Id = YitIdHelper.NextId());
|
||||
await _roleMenuRepository.InsertAsync(menus);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取角色拥有菜单Id集合
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<long>> OwnMenuAsync(QueryRoleInput input)
|
||||
{
|
||||
return await _roleMenuRepository.DetachedEntities
|
||||
.Where(u => u.RoleId == input.Id)
|
||||
.Select(u => u.MenuId).ToListAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
namespace JT.Shop.Application.Service.Business.Serve
|
||||
{
|
||||
/// <summary>
|
||||
/// 门店服务列表
|
||||
/// </summary>
|
||||
public class BusinessServeListC2SDto : PageInputV2Base
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否为非精护
|
||||
/// </summary>
|
||||
|
||||
public bool? IsWeight { get; set; }
|
||||
/// <summary>
|
||||
/// 创建时间范围
|
||||
/// </summary>
|
||||
public DateRangeFilterInput CreateTimeRange { get; set; }
|
||||
public long? ChildParentHeadId { get; set; }
|
||||
public long? ShopId { get; set; }
|
||||
/* /// <summary>
|
||||
/// 服务编码
|
||||
/// </summary>
|
||||
public string Code { get; set; }
|
||||
/// <summary>
|
||||
/// 服务名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }*/
|
||||
public HashSet<long> ServiceShareNameId { get; set; }
|
||||
/// <summary>
|
||||
/// 状态
|
||||
/// </summary>
|
||||
public GoodsStatus? Status { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 门店服务提交
|
||||
/// </summary>
|
||||
public class BusinessSubmitServeInput : BaseNullId
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务名称
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "服务名称不能为空")]
|
||||
[MaxLength(50, ErrorMessage = "服务名称不能超过50个字符")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 展示名称
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "展示名称不能为空")]
|
||||
[MaxLength(50, ErrorMessage = "展示名称不能超过50个字符")]
|
||||
public string ShowName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否为非精护
|
||||
/// </summary>
|
||||
public bool IsWeight { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 排序,数字越小越靠前
|
||||
/// </summary>
|
||||
public int SortCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
[MaxLength(200, ErrorMessage = "备注不能超过200个字符")]
|
||||
public string Remark { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 服务记录
|
||||
/// </summary>
|
||||
public class BusinessServeResultListInput : PageInputV2Base
|
||||
{
|
||||
/// <summary>
|
||||
/// 创建时间范围
|
||||
/// </summary>
|
||||
public DateRangeFilterInput CreateTimeRange { get; set; }
|
||||
public long? ChildParentHeadId { get; set; }
|
||||
public long? ShopId { get; set; }
|
||||
/// <summary>
|
||||
/// 会员名称或电话
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
public string Phone { get; set; }
|
||||
public long? RegUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 完成状态
|
||||
/// </summary>
|
||||
public ServeStatus? Status { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
using JT.Shop.Core;
|
||||
|
||||
namespace JT.Shop.Application.Service.Business.Serve
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务列表
|
||||
/// </summary>
|
||||
public class BusinessServeListS2CDto : BaseIdAndUserInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 展示名称
|
||||
/// </summary>
|
||||
public string ShowName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 编码
|
||||
/// </summary>
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序,数字越小越靠前
|
||||
/// </summary>
|
||||
public int SortCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态
|
||||
/// </summary>
|
||||
public GoodsStatus Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
public string Remark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否为非精护
|
||||
/// </summary>
|
||||
public bool IsWeight { get; set; } = false;
|
||||
public DateTime CreatedTime { get; set; }
|
||||
/// <summary>
|
||||
/// 服务计算次数
|
||||
/// </summary>
|
||||
public int ComputeTimes { get; set; }
|
||||
}
|
||||
|
||||
public class BusinessServeListS2CDtoOutput: PageResultV2<BusinessServeListS2CDto>
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 服务记录
|
||||
/// </summary>
|
||||
public class BusinessServeResultListOutputItem : BaseIdAndUserInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 注册用户ID
|
||||
/// </summary>
|
||||
public long RegUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户名称
|
||||
/// </summary>
|
||||
public string RegUserName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 完成状态
|
||||
/// </summary>
|
||||
public ServeStatus Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime? CreatedTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 服务ID
|
||||
/// </summary>
|
||||
public long ServeId { get; set; }
|
||||
/// <summary>
|
||||
/// 店员ID
|
||||
/// </summary>
|
||||
public long UserId { get; set; }
|
||||
/// <summary>
|
||||
/// 服务名称
|
||||
/// </summary>
|
||||
public string ServeName { get; set; }
|
||||
/// <summary>
|
||||
/// 店员名称
|
||||
/// </summary>
|
||||
public string UserName { get; set; }
|
||||
public long ProductId { get; set; }
|
||||
public string ProductName { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class BusinessServeResultListOutput: PageResultV2<BusinessServeResultListOutputItem>
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,441 @@
|
|||
using JT.Shop.Application.Service.Mch.Product;
|
||||
using JT.Shop.Application.Service.Mch.Serve;
|
||||
using JT.Shop.Application.Service.ShopHead;
|
||||
using JT.Shop.Core;
|
||||
using JT.Shop.Domain.Entity.ShopHead;
|
||||
using JT.Shop.Domain.FeatureDefinitions.ShopHead;
|
||||
using Volo.Abp.Authorization.Permissions;
|
||||
using Volo.Abp.Features;
|
||||
using Volo.Abp.Localization;
|
||||
|
||||
namespace JT.Shop.Application.Service.Business.Serve
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务管理
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings("总部")]
|
||||
[Route("/api/business/[controller]")]
|
||||
public class ServeService : AppService, IDynamicApiController
|
||||
{
|
||||
private readonly IRepository<PC_ShopService> _serveRepository;
|
||||
private readonly IRepository<PC_ShopServiceResult> _resultRepository;
|
||||
private readonly IRepository<PC_ShopRegUser> _regUserRepository;
|
||||
private readonly IRepository<PC_Shop> _shopRep;
|
||||
private readonly IPcShopHeadQueryService _sysUserRepository;
|
||||
private readonly IRepository<PC_BusinessShopService> _BusinessShopService;
|
||||
private readonly UserManager _userManager;
|
||||
private readonly IPcShopServiceQueryService pcShopServiceQueryService;
|
||||
private readonly IPcShopServiceResultQueryService pcShopServiceResultQueryService;
|
||||
private readonly OpAuditContext opAuditContext;
|
||||
|
||||
public ServeService(
|
||||
IRepository<PC_ShopService> serveRepository,
|
||||
UserManager userManager,
|
||||
IRepository<PC_ShopServiceResult> resultRepository,
|
||||
IRepository<PC_ShopRegUser> regUserRepository,
|
||||
IRepository<PC_Shop> shopRep,
|
||||
IRepository<PC_BusinessShopService> BusinessShopService,
|
||||
IPcShopHeadQueryService sysUserRepository, IPcShopServiceQueryService pcShopServiceQueryService, IPcShopServiceResultQueryService pcShopServiceResultQueryService, OpAuditContext opAuditContext)
|
||||
{
|
||||
_serveRepository = serveRepository;
|
||||
_userManager = userManager;
|
||||
_resultRepository = resultRepository;
|
||||
_regUserRepository = regUserRepository;
|
||||
_shopRep = shopRep;
|
||||
_BusinessShopService = BusinessShopService;
|
||||
_sysUserRepository = sysUserRepository;
|
||||
this.pcShopServiceQueryService = pcShopServiceQueryService;
|
||||
this.pcShopServiceResultQueryService = pcShopServiceResultQueryService;
|
||||
this.opAuditContext = opAuditContext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取服务列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopServePermissionDefinitionProvider.ViewName)]
|
||||
public async Task<BusinessServeListS2CDtoOutput> ListAsync(BusinessServeListC2SDto input)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
/* var list = await _serveRepository.DetachedEntities
|
||||
.Where(CurrentUser.AccountType == AdminType.None, x => x.BusinessId == CurrentUser.ShopHeadId)
|
||||
.Where(!input.Name.IsEmpty(), x => EF.Functions.Like(x.Name, $"%{input.Name}%"))
|
||||
.Where(input.Status != 0, x => x.Status == input.Status)
|
||||
.OrderBy(x => x.SortCode)
|
||||
.ProjectToType<BusinessServeListS2CDto>()
|
||||
.ToADPagedListAsync(input.PageNo, input.PageSize);*/
|
||||
var list = (await pcShopServiceQueryService.GetAllChildList(CurrentUser.ShopHeadId, input.ChildParentHeadId,
|
||||
input.ShopId, input.ServiceShareNameId, input.IsWeight, input.Status, input.CreateTimeRange, input)).Adapt<BusinessServeListS2CDtoOutput>();
|
||||
if (list.TotalRows == 0) return list;
|
||||
var uids = list.Rows.Select(x => x.BusinessId).ToList();
|
||||
var users = await _sysUserRepository.Get(uids.ToHashSet());
|
||||
var sids = list.Rows.Select(x => x.ShopId).ToHashSet();
|
||||
var shops = await _shopRep.DetachedEntities.Where(x => sids.Contains(x.Id))
|
||||
.Select(x => new PC_Shop
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name
|
||||
})
|
||||
.ToListAsync();
|
||||
list.Rows.ToList().ForEach(it =>
|
||||
{
|
||||
if (users.TryGetValue(it.BusinessId, out var user))
|
||||
{
|
||||
it.BusinessName = user.Name;
|
||||
it.BusinessCode = user.Code;
|
||||
}
|
||||
var shop = shops.Where(x => x.Id == it.ShopId).FirstOrDefault();
|
||||
if (shop != null)
|
||||
{
|
||||
it.ShopName = shop.Name;
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 状态设置
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopServePermissionDefinitionProvider.EnableName)]
|
||||
[OpAudit("上架", "门店服务", OpAuditLogEventTarget.Head)]
|
||||
[UnitOfWork(true)]
|
||||
public async Task Enable(MchSetStatusInput input, [FromServices] PcHeadLevelChildCheckDomainService headLevelChildCheckDomainService)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
|
||||
|
||||
|
||||
var data = await _serveRepository.Where(x => x.Id == input.Id).FirstOrDefaultAsync();
|
||||
if (data.IsEmpty())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PD0000);
|
||||
}
|
||||
|
||||
opAuditContext.Update(x =>
|
||||
{
|
||||
x.AddTargetSysAccountWhenRequestNormal(data.ShopId, OpAuditLogEventTarget.Shop);
|
||||
x.Msg = "上架";
|
||||
});
|
||||
|
||||
|
||||
await headLevelChildCheckDomainService.InChildShopCheck(data.BusinessId, CurrentUser.ShopHeadId);
|
||||
data.Status = GoodsStatus.ENABLE;
|
||||
await _serveRepository.UpdateIncludeNowAsync(data, new[] { nameof(data.Status) });
|
||||
}
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopServePermissionDefinitionProvider.DisableName)]
|
||||
[OpAudit("下架", "门店服务", OpAuditLogEventTarget.Head)]
|
||||
[UnitOfWork(true)]
|
||||
public async Task Disable(MchSetStatusInput input, [FromServices] PcHeadLevelChildCheckDomainService headLevelChildCheckDomainService)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
|
||||
|
||||
|
||||
var data = await _serveRepository.Where(x => x.Id == input.Id).FirstOrDefaultAsync();
|
||||
if (data.IsEmpty())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PD0000);
|
||||
}
|
||||
|
||||
opAuditContext.Update(x =>
|
||||
{
|
||||
x.AddTargetSysAccountWhenRequestNormal(data.ShopId, OpAuditLogEventTarget.Shop);
|
||||
x.Msg = "下架";
|
||||
});
|
||||
|
||||
|
||||
await headLevelChildCheckDomainService.InChildShopCheck(data.BusinessId, CurrentUser.ShopHeadId);
|
||||
data.Status = GoodsStatus.DISABLE;
|
||||
await _serveRepository.UpdateIncludeNowAsync(data, new[] { nameof(data.Status) });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 信息提交
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopServePermissionDefinitionProvider.EditName)]
|
||||
[OpAudit("编辑", "门店服务", OpAuditLogEventTarget.Head)]
|
||||
[UnitOfWork(true)]
|
||||
public async Task SubmitAsync(MchSubmitServeInput input, [FromServices] PcHeadLevelChildCheckDomainService headLevelChildCheckDomainService)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
var data = await _serveRepository.Where(x => x.Id == input.Id).FirstOrDefaultAsync();
|
||||
if (data.IsEmpty())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PD0000);
|
||||
}
|
||||
|
||||
opAuditContext.Update(x => x.AddTargetSysAccountWhenRequestNormal(data.ShopId, OpAuditLogEventTarget.Shop));
|
||||
|
||||
|
||||
await headLevelChildCheckDomainService.InChildShopCheck(data.BusinessId, CurrentUser.ShopHeadId);
|
||||
|
||||
//检测名称是否重复
|
||||
if (await _serveRepository
|
||||
.Where(x => x.ShopId == data.ShopId && x.Name == input.Name)
|
||||
.Where(input.Id > 0, x => x.Id != input.Id)
|
||||
.AnyAsync())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PW1023);
|
||||
}
|
||||
|
||||
data = input.Adapt(data);
|
||||
|
||||
|
||||
await _serveRepository.UpdateNowAsync(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 服务记录
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("resultlist")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfShopServePermissionDefinitionProvider.ViewRecordName)]
|
||||
public async Task<BusinessServeResultListOutput> ResultListAsync(BusinessServeResultListInput input)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
/* var list = await _resultRepository.DetachedEntities
|
||||
.Where(CurrentUser.AccountType == AdminType.None, x => x.BusinessId == CurrentUser.ShopHeadId)
|
||||
.Where(!input.Name.IsEmpty(), x => _regUserRepository.DetachedEntities.Where(e => e.Id == x.RegUserId).Where(e => EF.Functions.Like(e.Name, $"%{input.Name}%") || EF.Functions.Like(e.Phone, $"%{input.Name}%")).Any())
|
||||
.Where(input.Status != 0, x => x.Status == input.Status)
|
||||
.OrderByDescending(x => x.CreatedTime)
|
||||
.ProjectToType<BusinessServeResultListOutput>()
|
||||
.ToADPagedListAsync(input.PageNo, input.PageSize);*/
|
||||
var list = await Mapper.From(await pcShopServiceResultQueryService.GetAllChildList(CurrentUser.ShopHeadId,
|
||||
input.ChildParentHeadId, input.ShopId, input.Name, input.Phone, input.Status, input.CreateTimeRange, input.RegUserId,
|
||||
input)).AdaptToTypeAsync<BusinessServeResultListOutput>();
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
#region 总部配置-服务配置
|
||||
|
||||
/// <summary>
|
||||
/// 获取服务列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("BusinessServiceList")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfDefaultServePermissionDefinitionProvider.ViewName)]
|
||||
|
||||
public async Task<PageResult<MchServeListS2CDto>> ServiceListAsync(MchServeListC2SDto input)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();//总部账号ID其实就是对应sysuser表的ID
|
||||
var list = await _BusinessShopService.DetachedEntities
|
||||
.Where(x => x.BusinessId == CurrentUser.ShopHeadId)
|
||||
.Where(!input.Name.IsEmpty(), x => EF.Functions.Like(x.Name, $"%{input.Name}%"))
|
||||
.Where(input.Status.HasValue, x => x.Status == input.Status)
|
||||
.Where(input.IsWeight.HasValue, x => x.IsWeight == input.IsWeight)
|
||||
.OrderBy(x => x.SortCode)
|
||||
.ProjectToType<MchServeListS2CDto>()
|
||||
.ToADPagedListAsync(input.PageNo, input.PageSize);
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 信息提交
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("BusinessService-add")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfDefaultServePermissionDefinitionProvider.AddName)]
|
||||
[OpAudit("添加服务", "总部服务配置", OpAuditLogEventTarget.Head)]
|
||||
[UnitOfWork(true)]
|
||||
public async Task ZBServiceSubmitAddAsync(MchSubmitServeInput input, [FromServices] IFeatureChecker _featureChecker)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
if (await _BusinessShopService
|
||||
.DetachedEntities
|
||||
.Where(x => x.BusinessId == CurrentUser.ShopHeadId && x.Name == input.Name)
|
||||
.Where(input.Id > 0, x => x.Id != input.Id)
|
||||
.AnyAsync())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PW1023);
|
||||
}
|
||||
|
||||
{
|
||||
var maxLimitCount = await _featureChecker.GetAsync<int>(ShopHeadOfServeFeatureDefinitionProvider.LIMIT_MAX);
|
||||
if (await _BusinessShopService
|
||||
.DetachedEntities
|
||||
.Where(x => x.BusinessId == CurrentUser.ShopHeadId)
|
||||
.CountAsync() >= maxLimitCount)
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.LIMIT_MAX_COUNT10001, maxLimitCount);
|
||||
}
|
||||
}
|
||||
var data = input.Adapt<PC_BusinessShopService>();
|
||||
|
||||
/* if (!input.Id.IsEmpty())
|
||||
{
|
||||
await _BusinessShopService.UpdateIncludeNowAsync(data, new[] { nameof(data.Name), nameof(data.SortCode), nameof(data.Remark), nameof(data.ShowName), nameof(data.IsWeight) });
|
||||
}
|
||||
else*/
|
||||
{
|
||||
data.Status = GoodsStatus.ENABLE;
|
||||
//data.ShopId = CurrentUser.UserId;
|
||||
data.BusinessId = CurrentUser.ShopHeadId;
|
||||
data.Id = YitIdHelper.NextId();
|
||||
await _BusinessShopService.InsertNowAsync(data);
|
||||
}
|
||||
}
|
||||
[HttpPost("BusinessService-edit")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfDefaultServePermissionDefinitionProvider.EditName)]
|
||||
[OpAudit("编辑服务", "总部服务配置", OpAuditLogEventTarget.Head)]
|
||||
[UnitOfWork(true)]
|
||||
public async Task ZBServiceSubmitEditAsync(MchSubmitServeInput input)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
if (await _BusinessShopService
|
||||
.DetachedEntities
|
||||
.Where(x => x.BusinessId == CurrentUser.ShopHeadId && x.Name == input.Name)
|
||||
.Where(input.Id > 0, x => x.Id != input.Id)
|
||||
.AnyAsync())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PW1023);
|
||||
}
|
||||
|
||||
if (!input.Id.IsEmpty())
|
||||
{
|
||||
var _ = await _BusinessShopService.Where(x => x.Id == input.Id && x.BusinessId == CurrentUser.ShopHeadId).FirstOrDefaultAsync();
|
||||
if (_.IsEmpty())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PD0000);
|
||||
}
|
||||
var data = input.Adapt(_);
|
||||
|
||||
await _BusinessShopService.UpdateNowAsync(data);
|
||||
}
|
||||
/* else
|
||||
{
|
||||
data.Status = GoodsStatus.WAIT;
|
||||
data.ShopId = CurrentUser.UserId;
|
||||
data.BusinessId = CurrentUser.ShopHeadId;
|
||||
data.Id = YitIdHelper.NextId();
|
||||
await _BusinessShopService.InsertNowAsync(data);
|
||||
}*/
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 状态设置
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("BusinessZBFW-enable")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfDefaultServePermissionDefinitionProvider.EnableName)]
|
||||
[OpAudit("上架", "总部服务配置", OpAuditLogEventTarget.Head)]
|
||||
[UnitOfWork(true)]
|
||||
public async Task ZBFWEnable(MchSetStatusInput input)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
|
||||
var data = await _BusinessShopService.Where(x => x.Id == input.Id && x.BusinessId == CurrentUser.ShopHeadId).FirstOrDefaultAsync();
|
||||
if (data.IsEmpty())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PD0000);
|
||||
}
|
||||
opAuditContext.Update(x =>
|
||||
{
|
||||
x.Msg = "上架";
|
||||
});
|
||||
data.Status = GoodsStatus.ENABLE;
|
||||
await _BusinessShopService.UpdateIncludeNowAsync(data, new[] { nameof(data.Status) });
|
||||
}
|
||||
[HttpPost("BusinessZBFW-disable")]
|
||||
[ShopHeadSystemBusinessVersionAuthorize(ShopHeadOfDefaultServePermissionDefinitionProvider.DisableName)]
|
||||
[OpAudit("下架", "总部服务配置", OpAuditLogEventTarget.Head)]
|
||||
[UnitOfWork(true)]
|
||||
public async Task ZBFWSetStatusAsync(MchSetStatusInput input)
|
||||
{
|
||||
var CurrentUser = _userManager.GetCurrentShopHeadInfo();
|
||||
|
||||
var data = await _BusinessShopService.Where(x => x.Id == input.Id && x.BusinessId == CurrentUser.ShopHeadId).FirstOrDefaultAsync();
|
||||
if (data.IsEmpty())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PD0000);
|
||||
}
|
||||
opAuditContext.Update(x =>
|
||||
{
|
||||
x.Msg = "下架";
|
||||
});
|
||||
data.Status = GoodsStatus.DISABLE;
|
||||
await _BusinessShopService.UpdateIncludeNowAsync(data, new[] { nameof(data.Status) });
|
||||
}
|
||||
|
||||
#endregion 总部配置-服务配置
|
||||
}
|
||||
|
||||
public class ShopHeadOfShopServePermissionDefinitionProvider : PermissionDefinitionProvider
|
||||
{
|
||||
|
||||
|
||||
public const string GroupName = $"{ShopHeadPermissionDefinitionNames.Prefix}.shop.service";
|
||||
public const string ViewName = $"{GroupName}.view";
|
||||
public const string ViewRecordName = $"{GroupName}.record.view";
|
||||
|
||||
//public const string AddName = $"{GroupName}.add";
|
||||
//public const string DelName = $"{GroupName}.del";
|
||||
public const string EditName = $"{GroupName}.edit";
|
||||
public const string EnableName = $"{GroupName}.enable";
|
||||
public const string DisableName = $"{GroupName}.disable";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public override void Define(IPermissionDefinitionContext context)
|
||||
{
|
||||
{
|
||||
var groups = context.AddGroup($"{GroupName}", new FixedLocalizableString("门店服务管理"));
|
||||
|
||||
groups.AddPermission($"{ViewName}", new FixedLocalizableString("查看服务")).RequireFeatures(ShopHeadOfShopServeFeatureDefinitionProvider.Shop_MANAGE);
|
||||
groups.AddPermission($"{ViewRecordName}", new FixedLocalizableString("查看服务记录")).RequireFeatures(ShopHeadOfShopServeFeatureDefinitionProvider.Shop_MANAGE);
|
||||
//groups.AddPermission($"{AddName}", new FixedLocalizableString("添加")).RequireFeatures(ShopHeadOfShopServeFeatureDefinitionProvider.Shop_MANAGE);
|
||||
groups.AddPermission($"{EditName}", new FixedLocalizableString("编辑")).RequirePermissions(ViewName).RequireFeatures(ShopHeadOfShopServeFeatureDefinitionProvider.Shop_MANAGE);
|
||||
////groups.AddPermission($"{DelName}", new FixedLocalizableString("删除"));
|
||||
groups.AddPermission($"{EnableName}", new FixedLocalizableString("启用")).RequirePermissions(ViewName).RequireFeatures(ShopHeadOfShopServeFeatureDefinitionProvider.Shop_MANAGE);
|
||||
groups.AddPermission($"{DisableName}", new FixedLocalizableString("禁用")).RequirePermissions(ViewName).RequireFeatures(ShopHeadOfShopServeFeatureDefinitionProvider.Shop_MANAGE);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ShopHeadOfDefaultServePermissionDefinitionProvider : PermissionDefinitionProvider
|
||||
{
|
||||
|
||||
|
||||
public const string GroupName = $"{ShopHeadPermissionDefinitionNames.Prefix}.self.service";
|
||||
|
||||
|
||||
|
||||
public const string ViewName = $"{GroupName}.view";
|
||||
|
||||
public const string AddName = $"{GroupName}.add";
|
||||
//public const string DelName = $"{GroupName}.del";
|
||||
public const string EditName = $"{GroupName}.edit";
|
||||
public const string EnableName = $"{GroupName}.enable";
|
||||
public const string DisableName = $"{GroupName}.disable";
|
||||
|
||||
|
||||
public override void Define(IPermissionDefinitionContext context)
|
||||
{
|
||||
{
|
||||
var groups = context.AddGroup($"{GroupName}", new FixedLocalizableString("总部服务管理"));
|
||||
|
||||
|
||||
groups.AddPermission($"{ViewName}", new FixedLocalizableString("查看")).RequireFeatures(ShopHeadOfServeFeatureDefinitionProvider.Self_MANAGE);
|
||||
groups.AddPermission($"{AddName}", new FixedLocalizableString("添加")).RequirePermissions(ViewName).RequireFeatures(ShopHeadOfServeFeatureDefinitionProvider.Self_MANAGE);
|
||||
groups.AddPermission($"{EditName}", new FixedLocalizableString("编辑")).RequirePermissions(ViewName).RequireFeatures(ShopHeadOfServeFeatureDefinitionProvider.Self_MANAGE);
|
||||
//groups.AddPermission($"{DelName}", new FixedLocalizableString("删除"));
|
||||
groups.AddPermission($"{EnableName}", new FixedLocalizableString("上架")).RequirePermissions(ViewName).RequireFeatures(ShopHeadOfServeFeatureDefinitionProvider.Self_MANAGE);
|
||||
groups.AddPermission($"{DisableName}", new FixedLocalizableString("下架")).RequirePermissions(ViewName).RequireFeatures(ShopHeadOfServeFeatureDefinitionProvider.Self_MANAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
using static JT.Shop.Application.Service.ShopHead.Shop.HeadShopListQueryService;
|
||||
using static JT.Shop.Domain.IPcHeadShopQueryService;
|
||||
|
||||
namespace JT.Shop.Application.Service.Business.Shop.Dto
|
||||
{
|
||||
/// <summary>
|
||||
/// 映射
|
||||
/// </summary>
|
||||
public class CMapper : IRegister
|
||||
{
|
||||
/// <summary>
|
||||
/// 注册
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
public void Register(TypeAdapterConfig config)
|
||||
{
|
||||
// 门店添加
|
||||
config.ForType<ShopAddInput, PC_Shop>()
|
||||
.Map(dest => dest.Status, src => CommonStatus.Enable)
|
||||
;
|
||||
// 门店编辑
|
||||
config.ForType<ShopEditInput, PC_Shop>()
|
||||
.Map(dest => dest.Desc, src => src.Desc.ToStrNoEmpty())
|
||||
;
|
||||
// 门店列表
|
||||
config.ForType<PC_Shop, ShopPageListS2CDto>()
|
||||
.Map(dest => dest.AvatarUrl, src => src.Avatar.ImgFile())
|
||||
.Map(dest => dest.Url, src => src.Id.ShopUrl())
|
||||
;
|
||||
config.ForType<PC_Shop, AppBaseInfoOutput>()
|
||||
//.Map(dest => dest.AvatarUrl, src => src.Avatar.ImgFile())
|
||||
.Map(dest => dest.H5Url, src => src.Id.ShopUrl())
|
||||
;
|
||||
config.ForType<PcHeadShopDto, HeadShopListOutputItem>()
|
||||
.Map(dest => dest.AvatarUrl, src => src.Avatar.ImgFile())
|
||||
.Map(dest => dest.Url, src => src.Id.ShopUrl())
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
|
||||
namespace JT.Shop.Application.Service.Business.Shop
|
||||
{
|
||||
/// <summary>
|
||||
/// 门店添加
|
||||
/// </summary>
|
||||
public class ShopAddInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 头像
|
||||
/// </summary>
|
||||
[MaxLength(500, ErrorMessage = "头像最多500个字")]
|
||||
public string Avatar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 门店名称
|
||||
/// </summary>
|
||||
[MaxLength(64, ErrorMessage = "门店名称最多64个字")]
|
||||
[Required(ErrorMessage = "门店名称不可为空")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 门店编号
|
||||
/// </summary>
|
||||
[MaxLength(32, ErrorMessage = "门店编号最多32个字")]
|
||||
[Required(ErrorMessage = "门店编号不可为空")]
|
||||
public string ShopCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 联系人
|
||||
/// </summary>
|
||||
[MaxLength(50, ErrorMessage = "联系人最多50个字")]
|
||||
[Required(ErrorMessage = "联系人不可为空")]
|
||||
public string Contact { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 联系电话
|
||||
/// </summary>
|
||||
[MaxLength(20, ErrorMessage = "联系电话最多20个字")]
|
||||
[Required(ErrorMessage = "联系电话不可为空")]
|
||||
public string Phone { get; set; }
|
||||
|
||||
/* /// <summary>
|
||||
/// 账户密码
|
||||
/// </summary>
|
||||
[MinLength(6, ErrorMessage = "账户密码最少6位")]
|
||||
[Required(ErrorMessage = "账户密码不可为空")]
|
||||
public virtual string Password { get; set; }*/
|
||||
|
||||
/// <summary>
|
||||
/// 省份
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "省份不可为空")]
|
||||
[MaxLength(100, ErrorMessage = "省份最多100个字")]
|
||||
public string Province { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 市
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "市不可为空")]
|
||||
[MaxLength(100, ErrorMessage = "市最多100个字")]
|
||||
public string City { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 区
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "区不可为空")]
|
||||
[MaxLength(100, ErrorMessage = "区最多100个字")]
|
||||
public string Area { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 详细地址
|
||||
/// </summary>
|
||||
[MaxLength(100, ErrorMessage = "详细地址最多100个字")]
|
||||
[Required(ErrorMessage = "详细地址不可为空")]
|
||||
public string Address { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 联系人性别
|
||||
/// </summary>
|
||||
public Gender? Gender { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 联系人出生年月
|
||||
/// </summary>
|
||||
public DateTime? BirthDay { get; set; }
|
||||
|
||||
/* /// <summary>
|
||||
/// 角色ID
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "角色信息不可为空")]
|
||||
public long RoleId { get; set; }
|
||||
*/
|
||||
/// <summary>
|
||||
/// 机构ID
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "机构信息不可为空")]
|
||||
public long OrgId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 说明
|
||||
/// </summary>
|
||||
[MaxLength(200, ErrorMessage = "说明最多200个字")]
|
||||
public string Desc { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 门店编辑
|
||||
/// </summary>
|
||||
public class ShopEditInput : ShopAddInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 门店ID
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "门店ID不可为空")]
|
||||
public long Id { get; set; }
|
||||
|
||||
/* /// <summary>
|
||||
/// 账户密码
|
||||
/// </summary>
|
||||
[ValidateNever]
|
||||
public override string Password { get; set; }*/
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 门店列表
|
||||
/// </summary>
|
||||
public class ShopPageListC2SDto : PageInputBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 门店名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 联系电话
|
||||
/// </summary>
|
||||
public string Phone { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 同步总部配置
|
||||
/// </summary>
|
||||
public class TBZBpeizhiInput : DEntityBaseId
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
namespace JT.Shop.Application.Service.Business.Shop
|
||||
{
|
||||
/// <summary>
|
||||
/// 门店列表
|
||||
/// </summary>
|
||||
public class ShopPageListS2CDto : BaseId
|
||||
{
|
||||
/// <summary>
|
||||
/// 头像
|
||||
/// </summary>
|
||||
public string Avatar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 头像
|
||||
/// </summary>
|
||||
public string AvatarUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 门店名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 门店编号
|
||||
/// </summary>
|
||||
public string ShopCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 联系人
|
||||
/// </summary>
|
||||
public string Contact { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 联系电话
|
||||
/// </summary>
|
||||
public string Phone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 省份
|
||||
/// </summary>
|
||||
public string Province { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 市
|
||||
/// </summary>
|
||||
public string City { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 区
|
||||
/// </summary>
|
||||
public string Area { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 详细地址
|
||||
/// </summary>
|
||||
public string Address { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所属客户ID
|
||||
/// </summary>
|
||||
public long BusinessId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 客户名称
|
||||
/// </summary>
|
||||
public string BusinessName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime? CreatedTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态
|
||||
/// </summary>
|
||||
public CommonStatus Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 性别
|
||||
/// </summary>
|
||||
public Gender Gender { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 出生年月
|
||||
/// </summary>
|
||||
public DateTime? BirthDay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 机构ID
|
||||
/// </summary>
|
||||
public long OrgId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 说明
|
||||
/// </summary>
|
||||
public string Desc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 门店地址
|
||||
/// </summary>
|
||||
public string Url { get; set; }
|
||||
public long DianZhangShopAccountId { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,554 @@
|
|||
using JT.Shop.Domain.Entity.Business;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using System.Linq.Dynamic.Core;
|
||||
|
||||
namespace JT.Shop.Application.Service.Business.Shop
|
||||
{
|
||||
/// <summary>
|
||||
/// 门店管理
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings("管理平台")]
|
||||
[Route("/api/business/[controller]")]
|
||||
|
||||
public class ShopService //暂时关闭: IDynamicApiController, ITransient
|
||||
{
|
||||
private readonly IRepository<PC_Shop> _shopRepository;
|
||||
private readonly IRepository<PC_ShopAccount> _shopUserRepository;
|
||||
private readonly IRepository<PC_ShopPos> _posRepository;
|
||||
private readonly UserManager _userManager;
|
||||
private readonly IRepository<PC_Role> _roleRepository;
|
||||
private readonly IRepository<PC_ShopAccountRole> _shopAccountRoleRepository;
|
||||
private readonly IRepository<PC_ShopRealData> _shopRealDataRepository;
|
||||
private readonly IMyRepository<SysUser> _sysUserRepository;
|
||||
private readonly IRepository<PC_ShopBody> _bodyRep;
|
||||
private readonly IRepository<PC_ShopBodyRel> _bodyRelRepository;
|
||||
private readonly IRepository<PC_BusinessShopService> _BusinessShopService;//总部服务
|
||||
private readonly IRepository<PC_BusinessShopProduct> _BusinessShopProduct;//总部产品
|
||||
private readonly IRepository<PC_BusinessBody> _businessBodyRepository;//总部位置
|
||||
|
||||
private readonly IRepository<PC_ShopService> _serveRepository;//门店的服务
|
||||
private readonly IRepository<PC_ShopProduct> _productRepository;//门店的产品
|
||||
|
||||
public ShopService(
|
||||
IRepository<PC_Shop> shopRepository,
|
||||
IRepository<PC_ShopAccount> shopUserRepository,
|
||||
UserManager userManager,
|
||||
IRepository<PC_ShopPos> posRepository,
|
||||
IRepository<PC_Role> roleRepository,
|
||||
IRepository<PC_ShopAccountRole> shopAccountRoleRepository,
|
||||
IRepository<PC_ShopRealData> shopRealDataRepository,
|
||||
IMyRepository<SysUser> sysUserRepository,
|
||||
IRepository<PC_ShopBody> bodyRep,
|
||||
IRepository<PC_BusinessShopService> BusinessShopService,
|
||||
IRepository<PC_BusinessShopProduct> BusinessShopProduct,
|
||||
IRepository<PC_BusinessBody> BusinessBody,
|
||||
IRepository<PC_ShopService> serveRepository,
|
||||
IRepository<PC_ShopProduct> productRepository,
|
||||
IRepository<PC_ShopBodyRel> bodyRelRepository)
|
||||
{
|
||||
_shopRepository = shopRepository;
|
||||
_shopUserRepository = shopUserRepository;
|
||||
_userManager = userManager;
|
||||
_posRepository = posRepository;
|
||||
_roleRepository = roleRepository;
|
||||
_shopAccountRoleRepository = shopAccountRoleRepository;
|
||||
_shopRealDataRepository = shopRealDataRepository;
|
||||
_sysUserRepository = sysUserRepository;
|
||||
_bodyRep = bodyRep;
|
||||
_BusinessShopService = BusinessShopService;
|
||||
_BusinessShopProduct = BusinessShopProduct;
|
||||
_businessBodyRepository = BusinessBody;
|
||||
_serveRepository = serveRepository;
|
||||
_productRepository = productRepository;
|
||||
_bodyRelRepository = bodyRelRepository;
|
||||
}
|
||||
//TODO 添加门店
|
||||
/* /// <summary>
|
||||
/// 门店添加
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task AddAsync(ShopAddInput input)
|
||||
{
|
||||
var UserInfo = _userManager.GetCurrentAdminShopInfo();
|
||||
if (await _shopRepository.DetachedEntities.AnyAsync(x => x.ShopCode == input.ShopCode && x.BusinessId == UserInfo.ShopHeadId))
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PW1012);
|
||||
}
|
||||
var shop = input.Adapt<PC_Shop>();
|
||||
shop.Id = YitIdHelper.NextId();
|
||||
shop.BusinessId = UserInfo.UserId;
|
||||
//添加门店
|
||||
await _shopRepository.InsertNowAsync(shop);
|
||||
//添加门店数据信息
|
||||
var realdata = new PC_ShopRealData
|
||||
{
|
||||
Id = shop.Id,
|
||||
ShopId = shop.Id,
|
||||
BusinessId = UserInfo.UserId,
|
||||
CreatedTime = DateTime.Now,
|
||||
TotalUserCnt = 0
|
||||
};
|
||||
await _shopRealDataRepository.InsertNowAsync(realdata);
|
||||
var password = MD5Encryption.Encrypt(input.Password, true);
|
||||
//初始化职位
|
||||
var postlist = new List<PC_ShopPos>
|
||||
{
|
||||
new PC_ShopPos
|
||||
{
|
||||
Id = YitIdHelper.NextId(),
|
||||
Name = "店长",
|
||||
Status = CommonStatus.Enable,
|
||||
Sort = 1,
|
||||
BusinessId = UserInfo.UserId,
|
||||
Code = "0001",
|
||||
Remark = "店长",
|
||||
CreatedTime = DateTime.Now,
|
||||
CreatedUserId = UserInfo.UserId,
|
||||
CreatedUserName = UserInfo.Name,
|
||||
ShopId = shop.Id
|
||||
},
|
||||
new PC_ShopPos
|
||||
{
|
||||
Id = YitIdHelper.NextId(),
|
||||
Name = "店员",
|
||||
Status = CommonStatus.Enable,
|
||||
Sort = 2,
|
||||
BusinessId = UserInfo.UserId,
|
||||
Code = "0002",
|
||||
Remark = "店员",
|
||||
CreatedTime = DateTime.Now,
|
||||
CreatedUserId = UserInfo.UserId,
|
||||
CreatedUserName = UserInfo.Name,
|
||||
ShopId = shop.Id
|
||||
}
|
||||
};
|
||||
await _posRepository.InsertAsync(postlist);
|
||||
//添加管理员账户
|
||||
var shopUser = new PC_ShopAccount
|
||||
{
|
||||
ShopId = shop.Id,
|
||||
Account = input.Phone,
|
||||
Avatar = input.Avatar,
|
||||
BirthDay = input.BirthDay,
|
||||
Gender = input.Gender,
|
||||
BusinessId = UserInfo.UserId,
|
||||
Id = shop.Id,
|
||||
Name = input.Contact,
|
||||
Phone = input.Phone,
|
||||
Password = password,
|
||||
Status = CommonStatus.Enable,
|
||||
Code = "0001",
|
||||
LastLoginAddress = string.Empty,
|
||||
LastLoginIp = string.Empty,
|
||||
PosId = postlist.FirstOrDefault(x => x.Code == "0001").Id,
|
||||
};
|
||||
await _shopUserRepository.InsertNowAsync(shopUser);
|
||||
//添加管理员角色
|
||||
var shoprole = new PC_ShopAccountRole
|
||||
{
|
||||
Id = YitIdHelper.NextId(),
|
||||
RoleId = input.RoleId,
|
||||
UserId = shopUser.Id
|
||||
};
|
||||
await _shopAccountRoleRepository.InsertNowAsync(shoprole);
|
||||
////添加门店产品
|
||||
//var shopProduct = new PC_ShopProduct
|
||||
//{
|
||||
// Id = YitIdHelper.NextId(),
|
||||
// ShopId = shop.Id,
|
||||
// BusinessId = UserInfo.UserId,
|
||||
// CreatedTime = DateTime.Now,
|
||||
// CreatedUserId = UserInfo.UserId,
|
||||
// CreatedUserName = UserInfo.Name,
|
||||
// SortCode = 1,
|
||||
// Status = GoodsStatus.ENABLE,
|
||||
// Name = "紧肤膏",
|
||||
// Remark = "紧肤膏"
|
||||
//};
|
||||
//await _shopAccountRoleRepository.Change<PC_ShopProduct>().InsertNowAsync(shopProduct);
|
||||
////添加门店服务
|
||||
//var servicelist = new List<PC_ShopService>()
|
||||
//{
|
||||
// new PC_ShopService
|
||||
// {
|
||||
// Id = YitIdHelper.NextId(),
|
||||
// ShopId = shop.Id,
|
||||
// BusinessId = UserInfo.UserId,
|
||||
// CreatedTime = DateTime.Now,
|
||||
// CreatedUserId = UserInfo.UserId,
|
||||
// CreatedUserName = UserInfo.Name,
|
||||
// SortCode = 1,
|
||||
// Status = GoodsStatus.ENABLE,
|
||||
// Name = "减重",
|
||||
// Remark = "减重美体师",
|
||||
// ShowName = "减重美体师",
|
||||
// IsWeight=true,
|
||||
// Code="0001"
|
||||
// },
|
||||
// new PC_ShopService
|
||||
// {
|
||||
// Id = YitIdHelper.NextId(),
|
||||
// ShopId = shop.Id,
|
||||
// BusinessId = UserInfo.UserId,
|
||||
// CreatedTime = DateTime.Now,
|
||||
// CreatedUserId = UserInfo.UserId,
|
||||
// CreatedUserName = UserInfo.Name,
|
||||
// SortCode = 2,
|
||||
// Status = GoodsStatus.ENABLE,
|
||||
// Name = "腹部",
|
||||
// Remark = "腹部美体师",
|
||||
// ShowName = "腹部美体师",
|
||||
// IsWeight=true,
|
||||
// Code="0002"
|
||||
// },
|
||||
// new PC_ShopService
|
||||
// {
|
||||
// Id = YitIdHelper.NextId(),
|
||||
// ShopId = shop.Id,
|
||||
// BusinessId = UserInfo.UserId,
|
||||
// CreatedTime = DateTime.Now,
|
||||
// CreatedUserId = UserInfo.UserId,
|
||||
// CreatedUserName = UserInfo.Name,
|
||||
// SortCode = 3,
|
||||
// Status = GoodsStatus.ENABLE,
|
||||
// Name = "手臂",
|
||||
// Remark = "手臂美体师",
|
||||
// ShowName = "手臂美体师",
|
||||
// IsWeight=true,
|
||||
// Code="0003"
|
||||
// },
|
||||
// new PC_ShopService
|
||||
// {
|
||||
// Id = YitIdHelper.NextId(),
|
||||
// ShopId = shop.Id,
|
||||
// BusinessId = UserInfo.UserId,
|
||||
// CreatedTime = DateTime.Now,
|
||||
// CreatedUserId = UserInfo.UserId,
|
||||
// CreatedUserName = UserInfo.Name,
|
||||
// SortCode = 4,
|
||||
// Status = GoodsStatus.ENABLE,
|
||||
// Name = "前大腿",
|
||||
// Remark = "前大腿美体师",
|
||||
// ShowName = "前大腿美体师",
|
||||
// IsWeight=true,
|
||||
// Code="0004"
|
||||
// },
|
||||
// new PC_ShopService
|
||||
// {
|
||||
// Id = YitIdHelper.NextId(),
|
||||
// ShopId = shop.Id,
|
||||
// BusinessId = UserInfo.UserId,
|
||||
// CreatedTime = DateTime.Now,
|
||||
// CreatedUserId = UserInfo.UserId,
|
||||
// CreatedUserName = UserInfo.Name,
|
||||
// SortCode = 5,
|
||||
// Status = GoodsStatus.ENABLE,
|
||||
// Name = "后大腿",
|
||||
// Remark = "后大腿美体师",
|
||||
// ShowName = "后大腿美体师",
|
||||
// IsWeight=true,
|
||||
// Code="0005"
|
||||
// },
|
||||
// new PC_ShopService
|
||||
// {
|
||||
// Id = YitIdHelper.NextId(),
|
||||
// ShopId = shop.Id,
|
||||
// BusinessId = UserInfo.UserId,
|
||||
// CreatedTime = DateTime.Now,
|
||||
// CreatedUserId = UserInfo.UserId,
|
||||
// CreatedUserName = UserInfo.Name,
|
||||
// SortCode = 6,
|
||||
// Status = GoodsStatus.ENABLE,
|
||||
// Name = "小腿",
|
||||
// Remark = "小腿美体师",
|
||||
// ShowName = "小腿美体师",
|
||||
// IsWeight=true,
|
||||
// Code="0006"
|
||||
// },
|
||||
//};
|
||||
//await _shopAccountRoleRepository.InsertAsync(servicelist);
|
||||
////获取所有身体部位
|
||||
//var bodylist = await _bodyRep.DetachedEntities.Where(x => x.Status == CommonStatus.Enable).ToListAsync();
|
||||
////添加门店身体部位
|
||||
//var shopBodyRelList = new List<PC_ShopBodyRel>();
|
||||
//bodylist.ForEach(x =>
|
||||
//{
|
||||
// shopBodyRelList.Add(new PC_ShopBodyRel
|
||||
// {
|
||||
// Id = YitIdHelper.NextId(),
|
||||
// ShopId = shop.Id,
|
||||
// BodyId = x.Id,
|
||||
// BusinessId = shop.BusinessId
|
||||
// });
|
||||
//});
|
||||
//await _bodyRelRepository.InsertAsync(shopBodyRelList);
|
||||
|
||||
//TODO:服务、身体部位、产品使用总部的配置
|
||||
}*/
|
||||
|
||||
/// <summary>
|
||||
/// 同步总部配置
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("BusinessZBPZ")]
|
||||
public async Task AddZbPZToShopAsync(TBZBpeizhiInput input)
|
||||
{
|
||||
var UserInfo = _userManager.GetCurrentUserInfo();
|
||||
if (!await _shopRepository.DetachedEntities.AnyAsync(x => x.Id == input.Id))
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PD0000);
|
||||
}
|
||||
//获取操作的门店
|
||||
var shop = await _shopRepository.DetachedEntities.Where(x => x.Id == input.Id).FirstOrDefaultAsync();
|
||||
|
||||
#region 添加门店服务
|
||||
|
||||
//获取总部配置的服务
|
||||
var zbservicelist = await _BusinessShopService.DetachedEntities
|
||||
.Where(x => x.BusinessId == UserInfo.UserId).ToListAsync();
|
||||
//获取总部下的门店服务
|
||||
var mchservicelist = await _serveRepository.DetachedEntities
|
||||
.Where(x => x.BusinessId == UserInfo.UserId)
|
||||
.Where(x => x.ShopId == shop.Id)
|
||||
.OrderByDescending(x => x.SortCode).FirstOrDefaultAsync();
|
||||
int sortcode = 0;
|
||||
if (mchservicelist != null)
|
||||
{
|
||||
sortcode = mchservicelist.SortCode;
|
||||
}
|
||||
List<PC_ShopService> servicelist = new List<PC_ShopService>();
|
||||
if (zbservicelist.Count > 0)
|
||||
{
|
||||
zbservicelist.ForEach(x =>
|
||||
{
|
||||
//只同步不存在的服务名字
|
||||
if (!_serveRepository.DetachedEntities.Where(x => x.BusinessId == UserInfo.UserId)
|
||||
.Where(x => x.ShopId == shop.Id).Any(m => m.Name == x.Name.Trim()))
|
||||
{
|
||||
servicelist.Add(new PC_ShopService
|
||||
{
|
||||
Id = YitIdHelper.NextId(),
|
||||
ShopId = shop.Id,
|
||||
BusinessId = UserInfo.UserId,
|
||||
CreatedTime = DateTime.Now,
|
||||
CreatedUserId = UserInfo.UserId,
|
||||
CreatedUserName = UserInfo.Name,
|
||||
SortCode = sortcode + 1,//最大序号累加
|
||||
Status = x.Status,
|
||||
Name = x.Name,
|
||||
Remark = x.Remark,
|
||||
ShowName = x.ShowName,
|
||||
IsWeight = x.IsWeight,
|
||||
Code = x.Code,
|
||||
ComputeTimes = x.ComputeTimes
|
||||
});
|
||||
sortcode++;
|
||||
}
|
||||
});
|
||||
}
|
||||
//批量添加
|
||||
await _serveRepository.InsertAsync(servicelist);
|
||||
|
||||
#endregion 添加门店服务
|
||||
|
||||
#region 添加门店产品
|
||||
|
||||
//获取总部配置的产品配置
|
||||
var zbshopproductlist = await _BusinessShopProduct.DetachedEntities.Where(x => x.BusinessId == UserInfo.UserId).ToListAsync();
|
||||
|
||||
//获取总部下的门店产品配置
|
||||
var mchprductlist = await _productRepository.DetachedEntities.Where(x => x.BusinessId == UserInfo.UserId)
|
||||
.Where(x => x.ShopId == shop.Id).OrderByDescending(x => x.SortCode).FirstOrDefaultAsync();
|
||||
sortcode = 0;
|
||||
if (mchprductlist != null)
|
||||
{
|
||||
sortcode = mchprductlist.SortCode;
|
||||
}
|
||||
List<PC_ShopProduct> addShopProductlist = new List<PC_ShopProduct>();
|
||||
if (zbshopproductlist.Count > 0)
|
||||
{
|
||||
zbshopproductlist.ForEach(x =>
|
||||
{
|
||||
//只同步不存在的产品名字
|
||||
if (!_productRepository.DetachedEntities.Where(x => x.BusinessId == UserInfo.UserId)
|
||||
.Where(x => x.ShopId == shop.Id).Any(m => m.Name == x.Name.Trim()))
|
||||
{
|
||||
addShopProductlist.Add(new PC_ShopProduct
|
||||
{
|
||||
Id = YitIdHelper.NextId(),
|
||||
ShopId = shop.Id,
|
||||
BusinessId = UserInfo.UserId,
|
||||
CreatedTime = DateTime.Now,
|
||||
CreatedUserId = UserInfo.UserId,
|
||||
CreatedUserName = UserInfo.Name,
|
||||
SortCode = sortcode + 1,//最大序号累加
|
||||
Status = GoodsStatus.ENABLE,
|
||||
Name = x.Name,
|
||||
Remark = x.Remark,
|
||||
});
|
||||
sortcode++;
|
||||
}
|
||||
});
|
||||
}
|
||||
await _productRepository.InsertAsync(addShopProductlist);
|
||||
|
||||
#endregion 添加门店产品
|
||||
|
||||
#region 添加身体部位
|
||||
|
||||
//获取总部的部位配置
|
||||
var zbbody = await _businessBodyRepository.DetachedEntities.Where(x => x.BusinessId == UserInfo.UserId).ToListAsync();
|
||||
|
||||
//获取总部下的门店自己的部位配置
|
||||
var mchbody = await _bodyRelRepository.DetachedEntities.Where(x => x.BusinessId == UserInfo.UserId)
|
||||
.Where(x => x.ShopId == shop.Id).ToListAsync();
|
||||
var shopBodyRelList = new List<PC_ShopBodyRel>();
|
||||
if (zbbody.Count > 0)
|
||||
{
|
||||
zbbody.ForEach(x =>
|
||||
{
|
||||
if (!mchbody.Any(n => n.BodyId == x.BodyId))
|
||||
{
|
||||
shopBodyRelList.Add(new PC_ShopBodyRel
|
||||
{
|
||||
Id = YitIdHelper.NextId(),
|
||||
ShopId = shop.Id,
|
||||
BodyId = x.BodyId,
|
||||
BusinessId = shop.BusinessId
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
await _bodyRelRepository.InsertAsync(shopBodyRelList);
|
||||
|
||||
#endregion 添加身体部位
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 门店编辑
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[AppAuthorize("shop:edit")]
|
||||
public async Task EditAsync(ShopEditInput input)
|
||||
{
|
||||
var UserInfo = _userManager.GetCurrentAdminShopInfo();
|
||||
/* //判断手机号是否已存在
|
||||
if (await _shopUserRepository.DetachedEntities.AnyAsync(x => x.Account == input.Phone && x.ShopId == input.Id && x.Id != input.Id))
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PW1004);
|
||||
}*/
|
||||
|
||||
|
||||
if (await _shopRepository.DetachedEntities.AnyAsync(x => x.ShopCode == input.ShopCode && x.BusinessId == UserInfo.ShopHeadId && x.Id != input.Id))
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PW1012);
|
||||
}
|
||||
|
||||
var shop = await _shopRepository.DetachedEntities.Where(x => x.Id == input.Id && x.BusinessId == UserInfo.ShopHeadId).FirstAsync();
|
||||
|
||||
//更新门店基础信息
|
||||
shop = input.Adapt<ShopEditInput, PC_Shop>(shop);
|
||||
|
||||
/* //更新门店管理员信息
|
||||
var shopuser = await _shopUserRepository.FirstOrDefaultAsync(x => x.Phone == input.Phone && x.ShopId == UserInfo.ShopId);
|
||||
if (shopuser != null)
|
||||
{
|
||||
shopuser.Edit(input.Avatar, input.Contact, shopuser.Code, input.Gender, input.BirthDay);
|
||||
//shopuser.Name = input.Contact;
|
||||
//shopuser.Account = input.Phone;
|
||||
//shopuser.Avatar = input.Avatar;
|
||||
//shopuser.Phone = input.Phone;
|
||||
//shopuser.Gender = input.Gender;
|
||||
//shopuser.BirthDay = input.BirthDay;
|
||||
await _shopUserRepository.UpdateIncludeNowAsync(shopuser, new[] { nameof(shopuser.Name), nameof(shopuser.Avatar), nameof(shopuser.Gender), nameof(shopuser.BirthDay) });
|
||||
}
|
||||
else
|
||||
{
|
||||
shopuser = new PC_ShopAccount(id: YitIdHelper.NextId(), adminType: AdminType.Admin, accountId: 0, avatar: input.Avatar, name: input.Name, phone: input.Phone, code: string.Empty, gender: input.Gender, birthDay: input.BirthDay, posId: 0, shopId: UserInfo.ShopId, shopHeadId: UserInfo.ShopHeadId);
|
||||
*//* shopuser.Id = YitIdHelper.NextId();
|
||||
shopuser.Name = input.Contact;
|
||||
//shopuser.Account = input.Phone;
|
||||
shopuser.Avatar = input.Avatar;
|
||||
shopuser.Phone = input.Phone;
|
||||
shopuser.Gender = input.Gender;
|
||||
shopuser.BirthDay = input.BirthDay;
|
||||
shopuser.Status = CommonStatus.Enable;*//*
|
||||
await _shopUserRepository.InsertAsync(shopuser);
|
||||
shop.DianZhangShopAccountId = shopuser.Id;
|
||||
|
||||
//更新门店管理员角色
|
||||
//先删除原有角色
|
||||
await _shopAccountRoleRepository.Where(x => x.ShopId == UserInfo.ShopId && x.RoleId == shop.DianZhangRoleId).DeleteAsync();
|
||||
//添加新角色
|
||||
var shopRole = new PC_ShopAccountRole
|
||||
{
|
||||
RoleId = shop.DianZhangRoleId,
|
||||
UserId = shopuser.AccountId,
|
||||
ShopId = shopuser.ShopId
|
||||
};
|
||||
await _shopAccountRoleRepository.InsertNowAsync(shopRole);
|
||||
}*/
|
||||
|
||||
await _shopRepository.UpdateIncludeNowAsync(shop, new[] { nameof(PC_Shop.ShopCode), nameof(PC_Shop.Name), nameof(PC_Shop.Contact), nameof(PC_Shop.Phone), nameof(PC_Shop.Province), nameof(PC_Shop.City), nameof(PC_Shop.Area), nameof(PC_Shop.Address), nameof(shop.Desc), nameof(PC_Shop.OrgId) });
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 门店列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PageResult<ShopPageListS2CDto>> PageAsync(ShopPageListC2SDto input)
|
||||
{
|
||||
var UserInfo = _userManager.GetCurrentUserInfo();
|
||||
if (UserInfo.UserId == 0)
|
||||
{
|
||||
throw Oops.Bah("请登录总部账号查看门店管理!");
|
||||
}
|
||||
var list = await _shopRepository.DetachedEntities
|
||||
.Where(UserInfo.AccountType == AdminType.None, x => x.BusinessId == UserInfo.UserId)
|
||||
.Where(!input.Name.IsEmpty(), x => EF.Functions.Like(x.Name, $"%{input.Name}%"))
|
||||
.Where(!input.Phone.IsEmpty(), x => EF.Functions.Like(x.Phone, $"%{input.Phone}%"))
|
||||
.OrderBy(x => x.SortCode)
|
||||
.ThenByDescending(x => x.CreatedTime)
|
||||
.ProjectToType<ShopPageListS2CDto>()
|
||||
.ToADPagedListAsync(input.PageNo, input.PageSize);
|
||||
//获取门店管理员信息
|
||||
var shopids = list.Rows.Select(x => x.Id).ToList();
|
||||
var accountIds = list.Rows.Select(x => x.DianZhangShopAccountId).ToList();
|
||||
var shopuserlist = await _shopUserRepository.DetachedEntities.Where(x => accountIds.Contains(x.Id))
|
||||
.ToListAsync();
|
||||
//var shopuserrolelist = await _shopAccountRoleRepository.DetachedEntities.Where(x => shopids.Contains(x.UserId))
|
||||
//.ToListAsync();
|
||||
var bids = list.Rows.Select(x => x.BusinessId).ToList();
|
||||
var allbuss = await _sysUserRepository.GetAllNoFilterAsync(x => bids.Contains(x.Id), x => new SysUser
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name
|
||||
});
|
||||
list.Rows.ToList().ForEach(it =>
|
||||
{
|
||||
var shopuser = shopuserlist.FirstOrDefault(x => x.Id == it.Id);
|
||||
if (shopuser != null)
|
||||
{
|
||||
it.BirthDay = shopuser.BirthDay;
|
||||
it.Gender = shopuser.Gender;
|
||||
}
|
||||
//var shopuserrole = shopuserrolelist.FirstOrDefault(x => x.UserId == it.Id);
|
||||
/* if (shopuserrole != null)
|
||||
{
|
||||
it.RoleId = shopuserrole.RoleId;
|
||||
}*/
|
||||
var user = allbuss.FirstOrDefault(x => x.Id == it.BusinessId);
|
||||
if (user != null)
|
||||
{
|
||||
it.BusinessName = user.Name;
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
// ------------------------------------------------------------------------
|
||||
// 版权信息
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
using JT.Shop.Application.Service.ShopHead.Finance;
|
||||
using JT.Shop.Domain.Entity.Business;
|
||||
using JT.Shop.Domain.Entity.DianShu;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static JT.Shop.Application.Service.ShopHead.Finance.ShopHeadDianShuQueryService;
|
||||
using static JT.Shop.Domain.Entity.Business.ISystemBusinessVersionQueryService;
|
||||
using static JT.Shop.Domain.Entity.DianShu.IPcDianShuQueryService;
|
||||
|
||||
namespace JT.Shop.Application.Service.Business.Version
|
||||
{
|
||||
public class BusinessVersionListQueryService(ISystemBusinessVersionQueryService queryService, IPcDianShuQueryService dianShuQueryService, SystemBusinessVersionUpgradeComputeService computeService, SystemBusinessVersionTimeRangeComputeService timeRangeComputeService) : ITransient
|
||||
{
|
||||
public async Task<BusinessVersionListOutput> GetList(long dianshuId, BusinessVersionListQueryInput input, BusinessSystemApp app)
|
||||
{
|
||||
if (input.OrderType is SystemBusinessVersionConfigOrderType.Open)
|
||||
{
|
||||
return await GetList(dianshuId, await queryService.GetByList(app, input.AuthorizationMode, null, null, notConfigId: null, shopHeadId: input.ShopHeadId,
|
||||
input as IPageInput), x => x.DianShu, x => timeRangeComputeService.ComputeOrder(null, new SystemBusinessVersionDuration(x.UnitOfTime, x.Time), input.OrderType));
|
||||
|
||||
}
|
||||
|
||||
if (!(input.OrderId > 0)) throw Oops.Bah("消费订单参数必填");
|
||||
var order = await dianShuQueryService.GetConsume(input.OrderId.Value);
|
||||
if (order == null) throw Oops.Bah("消费订单记录不存在").WithData(new { input.OrderId });
|
||||
|
||||
|
||||
|
||||
if (input.OrderType is SystemBusinessVersionConfigOrderType.Renewal)
|
||||
{
|
||||
return await GetList(dianshuId, await queryService.GetByList(app, input.AuthorizationMode, null, null, notConfigId: null, shopHeadId: input.ShopHeadId,
|
||||
input as IPageInput), x => x.DianShu, x => timeRangeComputeService.ComputeOrder(order.SBV.ExpireTime, new SystemBusinessVersionDuration(x.UnitOfTime, x.Time), input.OrderType), order);
|
||||
}
|
||||
|
||||
|
||||
if (order.SBV.Mode == SystemAuthorizationMode.Probation)
|
||||
{//试用期升级里面生效
|
||||
return await GetList(dianshuId, await queryService.GetByList(app, input.AuthorizationMode, null, null, notConfigId: null, shopHeadId: input.ShopHeadId,
|
||||
input as IPageInput), x => x.DianShu, x => timeRangeComputeService.ComputeOrder(DateTime.Now, new SystemBusinessVersionDuration(x.UnitOfTime, x.Time), input.OrderType), order);
|
||||
}
|
||||
|
||||
return await GetList(dianshuId, await queryService.GetByList(app, input.AuthorizationMode, order.SBV.Time, order.SBV.UnitOfTime, notConfigId: order.SBV.ConfigId, shopHeadId: input.ShopHeadId,
|
||||
input as IPageInput), x => computeService.Compute(order.SBV.StartTime, order.SBV.ExpireTime, order.SBV.DianShu, x.DianShu), x => timeRangeComputeService.ComputeOrder(order.SBV.ExpireTime, new SystemBusinessVersionDuration(x.UnitOfTime, x.Time), input.OrderType), order);
|
||||
}
|
||||
|
||||
private async Task<BusinessVersionListOutput> GetList(long dianshuId, SystemBusinessVersionQueryListDto dto, Func<ShopHeadBusinessVersionListOutputItem, uint> ActualDianShu, Func<ShopHeadBusinessVersionListOutputItem, SystemBusinessVersionTimeRange> timeRangeFunc, ShopHeadDianShuConsumeDto order = null)
|
||||
{
|
||||
var output =
|
||||
dto.Adapt<BusinessVersionListOutput>();
|
||||
foreach (var item in output.Rows)
|
||||
{
|
||||
item.ActualDianShu = ActualDianShu(item);// input.OrderType == SystemBusinessVersionConfigOrderType.Upgrade ? computeService.Compute(order.SBV.StartTime, order.SBV.ExpireTime, order.DianShu,
|
||||
// item.DianShu) : item.DianShu;
|
||||
var timeRange = timeRangeFunc(item);// timeRangeComputeService.ComputeOrder(order.SBV.ExpireTime,
|
||||
// new SystemBusinessVersionDuration(item.UnitOfTime, item.Time), input.OrderType);
|
||||
item.ExpireTime = timeRange.ExpireTime;
|
||||
item.StartTime = timeRange.StartTime;
|
||||
|
||||
}
|
||||
|
||||
if (order != null) output.ConsumeOrder = order.Adapt<BusinessVersionConsumeOrderOutput>();
|
||||
output.CurrentDianShu = (await dianShuQueryService.GetById(dianshuId, null)).Adapt<ShopHeadDianShuOutput>();
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class BusinessVersionListQueryInput : PageInputV2Base
|
||||
{
|
||||
public SystemBusinessVersionConfigOrderType OrderType { get; set; }
|
||||
/// <summary>
|
||||
/// 授权模式
|
||||
/// </summary>
|
||||
|
||||
public SystemAuthorizationMode? AuthorizationMode { get; set; }
|
||||
public long? OrderId { get; set; }
|
||||
public long ShopHeadId { get; set; }
|
||||
}
|
||||
|
||||
public class BusinessVersionListOutput : PageResultV2<ShopHeadBusinessVersionListOutputItem>
|
||||
{
|
||||
public BusinessVersionConsumeOrderOutput ConsumeOrder { get; set; }
|
||||
public ShopHeadDianShuQueryService.ShopHeadDianShuOutput CurrentDianShu { get; set; }
|
||||
}
|
||||
public class BusinessVersionConsumeOrderOutput
|
||||
{
|
||||
public long Id { get; set; }
|
||||
|
||||
|
||||
public string No { get; set; }
|
||||
|
||||
public long DianShuId { get; set; }
|
||||
/// <summary>
|
||||
/// 订单消费点数
|
||||
/// </summary>
|
||||
public uint DianShu { get; set; }
|
||||
public PcDianShuConsumeType Type { get; set; }
|
||||
public SystemBusinessVersionConfig SBV { get; set; }
|
||||
}
|
||||
public class ShopHeadBusinessVersionListOutputItem
|
||||
{
|
||||
|
||||
public long Id { get; set; }
|
||||
|
||||
|
||||
public string Code { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
// public string Description { get; set; }
|
||||
/// <summary>
|
||||
/// 需要点数
|
||||
/// </summary>
|
||||
|
||||
public uint DianShu { get; set; }
|
||||
/// <summary>
|
||||
/// 真实点数
|
||||
/// </summary>
|
||||
public uint ActualDianShu { get; set; }
|
||||
/// <summary>
|
||||
/// 时间单位
|
||||
/// </summary>
|
||||
|
||||
public SystemBusinessVersionUnitOfTime UnitOfTime { get; set; }
|
||||
/// <summary>
|
||||
/// 时间数量
|
||||
/// </summary>
|
||||
|
||||
public uint Time { get; set; }
|
||||
public DateTime ExpireTime { get; set; }
|
||||
public DateTime StartTime { get; set; }
|
||||
/// <summary>
|
||||
/// 授权模式
|
||||
/// </summary>
|
||||
|
||||
public SystemAuthorizationMode AuthorizationMode { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
namespace JT.Shop.Application.Service.Business.WX
|
||||
{
|
||||
/// <summary>
|
||||
/// 小程序管理
|
||||
/// </summary>
|
||||
public interface IWXService
|
||||
{
|
||||
/// <summary>
|
||||
/// 信息提交
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
Task SubmitAsync(WXSubmitC2SDto input);
|
||||
|
||||
/// <summary>
|
||||
/// 小程序列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
Task<PageResult<WXListS2CDto>> ListAsync(WXListC2SDto input);
|
||||
|
||||
/// <summary>
|
||||
/// 小程序删除
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
Task DeleteAsync(WXDeleteC2SDto input);
|
||||
|
||||
/// <summary>
|
||||
/// 所有小程序列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<List<WXListS2CDto>> AllListAsync();
|
||||
|
||||
/// <summary>
|
||||
/// 获取域名列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
Task<MiniDomainListS2CDto> GetDomainAsync(BaseRequestId input);
|
||||
|
||||
/// <summary>
|
||||
/// 获取体验码
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
Task<string> GetQRCodeAsync(BaseRequestId input);
|
||||
|
||||
Task<(string AccessToken, string Result)> GetRequestToken(BaseRequestId input);
|
||||
|
||||
Task<ActionResult> OpenOAuthCallbackAsync(string id, string auth_code, int expires_in, string appId);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
namespace JT.Shop.Application.Service.Business.WX
|
||||
{
|
||||
/// <summary>
|
||||
/// 小程序管理
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings("管理平台")]
|
||||
[Route("/api/business/[controller]")]
|
||||
[AllowAnonymous]
|
||||
public class WXAppService : IDynamicApiController
|
||||
{
|
||||
private readonly IWXService _wxService;
|
||||
|
||||
public WXAppService(IWXService wxService)
|
||||
{
|
||||
_wxService = wxService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 小程序列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PageResult<WXListS2CDto>> ListAsync(WXListC2SDto input)
|
||||
{
|
||||
return await _wxService.ListAsync(input);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 所有小程序列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<List<WXListS2CDto>> AllListAsync()
|
||||
{
|
||||
return await _wxService.AllListAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 信息提交
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task SubmitAsync(WXSubmitC2SDto input)
|
||||
{
|
||||
await _wxService.SubmitAsync(input);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 小程序删除
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task DeleteAsync(WXDeleteC2SDto input)
|
||||
{
|
||||
await _wxService.DeleteAsync(input);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取域名列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<MiniDomainListS2CDto> GetDomainAsync(BaseRequestId input)
|
||||
{
|
||||
return await _wxService.GetDomainAsync(input);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取体验码
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<string> GetQRCodeAsync(BaseRequestId input)
|
||||
{
|
||||
return await _wxService.GetQRCodeAsync(input);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<ActionResult> OpenOAuthCallbackAsync(string id, string auth_code, int expires_in,
|
||||
string appId)
|
||||
{
|
||||
return await _wxService.OpenOAuthCallbackAsync(id, auth_code, expires_in, appId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,399 @@
|
|||
using JT.Shop.Application.Service.BaseCommon;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Senparc.CO2NET.Utilities;
|
||||
using Senparc.Weixin.Exceptions;
|
||||
using Senparc.Weixin.MP.Containers;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using Volo.Abp.Users;
|
||||
using Yitter.IdGenerator;
|
||||
|
||||
namespace JT.Shop.Application.Service.Business.WX
|
||||
{
|
||||
/// <summary>
|
||||
/// 小程序管理
|
||||
/// </summary>
|
||||
public class WXService : IWXService, ITransient
|
||||
{
|
||||
private readonly IHttpClientFactory _clientFactory;
|
||||
private readonly IRepository<PC_BusinessWX> _businessWXRepository;
|
||||
private readonly IMyRepository<SysUser> _sysuserRep;
|
||||
private readonly IMyRepository<SysLogEx> _sysLogEx;
|
||||
public WXService(
|
||||
IRepository<PC_BusinessWX> businessWXRepository,
|
||||
IMyRepository<SysUser> sysuserRep,
|
||||
IHttpClientFactory httpClientFactory,
|
||||
IMyRepository<SysLogEx> sysLogEx)
|
||||
{
|
||||
_businessWXRepository = businessWXRepository;
|
||||
_sysuserRep = sysuserRep;
|
||||
_clientFactory = httpClientFactory;
|
||||
_sysLogEx = sysLogEx;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 所有小程序列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<List<WXListS2CDto>> AllListAsync()
|
||||
{
|
||||
var list = await _businessWXRepository.DetachedEntities
|
||||
.OrderByDescending(x => x.CreatedTime)
|
||||
.ProjectToType<WXListS2CDto>()
|
||||
.ToListAsync();
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 小程序删除
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task DeleteAsync(WXDeleteC2SDto input)
|
||||
{
|
||||
var data = await _businessWXRepository.Where(x => x.Id == input.Id, true).Select(x => new PC_BusinessWX
|
||||
{
|
||||
Id = x.Id,
|
||||
AppId = x.AppId
|
||||
}).FirstOrDefaultAsync();
|
||||
if (data.IsEmpty())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PD0000);
|
||||
}
|
||||
await _businessWXRepository.FakeDeleteNowAsync(data);
|
||||
//删除公众号
|
||||
if (await AccessTokenContainer.CheckRegisteredAsync(data.AppId))
|
||||
{
|
||||
await AccessTokenContainer.RemoveFromCacheAsync(data.AppId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 小程序列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PageResult<WXListS2CDto>> ListAsync(WXListC2SDto input)
|
||||
{
|
||||
var list = await _businessWXRepository.DetachedEntities
|
||||
.Where(!input.Name.IsEmpty(), x => x.Name == input.Name.ToStr())
|
||||
.Where(!input.AppId.IsEmpty(), x => x.AppId == input.AppId.ToStr())
|
||||
.OrderByDescending(x => x.CreatedTime)
|
||||
.ProjectToType<WXListS2CDto>()
|
||||
.ToADPagedListAsync(input.PageNo, input.PageSize);
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 信息提交
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task SubmitAsync(WXSubmitC2SDto input)
|
||||
{
|
||||
//检查appid是否重复
|
||||
if (await _businessWXRepository.DetachedEntities.Where(x => x.AppId == input.AppId)
|
||||
.Where(!input.Id.IsEmpty(), x => x.Id != input.Id)
|
||||
.AnyAsync())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PD0001);
|
||||
}
|
||||
if (input.Id.IsEmpty())
|
||||
{
|
||||
var insertdata = input.Adapt<PC_BusinessWX>();
|
||||
insertdata.Id = YitIdHelper.NextId();
|
||||
await _businessWXRepository.InsertNowAsync(insertdata);
|
||||
await RegisterWxOpen(insertdata.AppId, insertdata.AppSecret);
|
||||
}
|
||||
else
|
||||
{
|
||||
var olddata = await _businessWXRepository.Where(x => x.Id == input.Id, true).Select(x => new PC_BusinessWX
|
||||
{
|
||||
Id = x.Id,
|
||||
AppId = x.AppId,
|
||||
AppSecret = x.AppSecret
|
||||
}).FirstOrDefaultAsync();
|
||||
if (olddata.IsEmpty())
|
||||
{
|
||||
throw Oops.Bah(PCErrorCode.PD0000);
|
||||
}
|
||||
var appid = olddata.AppSecret;
|
||||
var appsecret = olddata.AppSecret;
|
||||
var updatedata = input.Adapt<PC_BusinessWX>();
|
||||
await _businessWXRepository.UpdateIncludeNowAsync(updatedata, new[] { nameof(updatedata.Name), nameof(updatedata.AppId), nameof(updatedata.AppSecret), nameof(updatedata.Desc) });
|
||||
if (appid != updatedata.AppId || appsecret != updatedata.AppSecret)
|
||||
{
|
||||
await RegisterWxOpen(updatedata.AppId, updatedata.AppSecret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册公众号
|
||||
/// </summary>
|
||||
/// <param name="appid"></param>
|
||||
/// <param name="appsecret"></param>
|
||||
/// <returns></returns>
|
||||
private async Task RegisterWxOpen(string appid, string appsecret)
|
||||
{
|
||||
if (appid.IsEmpty() || appsecret.IsEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
//尝试重新注册公众号
|
||||
if (!await AccessTokenContainer.CheckRegisteredAsync(appid))
|
||||
{
|
||||
await AccessTokenContainer.TryGetAccessTokenAsync(appid, appsecret);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<(string AccessToken, string Result)> GetRequestToken(BaseRequestId input)
|
||||
{
|
||||
var office = await _businessWXRepository.Where(x => x.Id == input.Id, true).Select(x => new PC_BusinessWX
|
||||
{
|
||||
Id = x.Id,
|
||||
AppId = x.AppId,
|
||||
AppSecret = x.AppSecret
|
||||
}).FirstOrDefaultAsync();
|
||||
if (office == null)
|
||||
{
|
||||
throw Oops.Bah("小程序未找到");
|
||||
}
|
||||
var valueTuple = await GetRequestToken(office.AppId, office.AppSecret);
|
||||
if (valueTuple.AccessToken.IsEmpty())
|
||||
{
|
||||
throw Oops.Bah("获取token失败:" + valueTuple.Result);
|
||||
}
|
||||
return (valueTuple.AccessToken, valueTuple.Result);
|
||||
}
|
||||
|
||||
private async Task<(string AccessToken, string Result)> GetRequestToken(string appid, string appsecret)
|
||||
{
|
||||
var url = $"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appid}&secret={appsecret}";
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
||||
var client = _clientFactory.CreateClient();
|
||||
var response = await client.SendAsync(request);
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var result = await response.Content.ReadAsStringAsync();
|
||||
var tokenResult = result.ToObject<TokenResult>();
|
||||
if (tokenResult != null)
|
||||
{
|
||||
return (tokenResult.access_token, result);
|
||||
}
|
||||
}
|
||||
return (null, null);
|
||||
}
|
||||
|
||||
private async Task<string> HttpPost(string url, string requestJson)
|
||||
{
|
||||
var request = new HttpRequestMessage(HttpMethod.Post, url);
|
||||
if (!requestJson.IsNullOrEmpty())
|
||||
{
|
||||
request.Content = new StringContent(requestJson, Encoding.UTF8, "application/json");
|
||||
}
|
||||
var client = _clientFactory.CreateClient();
|
||||
var response = await client.SendAsync(request);
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var result = await response.Content.ReadAsStringAsync();
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private async Task<string> HttpGet(string url)
|
||||
{
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
||||
var client = _clientFactory.CreateClient();
|
||||
var response = await client.SendAsync(request);
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var result = await response.Content.ReadAsStringAsync();
|
||||
return result;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取域名列表
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<MiniDomainListS2CDto> GetDomainAsync(BaseRequestId input)
|
||||
{
|
||||
var office = await _businessWXRepository.Where(x => x.Id == input.Id, true).Select(x => new PC_BusinessWX
|
||||
{
|
||||
Id = x.Id,
|
||||
AppId = x.AppId,
|
||||
AppSecret = x.AppSecret
|
||||
}).FirstOrDefaultAsync();
|
||||
if (office == null)
|
||||
{
|
||||
throw Oops.Bah("小程序未找到");
|
||||
}
|
||||
var valueTuple = await GetRequestToken(office.AppId, office.AppSecret);
|
||||
if (valueTuple.AccessToken.IsEmpty())
|
||||
{
|
||||
throw Oops.Bah("获取token失败:" + valueTuple.Result);
|
||||
}
|
||||
var url = "https://api.weixin.qq.com/wxa/getwxadevinfo?access_token=" + valueTuple.AccessToken;
|
||||
var result = await HttpPost(url, null);
|
||||
if (!result.IsNullOrEmpty())
|
||||
{
|
||||
var miniDomain = JsonConvert.DeserializeObject<MiniDomainListS2CDto>(result);
|
||||
return miniDomain;
|
||||
}
|
||||
return new MiniDomainListS2CDto();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取体验码
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> GetQRCodeAsync(BaseRequestId input)
|
||||
{
|
||||
var office = await _businessWXRepository.Where(x => x.Id == input.Id, true).Select(x => new PC_BusinessWX
|
||||
{
|
||||
Id = x.Id,
|
||||
AppId = x.AppId,
|
||||
AppSecret = x.AppSecret
|
||||
}).FirstOrDefaultAsync();
|
||||
if (office == null)
|
||||
{
|
||||
throw Oops.Bah("小程序未找到");
|
||||
}
|
||||
var valueTuple = await GetRequestToken(office.AppId, office.AppSecret);
|
||||
if (valueTuple.AccessToken.IsEmpty())
|
||||
{
|
||||
throw Oops.Bah("获取token失败:" + valueTuple.Result);
|
||||
}
|
||||
var scene = JsonConvert.SerializeObject(new {
|
||||
scene = "1"
|
||||
});
|
||||
var url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + valueTuple.AccessToken;
|
||||
var result = await HttpPost(url, scene);
|
||||
if (!result.IsNullOrEmpty())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
IMemoryCache cache = new MemoryCache(new MemoryCacheOptions());
|
||||
|
||||
public void GetAuthorizerAccessToken()
|
||||
{
|
||||
|
||||
//1.先获取微信回调的component_verify_ticket
|
||||
//2.https://api.weixin.qq.com/cgi-bin/component/api_component_token 再用 第三方平台 appid、第三方平台 appsecret、微信后台推送的 ticket 去获取component_access_token
|
||||
//3.https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token=COMPONENT_ACCESS_TOKEN 再用component_access_token、第三方平台 appid去获取pre_auth_code 预授权码
|
||||
//4.再用预授权码、第三方平台方 appid 去https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid=xxxx&pre_auth_code = xxxxx & redirect_uri = xxxx & auth_type = xxx 获取正式授权码
|
||||
//5.https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token=COMPONENT_ACCESS_TOKEN使用 component_access_token、component_appid、正式授权码 去获取 authorizer_refresh_token、authorizer_access_token
|
||||
//6.使用authorizer_refresh_token 请求接口
|
||||
|
||||
//wxd1788d0fabf835f3
|
||||
//ticket@@@MQTPTAol0o-hB524vw-sIiV90bXGv-64ZjvxyU6hRAUSvCiD8CrGTPPzoLajxe4aDtJaKo32ON3Wv-yhqmpilw
|
||||
|
||||
|
||||
|
||||
|
||||
// 设置缓存项,并指定过期时间
|
||||
//cache.Set("key", "value", new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromMinutes(30)));
|
||||
// 获取缓存项
|
||||
//string result = cache.Get<string>("key");
|
||||
// 移除缓存项
|
||||
//cache.Remove("key");
|
||||
|
||||
|
||||
}
|
||||
|
||||
public async Task<ActionResult> OpenOAuthCallbackAsync(string id, string auth_code, int expires_in, string appId)
|
||||
{
|
||||
var param = $"授权回调,auth_code={auth_code},expires_in={expires_in},appid={appId},id={id}";
|
||||
var info = new SysLogEx();
|
||||
|
||||
info.Id = YitIdHelper.NextId();
|
||||
info.Account = "1";
|
||||
info.Name = param.Length > 128 ? "超出长度" : param;
|
||||
info.ExceptionTime = DateTime.Now;
|
||||
await _sysLogEx.InsertNowAsync(info);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发布已经通过审核的小程序
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> ReleaseAsync(BaseRequestId input)
|
||||
{
|
||||
var office = await _businessWXRepository.Where(x => x.Id == input.Id, true).Select(x => new PC_BusinessWX
|
||||
{
|
||||
Id = x.Id,
|
||||
AppId = x.AppId,
|
||||
AppSecret = x.AppSecret
|
||||
}).FirstOrDefaultAsync();
|
||||
if (office == null)
|
||||
{
|
||||
throw Oops.Bah("小程序未找到");
|
||||
}
|
||||
var valueTuple = await GetRequestToken(office.AppId, office.AppSecret);
|
||||
if (valueTuple.AccessToken.IsEmpty())
|
||||
{
|
||||
throw Oops.Bah("获取token失败:" + valueTuple.Result);
|
||||
}
|
||||
var scene = JsonConvert.SerializeObject(new {
|
||||
|
||||
});
|
||||
var url = "https://api.weixin.qq.com/wxa/release?access_token=" + valueTuple.AccessToken;
|
||||
var result = await HttpPost(url, scene);
|
||||
if (!result.IsNullOrEmpty())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询最新一次提交的审核状态
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> GetLatestAuditStatusAsync(BaseRequestId input)
|
||||
{
|
||||
var office = await _businessWXRepository.Where(x => x.Id == input.Id, true).Select(x => new PC_BusinessWX
|
||||
{
|
||||
Id = x.Id,
|
||||
AppId = x.AppId,
|
||||
AppSecret = x.AppSecret
|
||||
}).FirstOrDefaultAsync();
|
||||
if (office == null)
|
||||
{
|
||||
throw Oops.Bah("小程序未找到");
|
||||
}
|
||||
var valueTuple = await GetRequestToken(office.AppId, office.AppSecret);
|
||||
if (valueTuple.AccessToken.IsEmpty())
|
||||
{
|
||||
throw Oops.Bah("获取token失败:" + valueTuple.Result);
|
||||
}
|
||||
var url = "https://api.weixin.qq.com/wxa/get_latest_auditstatus?access_token=" + valueTuple.AccessToken;
|
||||
var result = await HttpGet(url);
|
||||
if (!result.IsNullOrEmpty())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class TokenResult
|
||||
{
|
||||
public string access_token { get; set; }
|
||||
public int expires_in { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,817 @@
|
|||
/****************************************************************
|
||||
* 作者:liuzl
|
||||
* 版权:PCXBC
|
||||
* 创建时间:2022/10/9 15:27:40
|
||||
* 描述说明:
|
||||
*
|
||||
* 修改标识:PC-2022
|
||||
* 修改描述:
|
||||
*
|
||||
*****************************************************************/
|
||||
|
||||
using Hinse.Util.Security;
|
||||
using IPTools.Core;
|
||||
using JT.Shop.Application.Upload;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.Formats.Png;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using System.ComponentModel;
|
||||
using System.Data.SqlTypes;
|
||||
using System.Text;
|
||||
using Volo.Abp.Threading;
|
||||
using ZXing;
|
||||
using ZXing.Common;
|
||||
using ZXing.QrCode;
|
||||
using static System.Text.RegularExpressions.Regex;
|
||||
|
||||
namespace JT.Shop.Application.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// 通用方法
|
||||
/// </summary>
|
||||
public static class CommonService
|
||||
{
|
||||
/// <summary>
|
||||
/// 图片文件地址
|
||||
/// </summary>
|
||||
public static string ImgUrl = App.Configuration["ApiUrlSetting:Img"];
|
||||
|
||||
/// <summary>
|
||||
/// 文件地址
|
||||
/// </summary>
|
||||
public static string FileUrl = App.Configuration["ApiUrlSetting:File"];
|
||||
|
||||
/// <summary>
|
||||
/// 接口地址
|
||||
/// </summary>
|
||||
public static string ApiUrl = App.Configuration["ApiUrlSetting:Api"];
|
||||
public static string UserWXBindH5 = App.Configuration["ApiUrlSetting:UserWXBindH5"];
|
||||
|
||||
/// <summary>
|
||||
/// 图片文件展示
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
public static string ImgFile(this string url)
|
||||
{
|
||||
return url.NetFile(ImgUrl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 图片文件展示,带版本号防止缓存
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
public static string ImgFileWithVersion(this string url)
|
||||
{
|
||||
if (url.IsEmpty())
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
return $"{url.NetFile(ImgUrl)}?v={DateTime.Now:yyyyMMddHHmmss}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 文件展示
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
public static string File(this string url)
|
||||
{
|
||||
return url.NetFile(FileUrl);
|
||||
}
|
||||
public static string DeviceEntryUrl(this WXClientType type, long devid)
|
||||
{
|
||||
return type == WXClientType.MinProgram
|
||||
? devid.DeviceWxMinProgramEntryUrl()
|
||||
: devid.DeviceWxGzH5EntryUrl();
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 根据设备id获取入口-微信公众号H5
|
||||
/// </summary>
|
||||
/// <param name="devid">设备ID</param>
|
||||
/// <returns></returns>
|
||||
public static string DeviceWxGzH5EntryUrl(this long devid)
|
||||
{
|
||||
var useridstr = Convert.ToBase64String(Encoding.UTF8.GetBytes(devid.ToString()));
|
||||
return $"{ApiUrl}/api/public/qr/r/{useridstr}";
|
||||
//return $"{ApiUrl}/qr/d?sn={devid}";
|
||||
}
|
||||
/// <summary>
|
||||
/// 根据设备id获取入口-微信小程序
|
||||
/// </summary>
|
||||
/// <param name="devid"></param>
|
||||
/// <returns></returns>
|
||||
public static string DeviceWxMinProgramEntryUrl(this long devid)
|
||||
{
|
||||
return $"{ApiUrl}/qr/d?sn={devid}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// H5-根据门店ID获取入口
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public static string ShopH5Url(this long id)
|
||||
{
|
||||
//return $"{ApiUrl}/api/public/shop/index/{id}";
|
||||
return $"{ApiUrl}/qr/s?id={id}";
|
||||
}
|
||||
public static string ShopUrl(this long id)
|
||||
{
|
||||
|
||||
var type = AsyncHelper.RunSync(async () => await App.GetRequiredService<PCShopSettingProvider>().GetWXClientType(id));
|
||||
if (type == WXClientType.Gz)
|
||||
{
|
||||
return $"{ApiUrl}/qr/s?id={id}";
|
||||
|
||||
}
|
||||
else if (type == WXClientType.MinProgram)
|
||||
{
|
||||
return id.ShopWXMinProgramUrl();
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
/// <summary>
|
||||
/// 微信小程序-门店手机端入口
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public static string ShopWXMinProgramUrl(this long id)
|
||||
{
|
||||
return $"{ApiUrl}/qr/s-e?id={id}";
|
||||
// return $"{ApiUrl}/qr/s?id={id}";
|
||||
}
|
||||
public static string MemberWXMinProgramBindUrl(this long shopid, string payload)
|
||||
{
|
||||
return $"{ApiUrl}/qr/wxb-m?shopid={shopid}&payload={payload}";
|
||||
}
|
||||
public static string MemberWXGzBindUrl(this long shopid, string payload)
|
||||
{
|
||||
return $"{UserWXBindH5}?id={shopid}&payload={payload}";
|
||||
}
|
||||
public static Task<string> ToQrCodeImageToBase64String(this string text, int width, int height, int margin = 1)
|
||||
{
|
||||
BarcodeWriterPixelData writer = new BarcodeWriterPixelData();
|
||||
writer.Format = BarcodeFormat.QR_CODE;
|
||||
QrCodeEncodingOptions codeEncodingOptions = new QrCodeEncodingOptions();
|
||||
codeEncodingOptions.DisableECI = true;
|
||||
codeEncodingOptions.CharacterSet = "UTF-8";
|
||||
codeEncodingOptions.Width = width;
|
||||
codeEncodingOptions.Height = height;
|
||||
codeEncodingOptions.Margin = margin;
|
||||
writer.Options = (EncodingOptions)codeEncodingOptions;
|
||||
return Task.FromResult(writer.WriteAsImageSharp<Rgba32>(text).ToBase64String(PngFormat.Instance));
|
||||
}
|
||||
/// <summary>
|
||||
/// 加载头像,如果为空则加载默认头像
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="sex">性别</param>
|
||||
/// <returns></returns>
|
||||
public static string HeadImg(this string url, Gender sex)
|
||||
{
|
||||
if (url.IsEmpty())
|
||||
{
|
||||
if (sex == Gender.MALE)
|
||||
{
|
||||
return $"{ImgUrl}/image/headimg_male.png";
|
||||
}
|
||||
//返回默认头像
|
||||
return $"{ImgUrl}/image/headimg.png";
|
||||
}
|
||||
return url.ImgFile();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 本地默认头像
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="sex"></param>
|
||||
/// <returns></returns>
|
||||
public static string LocalHeadImg(this string url, Gender sex)
|
||||
{
|
||||
if (url.IsEmpty())
|
||||
{
|
||||
if (sex == Gender.MALE)
|
||||
{
|
||||
return "/image/headimg_male.png";
|
||||
}
|
||||
//返回默认头像
|
||||
return "/image/headimg.png";
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取本地地址
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string LocalUrl(this string file)
|
||||
{
|
||||
if (file.IsEmpty())
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var _uploadOptions = App.GetRequiredService<UploadDomainService>();
|
||||
|
||||
return $"{_uploadOptions.GetUploadPhysicalRootPath()}{file}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取导出路径
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GetExportPath(string type)
|
||||
{
|
||||
return $"/download/result/{DateTime.Now:yyyyMMdd_HHmmss}_{type}.xlsx";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 时间格式化,带时分,如果同一年则不显示年,否则显示年份
|
||||
/// </summary>
|
||||
/// <param name="date"></param>
|
||||
/// <returns></returns>
|
||||
public static string ToYearDateTimeFromOffset(this DateTime date)
|
||||
{
|
||||
if (date == SqlDateTime.MinValue.Value)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
if (date.Year == DateTime.Now.Year)
|
||||
return date.ToString("MM/dd HH:mm");
|
||||
return date.ToString("yyyy/MM/dd HH:mm");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 时间格式化,带时分,如果同一年则不显示年,否则显示年份
|
||||
/// </summary>
|
||||
/// <param name="date"></param>
|
||||
/// <returns></returns>
|
||||
public static string ToYearDateTimeFromOffset(this DateTime? date)
|
||||
{
|
||||
if (date.IsEmpty())
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
return ToYearDateTimeFromOffset(date.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 出生日期转换
|
||||
/// </summary>
|
||||
/// <param name="birthday"></param>
|
||||
/// <returns></returns>
|
||||
public static string ToBirthday(this DateTime birthday)
|
||||
{
|
||||
if (birthday == DateTime.MinValue)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
if (birthday == SqlDateTime.MinValue)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
return birthday.ToString("yyyy-MM-dd");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取格式化时间
|
||||
/// </summary>
|
||||
/// <param name="time"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetFormatTime(this DateTime time)
|
||||
{
|
||||
return GetFormatTime(time, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取格式化时间
|
||||
/// </summary>
|
||||
/// <param name="time"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetFormatTime(this DateTime time, bool showThisYear = true)
|
||||
{
|
||||
return showThisYear ? time.ToString("yyyy/MM/dd") : time.ToString("MM/dd");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取格式化时间
|
||||
/// </summary>
|
||||
/// <param name="time"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetFormatTime(this DateTime? time)
|
||||
{
|
||||
return GetFormatTime(time, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取格式化时间
|
||||
/// </summary>
|
||||
/// <param name="time"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetFormatTime(this DateTime? time, bool showThisYear)
|
||||
{
|
||||
if (time.IsEmpty())
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
return showThisYear ? time!.Value.ToString("yyyy/MM/dd") : time!.Value.ToString("MM/dd");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取总天数
|
||||
/// </summary>
|
||||
/// <param name="endtime"></param>
|
||||
/// <param name="starttime"></param>
|
||||
/// <returns></returns>
|
||||
public static int GetDays(this DateTime endtime, DateTime starttime, bool plusOne = true)
|
||||
{
|
||||
return (endtime - starttime).Days + (plusOne ? 1 : 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 时间格式化 yyyy-MM-dd
|
||||
/// </summary>
|
||||
/// <param name="time"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetFormatTime1(this DateTime time)
|
||||
{
|
||||
return time.ToString("yyyy-MM-dd");
|
||||
}
|
||||
/// <summary>
|
||||
/// 时间格式化 yyyy-MM-dd
|
||||
/// </summary>
|
||||
/// <param name="time"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetFormatTime1(this DateTime? time)
|
||||
{
|
||||
return time?.ToString("yyyy-MM-dd") ?? string.Empty;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取时分时间
|
||||
/// </summary>
|
||||
/// <param name="time">时间</param>
|
||||
/// <returns></returns>
|
||||
public static string GetHourTime(this DateTime? time)
|
||||
{
|
||||
if (time.IsEmpty())
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
return time.Value.ToString("HH:mm");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算家庭成员的类型
|
||||
/// </summary>
|
||||
/// <param name="birthday">出生年月</param>
|
||||
/// <param name="nowtime">当前时间</param>
|
||||
/// <returns></returns>
|
||||
public static FamilyType GetFamilyType(this DateTime birthday, DateTime? nowtime)
|
||||
{
|
||||
if (birthday == DateTime.MinValue || birthday == SqlDateTime.MinValue)
|
||||
{
|
||||
return FamilyType.Baby;
|
||||
}
|
||||
nowtime = nowtime.IsEmpty() ? DateTime.Now : nowtime;
|
||||
//获取年龄
|
||||
var age = birthday.ToAge(nowtime);
|
||||
return age >= FamilyTypeLevel.Adult ? FamilyType.Adult : (age < FamilyTypeLevel.Child ? FamilyType.Baby : FamilyType.Children);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 转换成带几岁几个月的年龄
|
||||
/// </summary>
|
||||
/// <param name="birthday"></param>
|
||||
/// <returns></returns>
|
||||
public static string ToAgeStr(this DateTime birthday)
|
||||
{
|
||||
if (birthday == DateTime.MinValue || birthday == SqlDateTime.MinValue)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
return birthday.ToAAge();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为非空字符串
|
||||
/// </summary>
|
||||
/// <param name="str"></param>
|
||||
/// <returns></returns>
|
||||
public static string ToStrNoEmpty(this string str)
|
||||
{
|
||||
if (str.IsEmpty())
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
return str.Trim();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解析IP地址
|
||||
/// </summary>
|
||||
/// <param name="ip"></param>
|
||||
/// <returns></returns>
|
||||
public static (string ipLocation, double? longitude, double? latitude) GetIpAddress(string ip)
|
||||
{
|
||||
try
|
||||
{
|
||||
var ipInfo = IpTool.Search(ip);
|
||||
var addressList = new List<string>() { ipInfo.Country, ipInfo.Province, ipInfo.City, ipInfo.NetworkOperator };
|
||||
return (string.Join("|", addressList.Where(it => it != "0").ToList()), ipInfo.Longitude, ipInfo.Latitude); // 去掉0并用|连接
|
||||
}
|
||||
catch { }
|
||||
return ("未知", 0, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 千克转换为斤
|
||||
/// </summary>
|
||||
/// <param name="kgval">千克值</param>
|
||||
/// <returns></returns>
|
||||
public static decimal KG2Jin(this decimal kgval)
|
||||
{
|
||||
return kgval * 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 千克转换为斤,保留一位小数
|
||||
/// </summary>
|
||||
/// <param name="kgval"></param>
|
||||
/// <returns></returns>
|
||||
public static decimal KG2Jin1(this decimal kgval)
|
||||
{
|
||||
return kgval * 2.ToDecimal(1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为正数
|
||||
/// </summary>
|
||||
/// <param name="val"></param>
|
||||
/// <returns></returns>
|
||||
public static bool ZhengFu(this decimal val)
|
||||
{
|
||||
//正数返回1,负数返回-1,零返回0。
|
||||
bool ret;
|
||||
if (Math.Sign(val) == 1)
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else if (Math.Sign(val) == -1)
|
||||
{
|
||||
ret = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 名字打码
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public static string HideName(this string name)
|
||||
{
|
||||
//如果为空则返回空
|
||||
if (name.IsEmpty())
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
//如果长度等于2则最后一个字符显示*
|
||||
if (name.Length == 2)
|
||||
{
|
||||
return name.Substring(0, 1) + "*";
|
||||
}
|
||||
//如果长度大于2则第二个字符到倒数第二个字符显示*
|
||||
if (name.Length > 2)
|
||||
{
|
||||
return name.Substring(0, 1) + "*" + name.Substring(name.Length - 1, 1);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 名字中去除数字
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public static string RemoveNum(this string name)
|
||||
{
|
||||
if (name.IsEmpty())
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
return Replace(name, @"\d", "");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 千克转换为斤,小于0则返回0
|
||||
/// </summary>
|
||||
/// <param name="kgval">千克值</param>
|
||||
/// <returns></returns>
|
||||
public static decimal KG2JinNoZero(this decimal kgval)
|
||||
{
|
||||
if (kgval < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return kgval * 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 斤转换为千克
|
||||
/// </summary>
|
||||
/// <param name="jinval">斤值</param>
|
||||
/// <returns></returns>
|
||||
public static decimal Jin2KG(this decimal jinval)
|
||||
{
|
||||
return jinval / 2.0M;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 斤转换为千克
|
||||
/// </summary>
|
||||
/// <param name="jinval">斤值</param>
|
||||
/// <returns></returns>
|
||||
public static decimal Jin2KG(this int jinval)
|
||||
{
|
||||
return jinval / 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成塑形订单号,规则:年月日+6位随机数
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GetSXOrderNo()
|
||||
{
|
||||
return $"JT{DateTime.Now:yyyyMMdd}{new Random().Next(100000, 999999)}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算所需的周期,每5kg减一个周期,不足5kg按5kg计算,小于等于0则为1个周期
|
||||
/// </summary>
|
||||
/// <param name="shouldweight">应减重量,kg</param>
|
||||
/// <returns></returns>
|
||||
public static int CycleValue(this decimal shouldweight)
|
||||
{
|
||||
//if (shouldweight <= 0)
|
||||
//{
|
||||
// return 1;
|
||||
//}
|
||||
//var val = shouldweight / 5;
|
||||
//周期数=值+1
|
||||
//return val.ToInt() + 1;
|
||||
|
||||
//依据新的范围计算:
|
||||
//标准周期:根据标准体重,计算应减体重;应减体重20斤以内是2个周期,20.1~30斤 3个周期;30.1~40斤 4个周期;40.1~50斤 5个周期依次类推
|
||||
|
||||
decimal weight = shouldweight.KG2Jin();
|
||||
// 确定每个周期的重量起点
|
||||
decimal baseWeight = 20.0.ToDecimal();
|
||||
// 确定每个周期的增量重量
|
||||
decimal incrementWeight = 10.0.ToDecimal();
|
||||
// 初始化周期数为最低周期数
|
||||
int cycle = 3; // 最低周期数,对应20.1~30斤
|
||||
if (weight <= 20)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
// 计算体重所属的周期
|
||||
while (weight > (baseWeight + incrementWeight))
|
||||
{
|
||||
cycle++;
|
||||
baseWeight += incrementWeight; // 更新下一个周期的起始重量
|
||||
}
|
||||
|
||||
// 确保体重在当前周期范围内
|
||||
if (weight < baseWeight || weight <= baseWeight + incrementWeight)
|
||||
{
|
||||
// 体重在当前周期内,返回计算出的周期数
|
||||
return cycle;
|
||||
}
|
||||
else
|
||||
{
|
||||
//异常
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算周期时间
|
||||
/// </summary>
|
||||
/// <param name="cyclevalue">周期值</param>
|
||||
/// <param name="type">周期类型</param>
|
||||
/// <param name="StartTime">开始时间</param>
|
||||
/// <returns></returns>
|
||||
public static (DateTime, DateTime, DateTime?, DateTime?) GetWeightStartEnd(this int cyclevalue, ShopCycleEnum type, DateTime StartTime)
|
||||
{
|
||||
//如果是标准周期
|
||||
if (type == ShopCycleEnum.Stand)
|
||||
{
|
||||
//如果周期数为1,则为标准周期的一个周期,没有售后服务期
|
||||
if (cyclevalue == 1)
|
||||
{
|
||||
//减重期结束时间=开始时间+1月-1天
|
||||
var endtime = StartTime.AddMonths(1).AddDays(-1);
|
||||
return (StartTime, endtime, null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
//减重期结束时间=开始时间+周期数*月+1月-1天
|
||||
var endtime = StartTime.AddMonths(cyclevalue).AddMonths(1).AddDays(-1);
|
||||
//售后服务期开始时间=减重期结束时间+1天
|
||||
var shfwqstarttime = endtime.AddDays(1);
|
||||
//售后服务期结束时间=售后服务期开始时间+2年-1天
|
||||
var shfwqendtime = shfwqstarttime.AddYears(2).AddDays(-1);
|
||||
return (StartTime, endtime, shfwqstarttime, shfwqendtime);
|
||||
}
|
||||
}
|
||||
//单周期,固定30天
|
||||
else
|
||||
{
|
||||
//减重期结束时间=开始时间的本月-1天
|
||||
var endtime = StartTime.AddDays(30).AddDays(-1);
|
||||
return (StartTime, endtime, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算售后服务年限
|
||||
/// </summary>
|
||||
/// <param name="starttime">开始时间</param>
|
||||
/// <param name="endtime">结束时间</param>
|
||||
/// <returns></returns>
|
||||
public static int AfterYear(this DateTime? starttime, DateTime? endtime)
|
||||
{
|
||||
if (starttime.IsEmpty() || endtime.IsEmpty())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
var year = endtime.Value.Year - starttime.Value.Year;
|
||||
return Math.Abs(year);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算体重的完成率
|
||||
/// </summary>
|
||||
/// <param name="weight"></param>
|
||||
/// <param name="standweight"></param>
|
||||
/// <returns></returns>
|
||||
public static decimal WeightComper(this decimal weight, decimal standweight)
|
||||
{
|
||||
if (weight == 0 || standweight == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
var val = weight / standweight;
|
||||
return val >= 1 ? 100 : val * 100.ToDecimal(1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算时间是否为今天
|
||||
/// </summary>
|
||||
/// <param name="time"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsToday(this DateTime time)
|
||||
{
|
||||
var nowtime = DateTime.Now;
|
||||
return time.Date == nowtime.Date;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算时间是否为今天
|
||||
/// </summary>
|
||||
/// <param name="time"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsToday(this DateTime? time)
|
||||
{
|
||||
if (!time.HasValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return IsToday(time.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 系统默认Logo
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string DefaultLogo()
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 系统默认颜色
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string DefaultColor()
|
||||
{
|
||||
return "#ff677b";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 系统默认字体颜色
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string DefaultFontColor()
|
||||
{
|
||||
return "#ffffff";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 默认门店名称
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string DefaultShopName()
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取枚举成员的描述
|
||||
/// </summary>
|
||||
/// <param name="value">枚举成员的值</param>
|
||||
/// <returns>枚举成员的描述,如果没有描述则返回枚举成员的名称</returns>
|
||||
public static string GetDescription(Enum value)
|
||||
{
|
||||
var type = value.GetType();
|
||||
var memInfo = type.GetMember(value.ToString());
|
||||
if (memInfo.Length > 0)
|
||||
{
|
||||
var attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
|
||||
if (attrs.Length > 0)
|
||||
{
|
||||
return ((DescriptionAttribute)attrs[0]).Description;
|
||||
}
|
||||
}
|
||||
|
||||
//// 如果没有找到描述,返回枚举成员的名字
|
||||
//return value.ToString();
|
||||
return "";
|
||||
}
|
||||
|
||||
public static long GetLongId(this IDynamicApiController _, string id)
|
||||
{
|
||||
return GetLongId(id);
|
||||
}
|
||||
public static long GetLongId(this ControllerBase _, string id)
|
||||
{
|
||||
return GetLongId(id);
|
||||
}
|
||||
public static long GetLongId(string id)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(id)) return 0;
|
||||
if (IsMatch(id.Trim(), "^\\d+$"))
|
||||
{
|
||||
return id.ToLong();
|
||||
}
|
||||
return Base64Encryption.IsBase64(id) ? Encoding.UTF8.GetString(Convert.FromBase64String(id)).ToLong() : 0;
|
||||
}
|
||||
|
||||
public static string AddUrlParam(this string url, string keyValue)
|
||||
{
|
||||
return url.LastIndexOf('&') > url.LastIndexOf('?') ? $"{url}&{keyValue}" : $"{url}?{keyValue}";
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取公斤的体重值
|
||||
/// </summary>
|
||||
/// <param name="weight"></param>
|
||||
/// <param name="unit">体重单位</param>
|
||||
/// <returns></returns>
|
||||
public static decimal GetWeightKg(this WeightUnit unit, decimal weight)
|
||||
{
|
||||
if (unit == WeightUnit.LB)
|
||||
{
|
||||
return (weight * 0.4536m).ToDecimal(2);
|
||||
}
|
||||
if (unit == WeightUnit.JIN)
|
||||
{
|
||||
return (weight / 2.0m).ToDecimal(2);
|
||||
}
|
||||
if (unit == WeightUnit.ST)
|
||||
{
|
||||
return (weight * 6.35m).ToDecimal(2);
|
||||
}
|
||||
if (unit == WeightUnit.G)
|
||||
{
|
||||
return (weight / 1000.0m).ToDecimal(2);
|
||||
}
|
||||
return weight.ToDecimal(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,244 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Furion.Authorization;
|
||||
using JetBrains.Annotations;
|
||||
using JT.Shop.Domain.Entity.Business;
|
||||
using MapsterMapper;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Volo.Abp.Authorization.Permissions;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using Volo.Abp.Features;
|
||||
|
||||
namespace JT.Shop.Application.Service
|
||||
{
|
||||
|
||||
public interface IPermissionAppService
|
||||
{
|
||||
Task<GetPermissionListResultDto> GetAsync([NotNull] string providerName, [NotNull] string providerKey, [NotNull] string prefix);
|
||||
|
||||
Task UpdateAsync([NotNull] string providerName, [NotNull] string providerKey, UpdatePermissionsDto input);
|
||||
}
|
||||
|
||||
public class GetPermissionListResultDto
|
||||
{
|
||||
public string EntityDisplayName { get; set; }
|
||||
|
||||
public List<PermissionGroupDto> Groups { get; set; }
|
||||
}
|
||||
|
||||
public class PermissionGroupDto
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
public string DisplayNameKey { get; set; }
|
||||
|
||||
public string DisplayNameResource { get; set; }
|
||||
|
||||
public List<PermissionGrantInfoDto> Permissions { get; set; }
|
||||
}
|
||||
|
||||
public class UpdatePermissionsDto
|
||||
{
|
||||
public UpdatePermissionDto[] Permissions { get; set; } = [];
|
||||
}
|
||||
|
||||
public class UpdatePermissionDto
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public bool IsGranted { get; set; }
|
||||
}
|
||||
|
||||
public class PermissionGrantInfoDto
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
public string ParentName { get; set; }
|
||||
|
||||
public bool IsGranted { get; set; }
|
||||
|
||||
public List<string> AllowedProviders { get; set; }
|
||||
|
||||
public List<ProviderInfoDto> GrantedProviders { get; set; }
|
||||
}
|
||||
|
||||
public class ProviderInfoDto
|
||||
{
|
||||
public string ProviderName { get; set; }
|
||||
|
||||
public string ProviderKey { get; set; }
|
||||
}
|
||||
|
||||
public class SystemBusinessVersionAuthorizationRequirement : IAuthorizationRequirement
|
||||
{
|
||||
public SystemBusinessVersionAuthorizationRequirement(BusinessSystemApp app)
|
||||
{
|
||||
App = app;
|
||||
|
||||
}
|
||||
|
||||
public BusinessSystemApp App { get; }
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 到期不允许访问
|
||||
/// </summary>
|
||||
[SuppressSniffer, AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Method)]
|
||||
|
||||
public class SystemBusinessVersionAuthorizeAttribute : AuthorizeAttribute
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="policies">多个策略</param>
|
||||
public SystemBusinessVersionAuthorizeAttribute(BusinessSystemApp app, params string[] policies)
|
||||
{
|
||||
App = app;
|
||||
if (policies != null && policies.Length > 0)
|
||||
{
|
||||
Policies = policies;
|
||||
}
|
||||
else
|
||||
{
|
||||
Policy = SystemBusinessVersionPolicyProvider.FullPrefix(App);
|
||||
}
|
||||
}
|
||||
public BusinessSystemApp App { get; }
|
||||
/// <summary>
|
||||
/// 策略
|
||||
/// </summary>
|
||||
public string[] Policies
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Policy)) return Array.Empty<string>();
|
||||
|
||||
return Policy[SystemBusinessVersionPolicyProvider.FullPrefix(App).Length..].Split(',', StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
internal set => Policy = $"{SystemBusinessVersionPolicyProvider.FullPrefix(App)}{string.Join(',', value)}";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 总部到期不允许访问
|
||||
/// </summary>
|
||||
[SuppressSniffer, AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Method)]
|
||||
|
||||
public class ShopHeadSystemBusinessVersionAuthorizeAttribute : SystemBusinessVersionAuthorizeAttribute
|
||||
{
|
||||
public ShopHeadSystemBusinessVersionAuthorizeAttribute(params string[] policies) : base(BusinessSystemApp.ShopHead, policies)
|
||||
{
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 门店到期不允许访问
|
||||
/// </summary>
|
||||
[SuppressSniffer, AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Method)]
|
||||
|
||||
public class ShopSystemBusinessVersionAuthorizeAttribute : SystemBusinessVersionAuthorizeAttribute
|
||||
{
|
||||
public ShopSystemBusinessVersionAuthorizeAttribute(params string[] policies) : base(BusinessSystemApp.Shop, policies)
|
||||
{
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class SystemBusinessVersionPolicyProvider : DefaultAuthorizationPolicyProvider
|
||||
{
|
||||
public const string POLICY_PREFIX = "<SystemBusinessVersion>";
|
||||
|
||||
public SystemBusinessVersionPolicyProvider([NotNull][ItemNotNull] IOptions<AuthorizationOptions> options) : base(options)
|
||||
{
|
||||
}
|
||||
|
||||
public static string FullPrefix(BusinessSystemApp app) => $"{POLICY_PREFIX}<{(byte)app:000}>";
|
||||
|
||||
public static bool TryPrefixRead(string policyName, out BusinessSystemApp app, out string[] policies)
|
||||
{
|
||||
policies = null;
|
||||
app = default;
|
||||
if (!policyName.StartsWith(POLICY_PREFIX))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var start = $"{POLICY_PREFIX}<".Length;
|
||||
if (!byte.TryParse(policyName[start..(start + 3)], out var v))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Enum.IsDefined(typeof(BusinessSystemApp), v))
|
||||
{
|
||||
app = (BusinessSystemApp)v;
|
||||
policies = policyName[(start + 4)..].Split(',', StringSplitOptions.RemoveEmptyEntries);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override async Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
|
||||
{
|
||||
var policy = await base.GetPolicyAsync(policyName);
|
||||
if (policy != null)
|
||||
{
|
||||
return policy;
|
||||
}
|
||||
// 判断是否是包含授权策略前缀
|
||||
if (TryPrefixRead(policyName, out var app, out var policies))
|
||||
{
|
||||
// 添加策略需求
|
||||
var policyBuilder = new AuthorizationPolicyBuilder();
|
||||
policyBuilder.AddRequirements(new SystemBusinessVersionAuthorizationRequirement(app));
|
||||
policyBuilder.AddRequirements(new AppAuthorizeRequirement(policies));
|
||||
|
||||
return policyBuilder.Build();
|
||||
}
|
||||
|
||||
if (policyName.StartsWith(Penetrates.AppAuthorizePrefix))
|
||||
{
|
||||
// 解析策略名并获取策略参数
|
||||
policies = policyName[Penetrates.AppAuthorizePrefix.Length..].Split(',', StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
// 添加策略需求
|
||||
var policyBuilder = new AuthorizationPolicyBuilder();
|
||||
policyBuilder.AddRequirements(new AppAuthorizeRequirement(policies));
|
||||
|
||||
return policyBuilder.Build();
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 常量、公共方法配置类
|
||||
/// </summary>
|
||||
internal static class Penetrates
|
||||
{
|
||||
/// <summary>
|
||||
/// 授权策略前缀
|
||||
/// </summary>
|
||||
internal const string AppAuthorizePrefix = "<Furion.Authorization.AppAuthorizeRequirement>";
|
||||
}
|
||||
|
||||
public abstract class AppService : ITransientDependency
|
||||
{
|
||||
//public IAbpLazyServiceProvider LazyServiceProvider { get; set; } = default!;
|
||||
public IFeatureChecker FeatureChecker => App.GetRequiredService<IFeatureChecker>();
|
||||
public IPermissionChecker PermissionChecker => App.GetRequiredService<IPermissionChecker>();
|
||||
|
||||
public IMapper Mapper => App.GetRequiredService<IMapper>();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
// 品传科技
|
||||
// 开发:李鹏鹏
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
|
||||
namespace JT.Shop.Application.Service;
|
||||
|
||||
public class JTDataProtectionService(IDataProtectionProvider provider) : ITransientDependency
|
||||
{
|
||||
|
||||
public string Protect(string purpose, string content)
|
||||
{
|
||||
var _protector = provider.CreateProtector(purpose);
|
||||
|
||||
return _protector.Protect(content);
|
||||
}
|
||||
public string Unprotect(string purpose, string protectedPayload)
|
||||
{
|
||||
var _protector = provider.CreateProtector(purpose);
|
||||
|
||||
return _protector.Unprotect(protectedPayload);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,228 @@
|
|||
using JT.Shop.Application.Service.Shop;
|
||||
using JT.Shop.Application.Service.ShopHead.Colleague;
|
||||
using JT.Shop.Domain.Entity.Business;
|
||||
using JT.Shop.Domain.Entity.GeneralAccount;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using UAParser;
|
||||
|
||||
namespace JT.Shop.Application.Service.Mch.Account
|
||||
{
|
||||
/// <summary>
|
||||
/// 门店账号管理
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings("门店管理平台")]
|
||||
[Route("/api/mch/[controller]")]
|
||||
public class AccountService(
|
||||
IRepository<PC_ShopAccount> shopaccountRep,
|
||||
IRepository<PC_ShopAccountRole> shopaccountroleRep,
|
||||
IRepository<PcGeneralAccount> pcmanageAccountRep,
|
||||
IRepository<PC_Shop> shopRep,
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
UserManager userManager,
|
||||
IPcShopAccountRoleQueryService sysRoleService,
|
||||
GeneralAccountLoginVerifyDomainService manageAccountLoginVerifyDomainService,
|
||||
GeneralAccountAuthAppService authAppService,
|
||||
ISmsService smsService)
|
||||
: ITransient, IDynamicApiController
|
||||
{
|
||||
/// <summary>
|
||||
/// 账户登录
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
[OpAudit("登录", "账号", OpAuditLogEventTarget.Shop)]
|
||||
public async Task<string> LoginAsync(LoginInput input, [FromServices] PcShopAccountVerifyCheckOwnerShopDomainService loginVerifyDomainService)
|
||||
{
|
||||
var shopid = input.Id;
|
||||
var (accountId, tokenVersion) =
|
||||
await manageAccountLoginVerifyDomainService.LoginVerifyPassword(input.Account, input.Password);
|
||||
|
||||
var (_, user, shop,_) = await loginVerifyDomainService.VerifyShopAccount(accountId, shopid);
|
||||
|
||||
|
||||
return (await authAppService.Login(accountId, (await shopaccountroleRep.DetachedEntities.Where(x => x.UserId == user.Id && x.ShopId == user.ShopId).Select(x => x.RoleId).ToListAsync()), AccountIdentity.Shop, user.AdminType, name: user.Name, shopId: user.ShopId, shopHeadId: user.BusinessId, tokenVersion: tokenVersion, versionConfig: shop.SystemAuthorization?.ConfigId, userId: user.Id)).accessToken;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取登录信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<LoginOutput> GetLoginUserAsync([FromServices] IAccountIdentityRolePermissionAppService abpApplicationConfigurationAppService, [FromServices] ISystemBusinessVersionQueryService systemBusinessVersionQueryService, [FromServices] GeneralAccountWxLoginBindDomainService generalAccountWxLoginBindDomainService)
|
||||
{
|
||||
var CurrentUser = userManager.GetCurrentAdminShopInfo();
|
||||
var accountId = CurrentUser.AccountId;
|
||||
//var userId = CurrentUser.UserId;
|
||||
var data = await shopaccountRep.DetachedEntities.Where(x => x.AccountId == accountId && x.ShopId == CurrentUser.ShopId).FirstOrDefaultAsync();
|
||||
if (data.IsEmpty())
|
||||
throw Oops.Bah(ErrorCode.D1011);
|
||||
var account = await pcmanageAccountRep.DetachedEntities.FirstOrDefaultAsync(x => x.Id == accountId);
|
||||
var loginOutput = account.Adapt<LoginOutput>();
|
||||
var httpContext = httpContextAccessor.HttpContext;
|
||||
loginOutput.WxBind = await generalAccountWxLoginBindDomainService.IsBind(accountId);
|
||||
loginOutput.PwdNotYetSet = string.IsNullOrWhiteSpace(account.Password);
|
||||
loginOutput.LastLoginTime = account.LastLoginTime;
|
||||
loginOutput.LastLoginIp = account.LastLoginIp;
|
||||
var client = Parser.GetDefault().Parse(httpContext.Request.Headers["User-Agent"]);
|
||||
loginOutput.LastLoginBrowser = client.UA.Family + client.UA.Major;
|
||||
loginOutput.LastLoginOs = client.OS.Family + client.OS.Major;
|
||||
//角色门店角色信息
|
||||
loginOutput.Roles = (await sysRoleService.GetRolesByUserId(data.Id)).Select(x => new RoleOutput { Id = x.Id, Name = x.Name }).ToList();
|
||||
|
||||
loginOutput.AccountEnable = data.Status == CommonStatus.Disable;
|
||||
|
||||
loginOutput.ShopId = data.ShopId;
|
||||
loginOutput.Name = data.Name;
|
||||
loginOutput.Sex = (int)data.Gender;
|
||||
loginOutput.PwdNotYetSet = string.IsNullOrWhiteSpace(account.Password);
|
||||
loginOutput.AccountEnable = data.Status == CommonStatus.Disable;
|
||||
loginOutput.AdminType = (int)CurrentUser.AccountType;
|
||||
loginOutput.ShopHeadId = data.BusinessId;
|
||||
|
||||
var shop = await shopRep.DetachedEntities.FirstOrDefaultAsync(x => x.Id == data.ShopId);
|
||||
if (shop.IsEmpty()) throw Oops.Bah(PC_SHOP_ERROR_CODE.SHOP_NOTFOUND40004).WithData(data.ShopId);
|
||||
if (shop.Status == CommonStatus.Disable) throw Oops.Bah(HCErrorCode.SHOP0004).WithData(data.ShopId);
|
||||
if (shop.IsDeleted) throw Oops.Bah(HCErrorCode.SHOP0003).WithData(data.ShopId);
|
||||
loginOutput.App = shop.Adapt<AppBaseInfoOutput>();
|
||||
loginOutput.App.SystemAuthorization.BusinessVersion = (await systemBusinessVersionQueryService.GetDetail(shop.SystemAuthorization.ConfigId)).Adapt<BusinessVersionOutput>();
|
||||
|
||||
|
||||
var Auth = await abpApplicationConfigurationAppService.GetAuthConfigAsync(ShopPermissionDefinitionNames.Prefix);
|
||||
|
||||
// 权限信息
|
||||
loginOutput.Permissions = Auth.GrantedPolicies.Where(x => x.Value).Select(x => x.Key).ToList();
|
||||
loginOutput.Features = (await abpApplicationConfigurationAppService.GetFeaturesConfigAsync(ShopPermissionDefinitionNames.Prefix)).Values;
|
||||
|
||||
////获取权限信息
|
||||
//user.Permissions = await sysMenuService.GetPermissionList(accountId, AccountIdentity.Shop, data.AdminType == AdminType.SuperAdmin);
|
||||
////获取系统所有权限
|
||||
//user.AllPermissions = await sysMenuService.GetAllPermissionList(AccountIdentity.Shop);
|
||||
//// 具备应用信息(多系统,默认激活一个,可根据系统切换菜单),返回的结果中第一个为激活的系统
|
||||
//user.Apps = await sysAppService.GetShopLoginApps(accountId);
|
||||
////获取菜单信息
|
||||
//if (user.Apps.Any())
|
||||
//{
|
||||
// var activeApp = user.Apps.FirstOrDefault(u => u.Active == YesOrNot.Y.ToString());
|
||||
// var defaultActiveAppCode = activeApp != null ? activeApp.Code : user.Apps.FirstOrDefault().Code;
|
||||
// user.Menus = await sysMenuService.GetLoginMenusAntDesign(accountId, defaultActiveAppCode, CurrentUser.AccountIdentity, CurrentUser.IsSuperAdmin);
|
||||
//}
|
||||
return loginOutput;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 退出
|
||||
/// </summary>
|
||||
/// <param name="openid">用户openid</param>
|
||||
/// <returns></returns>
|
||||
[QueryParameters]
|
||||
[HttpGet]
|
||||
public void Logout(string openid = "")
|
||||
{
|
||||
var CurrentUser = userManager.GetCurrentAdminShopInfo();
|
||||
var ip = httpContextAccessor.HttpContext.GetRequestIPv4();
|
||||
httpContextAccessor.HttpContext.SignoutToSwagger();
|
||||
//_httpContextAccessor.HttpContext.Response.Headers["access-token"] = "invalid token";
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("shoplogininfo")]
|
||||
[AllowAnonymous]
|
||||
public async Task<ShopLoginInfoOutput> GetShopLoginInfo([FromQuery] long id)
|
||||
{
|
||||
var entity = await shopRep.DetachedEntities.Where(x => x.Id == id).FirstOrDefaultAsync();
|
||||
if (entity == null) throw Oops.Bah("门店标识不存在");
|
||||
return entity.Adapt<ShopLoginInfoOutput>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 邀请门店注册链接码
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("invite-shop-reg")]
|
||||
[AnyAccountIdentityAuthorize]
|
||||
public async Task<InviteRegShopOutput> GetInviteRegShop([FromServices] IdentityInfoVisitor identityInfoVisitor/*, [FromServices] IRepository<SystemBusinessVersion> repository*/)
|
||||
{
|
||||
var headid = identityInfoVisitor.ShopHeadId;
|
||||
/* var ver = await repository.DetachedEntities.Where(x =>
|
||||
x.Enable == true && x.AuthorizationMode == SystemAuthorizationMode.Probation &&
|
||||
x.SystemApp == BusinessSystemApp.Shop).FirstOrDefaultAsync();*/
|
||||
|
||||
var code = string.Format(App.Configuration["ApiUrlSetting:InviteShopReg"] ?? throw Oops.Bah("尚未配置门店注册邀请链接"), headid/*, ver?.Id*/);
|
||||
return new InviteRegShopOutput()
|
||||
{
|
||||
Code = code,
|
||||
Img = await code.ToQrCodeImageToBase64String(200, 200)
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
public class InviteRegShopOutput
|
||||
{
|
||||
public string Img { get; set; }
|
||||
public string Code { get; set; }
|
||||
}
|
||||
|
||||
public class ShopLoginInfoOutput
|
||||
{
|
||||
public long Id { get; set; }
|
||||
/// <summary>
|
||||
/// 头像
|
||||
/// </summary>
|
||||
public string Avatar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 门店名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 门店编号
|
||||
/// </summary>
|
||||
public string ShopCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 联系人
|
||||
/// </summary>
|
||||
public string Contact { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 联系电话
|
||||
/// </summary>
|
||||
public string Phone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 省份
|
||||
/// </summary>
|
||||
public string Province { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 市
|
||||
/// </summary>
|
||||
public string City { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 区
|
||||
/// </summary>
|
||||
public string Area { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 详细地址
|
||||
/// </summary>
|
||||
public string Address { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 总部/代理商
|
||||
/// </summary>
|
||||
public long BusinessId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 说明
|
||||
/// </summary>
|
||||
public string Desc { get; set; }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
using JT.Shop.Application.Service.Shop;
|
||||
using JT.Shop.Domain.FeatureDefinitions.Shop;
|
||||
using Volo.Abp.Authorization.Permissions;
|
||||
using Volo.Abp.Features;
|
||||
using Volo.Abp.Localization;
|
||||
|
||||
namespace JT.Shop.Application.Service.Mch.Body
|
||||
{
|
||||
/// <summary>
|
||||
/// 身体部位管理
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings("门店管理平台")]
|
||||
[Route("/api/mch/[controller]")]
|
||||
public class BodyService(
|
||||
IRepository<PC_ShopBodyRel> shopBodyRelRep,
|
||||
IRepository<PC_ShopBody> bodyRep,
|
||||
IRepository<PC_ShopBodyType> bodyTypeRep,
|
||||
UserManager userManager)
|
||||
: ITransient, IDynamicApiController
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取身体部位列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[ShopSystemBusinessVersionAuthorize(ShopOfBodyPermissionDefinitionProvider.ViewName)]
|
||||
public async Task<List<ShopBodyTypeListOutput>> ListAsync()
|
||||
{
|
||||
var CurrentUser = userManager.GetCurrentAdminShopInfo();
|
||||
//获取身体部位类型列表
|
||||
var typelist = await bodyTypeRep.DetachedEntities.Where(x => x.Status == CommonStatus.Enable).OrderBy(x => x.SortCode).ToListAsync();
|
||||
//获取身体部位列表
|
||||
var bodylist = await bodyRep.DetachedEntities.Where(x => x.Status == CommonStatus.Enable).ToListAsync();
|
||||
//获取门店关联的身体部位
|
||||
var shopBodyRelList = await shopBodyRelRep.DetachedEntities.Where(x => x.ShopId == CurrentUser.ShopId).ToListAsync();
|
||||
var returnlist = new List<ShopBodyTypeListOutput>();
|
||||
typelist.ForEach(x =>
|
||||
{
|
||||
var bodylistoutput = new ShopBodyTypeListOutput
|
||||
{
|
||||
TypeId = x.Id,
|
||||
TypeName = x.Name,
|
||||
List = new List<ShopBodyListOutput>()
|
||||
};
|
||||
var blist = bodylist.Where(y => y.TypeId == x.Id).ToList();
|
||||
blist.ForEach(y =>
|
||||
{
|
||||
var rel = shopBodyRelList.FirstOrDefault(z => z.BodyId == y.Id);
|
||||
var bodyoutput = new ShopBodyListOutput
|
||||
{
|
||||
Id = y.Id,
|
||||
Name = y.Name,
|
||||
TypeId = y.TypeId,
|
||||
IsChecked = !rel.IsEmpty()
|
||||
};
|
||||
bodylistoutput.List.Add(bodyoutput);
|
||||
});
|
||||
returnlist.Add(bodylistoutput);
|
||||
});
|
||||
return returnlist;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 身体部位信息绑定
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[OpAudit("编辑", "部位管理", OpAuditLogEventTarget.Shop)]
|
||||
[ShopSystemBusinessVersionAuthorize(ShopOfBodyPermissionDefinitionProvider.EditName)]
|
||||
[UnitOfWork(true)]
|
||||
public async Task SubmitAsync(ShopBodySubmitInput input)
|
||||
{
|
||||
var CurrentUser = userManager.GetCurrentAdminShopInfo();
|
||||
//先删除绑定的
|
||||
await shopBodyRelRep.Where(x => x.ShopId == CurrentUser.ShopId).DeleteAsync();
|
||||
if (input.ids.IsEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
//新增
|
||||
var insertlist = new List<PC_ShopBodyRel>();
|
||||
input.ids.ForEach(x =>
|
||||
{
|
||||
insertlist.Add(new PC_ShopBodyRel
|
||||
{
|
||||
Id = YitIdHelper.NextId(),
|
||||
ShopId = CurrentUser.ShopId,
|
||||
BodyId = x,
|
||||
BusinessId = CurrentUser.BusinessId
|
||||
});
|
||||
});
|
||||
await shopBodyRelRep.InsertAsync(insertlist);
|
||||
}
|
||||
}
|
||||
|
||||
public class ShopOfBodyPermissionDefinitionProvider : PermissionDefinitionProvider
|
||||
{
|
||||
|
||||
|
||||
public const string GroupName = $"{ShopPermissionDefinitionNames.Prefix}.bodymag";
|
||||
public const string ViewName = $"{GroupName}.view";
|
||||
|
||||
|
||||
|
||||
public const string EditName = $"{GroupName}.edit";
|
||||
|
||||
|
||||
|
||||
public override void Define(IPermissionDefinitionContext context)
|
||||
{
|
||||
{
|
||||
var groups = context.AddGroup($"{GroupName}", new FixedLocalizableString("部位配置"));
|
||||
|
||||
groups.AddPermission($"{ViewName}", new FixedLocalizableString("查看"));
|
||||
groups.AddPermission($"{EditName}", new FixedLocalizableString("修改"))
|
||||
.RequirePermissions(ViewName)
|
||||
.RequireFeatures(ShopOfBodyFeatureDefinitionProvider.EditName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue