Compare commits

..

27 Commits

Author SHA1 Message Date
ChenYan 2ccd2c658a Merge branch 'feature/resource' of https://gitea.qinmian.online/CY/mcwl-ai into preview 2025-01-02 17:03:22 +08:00
ChenYan 4c4f03583a build:依赖 工具 2025-01-02 17:01:52 +08:00
yang 5a2b6f8a97 Merge branch 'feature/my-invitation' into preview 2025-01-02 16:18:17 +08:00
yang 1e8197f01a build:调整 2025-01-02 16:17:18 +08:00
Diyu0904 42a4d25a8f Merge branch 'feature/admin' into preview
# Conflicts:
#	mcwl-admin/src/main/resources/application-druid.yml
2025-01-02 16:11:44 +08:00
yang 1b32f289cb 21191 进行的更改 2025-01-02 15:52:13 +08:00
yang 7215fcb48e Merge branch 'refs/heads/feature/my-invitation' into preview
# Conflicts:
#	mcwl-common/src/main/java/com/mcwl/common/domain/response/ResponseEnum.java
#	mcwl-common/src/main/java/com/mcwl/common/domain/response/ServerResponseEntity.java
#	mcwl-common/src/main/java/com/mcwl/common/exception/YamiBizException.java
#	mcwl-common/src/main/java/com/mcwl/common/exception/YamiShopBindException.java
#	mcwl-common/src/main/java/com/mcwl/common/i18n/I18nMessage.java
#	mcwl-common/src/main/java/com/mcwl/common/utils/ImageUtil.java
2025-01-02 15:49:11 +08:00
yang 5cc7874b77 refactor:调整 2025-01-02 15:47:03 +08:00
ChenYan 51055443c5 build:依赖 工具 2025-01-02 14:56:54 +08:00
ChenYan 1a1803b991 build:依赖 工具 2025-01-02 14:52:02 +08:00
ChenYan 1f05411e72 Merge branch 'feature/resource' of https://gitea.qinmian.online/CY/mcwl-ai into preview
# Conflicts:
#	mcwl-admin/src/main/resources/application.yml
2025-01-02 14:21:26 +08:00
ChenYan 76a23fa933 build:依赖 工具 2025-01-02 14:18:31 +08:00
yang 8df1daac3e Merge branch 'refs/heads/feature/my-invitation' into preview
# Conflicts:
#	mcwl-common/src/main/java/com/mcwl/common/utils/ShareCodeUtils.java
2025-01-02 14:13:18 +08:00
yang 1fce665900 feat:会员中心 2025-01-02 14:10:59 +08:00
ChenYan 5f5cc9aa7e build:依赖 工具 2025-01-02 11:44:13 +08:00
ChenYan 49e8e7f231 Merge branch 'preview' of https://gitea.qinmian.online/CY/mcwl-ai into feature/resource
# Conflicts:
#	mcwl-admin/pom.xml
2024-12-31 19:07:26 +08:00
ChenYan b778e26fbc build:依赖 工具 2024-12-31 19:05:37 +08:00
ChenYan e35045b1c8 Merge branch 'master' of https://gitea.qinmian.online/CY/mcwl-ai into feature/resource
# Conflicts:
#	mcwl-admin/pom.xml
2024-12-31 16:15:51 +08:00
ChenYan 12b00c70ed Merge branch 'preview' of https://gitea.qinmian.online/CY/mcwl-ai 2024-12-31 16:12:50 +08:00
ChenYan 9d5cf6040d Merge branch 'feature/resource' of https://gitea.qinmian.online/CY/mcwl-ai into preview
# Conflicts:
#	mcwl-admin/pom.xml
2024-12-31 16:09:18 +08:00
ChenYan 2b5c7e1f20 build:依赖 工具 2024-12-31 15:59:15 +08:00
yang 37b0e80892 chore:配置文件调整 2024-12-31 15:12:59 +08:00
yang 10b3a4b0b3 Merge branch 'feature/my-invitation' into preview 2024-12-31 15:06:15 +08:00
yang a18a478b36 style:调整 2024-12-31 15:05:15 +08:00
ChenYan 1f84a178b0 Merge branch 'preview' of https://gitea.qinmian.online/CY/mcwl-ai into feature/resource 2024-12-30 17:17:51 +08:00
ChenYan 5e249417f9 docs:仅文档更改 2024-12-30 17:16:47 +08:00
ChenYan 04f0d884f0 Merge branch 'preview' of https://gitea.qinmian.online/CY/mcwl-ai 2024-12-30 14:49:14 +08:00
67 changed files with 3012 additions and 84 deletions

View File

@ -37,7 +37,7 @@
<version>1.6.2</version>
</dependency>
<!-- Mysql驱动包 -->
<!-- Mysql驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
@ -54,6 +54,12 @@
<groupId>com.mcwl</groupId>
<artifactId>mcwl-quartz</artifactId>
</dependency>
<!-- 资源中心模块-->
<dependency>
<groupId>com.mcwl</groupId>
<artifactId>mcwl-resource</artifactId>
<version>3.8.8</version>
</dependency>
<!-- 我的邀请模块-->
<dependency>
@ -61,20 +67,39 @@
<artifactId>mcwl-myInvitation</artifactId>
<version>3.8.8</version>
</dependency>
<!-- 公共模块-->
<dependency>
<groupId>com.mcwl</groupId>
<artifactId>mcwl-common</artifactId>
<version>3.8.8</version>
</dependency>
<!-- 资源中心模块-->
<dependency>
<groupId>com.mcwl</groupId>
<artifactId>mcwl-resource</artifactId>
<version>3.8.8</version>
</dependency>
<!-- 代码生成-->
<dependency>
<groupId>com.mcwl</groupId>
<artifactId>mcwl-generator</artifactId>
</dependency>
<dependency>
<groupId>com.mcwl</groupId>
<artifactId>mcwl-memberCenter</artifactId>
<version>3.8.8</version>
</dependency>
<!-- rabbitmq依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
<version>3.1.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@ -102,7 +127,7 @@
<failOnMissingWebXml>false</failOnMissingWebXml>
<warName>${project.artifactId}</warName>
</configuration>
</plugin>
</plugin>
</plugins>
<finalName>${project.artifactId}</finalName>
</build>

View File

@ -1,8 +1,14 @@
package com.mcwl;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.Bean;
/**
*
@ -27,4 +33,16 @@ public class McWlApplication
" | | \\ / \\ / \n" +
" ''-' `'-' `-..-' ");
}
// 序列化枚举值为前端返回值
@Bean
public Jackson2ObjectMapperBuilderCustomizer customizer() {
return builder -> builder.featuresToEnable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
}
// mq 消息转换器
@Bean
public MessageConverter jacksonMessageConverter() {
return new Jackson2JsonMessageConverter();
}
}

View File

@ -1,11 +1,21 @@
package com.mcwl.web.controller.myInvitation;
import org.springframework.web.bind.annotation.RestController;
import com.mcwl.common.annotation.Anonymous;
import com.mcwl.common.domain.IdsParam;
import org.springframework.web.bind.annotation.*;
@RestController("/consume")
@RestController()
@RequestMapping("/consume")
public class ConsumeController {
@PostMapping()
@Anonymous
public void removeByIds(@RequestBody IdsParam ids){
System.out.println(ids);
}

View File

@ -8,15 +8,16 @@ import com.mcwl.myInvitation.domain.Invitation;
import com.mcwl.myInvitation.service.InvitationService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import static com.mcwl.common.core.domain.AjaxResult.success;
@RestController("/invitation")
@RestController()
@RequiredArgsConstructor
@RequestMapping("/invitation")
public class InvitationController {
private final InvitationService invitationService;
@ -26,6 +27,9 @@ public class InvitationController {
public AjaxResult getInvitationCode() {
// 获取当前用户
Long userId = SecurityUtils.getUserId();
if (userId == null) {
return AjaxResult.warn("用户未登录");
}
String invitationCode = invitationService.getInvitationCode(userId);
return success("操作成功", invitationCode);
}

View File

@ -20,4 +20,15 @@ public class CodeMQConfig {
public Queue queue() {
return new Queue(QueueConstants.CODE_QUEUE, true);
}
@Bean
public Queue emptyPointsRemindQueue() {
return new Queue(QueueConstants.EMPTY_POINTS_REMIND_QUEUE, true);
}
@Bean
public Queue memberBillingQueue() {
return new Queue(QueueConstants.MEMBER_BILLING_QUEUE, true);
}
}

View File

@ -0,0 +1,86 @@
package com.mcwl.web.controller.resource;
import com.mcwl.common.annotation.Anonymous;
import com.mcwl.common.core.controller.BaseController;
import com.mcwl.common.core.domain.AjaxResult;
import com.mcwl.common.core.page.TableDataInfo;
import com.mcwl.common.domain.IdsParam;
import com.mcwl.resource.domain.MallProduct;
import com.mcwl.resource.service.MallProductService;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @AuthorChenYan
* @ProjectMcWl
* @Packagecom.mcwl.web.controller.resource
* @FilenameMallProductController
* @Description
* @Date2024/12/31 10:48
*/
@RestController
@RequestMapping("/MallProduct")
public class MallProductController extends BaseController {
private final MallProductService mallProductRuleInfoService;
public MallProductController(MallProductService mallProductService) {
this.mallProductRuleInfoService = mallProductService;
}
/**
*
*/
@GetMapping("/list")
public TableDataInfo list(MallProduct sysJob)
{
startPage();
List<MallProduct> list = mallProductRuleInfoService.selectMallProductList(sysJob);
return getDataTable(list);
}
/**
*
*/
@GetMapping(value = "/{jobId}")
public AjaxResult getInfo(@PathVariable("jobId") Long jobId)
{
return success(mallProductRuleInfoService.selectMallProductById(jobId));
}
/**
*
*/
@PostMapping("/add")
public AjaxResult add(@RequestBody MallProduct mallProduct)
{
mallProduct.setCreateBy(getUsername());
return toAjax(mallProductRuleInfoService.insertMallProduct(mallProduct));
}
/**
*
*/
@PutMapping("/upda")
public AjaxResult edit(@RequestBody MallProduct mallProduct)
{
mallProduct.setUpdateBy(getUsername());
return toAjax(mallProductRuleInfoService.updateMallProduct(mallProduct));
}
/**
*
*/
@PostMapping
public AjaxResult remove(@RequestBody IdsParam ids)
{
mallProductRuleInfoService.deleteMallProductByIds(ids);
return success();
}
}

View File

@ -10,7 +10,7 @@ spring:
listener:
simple:
prefetch: 1 # 每次之能获取一条
acknowledge-mode: manual # 设置消费端手动ack确认
acknowledge-mode: auto # 设置消费端手动ack确认
retry:
enabled: true # 是否支持重试
# 生产者配置
@ -83,3 +83,4 @@ wechat:
appid: wx82d4c3c96f0ffa5b
# 应用密钥
secret: abbabcf1da711a3bbd95387ec83edcac

View File

@ -121,17 +121,19 @@ mybatis-plus:
# 关闭日志记录 (可单纯使用 p6spy 分析) org.apache.ibatis.logging.nologging.NoLoggingImpl
# 默认日志输出 org.apache.ibatis.logging.slf4j.Slf4jImpl
logImpl: org.apache.ibatis.logging.slf4j.Slf4jImpl
default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
global-config:
# 是否打印 Logo banner
banner: false
dbConfig:
# 主键类型
# AUTO 自增 NONE 空 INPUT 用户输入 ASSIGN_ID 雪花 ASSIGN_UUID 唯一 UUID
idType: ASSIGN_ID
# 逻辑已删除值
logicDeleteValue: 2
# 逻辑未删除值
logicNotDeleteValue: 0
idType: auto
logic-delete-field: del_flag
logic-delete-value: '2'
logic-not-delete-value: '0'
# 数据库字段下划线命名规则
table-underline: true
# 字段验证策略之 insert,在 insert 的时候的字段验证策略
# IGNORED 忽略 NOT_NULL 非NULL NOT_EMPTY 非空 DEFAULT 默认 NEVER 不加入 SQL
insertStrategy: NOT_NULL
@ -161,3 +163,15 @@ xss:
excludes: /system/notice
# 匹配链接
urlPatterns: /system/*,/monitor/*,/tool/*
#aliyun-oss
# aliyun:
# oss:
# file:
# endPoint: "http://oss-cn-beijing.aliyuncs.com" // 一般不用改,选择自己的地址即可
# keyid: "保存的key"
# keyecrets: "保存的secret"
# #bucket可以在控制台创建也可以使用java代码创建
# bucketname: "实例名称"

View File

@ -0,0 +1,58 @@
package com.mcwl.memberCenter;
import com.mcwl.McWlApplication;
import com.mcwl.common.utils.ShareCodeUtils;
import com.mcwl.memberCenter.consumer.EmptyPointsRemindConsumer;
import com.mcwl.memberCenter.domain.UserMember;
import com.mcwl.memberCenter.service.MemberService;
import com.mcwl.memberCenter.service.UserMemberService;
import com.mcwl.memberCenter.task.UserMemberTask;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = McWlApplication.class)
public class MemberTest {
@Autowired
private MemberService memberService;
@Autowired
private UserMemberService userMemberService;
@Autowired
private UserMemberTask userMemberTask;
@Autowired
private EmptyPointsRemindConsumer emptyPointsRemindConsumer;
@Test
public void createUserMember() {
System.out.println(userMemberService.createUserMember(1L, 1013L, "wechat"));
}
@Test
public void emptyPointsTaskTest() {
userMemberTask.emptyPointsTsk();
}
@Test
public void updateSubscriptionStatusTaskTest() {
userMemberTask.updateSubscriptionStatusTask();
}
@Test
public void emptyPointsRemindTaskTst() {
userMemberTask.emptyPointsRemindTask();
}
@Test
public void memberServiceTest() {
System.out.println(memberService.list());
}
}

View File

@ -17,6 +17,22 @@
</description>
<dependencies>
<!--OSS-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.17.1</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1.3</version>
</dependency>
<!-- Spring框架基本的核心工具 -->
<dependency>

View File

@ -12,4 +12,15 @@ public class QueueConstants {
//发送手机号验证码短信的mq队列
public static final String CODE_QUEUE = "codeQueue";
// 积分清零提醒队列
public static final String EMPTY_POINTS_REMIND_QUEUE = "emptyPointsRemindQueue";
// 会员账单队列
public static final String MEMBER_BILLING_QUEUE = "memberBillingQueue";
}

View File

@ -4,13 +4,16 @@ import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
/**
* Entity
*
*
* @author mcwl
*/
public class BaseEntity implements Serializable
@ -18,6 +21,7 @@ public class BaseEntity implements Serializable
private static final long serialVersionUID = 1L;
/** 搜索值 */
@TableField(exist = false)
@JsonIgnore
private String searchValue;
@ -35,11 +39,16 @@ public class BaseEntity implements Serializable
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
// 删除标志0代表存在 2代表删除
@TableLogic
private String delFlag;
/** 备注 */
private String remark;
/** 请求参数 */
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@TableField(exist = false)
private Map<String, Object> params;
public String getSearchValue()

View File

@ -0,0 +1,10 @@
package com.mcwl.common.domain;
import lombok.Data;
import java.util.List;
@Data
public class IdsParam {
private List<Long> ids;
}

View File

@ -1,18 +0,0 @@
package com.mcwl.common.domain;
import lombok.Data;
/**
*
*/
@Data
public class ResponsetEntity {
private Integer code;
private String message;
private Object data;
}

View File

@ -0,0 +1,38 @@
package com.mcwl.common.domain.response;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDate;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class OCRBackResult {
@JsonProperty("config_str")
private String configStr;
@JsonProperty("start_date")
@Schema(description = "开始日期")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate startDate;
@JsonProperty("end_date")
@Schema(description = "结束日期")
private String endDate;
@JsonProperty("issue")
@Schema(description = "签发机关")
private String issue;
@JsonProperty("is_fake")
private boolean isFake;
private String imagePath;
@JsonProperty("success")
private boolean success;
// Getters and setters
}

View File

@ -0,0 +1,220 @@
///*
// * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
// *
// * https://www.mall4j.com/
// *
// * 未经允许,不可做商业用途!
// *
// * 版权所有,侵权必究!
// */
//package com.mcwl.common.domain.response;
//
//
//import com.mcwl.common.i18n.I18nMessage;
//
///**
// * @author FrozenWatermelon
// * @date 2020/7/9
// */
//public enum ResponseEnum {
//
// /**
// * ok
// */
// OK("00000", "ok"),
//
// /**
// * 用于直接显示提示用户的错误,内容由输入内容决定
// */
// SHOW_FAIL("A00001", ""),
//
// /**
// * 用于直接显示提示系统的成功,内容由输入内容决定
// */
// SHOW_SUCCESS("A00002", ""),
//
// /**
// * 未授权
// */
// UNAUTHORIZED("A00004", "Unauthorized"),
//
// /**
// * 服务器出了点小差
// */
// EXCEPTION("A00005", "服务器出了点小差"),
//
// /**
// * TempUid异常
// * 一般不会出现这个异常,出现这个异常会有两种已知可能
// * 1. 一种是旧的tempUid
// * 2. 一种是同域名的localstorage 有个也叫tempUid的存储覆盖了有的人测试环境和正式环境放在同一个域名不同子目录下
// * 如果前端看到返回了这个异常为了让用户能够顺利登录需要重新获取一遍code重新获取tempUid
// */
// TEMP_UID_ERROR("A00012", "TempUid Error"),
//
// /**
// * 接口不存在
// */
// NOT_FOUND("A00013", "接口不存在"),
//
// /**
// * 方法参数没有校验,内容由输入内容决定
// */
// METHOD_ARGUMENT_NOT_VALID("A00014", "方法参数没有校验"),
//
// /**
// * 支付密码错误
// */
// PAY_PASSWORD_ERROR("A00015", I18nMessage.getMessage("yami.user.pay.password.error")),
//
//
// SCANCODE_PAY_ERROR("A00016", "扫描支付发生错误"),
//
//
// NEW_USER_NO_INVITOR_ERROR("A00017", "新注册用户必须填写邀请码"),
//
// NEW_USER_INVITOR_ERROR("A00018", "邀请码错误"),
//
// /**
// * 01开头代表商品
// * 商品已下架,返回特殊的状态码,用于渲染商品下架的页面
// */
//// SPU_NOT_EXIST("A01000", "商品不存在"),
//
// /**
// * 02开头代表购物车
// */
//// SHOP_CART_NOT_EXIST("A02000", "商品已下架"),
//
// /**
// * 03开头代表订单
// */
// API_ORDER_NOT_EXIST("A03000", "订单不存在"),
// ORDER_BUSY("A03001", "订单繁忙,请稍后再试"),
//
// /**
// * 订单不支持该配送方式
// */
// ORDER_DELIVERY_NOT_SUPPORTED("A03001", "The delivery method is not supported"),
//
// /**
// * 请勿重复提交订单,
// * 1.当前端遇到该异常时,说明前端防多次点击没做好
// * 2.提示用户 订单已发生改变,请勿重复下单
// */
// REPEAT_ORDER("A03002", "订单已过期,请重新下单"),
//
// /**
// * 优惠券不能共用
// */
// COUPON_CANNOT_USE_TOGETHER("A03003", "优惠券不能共用"),
//
// /**
// * 代金券金额超过了订单金额
// */
// COUPON_OF_RMRT_GT_ORDER("A03004", "代金券金额超过了订单金额"),
//
// /**
// * 库存不足body会具体返回那个skuid的库存不足后台通过skuId知道哪个商品库存不足前端不需要判断
// */
// NOT_STOCK("A03010", "not stock"),
//
// /**
// * 该社交账号被其他用户绑定了,如果返回这个状态码,前端应该提示用户解绑已经绑定的账号重新绑定
// */
// SOCIAL_ACCOUNT_BIND_BY_OTHER("A04002", "social account bind by other"),
//
// /**
// * 存在未完成订单不能注销
// */
// DESTROY_USER_FAIL("A05000", "您的账户当前有未完成的订单,请待所有订单完成后再注销账户"),
//
// /**
// * 用户收货地址超过配送范围
// */
// DELIVERY_OVER("A07001", ""),
// /**
// * 账号重复
// */
// ACCOUNT_REPEAT("P01001", "账号已经被使用"),
// ACCOUNT_NOT_EXIT("P01002", "账号不存在"),
// ACCOUNT_NOT_ROLE("P01003", "账号不存在角色"),
// ACCOUNT_STATUS_ERROR("P01004", "账号被锁"),
// ACCOUNT_NOT_AREA("P01005", "账号没绑定经营地区"),
// ACCOUNT_CREATE_ERROR("P01006", "账号创建失败"),
// ACCOUNT_NO_MENU("P01007", "账号无菜单权限"),
// PUSH_ID_NO_ACCOUNT("P01008", "该id无账号"),
// ACCOUNT_ERROR("P01009", "账号权限错误"),
// QUERY_TYPE_ERROR("P01010", "分页查询用户类型有误"),
// // P02 钱包类
// PUSH_USER_WALLET_NOT_EXIST("P02001", "用户钱包不存在"),
// ORDER_NOT_EXIST("P02002", "订单不存在"),
// NOT_SCANCODE_ORDER("P02003", "订单不是扫码下单"),
// NOT_PAY_ORDER("P02004", "订单为未支付完成"),
// ACTUAL_PAY_LITTLE_ORDER("P02005", "订单支付金额小于1元不进行分成"),
// NOT_BIND_ORDER("P02006", "订单商家未被推客绑定,不进行分成"),
// PUSH_ERR("P02007", "分成失败"),
// ACCOUNT_WX_BIND("P02101","改用户已经绑定openid" ),
// WX_APPID_SECRET_ERR("P02102","获取配置的appid错误" ),
// WITHDRAW_EXCESS_ERROR("P02005", "提现金额超出可提现额度"),
// SHOP_BANK_CARD_NOT_EXIST("P02006", "银行卡不存在"),
// SHOP_BANK_CARD_STATE_ERROR("P02007", "申请提现银行卡状态错误"),
//
// SHOP_BANK_ACCOUNT_ERROR("P02008", "注册新生账号异常"),
// SHOP_BANK_BIND_CONFIRM("P02010", "请输入验证码绑定银行卡"),
// /**
// * C开头为公共部分
// */
// ACCESS_TOKEN_ERR("C01001", "获取access_token失败"),
// TICKET_ERR("C01002", "获取ticket失败"),
// GENERATE_URL_LINK_ERR("C01003", "创建URLLink失败"),
// GET_WX_CODE_SESSION_ERR("C01004", "微信登录凭证校验败"),
//
// DATA_EXISTS("C01009", "数据已存在"),
// DATA_NOT_CHANGE_ABLE("C01010", "数据不可变更"),
//
//
//
//
// /**
// * 远程接口调用错误
// */
// RPC_CALL_EXCEPTION("A08001", ""),
// /**
// *
// */
// RPC_CALL_HTTP_EXCEPTION("A08002", ""),
//
//
// BAIDU_MAP_CONVERT_ERROR("A08003","百度地图接口调用错误" ),
//
// /**
// * T 平台活动类
// */
// REPEAT_ACTIVITY_SUB_ITEM("T00001", "重复的活动子项目"),;
//
//
//
// private final String code;
//
// private final String msg;
//
// public String value() {
// return code;
// }
//
// public String getMsg() {
// return msg;
// }
//
// ResponseEnum(String code, String msg) {
// this.code = code;
// this.msg = msg;
// }
//
// @Override
// public String toString() {
// return "ResponseEnum{" + "code='" + code + '\'' + ", msg='" + msg + '\'' + "} " + super.toString();
// }
//
//}

View File

@ -0,0 +1,215 @@
///*
// * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
// *
// * https://www.mall4j.com/
// *
// * 未经允许,不可做商业用途!
// *
// * 版权所有,侵权必究!
// */
//package com.mcwl.common.domain.response;
//
//import com.fasterxml.jackson.databind.annotation.JsonSerialize;
//import com.mcwl.common.config.serializer.SensitiveJsonSerializer;
//import io.swagger.v3.oas.annotations.media.Schema;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//
//import java.io.Serializable;
//import java.util.Objects;
//
///**
// * 响应实体
// * @author mcwl
// */
//public class ServerResponseEntity<T> implements Serializable {
//
// private static final Logger log = LoggerFactory.getLogger(ServerResponseEntity.class);
//
// /**
// * 状态码
// */
// @Schema(description = "状态码" ) private String code;
//
// /**
// * 信息
// */
// @Schema(description = "信息" ) private String msg;
//
// /**
// * 数据
// */
// @Schema(description = "数据" )
// @JsonSerialize(using = SensitiveJsonSerializer.class)
// private T data;
//
// /**
// * 版本
// */
// private String version;
//
// /**
// * 时间
// */
// private Long timestamp;
//
// private String sign;
//
// public String getSign() {
// return sign;
// }
//
// public void setSign(String sign) {
// this.sign = sign;
// }
//
// public String getCode() {
// return code;
// }
//
// public void setCode(String code) {
// this.code = code;
// }
//
// public String getMsg() {
// return msg;
// }
//
// public void setMsg(String msg) {
// this.msg = msg;
// }
//
// public T getData() {
// return data;
// }
//
// public ServerResponseEntity setData(T data) {
// this.data = data;
// return this;
// }
//
// public Long getTimestamp() {
// return timestamp;
// }
//
// public void setTimestamp(Long timestamp) {
// this.timestamp = timestamp;
// }
//
// public String getVersion() {
// return version;
// }
//
// public void setVersion(String version) {
// this.version = version;
// }
//
// public boolean isSuccess() {
// return Objects.equals(ResponseEnum.OK.value(), this.code);
// }
// public boolean isFail() {
// return !Objects.equals(ResponseEnum.OK.value(), this.code);
// }
//
// public ServerResponseEntity() {
// // 版本号
// this.version = "mall4j.v231204";
// }
//
// public static <T> ServerResponseEntity<T> success(T data) {
// ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>();
// serverResponseEntity.setData(data);
// serverResponseEntity.setCode(ResponseEnum.OK.value());
// return serverResponseEntity;
// }
//
// public static <T> ServerResponseEntity<T> success() {
// ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>();
// serverResponseEntity.setCode(ResponseEnum.OK.value());
// serverResponseEntity.setMsg(ResponseEnum.OK.getMsg());
// return serverResponseEntity;
// }
//
// public static <T> ServerResponseEntity<T> success(Integer code, T data) {
// return success(String.valueOf(code), data);
// }
//
// public static <T> ServerResponseEntity<T> success(String code, T data) {
// ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>();
// serverResponseEntity.setCode(code);
// serverResponseEntity.setData(data);
// return serverResponseEntity;
// }
//
// /**
// * 前端显示失败消息
// * @param msg 失败消息
// * @return
// */
// public static <T> ServerResponseEntity<T> showFailMsg(String msg) {
// log.error(msg);
// ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>();
// serverResponseEntity.setMsg(msg);
// serverResponseEntity.setCode(ResponseEnum.SHOW_FAIL.value());
// return serverResponseEntity;
// }
//
// public static <T> ServerResponseEntity<T> fail(ResponseEnum responseEnum) {
// log.error(responseEnum.toString());
// ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>();
// serverResponseEntity.setMsg(responseEnum.getMsg());
// serverResponseEntity.setCode(responseEnum.value());
// return serverResponseEntity;
// }
//
// public static <T> ServerResponseEntity<T> fail(ResponseEnum responseEnum, T data) {
// log.error(responseEnum.toString());
// ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>();
// serverResponseEntity.setMsg(responseEnum.getMsg());
// serverResponseEntity.setCode(responseEnum.value());
// serverResponseEntity.setData(data);
// return serverResponseEntity;
// }
//
// public static <T> ServerResponseEntity<T> fail(String code, String msg, T data) {
// log.error(msg);
// ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>();
// serverResponseEntity.setMsg(msg);
// serverResponseEntity.setCode(code);
// serverResponseEntity.setData(data);
// return serverResponseEntity;
// }
//
// public static <T> ServerResponseEntity<T> fail(String code, String msg) {
// return fail(code, msg, null);
// }
//
// public static <T> ServerResponseEntity<T> fail(Integer code, T data) {
// ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>();
// serverResponseEntity.setCode(String.valueOf(code));
// serverResponseEntity.setData(data);
// return serverResponseEntity;
// }
//
// @SuppressWarnings("unchecked")
// public static <T> ServerResponseEntity<T> transform(ServerResponseEntity<?> oldServerResponseEntity) {
// ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>();
// serverResponseEntity.setMsg(oldServerResponseEntity.getMsg());
// serverResponseEntity.setCode(oldServerResponseEntity.getCode());
// serverResponseEntity.setData((T) oldServerResponseEntity.getData());
// log.error(serverResponseEntity.toString());
// return serverResponseEntity;
// }
//
// @Override
// public String toString() {
// return "ServerResponseEntity{" +
// "code='" + code + '\'' +
// ", msg='" + msg + '\'' +
// ", data=" + data +
// ", version='" + version + '\'' +
// ", timestamp=" + timestamp +
// ", sign='" + sign + '\'' +
// '}';
// }
//}

View File

@ -0,0 +1,53 @@
package com.mcwl.common.enums;
import io.swagger.annotations.ApiModel;
import lombok.AllArgsConstructor;
import lombok.ToString;
@ToString
@AllArgsConstructor
@ApiModel(value = "返回对象", description = "返回状态")
public enum ResponseCodeEnum {
FAILED_STATE_ENUM(0, "failed"),
SUCCESS_STATE_ENUM(1, "success"),
LOCK_STATE_ENUM(2, "lock"),
PAY_SUCCESS_STATE_UPPER_CASE_ENUM(4, "SUCCESS"),
PAY_FAIL_STATE_UPPER_CASE_ENUM(5, "FAIL"),
UNLOCK_STATE_ENUM(3, "unlock");
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
private String name;
private int index;
private ResponseCodeEnum(int index, String name) {
this.index = index;
this.name = name;
}
public static String getName(int index) {
for (ResponseCodeEnum rkd : ResponseCodeEnum.values()) {
if (rkd.index == index) {
return rkd.name;
}
}
return null;
}
}

View File

@ -4,8 +4,6 @@ import com.mcwl.common.enums.ResultCode;
/**
*
* @author DaiZibo
* @date 2024/12/30
* @apiNote
*/

View File

@ -0,0 +1,60 @@
///*
// * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
// *
// * https://www.mall4j.com/
// *
// * 未经允许,不可做商业用途!
// *
// * 版权所有,侵权必究!
// */
//package com.mcwl.common.exception;
//
//
//import com.mcwl.common.domain.response.ResponseEnum;
//import lombok.Getter;
//
///**
// * 自定义异常
// * @author mcwl
// */
//@Getter
//public class YamiBizException extends RuntimeException{
//
// /**
// *
// */
// private static final long serialVersionUID = -4137688758944857209L;
//
// /**
// * http状态码
// */
// private String code;
//
// /**
// * @param responseEnum http状态码
// */
// public YamiBizException(ResponseEnum responseEnum) {
// super(responseEnum.getMsg());
// this.code = responseEnum.value();
// }
//
// /**
// * @param responseEnum http状态码
// */
// public YamiBizException(ResponseEnum responseEnum, String msg) {
// super(msg);
// this.code = responseEnum.value();
// }
//
// public YamiBizException(String msg) {
//// super(msg);
// super(msg);
// this.code = ResponseEnum.SHOW_FAIL.value();
// }
//
// public YamiBizException(String code,String msg) {
//// super(msg);
// super(msg);
// this.code = code;
// }
//}

View File

@ -0,0 +1,74 @@
///*
// * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
// *
// * https://www.mall4j.com/
// *
// * 未经允许,不可做商业用途!
// *
// * 版权所有,侵权必究!
// */
//package com.mcwl.common.exception;
//
//import com.mcwl.common.domain.response.ResponseEnum;
//import com.mcwl.common.domain.response.ServerResponseEntity;
//import com.mcwl.common.i18n.I18nMessage;
//import lombok.Getter;
//
///**
// * 自定义异常
// * @author mcwl
// */
//@Getter
//public class YamiShopBindException extends RuntimeException{
//
// /**
// *
// */
// private static final long serialVersionUID = -4137688758944857209L;
//
// /**
// * http状态码
// */
// private String code;
//
// private Object object;
//
// private ServerResponseEntity<?> serverResponseEntity;
//
// /**
// * @param responseEnum http状态码
// */
// public YamiShopBindException(ResponseEnum responseEnum) {
// super(responseEnum.getMsg());
// this.code = responseEnum.value();
// }
//
// /**
// * @param responseEnum http状态码
// */
// public YamiShopBindException(ResponseEnum responseEnum, String msg) {
// super(I18nMessage.getMessage(msg));
// this.code = responseEnum.value();
// }
//
// public YamiShopBindException(ServerResponseEntity<?> serverResponseEntity) {
// this.serverResponseEntity = serverResponseEntity;
// }
//
// public YamiShopBindException(String msg) {
//// super(msg);
// super(I18nMessage.getMessage(msg));
// this.code = ResponseEnum.SHOW_FAIL.value();
// }
//
// public YamiShopBindException(String msg, Object object) {
// super(I18nMessage.getMessage(msg));
// this.code = ResponseEnum.SHOW_FAIL.value();
// this.object = object;
// }
//
// public YamiShopBindException(String code, String msg) {
// super(I18nMessage.getMessage(msg));
// this.code = code;
// }
//}

View File

@ -0,0 +1,10 @@
package com.mcwl.common.exception.leaf;
/**
* @author lanhai
*/
public class InitException extends Exception{
public InitException(String msg) {
super(msg);
}
}

View File

@ -0,0 +1,14 @@
package com.mcwl.common.exception.leaf;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
/**
* @author lanhai
*/
@ResponseStatus(code=HttpStatus.INTERNAL_SERVER_ERROR)
public class LeafServerException extends RuntimeException {
public LeafServerException(String msg) {
super(msg);
}
}

View File

@ -0,0 +1,11 @@
package com.mcwl.common.exception.leaf;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
/**
* @author lanhai
*/
@ResponseStatus(code=HttpStatus.INTERNAL_SERVER_ERROR,reason="Key is none")
public class NoKeyException extends RuntimeException {
}

View File

@ -0,0 +1,80 @@
/*
* Copyright (c) 2018-2999 广 All rights reserved.
*
* https://www.mall4j.com/
*
*
*
*
*/
package com.mcwl.common.i18n;
import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Locale;
import java.util.Objects;
/**
*
* @author LGH
*/
@Getter
@AllArgsConstructor
public enum LanguageEnum {
/**
*
*/
LANGUAGE_ZH_CN("zh", 0),
/**
*
*/
LANGUAGE_EN("en", 1)
;
private String language;
private Integer lang;
/**
* (,)
*
* @param language
* @return
*/
public static String getLanguageType(String language){
if (StrUtil.isEmpty(language)) {
return LANGUAGE_ZH_CN.language;
}
for (LanguageEnum languageEnum : LanguageEnum.values()) {
if (languageEnum.language.equalsIgnoreCase(language)) {
return languageEnum.language;
}
}
return LANGUAGE_ZH_CN.language;
}
public static LanguageEnum valueOf(int lang) {
for (LanguageEnum languageEnum : values()) {
if (languageEnum.lang == lang) {
return languageEnum;
}
}
return LanguageEnum.LANGUAGE_ZH_CN;
}
public static LanguageEnum valueOf(Locale locale) {
for (LanguageEnum languageEnum : values()) {
if (Objects.equals(languageEnum.language, locale.toString())) {
return languageEnum;
}
}
return LanguageEnum.LANGUAGE_ZH_CN;
}
}

View File

@ -0,0 +1,53 @@
///*
// * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
// *
// * https://www.mall4j.com/
// *
// * 未经允许,不可做商业用途!
// *
// * 版权所有,侵权必究!
// */
//package com.mcwl.common.i18n;
//
//
//
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.context.i18n.LocaleContextHolder;
//import org.springframework.core.annotation.Order;
//import org.springframework.stereotype.Component;
//
//import javax.servlet.*;
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import java.io.IOException;
//import java.util.Locale;
//import java.util.Objects;
//
///**
// * RequestContextFilter 会传入默认的Locale优先级(-105) 要比RequestContextFilter优先级高
// * @author LGH
// */
//@Slf4j
//@Component
//@Order(-104)
//public class YamiLocaleChangeFilter implements Filter {
//
// public static String ZH_CN = "zh_CN";
// public static String ZH_CN_L = "zh_cn";
//
// @Override
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// HttpServletRequest request = (HttpServletRequest) servletRequest;
// HttpServletResponse response = (HttpServletResponse) servletResponse;
//
// String newLocale = request.getHeader("locale");
// if(Objects.equals(newLocale,ZH_CN)||Objects.equals(newLocale,ZH_CN_L)){
// newLocale = "zh";
// }
// if (newLocale != null) {
// String lowerLocale = newLocale.toLowerCase();
// LocaleContextHolder.setLocale(new Locale(lowerLocale));
// }
// filterChain.doFilter(request, response);
// }
//}

View File

@ -0,0 +1,58 @@
///*
// * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
// *
// * https://www.mall4j.com/
// *
// * 未经允许,不可做商业用途!
// *
// * 版权所有,侵权必究!
// */
//package com.mcwl.common.i18n;
//
//
//
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.stereotype.Component;
//import org.springframework.web.servlet.LocaleResolver;
//import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
//import org.springframework.web.servlet.support.RequestContextUtils;
//
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//
///**
// * @author LGH
// */
//@Component("localeChangeInterceptor")
//@Slf4j
//public class YamiLocaleChangeInterceptor extends LocaleChangeInterceptor {
//
// @Override
// public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
//
// String newLocale = request.getHeader(getParamName());
// if (newLocale != null) {
// LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
// if (localeResolver == null) {
// throw new IllegalStateException(
// "No LocaleResolver found: not in a DispatcherServlet request?");
// }
// try {
// localeResolver.setLocale(request, response, parseLocaleValue(newLocale));
// }
// catch (IllegalArgumentException ex) {
// if (isIgnoreInvalidLocale()) {
// if (logger.isDebugEnabled()) {
// logger.debug("Ignoring invalid locale value [" + newLocale + "]: " + ex.getMessage());
// }
// }
// else {
// throw ex;
// }
// }
// }
// // Proceed in any case.
// return true;
// }
//
//}

View File

@ -19,7 +19,6 @@ import java.lang.annotation.Target;
/**
* .
*
* @author java
* @date 2024/6/11 4:13
*/
@Target({ElementType.METHOD, ElementType.FIELD})

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 2018-2999 广 All rights reserved.
*
* https://www.mall4j.com/
*
*
*
*
*/
package com.mcwl.common.utils;
import com.alibaba.fastjson.JSONObject;
import java.util.List;
/**
*
*/
public class BeanUtil {
public static <S, D> List<D> mapAsList(final Iterable<S> sourceObject, Class<D> clazz) {
return JSONObject.parseArray(JSONObject.toJSONString(sourceObject), clazz);
}
public static <S, D> D map(final S sourceObject, Class<D> clazz) {
return JSONObject.parseObject(JSONObject.toJSONString(sourceObject), clazz);
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2018-2999 广 All rights reserved.
*
* https://www.mall4j.com/
*
*
*
*
*/
package com.mcwl.common.utils;
import lombok.AllArgsConstructor;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Component;
/**
*
*/
@Component
@AllArgsConstructor
public class CacheManagerUtil {
private CacheManager cacheManager;
@SuppressWarnings({"unchecked"})
public <T> T getCache(String cacheName,String key) {
Cache cache = cacheManager.getCache(cacheName);
if (cache == null) {
return null;
}
Cache.ValueWrapper valueWrapper = cache.get(key);
if (valueWrapper == null) {
return null;
}
return (T)valueWrapper.get();
}
public void putCache(String cacheName,String key, Object value) {
Cache cache = cacheManager.getCache(cacheName);
if (cache != null) {
cache.put(key, value);
}
}
public void evictCache(String cacheName,String key) {
Cache cache = cacheManager.getCache(cacheName);
if (cache != null) {
cache.evict(key);
}
}
}

View File

@ -0,0 +1,243 @@
package com.mcwl.common.utils;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class EncryptionUtil {
/**
* AES
*
* @param password
* @return
* @throws NoSuchAlgorithmException
*/
private static SecretKey generateAESKey(String password) throws NoSuchAlgorithmException {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128);
byte[] passwordBytes = password.getBytes(StandardCharsets.UTF_8);
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] keyBytes = digest.digest(passwordBytes);
return new SecretKeySpec(keyBytes, "AES");
}
public static String encryptWithAES(String plaintext) throws Exception {
Cipher cipher = Cipher.getInstance("AES");
SecretKey secretKey = generateAESKey("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(encryptedBytes);
}
/**
* AES
*
* @param plaintext
* @param password
* @return
* @throws Exception
*/
public static String encryptWithAES(String plaintext, String password) throws Exception {
Cipher cipher = Cipher.getInstance("AES");
SecretKey secretKey = generateAESKey(password);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(encryptedBytes);
}
/**
* AES
*
* @param ciphertext
* @param password
* @return
* @throws Exception
*/
public static String decryptWithAES(String ciphertext, String password) throws Exception {
Cipher cipher = Cipher.getInstance("AES");
SecretKey secretKey = generateAESKey(password);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(ciphertext));
return new String(decryptedBytes, StandardCharsets.UTF_8);
}
public static String decryptWithAES(String ciphertext) throws Exception {
Cipher cipher = Cipher.getInstance("AES");
SecretKey secretKey = generateAESKey("AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(ciphertext));
return new String(decryptedBytes, StandardCharsets.UTF_8);
}
/**
* RSA
*
* @return
* @throws NoSuchAlgorithmException
*/
public static KeyPair generateRSAKeyPair() throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
return keyPairGenerator.generateKeyPair();
}
/**
* RSABase64
*
* @return RSABase64
*/
public static String getRSAPublicKeyString(PublicKey publicKey) {
KeyFactory keyFactory;
try {
keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKey.getEncoded());
return Base64.getEncoder().encodeToString(keyFactory.generatePublic(publicKeySpec).getEncoded());
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* Base64RSA
*
* @param publicKeyString RSABase64
* @return RSA
*/
public static PublicKey getPublicKey(String publicKeyString) {
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyString));
return keyFactory.generatePublic(publicKeySpec);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* RSABase64
*
* @return RSABase64
*/
public static String getRSAPrivateKeyString(PrivateKey privateKey) {
KeyFactory keyFactory;
try {
keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKey.getEncoded());
return Base64.getEncoder().encodeToString(keyFactory.generatePrivate(privateKeySpec).getEncoded());
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* Base64RSA
*
* @param privateKeyString RSABase64
* @return RSA
*/
public static PrivateKey getPrivateKey(String privateKeyString) {
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyString));
return keyFactory.generatePrivate(privateKeySpec);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* RSA
*
* @param plaintext
* @param publicKey
* @return
* @throws Exception
*/
public static String encryptWithRSA(String plaintext, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
KeyPair keyPair = generateRSAKeyPair();
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(encryptedBytes);
}
/**
* RSA
*
* @param ciphertext
* @param privateKey
* @return
* @throws Exception
*/
public static String decryptWithRSA(String ciphertext, PrivateKey privateKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
KeyPair keyPair = generateRSAKeyPair();
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(ciphertext));
return new String(decryptedBytes, StandardCharsets.UTF_8);
}
/**
* SHA-256
*
* @param plaintext
* @return
* @throws NoSuchAlgorithmException
*/
public static String hashWithSHA256(String plaintext) throws NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hashBytes = digest.digest(plaintext.getBytes(StandardCharsets.UTF_8));
return bytesToHex(hashBytes);
}
/**
*
*
* @param bytes
* @return
*/
private static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(0xFF & b);
if (hex.length() == 1) {
sb.append('0');
}
sb.append(hex);
}
return sb.toString();
}
/**
* Base64
*
* @param plainText
* @return
*/
public static String encodeBase64(String plainText) {
byte[] plainBytes = plainText.getBytes(StandardCharsets.UTF_8);
return Base64.getEncoder().encodeToString(plainBytes);
}
/**
* Base64
*
* @param base64Text
* @return
*/
public static String decodeBase64(String base64Text) {
byte[] base64Bytes = Base64.getDecoder().decode(base64Text);
return new String(base64Bytes, StandardCharsets.UTF_8);
}
}

View File

@ -0,0 +1,99 @@
///*
// * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
// *
// * https://www.mall4j.com/
// *
// * 未经允许,不可做商业用途!
// *
// * 版权所有,侵权必究!
// */
//package com.mcwl.common.utils;
//
//import cn.hutool.core.util.StrUtil;
//import com.mcwl.common.exception.YamiShopBindException;
//
//
//import javax.imageio.ImageIO;
//import java.awt.*;
//import java.awt.image.BufferedImage;
//import java.io.ByteArrayOutputStream;
//import java.io.IOException;
//import java.net.URL;
//
///**
// * 图片处理工具类
//
// */
//public class ImageUtil {
// private static final String JPG = "jpg";
// private static final String JPEG = "jpeg";
// /**
// * 将图片转为二进制数组
// * @param imgUrl
// * @return
// */
// public static byte[] imgToBinary(String imgUrl) {
// try {
// BufferedImage bufferedImage = ImageIO.read(new URL(imgUrl));
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
// String suffix = imgUrlFileType(imgUrl);
// //ImageIO无法写入jpeg文件 报Invalid argument to native writeImage需重画
// if(StrUtil.equals(suffix, JPG) || StrUtil.equals(suffix,JPEG)){
// BufferedImage tag;
// tag = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(), BufferedImage.TYPE_INT_BGR);
// Graphics g = tag.getGraphics();
// g.drawImage(bufferedImage, 0, 0, null);
// g.dispose();
// bufferedImage = tag;
// }
// ImageIO.write(bufferedImage, suffix, baos);
// byte[] bytes = baos.toByteArray();
// return bytes;
// } catch (IOException e) {
// // 图片丢失,请重新上传图片
// throw new YamiShopBindException("yami.img.lose");
// }
// }
//
// /**
// * @param imgUrl
// * @return 文件得后缀,文件类型 jpg , png , ...
// */
// public static String imgUrlFileType(String imgUrl) {
// if (StrUtil.isBlank(imgUrl)) {
// return imgUrl;
// }
// imgUrl.trim();
// String[] split = imgUrl.split("\\.");
// String s = split[split.length - 1];
// return s;
// }
//
// /**
// * @param imgUrl
// * @return 获取文件名称
// */
// public static String imgUrlFileName(String imgUrl) {
// if (StrUtil.isBlank(imgUrl)) {
// return imgUrl;
// }
// imgUrl.trim();
// String[] split = imgUrl.split("/");
// String s = split[split.length - 1];
// return s;
// }
// /**
// * @param imgUrl
// * @return 获取文件名称 45d3631e97d8438d80f9db1369595b8c
// */
// public static String imgUrlFileNameNoSuffix(String imgUrl) {
// if (StrUtil.isBlank(imgUrl)) {
// return imgUrl;
// }
// imgUrl.trim();
// String[] split = imgUrl.split("/");
// String s = split[split.length - 1];
// String[] split1 = s.split("\\.");
// return split1[0];
// }
//}

View File

@ -0,0 +1,129 @@
/*
* Copyright (c) 2018-2999 广 All rights reserved.
*
* https://www.mall4j.com/
*
*
*
*
*/
package com.mcwl.common.utils;
import cn.hutool.core.util.StrUtil;
import java.util.regex.Pattern;
/**
*
*/
public class PrincipalUtil {
/**
* 110
*/
public static final String MOBILE_REGEXP = "1[0-9]{10}";
/**
*
*/
public static final String TEL_REGEXP = "([0-9]{3,4}-)?[0-9]{7,8}";
/**
*
*/
public static final String WX_NUMBER_REGEXP = "[a-zA-Z][a-zA-Z\\d_-]{5,19}$";
/**
* QQ
*/
public static final String QQ_NUMBER_REGEXP = "[1-9][0-9]{4,14}";
/**
* 1. 2. 线 4-16
*/
public static final String USER_NAME_REGEXP = "(?!\\d+$)([a-zA-Z0-9_]{4,16})";
/**
* 线
*/
public static final String FIELD_REGEXP = "([a-zA-Z0-9_]+)";
/**
*
*/
public static final String WITHOUT_CHINESE = "^[A-Za-z0-9]+$";
/**
* 线
*/
public static final String SIMPLE_CHAR_REGEXP = "([a-z0-9]+)";
/**
*
*/
public static final String MAIL_REGEXP = "([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})";
public static boolean isMobile(String value) {
if(StrUtil.isBlank(value)) {
return false;
}
return Pattern.matches(MOBILE_REGEXP, value);
}
public static boolean isTel(String value) {
if(StrUtil.isBlank(value)) {
return false;
}
return Pattern.matches(TEL_REGEXP, value);
}
public static boolean isWxNumber(String value) {
if(StrUtil.isBlank(value)) {
return false;
}
return Pattern.matches(WX_NUMBER_REGEXP, value);
}
public static boolean isQqNumber(String value) {
if(StrUtil.isBlank(value)) {
return false;
}
return Pattern.matches(QQ_NUMBER_REGEXP, value);
}
public static boolean isUserName(String value) {
if(StrUtil.isBlank(value)) {
return false;
}
return Pattern.matches(USER_NAME_REGEXP, value);
}
public static boolean isMail(String value) {
if(StrUtil.isBlank(value)) {
return false;
}
return Pattern.matches(MAIL_REGEXP, value);
}
/**
*
* @param value
* @return
*/
public static boolean isField(String value) {
return isMatching(FIELD_REGEXP, value);
}
public static boolean isMatching(String regexp, String value) {
if (StrUtil.isBlank(value)) {
return false;
}
return Pattern.matches(regexp, value);
}
/**
*
* @param value
* @return
*/
public static boolean isSimpleChar(String value) {
return isMatching(SIMPLE_CHAR_REGEXP, value);
}
}

View File

@ -0,0 +1,73 @@
package com.mcwl.common.utils;
import cn.hutool.core.collection.CollectionUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
import java.util.Objects;
/**
*
*
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
public class RequestPageEntity implements Serializable {
private static final int DEFAULT_PAGE_SIZE = 10;
/**
*
*/
private Integer pageNo = 1;
/**
* 10
*/
private Integer pageSize = DEFAULT_PAGE_SIZE;
/**
*
*/
private List<String> sortField;
/**
*
*
* @return
*/
public Integer getPageBegin() {
if (Objects.isNull(this.pageNo) || this.pageNo <= 0) {
this.pageNo = 1;
}
if (Objects.isNull(this.pageSize)) {
this.pageSize = DEFAULT_PAGE_SIZE;
}
return (this.pageNo - 1) * this.pageSize;
}
/**
*
*
* @return
*/
public String getSortString() {
List<String> sortField = this.getSortField();
if (CollectionUtil.isEmpty(sortField)) {
return null;
}
StringBuilder sortBuilder = new StringBuilder();
for (String field : sortField) {
String[] values = field.split(",");
sortBuilder.append(String.format("%s %s", values[0], values[1])).append(",");
}
return sortBuilder.deleteCharAt(sortBuilder.length() - 1).toString();
}
}

View File

@ -0,0 +1,84 @@
package com.mcwl.common.utils;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
*
*/
@AllArgsConstructor
@Data
public class ResponsePageEntity<T> implements Serializable {
private static final Integer ZERO = 0;
/**
*
*/
private Integer pageNo;
/**
*
*/
private Integer pageSize;
/**
*
*/
private Integer totalPage;
/**
*
*/
private Integer totalCount;
/**
*
*/
private List<T> data;
/**
*
*
* @param requestPageEntity
* @param <T>
* @return ResponsePageEntity
*/
public static <T> ResponsePageEntity<T> buildEmpty(RequestPageEntity requestPageEntity) {
return build(requestPageEntity, 0, new ArrayList<>(0));
}
/**
*
*
* @param requestPageEntity
* @param totalCount
* @param data
* @param <T>
* @return ResponsePageEntity
*/
public static <T> ResponsePageEntity<T> build(RequestPageEntity requestPageEntity, Integer totalCount, List<T> data) {
Integer totalPage = getTotalPage(requestPageEntity.getPageSize(), totalCount);
return new ResponsePageEntity(requestPageEntity.getPageNo(), requestPageEntity.getPageSize(), totalPage, totalCount, data);
}
private static Integer getTotalPage(Integer pageSize, Integer totalCount) {
if (Objects.isNull(pageSize) || Objects.isNull(totalCount)) {
return ZERO;
}
if (pageSize <= 0 || totalCount <= 0) {
return ZERO;
}
return totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1;
}
}

View File

@ -0,0 +1,101 @@
package com.mcwl.common.utils;
/**
*/
import java.util.Random;
/**
* <br/>
* 1ID1 <br/>
* 2使V <br/>
* 3'A'VA <br/>
* 4VA4VAHKHE <br/>
* 5'A'线'A' <br/>
*
* @author zzs
*/
public class ShareCodeUtils {
/**
* (0,1,o,l)AA31
*/
private static final char[] BASE = new char[]{'H', 'V', 'E', '8', 'S', '2', 'D', 'Z', 'X', '9', 'C', '7', 'P',
'5', 'I', 'K', '3', 'M', 'J', 'U', 'F', 'R', '4', 'W', 'Y', 'L', 'T', 'N', '6', 'B', 'G', 'Q'};
/**
* A
*/
private static final char SUFFIX_CHAR = 'A';
/**
*
*/
private static final int BIN_LEN = BASE.length;
/**
*
*/
private static final int CODE_LEN = 8;
/**
* ID
*
* @param id
* @return
*/
public static String idToCode(Long id) {
char[] buf = new char[BIN_LEN];
int charPos = BIN_LEN;
// 当id除以数组长度结果大于0则进行取模操作并以取模的值作为数组的坐标获得对应的字符
while (id / BIN_LEN > 0) {
int index = (int) (id % BIN_LEN);
buf[--charPos] = BASE[index];
id /= BIN_LEN;
}
buf[--charPos] = BASE[(int) (id % BIN_LEN)];
// 将字符数组转化为字符串
String result = new String(buf, charPos, BIN_LEN - charPos);
// 长度不足指定长度则随机补全
int len = result.length();
if (len < CODE_LEN) {
StringBuilder sb = new StringBuilder();
sb.append(SUFFIX_CHAR);
Random random = new Random();
// 去除SUFFIX_CHAR本身占位之后需要补齐的位数
for (int i = 0; i < CODE_LEN - len - 1; i++) {
sb.append(BASE[random.nextInt(BIN_LEN)]);
}
result += sb.toString();
}
return result;
}
/**
* ID<br/>
* idToCode
*
* @param code
* @return
*/
public static Long codeToId(String code) {
char[] charArray = code.toCharArray();
long result = 0L;
for (int i = 0; i < charArray.length; i++) {
int index = 0;
for (int j = 0; j < BIN_LEN; j++) {
if (charArray[i] == BASE[j]) {
index = j;
break;
}
}
if (charArray[i] == SUFFIX_CHAR) {
break;
}
if (i > 0) {
result = result * BIN_LEN + index;
} else {
result = index;
}
}
return result;
}
}

View File

@ -0,0 +1,87 @@
/*
* Copyright (c) 2018-2999 广 All rights reserved.
*
* https://www.mall4j.com/
*
*
*
*
*/
package com.mcwl.common.utils;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.util.RandomUtil;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.concurrent.ThreadLocalRandom;
/**
*
* @author yami
*/
public class SimpleCaptcha extends LineCaptcha{
private static final long serialVersionUID = -9042552338521307038L;
private static final String CAPTCHA_CODE = "abcdefhjkmnpqrstuvwxyz2345678";
private int codeCount;
public SimpleCaptcha(int width, int height, int codeCount, int interfereCount) {
super(width, height, codeCount, interfereCount);
this.codeCount = codeCount;
}
@Override
protected void generateCode() {
this.code = RandomUtil.randomString(CAPTCHA_CODE,codeCount);
}
@Override
public Image createImage(String code) {
// 图像buffer
final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
final ThreadLocalRandom random = RandomUtil.getRandom();
final Graphics2D g = ImgUtil.createGraphics(image, new Color(255,255,255));
// 干扰线
drawInterfere(g, random);
// 创建字体
g.setFont(this.font);
final FontMetrics metrics = g.getFontMetrics();
int minY = metrics.getAscent() - metrics.getLeading() - metrics.getDescent();
// 文字
final int len = codeCount;
int charWidth = width / len;
for (int i = 0; i < len; i++) {
// 产生随机的颜色值,让输出的每个字符的颜色值都将不同。
g.setColor(ImgUtil.randomColor(random));
g.drawString(String.valueOf(code.charAt(i)), i * charWidth, RandomUtil.randomInt(minY, this.height));
}
return image;
}
/**
* 线
*
* @param g {@link Graphics2D}
* @param random
*/
private void drawInterfere(Graphics2D g, ThreadLocalRandom random) {
// 干扰线
for (int i = 0; i < this.interfereCount; i++) {
int xs = random.nextInt(width);
int ys = random.nextInt(height);
int xe = xs + random.nextInt(width / 8);
int ye = ys + random.nextInt(height / 8);
g.setColor(ImgUtil.randomColor(random));
g.drawLine(xs, ys, xe, ye);
}
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2018-2999 广 All rights reserved.
*
* https://www.mall4j.com/
*
*
*
*
*/
package com.mcwl.common.utils;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import org.springframework.context.expression.MethodBasedEvaluationContext;
import org.springframework.core.StandardReflectionParameterNameDiscoverer;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import java.lang.reflect.Method;
/**
* SPEL
*/
public class SpelUtil {
/**
* #p0
* @param rootObject ,method
* @param spel
* @param method
* @param args
* @return
*/
public static String parse(Object rootObject,String spel, Method method, Object[] args) {
if (StrUtil.isBlank(spel)) {
return StrUtil.EMPTY;
}
//获取被拦截方法参数名列表(使用Spring支持类库)
StandardReflectionParameterNameDiscoverer standardReflectionParameterNameDiscoverer = new StandardReflectionParameterNameDiscoverer();
// LocalVariableTableParameterNameDiscoverer u =
// new LocalVariableTableParameterNameDiscoverer();
String[] paraNameArr = standardReflectionParameterNameDiscoverer.getParameterNames(method);
if (ArrayUtil.isEmpty(paraNameArr)) {
return spel;
}
//使用SPEL进行key的解析
ExpressionParser parser = new SpelExpressionParser();
//SPEL上下文
StandardEvaluationContext context = new MethodBasedEvaluationContext(rootObject,method,args,standardReflectionParameterNameDiscoverer);
//把方法参数放入SPEL上下文中
for (int i = 0; i < paraNameArr.length; i++) {
context.setVariable(paraNameArr[i], args[i]);
}
return parser.parseExpression(spel).getValue(context, String.class);
}
}

View File

@ -10,7 +10,7 @@ import java.math.BigDecimal;
/**
*
* @date 2024/6/11 4:13
* @date 2024/12/30 4:13
*/
public class MaxMoneyConstraintValidator implements ConstraintValidator<MaxMoney, BigDecimal> {

View File

@ -1,43 +0,0 @@
package com.mcwl.framework.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import com.mcwl.common.constant.Constants;
/**
*
*
* @author mcwl
*/
@Configuration
public class I18nConfig implements WebMvcConfigurer
{
@Bean
public LocaleResolver localeResolver()
{
SessionLocaleResolver slr = new SessionLocaleResolver();
// 默认语言
slr.setDefaultLocale(Constants.DEFAULT_LOCALE);
return slr;
}
@Bean
public LocaleChangeInterceptor localeChangeInterceptor()
{
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
// 参数名
lci.setParamName("lang");
return lci;
}
@Override
public void addInterceptors(InterceptorRegistry registry)
{
registry.addInterceptor(localeChangeInterceptor());
}
}

View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mcwl</groupId>
<artifactId>mcwl</artifactId>
<version>3.8.8</version>
</parent>
<artifactId>mcwl-memberCenter</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mybatis-plus.version>3.5.2</mybatis-plus.version>
</properties>
<dependencies>
<!-- 通用工具-->
<dependency>
<groupId>com.mcwl</groupId>
<artifactId>mcwl-common</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.mcwl</groupId>
<artifactId>mcwl-system</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!-- rabbitmq依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
<version>3.1.2</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,40 @@
package com.mcwl.memberCenter.consumer;
import com.mcwl.common.constant.QueueConstants;
import com.mcwl.memberCenter.domain.UserMember;
import com.mcwl.memberCenter.service.UserMemberService;
import com.mcwl.memberCenter.task.UserMemberTask;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
@Slf4j
@Component
@RequiredArgsConstructor
public class EmptyPointsRemindConsumer {
private final UserMemberService userMemberService;
@RabbitListener(queues = QueueConstants.EMPTY_POINTS_REMIND_QUEUE)
public void emptyPointsRemind(List<UserMember> userMemberList) {
// TODO 发送短信提醒用户积分即将清零
log.info("消费者获取到积分清零提醒的数据:{}", userMemberList);
}
@RabbitListener(queues = QueueConstants.MEMBER_BILLING_QUEUE)
public void memberBillingQueue(UserMember userMember) {
// TODO 发送短信提醒用户会员账单如果支付成功更新last_payment_date并重新计算end_datestart_date + 1个月
log.info("消费者获取到会员账单的数据:{}", userMember);
}
}

View File

@ -0,0 +1,39 @@
package com.mcwl.memberCenter.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.mcwl.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Objects;
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("mem_member")
public class Member extends BaseEntity {
@TableId
private Long id;
// 会员类型
private String memberType;
// 会员名称
private String memberName;
// 会员价格
private Double unitPrice;
// 会员原价
private Double originalPrice;
// 会员积分
private Integer points;
// 订阅周期(天)
private Integer subscriptionPeriod;
// 备注
private String remark;
}

View File

@ -0,0 +1,59 @@
package com.mcwl.memberCenter.domain;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.mcwl.common.core.domain.BaseEntity;
import com.mcwl.memberCenter.enums.MemberMenu;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("mem_user_member")
public class UserMember extends BaseEntity {
@TableId
private Long id;
// 用户ID
private Long userId;
// 会员ID
private Long memberId;
// 会员开始时间
private Date startDate;
// 会员结束时间
private Date endDate;
// 会员积分
private Integer points;
// 订阅状态 active活跃连续包月、inactive非活跃不连续包月、pending待支付和expired过期
private MemberMenu subscriptionStatus;
// 支付方式
private String paymentMethod;
// 上次支付时间
private Date lastPaymentDate;
// 下次计费时间
private Date nextBillingDate;
// 上次登录时间
private Date lastLoginDate;
// 状态(0:正常 1:禁用)
private String status;
// 备注
private String remark;
}

View File

@ -0,0 +1,19 @@
package com.mcwl.memberCenter.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum MemberMenu {
MEMBER_CENTER_ACTIVE("active", "活跃"),
MEMBER_CENTER_INACTIVE("inactive", "非活跃"),
MEMBER_CENTER_PENDING("pending", "待支付"),
MEMBER_CENTER_EXPIRED("expired", "过期");
private final String name;
@EnumValue
private final String value;
}

View File

@ -0,0 +1,11 @@
package com.mcwl.memberCenter.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mcwl.memberCenter.domain.Member;
import org.apache.ibatis.annotations.Mapper;
//@Mapper
public interface MemberMapper extends BaseMapper<Member> {
}

View File

@ -0,0 +1,9 @@
package com.mcwl.memberCenter.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mcwl.memberCenter.domain.UserMember;
import org.apache.ibatis.annotations.Mapper;
//@Mapper
public interface UserMemberMapper extends BaseMapper<UserMember> {
}

View File

@ -0,0 +1,11 @@
package com.mcwl.memberCenter.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.mcwl.memberCenter.domain.Member;
import java.util.List;
public interface MemberService extends IService<Member> {
}

View File

@ -0,0 +1,17 @@
package com.mcwl.memberCenter.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.mcwl.memberCenter.domain.UserMember;
public interface UserMemberService extends IService<UserMember> {
/**
*
* @param userId id
* @param memberId id
* @return
*/
UserMember createUserMember(Long userId, Long memberId, String paymentMethod);
}

View File

@ -0,0 +1,14 @@
package com.mcwl.memberCenter.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mcwl.memberCenter.domain.Member;
import com.mcwl.memberCenter.mapper.MemberMapper;
import com.mcwl.memberCenter.service.MemberService;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> implements MemberService {
}

View File

@ -0,0 +1,110 @@
package com.mcwl.memberCenter.service.impl;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mcwl.common.core.domain.entity.SysUser;
import com.mcwl.common.exception.ServiceException;
import com.mcwl.common.utils.SecurityUtils;
import com.mcwl.memberCenter.domain.Member;
import com.mcwl.memberCenter.domain.UserMember;
import com.mcwl.memberCenter.enums.MemberMenu;
import com.mcwl.memberCenter.mapper.UserMemberMapper;
import com.mcwl.memberCenter.service.MemberService;
import com.mcwl.memberCenter.service.UserMemberService;
import com.mcwl.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
@Service
@RequiredArgsConstructor
public class UserMemberServiceImpl extends ServiceImpl<UserMemberMapper, UserMember> implements UserMemberService {
private final MemberService memberService;
private final ISysUserService sysUserService;
public void aaa() {
LambdaQueryWrapper<Member> lqw = new LambdaQueryWrapper<>();
Member member = new Member();
memberService.update(lqw);
}
@Override
public UserMember createUserMember(Long userId, Long memberId, String paymentMethod) {
if (userId == null) {
throw new ServiceException("用户不能为空");
}
SysUser user = sysUserService.selectUserById(userId);
if (user == null) {
throw new ServiceException("用户不存在");
}
if (memberId == null) {
throw new ServiceException("会员不能为空");
}
Member member = memberService.getById(memberId);
if (member == null) {
throw new ServiceException("会员不存在");
}
// 查询用户是否已经存在会员
LambdaQueryWrapper<UserMember> lqw = new LambdaQueryWrapper<>();
lqw.eq(UserMember::getUserId, userId)
// subscriptionStatus不为expired
.ne(UserMember::getSubscriptionStatus, MemberMenu.MEMBER_CENTER_EXPIRED)
.orderBy(true, false, UserMember::getEndDate);
List<UserMember> userMemberList = baseMapper.selectList(lqw);
UserMember userMember = new UserMember();
// 设置用户id
userMember.setUserId(userId);
// 设置会员id
userMember.setMemberId(memberId);
if (userMemberList != null && !userMemberList.isEmpty()) {
UserMember lastUserMember = userMemberList.get(0);
Date endDate = lastUserMember.getEndDate();
// 设置会员开始时间和结束时间
Date startDate = new Date(endDate.getTime() + 1000L * 60L * 60L * 24L);
userMember.setStartDate(startDate);
userMember.setEndDate(new Date(startDate.getTime() + member.getSubscriptionPeriod() * 1000L * 60L * 60L * 24L));
} else {
// 用户不存在会员
// 设置会员开始时间和结束时间
Date startDate = new Date();
userMember.setStartDate(startDate);
userMember.setEndDate(new Date(startDate.getTime() + member.getSubscriptionPeriod() * 1000L * 60L * 60L * 24L));
}
// 设置积分
userMember.setPoints(member.getPoints());
// 设置订阅状态
if (member.getSubscriptionPeriod() == null) {
// 连续包月,会员状态为活跃
userMember.setSubscriptionStatus(MemberMenu.MEMBER_CENTER_ACTIVE);
Calendar calendar = Calendar.getInstance();
calendar.setTime(userMember.getEndDate());
calendar.add(Calendar.MONTH, 1);
userMember.setNextBillingDate(calendar.getTime());
} else {
userMember.setSubscriptionStatus(MemberMenu.MEMBER_CENTER_INACTIVE);
}
// 设置支付时间
userMember.setLastPaymentDate(new Date());
// 设置支付方式
userMember.setPaymentMethod(paymentMethod);
// 设置创建者
SysUser sysUser = sysUserService.selectUserById(userId);
userMember.setCreateBy(sysUser.getUserName());
userMember.setCreateTime(new Date());
userMember.setUpdateBy(sysUser.getUserName());
userMember.setUpdateTime(new Date());
baseMapper.insert(userMember);
return userMember;
}
}

View File

@ -0,0 +1,111 @@
package com.mcwl.memberCenter.task;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mcwl.common.constant.QueueConstants;
import com.mcwl.memberCenter.domain.UserMember;
import com.mcwl.memberCenter.enums.MemberMenu;
import com.mcwl.memberCenter.service.UserMemberService;
import lombok.RequiredArgsConstructor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
@Component("userMemberTask")
@RequiredArgsConstructor
public class UserMemberTask {
private final UserMemberService userMemberService;
private final RabbitTemplate rabbitTemplate;
/**
*
*/
public void emptyPointsRemindTask() {
List<UserMember> userMemberList = this.getUseUserMember();
// 发送积分清零消息
rabbitTemplate.convertAndSend(QueueConstants.EMPTY_POINTS_REMIND_QUEUE, userMemberList);
}
/**
*
*/
public void emptyPointsTsk() {
List<UserMember> userMemberList = this.getUseUserMember();
if (userMemberList == null || userMemberList.isEmpty()) {
return;
}
for (UserMember userMember : userMemberList) {
userMember.setPoints(0);
userMember.setUpdateTime(new Date());
}
userMemberService.updateBatchById(userMemberList);
}
/**
* 1h
*/
public void updateSubscriptionStatusTask() {
LambdaQueryWrapper<UserMember> qw = new LambdaQueryWrapper<>();
// endDate大于当前时间, subscriptionStatus不为过期
qw.gt(UserMember::getEndDate, System.currentTimeMillis())
.ne(UserMember::getSubscriptionStatus, MemberMenu.MEMBER_CENTER_EXPIRED);
List<UserMember> userMemberList = userMemberService.list(qw);
if (userMemberList == null || userMemberList.isEmpty()) {
return;
}
System.out.println("userMemberList = " + userMemberList);
for (UserMember userMember : userMemberList) {
MemberMenu subscriptionStatus = userMember.getSubscriptionStatus();
if (subscriptionStatus == MemberMenu.MEMBER_CENTER_ACTIVE) {
// 如果subscriptionStatus是活跃的表示连续包月。订阅状态改为"待支付"
userMember.setSubscriptionStatus(MemberMenu.MEMBER_CENTER_PENDING);
// nextBillingDate设置为当前会员结束日期的下个月的同一天,发送账单通知
Calendar calendar = Calendar.getInstance();
calendar.setTime(userMember.getEndDate());
calendar.add(Calendar.MONTH, 1);
userMember.setNextBillingDate(calendar.getTime());
userMemberService.updateById(userMember);
// 发送会员账单消息如果支付成功更新last_payment_date并重新计算end_datestart_date + 1个月
rabbitTemplate.convertAndSend(QueueConstants.MEMBER_BILLING_QUEUE, userMember);
} else if (subscriptionStatus == MemberMenu.MEMBER_CENTER_INACTIVE) {
// 不是连续包月,会员状态改为过期,状态改为"1"
userMember.setSubscriptionStatus(MemberMenu.MEMBER_CENTER_EXPIRED);
userMember.setStatus("1");
userMember.setUpdateTime(new Date());
}
}
}
// 获取正常使用的会员
private List<UserMember> getUseUserMember() {
// startDate 小于等于当前时间、endDate 大于等于当前时间
// subscriptionStatus 不为 "过期" 或 "待支付"
// status 为 0 的
LambdaQueryWrapper<UserMember> qw = new LambdaQueryWrapper<>();
qw.le(UserMember::getStartDate, System.currentTimeMillis())
.ge(UserMember::getEndDate, System.currentTimeMillis())
.ne(UserMember::getSubscriptionStatus, MemberMenu.MEMBER_CENTER_EXPIRED)
.ne(UserMember::getSubscriptionStatus, MemberMenu.MEMBER_CENTER_PENDING)
.eq(UserMember::getStatus, "0");
// 对应的sql为
System.out.println("sql = " + qw.getSqlSegment());
return userMemberService.list();
}
}

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mcwl.memberCenter.mapper.MemberMapper">
</mapper>

View File

@ -27,6 +27,9 @@ public class Commission extends BaseEntity {
// 支付状态
private Integer payStatus;
// 备注
private String remark;
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;

View File

@ -25,6 +25,9 @@ public class Consume extends BaseEntity {
// 消费时间
private Date consumeDate;
// 备注
private String remark;
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;

View File

@ -25,6 +25,9 @@ public class Invitation extends BaseEntity {
// 邀请码
private String invitationCode;
// 备注
private String remark;
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;

View File

@ -3,6 +3,7 @@ package com.mcwl.myInvitation.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mcwl.common.constant.JwtConstants;
import com.mcwl.common.utils.JwtUtils;
import com.mcwl.common.utils.ShareCodeUtils;
import com.mcwl.myInvitation.domain.Invitation;
import com.mcwl.myInvitation.mapper.InvitationMapper;
import com.mcwl.myInvitation.service.InvitationService;
@ -20,9 +21,7 @@ public class InvitationServiceImpl extends ServiceImpl<InvitationMapper, Invitat
@Override
public String getInvitationCode(Long userId) {
// 生成邀请码
Map<String, Object> claims = new HashMap<>() ;
claims.put(JwtConstants.DETAILS_USER_ID, userId);
String invitationCode = JwtUtils.createToken(claims);
String invitationCode = ShareCodeUtils.idToCode(userId);
return invitationCode;
}
}

View File

@ -9,6 +9,13 @@
<version>3.8.8</version>
</parent>
<artifactId>mcwl-resource</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<description>
resource资源中心模块
</description>
@ -20,5 +27,11 @@
<artifactId>mcwl-common</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,76 @@
package com.mcwl.resource.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.mcwl.common.core.domain.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
/**
* @AuthorChenYan
* @ProjectMcWl
* @Packagecom.mcwl.common.domain.resource
* @FilenameMallProduct
* @Description TODO
* @Date2024/12/30 17:22
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
@TableName("mall_product")
public class MallProduct extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId
private Integer productId;
/**
* ID
*/
private Integer userId;
/**
*
*/
private String productName;
/**
*
*/
private String detail;
/**
*
*/
private String model;
/**
*
*/
private BigDecimal amount;
/**
* (0 1 2 3)
*/
private String status;
/**
*
*/
private String name;
/**
* url
*/
private String url;
/**
* url
*/
private String zipUrl;
/**
* 0 2
*/
private String delFlag;
}

View File

@ -0,0 +1,61 @@
package com.mcwl.resource.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.mcwl.common.core.domain.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
/**
* @AuthorChenYan
* @ProjectMcWl
* @Packagecom.mcwl.common.domain.resource
* @FilenameMallProductComment
* @Description TODO
* @Date2024/12/30 17:22
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
@TableName("mall_product_comment")
public class MallProductComment extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId
private Long Id;
/**
* ID
*/
private Integer parentId;
/**
* ID
*/
private Integer productId;
/**
* ID
*/
private Integer userId;
/**
*
*/
private String content;
/**
*
*/
private Integer rating;
/**
* 0 2
*/
private String delFlag;
}

View File

@ -0,0 +1,20 @@
package com.mcwl.resource.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mcwl.resource.domain.MallProduct;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* @AuthorChenYan
* @ProjectMcWl
* @Packagecom.mcwl.resource.mapper
* @FilenameMallProductMapper
* @Description TODO
* @Date2024/12/30 18:23
*/
@Mapper
public interface MallProductMapper extends BaseMapper<MallProduct> {
String selectMallProductById(@Param("mallProductId") Long mallProductId);
}

View File

@ -0,0 +1,32 @@
package com.mcwl.resource.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.mcwl.common.domain.IdsParam;
import com.mcwl.resource.domain.MallProduct;
import kotlin.Result;
import java.util.List;
/**
* @AuthorChenYan
* @ProjectMcWl
* @Packagecom.mcwl.resource.service
* @FilenameMallProductServiceImpl
* @Description TODO
* @Date2024/12/30 18:20
*/
public interface MallProductService extends IService<MallProduct> {
List<MallProduct> selectMallProductList(MallProduct sysJob);
String selectMallProductById(Long mallProductId);
int insertMallProduct(MallProduct mallProduct);
int updateMallProduct(MallProduct mallProduct);
void deleteMallProductByIds(IdsParam ids);
}

View File

@ -0,0 +1,63 @@
package com.mcwl.resource.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mcwl.common.domain.IdsParam;
import com.mcwl.resource.domain.MallProduct;
import com.mcwl.resource.mapper.MallProductMapper;
import com.mcwl.resource.service.MallProductService;
import kotlin.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @AuthorChenYan
* @ProjectMcWl
* @Packagecom.mcwl.resource.service.impl
* @FilenameMallProductServiceImpl
* @Description TODO
* @Date2024/12/30 18:22
*/
@Service
public class MallProductServiceImpl extends ServiceImpl<MallProductMapper,MallProduct> implements MallProductService {
@Autowired
private MallProductMapper postMapper;
@Override
public List<MallProduct> selectMallProductList(MallProduct mallProduct) {
QueryWrapper<MallProduct> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(MallProduct::getProductName, mallProduct.getProductName());
queryWrapper.lambda().eq(MallProduct::getName, mallProduct.getName());
queryWrapper.lambda().eq(MallProduct::getAmount, mallProduct.getAmount());
return postMapper.selectList(queryWrapper);
}
@Override
public String selectMallProductById(Long mallProductId) {
return postMapper.selectMallProductById(mallProductId);
}
@Override
public int insertMallProduct(MallProduct mallProduct) {
return postMapper.insert(mallProduct);
}
@Override
public int updateMallProduct(MallProduct mallProduct) {
return postMapper.updateById(mallProduct);
}
@Override
public void deleteMallProductByIds(IdsParam ids) {
postMapper.deleteBatchIds(ids.getIds());
}
}

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mcwl.resource.mapper.MallProductMapper">
<select id="selectMallProductById" resultType="java.lang.String">
select product_id,
user_id,
product_name,
detail,
model,
amount,
name,
status,
zip_url,
url,
create_by,
create_time,
update_by,
update_time,
remark,
del_flag
from mall_product where product_id =#{mallProductId}
</select>
</mapper>

View File

@ -35,6 +35,7 @@
<logback.version>1.2.13</logback.version>
<spring-security.version>5.7.12</spring-security.version>
<spring-framework.version>5.3.39</spring-framework.version>
<mybatis-plus.version>3.5.2</mybatis-plus.version>
</properties>
<!-- 依赖声明 -->
@ -237,6 +238,7 @@
<module>mcwl-common</module>
<module>mcwl-myInvitation</module>
<module>mcwl-resource</module>
<module>mcwl-memberCenter</module>
</modules>
<packaging>pom</packaging>

View File

@ -7,3 +7,80 @@
-- post_code varchar(64) not null comment '岗位编码',
-- primary key (post_id)
-- ) engine=innodb comment = 'xxxx';
CREATE TABLE `mall_product`
(
`id` bigint NOT NULL COMMENT 'ID',
`product_id` bigint NOT NULL COMMENT '商品ID',
`product_name` varchar(100) NOT NULL COMMENT '商品名称',
`detail` blob NOT NULL COMMENT '商品详情',
`model` varchar(100) NOT NULL COMMENT '商品规格',
`amount` decimal(10, 3) NOT NULL COMMENT '金额',
`name` varchar(60) NOT NULL COMMENT '图片名称',
`url` varchar(200) NOT NULL COMMENT '图片url',
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志0代表存在 2代表删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='商品表';
CREATE TABLE `mall_index_product`
(
`id` bigint NOT NULL COMMENT 'ID',
`product_id` bigint NOT NULL COMMENT '商品ID',
`sort` int NOT NULL DEFAULT '999' COMMENT '排序',
`type` int NOT NULL COMMENT '模型类型 1: 热门模型 2: 最新模型 3推荐模型',
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志0代表存在 2代表删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='首页商品';
CREATE TABLE `mall_product_comment`
(
`id` bigint NOT NULL COMMENT 'ID',
`parent_id` bigint NOT NULL DEFAULT '0' COMMENT '父评论ID',
`product_id` bigint NOT NULL COMMENT '商品ID',
`user_id` bigint NOT NULL COMMENT '用户ID',
`content` varchar(500) NOT NULL COMMENT '评论内容',
`rating` int NOT NULL COMMENT '评分',
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志0代表存在 2代表删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='商品评论表';
CREATE TABLE `order_trade`
(
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
`code` varchar(30) NOT NULL COMMENT '订单编码',
`user_id` bigint NOT NULL COMMENT '用户ID',
`product_id` bigint NOT NULL COMMENT '商品ID',
`product_name` varchar(60) NOT NULL COMMENT '商品名称',
`user_name` varchar(30) NOT NULL COMMENT '用户名称',
`order_time` datetime(3) DEFAULT NULL COMMENT '下单时间',
`order_status` int NOT NULL COMMENT '订单状态 1:下单 2:支付 3完成 4取消',
`pay_status` int NOT NULL COMMENT '支付状态 1:待支付 2:已支付 3退款',
`total_amount` decimal(10, 3) NOT NULL COMMENT '总金额',
`payment_amount` decimal(10, 3) NOT NULL COMMENT '付款金额',
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志0代表存在 2代表删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1798708644507918337 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='订单表';