From 5e249417f9f5ca64c0b6f47f1e3a515c28940544 Mon Sep 17 00:00:00 2001 From: ChenYan <3139166962@qq.com> Date: Mon, 30 Dec 2024 17:16:47 +0800 Subject: [PATCH 1/2] =?UTF-8?q?docs:=E4=BB=85=E6=96=87=E6=A1=A3=E6=9B=B4?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql.sql | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/sql/mysql.sql b/sql/mysql.sql index 8d3b6f6..d696bef 100644 --- a/sql/mysql.sql +++ b/sql/mysql.sql @@ -8,3 +8,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='订单表'; From 2b5c7e1f20e369fab7da6346d6357cfc47a061dd Mon Sep 17 00:00:00 2001 From: ChenYan <3139166962@qq.com> Date: Tue, 31 Dec 2024 15:59:15 +0800 Subject: [PATCH 2/2] =?UTF-8?q?build:=E4=BE=9D=E8=B5=96=20=E5=B7=A5?= =?UTF-8?q?=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mcwl-admin/pom.xml | 9 +- .../resource/MallProductController.java | 96 +++++++ mcwl-common/pom.xml | 1 - .../mcwl/common/domain/ResponsetEntity.java | 18 -- .../common/domain/response/OCRBackResult.java | 38 +++ .../common/domain/response/ResponseEnum.java | 220 ++++++++++++++++ .../domain/response/ServerResponseEntity.java | 215 ++++++++++++++++ .../mcwl/common/enums/ResponseCodeEnum.java | 53 ++++ .../common/exception/ErrorCodeException.java | 2 - .../common/exception/YamiBizException.java | 60 +++++ .../exception/YamiShopBindException.java | 74 ++++++ .../common/exception/leaf/InitException.java | 10 + .../exception/leaf/LeafServerException.java | 14 + .../common/exception/leaf/NoKeyException.java | 11 + .../com/mcwl/common/i18n/I18nMessage.java | 144 +++++++++++ .../com/mcwl/common/i18n/LanguageEnum.java | 80 ++++++ .../common/i18n/YamiLocaleChangeFilter.java | 53 ++++ .../i18n/YamiLocaleChangeInterceptor.java | 58 +++++ .../com/mcwl/common/interfaces/MaxMoney.java | 1 - .../java/com/mcwl/common/utils/BeanUtil.java | 27 ++ .../mcwl/common/utils/CacheManagerUtil.java | 52 ++++ .../com/mcwl/common/utils/EncryptionUtil.java | 243 ++++++++++++++++++ .../java/com/mcwl/common/utils/ImageUtil.java | 99 +++++++ .../com/mcwl/common/utils/PrincipalUtil.java | 129 ++++++++++ .../mcwl/common/utils/RequestPageEntity.java | 73 ++++++ .../mcwl/common/utils/ResponsePageEntity.java | 84 ++++++ .../com/mcwl/common/utils/ShareCodeUtils.java | 106 ++++++++ .../com/mcwl/common/utils/SimpleCaptcha.java | 87 +++++++ .../java/com/mcwl/common/utils/SpelUtil.java | 57 ++++ .../valid/MaxMoneyConstraintValidator.java | 2 +- mcwl-resource/pom.xml | 13 + .../com/mcwl/resource/domain/MallProduct.java | 76 ++++++ .../resource/domain/MallProductComment.java | 61 +++++ .../resource/mapper/MallProductMapper.java | 17 ++ .../resource/service/MallProductService.java | 21 ++ .../service/impl/MallProductServiceImpl.java | 46 ++++ pom.xml | 1 + 37 files changed, 2326 insertions(+), 25 deletions(-) create mode 100644 mcwl-admin/src/main/java/com/mcwl/web/controller/resource/MallProductController.java delete mode 100644 mcwl-common/src/main/java/com/mcwl/common/domain/ResponsetEntity.java create mode 100644 mcwl-common/src/main/java/com/mcwl/common/domain/response/OCRBackResult.java create mode 100644 mcwl-common/src/main/java/com/mcwl/common/domain/response/ResponseEnum.java create mode 100644 mcwl-common/src/main/java/com/mcwl/common/domain/response/ServerResponseEntity.java create mode 100644 mcwl-common/src/main/java/com/mcwl/common/enums/ResponseCodeEnum.java create mode 100644 mcwl-common/src/main/java/com/mcwl/common/exception/YamiBizException.java create mode 100644 mcwl-common/src/main/java/com/mcwl/common/exception/YamiShopBindException.java create mode 100644 mcwl-common/src/main/java/com/mcwl/common/exception/leaf/InitException.java create mode 100644 mcwl-common/src/main/java/com/mcwl/common/exception/leaf/LeafServerException.java create mode 100644 mcwl-common/src/main/java/com/mcwl/common/exception/leaf/NoKeyException.java create mode 100644 mcwl-common/src/main/java/com/mcwl/common/i18n/I18nMessage.java create mode 100644 mcwl-common/src/main/java/com/mcwl/common/i18n/LanguageEnum.java create mode 100644 mcwl-common/src/main/java/com/mcwl/common/i18n/YamiLocaleChangeFilter.java create mode 100644 mcwl-common/src/main/java/com/mcwl/common/i18n/YamiLocaleChangeInterceptor.java create mode 100644 mcwl-common/src/main/java/com/mcwl/common/utils/BeanUtil.java create mode 100644 mcwl-common/src/main/java/com/mcwl/common/utils/CacheManagerUtil.java create mode 100644 mcwl-common/src/main/java/com/mcwl/common/utils/EncryptionUtil.java create mode 100644 mcwl-common/src/main/java/com/mcwl/common/utils/ImageUtil.java create mode 100644 mcwl-common/src/main/java/com/mcwl/common/utils/PrincipalUtil.java create mode 100644 mcwl-common/src/main/java/com/mcwl/common/utils/RequestPageEntity.java create mode 100644 mcwl-common/src/main/java/com/mcwl/common/utils/ResponsePageEntity.java create mode 100644 mcwl-common/src/main/java/com/mcwl/common/utils/ShareCodeUtils.java create mode 100644 mcwl-common/src/main/java/com/mcwl/common/utils/SimpleCaptcha.java create mode 100644 mcwl-common/src/main/java/com/mcwl/common/utils/SpelUtil.java create mode 100644 mcwl-resource/src/main/java/com/mcwl/resource/domain/MallProduct.java create mode 100644 mcwl-resource/src/main/java/com/mcwl/resource/domain/MallProductComment.java create mode 100644 mcwl-resource/src/main/java/com/mcwl/resource/mapper/MallProductMapper.java create mode 100644 mcwl-resource/src/main/java/com/mcwl/resource/service/MallProductService.java create mode 100644 mcwl-resource/src/main/java/com/mcwl/resource/service/impl/MallProductServiceImpl.java 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