diff --git a/mcwl-admin/pom.xml b/mcwl-admin/pom.xml
index 85736cc..7b6082e 100644
--- a/mcwl-admin/pom.xml
+++ b/mcwl-admin/pom.xml
@@ -61,7 +61,12 @@
mcwl-myInvitation
3.8.8
-
+
+
+ com.mcwl
+ mcwl-resource
+ 3.8.8
+
com.mcwl
@@ -100,4 +105,4 @@
${project.artifactId}
-
\ No newline at end of file
+
diff --git a/mcwl-admin/src/main/java/com/mcwl/web/controller/resource/MallProductController.java b/mcwl-admin/src/main/java/com/mcwl/web/controller/resource/MallProductController.java
new file mode 100644
index 0000000..65f4400
--- /dev/null
+++ b/mcwl-admin/src/main/java/com/mcwl/web/controller/resource/MallProductController.java
@@ -0,0 +1,96 @@
+package com.mcwl.web.controller.resource;
+
+
+import com.mcwl.common.core.controller.BaseController;
+import com.mcwl.common.utils.ResponsePageEntity;
+import com.mcwl.resource.domain.MallProduct;
+import com.mcwl.resource.service.MallProductService;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * @Author:ChenYan
+ * @Project:McWl
+ * @Package:com.mcwl.web.controller.resource
+ * @Filename:MallProductController
+ * @Description 商品
+ * @Date:2024/12/31 10:48
+ */
+@RestController
+@RequestMapping("/MallProduct")
+public class MallProductController extends BaseController {
+
+
+ private final MallProductService mallProductService;
+
+ public MallProductController(MallProductService mallProductService) {
+ this.mallProductService = mallProductService;
+ }
+
+// /**
+// * 通过id查询商品图片信息
+// *
+// * @param id 系统ID
+// * @return 商品图片信息
+// */
+// @ApiOperation(notes = "通过id查询商品图片信息", value = "通过id查询商品图片信息")
+// @GetMapping("/findById")
+// public MallProduct findById(Long id) {
+// return mallProductService.findById(id);
+// }
+//
+// /**
+// * 根据条件查询商品图片列表
+// *
+// * @param mallProduct 条件
+// * @return 商品图片列表
+// */
+// @ApiOperation(notes = "根据条件查询商品图片列表", value = "根据条件查询商品图片列表")
+// @PostMapping("/searchByPage")
+// public ResponsePageEntity searchByPage(@RequestBody MallProduct mallProduct) {
+// return mallProductService.searchByPage(mallProduct);
+// }
+//
+//
+// /**
+// * 添加商品图片
+// *
+// * @param mallProduct 商品实体
+// * @return 影响行数
+// */
+// @ApiOperation(notes = "添加商品", value = "添加商品")
+// @PostMapping("/insert")
+// public int insert(@RequestBody MallProduct mallProduct) {
+// return mallProductService.insert(mallProduct);
+// }
+//
+// /**
+// * 修改商品
+// *
+// * @param mallProduct 商品实体
+// * @return 影响行数
+// */
+// @ApiOperation(notes = "修改商品", value = "修改商品")
+// @PostMapping("/update")
+// public int update(@RequestBody MallProduct mallProduct) {
+// return mallProductService.update(mallProduct);
+// }
+//
+// /**
+// * 批量删除商品
+// *
+// * @param ids 商品ID集合
+// * @return 影响行数
+// */
+// @ApiOperation(notes = "批量删除商品", value = "批量删除商品")
+// @PostMapping("/deleteByIds")
+// public int deleteByIds(@RequestBody @NotNull List ids) {
+// return mallProductService.deleteByIds(ids);
+// }
+//
+
+
+}
diff --git a/mcwl-common/pom.xml b/mcwl-common/pom.xml
index 7eaba4a..2a1d25c 100644
--- a/mcwl-common/pom.xml
+++ b/mcwl-common/pom.xml
@@ -17,7 +17,6 @@
-
org.springframework
diff --git a/mcwl-common/src/main/java/com/mcwl/common/domain/ResponsetEntity.java b/mcwl-common/src/main/java/com/mcwl/common/domain/ResponsetEntity.java
deleted file mode 100644
index 31dca53..0000000
--- a/mcwl-common/src/main/java/com/mcwl/common/domain/ResponsetEntity.java
+++ /dev/null
@@ -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;
-
-
-}
diff --git a/mcwl-common/src/main/java/com/mcwl/common/domain/response/OCRBackResult.java b/mcwl-common/src/main/java/com/mcwl/common/domain/response/OCRBackResult.java
new file mode 100644
index 0000000..48b2b22
--- /dev/null
+++ b/mcwl-common/src/main/java/com/mcwl/common/domain/response/OCRBackResult.java
@@ -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
+}
diff --git a/mcwl-common/src/main/java/com/mcwl/common/domain/response/ResponseEnum.java b/mcwl-common/src/main/java/com/mcwl/common/domain/response/ResponseEnum.java
new file mode 100644
index 0000000..301a54e
--- /dev/null
+++ b/mcwl-common/src/main/java/com/mcwl/common/domain/response/ResponseEnum.java
@@ -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();
+ }
+
+}
diff --git a/mcwl-common/src/main/java/com/mcwl/common/domain/response/ServerResponseEntity.java b/mcwl-common/src/main/java/com/mcwl/common/domain/response/ServerResponseEntity.java
new file mode 100644
index 0000000..d06c71e
--- /dev/null
+++ b/mcwl-common/src/main/java/com/mcwl/common/domain/response/ServerResponseEntity.java
@@ -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 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 ServerResponseEntity success(T data) {
+ ServerResponseEntity serverResponseEntity = new ServerResponseEntity<>();
+ serverResponseEntity.setData(data);
+ serverResponseEntity.setCode(ResponseEnum.OK.value());
+ return serverResponseEntity;
+ }
+
+ public static ServerResponseEntity success() {
+ ServerResponseEntity serverResponseEntity = new ServerResponseEntity<>();
+ serverResponseEntity.setCode(ResponseEnum.OK.value());
+ serverResponseEntity.setMsg(ResponseEnum.OK.getMsg());
+ return serverResponseEntity;
+ }
+
+ public static ServerResponseEntity success(Integer code, T data) {
+ return success(String.valueOf(code), data);
+ }
+
+ public static ServerResponseEntity success(String code, T data) {
+ ServerResponseEntity serverResponseEntity = new ServerResponseEntity<>();
+ serverResponseEntity.setCode(code);
+ serverResponseEntity.setData(data);
+ return serverResponseEntity;
+ }
+
+ /**
+ * 前端显示失败消息
+ * @param msg 失败消息
+ * @return
+ */
+ public static ServerResponseEntity showFailMsg(String msg) {
+ log.error(msg);
+ ServerResponseEntity serverResponseEntity = new ServerResponseEntity<>();
+ serverResponseEntity.setMsg(msg);
+ serverResponseEntity.setCode(ResponseEnum.SHOW_FAIL.value());
+ return serverResponseEntity;
+ }
+
+ public static ServerResponseEntity fail(ResponseEnum responseEnum) {
+ log.error(responseEnum.toString());
+ ServerResponseEntity serverResponseEntity = new ServerResponseEntity<>();
+ serverResponseEntity.setMsg(responseEnum.getMsg());
+ serverResponseEntity.setCode(responseEnum.value());
+ return serverResponseEntity;
+ }
+
+ public static ServerResponseEntity fail(ResponseEnum responseEnum, T data) {
+ log.error(responseEnum.toString());
+ ServerResponseEntity serverResponseEntity = new ServerResponseEntity<>();
+ serverResponseEntity.setMsg(responseEnum.getMsg());
+ serverResponseEntity.setCode(responseEnum.value());
+ serverResponseEntity.setData(data);
+ return serverResponseEntity;
+ }
+
+ public static ServerResponseEntity fail(String code, String msg, T data) {
+ log.error(msg);
+ ServerResponseEntity serverResponseEntity = new ServerResponseEntity<>();
+ serverResponseEntity.setMsg(msg);
+ serverResponseEntity.setCode(code);
+ serverResponseEntity.setData(data);
+ return serverResponseEntity;
+ }
+
+ public static ServerResponseEntity fail(String code, String msg) {
+ return fail(code, msg, null);
+ }
+
+ public static ServerResponseEntity fail(Integer code, T data) {
+ ServerResponseEntity serverResponseEntity = new ServerResponseEntity<>();
+ serverResponseEntity.setCode(String.valueOf(code));
+ serverResponseEntity.setData(data);
+ return serverResponseEntity;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static ServerResponseEntity transform(ServerResponseEntity> oldServerResponseEntity) {
+ ServerResponseEntity 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 + '\'' +
+ '}';
+ }
+}
diff --git a/mcwl-common/src/main/java/com/mcwl/common/enums/ResponseCodeEnum.java b/mcwl-common/src/main/java/com/mcwl/common/enums/ResponseCodeEnum.java
new file mode 100644
index 0000000..4588116
--- /dev/null
+++ b/mcwl-common/src/main/java/com/mcwl/common/enums/ResponseCodeEnum.java
@@ -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;
+ }
+
+}
diff --git a/mcwl-common/src/main/java/com/mcwl/common/exception/ErrorCodeException.java b/mcwl-common/src/main/java/com/mcwl/common/exception/ErrorCodeException.java
index 6480741..721f47d 100644
--- a/mcwl-common/src/main/java/com/mcwl/common/exception/ErrorCodeException.java
+++ b/mcwl-common/src/main/java/com/mcwl/common/exception/ErrorCodeException.java
@@ -4,8 +4,6 @@ import com.mcwl.common.enums.ResultCode;
/**
* 自定义异常类
- * @author DaiZibo
- * @date 2024/12/30
* @apiNote
*/
diff --git a/mcwl-common/src/main/java/com/mcwl/common/exception/YamiBizException.java b/mcwl-common/src/main/java/com/mcwl/common/exception/YamiBizException.java
new file mode 100644
index 0000000..0eb9c88
--- /dev/null
+++ b/mcwl-common/src/main/java/com/mcwl/common/exception/YamiBizException.java
@@ -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;
+ }
+}
diff --git a/mcwl-common/src/main/java/com/mcwl/common/exception/YamiShopBindException.java b/mcwl-common/src/main/java/com/mcwl/common/exception/YamiShopBindException.java
new file mode 100644
index 0000000..918a4c5
--- /dev/null
+++ b/mcwl-common/src/main/java/com/mcwl/common/exception/YamiShopBindException.java
@@ -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;
+ }
+}
diff --git a/mcwl-common/src/main/java/com/mcwl/common/exception/leaf/InitException.java b/mcwl-common/src/main/java/com/mcwl/common/exception/leaf/InitException.java
new file mode 100644
index 0000000..5fcf245
--- /dev/null
+++ b/mcwl-common/src/main/java/com/mcwl/common/exception/leaf/InitException.java
@@ -0,0 +1,10 @@
+package com.mcwl.common.exception.leaf;
+
+/**
+ * @author lanhai
+ */
+public class InitException extends Exception{
+ public InitException(String msg) {
+ super(msg);
+ }
+}
diff --git a/mcwl-common/src/main/java/com/mcwl/common/exception/leaf/LeafServerException.java b/mcwl-common/src/main/java/com/mcwl/common/exception/leaf/LeafServerException.java
new file mode 100644
index 0000000..b2cbd19
--- /dev/null
+++ b/mcwl-common/src/main/java/com/mcwl/common/exception/leaf/LeafServerException.java
@@ -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);
+ }
+}
diff --git a/mcwl-common/src/main/java/com/mcwl/common/exception/leaf/NoKeyException.java b/mcwl-common/src/main/java/com/mcwl/common/exception/leaf/NoKeyException.java
new file mode 100644
index 0000000..c181425
--- /dev/null
+++ b/mcwl-common/src/main/java/com/mcwl/common/exception/leaf/NoKeyException.java
@@ -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 {
+}
diff --git a/mcwl-common/src/main/java/com/mcwl/common/i18n/I18nMessage.java b/mcwl-common/src/main/java/com/mcwl/common/i18n/I18nMessage.java
new file mode 100644
index 0000000..9411554
--- /dev/null
+++ b/mcwl-common/src/main/java/com/mcwl/common/i18n/I18nMessage.java
@@ -0,0 +1,144 @@
+/*
+ * 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.context.support.MessageSourceAccessor;
+import org.springframework.context.support.ReloadableResourceBundleMessageSource;
+
+import java.io.IOException;
+import java.util.Locale;
+import java.util.Objects;
+
+/**
+ * 多语言国际化消息工具类
+ * @author mcwl
+ */
+@Slf4j
+public class I18nMessage {
+ private static MessageSourceAccessor accessor;
+
+// private static final String BASE_FOLDE = "i18n";
+
+ private static final String BASE_NAME = "i18n/messages";
+
+ static{
+ ReloadableResourceBundleMessageSource reloadableResourceBundleMessageSource = new ReloadableResourceBundleMessageSource();
+ reloadableResourceBundleMessageSource.setBasenames(BASE_NAME);
+ reloadableResourceBundleMessageSource.setCacheSeconds(5);
+ reloadableResourceBundleMessageSource.setDefaultEncoding("UTF-8");
+ accessor = new MessageSourceAccessor(reloadableResourceBundleMessageSource);
+ }
+
+
+// /**
+// * 获取一条语言配置信息
+// *
+// * @param message 配置信息属性名,eg: api.response.code.user.signUp
+// * @return
+// */
+// public static String getMessage(String message) {
+// Locale locale = LocaleContextHolder.getLocale();
+// return I18nMessage.accessor.getMessage(message,locale);
+// }
+
+ /**
+ * 获取一条语言配置信息
+ *
+ * @param message 配置信息属性名,eg: api.response.code.user.signUp
+ * @return
+ */
+ public static String getMessage(String message) {
+ Locale locale = LocaleContextHolder.getLocale();
+ try {
+ return accessor.getMessage(message,locale);
+ }catch (Exception e){
+ return message;
+ }
+
+ }
+ /**
+ * 获取一条语言配置信息(后台管理)
+ *
+ * @return
+ * @throws IOException
+ */
+ public static Integer getLang() {
+ Locale locale = LocaleContextHolder.getLocale();
+ return LanguageEnum.valueOf(locale).getLang();
+ }
+
+ /**
+ * 获取一条语言配置信息(小程序、pc)
+ *
+ * @return
+ * @throws IOException
+ */
+ public static Integer getDbLang() {
+ Integer lang = getLang();
+ if (Objects.equals(lang, 0)) {
+ return LanguageEnum.LANGUAGE_ZH_CN.getLang();
+ }
+ return lang;
+ }
+
+// /**
+// * 获取文件夹下所有的国际化文件名
+// *
+// * @param folderName 文件名
+// * @return
+// * @throws IOException
+// */
+// private static String[] getAllBaseNames(final String folderName) throws IOException {
+// URL url = Thread.currentThread().getContextClassLoader()
+// .getResource(folderName);
+// if (null == url) {
+// throw new RuntimeException("无法获取资源文件路径");
+// }
+//
+// List baseNames = new ArrayList<>();
+// if (url.getProtocol().equalsIgnoreCase("file")) {
+// // 文件夹形式,用File获取资源路径
+// File file = new File(url.getFile());
+// if (file.exists() && file.isDirectory()) {
+// baseNames = Files.walk(file.toPath())
+// .filter(path -> path.toFile().isFile())
+// .map(Path::toString)
+// .map(path -> path.substring(path.indexOf(folderName)))
+// .map(I18nMessage::getI18FileName)
+// .distinct()
+// .collect(Collectors.toList());
+// } else {
+// log.error("指定的baseFile不存在或者不是文件夹");
+// }
+// }
+// return baseNames.toArray(new String[0]);
+// }
+//
+// /**
+// * 把普通文件名转换成国际化文件名
+// *
+// * @param filename
+// * @return
+// */
+// private static String getI18FileName(String filename) {
+// filename = filename.replace(".properties", "");
+//// for (int i = 0; i < 2; i++) {
+//// int index = filename.lastIndexOf("_");
+//// if (index != -1) {
+//// filename = filename.substring(0, index);
+//// }
+//// }
+// return filename.replace("\\", "/");
+// }
+
+}
diff --git a/mcwl-common/src/main/java/com/mcwl/common/i18n/LanguageEnum.java b/mcwl-common/src/main/java/com/mcwl/common/i18n/LanguageEnum.java
new file mode 100644
index 0000000..da5fe50
--- /dev/null
+++ b/mcwl-common/src/main/java/com/mcwl/common/i18n/LanguageEnum.java
@@ -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;
+ }
+
+}
diff --git a/mcwl-common/src/main/java/com/mcwl/common/i18n/YamiLocaleChangeFilter.java b/mcwl-common/src/main/java/com/mcwl/common/i18n/YamiLocaleChangeFilter.java
new file mode 100644
index 0000000..93ec305
--- /dev/null
+++ b/mcwl-common/src/main/java/com/mcwl/common/i18n/YamiLocaleChangeFilter.java
@@ -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);
+ }
+}
diff --git a/mcwl-common/src/main/java/com/mcwl/common/i18n/YamiLocaleChangeInterceptor.java b/mcwl-common/src/main/java/com/mcwl/common/i18n/YamiLocaleChangeInterceptor.java
new file mode 100644
index 0000000..89ff1c1
--- /dev/null
+++ b/mcwl-common/src/main/java/com/mcwl/common/i18n/YamiLocaleChangeInterceptor.java
@@ -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;
+ }
+
+}
diff --git a/mcwl-common/src/main/java/com/mcwl/common/interfaces/MaxMoney.java b/mcwl-common/src/main/java/com/mcwl/common/interfaces/MaxMoney.java
index 48f7b8d..904ef37 100644
--- a/mcwl-common/src/main/java/com/mcwl/common/interfaces/MaxMoney.java
+++ b/mcwl-common/src/main/java/com/mcwl/common/interfaces/MaxMoney.java
@@ -19,7 +19,6 @@ import java.lang.annotation.Target;
/**
* 最大值约束.
*
- * @author 苏三,该项目是知识星球:java突击队 的内部项目
* @date 2024/6/11 下午4:13
*/
@Target({ElementType.METHOD, ElementType.FIELD})
diff --git a/mcwl-common/src/main/java/com/mcwl/common/utils/BeanUtil.java b/mcwl-common/src/main/java/com/mcwl/common/utils/BeanUtil.java
new file mode 100644
index 0000000..1a1d185
--- /dev/null
+++ b/mcwl-common/src/main/java/com/mcwl/common/utils/BeanUtil.java
@@ -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 List mapAsList(final Iterable sourceObject, Class clazz) {
+ return JSONObject.parseArray(JSONObject.toJSONString(sourceObject), clazz);
+ }
+ public static D map(final S sourceObject, Class clazz) {
+ return JSONObject.parseObject(JSONObject.toJSONString(sourceObject), clazz);
+ }
+}
diff --git a/mcwl-common/src/main/java/com/mcwl/common/utils/CacheManagerUtil.java b/mcwl-common/src/main/java/com/mcwl/common/utils/CacheManagerUtil.java
new file mode 100644
index 0000000..3b52988
--- /dev/null
+++ b/mcwl-common/src/main/java/com/mcwl/common/utils/CacheManagerUtil.java
@@ -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 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);
+ }
+ }
+}
diff --git a/mcwl-common/src/main/java/com/mcwl/common/utils/EncryptionUtil.java b/mcwl-common/src/main/java/com/mcwl/common/utils/EncryptionUtil.java
new file mode 100644
index 0000000..05cfb42
--- /dev/null
+++ b/mcwl-common/src/main/java/com/mcwl/common/utils/EncryptionUtil.java
@@ -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();
+ }
+
+ /**
+ * 获取RSA公钥的Base64编码字符串
+ *
+ * @return RSA公钥Base64编码字符串
+ */
+ 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;
+ }
+ }
+
+ /**
+ * 根据Base64编码的字符串还原为RSA公钥
+ *
+ * @param publicKeyString RSA公钥Base64编码字符串
+ * @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;
+ }
+ }
+
+ /**
+ * 获取RSA私钥的Base64编码字符串
+ *
+ * @return RSA私钥Base64编码字符串
+ */
+ 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;
+ }
+ }
+
+ /**
+ * 根据Base64编码的字符串还原为RSA私钥
+ *
+ * @param privateKeyString RSA私钥Base64编码字符串
+ * @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);
+ }
+}
+
+
+
diff --git a/mcwl-common/src/main/java/com/mcwl/common/utils/ImageUtil.java b/mcwl-common/src/main/java/com/mcwl/common/utils/ImageUtil.java
new file mode 100644
index 0000000..c9453e8
--- /dev/null
+++ b/mcwl-common/src/main/java/com/mcwl/common/utils/ImageUtil.java
@@ -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];
+ }
+}
diff --git a/mcwl-common/src/main/java/com/mcwl/common/utils/PrincipalUtil.java b/mcwl-common/src/main/java/com/mcwl/common/utils/PrincipalUtil.java
new file mode 100644
index 0000000..d7826b4
--- /dev/null
+++ b/mcwl-common/src/main/java/com/mcwl/common/utils/PrincipalUtil.java
@@ -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 {
+
+ /**
+ * 以1开头,后面跟10位数
+ */
+ 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);
+ }
+
+}
diff --git a/mcwl-common/src/main/java/com/mcwl/common/utils/RequestPageEntity.java b/mcwl-common/src/main/java/com/mcwl/common/utils/RequestPageEntity.java
new file mode 100644
index 0000000..32c863e
--- /dev/null
+++ b/mcwl-common/src/main/java/com/mcwl/common/utils/RequestPageEntity.java
@@ -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 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 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();
+ }
+}
diff --git a/mcwl-common/src/main/java/com/mcwl/common/utils/ResponsePageEntity.java b/mcwl-common/src/main/java/com/mcwl/common/utils/ResponsePageEntity.java
new file mode 100644
index 0000000..8987918
--- /dev/null
+++ b/mcwl-common/src/main/java/com/mcwl/common/utils/ResponsePageEntity.java
@@ -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 implements Serializable {
+
+ private static final Integer ZERO = 0;
+
+ /**
+ * 页码
+ */
+ private Integer pageNo;
+
+ /**
+ * 每页大小
+ */
+ private Integer pageSize;
+
+ /**
+ * 总页数
+ */
+ private Integer totalPage;
+
+
+ /**
+ * 总记录数
+ */
+ private Integer totalCount;
+
+ /**
+ * 数据
+ */
+ private List data;
+
+
+ /**
+ * 构建分页响应实体
+ *
+ * @param requestPageEntity 分页请求实体
+ * @param 数据类型
+ * @return ResponsePageEntity实体
+ */
+ public static ResponsePageEntity buildEmpty(RequestPageEntity requestPageEntity) {
+ return build(requestPageEntity, 0, new ArrayList<>(0));
+ }
+
+
+ /**
+ * 构建分页响应实体
+ *
+ * @param requestPageEntity 分页请求实体
+ * @param totalCount 总记录数
+ * @param data 数据
+ * @param 数据类型
+ * @return ResponsePageEntity实体
+ */
+ public static ResponsePageEntity build(RequestPageEntity requestPageEntity, Integer totalCount, List 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;
+ }
+}
diff --git a/mcwl-common/src/main/java/com/mcwl/common/utils/ShareCodeUtils.java b/mcwl-common/src/main/java/com/mcwl/common/utils/ShareCodeUtils.java
new file mode 100644
index 0000000..1cfb260
--- /dev/null
+++ b/mcwl-common/src/main/java/com/mcwl/common/utils/ShareCodeUtils.java
@@ -0,0 +1,106 @@
+package com.mcwl.common.utils;
+
+/**
+ */
+
+import java.util.Random;
+
+/**
+ * 邀请码生成器,基本原理:
+ * 1)入参用户ID:1
+ * 2)使用自定义进制转换之后为:V
+ * 3)转换未字符串,并在后面添加'A':VA
+ * 4)在VA后面再随机补足4位,得到:VAHKHE
+ * 5)反向转换时以'A'为分界线,'A'后面的不再解析
+ *
+ * @author zzs
+ */
+public class ShareCodeUtils {
+ /**
+ * 自定义进制(0,1没有加入,容易与o,l混淆),数组顺序可进行调整增加反推难度,A用来补位因此此数组不包含A,共31个字符。
+ */
+ 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
+ * 基本操作思路恰好与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;
+ }
+
+ public static void main(String[] args) {
+ String code = idToCode(13653414955L);
+ System.out.println(code);
+ System.out.println(codeToId("IKGPUKXA"));
+
+ }
+}
diff --git a/mcwl-common/src/main/java/com/mcwl/common/utils/SimpleCaptcha.java b/mcwl-common/src/main/java/com/mcwl/common/utils/SimpleCaptcha.java
new file mode 100644
index 0000000..e281381
--- /dev/null
+++ b/mcwl-common/src/main/java/com/mcwl/common/utils/SimpleCaptcha.java
@@ -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);
+ }
+ }
+
+}
diff --git a/mcwl-common/src/main/java/com/mcwl/common/utils/SpelUtil.java b/mcwl-common/src/main/java/com/mcwl/common/utils/SpelUtil.java
new file mode 100644
index 0000000..0f02c3b
--- /dev/null
+++ b/mcwl-common/src/main/java/com/mcwl/common/utils/SpelUtil.java
@@ -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);
+ }
+}
diff --git a/mcwl-common/src/main/java/com/mcwl/common/valid/MaxMoneyConstraintValidator.java b/mcwl-common/src/main/java/com/mcwl/common/valid/MaxMoneyConstraintValidator.java
index 4ba54c5..7a0d1fa 100644
--- a/mcwl-common/src/main/java/com/mcwl/common/valid/MaxMoneyConstraintValidator.java
+++ b/mcwl-common/src/main/java/com/mcwl/common/valid/MaxMoneyConstraintValidator.java
@@ -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 {
diff --git a/mcwl-resource/pom.xml b/mcwl-resource/pom.xml
index 24b7da7..e1df24a 100644
--- a/mcwl-resource/pom.xml
+++ b/mcwl-resource/pom.xml
@@ -9,6 +9,13 @@
3.8.8
mcwl-resource
+
+
+ 8
+ 8
+ UTF-8
+
+
resource资源中心模块
@@ -20,5 +27,11 @@
mcwl-common
+
+ com.baomidou
+ mybatis-plus-boot-starter
+ ${mybatis-plus.version}
+
+
diff --git a/mcwl-resource/src/main/java/com/mcwl/resource/domain/MallProduct.java b/mcwl-resource/src/main/java/com/mcwl/resource/domain/MallProduct.java
new file mode 100644
index 0000000..48e6b3c
--- /dev/null
+++ b/mcwl-resource/src/main/java/com/mcwl/resource/domain/MallProduct.java
@@ -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;
+
+/**
+ * @Author:ChenYan
+ * @Project:McWl
+ * @Package:com.mcwl.common.domain.resource
+ * @Filename:MallProduct
+ * @Description TODO
+ * @Date:2024/12/30 17:22
+ */
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+@TableName("mall_product")
+public class MallProduct extends BaseEntity {
+ private static final long serialVersionUID = 1L;
+
+
+ /**
+ * ID
+ */
+ @TableId
+ private Long Id;
+ /**
+ * 用户ID
+ */
+ private Integer userId;
+ /**
+ * 商品ID
+ */
+ private Integer productId;
+ /**
+ * 商品名称
+ */
+ private String productName;
+ /**
+ * 商品详情
+ */
+ private String detail;
+ /**
+ * 商品规格
+ */
+ private String model;
+ /**
+ * 金额
+ */
+ private BigDecimal amount;
+ /**
+ * 图片名称
+ */
+ private String name;
+ /**
+ * 图片url
+ */
+ private String url;
+ /**
+ * 图片url
+ */
+ private String zipUrl;
+ /**
+ * 删除标志(0代表存在 2代表删除)
+ */
+ private String delFlag;
+
+
+
+}
diff --git a/mcwl-resource/src/main/java/com/mcwl/resource/domain/MallProductComment.java b/mcwl-resource/src/main/java/com/mcwl/resource/domain/MallProductComment.java
new file mode 100644
index 0000000..40b26e6
--- /dev/null
+++ b/mcwl-resource/src/main/java/com/mcwl/resource/domain/MallProductComment.java
@@ -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;
+
+/**
+ * @Author:ChenYan
+ * @Project:McWl
+ * @Package:com.mcwl.common.domain.resource
+ * @Filename:MallProductComment
+ * @Description TODO
+ * @Date:2024/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;
+
+
+
+
+}
diff --git a/mcwl-resource/src/main/java/com/mcwl/resource/mapper/MallProductMapper.java b/mcwl-resource/src/main/java/com/mcwl/resource/mapper/MallProductMapper.java
new file mode 100644
index 0000000..dd6a0b8
--- /dev/null
+++ b/mcwl-resource/src/main/java/com/mcwl/resource/mapper/MallProductMapper.java
@@ -0,0 +1,17 @@
+package com.mcwl.resource.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.mcwl.resource.domain.MallProduct;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @Author:ChenYan
+ * @Project:McWl
+ * @Package:com.mcwl.resource.mapper
+ * @Filename:MallProductMapper
+ * @Description TODO
+ * @Date:2024/12/30 18:23
+ */
+@Mapper
+public interface MallProductMapper extends BaseMapper {
+}
diff --git a/mcwl-resource/src/main/java/com/mcwl/resource/service/MallProductService.java b/mcwl-resource/src/main/java/com/mcwl/resource/service/MallProductService.java
new file mode 100644
index 0000000..f337bad
--- /dev/null
+++ b/mcwl-resource/src/main/java/com/mcwl/resource/service/MallProductService.java
@@ -0,0 +1,21 @@
+package com.mcwl.resource.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.mcwl.common.domain.response.ServerResponseEntity;
+import com.mcwl.common.utils.ResponsePageEntity;
+import com.mcwl.resource.domain.MallProduct;
+
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * @Author:ChenYan
+ * @Project:McWl
+ * @Package:com.mcwl.resource.service
+ * @Filename:MallProductServiceImpl
+ * @Description TODO
+ * @Date:2024/12/30 18:20
+ */
+public interface MallProductService extends IService {
+
+}
diff --git a/mcwl-resource/src/main/java/com/mcwl/resource/service/impl/MallProductServiceImpl.java b/mcwl-resource/src/main/java/com/mcwl/resource/service/impl/MallProductServiceImpl.java
new file mode 100644
index 0000000..f82ffea
--- /dev/null
+++ b/mcwl-resource/src/main/java/com/mcwl/resource/service/impl/MallProductServiceImpl.java
@@ -0,0 +1,46 @@
+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.annotation.DataSource;
+import com.mcwl.common.enums.DataSourceType;
+import com.mcwl.common.enums.ResponseCodeEnum;
+import com.mcwl.resource.domain.MallProduct;
+import com.mcwl.resource.mapper.MallProductMapper;
+import com.mcwl.resource.service.MallProductService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+
+/**
+ * @Author:ChenYan
+ * @Project:McWl
+ * @Package:com.mcwl.resource.service.impl
+ * @Filename:MallProductServiceImpl
+ * @Description TODO
+ * @Date:2024/12/30 18:22
+ */
+@Service
+public class MallProductServiceImpl extends ServiceImpl implements MallProductService {
+
+ @Autowired
+ private MallProductMapper mapper;
+
+// @Override
+// public List selectMallProductList(MallProduct mallProduct) {
+//
+// QueryWrapper queryWrapper = new QueryWrapper<>();
+// queryWrapper.lambda().eq(MallProduct::getProductName, mallProduct.getProductName());
+// queryWrapper.lambda().eq(MallProduct::getName, mallProduct.getName());
+// queryWrapper.lambda().eq(MallProduct::getAmount, mallProduct.getAmount());
+// mapper.selectList(queryWrapper);
+//
+// serviceEntity.setMessage(ResponseCodeEnum.SUCCESS_STATE_ENUM.getName());
+// return ;
+//
+// }
+
+
+}
diff --git a/pom.xml b/pom.xml
index bb609ff..405860d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -35,6 +35,7 @@
1.2.13
5.7.12
5.3.39
+ 3.5.2