75 Commits
dev ... b2c

Author SHA1 Message Date
chc
c69af3e751 获取用户信息时判断用户是否已禁用 2025-01-20 16:35:28 +08:00
chc
dfb98c107e B2C功能提交 2024-10-21 22:34:23 +08:00
chc
9d3ed4a4a7 b2c模式代码提交 2024-10-18 15:30:07 +08:00
Chopper711
e89be8eb8c !358 优化 web-二维码登录 优化睡眠时间使用指数退避策略来延长每次轮询的时间间隔,减少CPU占用率
Merge pull request !358 from 铉清/N/A
2024-09-25 01:59:23 +00:00
铉清
3559971a8d 优化 web-二维码登录 优化睡眠时间使用指数退避策略来延长每次轮询的时间间隔,减少CPU占用率
Signed-off-by: 铉清 <13698617+xuanqings@user.noreply.gitee.com>
2024-09-21 16:17:53 +00:00
Chopper711
dc1d1a7e7e Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop 2024-09-18 15:40:02 +08:00
Chopper711
10ecce1e0d fix:修复代码与注释不匹配问题 2024-09-18 15:39:56 +08:00
chc
2520c27f77 Merge remote-tracking branch 'origin/master' 2024-09-18 15:16:35 +08:00
chc
63d684c972 订单增加部分发货状态。
部分发货无法申请售后
2024-09-18 15:16:28 +08:00
Chopper711
35739b64a3 fix: 部分字段重复问题处理 2024-09-18 14:20:13 +08:00
Chopper711
ddcda57a08 Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop 2024-09-18 12:24:16 +08:00
Chopper711
16ae69ed06 fix: 脚本问题导致限流脚本无效,不确定是否是版本升级带来的问题。 2024-09-18 12:24:11 +08:00
Chopper711
fd067d8abf update DB/version4.3toMASTER.sql.
缺少标点符号导致无法一次性执行 sql

Signed-off-by: Chopper711 <1814994716@qq.com>
2024-09-18 02:09:02 +00:00
pikachu1995@126.com
42b3c72977 微信小程序发货信息录入参数错误,短信发送使用系统后台配置的短信CODE 2024-09-14 16:11:05 +08:00
OceansDeep
e34b4172b8 !356 fix & improve
Merge pull request !356 from OceansDeep/pg
2024-09-14 03:30:15 +00:00
misworga831
30d6ab64f8 fix & improvement 2024-09-14 11:29:39 +08:00
Chopper711
2e8c40bcf3 Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop 2024-09-14 11:17:44 +08:00
Chopper711
f2385c3ace fix: 订单物流费用展示问题处理 2024-09-14 11:17:37 +08:00
OceansDeep
a45355b125 !355 fix & improve
Merge pull request !355 from OceansDeep/pg
2024-09-13 17:44:17 +00:00
misworga831
b3bb771066 fix: 修复可能会出现在购物车内多促销活动多商品的清空下的促销金额分配问题 2024-09-14 01:39:19 +08:00
OceansDeep
068c6b986e !354 fix & improve
Merge pull request !354 from OceansDeep/pg
2024-09-13 09:29:15 +00:00
misworga831
18e2c89891 fix: 修复批量更新商品配送模版,没有更新sku问题 2024-09-13 17:27:39 +08:00
OceansDeep
7b485753a6 !353 fix & improve
Merge pull request !353 from OceansDeep/pg
2024-07-26 02:33:51 +00:00
misworga831
8556d27173 fix & improvement 2024-07-26 10:31:39 +08:00
chc
d677aabbf4 判断手机号是否存在,如果存在抛出异常 2024-07-24 10:37:41 +08:00
pikachu1995@126.com
aaa0748409 删除文件夹需判断,优化删除逻辑。是否文件夹下存在图片。 2024-07-18 14:28:59 +08:00
pikachu1995@126.com
57ee156798 Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop 2024-07-18 13:51:44 +08:00
pikachu1995@126.com
5ae4d8b4fa 微信小程序-上传发货信息 2024-07-18 13:51:37 +08:00
OceansDeep
681327274c !352 fix & improve
Merge pull request !352 from OceansDeep/pg
2024-07-18 03:46:26 +00:00
misworga831
6ab2888fd0 fix: 修复部分情况下秒杀活动商品无法添加问题 2024-07-18 11:45:18 +08:00
pikachu1995@126.com
80a0e0e8c7 增加导出订单数据判断,升级poi版本
传递删除则使用字段内容
2024-07-07 15:55:11 +08:00
pikachu1995@126.com
80773e2d58 优化支付、短信的配置内容 2024-07-07 14:48:11 +08:00
pikachu1995@126.com
065bcc8a55 优化支付、短信的配置内容 2024-07-07 14:03:31 +08:00
pikachu1995@126.com
9398413999 添加qq群 2024-07-02 15:07:51 +08:00
pikachu1995@126.com
cf623f6756 优化店铺结算单、店铺流水生成规则。
优化分销申请逻辑,分销佣金不转入预存款
2024-07-02 14:55:19 +08:00
pikachu1995@126.com
1b316baac6 将微信支付的调用appid进行优化。 2024-06-28 09:08:32 +08:00
pikachu1995@126.com
4fc1d0e346 升级poi 版本 2024-06-27 17:13:33 +08:00
pikachu1995@126.com
159fe37120 支持店铺通过excel批量更新商品库存功能 2024-06-27 17:09:25 +08:00
pikachu1995@126.com
6f9486f065 优化订单导出功能。 2024-06-26 11:50:45 +08:00
Chopper711
94da71336a Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop 2024-06-18 09:55:21 +08:00
Chopper711
8c5ce396b2 fix: 2024-03-25被错误的修改一个问题,导致分销订单无法结算,当前 commit 修复问题并优化问题,解决可能出现的事务问题,采用一条 sql 执行 2024-06-18 09:55:15 +08:00
OceansDeep
0063820fdf !351 fix & improve
Merge pull request !351 from OceansDeep/pg
2024-06-17 10:41:51 +00:00
misworga831
fe80edebbd fix: 修复 精确发券 类型的优惠券活动重复领取问题 2024-06-17 18:41:02 +08:00
OceansDeep
6b59c1e643 !350 fix & improve
Merge pull request !350 from OceansDeep/pg
2024-06-17 09:10:44 +00:00
misworga831
1b52381c71 fix: 修复可能出现的手机号登录重复问题 2024-06-17 17:09:33 +08:00
OceansDeep
763519876e !349 fix & improve
Merge pull request !349 from OceansDeep/pg
2024-06-17 07:14:46 +00:00
misworga831
cede181bc0 fix: 生成索引时,店铺商品分类优惠券判断条件补全 2024-06-17 15:13:07 +08:00
Chopper711
cb776eb4c0 merge 2024-06-17 08:31:49 +08:00
Chopper711
8ed4f6eb3c fix: 极端情况下,结算单可能存在未能被同级的订单流水 2024-06-17 08:31:28 +08:00
OceansDeep
9cf97f3203 !348 fix & improve
Merge pull request !348 from OceansDeep/pg
2024-06-14 03:31:36 +00:00
misworga831
2a984b8c56 fix: 优化店铺优惠券商品分类生成 2024-06-14 11:27:54 +08:00
OceansDeep
22ecf48168 !347 fix & improve
Merge pull request !347 from OceansDeep/pg
2024-06-14 01:55:33 +00:00
misworga831
89422b2736 fix: 自动领取优惠券判定同时,将精准发券功能同时判定 2024-06-14 09:54:26 +08:00
Chopper711
bcd4bf4ff1 fix: 用户领取优惠券时,无法领取精准赠送的优惠券 2024-06-12 18:07:53 +08:00
OceansDeep
a263bc6301 !346 fix & improve
Merge pull request !346 from OceansDeep/pg
2024-06-04 06:44:23 +00:00
misworga831
27ae773e20 fix & improvement 2024-06-04 14:43:37 +08:00
Chopper711
085b61c2ab fix: 单个文件夹删除报错问题处理,pom.xml 配置编译运行环境指定,开发测试环境 jdk22 导致无法编译 1.8版本 jdk 问题。 2024-05-27 14:45:42 +08:00
Chopper711
c7682680ee fix:文件目录为空时无法删除文件报错 2024-05-27 10:12:50 +08:00
lele0521
a301432a87 fix: 修复判断订单是否可以售后接口异常 2024-05-27 08:53:43 +08:00
OceansDeep
526de18a42 !343 上传图片时,选择的目录为空时,生成的图片访问不了
Merge pull request !343 from imalasong/pr/1
2024-05-24 03:15:48 +00:00
OceansDeep
c940bf6cb2 !342 多了一个结束符号进行移除
Merge pull request !342 from 铉清/N/A
2024-05-24 03:15:02 +00:00
OceansDeep
a7643a6b93 !345 fix & improve
Merge pull request !345 from OceansDeep/pg
2024-05-23 07:40:45 +00:00
misworga831
24f6b9e80f fix: 修复拼单订单失败时,未付款订单没有取消问题。 2024-05-23 15:39:26 +08:00
lele0521
d349616957 fix: 过滤订单售后状态(砍价、积分、赠品订单不可进行售后) 2024-05-20 11:16:36 +08:00
imalasong
f7c9ba820d Merge remote-tracking branch 'origin/pr/1' into pr/1 2024-05-16 21:16:28 +08:00
imalasong
f99f59963a fix: 上传图片时,选择的目录为空时,生成的图片访问不了 2024-05-16 21:16:17 +08:00
imalasong
caaf9c74f3 fix: 上次图片时,选择的目录为空时,生成的图片访问不了 2024-05-16 21:14:41 +08:00
lele0521
076f47f5c4 fix: 回滚用户注销逻辑 2024-05-16 09:36:52 +08:00
lele0521
f0e4e4c2bc fix: 修改注销账号的实现方式 2024-05-16 08:56:25 +08:00
lele0521
c87fe45dfa fix: 修改注销账号的实现方式 2024-05-15 18:38:41 +08:00
lele0521
49fd03df7f fix: 修改注销账号的实现方式 2024-05-13 19:44:51 +08:00
lele0521
6deed61311 fix: 增加商家订单备注功能 2024-05-11 09:21:27 +08:00
Chopper711
6311767320 Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop 2024-05-10 17:05:19 +08:00
Chopper711
2463d1b5bb 验证 TOKEN 2024-05-10 17:04:32 +08:00
铉清
2d052ffb1a 多了一个结束符号进行移除
Signed-off-by: 铉清 <13698617+xuanqings@user.noreply.gitee.com>
2024-04-19 05:17:44 +00:00
129 changed files with 3554 additions and 1291 deletions

View File

@@ -1,10 +0,0 @@
/**
交易唤醒表,增加交易流水详情
*/
ALTER TABLE li_order_item ADD `is_refund` varchar(255) DEFAULT NULL COMMENT '是否退款';
/**
交易表增加订单状态字段
*/
ALTER TABLE li_order_item ADD `refund_price` decimal(10,2) DEFAULT NULL COMMENT '退款金额';

View File

@@ -1,20 +0,0 @@
/**
文件表增加拥有者名称
*/
ALTER TABLE li_file ADD `owner_name` varchar(255) DEFAULT NULL COMMENT '拥有者名称';
/**
初始化文件拥有者名称
*/
UPDATE li_file f JOIN li_store s ON f.owner_id = s.id
SET f.owner_name = s.store_name
WHERE user_enums = 'STORE';
UPDATE li_file f JOIN li_admin_user a ON f.owner_id = a.id
SET f.owner_name = a.nick_name
WHERE user_enums = 'MANAGER';
UPDATE li_file f JOIN li_member m ON f.owner_id = m.id
SET f.owner_name = m.nick_name
WHERE user_enums = 'MEMBER';

11
DB/b2c.sql Normal file
View File

@@ -0,0 +1,11 @@
/**
物流公司增加电子面单参数
*/
ALTER TABLE li_logistics ADD `customer_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '客户代码';
ALTER TABLE li_logistics ADD `customer_pwd` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '客户密码';
ALTER TABLE li_logistics ADD `month_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '月结号/密钥';
ALTER TABLE li_logistics ADD `send_site` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '归属网点';
ALTER TABLE li_logistics ADD `send_staff` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '收件快递员';
ALTER TABLE li_logistics ADD `face_sheet_flag` bit(1) DEFAULT NULL COMMENT '是否使用电子面单';
ALTER TABLE li_logistics ADD `pay_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '支付方式';
ALTER TABLE li_logistics ADD `exp_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '快递类型';

View File

@@ -68,8 +68,6 @@ CREATE TABLE `li_order_package_item` (
*/
ALTER TABLE li_order_item ADD `deliver_number` int DEFAULT NULL COMMENT '发货数量';
ALTER TABLE li_goods_sku ADD `alert_quantity` int DEFAULT NULL COMMENT '预警库存';
/*
sku增加预警库存
*/
@@ -105,7 +103,7 @@ WHERE
sf.flow_type = 'REFUND'
AND sf.store_id=b.store_id
AND sf.create_time BETWEEN b.start_time
AND b.end_time),0)
AND b.end_time),0);
UPDATE li_bill b
SET b.kanjia_refund_settlement_price =IFNULL((
@@ -119,3 +117,51 @@ SET b.kanjia_refund_settlement_price =IFNULL((
AND sf.create_time BETWEEN b.start_time
AND b.end_time),0);
/**
*/
ALTER TABLE li_file ADD `owner_name` varchar(255) DEFAULT NULL COMMENT '拥有者名称';
/**
*/
UPDATE li_file f JOIN li_store s ON f.owner_id = s.id
SET f.owner_name = s.store_name
WHERE user_enums = 'STORE';
UPDATE li_file f JOIN li_admin_user a ON f.owner_id = a.id
SET f.owner_name = a.nick_name
WHERE user_enums = 'MANAGER';
UPDATE li_file f JOIN li_member m ON f.owner_id = m.id
SET f.owner_name = m.nick_name
WHERE user_enums = 'MEMBER';
ALTER TABLE `li_order`
ADD COLUMN `seller_remark` varchar(255) NULL COMMENT '商家订单备注' AFTER `remark`;
ALTER TABLE `li_distribution_cash`
ADD COLUMN `name` varchar(255) NULL COMMENT '会员姓名';
ALTER TABLE `li_distribution_cash`
ADD COLUMN `id_number` varchar(255) NULL COMMENT '身份证号' ;
ALTER TABLE `li_distribution_cash`
ADD COLUMN `settlement_bank_account_name` varchar(255) NULL COMMENT '结算银行开户行名称' ;
ALTER TABLE `li_distribution_cash`
ADD COLUMN `settlement_bank_account_num` varchar(255) NULL COMMENT '结算银行开户账号' ;
ALTER TABLE `li_distribution_cash`
ADD COLUMN `settlement_bank_branch_name` varchar(255) NULL COMMENT '结算银行开户支行名称' ;
ALTER TABLE `li_distribution` ADD `distribution_order_price` decimal(10,2) DEFAULT NULL COMMENT '分销订单金额';
ALTER TABLE `li_distribution_order` ADD `refund_num` int DEFAULT NULL COMMENT '退款商品数量';
ALTER TABLE `li_store_flow` ADD `bill_time` datetime(6) DEFAULT NULL COMMENT '结算时间';
ALTER TABLE `li_store_flow` ADD `full_refund` bit(1) DEFAULT NULL COMMENT '是否全部退款';
ALTER TABLE `li_store_flow` ADD `profit_sharing_status` varchar(255) NULL COMMENT '分账状态';
ALTER TABLE `li_store_flow` ADD `profit_sharing` varchar(255) NULL COMMENT '分账详情';
INSERT INTO `lilishop`.`li_setting` (`id`, `create_by`, `create_time`, `delete_flag`, `update_by`, `update_time`, `setting_value`) VALUES ('CONNECT_SETTING', 'admin', '2024-07-07 13:55:38.686000', b'0', NULL, NULL, '{\"callbackUrl\":\"https://buyer-api.pickmall.cn\",\"pc\":\"https://pc-b2b2c.pickmall.cn\",\"wap\":\"https://m-b2b2c.pickmall.cn\"}');
UPDATE `lilishop`.`li_setting` SET `create_by` = 'admin', `create_time` = '2021-01-23 02:18:03.299000', `delete_flag` = b'0', `update_by` = 'admin', `update_time` = '2024-07-07 13:53:44.732000', `setting_value` = '{\"accessKeyId\":\"test\",\"tencentSdkAppId\":\"null\",\"registerTemplateCode\":\"SMS_205755298\",\"huaweiSender\":\"null\",\"signName\":\"lili\",\"tencentSecretId\":\"null\",\"huaweiAppKey\":\"null\",\"isTestModel\":\"true\",\"tencentSecretKey\":\"null\",\"type\":\"ALI\",\"accessSecret\":\"test\",\"tencentSignName\":\"null\",\"huaweiSignature\":\"null\",\"payPasswordTemplateCode\":\"SMS_205755301\",\"walletPasswordTemplateCode\":\"SMS_205755297\",\"findPasswordTemplateCode\":\"SMS_205755301\",\"huaweiAppSecret\":\"null\",\"loginTemplateCode\":\"SMS_205755300\"}' WHERE `id` = 'SMS_SETTING';

View File

@@ -23,12 +23,13 @@ https://docs.pickmall.cn
#### 开发新手或者不熟悉的同学在群内提问或新开Issue提问前请先阅读[【提问的智慧】](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/master/README-zh_CN.md),并确保已查阅过 [【在线文档】](https://docs.pickmall.cn/) ,避免浪费大家的宝贵时间;
##### 交流 qq 1群 961316482 (1群扩建至2000人还有300坑)
##### 交流 qq 1群 961316482(已满)
##### 交流 qq 2群 875294241已满
##### 交流 qq 3群 263785057已满
##### 交流 qq 4群 674617534 (已满)
##### 交流 qq 5群 594675235 (已满)
##### 交流 qq 6群 917026848
##### 交流 qq 4群 674617534已满
##### 交流 qq 5群 594675235已满
##### 交流 qq 6群 917026848(已满)
##### 交流 qq 7群 936344822
##### 体验 公众号/小程序/APP 体验,扫描二维码

View File

@@ -0,0 +1,168 @@
package cn.lili.controller.other;
import cn.hutool.json.JSONUtil;
import cn.lili.cache.Cache;
import cn.lili.common.aop.annotation.DemoSite;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.*;
import cn.lili.modules.system.entity.dto.connect.ConnectSetting;
import cn.lili.modules.system.entity.dto.connect.QQConnectSetting;
import cn.lili.modules.system.entity.dto.connect.WechatConnectSetting;
import cn.lili.modules.system.entity.dto.payment.AlipayPaymentSetting;
import cn.lili.modules.system.entity.dto.payment.PaymentSupportSetting;
import cn.lili.modules.system.entity.dto.payment.UnionPaymentSetting;
import cn.lili.modules.system.entity.dto.payment.WechatPaymentSetting;
import cn.lili.modules.system.entity.dto.payment.dto.PaymentSupportForm;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author chc
* @since 2022/6/2114:46
*/
@RestController
@Api(tags = "买家端,系统设置")
@RequestMapping("/buyer/other/setting")
public class SettingBuyerController {
@Autowired
private SettingService settingService;
/**
* 缓存
*/
@Autowired
private Cache<String> cache;
@DemoSite
@ApiOperation(value = "查看配置")
@GetMapping(value = "/get/{key}")
@ApiImplicitParam(name = "key", value = "配置key", paramType = "path"
, allowableValues = "BASE_SETTING,EMAIL_SETTING,GOODS_SETTING,KUAIDI_SETTING,ORDER_SETTING,OSS_SETTING,POINT_SETTING," +
"WECHAT_PC_CONNECT,WECHAT_WAP_CONNECT,WECHAT_APP_CONNECT,WECHAT_MP_CONNECT," +
"QQ_WEB_CONNECT,QQ_APP_CONNECT," +
"QQ_WEB_CONNECT,QQ_APP_CONNECT,WEIBO_CONNECT,ALIPAY_CONNECT," +
"PAYMENT_SUPPORT,ALIPAY_PAYMENT,WECHAT_PAYMENT,SECKILL_SETTING,EXPERIENCE_SETTING,IM"
)
public ResultMessage settingGet(@PathVariable String key) {
return createSetting(key);
}
/**
* 获取表单
* 这里主要包含一个配置对象为空,导致转换异常问题的处理,解决配置项增加减少,带来的系统异常,无法直接配置
*
* @param key
* @return
* @throws InstantiationException
* @throws IllegalAccessException
*/
private ResultMessage createSetting(String key) {
SettingEnum settingEnum = SettingEnum.valueOf(key);
cache.remove(key);
Setting setting = settingService.get(key);
switch (settingEnum) {
case BASE_SETTING:
return setting == null ?
ResultUtil.data(new BaseSetting()) :
ResultUtil.data(JSONUtil.toBean(setting.getSettingValue(), BaseSetting.class));
case WITHDRAWAL_SETTING:
return setting == null ?
ResultUtil.data(new WithdrawalSetting()) :
ResultUtil.data(JSONUtil.toBean(setting.getSettingValue(), WithdrawalSetting.class));
case DISTRIBUTION_SETTING:
return setting == null ?
ResultUtil.data(new DistributionSetting()) :
ResultUtil.data(JSONUtil.toBean(setting.getSettingValue(), DistributionSetting.class));
case EMAIL_SETTING:
return setting == null ?
ResultUtil.data(new EmailSetting()) :
ResultUtil.data(JSONUtil.toBean(setting.getSettingValue(), EmailSetting.class));
case GOODS_SETTING:
return setting == null ?
ResultUtil.data(new GoodsSetting()) :
ResultUtil.data(JSONUtil.toBean(setting.getSettingValue(), GoodsSetting.class));
case LOGISTICS_SETTING:
return setting == null ?
ResultUtil.data(new LogisticsSetting()) :
ResultUtil.data(JSONUtil.toBean(setting.getSettingValue(), LogisticsSetting.class));
case ORDER_SETTING:
return setting == null ?
ResultUtil.data(new OrderSetting()) :
ResultUtil.data(JSONUtil.toBean(setting.getSettingValue(), OrderSetting.class));
case OSS_SETTING:
return setting == null ?
ResultUtil.data(new OssSetting()) :
ResultUtil.data(JSONUtil.toBean(setting.getSettingValue(), OssSetting.class));
case SMS_SETTING:
return setting == null ?
ResultUtil.data(new SmsSetting()) :
ResultUtil.data(JSONUtil.toBean(setting.getSettingValue(), SmsSetting.class));
case POINT_SETTING:
return setting == null ?
ResultUtil.data(new PointSetting()) :
ResultUtil.data(JSONUtil.toBean(setting.getSettingValue(), PointSetting.class));
case QQ_CONNECT:
return setting == null ?
ResultUtil.data(new QQConnectSetting()) :
ResultUtil.data(JSONUtil.toBean(setting.getSettingValue(), QQConnectSetting.class));
case CONNECT_SETTING:
return setting == null ?
ResultUtil.data(new ConnectSetting()) :
ResultUtil.data(JSONUtil.toBean(setting.getSettingValue(), ConnectSetting.class));
case PAYMENT_SUPPORT:
return setting == null ?
ResultUtil.data(new PaymentSupportSetting(new PaymentSupportForm())) :
ResultUtil.data(JSONUtil.toBean(setting.getSettingValue(), PaymentSupportSetting.class));
case ALIPAY_PAYMENT:
return setting == null ?
ResultUtil.data(new AlipayPaymentSetting()) :
ResultUtil.data(JSONUtil.toBean(setting.getSettingValue(), AlipayPaymentSetting.class));
case UNIONPAY_PAYMENT:
return setting == null ?
ResultUtil.data(new UnionPaymentSetting()) :
ResultUtil.data(JSONUtil.toBean(setting.getSettingValue(), UnionPaymentSetting.class));
case WECHAT_CONNECT:
return setting == null ?
ResultUtil.data(new WechatConnectSetting()) :
ResultUtil.data(JSONUtil.toBean(setting.getSettingValue(), WechatConnectSetting.class));
case WECHAT_PAYMENT:
return setting == null ?
ResultUtil.data(new WechatPaymentSetting()) :
ResultUtil.data(JSONUtil.toBean(setting.getSettingValue(), WechatPaymentSetting.class));
case SECKILL_SETTING:
return setting == null ?
ResultUtil.data(new SeckillSetting()) :
ResultUtil.data(JSONUtil.toBean(setting.getSettingValue(), SeckillSetting.class));
case EXPERIENCE_SETTING:
return setting == null ?
ResultUtil.data(new ExperienceSetting()) :
ResultUtil.data(JSONUtil.toBean(setting.getSettingValue(), ExperienceSetting.class));
case IM_SETTING:
return setting == null ?
ResultUtil.data(new ImSetting()) :
ResultUtil.data(JSONUtil.toBean(setting.getSettingValue(), ImSetting.class));
case HOT_WORDS:
return setting == null ?
ResultUtil.data(new HotWordsSetting()) :
ResultUtil.data(JSONUtil.toBean(setting.getSettingValue(), HotWordsSetting.class));
case DELIVERY_SETTING:
return setting == null ?
ResultUtil.data(new DeliverySetting()) :
ResultUtil.data(JSONUtil.toBean(setting.getSettingValue(), DeliverySetting.class));
default:
throw new ServiceException(ResultCode.SETTING_NOT_TO_SET);
}
}
}

View File

@@ -29,7 +29,7 @@ import org.springframework.web.context.request.async.DeferredResult;
import javax.validation.constraints.NotNull;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 买家端,会员接口
@@ -73,6 +73,8 @@ public class MemberBuyerController {
new ResponseEntity<>(ResultUtil.error(ResultCode.ERROR), HttpStatus.OK);
int timeoutSecond = 20;
DeferredResult<ResponseEntity<Object>> deferredResult = new DeferredResult<>(timeoutSecond * 1000L, timeoutResponseEntity);
// 用于记录重试次数
AtomicInteger retryCount = new AtomicInteger(0);
CompletableFuture.runAsync(() -> {
try {
int i = 0;
@@ -83,7 +85,16 @@ public class MemberBuyerController {
&& (QRCodeLoginSessionStatusEnum.WAIT_SCANNING.getCode() == status
|| QRCodeLoginSessionStatusEnum.SCANNING.getCode() == status)) {
//睡眠一秒种,继续等待结果
TimeUnit.SECONDS.sleep(1);
//TimeUnit.SECONDS.sleep(1);
// 应用指数退避策略
int baseSleepTime = 1000; // 基础退避时间(毫秒)
int maxSleepTime = 10000; // 最大退避时间(毫秒)
int sleepTime = Math.min(maxSleepTime, baseSleepTime * (1 + retryCount.getAndIncrement()));
int randomFactor = (int) (Math.random() * (sleepTime / 2)); // 随机化因子
TimeUnit.MILLISECONDS.sleep(sleepTime + randomFactor);
} else {
deferredResult.setResult(new ResponseEntity<>(ResultUtil.data(queryResult), HttpStatus.OK));
break;
@@ -167,9 +178,13 @@ public class MemberBuyerController {
@RequestHeader String uuid) {
if (smsUtil.verifyCode(mobile, VerificationEnums.BIND_MOBILE, uuid, code)) {
Member member = memberService.findByUsername(username);
Member memberByMobile = memberService.findByMobile(mobile);
if (member == null) {
throw new ServiceException(ResultCode.USER_NOT_EXIST);
}
if(memberByMobile != null){
throw new ServiceException(ResultCode.USER_MOBILE_REPEATABLE_ERROR);
}
return ResultUtil.data(memberService.changeMobile(member.getId(), mobile));
} else {
throw new ServiceException(ResultCode.VERIFICATION_SMS_CHECKED_ERROR);
@@ -272,12 +287,9 @@ public class MemberBuyerController {
}
@ApiOperation(value = "注销账号")
@ApiImplicitParams({
@ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "query")
})
@PutMapping("/cancellation")
public ResultMessage<Member> cancellation(@NotNull(message = "密码不能为空") @RequestParam String password) {
memberService.cancellation(password);
public ResultMessage<Member> cancellation() {
memberService.cancellation();
return ResultUtil.success();
}

View File

@@ -67,13 +67,19 @@ public class CouponBuyerController {
if (UserContext.getCurrentUser() == null) {
return ResultUtil.success();
}
return ResultUtil.data(couponActivityService.trigger(
List<MemberCoupon> memberCouponList = couponActivityService.trigger(
CouponActivityTrigger.builder()
.couponActivityTypeEnum(CouponActivityTypeEnum.AUTO_COUPON)
.nickName(UserContext.getCurrentUser().getNickName())
.userId(UserContext.getCurrentUser().getId())
.build())
);
.build());
memberCouponList.addAll(couponActivityService.trigger(
CouponActivityTrigger.builder()
.couponActivityTypeEnum(CouponActivityTypeEnum.SPECIFY)
.nickName(UserContext.getCurrentUser().getNickName())
.userId(UserContext.getCurrentUser().getId())
.build()));
return ResultUtil.data(memberCouponList);
}
@GetMapping

View File

@@ -213,18 +213,6 @@ lili:
lbs:
key: 4BYBZ-7MT6S-PUAOA-6BNWL-FJUD7-UUFXT
sk: zhNKVrJK6UPOhqIjn8AQvG37b9sz6
#域名
domain:
pc: https://pc-b2b2c.pickmall.cn
wap: https://m-b2b2c.pickmall.cn
store: https://store-b2b2c.pickmall.cn
admin: https://admin-b2b2c.pickmall.cn
#api地址
api:
buyer: https://buyer-api.pickmall.cn
common: https://common-api.pickmall.cn
manager: https://admin-api.pickmall.cn
store: https://store-api.pickmall.cn
# jwt 细节设定
jwt-setting:

View File

@@ -1,5 +1,6 @@
package cn.lili.controller.common;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.vo.ResultMessage;
@@ -57,8 +58,10 @@ public class FileDirectoryController {
@ApiOperation(value = "删除文件目录")
@DeleteMapping("/{id}")
public ResultMessage<Object> deleteSceneFileList(@PathVariable String id) {
//删除文件夹下面的图片
fileService.batchDeleteByDirectory(id);
//检测文件夹下是否包含图片
if(fileService.countByDirectory(id)){
return ResultUtil.error(ResultCode.FILE_DIRECTORY_NOT_EMPTY);
}
//删除目录
fileDirectoryService.removeById(id);
return ResultUtil.success();

View File

@@ -55,6 +55,9 @@ public class UploadController {
String base64,
@RequestHeader String accessToken, @RequestParam String directoryPath) {
if(StrUtil.isBlank(directoryPath)){
directoryPath = "default";
}
AuthUser authUser = UserContext.getAuthUser(cache, accessToken);
//如果用户未登录,则无法上传图片

View File

@@ -190,18 +190,6 @@ lili:
interfereNum: 0
#允许误差像素
faultTolerant: 3
#短信模版配置
sms:
#登录
LOGIN: SMS_205755300
#注册
REGISTER: SMS_205755298
#找回密码
FIND_USER: SMS_205755301
#设置密码
UPDATE_PASSWORD: SMS_205755297
#支付密码
WALLET_PASSWORD: SMS_205755301
system:
isTestModel: true
statistics:

View File

@@ -209,21 +209,8 @@ lili:
interfereNum: 1
#允许误差像素
faultTolerant: 3
#短信模版配置
sms:
#登录
LOGIN: SMS_205755300
#注册
REGISTER: SMS_205755298
#找回密码
FIND_USER: SMS_205755301
#设置密码
UPDATE_PASSWORD: SMS_205755297
#支付密码
WALLET_PASSWORD: SMS_205755301
system:
isDemoSite: false
isTestModel: true
# 脱敏级别:
# 0不做脱敏处理
# 1管理端用户手机号等信息脱敏
@@ -301,7 +288,7 @@ lili:
after-sale-topic: shop_lili_after_sale_topic
after-sale-group: shop_lili_after_sale_group
rocketmq:
name-server: 192.168.31.100:30876
name-server: 192.168.31.100:9876
isVIPChannel: false
producer:
group: lili_group

View File

@@ -27,7 +27,7 @@ import org.springframework.stereotype.Service;
*/
@Slf4j
@Service
public class DistributionOrderExecute implements OrderStatusChangeEvent, EveryDayExecute, AfterSaleStatusChangeEvent {
public class DistributionOrderExecute implements OrderStatusChangeEvent, AfterSaleStatusChangeEvent {
/**
* 分销订单
@@ -35,10 +35,6 @@ public class DistributionOrderExecute implements OrderStatusChangeEvent, EveryDa
@Autowired
private DistributionOrderService distributionOrderService;
@Autowired
private SettingService settingService;
@Override
public void orderChange(OrderMessage orderMessage) {
@@ -62,21 +58,6 @@ public class DistributionOrderExecute implements OrderStatusChangeEvent, EveryDa
}
}
@Override
public void execute() {
log.info("分销订单定时开始执行");
//设置结算天数(解冻日期)
Setting setting = settingService.get(SettingEnum.DISTRIBUTION_SETTING.name());
DistributionSetting distributionSetting = JSONUtil.toBean(setting.getSettingValue(), DistributionSetting.class);
//解冻时间
DateTime dateTime = new DateTime();
//当前时间-结算天数=最终结算时间
dateTime = dateTime.offsetNew(DateField.DAY_OF_MONTH, -distributionSetting.getCashDay());
//分销人员订单结算
distributionOrderService.updateRebate(dateTime, DistributionOrderStatusEnum.WAIT_BILL.name());
}
@Override
public void afterSaleStatusChange(AfterSale afterSale) {
if (afterSale.getServiceStatus().equals(AfterSaleStatusEnum.COMPLETE.name())) {

View File

@@ -8,6 +8,7 @@ import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
import cn.lili.modules.order.order.entity.enums.PayStatusEnum;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.order.order.service.StoreFlowService;
import cn.lili.modules.payment.entity.RefundLog;
import cn.lili.modules.payment.kit.Payment;
import cn.lili.modules.payment.entity.enums.PaymentMethodEnum;
@@ -30,6 +31,8 @@ public class PaymentExecute implements OrderStatusChangeEvent {
*/
@Autowired
private OrderService orderService;
@Autowired
private StoreFlowService storeFlowService;
@Override
public void orderChange(OrderMessage orderMessage) {
@@ -60,6 +63,8 @@ public class PaymentExecute implements OrderStatusChangeEvent {
.refundReason("订单取消")
.build();
payment.refund(refundLog);
}
}
}

View File

@@ -43,7 +43,7 @@ public class VerificationOrderExecute implements OrderStatusChangeEvent {
//修改虚拟订单货物可以进行售后、投诉
orderItemService.update(new LambdaUpdateWrapper<OrderItem>().eq(OrderItem::getOrderSn, orderMessage.getOrderSn())
.set(OrderItem::getAfterSaleStatus, OrderItemAfterSaleStatusEnum.NOT_APPLIED)
.set(OrderItem::getComplainStatus, OrderComplaintStatusEnum.COMPLETE));
.set(OrderItem::getComplainStatus, OrderComplaintStatusEnum.NO_APPLY));
}
}

View File

@@ -0,0 +1,48 @@
package cn.lili.event.impl;
import cn.lili.event.OrderStatusChangeEvent;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.wechat.service.WechatMPService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service ;
/**
* 微信小程序执行器
*
* @author Chopper
* @version v1.0 2021-04-19 14:25
*/
@Slf4j
@Service
public class WechatMPExecute implements OrderStatusChangeEvent {
@Autowired
private WechatMPService wechatMPService;
/**
* 订单已发货、待提货、待核验状态 如果是微信小程序的订单则进行 订单发货信息录入
*
* @param orderMessage 订单消息
*/
@Override
public void orderChange(OrderMessage orderMessage) {
switch (orderMessage.getNewStatus()) {
case TAKE:
case STAY_PICKED_UP:
case DELIVERED:
try {
wechatMPService.uploadShippingInfo(orderMessage.getOrderSn());
} catch (Exception e) {
log.error("发货信息录入失败", e);
}
break;
default:
break;
}
}
}

View File

@@ -292,6 +292,9 @@ public class GoodsMessageListener implements RocketMQListener<MessageExt> {
searchParams.setCategoryPath(promotions.getScopeId());
searchParams.setPageNumber(i);
searchParams.setPageSize(BATCH_SIZE);
if (CharSequenceUtil.isNotEmpty(promotions.getStoreId()) && !"0".equals(promotions.getStoreId())){
searchParams.setStoreId(promotions.getStoreId());
}
IPage<GoodsSku> goodsSkuByPage = this.goodsSkuService.getGoodsSkuByPage(searchParams);
if (goodsSkuByPage == null || goodsSkuByPage.getRecords().isEmpty()) {
break;

View File

@@ -1,60 +0,0 @@
package cn.lili.timetask.handler.impl.bill;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.lili.modules.store.entity.dto.StoreSettlementDay;
import cn.lili.modules.store.service.BillService;
import cn.lili.modules.store.service.StoreDetailService;
import cn.lili.timetask.handler.EveryDayExecute;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 店铺结算执行
*
* @author Bulbasaur
* @since 2021/2/18 3:45 下午
*/
@Component
public class BillExecute implements EveryDayExecute {
/**
* 结算单
*/
@Autowired
private BillService billService;
/**
* 店铺详情
*/
@Autowired
private StoreDetailService storeDetailService;
/**
* 1.查询今日待结算的商家
* 2.查询商家上次结算日期,生成本次结算单
* 3.记录商家结算日
*/
@Override
public void execute() {
//获取当前天数
int day = DateUtil.date().dayOfMonth();
//获取待结算商家列表
List<StoreSettlementDay> storeList = storeDetailService.getSettlementStore(day);
//获取当前时间
DateTime endTime = DateUtil.date();
//批量商家结算
for (StoreSettlementDay storeSettlementDay : storeList) {
//生成结算单
billService.createBill(storeSettlementDay.getStoreId(), storeSettlementDay.getSettlementDay(), endTime);
//修改店铺结算时间
storeDetailService.updateSettlementDay(storeSettlementDay.getStoreId(), endTime);
}
}
}

View File

@@ -18,6 +18,10 @@ import cn.lili.modules.order.order.entity.enums.OrderItemAfterSaleStatusEnum;
import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
import cn.lili.modules.order.order.service.OrderItemService;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.order.order.service.StoreFlowService;
import cn.lili.modules.store.entity.dto.StoreSettlementDay;
import cn.lili.modules.store.service.BillService;
import cn.lili.modules.store.service.StoreDetailService;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.OrderSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
@@ -25,12 +29,13 @@ import cn.lili.modules.system.service.SettingService;
import cn.lili.timetask.handler.EveryDayExecute;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
/**
* @author paulG
@@ -65,6 +70,20 @@ public class OrderEveryDayTaskExecute implements EveryDayExecute {
@Autowired
private DistributionOrderService distributionOrderService;
@Autowired
private StoreFlowService storeFlowService;
/**
* 结算单
*/
@Autowired
private BillService billService;
/**
* 店铺详情
*/
@Autowired
private StoreDetailService storeDetailService;
/**
* 执行每日任务
*/
@@ -92,7 +111,7 @@ public class OrderEveryDayTaskExecute implements EveryDayExecute {
}
try {
//关闭允许售后申请
closeAfterSale(orderSetting);
this.closeAfterSale(orderSetting);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
@@ -102,6 +121,22 @@ public class OrderEveryDayTaskExecute implements EveryDayExecute {
} catch (Exception e) {
log.error(e.getMessage(), e);
}
//修改分账状态
try {
storeFlowService.updateProfitSharingStatus();
} catch (Exception e) {
log.error("修改分账状态失败", e);
}
//生成店铺结算单
try {
createBill();
} catch (Exception e) {
log.error("生成店铺结算单", e);
}
}
/**
@@ -111,7 +146,6 @@ public class OrderEveryDayTaskExecute implements EveryDayExecute {
*/
private void completedOrder(OrderSetting orderSetting) {
//订单自动收货时间 = 当前时间 - 自动收货时间天数
DateTime receiveTime = DateUtil.offsetDay(DateUtil.date(), -orderSetting.getAutoReceive());
LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
@@ -144,7 +178,9 @@ public class OrderEveryDayTaskExecute implements EveryDayExecute {
DateTime receiveTime = DateUtil.offsetDay(DateUtil.date(), -orderSetting.getAutoEvaluation());
//订单完成时间 <= 订单自动好评时间
OrderItemOperationDTO orderItemOperationDTO = OrderItemOperationDTO.builder().receiveTime(receiveTime).commentStatus(CommentStatusEnum.UNFINISHED.name()).build();
OrderItemOperationDTO orderItemOperationDTO =
OrderItemOperationDTO.builder().receiveTime(receiveTime).commentStatus(CommentStatusEnum.UNFINISHED.name())
.build();
List<OrderItem> orderItems = orderItemService.waitOperationOrderItem(orderItemOperationDTO);
//判断是否有符合条件的订单,进行自动评价处理
@@ -170,25 +206,21 @@ public class OrderEveryDayTaskExecute implements EveryDayExecute {
}
}
/**
* 关闭允许售后申请
*
* @param orderSetting 订单设置
*/
private void closeAfterSale(OrderSetting orderSetting) {
@Transactional(rollbackFor = Exception.class)
public void closeAfterSale(OrderSetting orderSetting) {
//订单关闭售后申请时间 = 当前时间 - 自动关闭售后申请天数
DateTime receiveTime = DateUtil.offsetDay(DateUtil.date(), -orderSetting.getCloseAfterSale());
//关闭售后订单=未售后订单+小于订单关闭售后申请时间
OrderItemOperationDTO build = OrderItemOperationDTO.builder().receiveTime(receiveTime).afterSaleStatus(OrderItemAfterSaleStatusEnum.NOT_APPLIED.name()).build();
List<OrderItem> orderItems = orderItemService.waitOperationOrderItem(build);
//判断是否有符合条件的订单,关闭允许售后申请处理
if (!orderItems.isEmpty()) {
// OrderItemOperationDTO build = OrderItemOperationDTO.builder().receiveTime(receiveTime)
// .afterSaleStatus(OrderItemAfterSaleStatusEnum.NOT_APPLIED.name()).build();
// List<OrderItem> orderItems = orderItemService.waitOperationOrderItem(build);
//关闭售后订单=未售后订单+小于订单关闭售后申请时间
orderItemService.expiredAfterSaleStatus(receiveTime);
//修改对应分销订单状态
distributionOrderService.updateDistributionOrderStatus(orderItems);
}
}
@@ -207,7 +239,8 @@ public class OrderEveryDayTaskExecute implements EveryDayExecute {
DateTime receiveTime = DateUtil.offsetDay(DateUtil.date(), -orderSetting.getCloseComplaint());
//关闭售后订单=未售后订单+小于订单关闭售后申请时间
OrderItemOperationDTO build = OrderItemOperationDTO.builder().receiveTime(receiveTime).complainStatus(OrderComplaintStatusEnum.NO_APPLY.name()).build();
OrderItemOperationDTO build = OrderItemOperationDTO.builder().receiveTime(receiveTime)
.complainStatus(OrderComplaintStatusEnum.NO_APPLY.name()).build();
List<OrderItem> orderItems = orderItemService.waitOperationOrderItem(build);
//判断是否有符合条件的订单,关闭允许售后申请处理
@@ -217,12 +250,37 @@ public class OrderEveryDayTaskExecute implements EveryDayExecute {
List<String> orderItemIdList = orderItems.stream().map(OrderItem::getId).collect(Collectors.toList());
//修改订单投诉状态
LambdaUpdateWrapper<OrderItem> lambdaUpdateWrapper = new LambdaUpdateWrapper<OrderItem>()
.set(OrderItem::getComplainStatus, OrderItemAfterSaleStatusEnum.EXPIRED.name())
.in(OrderItem::getId, orderItemIdList);
LambdaUpdateWrapper<OrderItem> lambdaUpdateWrapper =
new LambdaUpdateWrapper<OrderItem>().set(OrderItem::getComplainStatus,
OrderItemAfterSaleStatusEnum.EXPIRED.name()).in(OrderItem::getId, orderItemIdList);
orderItemService.update(lambdaUpdateWrapper);
}
}
/**
* 1.查询今日待结算的商家
* 2.查询商家上次结算日期,生成本次结算单
* 3.记录商家结算日
*/
private void createBill() {
//获取当前天数
int day = DateUtil.date().dayOfMonth();
//获取待结算商家列表
List<StoreSettlementDay> storeList = storeDetailService.getSettlementStore(day);
//获取当前时间
DateTime endTime = DateUtil.date();
//批量商家结算
for (StoreSettlementDay storeSettlementDay : storeList) {
//生成结算单
billService.createBill(storeSettlementDay.getStoreId(), storeSettlementDay.getSettlementDay(), endTime);
//修改店铺结算时间
storeDetailService.updateSettlementDay(storeSettlementDay.getStoreId(), endTime);
}
}
}

View File

@@ -1,64 +0,0 @@
package cn.lili.buyer.test.cart;
import cn.lili.common.utils.DateUtil;
import cn.lili.timetask.handler.impl.statistics.OnlineMemberStatistics;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import java.util.Calendar;
import java.util.Random;
/**
* 订单库存扣减
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest
class OnlineTest {
@Autowired
private OnlineMemberStatistics onlineMemberStatistics;
//订单支付,库存扣减单元测试
@Test
void everyHour() {
onlineMemberStatistics.execute();
}
//订单支付,库存扣减单元测试
@Test
void customSetting() {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - 48 );
//循环填充数据
for (int i = 0; i < 48; i++) {
calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) + 1);
System.out.println(DateUtil.toString(calendar.getTime(),""));
Random random = new Random();
onlineMemberStatistics.execute(calendar.getTime(), random.nextInt(1000000));
}
}
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - 48 - 1);
//循环填充数据
for (int i = 0; i < 48; i++) {
calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) + 1);
System.out.println(calendar.getTime().getTime());
}
}
}

View File

@@ -1,6 +1,11 @@
package cn.lili.common.enums;
import cn.lili.common.utils.StringUtils;
import java.util.Arrays;
import java.util.EnumSet;
/**
* 促销分类枚举
*
@@ -52,4 +57,28 @@ public enum PromotionTypeEnum {
return description;
}
/**
* 判断促销类型是否有效
* @param typeEnumValue
* @return
*/
public static boolean isValid(String typeEnumValue) {
if (StringUtils.isBlank(typeEnumValue)) {
return false;
}
return Arrays.stream(PromotionTypeEnum.values()).anyMatch(c -> c.name().equals(typeEnumValue));
}
/**
* 判断订单类型是否可售后
* POINTS\KANJIA 两种促销类型的订单不可进行售后
* @return true 可售后 false 不可售后
*/
public static boolean isCanAfterSale(String promotionType) {
if (!isValid(promotionType)) {
return true;
}
EnumSet<PromotionTypeEnum> noAfterSale = EnumSet.of(PromotionTypeEnum.KANJIA, PromotionTypeEnum.POINTS_GOODS);
return !noAfterSale.contains(PromotionTypeEnum.valueOf(promotionType));
}
}

View File

@@ -42,6 +42,7 @@ public enum ResultCode {
PLATFORM_NOT_SUPPORTED_IM(1006, "平台未开启IM"),
STORE_NOT_SUPPORTED_IM(1007, "店铺未开启IM"),
UNINITIALIZED_PASSWORD(1008, "非初始化密码,无法进行初始化设置"),
FILE_DIRECTORY_NOT_EMPTY(1012, "文件夹下有文件,请删除所有文件后删除文件夹!"),
/**
* 分类
*/
@@ -89,6 +90,7 @@ public enum ResultCode {
VIRTUAL_GOODS_NOT_NEED_TEMP(11015, "虚拟商品无需选择配送模板"),
GOODS_NOT_EXIST_STORE(11017, "当前用户无权操作此商品"),
GOODS_TYPE_ERROR(11016, "需选择商品类型"),
GOODS_STOCK_IMPORT_ERROR(11018, "导入商品库存失败,请检查表格数据"),
/**
* 参数
@@ -150,6 +152,7 @@ public enum ResultCode {
CLERK_DISABLED_ERROR(20031, "店员已禁用"),
CLERK_CURRENT_SUPPER(20032, "无法删除当前登录店员"),
CANT_EDIT_CLERK_SHOPKEEPER(20033, "无法在店员管理编辑店员信息"),
USER_MOBILE_REPEATABLE_ERROR(20034, "该手机号已存在"),
/**
* 权限
*/
@@ -173,6 +176,7 @@ public enum ResultCode {
DISTRIBUTION_RETREAT_ERROR(22004, "分销员清退失败"),
DISTRIBUTION_CASH_NOT_EXIST(22005, "分销员提现记录不存在"),
DISTRIBUTION_GOODS_DOUBLE(22006, "不能重复添加分销商品"),
DISTRIBUTION_EDIT_ERROR(22007, "修改分销员失败"),
/**
* 购物车
@@ -460,6 +464,7 @@ public enum ResultCode {
ORDER_SETTING_ERROR(70006, "系统订单配置异常"),
ALI_SMS_SETTING_ERROR(70007, "您还未配置阿里云短信"),
SMS_SIGN_EXIST_ERROR(70008, "短信签名已存在"),
DELIVERY_SETTING_ERROR(70009, "请配置发货参数"),
/**
* 站内信

View File

@@ -14,23 +14,23 @@ import org.springframework.context.annotation.Configuration;
public class ApiProperties {
/**
* 买家api
*/
private String buyer;
// /**
// * 买家api
// */
// private String buyer;
/**
* 管理端域名
*/
private String store;
/**
* 管理端域名
*/
private String manager;
/**
* 管理端域名
*/
private String common;
// /**
// * 管理端域名
// */
// private String store;
//
// /**
// * 管理端域名
// */
// private String manager;
//
// /**
// * 管理端域名
// */
// private String common;
}

View File

@@ -23,6 +23,7 @@ import cn.lili.modules.connect.request.BaseAuthWeChatPCRequest;
import cn.lili.modules.connect.request.BaseAuthWeChatRequest;
import cn.lili.modules.connect.service.ConnectService;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.connect.ConnectSetting;
import cn.lili.modules.system.entity.dto.connect.QQConnectSetting;
import cn.lili.modules.system.entity.dto.connect.WechatConnectSetting;
import cn.lili.modules.system.entity.dto.connect.dto.QQConnectSettingItem;
@@ -70,8 +71,8 @@ public class ConnectUtil {
* @param connectAuthEnum 用户枚举
* @return 回调地址
*/
String getRedirectUri(ConnectAuthEnum connectAuthEnum) {
return apiProperties.getBuyer() + prefix + connectAuthEnum.getName();
String getRedirectUri(ConnectAuthEnum connectAuthEnum,String callbackUrl) {
return callbackUrl + prefix + connectAuthEnum.getName();
}
/**
@@ -106,10 +107,13 @@ public class ConnectUtil {
//缓存写入登录结果300秒有效
cache.put(CachePrefix.CONNECT_RESULT.getPrefix() + callback.getCode(), resultMessage, 300L);
//登录设置
ConnectSetting connectSetting = JSONUtil.toBean(settingService.get(SettingEnum.CONNECT_SETTING.name()).getSettingValue(), ConnectSetting.class);
//跳转地址
String url = this.check(httpServletRequest.getHeader("user-agent")) ?
domainProperties.getWap() + "/pages/passport/login?state=" + callback.getCode() :
domainProperties.getPc() + "/login?state=" + callback.getCode();
connectSetting.getWap() + "/pages/passport/login?state=" + callback.getCode() :
connectSetting.getPc() + "/login?state=" + callback.getCode();
try {
httpServletResponse.sendRedirect(url);
@@ -151,13 +155,15 @@ public class ConnectUtil {
//寻找配置
Setting setting = settingService.get(SettingEnum.WECHAT_CONNECT.name());
WechatConnectSetting wechatConnectSetting = JSONUtil.toBean(setting.getSettingValue(), WechatConnectSetting.class);
//登录设置
ConnectSetting connectSetting = JSONUtil.toBean(settingService.get(SettingEnum.CONNECT_SETTING.name()).getSettingValue(), ConnectSetting.class);
for (WechatConnectSettingItem wechatConnectSettingItem : wechatConnectSetting.getWechatConnectSettingItems()) {
if (wechatConnectSettingItem.getClientType().equals(ClientTypeEnum.H5.name())) {
authRequest = new BaseAuthWeChatRequest(AuthConfig.builder()
.clientId(wechatConnectSettingItem.getAppId())
.clientSecret(wechatConnectSettingItem.getAppSecret())
.redirectUri(getRedirectUri(authInterface))
.redirectUri(getRedirectUri(authInterface, connectSetting.getCallbackUrl()))
.build(), cache);
}
}
@@ -167,13 +173,14 @@ public class ConnectUtil {
//寻找配置
Setting setting = settingService.get(SettingEnum.WECHAT_CONNECT.name());
WechatConnectSetting wechatConnectSetting = JSONUtil.toBean(setting.getSettingValue(), WechatConnectSetting.class);
//登录设置
ConnectSetting connectSetting = JSONUtil.toBean(settingService.get(SettingEnum.CONNECT_SETTING.name()).getSettingValue(), ConnectSetting.class);
for (WechatConnectSettingItem wechatConnectSettingItem : wechatConnectSetting.getWechatConnectSettingItems()) {
if (wechatConnectSettingItem.getClientType().equals(ClientTypeEnum.PC.name())) {
authRequest = new BaseAuthWeChatPCRequest(AuthConfig.builder()
.clientId(wechatConnectSettingItem.getAppId())
.clientSecret(wechatConnectSettingItem.getAppSecret())
.redirectUri(getRedirectUri(authInterface))
.redirectUri(getRedirectUri(authInterface, connectSetting.getCallbackUrl()))
.build(), cache);
}
}
@@ -184,13 +191,14 @@ public class ConnectUtil {
//寻找配置
Setting setting = settingService.get(SettingEnum.QQ_CONNECT.name());
QQConnectSetting qqConnectSetting = JSONUtil.toBean(setting.getSettingValue(), QQConnectSetting.class);
//登录设置
ConnectSetting connectSetting = JSONUtil.toBean(settingService.get(SettingEnum.CONNECT_SETTING.name()).getSettingValue(), ConnectSetting.class);
for (QQConnectSettingItem qqConnectSettingItem : qqConnectSetting.getQqConnectSettingItemList()) {
if (qqConnectSettingItem.getClientType().equals(ClientTypeEnum.PC.name())) {
authRequest = new BaseAuthQQRequest(AuthConfig.builder()
.clientId(qqConnectSettingItem.getAppId())
.clientSecret(qqConnectSettingItem.getAppKey())
.redirectUri(getRedirectUri(authInterface))
.redirectUri(getRedirectUri(authInterface, connectSetting.getCallbackUrl()))
//这里qq获取unionid 需要配置为true详情可以查阅属性说明内部有帮助文档
.unionId(true)
.build(), cache);

View File

@@ -36,6 +36,7 @@ public class Distribution extends BaseEntity {
this.rebateTotal=0D;
this.canRebate=0D;
this.commissionFrozen=0D;
this.distributionOrderPrice=0D;
this.distributionStatus = DistributionStatusEnum.APPLY.name();
BeanUtil.copyProperties(distributionApplyDTO, this);
}
@@ -85,4 +86,7 @@ public class Distribution extends BaseEntity {
@ApiModelProperty(value = "结算银行开户支行名称")
private String settlementBankBranchName;
@ApiModelProperty(value = "分销订单金额")
private Double distributionOrderPrice;
}

View File

@@ -9,9 +9,11 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Length;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotBlank;
import java.util.Date;
/**
@@ -51,11 +53,30 @@ public class DistributionCash extends BaseEntity {
@ApiModelProperty(value = "状态")
private String distributionCashStatus;
public DistributionCash(String sn, String distributionId, Double price, String memberName) {
@ApiModelProperty(value = "会员姓名")
private String name;
@ApiModelProperty(value = "身份证号")
private String idNumber;
@ApiModelProperty(value = "结算银行开户行名称")
private String settlementBankAccountName;
@ApiModelProperty(value = "结算银行开户账号")
private String settlementBankAccountNum;
@ApiModelProperty(value = "结算银行开户支行名称")
private String settlementBankBranchName;
public DistributionCash(String sn,Double price, Distribution distribution) {
this.sn = sn;
this.distributionId = distributionId;
this.distributionId = distribution.getId();
this.price = price;
this.distributionCashStatus = WithdrawStatusEnum.APPLY.name();
this.distributionName = memberName;
this.distributionName = distribution.getMemberName();
this.name = distribution.getName();
this.idNumber = distribution.getIdNumber();
this.settlementBankAccountName = distribution.getSettlementBankAccountName();
this.settlementBankAccountNum = distribution.getSettlementBankAccountNum();
this.settlementBankBranchName = distribution.getSettlementBankBranchName();
}
}

View File

@@ -79,6 +79,8 @@ public class DistributionOrder extends BaseIdEntity {
private String image;
@ApiModelProperty(value = "商品数量")
private Integer num;
@ApiModelProperty(value = "退款商品数量")
private Integer refundNum;
public DistributionOrder(StoreFlow storeFlow) {
distributionOrderStatus = DistributionOrderStatusEnum.NO_COMPLETED.name();
@@ -95,6 +97,8 @@ public class DistributionOrder extends BaseIdEntity {
specs = storeFlow.getSpecs();
image = storeFlow.getImage();
num = storeFlow.getNum();
refundNum=0;
sellBackRebate=0D;
}
}

View File

@@ -6,16 +6,10 @@ package cn.lili.modules.distribution.entity.enums;
* @author pikachu
*/
public enum DistributionOrderStatusEnum {
//未完成
NO_COMPLETED("未完成"),
//待结算(冻结)
WAIT_BILL("待结算"),
//待提现
WAIT_CASH("待提现"),
//已提现
COMPLETE_CASH("提现完成"),
//订单取消
CANCEL("订单取消"),
//完成
COMPLETE("完成"),
//订单取消
REFUND("退款");

View File

@@ -13,25 +13,32 @@ import org.apache.ibatis.annotations.Update;
*/
public interface DistributionMapper extends BaseMapper<Distribution> {
/**
* 修改分销员可提现金额
*
* @param commissionFrozen 分销金额
* @param distributionId 分销员ID
*/
@Update("UPDATE li_distribution set commission_frozen = (IFNULL(commission_frozen,0)+#{commissionFrozen}) " +
", rebate_total=(IFNULL(rebate_total,0)+#{commissionFrozen}) WHERE id = #{distributionId}")
void subCanRebate(Double commissionFrozen, String distributionId);
@Update("UPDATE li_distribution set commission_frozen = (IFNULL(commission_frozen,0) - #{commissionFrozen}) " +
", rebate_total=(IFNULL(rebate_total,0) - #{commissionFrozen}) " +
", distribution_order_count=(IFNULL(distribution_order_count,0)-1) " +
" WHERE id = #{distributionId}")
void subRebate(Double commissionFrozen, String distributionId, Double distributionOrderPrice);
/**
* 添加分销金额
*
* @param commissionFrozen 分销金额
* @param distributionId 分销员ID
*/
@Update("UPDATE li_distribution set commission_frozen = (IFNULL(commission_frozen,0)+#{commissionFrozen}) " +
", rebate_total=(IFNULL(rebate_total,0)+#{commissionFrozen}) " +
", distribution_order_count=(IFNULL(distribution_order_count,0)+1) WHERE id = #{distributionId}")
void addCanRebate(Double commissionFrozen, String distributionId);
", distribution_order_price=(IFNULL(distribution_order_price,0)+#{distributionOrderPrice}) " +
", distribution_order_count=(IFNULL(distribution_order_count,0)+1) " +
" WHERE id = #{distributionId}")
void addRebate(Double commissionFrozen, String distributionId, Double distributionOrderPrice);
@Update("UPDATE li_distribution SET commission_frozen = (IFNULL(commission_frozen,0) - #{rebate}) " +
",can_rebate=(IFNULL(can_rebate,0) + #{rebate}) " +
" WHERE id = #{distributionId}")
void addCanRebate(Double rebate, String distributionId);
@Update("UPDATE li_distribution SET can_rebate=(IFNULL(can_rebate,0) - #{rebate}),cash_rebate=(IFNULL(cash_rebate,0) + #{rebate}) " +
" WHERE id = #{distributionId}")
void addCashRebate(Double rebate, String distributionId);
@Update("UPDATE li_distribution SET cash_rebate=(IFNULL(cash_rebate,0) - #{rebate}) " +
" WHERE id = #{distributionId}")
void subCashRebate(Double rebate, String distributionId);
}

View File

@@ -3,6 +3,9 @@ package cn.lili.modules.distribution.mapper;
import cn.hutool.core.date.DateTime;
import cn.lili.modules.distribution.entity.dos.DistributionOrder;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.util.Date;
import java.util.List;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
/**
@@ -24,4 +27,15 @@ public interface DistributionOrderMapper extends BaseMapper<DistributionOrder> {
",d.commission_frozen =(ifnull(d.commission_frozen,0) -(SELECT SUM( dorder.rebate ) FROM li_distribution_order AS dorder WHERE dorder.distribution_order_status = #{distributionOrderStatus} AND dorder.settle_cycle< #{settleCycle} AND dorder.distribution_id = d.id ) )")
void rebate(String distributionOrderStatus, DateTime settleCycle);
/**
* 查询待结算的分销订单
* @return 待结算的分销订单
*/
@Select("UPDATE li_distribution_order distribution_order"
+ " INNER JOIN li_order_item oi ON oi.sn = distribution_order.order_item_sn"
+ " SET distribution_order.distribution_order_status = 'WAIT_BILL',"
+ " distribution_order.settle_cycle = #{settleCycle} "
+ " WHERE distribution_order.distribution_order_status = 'NO_COMPLETED'"
+ " AND oi.after_sale_status = 'EXPIRED';")
List<DistributionOrder> distributionSettlementOrder(Date settleCycle);
}

View File

@@ -8,6 +8,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpServletResponse;
/**
* 分销佣金业务层
*
@@ -40,6 +42,9 @@ public interface DistributionCashService extends IService<DistributionCash> {
*/
IPage<DistributionCash> getDistributionCash(DistributionCashSearchParams distributionCashSearchParams);
void queryExport(HttpServletResponse response,DistributionCashSearchParams distributionCashSearchParams);
/**
* 审核分销提现申请
*

View File

@@ -5,6 +5,7 @@ import cn.lili.modules.distribution.entity.dos.DistributionOrder;
import cn.lili.modules.distribution.entity.vos.DistributionOrderSearchParams;
import cn.lili.modules.order.aftersale.entity.dos.AfterSale;
import cn.lili.modules.order.order.entity.dos.OrderItem;
import cn.lili.modules.order.order.entity.dos.StoreFlow;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
@@ -45,22 +46,12 @@ public interface DistributionOrderService extends IService<DistributionOrder> {
/**
* 订单退款
* 记录分销订单
*
* @param afterSaleSn 售后单号
*/
void refundOrder(AfterSale afterSale);
/**
* 分销订单状态修改
*
* @param orderItems
* 分销订单完成
*/
void updateDistributionOrderStatus(List<OrderItem> orderItems);
void completeOrder(StoreFlow storeFlow);
/**
* 分销订单结算
* @param dateTime
* @param distributionOrderStatus
*/
void updateRebate(DateTime dateTime, String distributionOrderStatus);
}

View File

@@ -78,18 +78,42 @@ public interface DistributionService extends IService<Distribution> {
void checkDistributionSetting();
/**
* 修改可提现金额
*
* @param canRebate 修改金额
* @param distributionId 分销员ID
*/
void subCanRebate(Double canRebate, String distributionId);
/**
* 添加分销金额
* 添加分销冻结金额
* 创建分销订单时进行调用
*
* @param rebate 金额
* @param distributionId 分销员ID
* @param distributionOrderPrice 分销订单金额
*/
void addRebate(Double rebate, String distributionId);
void addRebate(Double rebate, String distributionId, Double distributionOrderPrice);
/**
* 扣减分销冻结金额
* 订单取消/退款时进行调用
*
* @param rebate 佣金
* @param distributionId 分销员ID
*/
void subRebate(Double rebate, String distributionId, Double distributionOrderPrice);
/**
* 添加分销可提现金额
* 订单完成时进行调用
* @param rebate 佣金
* @param distributionId 分销员ID
*/
void addCanRebate(Double rebate, String distributionId);
/**
* 添加提现金额
* @param rebate
* @param distributionId
*/
void addCashRebate(Double rebate, String distributionId);
/**
* 扣减提现金额
* @param rebate
* @param distributionId
*/
void subCashRebate(Double rebate, String distributionId);
}

View File

@@ -1,5 +1,12 @@
package cn.lili.modules.distribution.serviceimpl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.common.context.ThreadContextHolder;
import cn.lili.common.enums.ClientTypeEnum;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.properties.RocketmqCustomProperties;
@@ -13,6 +20,14 @@ import cn.lili.modules.distribution.entity.vos.DistributionCashSearchParams;
import cn.lili.modules.distribution.mapper.DistributionCashMapper;
import cn.lili.modules.distribution.service.DistributionCashService;
import cn.lili.modules.distribution.service.DistributionService;
import cn.lili.modules.order.order.entity.dto.OrderExportDTO;
import cn.lili.modules.order.order.entity.dto.OrderExportDetailDTO;
import cn.lili.modules.order.order.entity.dto.OrderSearchParams;
import cn.lili.modules.order.order.entity.dto.PriceDetailDTO;
import cn.lili.modules.order.order.entity.enums.OrderItemAfterSaleStatusEnum;
import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
import cn.lili.modules.order.order.entity.enums.OrderTypeEnum;
import cn.lili.modules.payment.entity.enums.PaymentMethodEnum;
import cn.lili.modules.wallet.entity.dto.MemberWalletUpdateDTO;
import cn.lili.modules.wallet.entity.dto.MemberWithdrawalMessage;
import cn.lili.modules.wallet.entity.enums.DepositServiceTypeEnum;
@@ -25,12 +40,23 @@ import cn.lili.rocketmq.tags.MemberTagsEnum;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
@@ -76,7 +102,7 @@ public class DistributionCashServiceImpl extends ServiceImpl<DistributionCashMap
distribution.setCommissionFrozen(CurrencyUtil.add(distribution.getCommissionFrozen(), applyMoney));
distributionService.updateById(distribution);
//提现申请记录
DistributionCash distributionCash = new DistributionCash("D" + SnowFlake.getId(), distribution.getId(), applyMoney, distribution.getMemberName());
DistributionCash distributionCash = new DistributionCash("D" + SnowFlake.getId(),applyMoney, distribution);
boolean result = this.save(distributionCash);
if (result) {
//发送提现消息
@@ -109,6 +135,28 @@ public class DistributionCashServiceImpl extends ServiceImpl<DistributionCashMap
return this.page(PageUtil.initPage(distributionCashSearchParams), distributionCashSearchParams.queryWrapper());
}
@Override
public void queryExport(HttpServletResponse response, DistributionCashSearchParams distributionCashSearchParams) {
XSSFWorkbook workbook = initExportData(this.list(distributionCashSearchParams.queryWrapper()));
try {
// 设置响应头
String fileName = URLEncoder.encode("分销提现列表", "UTF-8");
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
ServletOutputStream out = response.getOutputStream();
workbook.write(out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
workbook.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public DistributionCash audit(String id, String result) {
@@ -123,17 +171,12 @@ public class DistributionCashServiceImpl extends ServiceImpl<DistributionCashMap
//获取分销员
Distribution distribution = distributionService.getById(distributorCash.getDistributionId());
if (distribution != null && distribution.getDistributionStatus().equals(DistributionStatusEnum.PASS.name())) {
MemberWithdrawalMessage memberWithdrawalMessage = new MemberWithdrawalMessage();
//审核通过
if (result.equals(WithdrawStatusEnum.VIA_AUDITING.name())) {
memberWithdrawalMessage.setStatus(WithdrawStatusEnum.VIA_AUDITING.name());
//分销记录操作
distributorCash.setDistributionCashStatus(WithdrawStatusEnum.VIA_AUDITING.name());
distributorCash.setPayTime(new Date());
//提现到余额
memberWalletService.increase(new MemberWalletUpdateDTO(distributorCash.getPrice(), distribution.getMemberId(), "分销[" + distributorCash.getSn() + "]佣金提现到余额[" + distributorCash.getPrice() + "]", DepositServiceTypeEnum.WALLET_COMMISSION.name()));
} else {
memberWithdrawalMessage.setStatus(WithdrawStatusEnum.FAIL_AUDITING.name());
//分销员可提现金额退回
distribution.setCanRebate(CurrencyUtil.add(distribution.getCanRebate(), distributorCash.getPrice()));
distributorCash.setDistributionCashStatus(WithdrawStatusEnum.FAIL_AUDITING.name());
@@ -142,14 +185,7 @@ public class DistributionCashServiceImpl extends ServiceImpl<DistributionCashMap
//分销员金额相关处理
distributionService.updateById(distribution);
//修改分销提现申请
boolean bool = this.updateById(distributorCash);
//if (bool) {
// //组织会员提现审核消息
// memberWithdrawalMessage.setMemberId(distribution.getMemberId());
// memberWithdrawalMessage.setPrice(distributorCash.getPrice());
// String destination = rocketmqCustomProperties.getMemberTopic() + ":" + MemberTagsEnum.MEMBER_WITHDRAWAL.name();
// rocketMQTemplate.asyncSend(destination, memberWithdrawalMessage, RocketmqSendCallbackBuilder.commonCallback());
//}
this.updateById(distributorCash);
return distributorCash;
}
throw new ServiceException(ResultCode.DISTRIBUTION_NOT_EXIST);
@@ -157,4 +193,38 @@ public class DistributionCashServiceImpl extends ServiceImpl<DistributionCashMap
throw new ServiceException(ResultCode.DISTRIBUTION_CASH_NOT_EXIST);
}
/**
* 初始化填充导出数据
*
* @param distributionCashList 导出的数据
* @return 填充导出数据
*/
private XSSFWorkbook initExportData(List<DistributionCash> distributionCashList) {
XSSFWorkbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("订单列表");
// 创建表头
Row header = sheet.createRow(0);
String[] headers = {"编号", "姓名", "身份证号", "结算银行开户行名称", "结算银行开户账号", "结算银行开户支行名称"};
for (int i = 0; i < headers.length; i++) {
Cell cell = header.createCell(i);
cell.setCellValue(headers[i]);
}
// 填充数据
for (int i = 0; i < distributionCashList.size(); i++) {
DistributionCash distributionCash = distributionCashList.get(i);
Row row = sheet.createRow(i + 1);
row.createCell(0).setCellValue(distributionCash.getSn());
row.createCell(1).setCellValue(distributionCash.getName());
row.createCell(2).setCellValue(distributionCash.getIdNumber());
row.createCell(3).setCellValue(distributionCash.getSettlementBankAccountName());
row.createCell(4).setCellValue(distributionCash.getSettlementBankAccountNum());
row.createCell(5).setCellValue(distributionCash.getSettlementBankBranchName());
}
return workbook;
}
}

View File

@@ -1,33 +1,23 @@
package cn.lili.modules.distribution.serviceimpl;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.common.utils.SpringContextUtil;
import cn.lili.modules.distribution.entity.dos.Distribution;
import cn.lili.modules.distribution.entity.dos.DistributionOrder;
import cn.lili.modules.distribution.entity.enums.DistributionOrderStatusEnum;
import cn.lili.modules.distribution.entity.enums.DistributionStatusEnum;
import cn.lili.modules.distribution.entity.vos.DistributionOrderSearchParams;
import cn.lili.modules.distribution.mapper.DistributionOrderMapper;
import cn.lili.modules.distribution.service.DistributionOrderService;
import cn.lili.modules.distribution.service.DistributionService;
import cn.lili.modules.order.aftersale.entity.dos.AfterSale;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dos.OrderItem;
import cn.lili.modules.order.order.entity.dos.StoreFlow;
import cn.lili.modules.order.order.entity.dto.StoreFlowProfitSharingDTO;
import cn.lili.modules.order.order.entity.dto.StoreFlowQueryDTO;
import cn.lili.modules.order.order.entity.enums.OrderItemAfterSaleStatusEnum;
import cn.lili.modules.order.order.entity.enums.FlowTypeEnum;
import cn.lili.modules.order.order.entity.enums.PayStatusEnum;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.order.order.service.StoreFlowService;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.DistributionSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import cn.lili.mybatis.util.PageUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -39,12 +29,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 分销订单接口实现
@@ -54,7 +40,8 @@ import java.util.stream.Collectors;
*/
@Slf4j
@Service
public class DistributionOrderServiceImpl extends ServiceImpl<DistributionOrderMapper, DistributionOrder> implements DistributionOrderService {
public class DistributionOrderServiceImpl extends ServiceImpl<DistributionOrderMapper, DistributionOrder>
implements DistributionOrderService {
/**
* 订单
@@ -71,15 +58,12 @@ public class DistributionOrderServiceImpl extends ServiceImpl<DistributionOrderM
*/
@Autowired
private DistributionService distributionService;
/**
* 系统设置
*/
@Autowired
private SettingService settingService;
@Override
public IPage<DistributionOrder> getDistributionOrderPage(DistributionOrderSearchParams distributionOrderSearchParams) {
return this.page(PageUtil.initPage(distributionOrderSearchParams), distributionOrderSearchParams.queryWrapper());
public IPage<DistributionOrder> getDistributionOrderPage(
DistributionOrderSearchParams distributionOrderSearchParams) {
return this.page(PageUtil.initPage(distributionOrderSearchParams),
distributionOrderSearchParams.queryWrapper());
}
@@ -100,8 +84,8 @@ public class DistributionOrderServiceImpl extends ServiceImpl<DistributionOrderM
//判断是否为分销订单,如果为分销订单则获取分销佣金
if (order.getDistributionId() != null) {
//根据订单编号获取有分销金额的店铺流水记录
List<StoreFlow> storeFlowList = storeFlowService
.listStoreFlow(StoreFlowQueryDTO.builder().justDistribution(true).orderSn(orderSn).build());
List<StoreFlow> storeFlowList = storeFlowService.listStoreFlow(
StoreFlowQueryDTO.builder().justDistribution(true).orderSn(orderSn).build());
double rebate = 0.0;
//循环店铺流水记录判断是否包含分销商品
//包含分销商品则进行记录分销订单、计算分销总额
@@ -116,39 +100,21 @@ public class DistributionOrderServiceImpl extends ServiceImpl<DistributionOrderM
Distribution distribution = distributionService.getById(order.getDistributionId());
distributionOrder.setDistributionName(distribution.getMemberName());
//设置结算天数(解冻日期)
Setting setting = settingService.get(SettingEnum.DISTRIBUTION_SETTING.name());
DistributionSetting distributionSetting = JSONUtil.toBean(setting.getSettingValue(), DistributionSetting.class);
//添加分销订单
this.save(distributionOrder);
//记录会员的分销总额
if (rebate != 0.0) {
distributionService.addRebate(rebate, order.getDistributionId());
//如果天数写0则立即进行结算
// if (distributionSetting.getCashDay().equals(0)) {
// DateTime dateTime = new DateTime();
// dateTime = dateTime.offsetNew(DateField.DAY_OF_MONTH, -distributionSetting.getCashDay());
// //防止事务失效采用上下文获取bean
// DistributionOrderService bean = SpringContextUtil.getBean(DistributionOrderService.class);
// //分销订单结算
// bean.updateRebate(dateTime, DistributionOrderStatusEnum.WAIT_BILL.name());
// }
distributionService.addRebate(rebate, order.getDistributionId(), storeFlow.getFinalPrice());
}
}
}
}
/**
* 1.获取订单判断是否为已付款的分销订单
* 2.查看店铺流水记录分销佣金
* 3.修改分销员的分销总金额、可提现金额
* 1.获取订单判断是否为已付款的分销订单 2.查看店铺流水记录分销佣金 3.修改分销员的分销总金额、可提现金额
*
* @param orderSn 订单编号
*/
@@ -162,41 +128,35 @@ public class DistributionOrderServiceImpl extends ServiceImpl<DistributionOrderM
if (order.getDistributionId() != null && order.getPayStatus().equals(PayStatusEnum.PAID.name())) {
//根据订单编号获取有分销金额的店铺流水记录
List<DistributionOrder> distributionOrderList = this.list(new LambdaQueryWrapper<DistributionOrder>()
.eq(DistributionOrder::getOrderSn, orderSn));
List<DistributionOrder> distributionOrderList =
this.list(new LambdaQueryWrapper<DistributionOrder>().eq(DistributionOrder::getOrderSn, orderSn));
//如果没有分销定单,则直接返回
if (distributionOrderList.isEmpty()) {
return;
}
//分销金额
double rebate = 0.0;
//包含分销商品则进行记录分销订单、计算分销总额
for (DistributionOrder distributionOrder : distributionOrderList) {
rebate = CurrencyUtil.add(rebate, distributionOrder.getRebate());
}
//如果包含分销商品则记录会员的分销总额
if (rebate != 0.0) {
distributionService.subCanRebate(CurrencyUtil.sub(0, rebate), order.getDistributionId());
distributionService.subRebate(distributionOrder.getRebate(), order.getDistributionId(), distributionOrder.getSellBackRebate());
}
}
//修改分销订单的状态
this.update(new LambdaUpdateWrapper<DistributionOrder>().eq(DistributionOrder::getOrderSn, orderSn)
.set(DistributionOrder::getDistributionOrderStatus, DistributionOrderStatusEnum.CANCEL.name()));
.set(DistributionOrder::getDistributionOrderStatus, DistributionOrderStatusEnum.REFUND.name()));
}
@Override
public void refundOrder(AfterSale afterSale) {
//判断是否为分销订单
StoreFlow refundStoreFlow = storeFlowService.queryOne(StoreFlowQueryDTO.builder().justDistribution(true).refundSn(afterSale.getSn()).build());
StoreFlow refundStoreFlow = storeFlowService.queryOne(
StoreFlowQueryDTO.builder().justDistribution(true).refundSn(afterSale.getSn()).build());
if (refundStoreFlow != null) {
//获取收款分销订单
DistributionOrder distributionOrder = this.getOne(new LambdaQueryWrapper<DistributionOrder>()
.eq(DistributionOrder::getOrderItemSn, afterSale.getOrderItemSn()));
DistributionOrder distributionOrder = this.getOne(
new LambdaQueryWrapper<DistributionOrder>().eq(DistributionOrder::getOrderItemSn,
afterSale.getOrderItemSn()));
//分销订单不存在,则直接返回
if (distributionOrder == null) {
return;
@@ -204,143 +164,41 @@ public class DistributionOrderServiceImpl extends ServiceImpl<DistributionOrderM
if (distributionOrder.getSellBackRebate() == null) {
distributionOrder.setSellBackRebate(refundStoreFlow.getDistributionRebate());
} else {
distributionOrder.setSellBackRebate(CurrencyUtil.add(distributionOrder.getSellBackRebate(), refundStoreFlow.getDistributionRebate()));
distributionOrder.setSellBackRebate(
CurrencyUtil.add(distributionOrder.getSellBackRebate(), refundStoreFlow.getDistributionRebate()));
}
distributionOrder.setRebate(CurrencyUtil.sub(distributionOrder.getRebate(), refundStoreFlow.getDistributionRebate()));
if (distributionOrder.getRebate() == 0) {
distributionOrder.setDistributionOrderStatus(DistributionOrderStatusEnum.REFUND.name());
}
distributionOrder.setRefundNum(distributionOrder.getRefundNum() + afterSale.getNum());
this.updateById(distributionOrder);
// 修改分销员提成金额
distributionService.subCanRebate(CurrencyUtil.sub(0, refundStoreFlow.getDistributionRebate()), distributionOrder.getDistributionId());
if (refundStoreFlow.getDistributionRebate() != 0.0) {
distributionService.subRebate(refundStoreFlow.getDistributionRebate(), distributionOrder.getDistributionId(), refundStoreFlow.getFinalPrice());
}
}
}
@Override
public void updateDistributionOrderStatus(List<OrderItem> orderItems) {
if (orderItems.isEmpty()) {
return;
public void completeOrder(StoreFlow storeFlow) {
if (storeFlow.getFlowType().equals(FlowTypeEnum.PAY.name())
&&storeFlow.getDistributionRebate() != null
&& storeFlow.getDistributionRebate() != 0) {
//获取分账内容
StoreFlowProfitSharingDTO storeFlowProfitSharingDTO = JSONUtil.toBean(storeFlow.getProfitSharing(), StoreFlowProfitSharingDTO.class);
//获取分销订单
DistributionOrder distributionOrder = this.getOne(new LambdaQueryWrapper<DistributionOrder>().eq(DistributionOrder::getOrderItemSn, storeFlow.getOrderItemSn()));
//解冻分销金额
distributionService.addCanRebate(storeFlowProfitSharingDTO.getDistributionPrice(), distributionOrder.getDistributionId());
// 订单完成
this.update(new LambdaUpdateWrapper<DistributionOrder>()
.eq(DistributionOrder::getId, distributionOrder.getId())
.set(DistributionOrder::getDistributionOrderStatus, DistributionOrderStatusEnum.COMPLETE.name()));
}
//获取未完成分销订单
List<DistributionOrder> distributionOrderList = this.list(new LambdaQueryWrapper<DistributionOrder>()
.eq(DistributionOrder::getDistributionOrderStatus, DistributionOrderStatusEnum.NO_COMPLETED.name()));
if (distributionOrderList.isEmpty()) {
return;
}
List<DistributionOrder> list = ListUtil.list(false);
orderItems.stream().forEach(orderItem -> {
//订单售后状态为已失效并且投诉状态为已失效
if (StrUtil.equals(OrderItemAfterSaleStatusEnum.EXPIRED.name(), orderItem.getAfterSaleStatus())) {
List<DistributionOrder> collect = distributionOrderList.stream()
.filter(distributionOrder -> StrUtil.equals(distributionOrder.getOrderItemSn(), orderItem.getSn()))
.map((distributionOrder) -> {
distributionOrder.setDistributionOrderStatus(DistributionOrderStatusEnum.WAIT_BILL.name());
distributionOrder.setSettleCycle(new Date());
return distributionOrder;
})
.collect(Collectors.toList());
list.addAll(collect);
}
});
if (!list.isEmpty()) {
//批量修改分销订单结算状态
this.updateBatchById(list);
}
}
@Override
public void updateRebate(DateTime dateTime, String distributionOrderStatus) {
//结算时间延后五分钟
dateTime = dateTime.offsetNew(DateField.MINUTE, 5);
//获取待结算订单
List<DistributionOrder> distributionOrderList = this.list(new LambdaQueryWrapper<DistributionOrder>()
.eq(DistributionOrder::getDistributionOrderStatus, distributionOrderStatus)
.isNotNull(DistributionOrder::getSettleCycle)
.le(DistributionOrder::getSettleCycle, dateTime));
//校验待结算订单
if (ObjectUtil.isNotNull(distributionOrderList) && distributionOrderList.size() > 0) {
//结算分销人员信息列表
List<Distribution> distributionUpdateList = new ArrayList<>();
//获取分销员信息
List<Distribution> distributionList = distributionService.list(new LambdaQueryWrapper<Distribution>()
.eq(Distribution::getDistributionStatus, DistributionStatusEnum.PASS.name()));
//根据销人员获取对应分销订单
Map<String, List<DistributionOrder>> distributionOrderList1 = distributionOrderList.stream()
.collect(Collectors.groupingBy(DistributionOrder::getDistributionId));
//校验分销订单不为空
if (ObjectUtil.isNotNull(distributionOrderList1) && distributionOrderList1.size() > 0) {
//遍历分销订单map
distributionOrderList1.forEach((key, value) -> {
//计算分销结算金额
distributionUpdateList.add(checkDistribution(key, value, distributionList));
});
}
//校验分销信息列表不为空
if (ObjectUtil.isNotNull(distributionUpdateList) && !distributionUpdateList.isEmpty()) {
//修改分销员收益
distributionService.updateBatchById(distributionUpdateList);
distributionOrderList.stream().forEach(distributionOrder -> {
//修改分销订单状态为待提现
distributionOrder.setDistributionOrderStatus(DistributionOrderStatusEnum.WAIT_CASH.name());
});
}
//修改分销订单状态
this.updateBatchById(distributionOrderList);
}
}
/**
* 计算分销结算金额
*
* @param distributionId 分销ID
* @param list 分销订单
* @param distributionList 分销列表
* @return
*/
public Distribution checkDistribution(String
distributionId, List<DistributionOrder> list, List<Distribution> distributionList) {
//获取所有待结算订单分销人员信息
Distribution distribution = distributionList.parallelStream().filter(a -> StrUtil.equals(a.getId(), distributionId)).collect(Collectors.toList()).get(0);
//获取分销订单总金额
double rebate = list.stream().mapToDouble(DistributionOrder::getRebate).sum();
//检验单分销人员冻结金额为负数时.扣除负数冻结金额后再结算
if (distribution.getCommissionFrozen() < 0) {
rebate = CurrencyUtil.add(distribution.getCommissionFrozen() == null ? 0.0 : distribution.getCommissionFrozen(), rebate);
}
//结算订单总金额+分销可提现金额
Double canRebate = CurrencyUtil.add(rebate, distribution.getCanRebate() == null ? 0.0 : distribution.getCanRebate());
//结算金额小于0
if (canRebate < 0) {
//结算订单总金额+分销可提现金额
distribution.setCanRebate(0.0);
//冻结金额
distribution.setCommissionFrozen(canRebate);
} else {
//结算订单总金额+分销可提现金额
distribution.setCanRebate(canRebate);
//冻结金额
distribution.setCommissionFrozen(0.0);
}
return distribution;
}
}

View File

@@ -181,14 +181,30 @@ public class DistributionServiceImpl extends ServiceImpl<DistributionMapper, Dis
}
}
@Override
public void subCanRebate(Double canRebate, String distributionId) {
this.baseMapper.subCanRebate(canRebate, distributionId);
public void subRebate(Double canRebate, String distributionId, Double distributionOrderPrice) {
this.baseMapper.subRebate(canRebate, distributionId, distributionOrderPrice);
}
@Override
public void addRebate(Double rebate, String distributionId) {
public void addRebate(Double rebate, String distributionId, Double distributionOrderPrice) {
this.baseMapper.addRebate(rebate, distributionId, distributionOrderPrice);
}
@Override
public void addCanRebate(Double rebate, String distributionId) {
this.baseMapper.addCanRebate(rebate, distributionId);
}
@Override
public void addCashRebate(Double rebate, String distributionId) {
this.baseMapper.addCashRebate(rebate, distributionId);
}
@Override
public void subCashRebate(Double rebate, String distributionId) {
this.baseMapper.subCashRebate(rebate, distributionId);
}
}

View File

@@ -31,6 +31,13 @@ public interface FileService extends IService<File> {
*/
void batchDeleteByDirectory(String directoryId);
/**
* 根据文件夹ID查看是否有文件
* @param directoryId 文件夹ID
* @return
*/
Boolean countByDirectory(String directoryId);
/**
* 所有者批量删除
*

View File

@@ -4,8 +4,6 @@ import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.AuthUser;
import cn.lili.common.vo.PageVO;
import cn.lili.common.vo.SearchVO;
import cn.lili.modules.file.entity.File;
import cn.lili.modules.file.entity.dto.FileOwnerDTO;
import cn.lili.modules.file.mapper.FileMapper;
@@ -15,11 +13,10 @@ import cn.lili.mybatis.util.PageUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 文件管理业务层实现
@@ -42,7 +39,9 @@ public class FileServiceImpl extends ServiceImpl<FileMapper, File> implements Fi
List<File> files = this.list(queryWrapper);
List<String> keys = new ArrayList<>();
files.forEach(item -> keys.add(item.getFileKey()));
if (!keys.isEmpty()) {
filePluginFactory.filePlugin().deleteFile(keys);
}
this.remove(queryWrapper);
}
@@ -54,10 +53,17 @@ public class FileServiceImpl extends ServiceImpl<FileMapper, File> implements Fi
List<File> files = this.list(queryWrapper);
List<String> keys = new ArrayList<>();
files.forEach(item -> keys.add(item.getFileKey()));
if (!keys.isEmpty()) {
filePluginFactory.filePlugin().deleteFile(keys);
}
this.remove(queryWrapper);
}
@Override
public Boolean countByDirectory(String directoryId) {
return this.count(new LambdaQueryWrapper<File>().eq(File::getFileDirectoryId, directoryId))>0;
}
@Override
public void batchDelete(List<String> ids, AuthUser authUser) {
LambdaQueryWrapper<File> queryWrapper = new LambdaQueryWrapper<>();
@@ -88,26 +94,33 @@ public class FileServiceImpl extends ServiceImpl<FileMapper, File> implements Fi
public IPage<File> customerPage(FileOwnerDTO fileOwnerDTO) {
LambdaQueryWrapper<File> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.like(CharSequenceUtil.isNotEmpty(fileOwnerDTO.getName()), File::getName, fileOwnerDTO.getName())
.like(CharSequenceUtil.isNotEmpty(fileOwnerDTO.getOwnerName()), File::getOwnerName, fileOwnerDTO.getOwnerName())
.eq(CharSequenceUtil.isNotEmpty(fileOwnerDTO.getFileDirectoryId()),File::getFileDirectoryId, fileOwnerDTO.getFileDirectoryId())
.like(CharSequenceUtil.isNotEmpty(fileOwnerDTO.getOwnerName()), File::getOwnerName,
fileOwnerDTO.getOwnerName())
.eq(CharSequenceUtil.isNotEmpty(fileOwnerDTO.getFileDirectoryId()), File::getFileDirectoryId,
fileOwnerDTO.getFileDirectoryId())
.like(CharSequenceUtil.isNotEmpty(fileOwnerDTO.getFileKey()), File::getFileKey, fileOwnerDTO.getFileKey())
.like(CharSequenceUtil.isNotEmpty(fileOwnerDTO.getFileType()), File::getFileType, fileOwnerDTO.getFileType())
.between(CharSequenceUtil.isNotEmpty(fileOwnerDTO.getStartDate()) && CharSequenceUtil.isNotEmpty(fileOwnerDTO.getEndDate()),
File::getCreateTime, fileOwnerDTO.getStartDate(), fileOwnerDTO.getEndDate());
.like(CharSequenceUtil.isNotEmpty(fileOwnerDTO.getFileType()), File::getFileType,
fileOwnerDTO.getFileType()).between(
CharSequenceUtil.isNotEmpty(fileOwnerDTO.getStartDate()) && CharSequenceUtil.isNotEmpty(
fileOwnerDTO.getEndDate()), File::getCreateTime, fileOwnerDTO.getStartDate(),
fileOwnerDTO.getEndDate());
return this.page(PageUtil.initPage(fileOwnerDTO), queryWrapper);
}
@Override
public IPage<File> customerPageOwner(FileOwnerDTO fileOwnerDTO) {
LambdaQueryWrapper<File> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(CharSequenceUtil.isNotEmpty(fileOwnerDTO.getOwnerId()), File::getOwnerId, fileOwnerDTO.getOwnerId())
.eq(File::getUserEnums, fileOwnerDTO.getUserEnums())
.eq(CharSequenceUtil.isNotEmpty(fileOwnerDTO.getFileDirectoryId()),File::getFileDirectoryId, fileOwnerDTO.getFileDirectoryId())
queryWrapper.eq(CharSequenceUtil.isNotEmpty(fileOwnerDTO.getOwnerId()), File::getOwnerId,
fileOwnerDTO.getOwnerId()).eq(File::getUserEnums, fileOwnerDTO.getUserEnums())
.eq(CharSequenceUtil.isNotEmpty(fileOwnerDTO.getFileDirectoryId()), File::getFileDirectoryId,
fileOwnerDTO.getFileDirectoryId())
.like(CharSequenceUtil.isNotEmpty(fileOwnerDTO.getName()), File::getName, fileOwnerDTO.getName())
.like(CharSequenceUtil.isNotEmpty(fileOwnerDTO.getFileKey()), File::getFileKey, fileOwnerDTO.getFileKey())
.like(CharSequenceUtil.isNotEmpty(fileOwnerDTO.getFileType()), File::getFileType, fileOwnerDTO.getFileType())
.between(CharSequenceUtil.isNotEmpty(fileOwnerDTO.getStartDate()) && CharSequenceUtil.isNotEmpty(fileOwnerDTO.getEndDate()),
File::getCreateTime, fileOwnerDTO.getStartDate(), fileOwnerDTO.getEndDate());
.like(CharSequenceUtil.isNotEmpty(fileOwnerDTO.getFileType()), File::getFileType,
fileOwnerDTO.getFileType()).between(
CharSequenceUtil.isNotEmpty(fileOwnerDTO.getStartDate()) && CharSequenceUtil.isNotEmpty(
fileOwnerDTO.getEndDate()), File::getCreateTime, fileOwnerDTO.getStartDate(),
fileOwnerDTO.getEndDate());
return this.page(PageUtil.initPage(fileOwnerDTO), queryWrapper);
}
}

View File

@@ -27,6 +27,7 @@ public class GoodsSearchParams extends PageVO {
private static final long serialVersionUID = 2544015852728566887L;
@ApiModelProperty(value = "商品编号")
private String goodsId;

View File

@@ -23,4 +23,19 @@ public class GoodsSkuStockDTO {
@ApiModelProperty(value = "预警库存")
private Integer alertQuantity;
@ApiModelProperty(value = "规格信息")
private String simpleSpecs;
@ApiModelProperty(value = "商品编号")
private String sn;
@ApiModelProperty(value = "商品名称")
private String goodsName;
/**
* @see cn.lili.modules.goods.entity.enums.GoodsStockTypeEnum
*/
@ApiModelProperty(value = "类型")
private String type;
}

View File

@@ -0,0 +1,32 @@
package cn.lili.modules.goods.entity.enums;
/**
* 库存操作类型
*/
public enum GoodsStockTypeEnum {
SUB(""),
ADD("");
private final String description;
GoodsStockTypeEnum(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
// 根据描述获取枚举实例
public static GoodsStockTypeEnum fromDescription(String description) {
for (GoodsStockTypeEnum type : GoodsStockTypeEnum.values()) {
if (type.getDescription().equals(description)) {
return type;
}
}
throw new IllegalArgumentException("No matching enum constant for description: " + description);
}
}

View File

@@ -3,6 +3,8 @@ package cn.lili.modules.goods.mapper;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.dto.GoodsSkuDTO;
import cn.lili.modules.goods.entity.dto.GoodsSkuStockDTO;
import cn.lili.modules.order.order.entity.dto.OrderExportDTO;
import cn.lili.modules.order.order.entity.vo.OrderSimpleVO;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -115,6 +117,7 @@ public interface GoodsSkuMapper extends BaseMapper<GoodsSku> {
@Select("SELECT *,g.params as params FROM li_goods_sku gs inner join li_goods g on gs.goods_id = g.id ${ew.customSqlSegment}")
IPage<GoodsSkuDTO> queryByParams(IPage<GoodsSkuDTO> page, @Param(Constants.WRAPPER) Wrapper<GoodsSkuDTO> queryWrapper);
@Select("SELECT id as sku_id, quantity, goods_id FROM li_goods_sku ${ew.customSqlSegment}")
@Select("SELECT id as sku_id, quantity, goods_id,simple_specs,sn,goods_name FROM li_goods_sku ${ew.customSqlSegment}")
List<GoodsSkuStockDTO> queryStocks(@Param(Constants.WRAPPER) Wrapper<GoodsSku> queryWrapper);
}

View File

@@ -28,13 +28,6 @@ public interface GoodsService extends IService<Goods> {
*/
List<Goods> getByBrandIds(List<String> brandIds);
/**
* 下架所有商家商品
*
* @param storeId 店铺ID
*/
void underStoreGoods(String storeId);
/**
* 更新商品参数
*
@@ -113,16 +106,6 @@ public interface GoodsService extends IService<Goods> {
Boolean updateGoodsMarketAble(List<String> goodsIds, GoodsStatusEnum goodsStatusEnum, String underReason);
/**
* 更新商品上架状态状态
*
* @param storeId 店铺ID
* @param goodsStatusEnum 更新的商品状态
* @param underReason 下架原因
* @return 更新结果
*/
Boolean updateGoodsMarketAbleByStoreId(String storeId, GoodsStatusEnum goodsStatusEnum, String underReason);
/**
* 更新商品上架状态状态
*
@@ -177,12 +160,6 @@ public interface GoodsService extends IService<Goods> {
* @param store
*/
void updateStoreDetail(Store store);
/**
* 统计店铺的商品数量
* @param storeId 店铺id
* @return
*/
long countStoreGoodsNum(String storeId);
/**
* 同步商品分类名称

View File

@@ -12,7 +12,9 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
@@ -146,7 +148,20 @@ public interface GoodsSkuService extends IService<GoodsSku> {
* @return 商品sku信息
*/
IPage<GoodsSku> getGoodsSkuByPage(GoodsSearchParams searchParams);
/**
* 查询导出商品库存
*
* @param searchParams 查询参数
* @return 导出商品库存
*/
void queryExportStock(HttpServletResponse response, GoodsSearchParams searchParams);
/**
* 导入商品库存
* @param storeId 店铺ID
* @param files 文件
*/
void importStock(String storeId, MultipartFile files);
/**
* 分页查询商品sku信息
@@ -187,6 +202,7 @@ public interface GoodsSkuService extends IService<GoodsSku> {
* @param goodsSkuStockDTOS sku库存修改实体
*/
void updateStocks(List<GoodsSkuStockDTO> goodsSkuStockDTOS);
void updateStocksByType(List<GoodsSkuStockDTO> goodsSkuStockDTOS);
/**
* 更新SKU预警库存
@@ -207,6 +223,7 @@ public interface GoodsSkuService extends IService<GoodsSku> {
* @param quantity 设置的库存数量
*/
void updateStock(String skuId, Integer quantity);
void updateStock(String skuId, Integer quantity,String type);
/**
* 获取商品sku库存
@@ -279,4 +296,13 @@ public interface GoodsSkuService extends IService<GoodsSku> {
* @return 库存数量
*/
Integer getGoodsStock(String goodsId);
/**
* 更新sku运费模版
*
* @param goodsId 商品id
* @param templateId 运费模版id
* @return 操作结果
*/
Boolean freight(List<String> goodsId, String templateId);
}

View File

@@ -114,7 +114,7 @@ public class GoodsImportServiceImpl implements GoodsImportService {
List<String> freightTemplateNameList = new ArrayList<>();
//循环列表存放ID-运费模板名称
for (FreightTemplateVO freightTemplateVO : freightTemplateService.getFreightTemplateList(storeId)) {
for (FreightTemplateVO freightTemplateVO : freightTemplateService.getFreightTemplateList()) {
freightTemplateNameList.add(freightTemplateVO.getId() + "-" + freightTemplateVO.getName());
}

View File

@@ -35,6 +35,7 @@ import cn.lili.modules.store.service.FreightTemplateService;
import cn.lili.modules.store.service.StoreService;
import cn.lili.modules.system.aspect.annotation.SystemLogPoint;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.BaseSetting;
import cn.lili.modules.system.entity.dto.GoodsSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
@@ -128,19 +129,6 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
return list(lambdaQueryWrapper);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void underStoreGoods(String storeId) {
//获取商品ID列表
List<String> list = this.baseMapper.getGoodsIdByStoreId(storeId);
//下架店铺下的商品
this.updateGoodsMarketAbleByStoreId(storeId, GoodsStatusEnum.DOWN, "店铺关闭");
applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("下架商品",
rocketmqCustomProperties.getGoodsTopic(), GoodsTagsEnum.DOWN.name(), JSONUtil.toJsonStr(list)));
}
/**
* 更新商品参数
*
@@ -339,29 +327,6 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
return result;
}
/**
* 更新商品上架状态状态
*
* @param storeId 店铺ID
* @param goodsStatusEnum 更新的商品状态
* @param underReason 下架原因
* @return 更新结果
*/
@Override
@SystemLogPoint(description = "店铺关闭下架商品", customerLog = "'操作类型:['+#goodsStatusEnum+'],操作对象:['+#storeId+'],操作原因:['+#underReason+']'")
public Boolean updateGoodsMarketAbleByStoreId(String storeId, GoodsStatusEnum goodsStatusEnum, String underReason) {
LambdaUpdateWrapper<Goods> updateWrapper = this.getUpdateWrapperByStoreAuthority();
updateWrapper.set(Goods::getMarketEnable, goodsStatusEnum.name());
updateWrapper.set(Goods::getUnderMessage, underReason);
updateWrapper.eq(Goods::getStoreId, storeId);
boolean result = this.update(updateWrapper);
//修改规格商品
this.goodsSkuService.updateGoodsSkuStatusByStoreId(storeId, goodsStatusEnum.name(), null);
return result;
}
@Override
@SystemLogPoint(description = "管理员关闭下架商品", customerLog = "'操作类型:['+#goodsStatusEnum+'],操作对象:['+#goodsIds+'],操作原因:['+#underReason+']'")
@@ -429,7 +394,7 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
if (freightTemplate == null) {
throw new ServiceException(ResultCode.FREIGHT_TEMPLATE_NOT_EXIST);
}
if (authUser != null && !freightTemplate.getStoreId().equals(authUser.getStoreId())) {
if (authUser != null) {
throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR);
}
LambdaUpdateWrapper<Goods> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
@@ -437,6 +402,7 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
lambdaUpdateWrapper.in(Goods::getId, goodsIds);
List<String> goodsCache = goodsIds.stream().map(item -> CachePrefix.GOODS.getPrefix() + item).collect(Collectors.toList());
cache.multiDel(goodsCache);
goodsSkuService.freight(goodsIds, templateId);
return this.update(lambdaUpdateWrapper);
}
@@ -515,16 +481,6 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
goodsSkuService.update(updateWrapper);
}
@Override
public long countStoreGoodsNum(String storeId) {
return this.count(
new LambdaQueryWrapper<Goods>()
.eq(Goods::getStoreId, storeId)
.eq(Goods::getDeleteFlag, Boolean.FALSE)
.eq(Goods::getAuthFlag, GoodsAuthEnum.PASS.name())
.eq(Goods::getMarketEnable, GoodsStatusEnum.UPPER.name()));
}
@Override
public void categoryGoodsName(String categoryId) {
//获取分类下的商品
@@ -662,20 +618,14 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
//获取商品系统配置决定是否审核
Setting setting = settingService.get(SettingEnum.GOODS_SETTING.name());
GoodsSetting goodsSetting = JSONUtil.toBean(setting.getSettingValue(), GoodsSetting.class);
Setting baseSetting = settingService.get(SettingEnum.BASE_SETTING.name());
BaseSetting baseSettingValue = JSONUtil.toBean(baseSetting.getSettingValue(), BaseSetting.class);
//是否需要审核
goods.setAuthFlag(Boolean.TRUE.equals(goodsSetting.getGoodsCheck()) ? GoodsAuthEnum.TOBEAUDITED.name() : GoodsAuthEnum.PASS.name());
//判断当前用户是否为店铺
if (Objects.requireNonNull(UserContext.getCurrentUser()).getRole().equals(UserEnums.STORE)) {
StoreVO storeDetail = this.storeService.getStoreDetail();
if (storeDetail.getSelfOperated() != null) {
goods.setSelfOperated(storeDetail.getSelfOperated());
}
goods.setStoreId(storeDetail.getId());
goods.setStoreName(storeDetail.getStoreName());
goods.setSelfOperated(storeDetail.getSelfOperated());
} else {
throw new ServiceException(ResultCode.STORE_NOT_LOGIN_ERROR);
}
//平台商品,默认处理
goods.setStoreId("-1");
goods.setStoreName(baseSettingValue.getSiteName());
goods.setSelfOperated(true);
}
/**
@@ -703,7 +653,7 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
LambdaUpdateWrapper<Goods> updateWrapper = new LambdaUpdateWrapper<>();
AuthUser authUser = this.checkStoreAuthority();
if (authUser != null) {
updateWrapper.eq(Goods::getStoreId, authUser.getStoreId());
updateWrapper.eq(Goods::getStoreId, "-1");
}
return updateWrapper;
}
@@ -717,7 +667,7 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
private AuthUser checkStoreAuthority() {
AuthUser currentUser = UserContext.getCurrentUser();
//如果当前会员不为空,且为店铺角色
if (currentUser != null && (currentUser.getRole().equals(UserEnums.STORE) && currentUser.getStoreId() != null)) {
if (currentUser != null) {
return currentUser;
}
return null;
@@ -747,7 +697,7 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
LambdaQueryWrapper<Goods> queryWrapper = new LambdaQueryWrapper<>();
AuthUser authUser = this.checkStoreAuthority();
if (authUser != null) {
queryWrapper.eq(Goods::getStoreId, authUser.getStoreId());
queryWrapper.eq(Goods::getStoreId, "-1");
}
return queryWrapper;
}

View File

@@ -1,6 +1,8 @@
package cn.lili.modules.goods.serviceimpl;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.lili.cache.Cache;
@@ -23,6 +25,7 @@ import cn.lili.modules.goods.entity.dto.GoodsSkuStockDTO;
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
import cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum;
import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;
import cn.lili.modules.goods.entity.enums.GoodsStockTypeEnum;
import cn.lili.modules.goods.entity.vos.GoodsSkuSpecVO;
import cn.lili.modules.goods.entity.vos.GoodsSkuVO;
import cn.lili.modules.goods.entity.vos.GoodsVO;
@@ -54,12 +57,22 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;
@@ -493,6 +506,115 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
return this.page(PageUtil.initPage(searchParams), searchParams.queryWrapper());
}
@Override
public void queryExportStock(HttpServletResponse response, GoodsSearchParams searchParams) {
List<GoodsSkuStockDTO> goodsSkuStockDTOList = this.baseMapper.queryStocks(searchParams.queryWrapper());
XSSFWorkbook workbook = initStockExportData(goodsSkuStockDTOList);
try {
// 设置响应头
String fileName = URLEncoder.encode("商品库存", "UTF-8");
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
ServletOutputStream out = response.getOutputStream();
workbook.write(out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
workbook.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void importStock(String storeId, MultipartFile file) {
List<GoodsSkuStockDTO> goodsSkuStockDTOList = new ArrayList<>();
try (InputStream inputStream = file.getInputStream()) {
// 使用 WorkbookFactory.create 方法读取 Excel 文件
Workbook workbook = WorkbookFactory.create(inputStream);
Sheet sheet = workbook.getSheetAt(0); // 我们只读取第一个sheet
// 检查第一个sheet的行数是否超过10002行
if (sheet.getPhysicalNumberOfRows() > 10002) {
throw new ServiceException(ResultCode.GOODS_STOCK_IMPORT_ERROR, "Excel行数超过10002行");
}
// 遍历行和单元格
Iterator<Row> rowIterator = sheet.rowIterator();
int rowIndex = 0;
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
rowIndex++;
// 跳过表头
if (rowIndex < 3) {
continue;
}
List<Object> objects = new ArrayList<>();
for (int i = 0; i < 4; i++) {
objects.add(getCellValue(row.getCell(i)));
}
log.error(getCellValue(row.getCell(2)));
log.error(getCellValue(row.getCell(3)));
// 判断数据格式
if (!"".equals(getCellValue(row.getCell(2))) && !"".equals(getCellValue(row.getCell(2)))) {
throw new ServiceException(ResultCode.GOODS_STOCK_IMPORT_ERROR, "库存修改方向列数据必须是“增”或“减”");
} else if (!NumberUtil.isInteger(getCellValue(row.getCell(3))) || Integer.parseInt(getCellValue(row.getCell(3))) < 0) {
throw new ServiceException(ResultCode.GOODS_STOCK_IMPORT_ERROR, "库存必须是正整数");
} else if (this.count(new LambdaQueryWrapper<GoodsSku>()
.eq(GoodsSku::getGoodsId, getCellValue(row.getCell(0)))
.eq(GoodsSku::getId, getCellValue(row.getCell(1)))
.eq(GoodsSku::getStoreId, storeId)) == 0) {
throw new ServiceException(ResultCode.GOODS_STOCK_IMPORT_ERROR, "" + rowIndex + "行商品不存在");
}
GoodsSkuStockDTO goodsSkuStockDTO = new GoodsSkuStockDTO();
goodsSkuStockDTO.setGoodsId(getCellValue(row.getCell(0)));
goodsSkuStockDTO.setSkuId(getCellValue(row.getCell(1)));
goodsSkuStockDTO.setType(GoodsStockTypeEnum.fromDescription(getCellValue(row.getCell(2))).name());
goodsSkuStockDTO.setQuantity(Integer.parseInt(getCellValue(row.getCell(3))));
goodsSkuStockDTOList.add(goodsSkuStockDTO);
}
} catch (IOException e) {
log.error("IOException occurred while processing the Excel file.", e);
throw new ServiceException(ResultCode.GOODS_STOCK_IMPORT_ERROR, e.getMessage());
}
// 批量修改商品库存
this.updateStocksByType(goodsSkuStockDTOList);
}
private String getCellValue(Cell cell) {
if (cell == null) {
return "";
}
switch (cell.getCellType()) {
case STRING:
return cell.getStringCellValue();
case NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
return cell.getDateCellValue().toString();
} else {
// 将数值转换为整数以去掉小数点
double numericValue = cell.getNumericCellValue();
if (numericValue == (long) numericValue) {
return String.valueOf((long) numericValue);
} else {
return String.valueOf(numericValue);
}
}
case BOOLEAN:
return String.valueOf(cell.getBooleanCellValue());
case FORMULA:
return cell.getCellFormula();
default:
return "";
}
}
@Override
public IPage<GoodsSkuDTO> getGoodsSkuDTOByPage(Page<GoodsSkuDTO> page, Wrapper<GoodsSkuDTO> queryWrapper) {
return this.baseMapper.queryByParams(page, queryWrapper);
@@ -529,6 +651,27 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateStocksByType(List<GoodsSkuStockDTO> goodsSkuStockDTOS) {
// 获取所有的goodsID并去除相同的goodsID
List<String> goodsIds = goodsSkuStockDTOS.stream()
.map(GoodsSkuStockDTO::getGoodsId)
.distinct()
.collect(Collectors.toList());
//更新SKU库存
for (GoodsSkuStockDTO goodsSkuStockDTO : goodsSkuStockDTOS) {
this.updateStock(goodsSkuStockDTO.getSkuId(), goodsSkuStockDTO.getQuantity(), goodsSkuStockDTO.getType());
}
//更新SPU库存
for (String goodsId : goodsIds) {
goodsService.updateStock(goodsId);
}
}
@Override
public void updateAlertQuantity(GoodsSkuStockDTO goodsSkuStockDTO) {
GoodsSku goodsSku = this.getById(goodsSkuStockDTO.getSkuId());
@@ -559,7 +702,6 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
this.updateBatchById(goodsSkuList);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateStock(String skuId, Integer quantity) {
@@ -591,6 +733,45 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateStock(String skuId, Integer quantity, String type) {
GoodsSku goodsSku = getGoodsSkuByIdFromCache(skuId);
if (goodsSku != null) {
//计算修改库存
if (type.equals(GoodsStockTypeEnum.ADD.name())) {
quantity = Convert.toInt(NumberUtil.add(goodsSku.getQuantity(), quantity));
} else {
quantity = Convert.toInt(NumberUtil.sub(goodsSku.getQuantity(), quantity));
}
goodsSku.setQuantity(quantity);
//判断商品sku是否已经下架(修改商品库存为0时 会自动下架商品),再次更新商品库存时 需更新商品索引
boolean isFlag = goodsSku.getQuantity() <= 0;
boolean update = this.update(new LambdaUpdateWrapper<GoodsSku>().eq(GoodsSku::getId, skuId).set(GoodsSku::getQuantity, quantity));
if (update) {
cache.remove(CachePrefix.GOODS.getPrefix() + goodsSku.getGoodsId());
}
cache.put(GoodsSkuService.getCacheKeys(skuId), goodsSku);
cache.put(GoodsSkuService.getStockCacheKey(skuId), quantity);
this.promotionGoodsService.updatePromotionGoodsStock(goodsSku.getId(), quantity);
//商品库存为0是删除商品索引
if (quantity <= 0) {
goodsIndexService.deleteIndexById(goodsSku.getId());
}
//商品SKU库存为0并且商品sku状态为上架时更新商品库存
if (isFlag && CharSequenceUtil.equals(goodsSku.getMarketEnable(), GoodsStatusEnum.UPPER.name())) {
List<String> goodsIds = new ArrayList<>();
goodsIds.add(goodsSku.getGoodsId());
applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("更新商品", rocketmqCustomProperties.getGoodsTopic(),
GoodsTagsEnum.UPDATE_GOODS_INDEX.name(), goodsIds));
}
}
}
@Override
public Integer getStock(String skuId) {
String cacheKeys = GoodsSkuService.getStockCacheKey(skuId);
@@ -707,6 +888,17 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
}
@Override
public Boolean freight(List<String> goodsId, String templateId) {
LambdaUpdateWrapper<GoodsSku> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.in(GoodsSku::getGoodsId, goodsId);
updateWrapper.set(GoodsSku::getFreightTemplateId, templateId);
updateWrapper.set(GoodsSku::getUpdateTime, new Date());
List<String> skuIds = this.list(updateWrapper).stream().map(GoodsSku::getId).collect(Collectors.toList());
skuIds.forEach(this::clearCache);
return this.update(updateWrapper);
}
/**
* 渲染商品sku
*
@@ -743,6 +935,9 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
* @param goodsSku sku
*/
void renderImages(GoodsSku goodsSku, List<String> goodsImages) {
if (goodsImages == null || goodsImages.isEmpty()) {
return;
}
JSONObject jsonObject = JSONUtil.parseObj(goodsSku.getSpecs());
List<String> images = jsonObject.getBeanList("images", String.class);
GoodsGallery goodsGallery;
@@ -777,4 +972,150 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
return skuSpecVOList;
}
/**
* 初始化填充商品库存导出数据
*
* @param goodsSkuStockDTOList 导出的库存数据
* @return 商品库存导出列表
*/
private XSSFWorkbook initStockExportData(List<GoodsSkuStockDTO> goodsSkuStockDTOList) {
XSSFWorkbook workbook = new XSSFWorkbook();
// 创建模板
this.createTemplate(workbook);
// 创建sku库存列表
this.skuStockList(workbook, goodsSkuStockDTOList);
// 创建sku库存列表
this.skuList(workbook, goodsSkuStockDTOList);
return workbook;
}
/**
* 创建模板
*
* @param workbook
*/
private void createTemplate(XSSFWorkbook workbook) {
Sheet templateSheet = workbook.createSheet("商品库存编辑模板");
// 创建表头
Row description = templateSheet.createRow(0);
description.setHeightInPoints(90);
Cell descriptionCell = description.createCell(0);
descriptionCell.setCellValue("填写说明(请勿删除本说明):\n" +
"1.可批量设置多个商品的库存一次最多10000行\n" +
"2.库存修改方向:选择库存方向后,会在原先库存基础上进行增加或者减少\n" +
"3.库存变更数量需要为整数不能填写0和负数");
// 合并描述行的单元格
templateSheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 3));
// 设置描述行单元格样式(例如,自动换行)
CellStyle descriptionStyle = workbook.createCellStyle();
descriptionStyle.setWrapText(true);
descriptionStyle.setAlignment(HorizontalAlignment.LEFT);
descriptionStyle.setVerticalAlignment(VerticalAlignment.CENTER);
descriptionCell.setCellStyle(descriptionStyle);
// 创建表头
Row header = templateSheet.createRow(1);
String[] headers = {"商品ID必填", "skuID必填", "库存修改方向(必填,填 增 或者 减)", "库存变更数量(必填)"};
CellStyle headerStyle = workbook.createCellStyle();
Font headerFont = workbook.createFont();
headerFont.setBold(true);
headerStyle.setFont(headerFont);
for (int i = 0; i < headers.length; i++) {
Cell cell = header.createCell(i);
cell.setCellValue(headers[i]);
cell.setCellStyle(headerStyle);
}
//修改列宽
templateSheet.setColumnWidth(0, 30 * 256);
templateSheet.setColumnWidth(1, 30 * 256);
templateSheet.setColumnWidth(2, 40 * 256);
templateSheet.setColumnWidth(3, 25 * 256);
// 设置下拉列表数据验证
DataValidationHelper validationHelper = templateSheet.getDataValidationHelper();
DataValidationConstraint constraint = validationHelper.createExplicitListConstraint(new String[]{"", ""});
CellRangeAddressList addressList = new CellRangeAddressList(2, 10001, 2, 2); // 从第3行到第10002行第3列
DataValidation validation = validationHelper.createValidation(constraint, addressList);
validation.setSuppressDropDownArrow(true);
validation.setShowErrorBox(true);
templateSheet.addValidationData(validation);
}
/**
* 创建sku库存列表
*
* @param workbook
*/
private void skuStockList(XSSFWorkbook workbook, List<GoodsSkuStockDTO> goodsSkuStockDTOList) {
Sheet skuListSheet = workbook.createSheet("商品库存信息");
// 创建表头
Row header = skuListSheet.createRow(0);
String[] headers = {"商品ID", "商品名称", "规格ID(SKUID)", "规格名称", "货号", "当前库存数量"};
for (int i = 0; i < headers.length; i++) {
Cell cell = header.createCell(i);
cell.setCellValue(headers[i]);
}
// 填充数据
for (int i = 0; i < goodsSkuStockDTOList.size(); i++) {
GoodsSkuStockDTO dto = goodsSkuStockDTOList.get(i);
Row row = skuListSheet.createRow(i + 1);
row.createCell(0).setCellValue(dto.getGoodsId());
row.createCell(1).setCellValue(dto.getGoodsName());
row.createCell(2).setCellValue(dto.getSkuId());
row.createCell(3).setCellValue(dto.getSimpleSpecs());
row.createCell(4).setCellValue(dto.getSn());
row.createCell(5).setCellValue(dto.getQuantity());
}
//修改列宽
skuListSheet.setColumnWidth(0, 30 * 256);
skuListSheet.setColumnWidth(1, 30 * 256);
skuListSheet.setColumnWidth(2, 30 * 256);
skuListSheet.setColumnWidth(3, 30 * 256);
skuListSheet.setColumnWidth(4, 30 * 256);
skuListSheet.setColumnWidth(5, 15 * 256);
}
private void skuList(XSSFWorkbook workbook, List<GoodsSkuStockDTO> goodsSkuStockDTOList) {
Sheet skuListSheet = workbook.createSheet("商品规格");
// 创建表头
Row header = skuListSheet.createRow(0);
String[] headers = {"商品ID", "商品名称", "规格ID(SKUID)", "规格名称", "货号"};
for (int i = 0; i < headers.length; i++) {
Cell cell = header.createCell(i);
cell.setCellValue(headers[i]);
}
// 填充数据
for (int i = 0; i < goodsSkuStockDTOList.size(); i++) {
GoodsSkuStockDTO dto = goodsSkuStockDTOList.get(i);
Row row = skuListSheet.createRow(i + 1);
row.createCell(0).setCellValue(dto.getGoodsId());
row.createCell(1).setCellValue(dto.getGoodsName());
row.createCell(2).setCellValue(dto.getSkuId());
row.createCell(3).setCellValue(dto.getSimpleSpecs());
row.createCell(4).setCellValue(dto.getSn());
}
//修改列宽
skuListSheet.setColumnWidth(0, 30 * 256);
skuListSheet.setColumnWidth(1, 30 * 256);
skuListSheet.setColumnWidth(2, 30 * 256);
skuListSheet.setColumnWidth(3, 30 * 256);
skuListSheet.setColumnWidth(4, 30 * 256);
}
}

View File

@@ -1,6 +1,7 @@
package cn.lili.modules.logistics.plugin.kdniao;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.modules.logistics.LogisticsPlugin;
@@ -12,8 +13,13 @@ import cn.lili.modules.order.order.entity.vo.OrderDetailVO;
import cn.lili.modules.store.entity.dos.StoreLogistics;
import cn.lili.modules.store.entity.dto.StoreDeliverGoodsAddressDTO;
import cn.lili.modules.system.entity.dos.Logistics;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.DeliverySetting;
import cn.lili.modules.system.entity.dto.LogisticsSetting;
import cn.lili.modules.system.entity.dto.payment.UnionPaymentSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.entity.vo.Traces;
import cn.lili.modules.system.service.SettingService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
@@ -40,6 +46,9 @@ public class KdniaoPlugin implements LogisticsPlugin {
@Autowired
private LogisticsSetting logisticsSetting;
@Autowired
private SettingService settingService;
public KdniaoPlugin(LogisticsSetting logisticsSetting) {
this.logisticsSetting = logisticsSetting;
}
@@ -124,31 +133,41 @@ public class KdniaoPlugin implements LogisticsPlugin {
//收件人地址
String[] ConsigneeAddress = order.getConsigneeAddressPath().split(",");
//获取店家信息
StoreDeliverGoodsAddressDTO storeDeliverGoodsAddressDTO = labelOrderDTO.getStoreDeliverGoodsAddressDTO();
// StoreDeliverGoodsAddressDTO storeDeliverGoodsAddressDTO = labelOrderDTO.getStoreDeliverGoodsAddressDTO();
//发件人地址
String[] consignorAddress = storeDeliverGoodsAddressDTO.getSalesConsignorAddressPath().split(",");
// String[] consignorAddress = storeDeliverGoodsAddressDTO.getSalesConsignorAddressPath().split(",");
//店铺-物流公司设置
StoreLogistics storeLogistics = labelOrderDTO.getStoreLogistics();
// StoreLogistics storeLogistics = labelOrderDTO.getStoreLogistics();
Setting systemSetting = settingService.get(SettingEnum.DELIVERY_SETTING.name());
DeliverySetting deliverySetting = JSONUtil.toBean(systemSetting.getSettingValue(), DeliverySetting.class);
if(deliverySetting.getSalesConsignorName() == null
|| deliverySetting.getSalesConsignorAddressId() == null
|| deliverySetting.getSalesConsignorAddressPath() == null
|| deliverySetting.getSalesConsignorMobile() == null
|| deliverySetting.getSalesConsignorDetail() == null){
throw new ServiceException(ResultCode.DELIVERY_SETTING_ERROR);
}
String[] consignorAddress = deliverySetting.getSalesConsignorAddressPath().split(",");
//组装快递鸟应用级参数
String resultDate = "{" +
"'OrderCode': '" + order.getSn() + "'," + //订单编码
"'ShipperCode': '" + logistics.getCode() + "'," + //快递公司编码
"'CustomerName': '" + storeLogistics.getCustomerName() + "'," +//客户编码
"'CustomerPwd': '" + storeLogistics.getCustomerPwd() + "'," + //客户密码
"'MonthCode': '" + storeLogistics.getMonthCode() + "'," + //密钥
"'SendSite': '" + storeLogistics.getSendSite() + "'," + //归属网点
"'SendStaff': '" + storeLogistics.getSendStaff() + "'," + //收件快递员
"'PayType': " + storeLogistics.getPayType() + "," +
"'ExpType': " + storeLogistics.getExpType() + "," +
"'CustomerName': '" + logistics.getCustomerName() + "'," +//客户编码
"'CustomerPwd': '" + logistics.getCustomerPwd() + "'," + //客户密码
"'MonthCode': '" + logistics.getMonthCode() + "'," + //密钥
"'SendSite': '" + logistics.getSendSite() + "'," + //归属网点
"'SendStaff': '" + logistics.getSendStaff() + "'," + //收件快递员
"'PayType': " + logistics.getPayType() + "," +
"'ExpType': " + logistics.getExpType() + "," +
//发件人信息
"'Sender': {" +
"'Name': '" + storeDeliverGoodsAddressDTO.getSalesConsignorName() + "'," +
"'Mobile': '" + storeDeliverGoodsAddressDTO.getSalesConsignorMobile() + "'," +
"'Name': '" + deliverySetting.getSalesConsignorName() + "'," +
"'Mobile': '" + deliverySetting.getSalesConsignorMobile() + "'," +
"'ProvinceName': '" + consignorAddress[0] + "'," + //省
"'CityName': '" + consignorAddress[1] + "'," + //市
"'ExpAreaName': '" + consignorAddress[2] + "'," + //区
"'Address': '" + storeDeliverGoodsAddressDTO.getSalesConsignorDetail() + "'" + //发件人详细地址
"'Address': '" + deliverySetting.getSalesConsignorDetail() + "'" + //发件人详细地址
"}," +
//收件人信息
"'Receiver': {" +

View File

@@ -24,13 +24,16 @@ public class MemberGrade extends BaseEntity {
private String gradeName;
@NotNull
@ApiModelProperty(value = "等级图片")
@ApiModelProperty(value = "等级图片 1029*498")
private String gradeImage;
@NotNull
@ApiModelProperty(value = "所需经验值")
private Integer experienceValue;
@ApiModelProperty(value = "会员等级")
private Integer level;
@ApiModelProperty(value = "是否为默认等级")
private Boolean isDefault;
@ApiModelProperty(value = "累计实付")
private Double payPrice;
@ApiModelProperty(value = "累计购买次数")
private Integer count;
}

View File

@@ -135,10 +135,9 @@ public interface MemberService extends IService<Member> {
/**
* 注销账号
*
* @param password 密码
* @return 操作结果
*/
void cancellation(String password);
void cancellation();
/**
* 修改当前会员的手机号
*

View File

@@ -118,7 +118,11 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
public Member getUserInfo() {
AuthUser tokenUser = UserContext.getCurrentUser();
if (tokenUser != null) {
return this.findByUsername(tokenUser.getUsername());
Member member = this.findByUsername(tokenUser.getUsername());
if(member != null && member.getDisabled()){
throw new ServiceException(ResultCode.USER_STATUS_ERROR);
}
return member;
}
throw new ServiceException(ResultCode.USER_NOT_LOGIN);
}
@@ -233,7 +237,7 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
private Member findMember(String userName) {
QueryWrapper<Member> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username", userName).or().eq("mobile", userName);
return this.getOne(queryWrapper);
return this.getOne(queryWrapper, false);
}
@Override
@@ -286,12 +290,16 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
public Token mobilePhoneLogin(String mobilePhone) {
QueryWrapper<Member> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("mobile", mobilePhone);
Member member = this.baseMapper.selectOne(queryWrapper);
Member member = this.baseMapper.selectOne(queryWrapper, false);
//如果手机号不存在则自动注册用户
if (member == null) {
member = new Member(mobilePhone, UuidUtils.getUUID(), mobilePhone);
registerHandler(member);
}
//判断用户是否有效
if (member.getDisabled().equals(false) || member.getDeleteFlag().equals(true)) {
throw new ServiceException(ResultCode.USER_STATUS_ERROR);
}
loginBindUser(member);
return memberTokenGenerate.createToken(member, false);
}
@@ -375,20 +383,18 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
}
@Override
public void cancellation(String password) {
public void cancellation() {
AuthUser tokenUser = UserContext.getCurrentUser();
if (tokenUser == null) {
throw new ServiceException(ResultCode.USER_NOT_LOGIN);
}
Member member = this.getById(tokenUser.getId());
if (member.getPassword().equals(new BCryptPasswordEncoder().encode(password))) {
//删除联合登录
connectService.deleteByMemberId(member.getId());
//混淆用户信息
this.confusionMember(member);
}
}
/**
* 混淆之前的会员信息

View File

@@ -5,6 +5,7 @@ import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.event.TransactionCommitSendMQEvent;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.properties.RocketmqCustomProperties;
import cn.lili.common.security.AuthUser;
@@ -40,6 +41,7 @@ import cn.lili.modules.system.service.LogisticsService;
import cn.lili.mybatis.util.PageUtil;
import cn.lili.rocketmq.RocketmqSendCallbackBuilder;
import cn.lili.rocketmq.tags.AfterSaleTagsEnum;
import cn.lili.rocketmq.tags.OrderTagsEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@@ -48,6 +50,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -100,6 +103,9 @@ public class AfterSaleServiceImpl extends ServiceImpl<AfterSaleMapper, AfterSale
*/
@Autowired
private RocketMQTemplate rocketMQTemplate;
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
@Override
public IPage<AfterSaleVO> getAfterSalePages(AfterSaleSearchParams saleSearchParams) {
@@ -580,11 +586,10 @@ public class AfterSaleServiceImpl extends ServiceImpl<AfterSaleMapper, AfterSale
*
* @param afterSale 售后对象
*/
private void sendAfterSaleMessage(AfterSale afterSale) {
//发送售后创建消息
String destination = rocketmqCustomProperties.getAfterSaleTopic() + ":" + AfterSaleTagsEnum.AFTER_SALE_STATUS_CHANGE.name();
//发送订单变更mq消息
rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(afterSale), RocketmqSendCallbackBuilder.commonCallback());
@Transactional(rollbackFor = Exception.class)
public void sendAfterSaleMessage(AfterSale afterSale) {
applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("发送售后单状态变更MQ消息", rocketmqCustomProperties.getAfterSaleTopic(),
AfterSaleTagsEnum.AFTER_SALE_STATUS_CHANGE.name(), JSONUtil.toJsonStr(afterSale)));
}
/**

View File

@@ -1,5 +1,6 @@
package cn.lili.modules.order.cart.render.util;
import cn.hutool.core.map.MapUtil;
import cn.lili.common.enums.PromotionTypeEnum;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
@@ -10,7 +11,8 @@ import lombok.extern.slf4j.Slf4j;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
/**
* 促销价格计算业务层实现
@@ -33,7 +35,7 @@ public class PromotionPriceUtil {
PromotionTypeEnum promotionTypeEnum, String activityId) {
// sku 促销信息非空判定
if (skuPromotionDetail == null || skuPromotionDetail.size() == 0) {
if (skuPromotionDetail == null || skuPromotionDetail.isEmpty()) {
return;
}
@@ -68,40 +70,39 @@ public class PromotionPriceUtil {
List<CartSkuVO> skuVOList = tradeDTO.getSkuList();
// 获取map分配sku的总数如果是最后一个商品分配金额则将金额从百分比改为总金额扣减避免出现小数除不尽
int count = skuPromotionDetail.size();
AtomicInteger count = new AtomicInteger(skuPromotionDetail.size());
//已优惠金额
Double deducted = 0D;
AtomicReference<Double> deducted = new AtomicReference<>(0D);
for (String skuId : skuPromotionDetail.keySet()) {
//获取对应商品进行计算
for (CartSkuVO cartSkuVO : skuVOList) {
if (cartSkuVO.getGoodsSku().getId().equals(skuId)) {
count--;
Double finalDiscountPrice = discountPrice;
Double finalTotalPrice = totalPrice;
skuVOList.stream().filter(l -> l.getGoodsSku().getId().equals(skuId)).findFirst().ifPresent(cartSkuVO -> {
//sku 优惠金额
Double skuDiscountPrice;
count.getAndDecrement();
//非最后一个商品,则按照比例计算
if (count > 0) {
if (count.get() > 0) {
//商品金额占比
double point = CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getGoodsPrice(), totalPrice, 4);
double point = CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getGoodsPrice(), finalTotalPrice, 4);
//商品优惠金额
skuDiscountPrice = CurrencyUtil.mul(discountPrice, point);
skuDiscountPrice = CurrencyUtil.mul(finalDiscountPrice, point);
//累加已优惠金额
deducted = CurrencyUtil.add(deducted, skuDiscountPrice);
deducted.set(CurrencyUtil.add(deducted.get(), skuDiscountPrice));
}
// 如果是最后一个商品 则减去之前优惠的金额来进行计算
else {
skuDiscountPrice = CurrencyUtil.sub(discountPrice, deducted);
skuDiscountPrice = CurrencyUtil.sub(finalDiscountPrice, deducted.get());
}
calculateCartSkuPromotionsPrice(cartSkuVO, skuDiscountPrice, promotionTypeEnum, activityId);
}
}
});
}
calculateNotEnoughPromotionsPrice(skuVOList, skuPromotionDetail, discountPrice, totalPrice, promotionTypeEnum, activityId);
@@ -186,51 +187,100 @@ public class PromotionPriceUtil {
// 特殊情况处理,如参与多个促销活动,部分商品在其他促销计算后的金额不足以满足与当前参与的促销活动的优惠金额
// 但当前购物车内存在当前当前促销活动的其他商品且剩余金额也满足分摊不足商品的不足金额,则分摊到其他商品上
// 满足当前促销的总优惠金额
if (skuPromotionDetail == null || skuPromotionDetail.isEmpty()) {
if (skuPromotionDetail == null || skuPromotionDetail.size() < 2) {
return;
}
// clone skuPromotionDetail
Map<String, Double> skuPromotionDetailClone = MapUtil.sortByValue(skuPromotionDetail, false);
// 未满足优惠金额的商品
long matchPromotionsZeroCount =
skuVOList.stream().filter(l -> l.getPriceDetailDTO().getFlowPrice() == 0 && skuPromotionDetail.containsKey(l.getGoodsSku().getId())).count();
long matchPromotionsCount = skuVOList.stream().filter(l -> skuPromotionDetail.containsKey(l.getGoodsSku().getId())).count();
skuVOList.stream().filter(l -> l.getPriceDetailDTO().getFlowPrice() == 0 && skuPromotionDetailClone.containsKey(l.getGoodsSku().getId())).count();
// 参与当前促销活动的商品
long matchPromotionsCount = skuVOList.stream().filter(l -> skuPromotionDetailClone.containsKey(l.getGoodsSku().getId())).count();
if (matchPromotionsZeroCount == matchPromotionsCount) {
return;
}
// 获取剩余金额不足优惠金额的商品
List<CartSkuVO> unEnoughSku = skuVOList.stream().filter(k -> {
if (skuPromotionDetail.containsKey(k.getGoodsSku().getId()) && skuPromotionDetail.size() >= 2) {
//商品金额占比
double point = CurrencyUtil.div(k.getPriceDetailDTO().getGoodsPrice(), totalPrice, 4);
//商品优惠金额
Double skuDiscountPrice = CurrencyUtil.mul(discountPrice, point);
return k.getPriceDetailDTO().getCouponPrice() > 0 && skuDiscountPrice > k.getPriceDetailDTO().getCouponPrice();
}
return false;
}).collect(Collectors.toList());
if (!unEnoughSku.isEmpty()) {
if (unEnoughSku.size() == skuVOList.size()) {
return;
}
for (CartSkuVO cartSkuVO : skuVOList) {
if (unEnoughSku.isEmpty()) {
// 分配到其他商品的优惠金额
AtomicReference<Double> balance = new AtomicReference<>(0D);
StringBuilder lastSkuId = new StringBuilder();
// 计数器
int count = 0;
// 检查是否有不满足优惠金额的商品
filterEnoughSku(skuVOList, skuPromotionDetailClone, discountPrice, totalPrice, balance, lastSkuId, promotionTypeEnum, activityId);
// 循环 优惠金额分摊,直到所有商品都满足优惠金额
while (true) {
// 如果还有剩余金额,则继续分摊
if (balance.get() > 0) {
skuPromotionDetailClone.remove(lastSkuId.toString());
double lastDiscountPrice = CurrencyUtil.sub(discountPrice, skuPromotionDetail.get(lastSkuId.toString()));
double lastTotalPrice = CurrencyUtil.sub(totalPrice, skuPromotionDetail.get(lastSkuId.toString()));
filterEnoughSku(skuVOList, skuPromotionDetailClone, lastDiscountPrice, lastTotalPrice, balance, lastSkuId, promotionTypeEnum, activityId);
} else {
break;
}
if (skuPromotionDetail.containsKey(cartSkuVO.getGoodsSku().getId()) && unEnoughSku.stream().noneMatch(k -> k.getGoodsSku().getId().equals(cartSkuVO.getGoodsSku().getId()))) {
count++;
// 防止死循环
if (count > skuPromotionDetail.size()) {
break;
}
}
}
private static void filterEnoughSku(List<CartSkuVO> skuVOList, Map<String, Double> skuPromotionDetail,
Double discountPrice, Double totalPrice,
AtomicReference<Double> balance, StringBuilder lastSkuId,
PromotionTypeEnum promotionTypeEnum, String activityId) {
AtomicInteger count = new AtomicInteger(skuPromotionDetail.size());
AtomicReference<Double> countPrice = new AtomicReference<>(0D);
for (String skuId : skuPromotionDetail.keySet()) {
skuVOList.forEach(l -> {
if (l.getGoodsSku().getId().equals(skuId)) {
count.getAndDecrement();
//商品金额占比
double point = CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getGoodsPrice(), totalPrice, 4);
double point = CurrencyUtil.div(l.getPriceDetailDTO().getGoodsPrice(), totalPrice, 4);
//商品优惠金额
Double skuDiscountPrice = CurrencyUtil.mul(discountPrice, point);
// 商品优惠金额 - 不足优惠金额 = 差额
Double sub = CurrencyUtil.sub(skuDiscountPrice, unEnoughSku.get(0).getPriceDetailDTO().getCouponPrice());
// 分摊到其他商品: 其他商品原优惠金额 + 差额
calculateCartSkuPromotionsPrice(cartSkuVO, sub, promotionTypeEnum, activityId);
// 从不足商品列表中移除
unEnoughSku.remove(0);
}
}
Double skuDiscountPrice;
if (count.get() > 0) {
//非最后一个商品,则按照比例计算
skuDiscountPrice = CurrencyUtil.mul(discountPrice, point);
} else {
return;
// 如果是最后一个商品 则减去之前优惠的金额来进行计算
skuDiscountPrice = CurrencyUtil.sub(discountPrice, countPrice.get());
}
if (balance.get() > 0) {
// 分摊到其他商品: 其他商品原优惠金额 + 差额
calculateCartSkuPromotionsPrice(l, balance.get(), promotionTypeEnum, activityId);
}
// 如果商品优惠金额大于商品金额,则取商品金额。差额分摊到其他商品
if (skuDiscountPrice > l.getPriceDetailDTO().getGoodsPrice()) {
balance.set(CurrencyUtil.sub(skuDiscountPrice, l.getPriceDetailDTO().getGoodsPrice()));
lastSkuId.append(skuId);
skuDiscountPrice = l.getPriceDetailDTO().getGoodsPrice();
} else {
balance.set(0D);
}
countPrice.set(CurrencyUtil.add(countPrice.get(), skuDiscountPrice));
}
});
}
calculateNotEnoughPromotionsPrice(skuVOList, skuPromotionDetail, discountPrice, totalPrice, promotionTypeEnum, activityId);
}
/**

View File

@@ -148,6 +148,9 @@ public class Order extends BaseEntity {
@ApiModelProperty(value = "买家订单备注")
private String remark;
@ApiModelProperty(value = "卖家订单备注")
private String sellerRemark;
@ApiModelProperty(value = "订单取消原因")
private String cancelReason;
@@ -240,7 +243,7 @@ public class Order extends BaseEntity {
this.setDeliverStatus(DeliverStatusEnum.UNDELIVERED.name());
this.setTradeSn(tradeDTO.getSn());
this.setRemark(cartVO.getRemark());
this.setFreightPrice(tradeDTO.getPriceDetailDTO().getFreightPrice());
this.setFreightPrice(cartVO.getPriceDetailDTO().getFreightPrice());
//会员收件信息
if (tradeDTO.getMemberAddress() != null && DeliveryMethodEnum.LOGISTICS.name().equals(cartVO.getDeliveryMethod())) {
this.setConsigneeAddressIdPath(tradeDTO.getMemberAddress().getConsigneeAddressIdPath());

View File

@@ -2,6 +2,7 @@ package cn.lili.modules.order.order.entity.dos;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.common.enums.PromotionTypeEnum;
import cn.lili.common.utils.BeanUtil;
import cn.lili.common.utils.SnowFlake;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
@@ -187,4 +188,10 @@ public class OrderItem extends BaseEntity {
this.priceDetail = JSONUtil.toJsonStr(priceDetail);
}
public String getAfterSaleStatus() {
if (!PromotionTypeEnum.isCanAfterSale(this.promotionType)) {
return OrderItemAfterSaleStatusEnum.EXPIRED.name();
}
return afterSaleStatus;
}
}

View File

@@ -1,5 +1,6 @@
package cn.lili.modules.order.order.entity.dos;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.common.utils.BeanUtil;
@@ -8,6 +9,7 @@ import cn.lili.common.utils.SnowFlake;
import cn.lili.modules.order.order.entity.dto.PriceDetailDTO;
import cn.lili.modules.order.order.entity.enums.FlowTypeEnum;
import cn.lili.modules.order.order.entity.enums.OrderPromotionTypeEnum;
import cn.lili.modules.order.order.entity.enums.ProfitSharingStatusEnum;
import cn.lili.modules.payment.entity.enums.PaymentMethodEnum;
import cn.lili.mybatis.BaseIdEntity;
import com.baomidou.mybatisplus.annotation.FieldFill;
@@ -141,6 +143,24 @@ public class StoreFlow extends BaseIdEntity {
@ApiModelProperty(value = "创建时间", hidden = true)
private Date createTime;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@TableField(fill = FieldFill.INSERT)
@ApiModelProperty(value = "结算时间", hidden = true)
private Date billTime;
@ApiModelProperty(value = "是否全部退款true为全部退款")
private Boolean fullRefund;
/**
* @see ProfitSharingStatusEnum
*/
@ApiModelProperty(value = "分账状态")
private String profitSharingStatus;
@ApiModelProperty(value = "实际分账金额DTO", hidden = true)
private String profitSharing;
public StoreFlow(Order order, OrderItem item, FlowTypeEnum flowTypeEnum) {
//获取订单促销类型,如果为促销订单则获取促销商品并获取结算价
@@ -196,6 +216,10 @@ public class StoreFlow extends BaseIdEntity {
this.setPaymentName(order.getPaymentMethod());
//添加第三方支付流水号
this.setTransactionId(order.getReceivableNo());
//默认结算时间180天
if (flowTypeEnum.equals(FlowTypeEnum.PAY)) {
this.billTime = DateUtil.offsetDay(new Date(), 180);
this.fullRefund = false;
}
}
}

View File

@@ -1,8 +1,9 @@
package cn.lili.modules.order.order.entity.dto;
import cn.lili.modules.order.order.entity.enums.DeliverStatusEnum;
import cn.lili.common.enums.ClientTypeEnum;
import cn.lili.modules.order.order.entity.enums.OrderItemAfterSaleStatusEnum;
import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
import cn.lili.modules.order.order.entity.enums.PayStatusEnum;
import cn.lili.modules.order.order.entity.enums.OrderTypeEnum;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -19,77 +20,71 @@ import java.util.Date;
@Data
public class OrderExportDTO {
@ApiModelProperty("订单编号")
private String sn;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建时间")
private Date createTime;
@ApiModelProperty(value = "用户名")
private String memberName;
@ApiModelProperty(value = "收件人姓名")
private String consigneeName;
@ApiModelProperty(value = "收件人手机")
private String consigneeMobile;
@ApiModelProperty(value = "收件人地址")
private String consigneeAddressPath;
@ApiModelProperty(value = "详细地址")
private String consigneeDetail;
@ApiModelProperty(value = "支付方式")
private String paymentMethod;
@ApiModelProperty(value = "物流公司名称")
private String logisticsName;
@ApiModelProperty(value = "运费")
private Double freightPrice;
@ApiModelProperty(value = "商品价格")
private Double goodsPrice;
@ApiModelProperty(value = "优惠的金额")
private Double discountPrice;
@ApiModelProperty(value = "总价格")
private Double flowPrice;
@ApiModelProperty(value = "商品名称")
@ApiModelProperty(value = "订单编号")
private String orderSn;
@ApiModelProperty(value = "子订单编号")
private String orderItemSn;
@ApiModelProperty(value = "选购商品")
private String goodsName;
@ApiModelProperty(value = "商品数量")
private Integer num;
@ApiModelProperty(value = "买家订单备注")
@ApiModelProperty(value = "商品ID")
private String goodsId;
@ApiModelProperty(value = "商品单价")
private Double unitPrice;
@ApiModelProperty(value = "订单应付金额")
private Double flowPrice;
@ApiModelProperty(value = "价格内容")
private String priceDetail;
@ApiModelProperty(value = "支付方式")
private String paymentMethod;
@ApiModelProperty(value = "收件人")
private String consigneeName;
@ApiModelProperty(value = "收件人手机")
private String consigneeMobile;
@ApiModelProperty(value = "收件人地址")
private String consigneeAddressPath;
@ApiModelProperty(value = "详细地址")
private String consigneeDetail;
@ApiModelProperty(value = "买家留言")
private String remark;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "订单提交时间")
private Date createTime;
@ApiModelProperty(value = "支付完成时间")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date paymentTime;
/**
* @see ClientTypeEnum
*/
@ApiModelProperty(value = "来源")
private String clientType;
/**
* @see OrderStatusEnum
*/
@ApiModelProperty(value = "订单状态")
private String orderStatus;
/**
* @see PayStatusEnum
* @see OrderTypeEnum
*/
@ApiModelProperty(value = "付款状态")
private String payStatus;
@ApiModelProperty(value = "订单类型")
private String orderType;
/**
* @see DeliverStatusEnum
* @see OrderItemAfterSaleStatusEnum
*/
@ApiModelProperty(value = "货运状态")
private String deliverStatus;
@ApiModelProperty(value = "是否需要发票")
private Boolean needReceipt;
@ApiModelProperty(value = "店铺名称")
@ApiModelProperty(value = "售后状态")
private String afterSaleStatus;
@ApiModelProperty(value = "取消原因")
private String cancelReason;
@ApiModelProperty(value = "发货时间")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date logisticsTime;
@ApiModelProperty(value = "完成时间")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date completeTime;
@ApiModelProperty(value = "店铺")
private String storeName;
}

View File

@@ -0,0 +1,93 @@
package cn.lili.modules.order.order.entity.dto;
import cn.lili.common.enums.ClientTypeEnum;
import cn.lili.modules.order.order.entity.enums.OrderItemAfterSaleStatusEnum;
import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
import cn.lili.modules.order.order.entity.enums.OrderTypeEnum;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 订单导出DTO
* @author Bulbasaur
* @since 2021/6/3 6:36 下午
*
*/
@Data
public class OrderExportDetailDTO {
@ApiModelProperty(value = "主订单编号")
private String orderSn;
@ApiModelProperty(value = "子订单编号")
private String orderItemSn;
@ApiModelProperty(value = "选购商品")
private String goodsName;
@ApiModelProperty(value = "商品数量")
private Integer num;
@ApiModelProperty(value = "商品ID")
private String goodsId;
@ApiModelProperty(value = "商品单价")
private Double unitPrice;
@ApiModelProperty(value = "订单应付金额")
private Double flowPrice;
@ApiModelProperty(value = "运费")
private Double freightPrice;
@ApiModelProperty(value = "优惠总金额")
private Double discountPrice;
@ApiModelProperty(value = "平台")
private Double siteMarketingCost;
@ApiModelProperty(value = "商家优惠")
private Double storeMarketingCost;
@ApiModelProperty(value = "商家改价")
private Double updatePrice;
@ApiModelProperty(value = "支付方式")
private String paymentMethod;
@ApiModelProperty(value = "收件人")
private String consigneeName;
@ApiModelProperty(value = "收件人手机")
private String consigneeMobile;
@ApiModelProperty(value = "")
private String province;
@ApiModelProperty(value = "")
private String city;
@ApiModelProperty(value = "")
private String district;
@ApiModelProperty(value = "街道")
private String street;
@ApiModelProperty(value = "详细地址")
private String consigneeDetail;
@ApiModelProperty(value = "买家留言")
private String remark;
@ApiModelProperty(value = "订单提交时间")
private String createTime;
@ApiModelProperty(value = "支付完成时间")
private String paymentTime;
/**
* @see ClientTypeEnum
*/
@ApiModelProperty(value = "来源")
private String clientType;
/**
* @see OrderStatusEnum
*/
@ApiModelProperty(value = "订单状态")
private String orderStatus;
/**
* @see OrderTypeEnum
*/
@ApiModelProperty(value = "订单类型")
private String orderType;
/**
* @see OrderItemAfterSaleStatusEnum
*/
@ApiModelProperty(value = "售后状态")
private String afterSaleStatus;
@ApiModelProperty(value = "取消原因")
private String cancelReason;
@ApiModelProperty(value = "发货时间")
private String logisticsTime;
@ApiModelProperty(value = "完成时间")
private String completeTime;
@ApiModelProperty(value = "店铺")
private String storeName;
}

View File

@@ -0,0 +1,20 @@
package cn.lili.modules.order.order.entity.dto;
import lombok.Data;
/**
* 流水-实际分账DTO
*/
@Data
public class StoreFlowProfitSharingDTO {
//平台获取金额
private Double platformPrice;
//店铺获取金额
private Double storePrice;
//分销员获取金额
private Double distributionPrice;
//合计金额 --剩余金额
private Double price;
//补差金额
private Double subsidies;
}

View File

@@ -12,6 +12,7 @@ public enum DeliverStatusEnum {
* 发货状态
*/
UNDELIVERED("未发货"),
PARTS_DELIVERED("部分发货"),
DELIVERED("已发货"),
RECEIVED("已收货");

View File

@@ -1,5 +1,10 @@
package cn.lili.modules.order.order.entity.enums;
import cn.lili.common.utils.StringUtils;
import java.util.Arrays;
import java.util.EnumSet;
/**
* 订单促销类型枚举
*
@@ -27,6 +32,30 @@ public enum OrderPromotionTypeEnum {
/**
* 砍价订单
*/
KANJIA
KANJIA;
/**
* 判断促销类型是否有效
* @param typeEnumValue
* @return
*/
public static boolean isValid(String typeEnumValue) {
if (StringUtils.isBlank(typeEnumValue)) {
return false;
}
return Arrays.stream(OrderPromotionTypeEnum.values()).anyMatch(c -> c.name().equals(typeEnumValue));
}
/**
* 判断订单类型是否可售后
* GIFT\POINTS\KANJIA 三种促销类型的订单不可进行售后
* @return true 可售后 false 不可售后
*/
public static boolean isCanAfterSale(String orderPromotionType) {
if (!isValid(orderPromotionType)) {
return true;
}
EnumSet<OrderPromotionTypeEnum> noAfterSale = EnumSet.of(OrderPromotionTypeEnum.GIFT, OrderPromotionTypeEnum.POINTS, OrderPromotionTypeEnum.KANJIA);
return !noAfterSale.contains(OrderPromotionTypeEnum.valueOf(orderPromotionType));
}
}

View File

@@ -14,6 +14,7 @@ public enum OrderStatusEnum {
UNPAID("未付款"),
PAID("已付款"),
UNDELIVERED("待发货"),
PARTS_DELIVERED("部分发货"),
DELIVERED("已发货"),
COMPLETED("已完成"),
STAY_PICKED_UP("待自提"),

View File

@@ -0,0 +1,22 @@
package cn.lili.modules.order.order.entity.enums;
/**
* 分账状态 枚举
*/
public enum ProfitSharingStatusEnum {
ORDER_CANCEL("订单取消"),
WAIT_COMPLETE("待订单完成"),
PROCESSING("处理中"),
FINISHED("分账完成");
// FAIL("分账失败"),
// ARTIFICIAL("人工处理");
private String description;
ProfitSharingStatusEnum(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}

View File

@@ -73,18 +73,18 @@ public class AllowOperation implements Serializable {
//可编辑订单收件人信息=实物订单 && 订单未发货 && 订单未取消 && 订单不是自提
this.editConsignee = order.getOrderType().equals(OrderTypeEnum.NORMAL.name())
&& order.getDeliverStatus().equals(DeliverStatusEnum.UNDELIVERED.name())
&& (order.getDeliverStatus().equals(DeliverStatusEnum.UNDELIVERED.name()) || order.getDeliverStatus().equals(DeliverStatusEnum.PARTS_DELIVERED.name()))
&& !status.equals(OrderStatusEnum.CANCELLED.name())
&& !order.getDeliveryMethod().equals(DeliveryMethodEnum.SELF_PICK_UP.name());
//是否允许被发货
this.ship = editConsignee && status.equals(OrderStatusEnum.UNDELIVERED.name());
this.ship = editConsignee && (status.equals(OrderStatusEnum.UNDELIVERED.name()) || order.getDeliverStatus().equals(DeliverStatusEnum.PARTS_DELIVERED.name()));
//是否允许被收货
this.rog = status.equals(OrderStatusEnum.DELIVERED.name());
//是否允许查看物流信息
this.showLogistics = order.getDeliverStatus().equals(DeliverStatusEnum.DELIVERED.name()) && status.equals(OrderStatusEnum.DELIVERED.name());
this.showLogistics = (order.getDeliverStatus().equals(DeliverStatusEnum.DELIVERED.name()) || order.getDeliverStatus().equals(DeliverStatusEnum.PARTS_DELIVERED.name())) && (status.equals(OrderStatusEnum.DELIVERED.name()) || status.equals(OrderStatusEnum.PARTS_DELIVERED.name()));
//虚拟订单 或 自提订单可以核销
this.take =
@@ -107,11 +107,8 @@ public class AllowOperation implements Serializable {
}
//取消判定
if (CharSequenceUtil.equalsAny(status, OrderStatusEnum.UNPAID.name(), OrderStatusEnum.PAID.name(), OrderStatusEnum.UNDELIVERED.name(),
OrderStatusEnum.STAY_PICKED_UP.name(),
OrderStatusEnum.TAKE.name())) {
if (CharSequenceUtil.equalsAny(status, OrderStatusEnum.UNPAID.name(), OrderStatusEnum.PAID.name(), OrderStatusEnum.UNDELIVERED.name())) {
this.cancel = true;
}
//新订单,允许支付
this.pay = status.equals(OrderStatusEnum.UNPAID.name());

View File

@@ -4,6 +4,8 @@ import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.common.enums.ClientTypeEnum;
import cn.lili.common.security.sensitive.Sensitive;
import cn.lili.common.security.sensitive.enums.SensitiveStrategy;
import cn.lili.modules.order.order.entity.enums.OrderItemAfterSaleStatusEnum;
import cn.lili.modules.order.order.entity.enums.OrderPromotionTypeEnum;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -148,6 +150,9 @@ public class OrderSimpleVO {
@ApiModelProperty(value = "退款金额")
private String groupRefundPrice;
@ApiModelProperty(value = "卖家订单备注")
private String sellerRemark;
public List<OrderItemVO> getOrderItems() {
if (CharSequenceUtil.isEmpty(groupGoodsId)) {
return new ArrayList<>();
@@ -183,8 +188,12 @@ public class OrderSimpleVO {
orderItemVO.setImage(groupImages.split(",")[i]);
}
if (CharSequenceUtil.isNotEmpty(groupAfterSaleStatus) && groupAfterSaleStatus.split(",").length == groupGoodsId.split(",").length) {
if (!OrderPromotionTypeEnum.isCanAfterSale(this.orderPromotionType)) {
orderItemVO.setAfterSaleStatus(OrderItemAfterSaleStatusEnum.EXPIRED.name());
} else {
orderItemVO.setAfterSaleStatus(groupAfterSaleStatus.split(",")[i]);
}
}
if (CharSequenceUtil.isNotEmpty(groupComplainStatus) && groupComplainStatus.split(",").length == groupGoodsId.split(",").length) {
orderItemVO.setComplainStatus(groupComplainStatus.split(",")[i]);
}
@@ -211,5 +220,11 @@ public class OrderSimpleVO {
return new AllowOperation(this);
}
public String getGroupAfterSaleStatus() {
// 不可售后的订单类型集合
if (!OrderPromotionTypeEnum.isCanAfterSale(this.orderPromotionType)) {
return OrderItemAfterSaleStatusEnum.EXPIRED.name();
}
return groupAfterSaleStatus;
}
}

View File

@@ -37,10 +37,30 @@ public interface OrderMapper extends BaseMapper<Order> {
* @param queryWrapper 查询条件
* @return 导出订单DTO列表
*/
@Select("SELECT o.sn,o.create_time,o.member_name,o.consignee_name,o.consignee_mobile,o.consignee_address_path,o.consignee_detail," +
"o.payment_method, o.logistics_name,o.freight_price,oi.goods_price,o.discount_price,o.flow_price,oi.goods_name,oi.num," +
"o.remark,o.order_status,o.pay_status,o.deliver_status,o.need_receipt,o.store_name FROM li_order o LEFT JOIN li_order_item oi " +
"ON oi.order_sn=o.sn ${ew.customSqlSegment}")
@Select("SELECT o.sn AS order_sn," +
"oi.sn AS order_item_sn," +
"oi.goods_name AS goods_name," +
"oi.num AS num," +
"oi.goods_id AS goods_id," +
"oi.unit_price AS unit_price," +
"oi.flow_price AS flow_price," +
"oi.price_detail AS price_detail," +
"o.payment_method AS payment_method," +
"o.consignee_name AS consignee_name," +
"o.consignee_mobile AS consignee_mobile," +
"o.consignee_address_path AS consignee_address_path," +
"o.consignee_detail AS consignee_detail," +
"o.remark AS remark," +
"o.create_time AS create_time," +
"o.payment_time AS payment_time," +
"o.client_type AS client_type," +
"o.order_status AS order_status," +
"o.order_type AS order_type," +
"oi.after_sale_status AS after_sale_status," +
"o.logistics_time AS logistics_time," +
"o.complete_time AS complete_time," +
"o.store_name AS store_name " +
" FROM li_order o LEFT JOIN li_order_item oi ON oi.order_sn = o.sn ${ew.customSqlSegment}")
List<OrderExportDTO> queryExportOrder(@Param(Constants.WRAPPER) Wrapper<OrderSimpleVO> queryWrapper);
/**
@@ -60,7 +80,8 @@ public interface OrderMapper extends BaseMapper<Order> {
* @param queryWrapper 查询条件
* @return 简短订单分页
*/
@Select("select o.sn,o.flow_price,o.create_time,o.order_status,o.pay_status,o.payment_method,o.payment_time,o.member_name,o.store_name as store_name,o.store_id as store_id,o.client_type,o.order_type,o.deliver_status,o.order_promotion_type " +
@Select("select o.sn,o.flow_price,o.create_time,o.order_status,o.pay_status,o.payment_method,o.payment_time,o.member_name,o.store_name as " +
"store_name,o.store_id as store_id,o.client_type,o.order_type,o.deliver_status,o.order_promotion_type,o.seller_remark " +
",GROUP_CONCAT(oi.goods_id) as group_goods_id," +
" GROUP_CONCAT(oi.sku_id) as group_sku_id," +
" GROUP_CONCAT(oi.num) as group_num" +

View File

@@ -1,13 +1,16 @@
package cn.lili.modules.order.order.mapper;
import cn.lili.modules.order.order.entity.dos.StoreFlow;
import cn.lili.modules.store.entity.dos.Bill;
import cn.lili.modules.store.entity.vos.StoreFlowPayDownloadVO;
import cn.lili.modules.store.entity.vos.StoreFlowRefundDownloadVO;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
@@ -34,4 +37,84 @@ public interface StoreFlowMapper extends BaseMapper<StoreFlow> {
*/
@Select("SELECT * FROM li_store_flow ${ew.customSqlSegment}")
List<StoreFlowRefundDownloadVO> getStoreFlowRefundDownloadVO(@Param(Constants.WRAPPER) Wrapper<StoreFlow> queryWrapper);
@Update("UPDATE li_store_flow "+
"SET profit_sharing_status = 'PROCESSING', "+
"bill_time=NOW() "+
"WHERE order_item_sn IN ( "+
"SELECT o.order_item_sn "+
"FROM ( "+
"SELECT lof.order_item_sn "+
"FROM li_store_flow lof "+
"LEFT JOIN ( "+
"SELECT order_sn "+
"FROM li_order_item "+
"WHERE after_sale_status <> 'EXPIRED' "+
"GROUP BY order_sn "+
") oi ON lof.order_sn = oi.order_sn "+
"WHERE lof.profit_sharing_status = 'WAIT_COMPLETE' "+
"AND oi.order_sn IS NULL "+
") o "+
")")
void updateProfitSharingStatus();
@Select("SELECT * FROM li_store_flow "+
"WHERE order_item_sn IN ( "+
"SELECT o.order_item_sn "+
"FROM ( "+
"SELECT lof.order_item_sn "+
"FROM li_store_flow lof "+
"LEFT JOIN ( "+
"SELECT order_sn "+
"FROM li_order_item "+
"WHERE after_sale_status <> 'EXPIRED' "+
"GROUP BY order_sn "+
") oi ON lof.order_sn = oi.order_sn "+
"WHERE lof.profit_sharing_status = 'WAIT_COMPLETE' "+
"AND oi.order_sn IS NULL "+
") o "+
")")
List<StoreFlow> completeList();
/**
* 查询订单货物退款数量
* @param orderItemSn
* @return
*/
@Select("SELECT SUM(num) AS num FROM li_store_flow WHERE flow_type = 'REFUND' AND order_item_sn = #{orderItemSn}")
Integer getRefundNum(String orderItemSn);
/**
* 查询退款结算单
*
* @param queryWrapper 查询条件
* @return 结算单
*/
@Select("SELECT IFNULL(SUM( final_price ),0) AS refundPrice,IFNULL(SUM( commission_price ),0) AS refundCommissionPrice" +
",IFNULL(SUM( distribution_rebate ),0) AS distributionRefundCommission" +
",IFNULL(SUM( site_coupon_commission ),0) AS siteCouponRefundCommission" +
",IFNULL(SUM( point_settlement_price ),0) AS pointSettlementPrice " +
",IFNULL(SUM( kanjia_settlement_price ),0) AS kanjiaSettlementPrice " +
",IFNULL(SUM( bill_price ),0) AS billPrice " +
"FROM li_store_flow ${ew.customSqlSegment}")
Bill getRefundBill(@Param(Constants.WRAPPER) QueryWrapper<Bill> queryWrapper);
/**
* 查询订单结算
*
* @param queryWrapper 查询条件
* @return 结算单
*/
@Select("SELECT IFNULL(SUM( final_price ),0) AS orderPrice" +
",IFNULL(SUM( commission_price ),0) AS commissionPrice" +
",IFNULL(SUM( distribution_rebate ),0) AS distributionCommission" +
",IFNULL(SUM( site_coupon_commission ),0) AS siteCouponCommission" +
",IFNULL(SUM( point_settlement_price ),0) AS pointSettlementPrice " +
",IFNULL(SUM( kanjia_settlement_price ),0) AS kanjiaSettlementPrice " +
",IFNULL(SUM( bill_price ),0) AS billPrice " +
"FROM li_store_flow ${ew.customSqlSegment}")
Bill getOrderBill(@Param(Constants.WRAPPER) QueryWrapper<Bill> queryWrapper);
}

View File

@@ -99,7 +99,7 @@ public interface OrderService extends IService<Order> {
* @param orderSearchParams 查询参数
* @return 导出订单列表
*/
List<OrderExportDTO> queryExportOrder(OrderSearchParams orderSearchParams);
void queryExportOrder(HttpServletResponse response,OrderSearchParams orderSearchParams) ;
/**
@@ -320,4 +320,12 @@ public interface OrderService extends IService<Order> {
*/
Order partDelivery(PartDeliveryParamsDTO partDeliveryParamsDTO);
/**
* 卖家订单备注
*
* @param orderSn 订单编号
* @param sellerRemark 卖家订单备注
* @return 订单
*/
Order updateSellerRemark(String orderSn, String sellerRemark);
}

View File

@@ -4,6 +4,8 @@ import cn.lili.common.vo.PageVO;
import cn.lili.modules.order.aftersale.entity.dos.AfterSale;
import cn.lili.modules.order.order.entity.dos.StoreFlow;
import cn.lili.modules.order.order.entity.dto.StoreFlowQueryDTO;
import cn.lili.modules.store.entity.dos.Bill;
import cn.lili.modules.store.entity.dto.BillSearchParams;
import cn.lili.modules.store.entity.vos.StoreFlowPayDownloadVO;
import cn.lili.modules.store.entity.vos.StoreFlowRefundDownloadVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -26,6 +28,12 @@ public interface StoreFlowService extends IService<StoreFlow> {
*/
void payOrder(String orderSn);
/**
* 订单取消
* @param orderSn 订单
*/
void orderCancel(String orderSn);
/**
* 订单退款
*
@@ -93,4 +101,24 @@ public interface StoreFlowService extends IService<StoreFlow> {
* @return 商家流水集合
*/
List<StoreFlow> listStoreFlow(StoreFlowQueryDTO storeFlowQueryDTO);
/**
* 修改分账状态
*/
void updateProfitSharingStatus();
/**
* 获取退款的流水
*
* @param searchParams
* @return
*/
Bill getRefundBill(BillSearchParams searchParams);
/**
* 获取订单的流水
*
* @param searchParams
* @return
*/
Bill getOrderBill(BillSearchParams searchParams);
}

View File

@@ -4,10 +4,12 @@ import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.lili.common.enums.ClientTypeEnum;
import cn.lili.common.enums.PromotionTypeEnum;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.event.TransactionCommitSendMQEvent;
@@ -16,9 +18,11 @@ import cn.lili.common.properties.RocketmqCustomProperties;
import cn.lili.common.security.OperationalJudgment;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.security.enums.UserEnums;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.common.utils.SnowFlake;
import cn.lili.modules.goods.entity.dto.GoodsCompleteMessage;
import cn.lili.modules.member.entity.dto.MemberAddressDTO;
import cn.lili.modules.order.aftersale.entity.enums.ComplaintStatusEnum;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.cart.entity.enums.DeliveryMethodEnum;
import cn.lili.modules.order.order.aop.OrderLogPoint;
@@ -64,7 +68,11 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
@@ -161,6 +169,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
@Autowired
private SettingService settingService;
@Override
@Transactional(rollbackFor = Exception.class)
public void intoDB(TradeDTO tradeDTO) {
@@ -283,8 +292,26 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
}
@Override
public List<OrderExportDTO> queryExportOrder(OrderSearchParams orderSearchParams) {
return this.baseMapper.queryExportOrder(orderSearchParams.queryWrapper());
public void queryExportOrder(HttpServletResponse response, OrderSearchParams orderSearchParams) {
XSSFWorkbook workbook = initOrderExportData(this.baseMapper.queryExportOrder(orderSearchParams.queryWrapper()));
try {
// 设置响应头
String fileName = URLEncoder.encode("订单列表", "UTF-8");
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
ServletOutputStream out = response.getOutputStream();
workbook.write(out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
workbook.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
@@ -326,7 +353,8 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
//修改订单
this.updateById(order);
//生成店铺退款流水
this.generatorStoreRefundFlow(order);
storeFlowService.orderCancel(orderSn);
//发送消息
orderStatusMessage(order);
return order;
} else {
@@ -345,7 +373,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
this.updateById(order);
if (refundMoney) {
//生成店铺退款流水
this.generatorStoreRefundFlow(order);
storeFlowService.orderCancel(orderSn);
orderStatusMessage(order);
}
}
@@ -443,7 +471,8 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
public Order delivery(String orderSn, String logisticsNo, String logisticsId) {
Order order = OperationalJudgment.judgment(this.getBySn(orderSn));
//如果订单未发货,并且订单状态值等于待发货
if (order.getDeliverStatus().equals(DeliverStatusEnum.UNDELIVERED.name()) && order.getOrderStatus().equals(OrderStatusEnum.UNDELIVERED.name())) {
if ((order.getDeliverStatus().equals(DeliverStatusEnum.UNDELIVERED.name()) || order.getDeliverStatus().equals(DeliverStatusEnum.PARTS_DELIVERED.name())) &&
(order.getOrderStatus().equals(OrderStatusEnum.UNDELIVERED.name()) || order.getOrderStatus().equals(OrderStatusEnum.PARTS_DELIVERED.name()))) {
//获取对应物流
Logistics logistics = logisticsService.getById(logisticsId);
if (logistics == null) {
@@ -661,7 +690,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
this.pintuanOrderSuccess(list);
} else if (Boolean.FALSE.equals(pintuan.getFictitious()) && pintuan.getRequiredNum() > list.size()) {
//如果未开启虚拟成团且当前订单数量不足成团数量,则认为拼团失败
this.pintuanOrderFailed(list);
this.pintuanOrderFailed(parentOrderSn);
}
}
@@ -845,7 +874,6 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
throw new ServiceException("发货数量不正确!");
}
orderItem.setDeliverNumber((partDeliveryDTO.getDeliveryNum() + orderItem.getDeliverNumber()));
// 记录分包裹中每个item子单的具体发货信息
OrderPackageItem orderPackageItem = new OrderPackageItem();
orderPackageItem.setOrderSn(orderSn);
@@ -879,10 +907,23 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
//是否全部发货
if (delivery) {
return delivery(orderSn, invoiceNumber, logisticsId);
}else if(order.getDeliverStatus().equals(DeliverStatusEnum.UNDELIVERED.name()) || order.getOrderStatus().equals(OrderStatusEnum.UNDELIVERED.name())){
//更改订单状态为部分发货
order.setDeliverStatus(DeliverStatusEnum.PARTS_DELIVERED.name());
order.setOrderStatus(OrderStatusEnum.PARTS_DELIVERED.name());
this.updateById(order);
}
return order;
}
@Override
public Order updateSellerRemark(String orderSn, String sellerRemark) {
Order order = this.getBySn(orderSn);
order.setSellerRemark(sellerRemark);
this.updateById(order);
return order;
}
/**
* 虚拟成团
*
@@ -945,24 +986,24 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
this.sendUpdateStatusMessage(orderMessage);
}
/**
* 生成店铺退款流水
*
* @param order 订单信息
*/
private void generatorStoreRefundFlow(Order order) {
// 判断订单是否是付款
if (!PayStatusEnum.PAID.name().equals((order.getPayStatus()))) {
return;
}
List<OrderItem> items = orderItemService.getByOrderSn(order.getSn());
List<StoreFlow> storeFlows = new ArrayList<>();
for (OrderItem item : items) {
StoreFlow storeFlow = new StoreFlow(order, item, FlowTypeEnum.REFUND);
storeFlows.add(storeFlow);
}
storeFlowService.saveBatch(storeFlows);
}
// /**
// * 生成店铺退款流水
// *
// * @param order 订单信息
// */
// private void generatorStoreRefundFlow(Order order) {
// // 判断订单是否是付款
// if (!PayStatusEnum.PAID.name().equals((order.getPayStatus()))) {
// return;
// }
// List<OrderItem> items = orderItemService.getByOrderSn(order.getSn());
// List<StoreFlow> storeFlows = new ArrayList<>();
// for (OrderItem item : items) {
// StoreFlow storeFlow = new StoreFlow(order, item, FlowTypeEnum.REFUND);
// storeFlows.add(storeFlow);
// }
// storeFlowService.saveBatch(storeFlows);
// }
/**
* 此方法只提供内部调用,调用前应该做好权限处理
@@ -1054,9 +1095,10 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
/**
* 根据提供的拼团订单列表更新拼团状态为拼团失败
*
* @param list 需要更新拼团状态为失败的拼团订单列表
* @param parentOrderSn 拼团订单sn
*/
private void pintuanOrderFailed(List<Order> list) {
private void pintuanOrderFailed(String parentOrderSn) {
List<Order> list = this.list(new LambdaQueryWrapper<Order>().eq(Order::getParentOrderSn, parentOrderSn).or().eq(Order::getSn, parentOrderSn));
for (Order order : list) {
try {
this.systemCancel(order.getSn(), "拼团人数不足,拼团失败!", true);
@@ -1176,4 +1218,132 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
.set(OrderItem::getComplainStatus, OrderComplaintStatusEnum.EXPIRED.name());
orderItemService.update(lambdaUpdateWrapper);
}
/**
* 初始化填充订单导出数据
*
* @param orderExportDTOList 导出的订单数据
* @return 订单导出列表
*/
private XSSFWorkbook initOrderExportData(List<OrderExportDTO> orderExportDTOList) {
List<OrderExportDetailDTO> orderExportDetailDTOList = new ArrayList<>();
for (OrderExportDTO orderExportDTO : orderExportDTOList) {
OrderExportDetailDTO orderExportDetailDTO = new OrderExportDetailDTO();
BeanUtil.copyProperties(orderExportDTO, orderExportDetailDTO);
//金额
PriceDetailDTO priceDetailDTO = JSONUtil.toBean(orderExportDTO.getPriceDetail(), PriceDetailDTO.class);
orderExportDetailDTO.setFreightPrice(priceDetailDTO.getFreightPrice());
orderExportDetailDTO.setDiscountPrice(CurrencyUtil.add(priceDetailDTO.getDiscountPrice(), priceDetailDTO.getCouponPrice()));
orderExportDetailDTO.setUpdatePrice(priceDetailDTO.getUpdatePrice());
orderExportDetailDTO.setStoreMarketingCost(priceDetailDTO.getSiteCouponCommission());
orderExportDetailDTO.setSiteMarketingCost(CurrencyUtil.sub(orderExportDetailDTO.getDiscountPrice(), orderExportDetailDTO.getStoreMarketingCost()));
//地址
if (StrUtil.isNotBlank(orderExportDTO.getConsigneeAddressPath())) {
String[] receiveAddress = orderExportDTO.getConsigneeAddressPath().split(",");
orderExportDetailDTO.setProvince(receiveAddress[0]);
orderExportDetailDTO.setCity(receiveAddress.length > 1 ?receiveAddress[1]:"");
orderExportDetailDTO.setDistrict(receiveAddress.length > 2 ? receiveAddress[2] : "");
orderExportDetailDTO.setStreet(receiveAddress.length > 3 ? receiveAddress[3] : "");
}
//状态
orderExportDetailDTO.setOrderStatus(OrderStatusEnum.valueOf(orderExportDTO.getOrderStatus()).description());
orderExportDetailDTO.setPaymentMethod(CharSequenceUtil.isNotBlank(orderExportDTO.getPaymentMethod()) ? PaymentMethodEnum.valueOf(orderExportDTO.getPaymentMethod()).paymentName() : "");
orderExportDetailDTO.setClientType(ClientTypeEnum.valueOf(orderExportDTO.getClientType()).value());
orderExportDetailDTO.setOrderType(orderExportDTO.getOrderType().equals(OrderTypeEnum.NORMAL.name()) ? "普通订单" : "虚拟订单");
orderExportDetailDTO.setAfterSaleStatus(OrderItemAfterSaleStatusEnum.valueOf(orderExportDTO.getAfterSaleStatus()).description());
//时间
orderExportDetailDTO.setCreateTime(DateUtil.formatDateTime(orderExportDTO.getCreateTime()));
orderExportDetailDTO.setPaymentTime(DateUtil.formatDateTime(orderExportDTO.getPaymentTime()));
orderExportDetailDTO.setLogisticsTime(DateUtil.formatDateTime(orderExportDTO.getLogisticsTime()));
orderExportDetailDTO.setCompleteTime(DateUtil.formatDateTime(orderExportDTO.getCompleteTime()));
orderExportDetailDTOList.add(orderExportDetailDTO);
}
XSSFWorkbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("订单列表");
// 创建表头
Row header = sheet.createRow(0);
String[] headers = {"主订单编号", "子订单编号", "选购商品", "商品数量", "商品ID", "商品单价", "订单应付金额",
"运费", "优惠总金额", "平台优惠", "商家优惠", "商家改价", "支付方式", "收件人", "收件人手机号",
"", "", "", "街道", "详细地址", "买家留言", "订单提交时间", "支付完成时间", "来源",
"订单状态", "订单类型", "售后状态", "取消原因", "发货时间", "完成时间", "店铺"};
for (int i = 0; i < headers.length; i++) {
Cell cell = header.createCell(i);
cell.setCellValue(headers[i]);
}
// 填充数据
for (int i = 0; i < orderExportDetailDTOList.size(); i++) {
OrderExportDetailDTO dto = orderExportDetailDTOList.get(i);
Row row = sheet.createRow(i + 1);
row.createCell(0).setCellValue(dto.getOrderSn());
row.createCell(1).setCellValue(dto.getOrderItemSn());
row.createCell(2).setCellValue(dto.getGoodsName());
row.createCell(3).setCellValue(dto.getNum());
row.createCell(4).setCellValue(dto.getGoodsId());
row.createCell(5).setCellValue(dto.getUnitPrice()!=null?dto.getUnitPrice():0);
row.createCell(6).setCellValue(dto.getFlowPrice()!=null?dto.getFlowPrice():0);
row.createCell(7).setCellValue(dto.getFreightPrice()!=null?dto.getFreightPrice():0);
row.createCell(8).setCellValue(dto.getDiscountPrice()!=null?dto.getDiscountPrice():0);
row.createCell(9).setCellValue(dto.getSiteMarketingCost()!=null?dto.getSiteMarketingCost():0);
row.createCell(10).setCellValue(dto.getStoreMarketingCost()!=null?dto.getStoreMarketingCost():0);
row.createCell(11).setCellValue(dto.getUpdatePrice()!=null?dto.getUpdatePrice():0);
row.createCell(12).setCellValue(dto.getPaymentMethod());
row.createCell(13).setCellValue(dto.getConsigneeName());
row.createCell(14).setCellValue(dto.getConsigneeMobile());
row.createCell(15).setCellValue(dto.getProvince());
row.createCell(16).setCellValue(dto.getCity());
row.createCell(17).setCellValue(dto.getDistrict());
row.createCell(18).setCellValue(dto.getStreet());
row.createCell(19).setCellValue(dto.getConsigneeDetail());
row.createCell(20).setCellValue(dto.getRemark());
row.createCell(21).setCellValue(dto.getCreateTime());
row.createCell(22).setCellValue(dto.getPaymentTime());
row.createCell(23).setCellValue(dto.getClientType());
row.createCell(24).setCellValue(dto.getOrderStatus());
row.createCell(25).setCellValue(dto.getOrderType());
row.createCell(26).setCellValue(dto.getAfterSaleStatus());
row.createCell(27).setCellValue(dto.getCancelReason());
row.createCell(28).setCellValue(dto.getLogisticsTime());
row.createCell(29).setCellValue(dto.getCompleteTime());
row.createCell(30).setCellValue(dto.getStoreName());
}
//修改列宽
// sheet.setColumnWidth(0, 30 * 256);
// sheet.setColumnWidth(1, 30 * 256);
// sheet.setColumnWidth(2, 30 * 256);
// sheet.setColumnWidth(3, 8 * 256);
// sheet.setColumnWidth(4, 20 * 256);
// sheet.setColumnWidth(5, 10 * 256);
// sheet.setColumnWidth(6, 10 * 256);
// sheet.setColumnWidth(7, 10 * 256);
// sheet.setColumnWidth(8, 10 * 256);
// sheet.setColumnWidth(9, 10 * 256);
// sheet.setColumnWidth(10, 10 * 256);
// sheet.setColumnWidth(11, 10 * 256);
// sheet.setColumnWidth(12, 10 * 256);
// sheet.setColumnWidth(13, 10 * 256);
// sheet.setColumnWidth(14, 16 * 256);
// sheet.setColumnWidth(15, 10 * 256);
// sheet.setColumnWidth(16, 10 * 256);
// sheet.setColumnWidth(17, 10 * 256);
// sheet.setColumnWidth(18, 10 * 256);
// sheet.setColumnWidth(19, 30 * 256);
// sheet.setColumnWidth(20, 20 * 256);
// sheet.setColumnWidth(21, 20 * 256);
// sheet.setColumnWidth(22, 20 * 256);
// sheet.setColumnWidth(23, 10 * 256);
// sheet.setColumnWidth(24, 10 * 256);
// sheet.setColumnWidth(25, 10 * 256);
// sheet.setColumnWidth(26, 10 * 256);
// sheet.setColumnWidth(27, 20 * 256);
// sheet.setColumnWidth(28, 20 * 256);
// sheet.setColumnWidth(29, 20 * 256);
// sheet.setColumnWidth(30, 20 * 256);
return workbook;
}
}

View File

@@ -1,16 +1,20 @@
package cn.lili.modules.order.order.serviceimpl;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.common.utils.SnowFlake;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.distribution.service.DistributionOrderService;
import cn.lili.modules.order.aftersale.entity.dos.AfterSale;
import cn.lili.modules.order.aftersale.service.AfterSaleService;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dos.OrderItem;
import cn.lili.modules.order.order.entity.dos.StoreFlow;
import cn.lili.modules.order.order.entity.dto.StoreFlowProfitSharingDTO;
import cn.lili.modules.order.order.entity.dto.StoreFlowQueryDTO;
import cn.lili.modules.order.order.entity.enums.FlowTypeEnum;
import cn.lili.modules.order.order.entity.enums.PayStatusEnum;
import cn.lili.modules.order.order.entity.enums.ProfitSharingStatusEnum;
import cn.lili.modules.order.order.mapper.StoreFlowMapper;
import cn.lili.modules.order.order.service.OrderItemService;
import cn.lili.modules.order.order.service.OrderService;
@@ -18,9 +22,11 @@ import cn.lili.modules.order.order.service.StoreFlowService;
import cn.lili.modules.payment.entity.RefundLog;
import cn.lili.modules.payment.service.RefundLogService;
import cn.lili.modules.store.entity.dos.Bill;
import cn.lili.modules.store.entity.dto.BillSearchParams;
import cn.lili.modules.store.entity.vos.StoreFlowPayDownloadVO;
import cn.lili.modules.store.entity.vos.StoreFlowRefundDownloadVO;
import cn.lili.modules.store.service.BillService;
import cn.lili.modules.system.entity.dto.payment.WechatPaymentSetting;
import cn.lili.mybatis.util.PageUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@@ -31,6 +37,8 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
@@ -63,7 +71,8 @@ public class StoreFlowServiceImpl extends ServiceImpl<StoreFlowMapper, StoreFlow
private BillService billService;
@Autowired
private AfterSaleService afterSaleService;
private DistributionOrderService distributionOrderService;
/**
* 店铺订单支付流水
*
@@ -79,11 +88,42 @@ public class StoreFlowServiceImpl extends ServiceImpl<StoreFlowMapper, StoreFlow
//循环子订单记录流水
for (OrderItem item : orderItems) {
StoreFlow storeFlow = new StoreFlow(order, item, FlowTypeEnum.PAY);
saveProfitSharing(storeFlow);
//添加付款交易流水
this.save(storeFlow);
}
}
@Override
public void orderCancel(String orderSn) {
//根据订单编号获取订单数据
Order order = orderService.getBySn(orderSn);
// 判断订单是否是付款
if (!PayStatusEnum.PAID.name()
.equals((order.getPayStatus()))) {
return;
}
List<OrderItem> items = orderItemService.getByOrderSn(order.getSn());
List<StoreFlow> storeFlows = new ArrayList<>();
//修改付款记录
this.update(new LambdaUpdateWrapper<StoreFlow>()
.eq(StoreFlow::getOrderSn, order.getSn())
.set(StoreFlow::getBillTime, new Date())
.set(StoreFlow::getProfitSharingStatus, ProfitSharingStatusEnum.ORDER_CANCEL.name())
.set(StoreFlow::getFullRefund, true));
//记录退款记录
for (OrderItem item : items) {
StoreFlow storeFlow = new StoreFlow(order, item, FlowTypeEnum.REFUND);
storeFlow.setProfitSharingStatus(ProfitSharingStatusEnum.ORDER_CANCEL.name());
storeFlow.setBillTime(new Date());
storeFlows.add(storeFlow);
}
this.saveBatch(storeFlows);
}
/**
* 店铺订单退款流水
@@ -110,6 +150,7 @@ public class StoreFlowServiceImpl extends ServiceImpl<StoreFlowMapper, StoreFlow
storeFlow.setSpecs(afterSale.getSpecs());
//获取付款信息
StoreFlow payStoreFlow = this.getOne(new LambdaUpdateWrapper<StoreFlow>().eq(StoreFlow::getOrderItemSn, afterSale.getOrderItemSn())
.eq(StoreFlow::getFlowType, FlowTypeEnum.PAY));
@@ -149,14 +190,58 @@ public class StoreFlowServiceImpl extends ServiceImpl<StoreFlowMapper, StoreFlow
storeFlow.setTransactionId(refundLog.getReceivableNo());
//支付方式
storeFlow.setPaymentName(refundLog.getPaymentName());
//修改付款的StoreFlow
StoreFlowProfitSharingDTO storeFlowProfitSharingDTO = JSONUtil.toBean(payStoreFlow.getProfitSharing(), StoreFlowProfitSharingDTO.class);
if (storeFlow.getBillPrice()
.equals(payStoreFlow.getFinalPrice())) {
payStoreFlow.setFullRefund(true);
storeFlowProfitSharingDTO.setPrice(0D);
storeFlowProfitSharingDTO.setStorePrice(0D);
storeFlowProfitSharingDTO.setPlatformPrice(0D);
storeFlowProfitSharingDTO.setDistributionPrice(0D);
storeFlowProfitSharingDTO.setSubsidies(0D);
payStoreFlow.setBillTime(new Date());
payStoreFlow.setProfitSharingStatus(ProfitSharingStatusEnum.ORDER_CANCEL.name());
//设置退款时间
storeFlow.setBillTime(new Date());
} else {
//计算 累计订单退款金额,修改分账信息
Integer refundNum = this.baseMapper.getRefundNum(payStoreFlow.getOrderItemSn());
refundNum = refundNum == null ? 0 : refundNum;
int allNum = storeFlow.getNum() + refundNum;
Double proportion = CurrencyUtil.div((payStoreFlow.getNum() - allNum), payStoreFlow.getNum());
if (proportion.equals(0D)) {
payStoreFlow.setFullRefund(true);
storeFlowProfitSharingDTO.setPrice(0D);
storeFlowProfitSharingDTO.setStorePrice(0D);
storeFlowProfitSharingDTO.setPlatformPrice(0D);
storeFlowProfitSharingDTO.setDistributionPrice(0D);
storeFlowProfitSharingDTO.setSubsidies(0D);
payStoreFlow.setBillTime(new Date());
payStoreFlow.setProfitSharingStatus(ProfitSharingStatusEnum.ORDER_CANCEL.name());
//设置退款时间
storeFlow.setBillTime(new Date());
} else {
storeFlowProfitSharingDTO.setPrice(CurrencyUtil.mul(payStoreFlow.getFinalPrice(), proportion));
storeFlowProfitSharingDTO.setStorePrice(CurrencyUtil.mul(payStoreFlow.getBillPrice(), proportion));
storeFlowProfitSharingDTO.setPlatformPrice(CurrencyUtil.mul(payStoreFlow.getCommissionPrice(), proportion));
storeFlowProfitSharingDTO.setSubsidies(CurrencyUtil.mul(payStoreFlow.getSiteCouponCommission(), proportion));
storeFlowProfitSharingDTO.setDistributionPrice(CurrencyUtil.mul(payStoreFlow.getDistributionRebate(), proportion));
}
}
payStoreFlow.setProfitSharing(JSONUtil.toJsonStr(storeFlowProfitSharingDTO));
//修改付款流水
this.updateById(payStoreFlow);
//保存退款流水·
this.save(storeFlow);
}
@Override
public IPage<StoreFlow> getStoreFlow(StoreFlowQueryDTO storeFlowQueryDTO) {
return this.page(PageUtil.initPage(storeFlowQueryDTO.getPageVO()), generatorQueryWrapper(storeFlowQueryDTO));
}
@@ -193,6 +278,28 @@ public class StoreFlowServiceImpl extends ServiceImpl<StoreFlowMapper, StoreFlow
return this.list(generatorQueryWrapper(storeFlowQueryDTO));
}
@Override
public void updateProfitSharingStatus() {
//获取已完成的列表,进行相关的处理
List<StoreFlow> storeFlowList = this.baseMapper.completeList();
for (StoreFlow storeFlow : storeFlowList) {
distributionOrderService.completeOrder(storeFlow);
}
this.baseMapper.updateProfitSharingStatus();
}
@Override
public Bill getRefundBill(BillSearchParams searchParams) {
return this.baseMapper.getRefundBill(searchParams.queryWrapper());
}
@Override
public Bill getOrderBill(BillSearchParams searchParams) {
return this.baseMapper.getOrderBill(searchParams.queryWrapper());
}
/**
* 生成查询wrapper
*
@@ -226,9 +333,37 @@ public class StoreFlowServiceImpl extends ServiceImpl<StoreFlowMapper, StoreFlow
if (storeFlowQueryDTO.getBill() != null) {
Bill bill = storeFlowQueryDTO.getBill();
lambdaQueryWrapper.eq(CharSequenceUtil.isNotEmpty(bill.getStoreId()), StoreFlow::getStoreId, bill.getStoreId());
lambdaQueryWrapper.between(bill.getStartTime() != null && bill.getEndTime() != null,
StoreFlow::getCreateTime, bill.getStartTime(), bill.getEndTime());
lambdaQueryWrapper.ge(bill.getStartTime() != null && bill.getEndTime() != null,
StoreFlow::getBillTime, bill.getStartTime());
lambdaQueryWrapper.lt(bill.getStartTime() != null && bill.getEndTime() != null,
StoreFlow::getBillTime, bill.getEndTime());
}
return lambdaQueryWrapper;
}
/**
* 添加分账内容
*
* @param storeFlow 店铺流水
*/
private void saveProfitSharing(StoreFlow storeFlow) {
StoreFlowProfitSharingDTO storeFlowProfitSharingDTO = new StoreFlowProfitSharingDTO();
//店铺获取
storeFlowProfitSharingDTO.setStorePrice(storeFlow.getBillPrice());
//平台佣金
storeFlowProfitSharingDTO.setPlatformPrice(storeFlow.getCommissionPrice());
//分销佣金
storeFlowProfitSharingDTO.setDistributionPrice(storeFlow.getDistributionRebate());
//总金额
storeFlowProfitSharingDTO.setPrice(storeFlow.getFinalPrice());
//平台补差
storeFlowProfitSharingDTO.setSubsidies(storeFlow.getSiteCouponCommission());
//分账详情
storeFlow.setProfitSharing(JSONUtil.toJsonStr(storeFlowProfitSharingDTO));
//分账状态
storeFlow.setProfitSharingStatus(ProfitSharingStatusEnum.WAIT_COMPLETE.name());
}
}

View File

@@ -72,11 +72,6 @@ public class AliPayPlugin implements Payment {
*/
@Autowired
private SettingService settingService;
/**
* API域名
*/
@Autowired
private ApiProperties apiProperties;
/**
* 域名配置
*/
@@ -87,6 +82,7 @@ public class AliPayPlugin implements Payment {
public ResultMessage<Object> h5pay(HttpServletRequest request, HttpServletResponse response, PayParam payParam) {
CashierParam cashierParam = cashierSupport.cashierParam(payParam);
AlipayPaymentSetting alipayPaymentSetting = alipayPaymentSetting();
//请求订单编号
String outTradeNo = SnowFlake.getIdStr();
//准备支付参数
@@ -102,8 +98,8 @@ public class AliPayPlugin implements Payment {
payModel.setProductCode("QUICK_WAP_PAY");
try {
log.info("支付宝H5支付{}", JSONUtil.toJsonStr(payModel));
AliPayRequest.wapPay(response, payModel, callbackUrl(apiProperties.getBuyer(), PaymentMethodEnum.ALIPAY),
notifyUrl(apiProperties.getBuyer(), PaymentMethodEnum.ALIPAY));
AliPayRequest.wapPay(response, payModel, callbackUrl(alipayPaymentSetting.getCallbackUrl(), PaymentMethodEnum.ALIPAY),
notifyUrl(alipayPaymentSetting.getCallbackUrl(), PaymentMethodEnum.ALIPAY));
} catch (Exception e) {
log.error("H5支付异常", e);
throw new ServiceException(ResultCode.ALIPAY_EXCEPTION);
@@ -122,6 +118,7 @@ public class AliPayPlugin implements Payment {
try {
CashierParam cashierParam = cashierSupport.cashierParam(payParam);
AlipayPaymentSetting alipayPaymentSetting = alipayPaymentSetting();
//请求订单编号
String outTradeNo = SnowFlake.getIdStr();
@@ -139,7 +136,7 @@ public class AliPayPlugin implements Payment {
payModel.setProductCode("QUICK_MSECURITY_PAY");
log.info("支付宝APP支付{}", payModel);
String orderInfo = AliPayRequest.appPayToResponse(payModel, notifyUrl(apiProperties.getBuyer(), PaymentMethodEnum.ALIPAY)).getBody();
String orderInfo = AliPayRequest.appPayToResponse(payModel, notifyUrl(alipayPaymentSetting.getCallbackUrl(), PaymentMethodEnum.ALIPAY)).getBody();
log.info("支付宝APP支付返回内容{}", orderInfo);
return ResultUtil.data(orderInfo);
} catch (AlipayApiException e) {
@@ -156,6 +153,7 @@ public class AliPayPlugin implements Payment {
try {
CashierParam cashierParam = cashierSupport.cashierParam(payParam);
AlipayPaymentSetting alipayPaymentSetting = alipayPaymentSetting();
AlipayTradePrecreateModel payModel = new AlipayTradePrecreateModel();
@@ -172,7 +170,7 @@ public class AliPayPlugin implements Payment {
payModel.setOutTradeNo(outTradeNo);
log.info("支付宝扫码:{}", payModel);
String resultStr =
AliPayRequest.tradePrecreatePayToResponse(payModel, notifyUrl(apiProperties.getBuyer(), PaymentMethodEnum.ALIPAY)).getBody();
AliPayRequest.tradePrecreatePayToResponse(payModel, notifyUrl(alipayPaymentSetting.getCallbackUrl(), PaymentMethodEnum.ALIPAY)).getBody();
log.info("支付宝扫码交互返回:{}", resultStr);
JSONObject jsonObject = JSONObject.parseObject(resultStr);
@@ -338,7 +336,7 @@ public class AliPayPlugin implements Payment {
}
/**
* 获取微信支付配置
* 获取支付配置
*
* @return
*/

View File

@@ -20,6 +20,7 @@ import cn.lili.modules.connect.entity.Connect;
import cn.lili.modules.connect.entity.enums.SourceEnum;
import cn.lili.modules.connect.service.ConnectService;
import cn.lili.modules.member.entity.dto.ConnectQueryDTO;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.payment.entity.RefundLog;
import cn.lili.modules.payment.entity.enums.PaymentMethodEnum;
@@ -48,6 +49,7 @@ import cn.lili.modules.system.service.SettingService;
import cn.lili.modules.wallet.entity.dos.MemberWithdrawApply;
import cn.lili.modules.wallet.entity.dto.TransferResultDTO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -93,11 +95,6 @@ public class WechatPlugin implements Payment {
*/
@Autowired
private RefundLogService refundLogService;
/**
* API域名
*/
@Autowired
private ApiProperties apiProperties;
/**
* 配置
*/
@@ -140,7 +137,7 @@ public class WechatPlugin implements Payment {
WechatPaymentSetting setting = wechatPaymentSetting();
String appid = setting.getServiceAppId();
String appid = setting.getH5AppId();
if (appid == null) {
throw new ServiceException(ResultCode.WECHAT_PAYMENT_NOT_SETTING);
}
@@ -151,7 +148,7 @@ public class WechatPlugin implements Payment {
.setOut_trade_no(outOrderNo)
.setTime_expire(timeExpire)
.setAttach(attach)
.setNotify_url(notifyUrl(apiProperties.getBuyer(), PaymentMethodEnum.WECHAT))
.setNotify_url(notifyUrl(wechatPaymentSetting().getCallbackUrl(),PaymentMethodEnum.WECHAT))
.setAmount(new Amount().setTotal(fen)).setScene_info(sceneInfo);
log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
@@ -166,6 +163,8 @@ public class WechatPlugin implements Payment {
JSONUtil.toJsonStr(unifiedOrderModel)
);
updateOrderPayNo(payParam,outOrderNo);
return ResultUtil.data(JSONUtil.toJsonStr(response.getBody()));
} catch (Exception e) {
log.error("微信H5支付错误", e);
@@ -199,7 +198,7 @@ public class WechatPlugin implements Payment {
String attach = URLEncoder.createDefault().encode(JSONUtil.toJsonStr(payParam), StandardCharsets.UTF_8);
WechatPaymentSetting setting = wechatPaymentSetting();
String appid = setting.getServiceAppId();
String appid = setting.getJsapiAppId();
if (appid == null) {
throw new ServiceException(ResultCode.WECHAT_PAYMENT_NOT_SETTING);
}
@@ -210,7 +209,7 @@ public class WechatPlugin implements Payment {
.setOut_trade_no(outOrderNo)
.setTime_expire(timeExpire)
.setAttach(attach)
.setNotify_url(notifyUrl(apiProperties.getBuyer(), PaymentMethodEnum.WECHAT))
.setNotify_url(notifyUrl(wechatPaymentSetting().getCallbackUrl(), PaymentMethodEnum.WECHAT))
.setAmount(new Amount().setTotal(fen))
.setPayer(payer);
@@ -237,6 +236,8 @@ public class WechatPlugin implements Payment {
Map<String, String> map = WxPayKit.jsApiCreateSign(appid, prepayId, setting.getApiclient_key());
log.info("唤起支付参数:{}", map);
updateOrderPayNo(payParam,outOrderNo);
return ResultUtil.data(map);
}
log.error("微信支付参数验证错误,请及时处理");
@@ -264,7 +265,7 @@ public class WechatPlugin implements Payment {
String attach = URLEncoder.createDefault().encode(JSONUtil.toJsonStr(payParam), StandardCharsets.UTF_8);
WechatPaymentSetting setting = wechatPaymentSetting();
String appid = setting.getAppId();
String appid = setting.getJsapiAppId();
if (appid == null) {
throw new ServiceException(ResultCode.WECHAT_PAYMENT_NOT_SETTING);
}
@@ -275,7 +276,7 @@ public class WechatPlugin implements Payment {
.setOut_trade_no(outOrderNo)
.setTime_expire(timeExpire)
.setAttach(attach)
.setNotify_url(notifyUrl(apiProperties.getBuyer(), PaymentMethodEnum.WECHAT))
.setNotify_url(notifyUrl(wechatPaymentSetting().getCallbackUrl(), PaymentMethodEnum.WECHAT))
.setAmount(new Amount().setTotal(fen));
@@ -304,6 +305,8 @@ public class WechatPlugin implements Payment {
setting.getApiclient_key(), SignType.MD5);
log.info("唤起支付参数:{}", map);
updateOrderPayNo(payParam,outOrderNo);
return ResultUtil.data(map);
}
log.error("微信支付参数验证错误,请及时处理");
@@ -332,7 +335,7 @@ public class WechatPlugin implements Payment {
WechatPaymentSetting setting = wechatPaymentSetting();
String appid = setting.getServiceAppId();
String appid = setting.getNativeAppId();
if (appid == null) {
throw new ServiceException(ResultCode.WECHAT_PAYMENT_NOT_SETTING);
}
@@ -344,7 +347,7 @@ public class WechatPlugin implements Payment {
.setTime_expire(timeExpire)
//回传参数
.setAttach(attach)
.setNotify_url(notifyUrl(apiProperties.getBuyer(), PaymentMethodEnum.WECHAT))
.setNotify_url(notifyUrl(wechatPaymentSetting().getCallbackUrl(), PaymentMethodEnum.WECHAT))
.setAmount(new Amount().setTotal(fen));
log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
@@ -364,6 +367,8 @@ public class WechatPlugin implements Payment {
log.info("verifySignature: {}", verifySignature);
if (verifySignature) {
updateOrderPayNo(payParam,outOrderNo);
return ResultUtil.data(new JSONObject(response.getBody()).getStr("code_url"));
} else {
log.error("微信支付参数验证错误,请及时处理");
@@ -417,7 +422,7 @@ public class WechatPlugin implements Payment {
.setOut_trade_no(outOrderNo)
.setTime_expire(timeExpire)
.setAttach(attach)
.setNotify_url(notifyUrl(apiProperties.getBuyer(), PaymentMethodEnum.WECHAT))
.setNotify_url(notifyUrl(wechatPaymentSetting().getCallbackUrl(), PaymentMethodEnum.WECHAT))
.setAmount(new Amount().setTotal(fen))
.setPayer(payer);
@@ -443,7 +448,7 @@ public class WechatPlugin implements Payment {
String prepayId = jsonObject.getStr("prepay_id");
Map<String, String> map = WxPayKit.jsApiCreateSign(appid, prepayId, setting.getApiclient_key());
log.info("唤起支付参数:{}", map);
updateOrderPayNo(payParam,outOrderNo);
return ResultUtil.data(map);
}
log.error("微信支付参数验证错误,请及时处理");
@@ -618,7 +623,7 @@ public class WechatPlugin implements Payment {
.setOut_refund_no(refundLog.getOutOrderNo())
.setReason(refundLog.getRefundReason())
.setAmount(amount)
.setNotify_url(refundNotifyUrl(apiProperties.getBuyer(), PaymentMethodEnum.WECHAT));
.setNotify_url(refundNotifyUrl(wechatPaymentSetting().getCallbackUrl(), PaymentMethodEnum.WECHAT));
WechatPaymentSetting setting = wechatPaymentSetting();
@@ -788,4 +793,21 @@ public class WechatPlugin implements Payment {
cipherText
);
}
/**
* 修改订单支付单号
* @param payParam 支付参数
* @param outOrderNo 订单号
*/
private void updateOrderPayNo(PayParam payParam,String outOrderNo ){
if(payParam.getOrderType().equals("ORDER")){
orderService.update(new LambdaUpdateWrapper<Order>()
.eq(Order::getSn,payParam.getSn())
.set(Order::getPayOrderNo,outOrderNo));
}else if(payParam.getOrderType().equals("TRADE")){
orderService.update(new LambdaUpdateWrapper<Order>()
.eq(Order::getTradeSn,payParam.getSn())
.set(Order::getPayOrderNo,outOrderNo));
}
}
}

View File

@@ -4,7 +4,6 @@ import cn.lili.cache.CachePrefix;
import cn.lili.common.enums.PromotionTypeEnum;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.dto.GoodsSkuDTO;
import cn.lili.modules.promotion.entity.dos.PromotionGoods;
import cn.lili.modules.promotion.entity.dto.search.PromotionGoodsSearchParams;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -52,7 +51,7 @@ public interface PromotionGoodsService extends IService<PromotionGoods> {
* @param skus 商品skuId
* @return 促销商品集合
*/
List<PromotionGoods> findSkuValidPromotions(List<GoodsSkuDTO> skus);
List<PromotionGoods> findSkuValidPromotions(List<String> skus);
/**
* 分页获取促销商品信息

View File

@@ -29,7 +29,7 @@ import cn.lili.trigger.model.TimeExecuteConstant;
import cn.lili.trigger.model.TimeTriggerMsg;
import cn.lili.trigger.util.DelayQueueTools;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import groovy.util.logging.Slf4j;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -46,8 +46,8 @@ import java.util.stream.Collectors;
* @author Bulbasaur
* @since 2021/5/20 6:10 下午
*/
@Slf4j
@Service
@Slf4j
public class CouponActivityServiceImpl extends AbstractPromotionsServiceImpl<CouponActivityMapper, CouponActivity> implements CouponActivityService {
@Autowired
@@ -227,15 +227,18 @@ public class CouponActivityServiceImpl extends AbstractPromotionsServiceImpl<Cou
/**
* 自动发送优惠券则需要补足日志
*/
if (couponActivityTrigger.getCouponActivityTypeEnum().equals(CouponActivityTypeEnum.AUTO_COUPON)) {
if (couponActivityTrigger.getCouponActivityTypeEnum().equals(CouponActivityTypeEnum.AUTO_COUPON) || couponActivityTrigger.getCouponActivityTypeEnum().equals(CouponActivityTypeEnum.SPECIFY)) {
couponActivities = memberCouponSignService.receiveCoupon(couponActivities);
}
//优惠券发放列表
log.info("当前用户的优惠券活动信息:{}", couponActivityTrigger);
log.info("当前进行的优惠券活动:{}", couponActivities);
List<CouponActivityItemVO> couponActivityItemVOS = new ArrayList<>();
//准备发放优惠券活动的列表
couponActivities.stream().forEach(item -> couponActivityItemVOS.addAll(item.getCouponActivityItems()));
couponActivities.forEach(item -> couponActivityItemVOS.addAll(item.getCouponActivityItems()));
AuthUser authUser = new AuthUser();
authUser.setId(couponActivityTrigger.getUserId());

View File

@@ -107,8 +107,10 @@ public class PintuanServiceImpl extends AbstractPromotionsServiceImpl<PintuanMap
//获取已参团人数
this.setMemberVONum(memberVO, pintuan.getRequiredNum(), order.getSn());
memberVO.setOrderSn(order.getSn());
if (memberVO.getToBeGroupedNum() > 0) {
members.add(memberVO);
}
}
return members;
}

View File

@@ -1,15 +1,12 @@
package cn.lili.modules.promotion.serviceimpl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.lili.cache.Cache;
import cn.lili.common.enums.PromotionTypeEnum;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.dto.GoodsSkuDTO;
import cn.lili.modules.goods.entity.vos.GoodsVO;
import cn.lili.modules.goods.service.GoodsService;
import cn.lili.modules.goods.service.GoodsSkuService;
@@ -34,7 +31,6 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -52,11 +48,6 @@ public class PromotionGoodsServiceImpl extends ServiceImpl<PromotionGoodsMapper,
private static final String SKU_ID_COLUMN = "sku_id";
/**
* Redis
*/
@Autowired
private StringRedisTemplate stringRedisTemplate;
/**
* 秒杀活动申请
*/
@@ -96,22 +87,12 @@ public class PromotionGoodsServiceImpl extends ServiceImpl<PromotionGoodsMapper,
}
@Override
public List<PromotionGoods> findSkuValidPromotions(List<GoodsSkuDTO> skus) {
List<String> categories = skus.stream().map(GoodsSku::getCategoryPath).collect(Collectors.toList());
List<String> skuIds = skus.stream().map(GoodsSku::getId).collect(Collectors.toList());
List<String> categoriesPath = new ArrayList<>();
categories.forEach(i -> {
if (CharSequenceUtil.isNotEmpty(i)) {
categoriesPath.addAll(Arrays.asList(i.split(",")));
}
}
);
public List<PromotionGoods> findSkuValidPromotions(List<String> skuIds) {
QueryWrapper<PromotionGoods> queryWrapper = new QueryWrapper<>();
queryWrapper.and(i -> i.or(j -> j.in(SKU_ID_COLUMN, skuIds))
.or(n -> n.eq("scope_type", PromotionsScopeTypeEnum.ALL.name()))
.or(n -> n.and(k -> k.eq("scope_type", PromotionsScopeTypeEnum.PORTION_GOODS_CATEGORY.name())
.and(l -> l.in(CollUtil.isNotEmpty(categoriesPath), "scope_id", categoriesPath)))));
.or(n -> n.and(k -> k.eq("scope_type", PromotionsScopeTypeEnum.PORTION_GOODS_CATEGORY.name()))));
queryWrapper.and(i -> i.or(PromotionTools.queryPromotionStatus(PromotionsStatusEnum.START)).or(PromotionTools.queryPromotionStatus(PromotionsStatusEnum.NEW)));
return this.list(queryWrapper);
}

View File

@@ -172,11 +172,11 @@ public class SeckillApplyServiceImpl extends ServiceImpl<SeckillApplyMapper, Sec
for (SeckillApplyVO seckillApply : seckillApplyList) {
//获取参与活动的商品信息
GoodsSku goodsSku = goodsSkuService.getCanPromotionGoodsSkuByIdFromCache(seckillApply.getSkuId());
if (!goodsSku.getStoreId().equals(storeId)) {
continue;
}
// if (!goodsSku.getStoreId().equals(storeId)) {
// continue;
// }
//获取秒杀活动时间段
DateTime startTime = DateUtil.offsetHour(seckill.getStartTime(), seckillApply.getTimeLine());
DateTime startTime = DateUtil.offsetHour(DateUtil.beginOfDay(seckill.getStartTime()), seckillApply.getTimeLine());
//检测是否可以发布促销商品
checkSeckillGoodsSku(seckill, seckillApply, goodsSku, startTime);
//设置秒杀申请默认内容

View File

@@ -205,11 +205,20 @@ public class PromotionTools {
try {
//移除无效促销活动
return map.entrySet().stream().filter(Objects::nonNull).filter(i -> {
try {
if (JSONUtil.isTypeJSON(JSONUtil.toJsonStr(i.getValue()))) {
JSONObject promotionsObj = JSONUtil.parseObj(i.getValue());
BasePromotions basePromotions = promotionsObj.toBean(BasePromotions.class);
if (basePromotions != null && basePromotions.getStartTime() != null && basePromotions.getEndTime() != null) {
return basePromotions.getStartTime().getTime() <= System.currentTimeMillis() && basePromotions.getEndTime().getTime() >= System.currentTimeMillis();
}
} else {
return false;
}
} catch (Exception ee) {
log.debug("转换异常促销活动信息:{}", i);
return false;
}
return i.getValue() != null;
}).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> newValue));
} catch (Exception e) {

View File

@@ -196,7 +196,8 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
if (skuIPage == null || CollUtil.isEmpty(skuIPage.getRecords())) {
break;
}
List<PromotionGoods> skuValidPromotions = promotionGoodsService.findSkuValidPromotions(skuIPage.getRecords());
List<String> skuIds = skuIPage.getRecords().stream().map(GoodsSku::getId).collect(Collectors.toList());
List<PromotionGoods> skuValidPromotions = promotionGoodsService.findSkuValidPromotions(skuIds);
List<String> brandIds = new ArrayList<>();
@@ -248,7 +249,9 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
(CharSequenceUtil.isNotEmpty(j.getSkuId()) && j.getSkuId().equals(goodsSku.getId())) ||
(j.getScopeType().equals(PromotionsScopeTypeEnum.ALL.name()) && j.getStoreId().equals("0")) ||
(j.getScopeType().equals(PromotionsScopeTypeEnum.ALL.name()) && j.getStoreId().equals(esGoodsIndex.getStoreId())) ||
(j.getScopeType().equals(PromotionsScopeTypeEnum.PORTION_GOODS_CATEGORY.name()) && j.getScopeId().contains(goodsSku.getCategoryPath())))
(j.getScopeType().equals(PromotionsScopeTypeEnum.PORTION_GOODS_CATEGORY.name()) && j.getStoreId().equals("0") && j.getScopeId().contains(goodsSku.getCategoryPath()))||
(j.getScopeType().equals(PromotionsScopeTypeEnum.PORTION_GOODS_CATEGORY.name()) && j.getStoreId().equals(goodsSku.getStoreId()) && j.getScopeId().contains(goodsSku.getCategoryPath()))
)
.collect(Collectors.toList());
if (CollUtil.isNotEmpty(promotionGoods)) {
esGoodsIndex.setPromotionMapJson(JSONUtil.toJsonStr(promotionService.wrapperPromotionMapList(promotionGoods)));

View File

@@ -88,6 +88,7 @@ public class EsGoodsSearchServiceImpl implements EsGoodsSearchService {
cache.incrementScore(CachePrefix.HOT_WORD.getPrefix(), searchDTO.getKeyword());
}
NativeSearchQueryBuilder searchQueryBuilder = createSearchQueryBuilder(searchDTO, pageVo);
// searchQueryBuilder.withCollapseField("goodsId.keyword");
NativeSearchQuery searchQuery = searchQueryBuilder.build();
searchQuery.setTrackTotalHits(true);
log.debug("searchGoods DSL:{}", searchQuery.getQuery());
@@ -130,6 +131,7 @@ public class EsGoodsSearchServiceImpl implements EsGoodsSearchService {
//品牌
AggregationBuilder brandNameBuilder = AggregationBuilders.terms(ATTR_BRAND_NAME).field("brandName.keyword");
builder.addAggregation(AggregationBuilders.terms("brandIdNameAgg").field(ATTR_BRAND_ID).size(Integer.MAX_VALUE).subAggregation(brandNameBuilder));
AggregationBuilder brandUrlBuilder = AggregationBuilders.terms(ATTR_BRAND_URL).field("brandUrl.keyword");
builder.addAggregation(AggregationBuilders.terms("brandIdUrlAgg").field(ATTR_BRAND_ID).size(Integer.MAX_VALUE).subAggregation(brandUrlBuilder));
//参数

View File

@@ -5,8 +5,6 @@ import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.properties.SmsTemplateProperties;
import cn.lili.common.properties.SystemSettingProperties;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.CommonUtil;
import cn.lili.modules.member.entity.dos.Member;
@@ -48,12 +46,6 @@ public class SmsUtilAliImplService implements SmsUtil {
@Autowired
private SmsPluginFactory smsPluginFactory;
@Autowired
private SmsTemplateProperties smsTemplateProperties;
@Autowired
private SystemSettingProperties systemSettingProperties;
@Override
public void sendSmsCode(String mobile, VerificationEnums verificationEnums, String uuid) {
//获取短信配置
@@ -78,18 +70,18 @@ public class SmsUtilAliImplService implements SmsUtil {
switch (verificationEnums) {
//登录
case LOGIN: {
templateCode = smsTemplateProperties.getLOGIN();
templateCode = smsSetting.getLoginTemplateCode();
break;
}
//注册
case BIND_MOBILE:
case REGISTER: {
templateCode = smsTemplateProperties.getREGISTER();
templateCode = smsSetting.getRegisterTemplateCode();
break;
}
//找回密码
case FIND_USER: {
templateCode = smsTemplateProperties.getFIND_USER();
templateCode = smsSetting.getFindPasswordTemplateCode();
break;
}
//修改密码
@@ -100,7 +92,7 @@ public class SmsUtilAliImplService implements SmsUtil {
}
//更新为用户最新手机号
mobile = member.getMobile();
templateCode = smsTemplateProperties.getUPDATE_PASSWORD();
templateCode = smsSetting.getFindPasswordTemplateCode();
break;
}
//设置支付密码
@@ -108,7 +100,7 @@ public class SmsUtilAliImplService implements SmsUtil {
Member member = memberService.getById(UserContext.getCurrentUser().getId());
//更新为用户最新手机号
mobile = member.getMobile();
templateCode = smsTemplateProperties.getWALLET_PASSWORD();
templateCode = smsSetting.getWalletPasswordTemplateCode();
break;
}
//如果不是有效的验证码手段,则此处不进行短信操作
@@ -116,7 +108,7 @@ public class SmsUtilAliImplService implements SmsUtil {
return;
}
//如果是测试模式 默认验证码 6个1
if (systemSettingProperties.getIsTestModel()) {
if (smsSetting.getIsTestModel()) {
code = "111111";
log.info("测试模式 - 接收手机:{},验证码:{}", mobile, code);
} else {

View File

@@ -1,5 +1,6 @@
package cn.lili.modules.store.entity.dto;
import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.security.enums.UserEnums;
import cn.lili.common.utils.StringUtils;
@@ -8,9 +9,14 @@ import cn.lili.modules.store.entity.enums.BillStatusEnum;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* 结算单搜索参数
*
@@ -18,6 +24,9 @@ import org.springframework.format.annotation.DateTimeFormat;
* @since 2021/3/17 6:08 下午
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class BillSearchParams extends PageVO {
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@@ -39,32 +48,99 @@ public class BillSearchParams extends PageVO {
@ApiModelProperty(value = "状态OUT(已出账),CHECK(已对账),EXAMINE(已审核),PAY(已付款)")
private String billStatus;
@ApiModelProperty(value = "流水类型")
private String flowType;
@ApiModelProperty(value = "店铺名称")
private String storeName;
@ApiModelProperty(value = "店铺ID", hidden = true)
@ApiModelProperty(value = "店铺ID")
private String storeId;
@ApiModelProperty(value = "支付方式")
private String paymentName;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "起始日期")
private Date startTime;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "起始日期")
private Date endTime;
public <T> QueryWrapper<T> queryWrapper() {
QueryWrapper<T> wrapper = new QueryWrapper<>();
//创建时间
if (StringUtils.isNotEmpty(startDate) && StringUtils.isNotEmpty(endDate)) {
if (CharSequenceUtil.isNotEmpty(startDate) && CharSequenceUtil.isNotEmpty(endDate)) {
wrapper.between("bill_time", startDate, endDate);
} else if (CharSequenceUtil.isNotEmpty(startDate)) {
wrapper.ge("bill_time", startDate);
} else if (CharSequenceUtil.isNotEmpty(endDate)) {
wrapper.le("bill_time", endDate);
}
//账单号
wrapper.eq(CharSequenceUtil.isNotEmpty(sn), "sn", sn);
//结算状态
wrapper.eq(CharSequenceUtil.isNotEmpty(billStatus), "bill_status", billStatus);
//店铺名称
wrapper.eq(CharSequenceUtil.isNotEmpty(storeName), "store_name", storeName);
//按卖家查询
wrapper.eq(CharSequenceUtil.isNotEmpty(storeId),
"store_id", storeId);
//按卖家查询
wrapper.eq(CharSequenceUtil.isNotEmpty(paymentName),
"payment_name", paymentName);
wrapper.eq(CharSequenceUtil.isNotEmpty(flowType), "flow_type", flowType);
if (startTime != null && endTime != null) {
wrapper.between("bill_time", startTime, endTime);
} else if (startTime != null) {
wrapper.ge("bill_time", startTime);
} else if (endTime != null) {
wrapper.le("bill_time", endTime);
}
return wrapper;
}
public <T> QueryWrapper<T> queryWrapperBillList() {
QueryWrapper<T> wrapper = new QueryWrapper<>();
//创建时间
if (CharSequenceUtil.isNotEmpty(startDate) && CharSequenceUtil.isNotEmpty(endDate)) {
wrapper.between("create_time", startDate, endDate);
} else if (StringUtils.isNotEmpty(startDate)) {
} else if (CharSequenceUtil.isNotEmpty(startDate)) {
wrapper.ge("create_time", startDate);
} else if (StringUtils.isNotEmpty(endDate)) {
} else if (CharSequenceUtil.isNotEmpty(endDate)) {
wrapper.le("create_time", endDate);
}
//账单号
wrapper.eq(StringUtils.isNotEmpty(sn), "sn", sn);
wrapper.eq(CharSequenceUtil.isNotEmpty(sn), "sn", sn);
//结算状态
wrapper.eq(StringUtils.isNotEmpty(billStatus), "bill_status", billStatus);
wrapper.eq(CharSequenceUtil.isNotEmpty(billStatus), "bill_status", billStatus);
//店铺名称
wrapper.eq(StringUtils.isNotEmpty(storeName), "store_name", storeName);
wrapper.eq(CharSequenceUtil.isNotEmpty(storeName), "store_name", storeName);
//按卖家查询
wrapper.eq(StringUtils.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name()),
"store_id", UserContext.getCurrentUser().getStoreId());
wrapper.eq(CharSequenceUtil.isNotEmpty(storeId),
"store_id", storeId);
//按卖家查询
wrapper.eq(CharSequenceUtil.isNotEmpty(paymentName),
"payment_name", paymentName);
wrapper.eq(CharSequenceUtil.isNotEmpty(flowType), "flow_type", flowType);
if (startTime != null && endTime != null) {
wrapper.between("create_time", startTime, endTime);
} else if (startTime != null) {
wrapper.ge("create_time", startTime);
} else if (endTime != null) {
wrapper.le("create_time", endTime);
}
return wrapper;
}

View File

@@ -29,34 +29,6 @@ public interface BillMapper extends BaseMapper<Bill> {
@Select("select b.id,b.sn,b.start_time,b.end_time,b.bill_status,b.store_name,b.bill_price,b.create_time from li_bill as b ${ew.customSqlSegment}")
IPage<BillListVO> queryBillPage(IPage<BillListVO> page, @Param(Constants.WRAPPER) Wrapper<BillListVO> queryWrapper);
/**
* 查询订单结算
*
* @param queryWrapper 查询条件
* @return 结算单
*/
@Select("SELECT IFNULL(SUM( final_price ),0) AS orderPrice" +
",IFNULL(SUM( commission_price ),0) AS commissionPrice" +
",IFNULL(SUM( distribution_rebate ),0) AS distributionCommission" +
",IFNULL(SUM( site_coupon_commission ),0) AS siteCouponCommission" +
",IFNULL(SUM( point_settlement_price ),0) AS pointSettlementPrice " +
",IFNULL(SUM( kanjia_settlement_price ),0) AS kanjiaSettlementPrice " +
",IFNULL(SUM( bill_price ),0) AS billPrice " +
"FROM li_store_flow ${ew.customSqlSegment}")
Bill getOrderBill(@Param(Constants.WRAPPER) QueryWrapper<Bill> queryWrapper);
/**
* 查询退款结算单
*
* @param queryWrapper 查询条件
* @return 结算单
*/
@Select("SELECT IFNULL(SUM( final_price ),0) AS refundPrice" +
",IFNULL(SUM( commission_price ),0) AS refundCommissionPrice" +
",IFNULL(SUM( distribution_rebate ),0) AS distributionRefundCommission" +
",IFNULL(SUM( site_coupon_commission ),0) AS siteCouponRefundCommission" +
",IFNULL(SUM( kanjia_settlement_price ),0) AS kanjiaRefundSettlementPrice" +
",IFNULL(SUM( point_settlement_price ),0) AS pointRefundSettlementPrice" +
",IFNULL(SUM( bill_price ),0) AS billPrice FROM li_store_flow ${ew.customSqlSegment}")
Bill getRefundBill(@Param(Constants.WRAPPER) QueryWrapper<Bill> queryWrapper);
}

View File

@@ -34,7 +34,7 @@ public interface FreightTemplateService extends IService<FreightTemplate> {
* @param storeId
* @return 运费模板列表
*/
List<FreightTemplateVO> getFreightTemplateList(String storeId);
List<FreightTemplateVO> getFreightTemplateList();
/**
* 获取运费模板详细信息

View File

@@ -30,10 +30,6 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
@@ -41,9 +37,11 @@ import org.springframework.transaction.annotation.Transactional;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* 结算单业务层实现
@@ -92,8 +90,30 @@ public class BillServiceImpl extends ServiceImpl<BillMapper, Bill> implements Bi
//店铺结算单号
bill.setSn(SnowFlake.createStr("B"));
//结算金额初始化
initBillPrice(bill, storeId, startTime, endTime);
//添加结算单
this.save(bill);
}
/**
* 结算单金额初始化
*
* @param bill 结算单
* @param storeId 店铺ID
* @param startTime 开始时间
* @param endTime 结束时间
*/
private void initBillPrice(Bill bill, String storeId, Date startTime, DateTime endTime) {
//退款结算信息
Bill refundBill = this.baseMapper.getRefundBill(new QueryWrapper<Bill>().eq("store_id", storeId).eq("flow_type", FlowTypeEnum.REFUND.name()).between("create_time", startTime, endTime));
Bill refundBill = storeFlowService.getRefundBill(BillSearchParams.builder()
.storeId(storeId)
.flowType(FlowTypeEnum.REFUND.name())
.startTime(startTime)
.endTime(endTime)
.build());
//店铺退款金额
if (refundBill != null) {
//退单金额
@@ -112,10 +132,13 @@ public class BillServiceImpl extends ServiceImpl<BillMapper, Bill> implements Bi
}
/**
* @TODO 入账结算信息
*/
Bill orderBill = this.baseMapper.getOrderBill(new QueryWrapper<Bill>().eq("store_id", storeId).eq("flow_type", FlowTypeEnum.PAY.name()).between("create_time", startTime, endTime));
//入账
Bill orderBill = this.storeFlowService.getOrderBill(BillSearchParams.builder()
.storeId(storeId)
.flowType(FlowTypeEnum.PAY.name())
.startTime(startTime)
.endTime(endTime)
.build());
//店铺入款结算金额
if (orderBill != null) {
@@ -131,16 +154,12 @@ public class BillServiceImpl extends ServiceImpl<BillMapper, Bill> implements Bi
bill.setPointSettlementPrice(orderBill.getPointSettlementPrice() != null ? orderBill.getPointSettlementPrice() : 0D);
//砍价商品结算价格
bill.setKanjiaSettlementPrice(orderBill.getKanjiaSettlementPrice() != null ? orderBill.getKanjiaSettlementPrice() : 0D);
}
//最终结算金额=入款结算金额-退款结算金额
Double finalPrice = CurrencyUtil.sub(orderBill.getBillPrice(), refundBill.getBillPrice());
//店铺最终结算金额=最终结算金额
bill.setBillPrice(finalPrice);
//添加结算单
this.save(bill);
}
@@ -271,7 +290,6 @@ public class BillServiceImpl extends ServiceImpl<BillMapper, Bill> implements Bi
writer.writeRow(map, true);
writer.setSheet("入账订单");
writer.addHeaderAlias("createTime", "入账时间");
writer.setColumnWidth(0, 20);

View File

@@ -48,17 +48,15 @@ public class FreightTemplateServiceImpl extends ServiceImpl<FreightTemplateMappe
@Override
public List<FreightTemplateVO> getFreightTemplateList(String storeId) {
public List<FreightTemplateVO> getFreightTemplateList() {
//先从缓存中获取运费模板,如果有则直接返回,如果没有则查询数据后再返回
List<FreightTemplateVO> list = (List<FreightTemplateVO>) cache.get(CachePrefix.SHIP_TEMPLATE.getPrefix() + storeId);
List<FreightTemplateVO> list = (List<FreightTemplateVO>) cache.get(CachePrefix.SHIP_TEMPLATE.getPrefix());
if (list != null) {
return list;
}
list = new ArrayList<>();
//查询运费模板
LambdaQueryWrapper<FreightTemplate> lambdaQueryWrapper = Wrappers.lambdaQuery();
lambdaQueryWrapper.eq(FreightTemplate::getStoreId, storeId);
List<FreightTemplate> freightTemplates = this.baseMapper.selectList(lambdaQueryWrapper);
List<FreightTemplate> freightTemplates = this.list();
if (!freightTemplates.isEmpty()) {
//如果模板不为空则查询子模板信息
for (FreightTemplate freightTemplate : freightTemplates) {
@@ -71,16 +69,14 @@ public class FreightTemplateServiceImpl extends ServiceImpl<FreightTemplateMappe
list.add(freightTemplateVO);
}
}
cache.put(CachePrefix.SHIP_TEMPLATE.getPrefix() + storeId, list);
cache.put(CachePrefix.SHIP_TEMPLATE.getPrefix(), list);
return list;
}
@Override
public IPage<FreightTemplate> getFreightTemplate(PageVO pageVo) {
LambdaQueryWrapper<FreightTemplate> lambdaQueryWrapper = Wrappers.lambdaQuery();
lambdaQueryWrapper.eq(FreightTemplate::getStoreId, UserContext.getCurrentUser().getStoreId());
return this.baseMapper.selectPage(PageUtil.initPage(pageVo), lambdaQueryWrapper);
return this.page(PageUtil.initPage(pageVo));
}
@Override
@@ -101,10 +97,7 @@ public class FreightTemplateServiceImpl extends ServiceImpl<FreightTemplateMappe
@Override
public FreightTemplateVO addFreightTemplate(FreightTemplateVO freightTemplateVO) {
//获取当前登录商家账号
AuthUser tokenUser = UserContext.getCurrentUser();
FreightTemplate freightTemplate = new FreightTemplate();
//设置店铺ID
freightTemplateVO.setStoreId(tokenUser.getStoreId());
//复制属性
BeanUtils.copyProperties(freightTemplateVO, freightTemplate);
//添加运费模板
@@ -122,7 +115,7 @@ public class FreightTemplateServiceImpl extends ServiceImpl<FreightTemplateMappe
}
//更新缓存
cache.remove(CachePrefix.SHIP_TEMPLATE.getPrefix() + tokenUser.getStoreId());
cache.remove(CachePrefix.SHIP_TEMPLATE.getPrefix());
return freightTemplateVO;
}
@@ -130,10 +123,10 @@ public class FreightTemplateServiceImpl extends ServiceImpl<FreightTemplateMappe
@Transactional(rollbackFor = Exception.class)
public FreightTemplateVO editFreightTemplate(FreightTemplateVO freightTemplateVO) {
//获取当前登录商家账号
AuthUser tokenUser = UserContext.getCurrentUser();
if (freightTemplateVO.getId().equals(tokenUser.getStoreId())) {
throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR);
}
// AuthUser tokenUser = UserContext.getCurrentUser();
// if (freightTemplateVO.getId().equals(tokenUser.getStoreId())) {
// throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR);
// }
FreightTemplate freightTemplate = new FreightTemplate();
//复制属性
BeanUtils.copyProperties(freightTemplateVO, freightTemplate);
@@ -150,7 +143,7 @@ public class FreightTemplateServiceImpl extends ServiceImpl<FreightTemplateMappe
//添加模板子内容
freightTemplateChildService.addFreightTemplateChild(list);
//更新缓存
cache.remove(CachePrefix.SHIP_TEMPLATE.getPrefix() + tokenUser.getStoreId());
cache.remove(CachePrefix.SHIP_TEMPLATE.getPrefix());
return null;
}
@@ -159,13 +152,11 @@ public class FreightTemplateServiceImpl extends ServiceImpl<FreightTemplateMappe
@Transactional(rollbackFor = Exception.class)
public boolean removeFreightTemplate(String id) {
//获取当前登录商家账号
AuthUser tokenUser = UserContext.getCurrentUser();
LambdaQueryWrapper<FreightTemplate> lambdaQueryWrapper = Wrappers.lambdaQuery();
lambdaQueryWrapper.eq(FreightTemplate::getStoreId, tokenUser.getStoreId());
lambdaQueryWrapper.eq(FreightTemplate::getId, id);
//如果删除成功则删除运费模板子项
if (this.remove(lambdaQueryWrapper)) {
cache.remove(CachePrefix.SHIP_TEMPLATE.getPrefix() + tokenUser.getStoreId());
cache.remove(CachePrefix.SHIP_TEMPLATE.getPrefix());
return freightTemplateChildService.removeFreightTemplate(id);
}
return false;

View File

@@ -241,10 +241,6 @@ public class StoreServiceImpl extends ServiceImpl<StoreMapper, Store> implements
storeLambdaUpdateWrapper.eq(Store::getId, id);
storeLambdaUpdateWrapper.set(Store::getStoreDisable, StoreStatusEnum.CLOSED.value());
boolean update = this.update(storeLambdaUpdateWrapper);
//下架所有此店铺商品
if (update) {
goodsService.underStoreGoods(id);
}
//删除店员token
clerkService.list(new LambdaQueryWrapper<Clerk>().eq(Clerk::getStoreId, id)).forEach(clerk -> {

View File

@@ -1,5 +1,6 @@
package cn.lili.modules.system.entity.dos;
import cn.lili.modules.store.entity.dto.StoreLogisticsCustomerDTO;
import cn.lili.mybatis.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
@@ -37,4 +38,29 @@ public class Logistics extends BaseEntity {
@ApiModelProperty(value = "禁用状态 OPEN开启CLOSE禁用")
private String disabled;
@ApiModelProperty(value = "客户代码")
private String customerName;
@ApiModelProperty(value = "客户密码")
private String customerPwd;
@ApiModelProperty(value = "密钥")
private String monthCode;
@ApiModelProperty(value = "归属网点/网点编码")
private String sendSite;
@ApiModelProperty(value = "收件快递员")
private String sendStaff;
@ApiModelProperty(value = "是否使用电子面单")
private boolean faceSheetFlag;
@ApiModelProperty(value = "支付方式")
private String payType;
@ApiModelProperty(value = "快递类型")
private String expType;
}

View File

@@ -0,0 +1,29 @@
package cn.lili.modules.system.entity.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @author chc
* @since 2022/6/2114:46
*/
@Data
public class DeliverySetting implements Serializable {
@ApiModelProperty(value = "发货人姓名")
private String salesConsignorName;
@ApiModelProperty(value = "发货人手机号")
private String salesConsignorMobile;
@ApiModelProperty(value = "地址Id ''分割")
private String salesConsignorAddressId;
@ApiModelProperty(value = "地址名称, ''分割")
private String salesConsignorAddressPath;
@ApiModelProperty(value = "详细地址")
private String salesConsignorDetail;
}

View File

@@ -23,9 +23,5 @@ public class DistributionSetting implements Serializable {
* 分销关系绑定天数
*/
private Integer distributionDay;
/**
* 分销结算天数
*/
private Integer cashDay;
}

View File

@@ -15,8 +15,14 @@ import java.io.Serializable;
public class ImSetting implements Serializable {
@ApiModelProperty(value = "平台地址")
private String httpUrl;
@ApiModelProperty(value = "地址")
private String url;
@ApiModelProperty(value = "企业Id")
private String companyId;
@ApiModelProperty(value = "二维码")
private String qrCode;
}

View File

@@ -0,0 +1,25 @@
package cn.lili.modules.system.entity.dto;
import cn.lili.common.vo.PageVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author chc
* @since 2022/6/2114:46
*/
@Data
public class LogisticsSearchParams extends PageVO {
@ApiModelProperty(value = "支持电子面单")
private Boolean standBy;
public <T> QueryWrapper<T> queryWrapper() {
QueryWrapper<T> wrapper = new QueryWrapper<>();
if(standBy != null){
wrapper.eq("standBy",standBy);
}
return wrapper;
}
}

View File

@@ -18,6 +18,30 @@ public class SmsSetting implements Serializable {
* 类型
*/
private String type;
/**
* 是否测试模式
*/
private Boolean isTestModel;
/**
* 登录短信模板CODE
*/
private String loginTemplateCode;
/**
* 注册短信模板CODE
*/
private String registerTemplateCode;
/**
* 找回密码短信模板CODE
*/
private String findPasswordTemplateCode;
/**
* 设置密码短信模板CODE
*/
private String walletPasswordTemplateCode;
/**
* 支付密码短信模板CODE
*/
private String payPasswordTemplateCode;
/**
* key

View File

@@ -0,0 +1,32 @@
package cn.lili.modules.system.entity.dto.connect;
import cn.lili.modules.system.entity.dto.connect.dto.WechatConnectSettingItem;
import lombok.Data;
import java.util.List;
/**
* 登录设置
*
* @author Chopper
* @since 2020/11/17 8:00 下午
*/
@Data
public class ConnectSetting {
/**
* 买家PC端域名
*/
private String pc;
/**
* 买家WAP端域名
*/
private String wap;
/**
* 回调域名
*/
private String callbackUrl;
}

View File

@@ -38,4 +38,9 @@ public class AlipayPaymentSetting {
*/
private String rootCertPath;
/**
* 回调API地址
*/
private String callbackUrl;
}

View File

@@ -14,17 +14,25 @@ import lombok.experimental.Accessors;
public class WechatPaymentSetting {
/**
* APP应用id
* JSAPI支付应用ID
*/
private String appId;
private String jsapiAppId;
/**
* 小程序应用id
* native支付应用ID
*/
private String nativeAppId;
/**
* 小程序支付应用id
*/
private String mpAppId;
/**
* 服务号应用id
* H5支付应用ID
*/
private String serviceAppId;
private String h5AppId;
/**
* APP支付应用ID
*/
private String appAppId;
/**
* 商户号
*/
@@ -49,4 +57,8 @@ public class WechatPaymentSetting {
* apiv3私钥
*/
private String apiKey3;
/**
* 回调API地址
*/
private String callbackUrl;
}

View File

@@ -34,10 +34,14 @@ public enum SettingEnum {
//IM 配置
IM_SETTING,
//登录设置
CONNECT_SUPPORT,
//微信 联合登陆设置
WECHAT_CONNECT,
//QQ 浏览器 联合登录设置
QQ_CONNECT,
//登录设置
CONNECT_SETTING,
//各端支持支付设置
PAYMENT_SUPPORT,
@@ -48,5 +52,7 @@ public enum SettingEnum {
//银联支付设置
UNIONPAY_PAYMENT,
//热词设置
HOT_WORDS
HOT_WORDS,
//发货设置
DELIVERY_SETTING,
}

View File

@@ -102,19 +102,11 @@ public class LogisticsServiceImpl extends ServiceImpl<LogisticsMapper, Logistics
logistics = this.getById(logisticsId);
}
// 店铺-物流公司设置
LambdaQueryWrapper<StoreLogistics> lambdaQueryWrapper = Wrappers.lambdaQuery();
lambdaQueryWrapper.eq(StoreLogistics::getLogisticsId, logistics.getId());
lambdaQueryWrapper.eq(StoreLogistics::getStoreId, order.getStoreId());
StoreLogistics storeLogistics = storeLogisticsService.getOne(lambdaQueryWrapper);
//获取店家信息
StoreDeliverGoodsAddressDTO storeDeliverGoodsAddressDTO = storeDetailService.getStoreDeliverGoodsAddressDto(order.getStoreId());
LabelOrderDTO labelOrderDTO = new LabelOrderDTO();
labelOrderDTO.setOrder(order);
labelOrderDTO.setOrderItems(orderItems);
labelOrderDTO.setLogistics(logistics);
labelOrderDTO.setStoreLogistics(storeLogistics);
labelOrderDTO.setStoreDeliverGoodsAddressDTO(storeDeliverGoodsAddressDTO);
//触发电子面单
return logisticsPluginFactory.filePlugin().labelOrder(labelOrderDTO);
} else {

Some files were not shown because too many files have changed in this diff Show More