mirror of
http://192.168.1.205:9980/cf_devdept2/cf_imes_server.git
synced 2026-08-12 21:02:08 +08:00
资金管理相关接口
This commit is contained in:
+34
-9
@@ -2,14 +2,10 @@ package com.cf.imes.framework.mq.rabbitmq.config;
|
||||
|
||||
import com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.amqp.core.Binding;
|
||||
import org.springframework.amqp.core.BindingBuilder;
|
||||
import org.springframework.amqp.core.DirectExchange;
|
||||
import org.springframework.amqp.core.FanoutExchange;
|
||||
import org.springframework.amqp.core.Queue;
|
||||
import org.springframework.amqp.core.QueueBuilder;
|
||||
import org.springframework.amqp.core.*;
|
||||
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
||||
import org.springframework.amqp.support.converter.MessageConverter;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -17,9 +13,7 @@ import org.springframework.context.annotation.Bean;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants.ORDER_IMPORT_DEAD_LETTER_EXCHANGE;
|
||||
import static com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants.ORDER_IMPORT_DEAD_LETTER_QUEUE;
|
||||
import static com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants.ORDER_IMPORT_DEAD_LETTER_ROUTING_KEY;
|
||||
import static com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants.*;
|
||||
|
||||
/**
|
||||
* RabbitMQ 消息队列配置类
|
||||
@@ -139,4 +133,35 @@ public class ChenfengRabbitMQAutoConfiguration {
|
||||
return BindingBuilder.bind(orderImportDeadLetterQueue()).to(orderImportDeadLetterExchange()).with(ORDER_IMPORT_DEAD_LETTER_ROUTING_KEY);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 广告状态修改 延迟队列
|
||||
*/
|
||||
@Bean
|
||||
public Queue advertisementUpdateDelayedQueue(){
|
||||
return QueueBuilder.durable(SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_QUEUE).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 广告状态修改 定义延迟交换机
|
||||
*/
|
||||
@Bean
|
||||
public CustomExchange advertisementUpdateDelayExchange() {
|
||||
Map<String, Object> args = new HashMap<>();
|
||||
args.put("x-delayed-type", "direct");
|
||||
return new CustomExchange(SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_EXCHANGE, "x-delayed-message", true, false, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 广告状态修改 队列与交换机绑定
|
||||
*/
|
||||
@Bean
|
||||
public Binding advertisementUpdateQueueABindingX(@Qualifier("advertisementUpdateDelayedQueue") Queue queue,
|
||||
@Qualifier("advertisementUpdateDelayExchange") CustomExchange delayedExchange){
|
||||
return BindingBuilder.bind(queue)
|
||||
.to(delayedExchange)
|
||||
.with(SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_ROUTING_KEY)
|
||||
.noargs();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+16
@@ -41,4 +41,20 @@ public class RabbitMqConstants {
|
||||
* 生产单导入死信路由键
|
||||
*/
|
||||
public static final String ORDER_IMPORT_DEAD_LETTER_ROUTING_KEY = "order_import_dead_letter_routing_key";
|
||||
|
||||
/**
|
||||
* 广告状态修改 延迟队列
|
||||
*/
|
||||
public static final String SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_QUEUE = "system_advertisement_update_delayed_queue";
|
||||
|
||||
/**
|
||||
* 广告状态修改 延迟交换机
|
||||
*/
|
||||
public static final String SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_EXCHANGE = "system_advertisement_update_delayed_exchange";
|
||||
|
||||
/**
|
||||
* 广告状态修改 延迟路由键
|
||||
*/
|
||||
public static final String SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_ROUTING_KEY = "system_advertisement_update_delayed_routing_key";
|
||||
|
||||
}
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.cf.imes.module.system.api.advertisement;
|
||||
|
||||
import com.cf.imes.module.system.enums.ApiConstants;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
@FeignClient(name = ApiConstants.NAME) // TODO 晨丰:fallbackFactory =
|
||||
@Tag(name = "RPC 服务 - 广告管理")
|
||||
public interface AdvertisementApi {
|
||||
|
||||
String PREFIX = ApiConstants.PREFIX + "/ad";
|
||||
|
||||
@GetMapping(PREFIX + "/published")
|
||||
@Operation(summary = "结束发布广告")
|
||||
@Parameter(name = "id", description = "广告id", required = true)
|
||||
Boolean published(@RequestParam("id") Long id) ;
|
||||
|
||||
@GetMapping(PREFIX + "/publishing")
|
||||
@Operation(summary = "立即发布广告")
|
||||
@Parameter(name = "id", description = "广告id", required = true)
|
||||
Boolean publishing(@RequestParam("id") Long id) ;
|
||||
}
|
||||
+4
@@ -29,4 +29,8 @@ public class DictTypeConstants {
|
||||
|
||||
|
||||
public static final String PLATE_TEXTURE_TYPE = "plate_texture_type";// 板材纹路:0有 1无
|
||||
|
||||
|
||||
public static final String ADVERTISEMENT_POSITION = "advertisement_position";
|
||||
|
||||
}
|
||||
|
||||
+19
@@ -422,5 +422,24 @@ public class ErrorCodeConstants {
|
||||
public static final ErrorCode INVOICE_FILE_DATA_ERROR = new ErrorCode(1_002_043_007, "发票附件下载失败,请重新下载或稍等重试");
|
||||
|
||||
|
||||
public static final ErrorCode PRODUCTS_NO_EXIST = new ErrorCode(1_002_044_001, "当前产品不存在");
|
||||
public static final ErrorCode PRODUCTS_DETAIL_NO_EXIST = new ErrorCode(1_002_044_002, "当前产品的规则不存在");
|
||||
public static final ErrorCode PRODUCTS_DURATION_NOT_NULL = new ErrorCode(1_002_044_003, "购买方式为时长时,需确定产品时长");
|
||||
public static final ErrorCode PRODUCTS_OUTPUT_NOT_NULL = new ErrorCode(1_002_044_004, "购买方式为产量时,需确定产量数量");
|
||||
public static final ErrorCode PRODUCTS_DETAIL_DURATION_EXIST = new ErrorCode(1_002_044_005, "存在当前时长的产品定价规则");
|
||||
public static final ErrorCode PRODUCTS_DETAIL_OUTPUT_EXIST = new ErrorCode(1_002_044_006, "存在当前产量的产品定价规则");
|
||||
public static final ErrorCode PRODUCTS_DURATION_NUM_ERR = new ErrorCode(1_002_044_007, "产品定价规则,时长数据设置有误");
|
||||
public static final ErrorCode PRODUCTS_DURATION_INT_ERR = new ErrorCode(1_002_044_008, "产品定价规则,时长数据为正整数");
|
||||
public static final ErrorCode PRODUCTS_DURATION_UNIT_ERR = new ErrorCode(1_002_044_009, "产品定价规则,时长单位设置有误");
|
||||
|
||||
public static final ErrorCode ADVERTISEMENT_POSITION_NO_EXIST = new ErrorCode(1_003_001_001, "广告所选放置位置不存在");
|
||||
public static final ErrorCode ADVERTISEMENT_NO_EXIST = new ErrorCode(1_003_001_002, "广告不存在");
|
||||
public static final ErrorCode ADVERTISEMENT_STATUS_ERROR = new ErrorCode(1_003_001_003, "当前广告已经发布,无需立即发布");
|
||||
public static final ErrorCode ADVERTISEMENT_STATUS_ERROR2 = new ErrorCode(1_003_001_004, "当前广告已过结束时间,请点击重新发布");
|
||||
public static final ErrorCode ADVERTISEMENT_END_ERROR = new ErrorCode(1_003_001_005, "当前广告未发布,无需结束发布");
|
||||
public static final ErrorCode ADVERTISEMENT_END_ERROR2 = new ErrorCode(1_003_001_006, "当前广告已结束,无需立即结束");
|
||||
public static final ErrorCode ADVERTISEMENT_FAIL = new ErrorCode(1_003_001_007, "自动发布失败");
|
||||
|
||||
public static final ErrorCode RECHARGE_ACTIVE_NO_EXIST = new ErrorCode(1_004_001_001, "当前赠送金活动不存在");
|
||||
|
||||
}
|
||||
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
package com.cf.imes.module.system.enums.advertisement;
|
||||
|
||||
import com.cf.imes.framework.common.core.IntArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 广告状态单位态枚举
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum AdvertisementStatusEnum implements IntArrayValuable {
|
||||
|
||||
ALL(0, "全部"),
|
||||
UNPUBLISHED(1, "未发布"),
|
||||
PUBLISHED(2, "已发布"),
|
||||
ENDED(3, "已结束");
|
||||
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(AdvertisementStatusEnum::getStatus).toArray();
|
||||
|
||||
/**
|
||||
* 状态值
|
||||
*/
|
||||
private final Integer status;
|
||||
/**
|
||||
* 状态名
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public int[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static boolean isAll(String name) {
|
||||
return Objects.equals(ALL.name, name);
|
||||
}
|
||||
|
||||
public static boolean isUnpublished(String name) {
|
||||
return Objects.equals(UNPUBLISHED.name, name);
|
||||
}
|
||||
|
||||
public static boolean isPublished(String name) {
|
||||
return Objects.equals(PUBLISHED.name, name);
|
||||
}
|
||||
|
||||
public static boolean isEnded(String name) {
|
||||
return Objects.equals(ENDED.name, name);
|
||||
}
|
||||
|
||||
public static Integer getNameByStatus(String name) {
|
||||
for (AdvertisementStatusEnum e : values()) {
|
||||
if (e.getName().equals(name)) {
|
||||
return e.getStatus();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package com.cf.imes.module.system.enums.advertisement;
|
||||
|
||||
import com.cf.imes.framework.common.core.IntArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 延迟消息状态单位态枚举
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum MessageStatusEnum implements IntArrayValuable {
|
||||
|
||||
PENDING(0, "待处理"),
|
||||
PROCESSED(1, "已处理"),
|
||||
CANCELLED(2, "已取消");
|
||||
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(MessageStatusEnum::getStatus).toArray();
|
||||
|
||||
/**
|
||||
* 状态值
|
||||
*/
|
||||
private final Integer status;
|
||||
/**
|
||||
* 状态名
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public int[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static boolean isPending(String name) {
|
||||
return Objects.equals(PENDING.name, name);
|
||||
}
|
||||
|
||||
public static boolean isProcessed(String name) {
|
||||
return Objects.equals(PROCESSED.name, name);
|
||||
}
|
||||
|
||||
public static boolean isCancelled(String name) {
|
||||
return Objects.equals(CANCELLED.name, name);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.cf.imes.module.system.enums.products;
|
||||
|
||||
import com.cf.imes.framework.common.core.IntArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 时长单位态枚举
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum DurationUnitEnum implements IntArrayValuable {
|
||||
|
||||
YEAR(0, "year"),
|
||||
MONTH(1, "month"),
|
||||
DAY(2, "day");
|
||||
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(DurationUnitEnum::getStatus).toArray();
|
||||
|
||||
/**
|
||||
* 状态值
|
||||
*/
|
||||
private final Integer status;
|
||||
/**
|
||||
* 状态名
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public int[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static boolean isYear(String name) {
|
||||
return Objects.equals(YEAR.name, name);
|
||||
}
|
||||
|
||||
public static boolean isMonth(String name) {
|
||||
return Objects.equals(MONTH.name, name);
|
||||
}
|
||||
|
||||
public static boolean isDay(String name) {
|
||||
return Objects.equals(DAY.name, name);
|
||||
}
|
||||
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.cf.imes.module.system.enums.products;
|
||||
|
||||
import com.cf.imes.framework.common.core.IntArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 产品状态枚举
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ProductStatusEnum implements IntArrayValuable {
|
||||
|
||||
PRODUCT_ALL(0, "全部"),
|
||||
PRODUCT_WAITING_UPDATES(1, "待上架"),
|
||||
PRODUCT_UPDATES(2, "已上架"),
|
||||
PRODUCT_DELIS(3, "已下架");
|
||||
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductStatusEnum::getStatus).toArray();
|
||||
|
||||
/**
|
||||
* 状态值
|
||||
*/
|
||||
private final Integer status;
|
||||
/**
|
||||
* 状态名
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public int[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static boolean isProductWaitingUpdates(Integer status) {
|
||||
return Objects.equals(PRODUCT_WAITING_UPDATES.status, status);
|
||||
}
|
||||
|
||||
public static boolean isProductUpdates(Integer status) {
|
||||
return Objects.equals(PRODUCT_UPDATES.status, status);
|
||||
}
|
||||
|
||||
public static boolean isProductDelis(Integer status) {
|
||||
return Objects.equals(PRODUCT_DELIS.status, status);
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package com.cf.imes.module.system.enums.products;
|
||||
|
||||
import com.cf.imes.framework.common.core.IntArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 产品详情购买方式状态枚举
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ProductsPurchaseTypeEnum implements IntArrayValuable {
|
||||
|
||||
DURATION(0, "时长"),
|
||||
OUTPUT(1, "产量");
|
||||
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductsPurchaseTypeEnum::getStatus).toArray();
|
||||
|
||||
/**
|
||||
* 状态值
|
||||
*/
|
||||
private final Integer status;
|
||||
/**
|
||||
* 状态名
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public int[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static boolean isDURATION(Integer status) {
|
||||
return Objects.equals(DURATION.status, status);
|
||||
}
|
||||
|
||||
public static boolean isOUTPUT(Integer status) {
|
||||
return Objects.equals(OUTPUT.status, status);
|
||||
}
|
||||
}
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package com.cf.imes.module.system.enums.recharge;
|
||||
|
||||
import com.cf.imes.framework.common.core.IntArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 充值赠送类型枚举
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PurchaseTypeEnum implements IntArrayValuable {
|
||||
|
||||
ONE(0, "满X送X"),
|
||||
TWO(1, "每满X送X");
|
||||
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PurchaseTypeEnum::getStatus).toArray();
|
||||
|
||||
/**
|
||||
* 状态值
|
||||
*/
|
||||
private final Integer status;
|
||||
/**
|
||||
* 状态名
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public int[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static boolean isOne(String name) {
|
||||
return Objects.equals(ONE.name, name);
|
||||
}
|
||||
|
||||
public static boolean isTwo(String name) {
|
||||
return Objects.equals(TWO.name, name);
|
||||
}
|
||||
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package com.cf.imes.module.system.enums.recharge;
|
||||
|
||||
import com.cf.imes.framework.common.core.IntArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 充值类型枚举
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum RechargeTypeEnum implements IntArrayValuable {
|
||||
|
||||
ONE(0, "微信、支付宝"),
|
||||
TWO(1, "微信"),
|
||||
THREE(2, "支付宝");
|
||||
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(RechargeTypeEnum::getStatus).toArray();
|
||||
|
||||
/**
|
||||
* 状态值
|
||||
*/
|
||||
private final Integer status;
|
||||
/**
|
||||
* 状态名
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public int[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static boolean isOne(String name) {
|
||||
return Objects.equals(ONE.name, name);
|
||||
}
|
||||
|
||||
public static boolean isTwo(String name) {
|
||||
return Objects.equals(TWO.name, name);
|
||||
}
|
||||
|
||||
public static boolean isThree(String name) {
|
||||
return Objects.equals(THREE.name, name);
|
||||
}
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
package com.cf.imes.module.system.controller.admin.advertisement;
|
||||
|
||||
import com.cf.imes.framework.common.pojo.CommonResult;
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.common.util.object.BeanUtils;
|
||||
import com.cf.imes.module.system.controller.admin.advertisement.vo.AdvertisementPageReqVO;
|
||||
import com.cf.imes.module.system.controller.admin.advertisement.vo.AdvertisementRespVO;
|
||||
import com.cf.imes.module.system.controller.admin.advertisement.vo.AdvertisementSaveReqVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.advertisement.AdvertisementDO;
|
||||
import com.cf.imes.module.system.enums.advertisement.AdvertisementStatusEnum;
|
||||
import com.cf.imes.module.system.service.advertisement.AdvertisementService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static com.cf.imes.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 广告管理")
|
||||
@RestController
|
||||
@RequestMapping("/system/ad")
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class AdvertisementController {
|
||||
|
||||
@Resource
|
||||
private AdvertisementService advertisementService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "新建广告")
|
||||
@PreAuthorize("@ss.hasPermission('base:advertisement:create')")
|
||||
public CommonResult<Long> createAdvertisement(@Valid @RequestBody AdvertisementSaveReqVO createReqVO) {
|
||||
return success(advertisementService.create(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新广告")
|
||||
@PreAuthorize("@ss.hasPermission('base:advertisement:update')")
|
||||
public CommonResult<Boolean> updateAdvertisement(@Valid @RequestBody AdvertisementSaveReqVO updateReqVO) {
|
||||
AdvertisementDO productsDO = BeanUtils.toBean(updateReqVO, AdvertisementDO.class);
|
||||
advertisementService.update(productsDO, 0);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除广告")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('base:advertisement:delete')")
|
||||
public CommonResult<Boolean> deleteAdvertisement(@RequestParam("id") Long id) {
|
||||
advertisementService.delete(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得广告")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('base:advertisement:query')")
|
||||
public CommonResult<AdvertisementRespVO> getAdvertisement(@RequestParam("id") Long id) {
|
||||
AdvertisementDO productRespVO = advertisementService.get(id);
|
||||
return success(BeanUtils.toBean(productRespVO, AdvertisementRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得广告分页")
|
||||
@PreAuthorize("@ss.hasPermission('base:advertisement:query')")
|
||||
public CommonResult<PageResult<AdvertisementSaveReqVO>> getAdvertisementPage(@Valid AdvertisementPageReqVO pageReqVO) {
|
||||
PageResult<AdvertisementDO> pageResult = advertisementService.getPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, AdvertisementSaveReqVO.class));
|
||||
}
|
||||
|
||||
@PutMapping("/published")
|
||||
@Operation(summary = "结束发布广告")
|
||||
@Parameter(name = "id", description = "广告id", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('base:advertisement:update')")
|
||||
public CommonResult<Boolean> published(@RequestParam("id") Long id) {
|
||||
advertisementService.update(id, AdvertisementStatusEnum.ENDED.getStatus());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/publishing")
|
||||
@Operation(summary = "立即发布广告")
|
||||
@PreAuthorize("@ss.hasPermission('base:advertisement:update')")
|
||||
@Parameter(name = "id", description = "广告id", required = true)
|
||||
public CommonResult<Boolean> publishing(@RequestParam("id") Long id) {
|
||||
advertisementService.update(id,AdvertisementStatusEnum.PUBLISHED.getStatus());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/republish")
|
||||
@Operation(summary = "重新发布广告")
|
||||
@Parameter(name = "id", description = "广告id", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('base:advertisement:update')")
|
||||
public CommonResult<Boolean> republish(@Valid @RequestBody AdvertisementSaveReqVO updateReqVO) {
|
||||
AdvertisementDO productsDO = BeanUtils.toBean(updateReqVO, AdvertisementDO.class);
|
||||
advertisementService.update(productsDO, 1);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
package com.cf.imes.module.system.controller.admin.advertisement.vo;
|
||||
|
||||
import com.cf.imes.framework.common.pojo.PageParam;
|
||||
import com.cf.imes.module.system.validation.advertisement.AdvertisementStatus;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static com.cf.imes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 广告分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class AdvertisementPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "广告id", example = "163681486581530624")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "广告名称", example = "西亚哈")
|
||||
private String adName;
|
||||
|
||||
@Schema(description = "软件标识", example = "163681481946824704")
|
||||
private String softwareId;
|
||||
|
||||
@Schema(description = "广告位置")
|
||||
private String adPosition;
|
||||
|
||||
@Schema(description = "广告图片")
|
||||
private String adImagePath;
|
||||
|
||||
@Schema(description = "投放开始时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] startTime;
|
||||
|
||||
@Schema(description = "投放结束时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] endTime;
|
||||
|
||||
@Schema(description = "跳转路径")
|
||||
private String adRedirectUrl;
|
||||
|
||||
@Schema(description = "广告顺序")
|
||||
private Short sort;
|
||||
|
||||
@Schema(description = "广告状态", example = "0全部 1未发布 2已发布 3已结束")
|
||||
@AdvertisementStatus
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "操作人")
|
||||
private String updater;
|
||||
|
||||
@Schema(description = "操作时间")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@Schema(description = "排序", example = "ascend")
|
||||
private String order;
|
||||
|
||||
@Schema(description = "排序字段", example = "id")
|
||||
private String field;
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.cf.imes.module.system.controller.admin.advertisement.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 广告管理 Response VO")
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class AdvertisementRespVO {
|
||||
|
||||
@Schema(description = "广告id", requiredMode = Schema.RequiredMode.REQUIRED, example = "163681486581530624")
|
||||
private int id;
|
||||
|
||||
@Schema(description = "广告名称", example = "西亚哈")
|
||||
private String adName;
|
||||
|
||||
@Schema(description = "广告位置")
|
||||
private String adPosition;
|
||||
|
||||
@Schema(description = "图片路径")
|
||||
private String adImagePath;
|
||||
|
||||
@Schema(description = "投放开始时间")
|
||||
private LocalDateTime startTime;
|
||||
|
||||
@Schema(description = "投放结束时间")
|
||||
private LocalDateTime endTime;
|
||||
|
||||
@Schema(description = "跳转路径")
|
||||
private String adRedirectUrl;
|
||||
|
||||
@Schema(description = "广告顺序")
|
||||
private Short sort;
|
||||
|
||||
@Schema(description = "广告状态", example = "0全部 1未发布 2已发布 3已结束")
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package com.cf.imes.module.system.controller.admin.advertisement.vo;
|
||||
|
||||
import com.cf.imes.framework.common.validation.NumberValid;
|
||||
import com.cf.imes.module.system.validation.advertisement.AdvertisementStatus;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 广告新增/修改 Request VO")
|
||||
@Data
|
||||
public class AdvertisementSaveReqVO {
|
||||
|
||||
@Schema(description = "广告id", example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "广告名称", example = "西亚哈")
|
||||
@NotBlank(message = "广告名称不能为空")
|
||||
@Size(max = 32, message = "广告名称长度不能超过 32 个字符")
|
||||
private String adName;
|
||||
|
||||
@Schema(description = "软件标识", example = "163681481946824704")
|
||||
private String softwareId;
|
||||
|
||||
@Schema(description = "广告位置,字典键值", example = "[1,2]")
|
||||
@NotNull(message = "广告位置不能为空")
|
||||
private Integer[] adPosition;
|
||||
|
||||
@Schema(description = "广告图片")
|
||||
@NotBlank(message = "广告图片不能为空")
|
||||
@Size(max = 255, message = "广告图片长度不能超过 255 个字符")
|
||||
private String adImagePath;
|
||||
|
||||
@Schema(description = "投放开始时间")
|
||||
@NotNull(message = "投放开始时间不能为空")
|
||||
private LocalDateTime startTime;
|
||||
|
||||
@Schema(description = "投放结束时间")
|
||||
@NotNull(message = "投放结束时间不能为空")
|
||||
private LocalDateTime endTime;
|
||||
|
||||
@Schema(description = "跳转路径")
|
||||
@Size(max = 255, message = "链接长度不能超过 255 个字符")
|
||||
private String adRedirectUrl;
|
||||
|
||||
@Schema(description = "广告顺序")
|
||||
@NumberValid(name = "广告顺序")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "广告状态", example = "0全部 1未发布 2已发布 3已结束")
|
||||
@AdvertisementStatus
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
package com.cf.imes.module.system.controller.admin.products;
|
||||
|
||||
import com.cf.imes.framework.common.pojo.CommonResult;
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.common.util.object.BeanUtils;
|
||||
import com.cf.imes.module.system.controller.admin.products.vo.product.ProductPageReqVO;
|
||||
import com.cf.imes.module.system.controller.admin.products.vo.product.ProductRespVO;
|
||||
import com.cf.imes.module.system.controller.admin.products.vo.product.ProductSaveReqVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.products.ProductsDO;
|
||||
import com.cf.imes.module.system.service.products.ProductsService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static com.cf.imes.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 产品管理")
|
||||
@RestController
|
||||
@RequestMapping("/system/products")
|
||||
@Validated
|
||||
public class ProductsController {
|
||||
|
||||
|
||||
@Resource
|
||||
private ProductsService productsService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "新建产品")
|
||||
// @PreAuthorize("@ss.hasPermission('base:products:create')")
|
||||
public CommonResult<Long> createProducts(@RequestParam("productName") String productName) {
|
||||
return success(productsService.create(productName));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新产品")
|
||||
// @PreAuthorize("@ss.hasPermission('base:products:update')")
|
||||
public CommonResult<Boolean> updateProducts(@Valid @RequestBody ProductSaveReqVO updateReqVO) {
|
||||
ProductsDO productsDO = BeanUtils.toBean(updateReqVO, ProductsDO.class);
|
||||
productsService.update(productsDO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/freeze")
|
||||
@Operation(summary = "下架产品")
|
||||
// @PreAuthorize("@ss.hasPermission('base:products:freeze')")
|
||||
public CommonResult<Boolean> freezeProducts(@Valid Long id) {
|
||||
ProductsDO productsDO = new ProductsDO().setId(id).setStatus(3);
|
||||
productsService.update(productsDO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/melt")
|
||||
@Operation(summary = "上架产品")
|
||||
@PreAuthorize("@ss.hasPermission('base:products:melt')")
|
||||
public CommonResult<Boolean> meltProducts(@Valid Long id) {
|
||||
ProductsDO productsDO = new ProductsDO().setId(id).setStatus(2);
|
||||
productsService.update(productsDO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除产品")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('base:products:delete')")
|
||||
public CommonResult<Boolean> deleteProducts(@RequestParam("id") Long id) {
|
||||
productsService.delete(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得产品")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('base:products:query')")
|
||||
public CommonResult<ProductRespVO> getProducts(@RequestParam("id") Long id) {
|
||||
ProductsDO productRespVO = productsService.get(id);
|
||||
return success(BeanUtils.toBean(productRespVO, ProductRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得产品分页")
|
||||
@PreAuthorize("@ss.hasPermission('base:products:query')")
|
||||
public CommonResult<PageResult<ProductRespVO>> getProductsPage(@Valid ProductPageReqVO pageReqVO) {
|
||||
PageResult<ProductsDO> pageResult = productsService.getPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, ProductRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
package com.cf.imes.module.system.controller.admin.products;
|
||||
|
||||
import com.cf.imes.framework.common.pojo.CommonResult;
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.common.util.object.BeanUtils;
|
||||
import com.cf.imes.module.system.controller.admin.products.vo.productDetails.ProductDetailsPageReqVO;
|
||||
import com.cf.imes.module.system.controller.admin.products.vo.productDetails.ProductDetailsRespVO;
|
||||
import com.cf.imes.module.system.controller.admin.products.vo.productDetails.ProductDetailsSaveReqVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.products.ProductsDetailDO;
|
||||
import com.cf.imes.module.system.service.products.ProductsDetailService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
import static com.cf.imes.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 产品明细管理")
|
||||
@RestController
|
||||
@RequestMapping("/system/product-details")
|
||||
@Validated
|
||||
public class ProductsDetailController {
|
||||
|
||||
@Resource
|
||||
private ProductsDetailService productDetailsService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "新建产品明细")
|
||||
@PreAuthorize("@ss.hasPermission('base:productDetails:create')")
|
||||
public CommonResult<Long> createProducts(@Valid @RequestBody ProductDetailsSaveReqVO createReqVO) {
|
||||
return success(productDetailsService.create(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新产品明细")
|
||||
@PreAuthorize("@ss.hasPermission('base:productDetails:update')")
|
||||
public CommonResult<Boolean> updateProducts(@Valid @RequestBody ProductDetailsSaveReqVO updateReqVO) {
|
||||
productDetailsService.update(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除产品明细")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('base:productDetails:delete')")
|
||||
public CommonResult<Boolean> deleteProducts(@RequestParam("id") Long id) {
|
||||
productDetailsService.delete(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得产品明细")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('base:productDetails:query')")
|
||||
public CommonResult<List<ProductsDetailDO>> getProducts(@RequestParam("id") Long id) {
|
||||
List<ProductsDetailDO> productDetailsDO = productDetailsService.get(id);
|
||||
return success(productDetailsDO);
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得产品明细分页")
|
||||
@PreAuthorize("@ss.hasPermission('base:productDetails:query')")
|
||||
public CommonResult<PageResult<ProductDetailsRespVO>> getProductsPage(@Valid ProductDetailsPageReqVO pageReqVO) {
|
||||
PageResult<ProductsDetailDO> pageResult = productDetailsService.getPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, ProductDetailsRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.cf.imes.module.system.controller.admin.products.vo.product;
|
||||
|
||||
import com.cf.imes.framework.common.pojo.PageParam;
|
||||
import com.cf.imes.module.system.validation.products.ProductStatus;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static com.cf.imes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 产品表 products Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class ProductPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "产品id", example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "产品名称", example = "赵六")
|
||||
private String productName;
|
||||
|
||||
@Schema(description = "产品状态", example = "0待上架 1已上架 2已下架")
|
||||
@ProductStatus
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "软件id", example = "1")
|
||||
private Long softwareId;
|
||||
|
||||
@Schema(description = "操作时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] updateTime;
|
||||
|
||||
@Schema(description = "是否删除")
|
||||
private Integer deleted;
|
||||
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package com.cf.imes.module.system.controller.admin.products.vo.product;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.cf.imes.module.system.validation.products.ProductStatus;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 产品表 products Response VO")
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class ProductRespVO {
|
||||
|
||||
@Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "10725")
|
||||
@ExcelProperty("产品ID")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
|
||||
@ExcelProperty("产品名称")
|
||||
private String productName;
|
||||
|
||||
@Schema(description = "产品状态", example = "0待上架 1已上架 2已下架")
|
||||
@ExcelProperty("产品状态")
|
||||
@ProductStatus
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "软件id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("软件id")
|
||||
private Long softwareId;
|
||||
|
||||
@Schema(description = "编辑时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("编辑时间")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.cf.imes.module.system.controller.admin.products.vo.product;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
@Schema(description = "管理后台 - 产品表 product新增/修改 Request VO")
|
||||
@Data
|
||||
public class ProductSaveReqVO {
|
||||
|
||||
@Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "10725")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
|
||||
@NotEmpty(message = "产品名称不能为空")
|
||||
private String productName;
|
||||
|
||||
@Schema(description = "产品状态", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "软件id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Long softwareId;
|
||||
|
||||
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package com.cf.imes.module.system.controller.admin.products.vo.productDetails;
|
||||
|
||||
import com.cf.imes.framework.common.pojo.PageParam;
|
||||
import com.cf.imes.module.system.validation.products.ProductType;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static com.cf.imes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 产品详情表 productDetails Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class ProductDetailsPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "产品详情id", example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "产品ID", example = "1")
|
||||
private String productId;
|
||||
|
||||
@Schema(description = "购买方式", example = "购买方式:0时长;1产量")
|
||||
@ProductType
|
||||
private Integer purchaseType;
|
||||
|
||||
@Schema(description = "正常时间", example = "半个月")
|
||||
private String duration;
|
||||
|
||||
@Schema(description = "正常产量", example = "")
|
||||
private BigDecimal output;
|
||||
|
||||
@Schema(description = "赠送时间", example = "半个月")
|
||||
private String giftDuration;
|
||||
|
||||
@Schema(description = "赠送产量", example = "")
|
||||
private BigDecimal giftOutput;
|
||||
|
||||
@Schema(description = "产品原价", example = "100")
|
||||
private BigDecimal originalPrice;
|
||||
|
||||
@Schema(description = "折扣", example = "0.8")
|
||||
private BigDecimal discount;
|
||||
|
||||
@Schema(description = "产品现价", example = "80")
|
||||
private BigDecimal currentPrice;
|
||||
|
||||
@Schema(description = "是否特惠", example = "是")
|
||||
private Boolean isDiscounted;
|
||||
|
||||
@Schema(description = "操作时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] updateTime;
|
||||
|
||||
@Schema(description = "是否删除")
|
||||
private Integer deleted;
|
||||
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package com.cf.imes.module.system.controller.admin.products.vo.productDetails;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.cf.imes.module.system.validation.products.ProductType;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
|
||||
@Schema(description = "管理后台 - 产品明细表 productsDetails Response VO")
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class ProductDetailsRespVO {
|
||||
|
||||
@Schema(description = "产品详情id", requiredMode = Schema.RequiredMode.REQUIRED, example = "10725")
|
||||
@ExcelProperty("产品详情id")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@ExcelProperty("产品ID")
|
||||
private String productId;
|
||||
|
||||
@Schema(description = "购买方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "购买方式:0时长;1产量")
|
||||
@ProductType
|
||||
private Integer purchaseType;
|
||||
|
||||
@Schema(description = "正常时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "半个月")
|
||||
private String duration;
|
||||
|
||||
@Schema(description = "正常产量", requiredMode = Schema.RequiredMode.REQUIRED, example = "")
|
||||
private BigDecimal output;
|
||||
|
||||
@Schema(description = "赠送时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "半个月")
|
||||
private String giftDuration;
|
||||
|
||||
@Schema(description = "赠送产量", requiredMode = Schema.RequiredMode.REQUIRED, example = "")
|
||||
private BigDecimal giftOutput;
|
||||
|
||||
@Schema(description = "产品原价", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
|
||||
private BigDecimal originalPrice;
|
||||
|
||||
@Schema(description = "折扣", requiredMode = Schema.RequiredMode.REQUIRED, example = "0.8")
|
||||
private BigDecimal discount;
|
||||
|
||||
@Schema(description = "产品现价", requiredMode = Schema.RequiredMode.REQUIRED, example = "80")
|
||||
private BigDecimal currentPrice;
|
||||
|
||||
@Schema(description = "是否特惠", requiredMode = Schema.RequiredMode.REQUIRED, example = "是")
|
||||
private Boolean isDiscounted;
|
||||
|
||||
@Schema(description = "操作时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package com.cf.imes.module.system.controller.admin.products.vo.productDetails;
|
||||
|
||||
import com.cf.imes.module.system.validation.products.ProductType;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Schema(description = "管理后台 - 产品明细表 productDetails新增/修改 Request VO")
|
||||
@Data
|
||||
public class ProductDetailsSaveReqVO {
|
||||
|
||||
@Schema(description = "产品详情id", requiredMode = Schema.RequiredMode.REQUIRED, example = "10725")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "产品名称不能为空")
|
||||
private Long productId;
|
||||
|
||||
@Schema(description = "购买方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "购买方式:0时长;1产量")
|
||||
@NotNull(message = "购买方式不能为空")
|
||||
@ProductType
|
||||
private Integer purchaseType;
|
||||
|
||||
@Schema(description = "产品时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "1month")
|
||||
private String duration;
|
||||
|
||||
@Schema(description = "产品产量", requiredMode = Schema.RequiredMode.REQUIRED, example = "")
|
||||
private BigDecimal output;
|
||||
|
||||
@Schema(description = "赠送时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "半个月")
|
||||
private String giftDuration;
|
||||
|
||||
@Schema(description = "赠送产量", requiredMode = Schema.RequiredMode.REQUIRED, example = "")
|
||||
private BigDecimal giftOutput;
|
||||
|
||||
@Schema(description = "产品原价", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
|
||||
@NotNull(message = "产品时间不能为空")
|
||||
private BigDecimal originalPrice;
|
||||
|
||||
@Schema(description = "折扣", requiredMode = Schema.RequiredMode.REQUIRED, example = "0.8")
|
||||
private BigDecimal discount;
|
||||
|
||||
@Schema(description = "产品现价", requiredMode = Schema.RequiredMode.REQUIRED, example = "80")
|
||||
@NotNull(message = "产品时间不能为空")
|
||||
private BigDecimal currentPrice;
|
||||
|
||||
@Schema(description = "是否特惠", requiredMode = Schema.RequiredMode.REQUIRED, example = "是")
|
||||
private Boolean isDiscounted;
|
||||
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
package com.cf.imes.module.system.controller.admin.recharge;
|
||||
|
||||
import com.cf.imes.framework.common.pojo.CommonResult;
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.common.util.object.BeanUtils;
|
||||
import com.cf.imes.module.system.controller.admin.recharge.vo.RechargePageReqVO;
|
||||
import com.cf.imes.module.system.controller.admin.recharge.vo.RechargeRespVO;
|
||||
import com.cf.imes.module.system.controller.admin.recharge.vo.RechargeSaveReqVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.recharge.GiftMoneyDetailsDO;
|
||||
import com.cf.imes.module.system.service.recharge.RechargeActiveService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static com.cf.imes.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 充值活动管理")
|
||||
@RestController
|
||||
@RequestMapping("/system/recharge-active")
|
||||
@Validated
|
||||
public class RechargeActiveController {
|
||||
|
||||
@Resource
|
||||
private RechargeActiveService productsService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "新建充值活动")
|
||||
@PreAuthorize("@ss.hasPermission('base:recharge-active:create')")
|
||||
public CommonResult<Long> createRechargeActive(@Valid @RequestBody RechargeSaveReqVO createReqVO) {
|
||||
return success(productsService.create(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新充值活动")
|
||||
@PreAuthorize("@ss.hasPermission('base:recharge-active:update')")
|
||||
public CommonResult<Boolean> updateRechargeActive(@Valid @RequestBody RechargeSaveReqVO updateReqVO) {
|
||||
productsService.update(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除充值活动")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('base:recharge-active:delete')")
|
||||
public CommonResult<Boolean> deleteRechargeActive(@RequestParam("id") Long id) {
|
||||
productsService.delete(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得充值活动")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('base:recharge-active:query')")
|
||||
public CommonResult<RechargeRespVO> getRechargeActive(@RequestParam("id") Long id) {
|
||||
GiftMoneyDetailsDO giftMoneyDetailsDO = productsService.get(id);
|
||||
return success(BeanUtils.toBean(giftMoneyDetailsDO, RechargeRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得充值活动分页")
|
||||
@PreAuthorize("@ss.hasPermission('base:recharge-active:query')")
|
||||
public CommonResult<PageResult<RechargeRespVO>> getRechargeActivePage(@Valid RechargePageReqVO pageReqVO) {
|
||||
PageResult<GiftMoneyDetailsDO> pageResult = productsService.getPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, RechargeRespVO.class));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
package com.cf.imes.module.system.controller.admin.recharge.vo;
|
||||
|
||||
import com.cf.imes.framework.common.pojo.PageParam;
|
||||
import com.cf.imes.module.system.validation.recharge.PurchaseType;
|
||||
import com.cf.imes.module.system.validation.recharge.RechargeType;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static com.cf.imes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 赠送金活动表 gift_money Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class RechargePageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "活动id", example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "活动名称", example = "赵六")
|
||||
private String activityName;
|
||||
|
||||
@Schema(description = "赠送类型", example = "0满X送X; 1每满X送X")
|
||||
@PurchaseType
|
||||
private Integer purchaseType;
|
||||
|
||||
@Schema(description = "充值类型", example = "0微信、支付宝 1微信 2支付宝")
|
||||
@RechargeType
|
||||
private Integer rechargeType;
|
||||
|
||||
@Schema(description = "充值金额")
|
||||
private BigDecimal rechargeAmount;
|
||||
|
||||
@Schema(description = "赠送金额")
|
||||
private BigDecimal giftAmount;
|
||||
|
||||
@Schema(description = "投放开始时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] startTime;
|
||||
|
||||
@Schema(description = "投放结束时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] endTime;
|
||||
|
||||
@Schema(description = "操作时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] updateTime;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "是否删除")
|
||||
private Integer deleted;
|
||||
|
||||
@Schema(description = "排序", example = "ascend")
|
||||
private String order;
|
||||
|
||||
@Schema(description = "排序字段", example = "id")
|
||||
private String field;
|
||||
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package com.cf.imes.module.system.controller.admin.recharge.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static com.cf.imes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 赠送金活动表 gift_money Request VO")
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class RechargeRespVO {
|
||||
|
||||
@Schema(description = "活动id", example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "活动名称", example = "赵六")
|
||||
private String activityName;
|
||||
|
||||
@Schema(description = "赠送类型", example = "0满X送X; 1每满X送X")
|
||||
private Integer purchaseType;
|
||||
|
||||
@Schema(description = "充值类型", example = "0微信、支付宝 1微信 2支付宝")
|
||||
private Integer rechargeType;
|
||||
|
||||
@Schema(description = "充值金额")
|
||||
private BigDecimal rechargeAmount;
|
||||
|
||||
@Schema(description = "赠送金额")
|
||||
private BigDecimal giftAmount;
|
||||
|
||||
@Schema(description = "投放开始时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime startTime;
|
||||
|
||||
@Schema(description = "投放结束时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime endTime;
|
||||
|
||||
@Schema(description = "操作时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "是否删除")
|
||||
private Integer deleted;
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
package com.cf.imes.module.system.controller.admin.recharge.vo;
|
||||
|
||||
import com.cf.imes.module.system.validation.recharge.MoneyValid;
|
||||
import com.cf.imes.module.system.validation.recharge.PurchaseType;
|
||||
import com.cf.imes.module.system.validation.recharge.RechargeType;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static com.cf.imes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 赠送金活动表 gift_money 新增/修改 Request VO")
|
||||
@Data
|
||||
public class RechargeSaveReqVO {
|
||||
|
||||
@Schema(description = "活动id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "活动名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
|
||||
@NotNull(message = "活动名称不能为空")
|
||||
private String activityName;
|
||||
|
||||
@Schema(description = "赠送类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "0满X送X; 1每满X送X")
|
||||
@NotNull(message = "赠送类型不能为空")
|
||||
@PurchaseType
|
||||
private Integer purchaseType;
|
||||
|
||||
@Schema(description = "充值类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "0微信、支付宝 1微信 2支付宝")
|
||||
@NotNull(message = "充值类型不能为空")
|
||||
@RechargeType
|
||||
private Integer rechargeType;
|
||||
|
||||
@Schema(description = "充值金额",requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
|
||||
@NotNull(message = "充值金额不能为空")
|
||||
@MoneyValid(name = "充值金额")
|
||||
private BigDecimal rechargeAmount;
|
||||
|
||||
@Schema(description = "赠送金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
|
||||
@NotNull(message = "赠送金额不能为空")
|
||||
@MoneyValid(name = "赠送金额")
|
||||
private BigDecimal giftAmount;
|
||||
|
||||
@Schema(description = "开始时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@NotNull(message = "开始时间不能为空")
|
||||
private LocalDateTime startTime;
|
||||
|
||||
@Schema(description = "结束时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@NotNull(message = "结束时间不能为空")
|
||||
private LocalDateTime endTime;
|
||||
|
||||
@Schema(description = "操作时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "是否删除")
|
||||
private Integer deleted;
|
||||
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
package com.cf.imes.module.system.dal.dataobject.advertisement;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.cf.imes.framework.mybatis.core.dataobject.BaseDO;
|
||||
import lombok.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 广告表 product_details DO
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@TableName("advertisement")
|
||||
@KeySequence("advertisement_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class AdvertisementDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 广告 ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 广告名称
|
||||
*/
|
||||
private String adName;
|
||||
/**
|
||||
* 软件id,不同软件的标识(用于分辩不同系统中的产品)---目前就只有一个产品
|
||||
*/
|
||||
private String softwareId;
|
||||
/**
|
||||
* 广告位置
|
||||
*/
|
||||
private String adPosition;
|
||||
/**
|
||||
* 图片路径
|
||||
*/
|
||||
private String adImagePath;
|
||||
|
||||
/**
|
||||
* 投放开始时间
|
||||
*/
|
||||
private LocalDateTime startTime;
|
||||
|
||||
/**
|
||||
* 投放结束时间
|
||||
*/
|
||||
private LocalDateTime endTime;
|
||||
/**
|
||||
* 跳转路径
|
||||
*/
|
||||
private String adRedirectUrl;
|
||||
/**
|
||||
* 广告顺序
|
||||
*/
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 广告状态 0全部 1未发布 2已发布 3已结束
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
|
||||
private Boolean deleted;
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package com.cf.imes.module.system.dal.dataobject.advertisement;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.cf.imes.framework.mybatis.core.dataobject.BaseDO;
|
||||
import lombok.*;
|
||||
|
||||
/**
|
||||
* 广告状态修改任务
|
||||
*
|
||||
*/
|
||||
@TableName("system_advertisement_task")
|
||||
@KeySequence("system_advertisement_task_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class AdvertisementTaskDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 广告id
|
||||
*/
|
||||
private Long advertisementId;
|
||||
|
||||
/**
|
||||
* 消息id
|
||||
*/
|
||||
private String messageId;
|
||||
|
||||
/**
|
||||
* 广告状态,AdvertisementStatusEnum
|
||||
*/
|
||||
private Integer advertisementStatus;
|
||||
|
||||
/**
|
||||
* 消费状态 MessageStatusEnum
|
||||
*/
|
||||
private Integer messageStatus;
|
||||
|
||||
private Boolean deleted;
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package com.cf.imes.module.system.dal.dataobject.products;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.cf.imes.framework.mybatis.core.dataobject.BaseDO;
|
||||
import lombok.*;
|
||||
|
||||
|
||||
/**
|
||||
* 产品表 products DO
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@TableName("products")
|
||||
@KeySequence("products_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ProductsDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 产品 ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 产品名称
|
||||
*/
|
||||
private String productName;
|
||||
/**
|
||||
* 产品状态
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 软件id,不同软件的标识(用于分辩不同系统中的产品)---目前就只有一个产品
|
||||
*/
|
||||
private Integer softwareId;
|
||||
|
||||
private Boolean deleted;
|
||||
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
package com.cf.imes.module.system.dal.dataobject.products;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.cf.imes.framework.mybatis.core.dataobject.BaseDO;
|
||||
import lombok.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 产品明细表 product_details DO
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@TableName("products_detail")
|
||||
@KeySequence("products_detail_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ProductsDetailDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 产品明细 ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 产品id
|
||||
*/
|
||||
private Long productId;
|
||||
|
||||
/**
|
||||
* 产品明细购买方式 0时长 1产量
|
||||
*/
|
||||
private Integer purchaseType;
|
||||
|
||||
/**
|
||||
* 正常时间,不加赠送时间
|
||||
*/
|
||||
private String duration;
|
||||
|
||||
/**
|
||||
* 正常产量,不加赠送产量
|
||||
*/
|
||||
@TableField("`output`")
|
||||
private BigDecimal output;
|
||||
|
||||
/**
|
||||
* 赠送时间
|
||||
*/
|
||||
private String giftDuration;
|
||||
|
||||
/**
|
||||
* 赠送产量
|
||||
*/
|
||||
private BigDecimal giftOutput;
|
||||
|
||||
/**
|
||||
* 产品原价
|
||||
*/
|
||||
private BigDecimal originalPrice;
|
||||
|
||||
/**
|
||||
* 折扣
|
||||
*/
|
||||
private BigDecimal discount;
|
||||
|
||||
/**
|
||||
* 产品现价
|
||||
*/
|
||||
private BigDecimal currentPrice;
|
||||
|
||||
/**
|
||||
* 是否特惠: 0否1是
|
||||
*/
|
||||
private Boolean isDiscounted;
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
package com.cf.imes.module.system.dal.dataobject.recharge;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.cf.imes.framework.mybatis.core.dataobject.BaseDO;
|
||||
import lombok.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 赠送金规则表 gift_money_details DO
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@TableName("gift_money_details")
|
||||
@KeySequence("gift_money_details_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class GiftMoneyDetailsDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 产品 ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 活动名称
|
||||
*/
|
||||
private String activityName;
|
||||
/**
|
||||
* 赠送类型 0满X送X; 1每满X送X
|
||||
*/
|
||||
private Integer purchaseType;
|
||||
/**
|
||||
* 充值类型 0微信、支付宝 1微信 2支付宝
|
||||
*/
|
||||
private Integer rechargeType;
|
||||
/**
|
||||
* 充值金额
|
||||
*/
|
||||
private BigDecimal rechargeAmount;
|
||||
/**
|
||||
* 赠送金额
|
||||
*/
|
||||
private BigDecimal giftAmount;
|
||||
/**
|
||||
* 活动开始时间
|
||||
*/
|
||||
private LocalDateTime startTime;
|
||||
/**
|
||||
* 活动结束时间
|
||||
*/
|
||||
private LocalDateTime endTime;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
private Boolean deleted;
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
package com.cf.imes.module.system.dal.mysql.advertisement;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.cf.imes.module.system.controller.admin.advertisement.vo.AdvertisementPageReqVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.advertisement.AdvertisementDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 广告信息表 Mapper
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@Mapper
|
||||
public interface AdvertisementMapper extends BaseMapperX<AdvertisementDO> {
|
||||
|
||||
default PageResult<AdvertisementDO> selectPage(AdvertisementPageReqVO reqVO, boolean deleted) {
|
||||
|
||||
LambdaQueryWrapperX<AdvertisementDO> queryWrapper = new LambdaQueryWrapperX<AdvertisementDO>()
|
||||
.likeIfPresent(AdvertisementDO::getAdName, reqVO.getAdName())
|
||||
.likeIfPresent(AdvertisementDO::getAdPosition, reqVO.getAdPosition())
|
||||
.eqIfPresent(AdvertisementDO::getStatus, reqVO.getStatus())
|
||||
.eqIfPresent(AdvertisementDO::getDeleted, deleted);
|
||||
|
||||
if (reqVO.getOrder() == null) {
|
||||
queryWrapper.orderByDesc(AdvertisementDO::getSort);
|
||||
}else {
|
||||
if (reqVO.getOrder().equals("ascend")) {
|
||||
switch (reqVO.getField()) {
|
||||
case "id" -> queryWrapper.orderByAsc(AdvertisementDO::getId);
|
||||
case "adName" -> queryWrapper.orderByAsc(AdvertisementDO::getAdName);
|
||||
case "updater" -> queryWrapper.orderByAsc(AdvertisementDO::getUpdater);
|
||||
case "updateTime" -> queryWrapper.orderByAsc(AdvertisementDO::getUpdateTime);
|
||||
default -> {
|
||||
// default不排序
|
||||
}
|
||||
}
|
||||
}else if (reqVO.getOrder().equals("descend")) {
|
||||
switch (reqVO.getField()) {
|
||||
case "id" -> queryWrapper.orderByDesc(AdvertisementDO::getId);
|
||||
case "adName" -> queryWrapper.orderByDesc(AdvertisementDO::getAdName);
|
||||
case "updater" -> queryWrapper.orderByDesc(AdvertisementDO::getUpdater);
|
||||
case "updateTime" -> queryWrapper.orderByDesc(AdvertisementDO::getUpdateTime);
|
||||
default -> {
|
||||
// default不排序
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return selectPage(reqVO, queryWrapper);
|
||||
|
||||
}
|
||||
|
||||
default int updateAdStatus(Long id, Integer newStatus) {
|
||||
return update(new LambdaUpdateWrapper<AdvertisementDO>()
|
||||
.set(AdvertisementDO::getStatus, newStatus)
|
||||
.eq(AdvertisementDO::getId, id)
|
||||
.eq(AdvertisementDO::getDeleted, false));
|
||||
}
|
||||
|
||||
default List<AdvertisementDO> selectList(LocalDateTime now, Integer status) {
|
||||
return selectList(new LambdaQueryWrapperX<AdvertisementDO>()
|
||||
.le(AdvertisementDO::getStartTime, now)
|
||||
.eq(AdvertisementDO::getStatus, status));
|
||||
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package com.cf.imes.module.system.dal.mysql.advertisement;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.cf.imes.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import com.cf.imes.module.system.dal.dataobject.advertisement.AdvertisementTaskDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 广告消费信息表 Mapper
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@Mapper
|
||||
public interface AdvertisementTaskMapper extends BaseMapperX<AdvertisementTaskDO> {
|
||||
|
||||
default int updateToDeletedById(Long adId, Boolean deleted, Integer messageStatus) {
|
||||
return update(new LambdaUpdateWrapper<AdvertisementTaskDO>()
|
||||
.set(AdvertisementTaskDO::getDeleted, deleted)
|
||||
.set(AdvertisementTaskDO::getMessageStatus, messageStatus)
|
||||
.eq(AdvertisementTaskDO::getAdvertisementId, adId));
|
||||
}
|
||||
|
||||
default List<String> selectIdByAdvertisementId(Long adId) {
|
||||
return selectList(new LambdaUpdateWrapper<AdvertisementTaskDO>()
|
||||
.eq(AdvertisementTaskDO::getAdvertisementId, adId))
|
||||
.stream()
|
||||
.map(AdvertisementTaskDO::getMessageId)
|
||||
.toList();
|
||||
}
|
||||
|
||||
default AdvertisementTaskDO selectByMessageId(String messageId) {
|
||||
return selectOne(new LambdaUpdateWrapper<AdvertisementTaskDO>()
|
||||
.eq(AdvertisementTaskDO::getMessageId, messageId)
|
||||
.eq(AdvertisementTaskDO::getDeleted, Boolean.FALSE));
|
||||
}
|
||||
|
||||
default int updateMessageStateByMessageId(String messageId, Boolean deleted, Integer messageStatus) {
|
||||
return update(new LambdaUpdateWrapper<AdvertisementTaskDO>()
|
||||
.set(AdvertisementTaskDO::getMessageStatus, messageStatus)
|
||||
.eq(AdvertisementTaskDO::getMessageId, messageId)
|
||||
.eq(AdvertisementTaskDO::getDeleted, deleted));
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package com.cf.imes.module.system.dal.mysql.products;
|
||||
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.cf.imes.module.system.controller.admin.products.vo.productDetails.ProductDetailsPageReqVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.products.ProductsDetailDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 产品明细表 product_details Mapper
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@Mapper
|
||||
public interface ProductsDetailMapper extends BaseMapperX<ProductsDetailDO> {
|
||||
|
||||
default PageResult<ProductsDetailDO> selectPage(ProductDetailsPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<ProductsDetailDO>()
|
||||
.eqIfPresent(ProductsDetailDO::getPurchaseType, reqVO.getPurchaseType())
|
||||
.eqIfPresent(ProductsDetailDO::getProductId, reqVO.getProductId())
|
||||
.eqIfPresent(ProductsDetailDO::getDuration, reqVO.getDuration())
|
||||
.eqIfPresent(ProductsDetailDO::getGiftDuration, reqVO.getGiftDuration())
|
||||
.eqIfPresent(ProductsDetailDO::getOutput, reqVO.getOutput())
|
||||
.eqIfPresent(ProductsDetailDO::getGiftOutput, reqVO.getGiftOutput())
|
||||
.eqIfPresent(ProductsDetailDO::getOriginalPrice, reqVO.getOriginalPrice())
|
||||
.eqIfPresent(ProductsDetailDO::getDiscount, reqVO.getDiscount())
|
||||
.eqIfPresent(ProductsDetailDO::getCurrentPrice, reqVO.getCurrentPrice())
|
||||
.eqIfPresent(ProductsDetailDO::getIsDiscounted, reqVO.getIsDiscounted())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// 时长查重,添加productId为查询条件
|
||||
default int selectCountByDuration(String duration, Long productId, Boolean flag) {
|
||||
LambdaQueryWrapperX<ProductsDetailDO> queryWrapper = new LambdaQueryWrapperX<>();
|
||||
queryWrapper.eq(ProductsDetailDO::getDuration, duration)
|
||||
.eq(ProductsDetailDO::getDeleted, false);
|
||||
if (flag) { // flag为true时,查询条件中添加productId
|
||||
queryWrapper.eq(ProductsDetailDO::getProductId, productId);
|
||||
}
|
||||
return Math.toIntExact(selectCount(queryWrapper));
|
||||
}
|
||||
|
||||
// 产量查重
|
||||
default int selectCountByOutput(BigDecimal output, Long productId, Boolean flag) {
|
||||
LambdaQueryWrapperX<ProductsDetailDO> queryWrapper = new LambdaQueryWrapperX<>();
|
||||
queryWrapper.eq(ProductsDetailDO::getDuration, output)
|
||||
.eq(ProductsDetailDO::getDeleted, false);
|
||||
if (flag) { // flag为true时,查询条件中添加productId
|
||||
queryWrapper.eq(ProductsDetailDO::getProductId, productId);
|
||||
}
|
||||
return Math.toIntExact(selectCount(queryWrapper));
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.cf.imes.module.system.dal.mysql.products;
|
||||
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.cf.imes.module.system.controller.admin.products.vo.product.ProductPageReqVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.products.ProductsDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 产品表 product Mapper
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@Mapper
|
||||
public interface ProductsMapper extends BaseMapperX<ProductsDO> {
|
||||
|
||||
default PageResult<ProductsDO> selectPage(ProductPageReqVO reqVO, boolean deleted) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<ProductsDO>()
|
||||
.eqIfPresent(ProductsDO::getId, reqVO.getId())
|
||||
.likeIfPresent(ProductsDO::getProductName, reqVO.getProductName())
|
||||
.eqIfPresent(ProductsDO::getStatus, reqVO.getStatus())
|
||||
.eq(ProductsDO::getDeleted, deleted));
|
||||
}
|
||||
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
package com.cf.imes.module.system.dal.mysql.recharge;
|
||||
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.cf.imes.module.system.controller.admin.recharge.vo.RechargePageReqVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.recharge.GiftMoneyDetailsDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 赠送金活动详情表 gift_money_details Mapper
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@Mapper
|
||||
public interface GiftMoneyDetailsMapper extends BaseMapperX<GiftMoneyDetailsDO> {
|
||||
default PageResult<GiftMoneyDetailsDO> selectPage(RechargePageReqVO reqVO) {
|
||||
LambdaQueryWrapperX<GiftMoneyDetailsDO> queryWrapper = new LambdaQueryWrapperX<GiftMoneyDetailsDO>()
|
||||
.likeIfPresent(GiftMoneyDetailsDO::getActivityName, reqVO.getActivityName())
|
||||
.eqIfPresent(GiftMoneyDetailsDO::getPurchaseType, reqVO.getPurchaseType())
|
||||
.eqIfPresent(GiftMoneyDetailsDO::getRechargeType, reqVO.getRechargeType())
|
||||
.eqIfPresent(GiftMoneyDetailsDO::getGiftAmount, reqVO.getGiftAmount())
|
||||
.eqIfPresent(GiftMoneyDetailsDO::getRechargeAmount, reqVO.getRechargeAmount())
|
||||
.betweenIfPresent(GiftMoneyDetailsDO::getStartTime, reqVO.getStartTime())
|
||||
.betweenIfPresent(GiftMoneyDetailsDO::getEndTime, reqVO.getEndTime());
|
||||
|
||||
if (reqVO.getOrder() == null) {
|
||||
queryWrapper.orderByDesc(GiftMoneyDetailsDO::getId);
|
||||
}else {
|
||||
if (reqVO.getOrder().equals("ascend")) {
|
||||
switch (reqVO.getField()) {
|
||||
case "id" -> queryWrapper.orderByAsc(GiftMoneyDetailsDO::getId);
|
||||
case "rechargeAmount" -> queryWrapper.orderByAsc(GiftMoneyDetailsDO::getRechargeAmount);
|
||||
case "giftAmount" -> queryWrapper.orderByAsc(GiftMoneyDetailsDO::getGiftAmount);
|
||||
case "startTime" -> queryWrapper.orderByAsc(GiftMoneyDetailsDO::getStartTime);
|
||||
case "endTime" -> queryWrapper.orderByAsc(GiftMoneyDetailsDO::getEndTime);
|
||||
case "updateTime" -> queryWrapper.orderByAsc(GiftMoneyDetailsDO::getUpdateTime);
|
||||
default -> {
|
||||
// default不排序
|
||||
}
|
||||
}
|
||||
}else if (reqVO.getOrder().equals("descend")) {
|
||||
switch (reqVO.getField()) {
|
||||
case "id" -> queryWrapper.orderByDesc(GiftMoneyDetailsDO::getId);
|
||||
case "rechargeAmount" -> queryWrapper.orderByDesc(GiftMoneyDetailsDO::getRechargeAmount);
|
||||
case "giftAmount" -> queryWrapper.orderByDesc(GiftMoneyDetailsDO::getGiftAmount);
|
||||
case "startTime" -> queryWrapper.orderByDesc(GiftMoneyDetailsDO::getStartTime);
|
||||
case "endTime" -> queryWrapper.orderByDesc(GiftMoneyDetailsDO::getEndTime);
|
||||
case "updateTime" -> queryWrapper.orderByDesc(GiftMoneyDetailsDO::getUpdateTime);
|
||||
default -> {
|
||||
// default不排序
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return selectPage(reqVO, queryWrapper);
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
package com.cf.imes.module.system.mq.consumer.advertisement;
|
||||
|
||||
import com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants;
|
||||
import com.cf.imes.module.system.dal.dataobject.advertisement.AdvertisementDO;
|
||||
import com.cf.imes.module.system.dal.dataobject.advertisement.AdvertisementTaskDO;
|
||||
import com.cf.imes.module.system.dal.mysql.advertisement.AdvertisementMapper;
|
||||
import com.cf.imes.module.system.dal.mysql.advertisement.AdvertisementTaskMapper;
|
||||
import com.cf.imes.module.system.enums.advertisement.AdvertisementStatusEnum;
|
||||
import com.cf.imes.module.system.enums.advertisement.MessageStatusEnum;
|
||||
import com.cf.imes.module.system.mq.message.advertisement.AdvertisementSendMessage;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
/**
|
||||
* 针对 {@link AdvertisementSendMessage} 的消费者
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AdvertisementSendConsumer {
|
||||
|
||||
@Resource
|
||||
private AdvertisementMapper advertisementMapper;
|
||||
|
||||
@Resource
|
||||
private AdvertisementTaskMapper advertisementTaskMapper;
|
||||
|
||||
@RabbitListener(queues = RabbitMqConstants.SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_QUEUE)
|
||||
public void onMessage(AdvertisementSendMessage message){
|
||||
// 1. 获取广告数据
|
||||
AdvertisementDO ad = advertisementMapper.selectById(message.getAdId());
|
||||
if (ad == null || ad.getDeleted())
|
||||
return;
|
||||
|
||||
// 2. 检查消息有效性
|
||||
AdvertisementTaskDO messageRecord = advertisementTaskMapper.selectByMessageId(message.getMessageId());
|
||||
if (messageRecord == null ||
|
||||
Objects.equals(messageRecord.getMessageStatus(), MessageStatusEnum.CANCELLED.getStatus())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. 处理状态变更
|
||||
if (AdvertisementStatusEnum.PUBLISHED.getName().equals(message.getAction())) { // 待发布
|
||||
if (ad.getStatus() == AdvertisementStatusEnum.UNPUBLISHED.getStatus() &&
|
||||
LocalDateTime.now().isAfter(ad.getStartTime())) {
|
||||
updateAdStatus(ad, messageRecord.getAdvertisementStatus());
|
||||
}
|
||||
} else if (AdvertisementStatusEnum.ENDED.getName().equals(message.getAction())) { // 待结束
|
||||
if (ad.getStatus() == AdvertisementStatusEnum.PUBLISHED.getStatus() &&
|
||||
LocalDateTime.now().isAfter(ad.getEndTime())) {
|
||||
updateAdStatus(ad, messageRecord.getAdvertisementStatus());
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 标记消息为已处理
|
||||
messageRecord.setMessageStatus(MessageStatusEnum.PROCESSED.getStatus());
|
||||
advertisementTaskMapper.updateMessageStateByMessageId(message.getMessageId(),false, MessageStatusEnum.PROCESSED.getStatus());
|
||||
}
|
||||
|
||||
private void updateAdStatus(AdvertisementDO ad, Integer newStatus) {
|
||||
advertisementMapper.updateAdStatus(ad.getId(), newStatus);
|
||||
}
|
||||
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package com.cf.imes.module.system.mq.message.advertisement;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 广告状态更改消息
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class AdvertisementSendMessage {
|
||||
|
||||
/**
|
||||
* 广告id
|
||||
*/
|
||||
@NotNull(message = "广告id不能为空")
|
||||
private Long adId;
|
||||
|
||||
/**
|
||||
* 消息id
|
||||
*/
|
||||
@NotNull(message = "消息id")
|
||||
private String messageId;
|
||||
|
||||
/**
|
||||
* 消息类别
|
||||
*/
|
||||
private String action;
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
package com.cf.imes.module.system.mq.producer.advertisement;
|
||||
|
||||
import com.cf.imes.module.system.mq.message.advertisement.AdvertisementSendMessage;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants.SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_EXCHANGE;
|
||||
import static com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants.SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_ROUTING_KEY;
|
||||
|
||||
/**
|
||||
* Advertisement 广告相关消息的 Producer
|
||||
*
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class AdvertisementProducer {
|
||||
|
||||
@Resource
|
||||
private RabbitTemplate rabbitTemplate;
|
||||
|
||||
|
||||
/**
|
||||
* 发送 {@link AdvertisementSendMessage} 消息
|
||||
*
|
||||
* @param adId 广告id
|
||||
* @param action 类型
|
||||
* @param triggerTime 到期时间
|
||||
*/
|
||||
|
||||
public String sendAdvertisementSendMessage(Long adId, String action, LocalDateTime triggerTime) {
|
||||
|
||||
String messageId = UUID.randomUUID().toString();
|
||||
|
||||
|
||||
long delay = Duration.between(LocalDateTime.now(), triggerTime).toMillis();
|
||||
|
||||
if (delay > 0) {
|
||||
RequestContextHolder.setRequestAttributes(RequestContextHolder.getRequestAttributes(), true);
|
||||
AdvertisementSendMessage message = new AdvertisementSendMessage(adId, messageId, action);
|
||||
|
||||
if (TransactionSynchronizationManager.isActualTransactionActive()) {
|
||||
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
||||
@Override
|
||||
public void afterCommit() {
|
||||
// 数据库操作全部完成发送消息
|
||||
rabbitTemplate.convertAndSend(
|
||||
SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_EXCHANGE,
|
||||
SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_ROUTING_KEY,
|
||||
message,
|
||||
correlationData -> {
|
||||
correlationData.getMessageProperties().setMessageId(messageId);
|
||||
correlationData.getMessageProperties().setDelay(Long.valueOf(delay).intValue());
|
||||
return correlationData;
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 数据库操作全部完成发送消息
|
||||
rabbitTemplate.convertAndSend(
|
||||
SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_EXCHANGE,
|
||||
SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_ROUTING_KEY,
|
||||
message,
|
||||
correlationData -> {
|
||||
correlationData.getMessageProperties().setMessageId(messageId);
|
||||
correlationData.getMessageProperties().setDelay(Long.valueOf(delay).intValue());
|
||||
return correlationData;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return messageId;
|
||||
}
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
package com.cf.imes.module.system.service.advertisement;
|
||||
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.cf.imes.module.system.dal.dataobject.advertisement.AdvertisementDO;
|
||||
import com.cf.imes.module.system.dal.dataobject.advertisement.AdvertisementTaskDO;
|
||||
import com.cf.imes.module.system.dal.mysql.advertisement.AdvertisementMapper;
|
||||
import com.cf.imes.module.system.dal.mysql.advertisement.AdvertisementTaskMapper;
|
||||
import com.cf.imes.module.system.enums.advertisement.AdvertisementStatusEnum;
|
||||
import com.cf.imes.module.system.enums.advertisement.MessageStatusEnum;
|
||||
import com.cf.imes.module.system.mq.message.advertisement.AdvertisementSendMessage;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants.SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_EXCHANGE;
|
||||
import static com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants.SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_ROUTING_KEY;
|
||||
|
||||
/**
|
||||
* 广告状态修改 Service 实现类
|
||||
*
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class AdvertisementCompensateTask {
|
||||
|
||||
@Resource
|
||||
private AdvertisementMapper advertisementMapper;
|
||||
|
||||
@Resource
|
||||
private AdvertisementTaskMapper advertisementTaskMapper;
|
||||
|
||||
@Resource
|
||||
private RabbitTemplate rabbitTemplate;
|
||||
|
||||
|
||||
//=== 补偿任务 ===//
|
||||
// @Scheduled(cron = "0 0/30 * * * ?")
|
||||
public void checkAdStatusConsistency() {
|
||||
// 1. 检查应发布但未发布的广告
|
||||
List<AdvertisementDO> unpublishedAds = advertisementMapper.selectList(LocalDateTime.now(), AdvertisementStatusEnum.UNPUBLISHED.getStatus());
|
||||
unpublishedAds.forEach(ad -> {
|
||||
updateAdStatus(ad, AdvertisementStatusEnum.PUBLISHED.getStatus());
|
||||
rescheduleExpireMessage(ad);
|
||||
});
|
||||
|
||||
// 2. 检查应结束但未结束的广告
|
||||
List<AdvertisementDO> publishedAds = advertisementMapper.selectList(
|
||||
new QueryWrapper<AdvertisementDO>()
|
||||
.le("end_time", LocalDateTime.now())
|
||||
.eq("status", AdvertisementStatusEnum.PUBLISHED.getStatus())
|
||||
);
|
||||
publishedAds.forEach(ad -> updateAdStatus(ad, AdvertisementStatusEnum.ENDED.getStatus()));
|
||||
}
|
||||
|
||||
private void rescheduleExpireMessage(AdvertisementDO ad) {
|
||||
if (ad.getEndTime().isAfter(LocalDateTime.now())) {
|
||||
String newMsgId = sendSingleMessage(ad.getId(), "expire", ad.getEndTime());
|
||||
trackMessage(ad.getId(), newMsgId, AdvertisementStatusEnum.PUBLISHED.getStatus(), MessageStatusEnum.CANCELLED.getStatus());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAdStatus(AdvertisementDO ad, Integer newStatus) {
|
||||
advertisementMapper.updateAdStatus(ad.getId(), newStatus);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送单个延迟消息
|
||||
*/
|
||||
private String sendSingleMessage(Long adId, String action, LocalDateTime triggerTime) {
|
||||
String messageId = UUID.randomUUID().toString();
|
||||
long delay = Duration.between(LocalDateTime.now(), triggerTime).toMillis();
|
||||
|
||||
|
||||
if (delay > 0) {
|
||||
RequestContextHolder.setRequestAttributes(RequestContextHolder.getRequestAttributes(), true);
|
||||
|
||||
rabbitTemplate.convertAndSend(
|
||||
SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_EXCHANGE,
|
||||
SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_ROUTING_KEY,
|
||||
new AdvertisementSendMessage(adId, messageId, action),
|
||||
correlationData -> {
|
||||
correlationData.getMessageProperties().setMessageId(messageId);
|
||||
correlationData.getMessageProperties().setDelay(Long.valueOf(delay).intValue());
|
||||
return correlationData;
|
||||
}
|
||||
);
|
||||
}
|
||||
return messageId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录消息追踪
|
||||
*/
|
||||
private void trackMessage(Long adId, String messageId, Integer advertisementStatus, Integer messageStatus) {
|
||||
if (StringUtils.isNotBlank(messageId)) {
|
||||
advertisementTaskMapper.insert(new AdvertisementTaskDO()
|
||||
.setAdvertisementId(adId)
|
||||
.setMessageId(messageId)
|
||||
.setMessageStatus(messageStatus)
|
||||
.setAdvertisementStatus(advertisementStatus)
|
||||
);
|
||||
log.info("[trackMessage][adId({}) messageId({}) 记录消息追踪成功]", adId, messageId);
|
||||
}
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package com.cf.imes.module.system.service.advertisement;
|
||||
|
||||
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.module.system.controller.admin.advertisement.vo.AdvertisementPageReqVO;
|
||||
import com.cf.imes.module.system.controller.admin.advertisement.vo.AdvertisementSaveReqVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.advertisement.AdvertisementDO;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
public interface AdvertisementService {
|
||||
|
||||
/**
|
||||
* 创建广告
|
||||
*
|
||||
* @param createReqVO 产品名称
|
||||
* @return 编号
|
||||
*/
|
||||
Long create(@Valid AdvertisementSaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新广告
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void update(@Valid AdvertisementDO updateReqVO, Integer index);
|
||||
|
||||
/**
|
||||
* 更新广告状态
|
||||
*
|
||||
* @param id 更新信息
|
||||
*/
|
||||
void update(Long id, Integer status);
|
||||
|
||||
/**
|
||||
* 删除广告
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void delete(Long id);
|
||||
|
||||
/**
|
||||
* 获得广告
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
AdvertisementDO get(Long id);
|
||||
|
||||
/**
|
||||
* 获得广告 分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
*/
|
||||
PageResult<AdvertisementDO> getPage(AdvertisementPageReqVO pageReqVO);
|
||||
|
||||
}
|
||||
+251
@@ -0,0 +1,251 @@
|
||||
package com.cf.imes.module.system.service.advertisement;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.common.util.object.BeanUtils;
|
||||
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.cf.imes.framework.mybatis.core.query.LambdaUpdateWrapperX;
|
||||
import com.cf.imes.module.system.controller.admin.advertisement.vo.AdvertisementPageReqVO;
|
||||
import com.cf.imes.module.system.controller.admin.advertisement.vo.AdvertisementSaveReqVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.advertisement.AdvertisementDO;
|
||||
import com.cf.imes.module.system.dal.dataobject.advertisement.AdvertisementTaskDO;
|
||||
import com.cf.imes.module.system.dal.mysql.advertisement.AdvertisementMapper;
|
||||
import com.cf.imes.module.system.dal.mysql.advertisement.AdvertisementTaskMapper;
|
||||
import com.cf.imes.module.system.enums.advertisement.AdvertisementStatusEnum;
|
||||
import com.cf.imes.module.system.enums.advertisement.MessageStatusEnum;
|
||||
import com.cf.imes.module.system.mq.producer.advertisement.AdvertisementProducer;
|
||||
import com.cf.imes.module.system.service.dict.DictDataService;
|
||||
import com.cf.imes.module.system.util.SnowflakeIdWorker3rd;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static com.cf.imes.module.system.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* 广告表 advertisement Service 实现类
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class AdvertisementServiceImpl implements AdvertisementService{
|
||||
|
||||
private static final String ADVERTISEMENT_POSITION = "advertisement_position";
|
||||
|
||||
private static final String EMPTY_STRING = new String();
|
||||
|
||||
@Value("${chenfeng.info.name}")
|
||||
private String SOFT_WARE_ID; // 获取软件标识-可修改
|
||||
|
||||
@Resource
|
||||
private DictDataService dictDataService;
|
||||
|
||||
@Resource
|
||||
private AdvertisementMapper advertisementMapper;
|
||||
|
||||
@Resource
|
||||
private AdvertisementTaskMapper advertisementTaskMapper;
|
||||
|
||||
@Resource
|
||||
private SnowflakeIdWorker3rd idWorker;
|
||||
|
||||
@Resource
|
||||
private AdvertisementProducer advertisementProducer;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long create(AdvertisementSaveReqVO createReqVO) {
|
||||
// 遍历adPosition验证广告位置是否存在
|
||||
for (Integer adPosition : createReqVO.getAdPosition()) {
|
||||
if (dictDataService.getDictData(ADVERTISEMENT_POSITION, adPosition.toString()) == null) {
|
||||
throw exception(ADVERTISEMENT_POSITION_NO_EXIST);
|
||||
}
|
||||
}
|
||||
// 插入广告
|
||||
Long id = idWorker.nextId();
|
||||
createReqVO.setId(id);
|
||||
AdvertisementDO advertisementDO = BeanUtils.toBean(createReqVO, AdvertisementDO.class)
|
||||
.setAdPosition(Arrays.toString(createReqVO.getAdPosition()))
|
||||
// .setStartTime(createReqVO.getStartTime().toLocalDate().atStartOfDay()) // 开始结束时间设置为每天00:00:00
|
||||
// .setEndTime(createReqVO.getEndTime().toLocalDate().atStartOfDay())
|
||||
.setStatus(validateAdvertisementStatus(createReqVO.getStartTime(), createReqVO.getEndTime()))
|
||||
.setSoftwareId(SOFT_WARE_ID);
|
||||
advertisementMapper.insert(advertisementDO);
|
||||
|
||||
// 使用子线程,添加生产者队列,待到达发布时间进行广告状态修改为已发布
|
||||
sendDelayMessages(advertisementDO);
|
||||
return advertisementDO.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送初始延迟消息
|
||||
*
|
||||
* 根据状态发送延迟信息
|
||||
*/
|
||||
private void sendDelayMessages(AdvertisementDO ad) {
|
||||
|
||||
// 删除可能存在的旧消息
|
||||
cancelExistingMessages(ad.getId());
|
||||
|
||||
// 发送发布消息
|
||||
if (ad.getStartTime().isAfter(LocalDateTime.now())) {
|
||||
String publishMsgId = advertisementProducer.sendAdvertisementSendMessage(ad.getId(), AdvertisementStatusEnum.PUBLISHED.getName(), ad.getStartTime()); // 发布
|
||||
trackMessage(ad.getId(), publishMsgId, AdvertisementStatusEnum.PUBLISHED.getStatus(), MessageStatusEnum.PENDING.getStatus());
|
||||
}
|
||||
|
||||
// 发送结束消息
|
||||
if (ad.getEndTime().isAfter(LocalDateTime.now())) {
|
||||
String expireMsgId = advertisementProducer.sendAdvertisementSendMessage(ad.getId(), AdvertisementStatusEnum.ENDED.getName(), ad.getEndTime()); // 结束
|
||||
trackMessage(ad.getId(), expireMsgId, AdvertisementStatusEnum.ENDED.getStatus(), MessageStatusEnum.PENDING.getStatus());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录消息追踪
|
||||
*/
|
||||
private void trackMessage(Long adId, String messageId, Integer advertisementStatus, Integer messageStatus) {
|
||||
if (StringUtils.isNotBlank(messageId)) {
|
||||
advertisementTaskMapper.insert(new AdvertisementTaskDO()
|
||||
.setAdvertisementId(adId)
|
||||
.setMessageId(messageId)
|
||||
.setMessageStatus(messageStatus)
|
||||
.setAdvertisementStatus(advertisementStatus)
|
||||
);
|
||||
log.info("[trackMessage][adId({}) messageId({}) 记录消息追踪成功]", adId, messageId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消关联的消息
|
||||
*/
|
||||
private void cancelExistingMessages(Long adId) {
|
||||
// 标记消息为已取消(实际消费时检查)
|
||||
advertisementTaskMapper.updateToDeletedById(adId,true, MessageStatusEnum.CANCELLED.getStatus());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void update(AdvertisementDO updateReqVO, Integer index) {
|
||||
// 确认广告是否存在
|
||||
validateAdvertisementExists(updateReqVO.getId(), false);
|
||||
// 更新内容
|
||||
AdvertisementDO advertisementDO = BeanUtils.toBean(updateReqVO, AdvertisementDO.class);
|
||||
// 删除现有广告的延迟队列
|
||||
if (index == 0) { // 全部更新
|
||||
advertisementDO.setAdRedirectUrl(getEmpty(advertisementDO.getAdRedirectUrl()))
|
||||
.setSort(getZeroInt(advertisementDO.getSort()))
|
||||
.setStatus(validateAdvertisementStatus(advertisementDO.getStartTime(), advertisementDO.getEndTime()));
|
||||
|
||||
} else {
|
||||
advertisementDO = getAdvertisementDO(updateReqVO.getId(), false)
|
||||
.setStartTime(updateReqVO.getStartTime())
|
||||
.setEndTime(updateReqVO.getEndTime())
|
||||
.setStatus(validateAdvertisementStatus(advertisementDO.getStartTime(), advertisementDO.getEndTime()));
|
||||
|
||||
}
|
||||
// 根据修改时间,新增广告状态修改延迟队列
|
||||
advertisementMapper.updateById(advertisementDO);
|
||||
|
||||
// 使用子线程,添加生产者队列,待到达发布时间进行广告状态修改为已发布
|
||||
sendDelayMessages(advertisementDO);
|
||||
}
|
||||
// 判断广告状态
|
||||
public int validateAdvertisementStatus(LocalDateTime startTime, LocalDateTime endTime) {
|
||||
// 当前时间
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
if (now.isBefore(startTime)) { // 未开始
|
||||
return AdvertisementStatusEnum.UNPUBLISHED.getStatus();
|
||||
} else if (now.isAfter(endTime)) { // 已结束
|
||||
return AdvertisementStatusEnum.ENDED.getStatus();
|
||||
} else { // 进行中
|
||||
return AdvertisementStatusEnum.PUBLISHED.getStatus();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* value为空返回EMPTY_STRING
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
private String getEmpty(String value) {
|
||||
return StringUtils.defaultIfEmpty(value, EMPTY_STRING);
|
||||
}
|
||||
|
||||
/**
|
||||
* value为空返回0.0
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
private int getZeroInt(Integer value) {
|
||||
return ObjectUtil.defaultIfNull(value, 0);
|
||||
}
|
||||
|
||||
private void validateAdvertisementExists(Long id, Boolean deleted) {
|
||||
AdvertisementDO advertisementDO = advertisementMapper.selectOne(new LambdaQueryWrapperX<AdvertisementDO>()
|
||||
.eq(AdvertisementDO::getId, id)
|
||||
.eq(AdvertisementDO::getDeleted, deleted));
|
||||
if (advertisementDO == null) {
|
||||
throw exception(ADVERTISEMENT_NO_EXIST);
|
||||
}
|
||||
}
|
||||
|
||||
private AdvertisementDO getAdvertisementDO(Long id, Boolean deleted) {
|
||||
return advertisementMapper.selectOne(new LambdaQueryWrapperX<AdvertisementDO>()
|
||||
.eq(AdvertisementDO::getId, id)
|
||||
.eq(AdvertisementDO::getDeleted, deleted));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Long id, Integer status) { // 发布,结束
|
||||
if (status.equals(AdvertisementStatusEnum.PUBLISHED.getStatus())) { // 立即发布
|
||||
if (LocalDateTime.now().isAfter(getAdvertisementDO(id, false).getStartTime())) {
|
||||
throw exception(ADVERTISEMENT_STATUS_ERROR);
|
||||
}
|
||||
if (LocalDateTime.now().isAfter(getAdvertisementDO(id, false).getEndTime())) {
|
||||
throw exception(ADVERTISEMENT_STATUS_ERROR2);
|
||||
}
|
||||
|
||||
} else if (status.equals(AdvertisementStatusEnum.ENDED.getStatus())) { // 结束发布
|
||||
if (LocalDateTime.now().isBefore(getAdvertisementDO(id, false).getStartTime())) {
|
||||
throw exception(ADVERTISEMENT_END_ERROR);
|
||||
}
|
||||
if (LocalDateTime.now().isAfter(getAdvertisementDO(id, false).getEndTime())) {
|
||||
throw exception(ADVERTISEMENT_END_ERROR2);
|
||||
}
|
||||
}
|
||||
advertisementMapper.update(new AdvertisementDO().setStatus(status),
|
||||
new LambdaUpdateWrapperX<AdvertisementDO>()
|
||||
.eq(AdvertisementDO::getId, id)
|
||||
.eq(AdvertisementDO::getDeleted, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Long id) {
|
||||
// 确认广告是否存在
|
||||
validateAdvertisementExists(id, false);
|
||||
advertisementMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdvertisementDO get(Long id) {
|
||||
validateAdvertisementExists(id, false);
|
||||
return getAdvertisementDO(id, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<AdvertisementDO> getPage(AdvertisementPageReqVO pageReqVO) {
|
||||
return advertisementMapper.selectPage(pageReqVO, false);
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
package com.cf.imes.module.system.service.products;
|
||||
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.module.system.controller.admin.products.vo.productDetails.ProductDetailsPageReqVO;
|
||||
import com.cf.imes.module.system.controller.admin.products.vo.productDetails.ProductDetailsSaveReqVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.products.ProductsDetailDO;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 产品明细表 product_details Service 接口
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
public interface ProductsDetailService {
|
||||
|
||||
/**
|
||||
* 创建产品明细(定价规则)
|
||||
*
|
||||
* @param createReqVO 产品明细内容
|
||||
* @return 编号
|
||||
*/
|
||||
Long create(@Valid ProductDetailsSaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新产品
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void update(@Valid ProductDetailsSaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除产品
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void delete(Long id);
|
||||
|
||||
/**
|
||||
* 获得产品
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
List<ProductsDetailDO> get(Long id);
|
||||
|
||||
/**
|
||||
* 获得产品 分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
*/
|
||||
PageResult<ProductsDetailDO> getPage(ProductDetailsPageReqVO pageReqVO);
|
||||
|
||||
}
|
||||
+253
@@ -0,0 +1,253 @@
|
||||
package com.cf.imes.module.system.service.products;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.common.util.object.BeanUtils;
|
||||
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.cf.imes.module.system.controller.admin.products.vo.productDetails.ProductDetailsPageReqVO;
|
||||
import com.cf.imes.module.system.controller.admin.products.vo.productDetails.ProductDetailsSaveReqVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.products.ProductsDO;
|
||||
import com.cf.imes.module.system.dal.dataobject.products.ProductsDetailDO;
|
||||
import com.cf.imes.module.system.dal.mysql.products.ProductsDetailMapper;
|
||||
import com.cf.imes.module.system.dal.mysql.products.ProductsMapper;
|
||||
import com.cf.imes.module.system.enums.products.DurationUnitEnum;
|
||||
import com.cf.imes.module.system.enums.products.ProductsPurchaseTypeEnum;
|
||||
import com.cf.imes.module.system.util.SnowflakeIdWorker3rd;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static com.cf.imes.module.system.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* 产品明细 productsDetails Service 实现类
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class ProductsDetailServiceImpl implements ProductsDetailService {
|
||||
|
||||
@Resource
|
||||
private ProductsDetailMapper productDetailsMapper;
|
||||
|
||||
@Resource
|
||||
private ProductsMapper productsMapper;
|
||||
|
||||
@Resource
|
||||
private SnowflakeIdWorker3rd idWorker;
|
||||
|
||||
private static final String EMPTY_STRING = new String();
|
||||
private static final String DURATION_NUM = "\\d+";
|
||||
private static final String DURATION_UNIT = "[a-zA-Z]+";
|
||||
|
||||
@Override
|
||||
public Long create(ProductDetailsSaveReqVO createReqVO) {
|
||||
// 校验是否有这个产品
|
||||
validateProductExist(createReqVO.getProductId(), false);
|
||||
|
||||
if (createReqVO.getPurchaseType() == ProductsPurchaseTypeEnum.DURATION.getStatus()) {
|
||||
if (StringUtils.isBlank(createReqVO.getDuration())) {
|
||||
throw exception(PRODUCTS_DURATION_NOT_NULL);
|
||||
}
|
||||
// 校验时长
|
||||
String duration = checkDuration(createReqVO.getDuration());
|
||||
String giftDuration = null;
|
||||
if (createReqVO.getGiftDuration() != null) {
|
||||
giftDuration = checkDuration(createReqVO.getGiftDuration());
|
||||
}
|
||||
createReqVO.setDuration(duration).setGiftDuration(giftDuration);
|
||||
|
||||
// 时长/产量 去重
|
||||
checkProductDetails(createReqVO, false);
|
||||
} else if (createReqVO.getPurchaseType() == ProductsPurchaseTypeEnum.OUTPUT.getStatus()) {
|
||||
if (StringUtils.isBlank(createReqVO.getDuration())) {
|
||||
throw exception(PRODUCTS_OUTPUT_NOT_NULL);
|
||||
}
|
||||
}
|
||||
|
||||
Long id = idWorker.nextId();
|
||||
createReqVO.setId(id);
|
||||
ProductsDetailDO productDetailsDO = BeanUtils.toBean(createReqVO, ProductsDetailDO.class).setId(id);
|
||||
productDetailsMapper.insert(productDetailsDO);
|
||||
return id ;
|
||||
}
|
||||
|
||||
// 时长校验
|
||||
private String checkDuration(String duration){
|
||||
int number = extractDuration(duration);
|
||||
String unit = extractDurationUnit(duration);
|
||||
return number + "-" + unit;
|
||||
}
|
||||
|
||||
// 数字提取
|
||||
private int extractDuration(String duration) {
|
||||
Pattern pattern = Pattern.compile(DURATION_NUM);
|
||||
Matcher matcher = pattern.matcher(duration);
|
||||
|
||||
List<String> numbers = new ArrayList<>();
|
||||
while (matcher.find()) {
|
||||
numbers.add(matcher.group());
|
||||
}
|
||||
|
||||
if (numbers.size() != 1) {
|
||||
throw exception(PRODUCTS_DURATION_NUM_ERR);
|
||||
}
|
||||
|
||||
String numberStr = numbers.get(0);
|
||||
int number;
|
||||
try {
|
||||
number = Integer.parseInt(numberStr);
|
||||
} catch (NumberFormatException e) {
|
||||
throw exception(PRODUCTS_DURATION_NUM_ERR);
|
||||
}
|
||||
|
||||
// 校验数值是否为正整数(>0)
|
||||
if (number < 0) {
|
||||
throw exception(PRODUCTS_DURATION_INT_ERR);
|
||||
}
|
||||
|
||||
// 校验字符串格式(禁止前导零)
|
||||
if (numberStr.startsWith("0") && numberStr.length() > 1) {
|
||||
throw exception(PRODUCTS_DURATION_NUM_ERR);
|
||||
}
|
||||
|
||||
return number;
|
||||
}
|
||||
|
||||
// 时长单位提取
|
||||
private String extractDurationUnit(String duration){
|
||||
Pattern pattern = Pattern.compile(DURATION_UNIT);
|
||||
Matcher matcher = pattern.matcher(duration);
|
||||
|
||||
while (matcher.find()) {
|
||||
String unit = matcher.group();
|
||||
if (DurationUnitEnum.isYear(unit)) {
|
||||
return DurationUnitEnum.YEAR.getName();
|
||||
} else if (DurationUnitEnum.isMonth(unit)) {
|
||||
return DurationUnitEnum.MONTH.getName();
|
||||
} else if (DurationUnitEnum.isDay(unit)) {
|
||||
return DurationUnitEnum.DAY.getName();
|
||||
}
|
||||
}
|
||||
throw exception(PRODUCTS_DURATION_UNIT_ERR);
|
||||
}
|
||||
// 产品存在性校验
|
||||
private void validateProductExist(Long productId, boolean deleted){
|
||||
ProductsDO productsDO = productsMapper.selectOne(new LambdaQueryWrapperX<ProductsDO>()
|
||||
.eq(ProductsDO::getId, productId)
|
||||
.eq(ProductsDO::getDeleted, deleted));
|
||||
if (productsDO == null) {
|
||||
throw exception(PRODUCTS_NO_EXIST);
|
||||
}
|
||||
}
|
||||
// 时长/产量去重
|
||||
private void checkProductDetails(ProductDetailsSaveReqVO createReqVO, Boolean flag){
|
||||
int count;
|
||||
if (createReqVO.getPurchaseType() == 0){
|
||||
//时长去重
|
||||
count = productDetailsMapper.selectCountByDuration(createReqVO.getDuration(), createReqVO.getProductId(), flag);
|
||||
if (count > 0) {
|
||||
throw exception(PRODUCTS_DETAIL_DURATION_EXIST);
|
||||
}
|
||||
}else if (createReqVO.getPurchaseType() == 1){
|
||||
//产量去重
|
||||
count = productDetailsMapper.selectCountByOutput(createReqVO.getOutput(), createReqVO.getProductId(), flag);
|
||||
if (count > 0) {
|
||||
throw exception(PRODUCTS_DETAIL_OUTPUT_EXIST);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(ProductDetailsSaveReqVO updateReqVO) {
|
||||
// 校验是否有这个产品
|
||||
validateProductExist(updateReqVO.getProductId(), false);
|
||||
|
||||
validateProductDetailsExists(updateReqVO.getId(), false);
|
||||
|
||||
if (updateReqVO.getPurchaseType() == ProductsPurchaseTypeEnum.DURATION.getStatus()) {
|
||||
if (StringUtils.isBlank(updateReqVO.getDuration())) {
|
||||
throw exception(PRODUCTS_DURATION_NOT_NULL);
|
||||
}
|
||||
// 校验时长
|
||||
String duration = checkDuration(updateReqVO.getDuration());
|
||||
String giftDuration = null;
|
||||
if (updateReqVO.getGiftDuration() != null) {
|
||||
giftDuration = checkDuration(updateReqVO.getGiftDuration());
|
||||
}
|
||||
updateReqVO.setDuration(duration).setGiftDuration(giftDuration);
|
||||
|
||||
// 时长/产量 去重
|
||||
checkProductDetails(updateReqVO, true);
|
||||
} else if (updateReqVO.getPurchaseType() == ProductsPurchaseTypeEnum.OUTPUT.getStatus()) {
|
||||
if (StringUtils.isBlank(updateReqVO.getDuration())) {
|
||||
throw exception(PRODUCTS_OUTPUT_NOT_NULL);
|
||||
}
|
||||
}
|
||||
ProductsDetailDO productDetailsDO = BeanUtils.toBean(updateReqVO, ProductsDetailDO.class)
|
||||
.setDiscount(getZeroBigDecimal(updateReqVO.getDiscount()))
|
||||
.setOriginalPrice(getZeroBigDecimal(updateReqVO.getOriginalPrice()))
|
||||
.setIsDiscounted(updateReqVO.getIsDiscounted() ? Boolean.TRUE : Boolean.FALSE);
|
||||
productDetailsMapper.updateById(productDetailsDO);
|
||||
}
|
||||
|
||||
/**
|
||||
* value为空返回EMPTY_STRING
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
private String getEmpty(String value) {
|
||||
return StringUtils.defaultIfEmpty(value, EMPTY_STRING);
|
||||
}
|
||||
|
||||
/**
|
||||
* value为空返回0.0
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
private BigDecimal getZeroBigDecimal(BigDecimal value) {
|
||||
return ObjectUtil.defaultIfNull(value, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Long id) {
|
||||
// 判单是否存在
|
||||
validateProductDetailsExists(id, false);
|
||||
productDetailsMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProductsDetailDO> get(Long id) {
|
||||
validateProductDetailsExists(id, false);
|
||||
return productDetailsMapper.selectList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<ProductsDetailDO> getPage(ProductDetailsPageReqVO pageReqVO) {
|
||||
return productDetailsMapper.selectPage(pageReqVO.setDeleted(0));
|
||||
}
|
||||
|
||||
// 判断是否存在
|
||||
private void validateProductDetailsExists(Long id, boolean deleted) {
|
||||
if (id == null) {
|
||||
throw exception(PRODUCTS_DETAIL_NO_EXIST);
|
||||
}
|
||||
if (productDetailsMapper.selectOne(new LambdaQueryWrapperX<ProductsDetailDO>()
|
||||
.eq(ProductsDetailDO::getId, id)
|
||||
.eq(ProductsDetailDO::getDeleted, false)) == null) {
|
||||
throw exception(PRODUCTS_DETAIL_NO_EXIST);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package com.cf.imes.module.system.service.products;
|
||||
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.module.system.controller.admin.products.vo.product.ProductPageReqVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.products.ProductsDO;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* 产品表 products Service 接口
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
public interface ProductsService {
|
||||
|
||||
/**
|
||||
* 创建产品
|
||||
*
|
||||
* @param productName 产品名称
|
||||
* @return 编号
|
||||
*/
|
||||
Long create(@Valid String productName);
|
||||
|
||||
/**
|
||||
* 更新产品
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void update(@Valid ProductsDO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除产品
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void delete(Long id);
|
||||
|
||||
/**
|
||||
* 获得产品
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
ProductsDO get(Long id);
|
||||
|
||||
/**
|
||||
* 获得产品 分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
*/
|
||||
PageResult<ProductsDO> getPage(ProductPageReqVO pageReqVO);
|
||||
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
package com.cf.imes.module.system.service.products;
|
||||
|
||||
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.cf.imes.module.system.controller.admin.products.vo.product.ProductPageReqVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.products.ProductsDO;
|
||||
import com.cf.imes.module.system.dal.mysql.products.ProductsMapper;
|
||||
import com.cf.imes.module.system.util.SnowflakeIdWorker3rd;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static com.cf.imes.module.system.enums.ErrorCodeConstants.PRODUCTS_NO_EXIST;
|
||||
|
||||
/**
|
||||
* 产品 products Service 实现类
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class ProductsServiceImpl implements ProductsService{
|
||||
|
||||
@Resource
|
||||
private ProductsMapper productsMapper;
|
||||
|
||||
@Resource
|
||||
private SnowflakeIdWorker3rd idWorker;
|
||||
|
||||
@Override
|
||||
public Long create(String productName) {
|
||||
Long id = idWorker.nextId();
|
||||
productsMapper.insert(
|
||||
new ProductsDO()
|
||||
.setId(id)
|
||||
.setProductName(productName)
|
||||
.setStatus(1)
|
||||
.setSoftwareId(0)
|
||||
);
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(ProductsDO updateReqVO) {
|
||||
validateProductPlateExists(updateReqVO.getId());
|
||||
|
||||
productsMapper.updateById(updateReqVO);
|
||||
}
|
||||
|
||||
private void validateProductPlateExists(Long id) {
|
||||
ProductsDO productsDO = getProductWithFalse(id);
|
||||
if (productsDO == null) {
|
||||
throw exception(PRODUCTS_NO_EXIST);
|
||||
}
|
||||
}
|
||||
|
||||
public ProductsDO getProductWithFalse(Long id) {
|
||||
return productsMapper.selectOne(new LambdaQueryWrapperX<ProductsDO>()
|
||||
.eq(ProductsDO::getId, id)
|
||||
.eq(ProductsDO::getDeleted, false));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Long id) {
|
||||
validateProductPlateExists(id);
|
||||
productsMapper.updateById(
|
||||
new ProductsDO()
|
||||
.setId(id)
|
||||
.setDeleted(true)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProductsDO get(Long id) {
|
||||
return getProductWithFalse(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<ProductsDO> getPage(ProductPageReqVO pageReqVO) {
|
||||
return productsMapper.selectPage(pageReqVO, false);
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package com.cf.imes.module.system.service.recharge;
|
||||
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.module.system.controller.admin.recharge.vo.RechargePageReqVO;
|
||||
import com.cf.imes.module.system.controller.admin.recharge.vo.RechargeSaveReqVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.recharge.GiftMoneyDetailsDO;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* 充值活动详情表 gift_money_details Service 接口
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
public interface RechargeActiveService {
|
||||
|
||||
/**
|
||||
* 创建充值活动
|
||||
*
|
||||
* @param createReqVO
|
||||
* @return 编号
|
||||
*/
|
||||
Long create(@Valid RechargeSaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新充值活动
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void update(@Valid RechargeSaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除充值活动
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void delete(Long id);
|
||||
|
||||
/**
|
||||
* 获得充值活动
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
GiftMoneyDetailsDO get(Long id);
|
||||
|
||||
/**
|
||||
* 获得充值活动 分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
*/
|
||||
PageResult<GiftMoneyDetailsDO> getPage(RechargePageReqVO pageReqVO);
|
||||
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
package com.cf.imes.module.system.service.recharge;
|
||||
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.common.util.object.BeanUtils;
|
||||
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.cf.imes.module.system.controller.admin.recharge.vo.RechargePageReqVO;
|
||||
import com.cf.imes.module.system.controller.admin.recharge.vo.RechargeSaveReqVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.recharge.GiftMoneyDetailsDO;
|
||||
import com.cf.imes.module.system.dal.mysql.recharge.GiftMoneyDetailsMapper;
|
||||
import com.cf.imes.module.system.util.SnowflakeIdWorker3rd;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static com.cf.imes.module.system.enums.ErrorCodeConstants.RECHARGE_ACTIVE_NO_EXIST;
|
||||
|
||||
/**
|
||||
* 充值活动详情表 gift_money_details Service 实现类
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class RechargeActiveServiceImpl implements RechargeActiveService{
|
||||
|
||||
@Resource
|
||||
private SnowflakeIdWorker3rd idWorker;
|
||||
|
||||
@Resource
|
||||
private GiftMoneyDetailsMapper giftMoneyDetailsMapper;
|
||||
|
||||
@Override
|
||||
public Long create(RechargeSaveReqVO createReqVO) {
|
||||
Long id = idWorker.nextId();
|
||||
GiftMoneyDetailsDO giftMoneyDetailsDOn = BeanUtils.toBean(createReqVO, GiftMoneyDetailsDO.class).setId(id);
|
||||
giftMoneyDetailsMapper.insert(giftMoneyDetailsDOn);
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(RechargeSaveReqVO updateReqVO) {
|
||||
validateRechargeActiveExists(updateReqVO.getId(), false);
|
||||
}
|
||||
|
||||
// 校验是否存在
|
||||
private void validateRechargeActiveExists(Long id, boolean deleted) {
|
||||
if (id == null) {
|
||||
throw exception(RECHARGE_ACTIVE_NO_EXIST);
|
||||
}
|
||||
GiftMoneyDetailsDO dictType = giftMoneyDetailsMapper.selectOne(new LambdaQueryWrapperX<GiftMoneyDetailsDO>()
|
||||
.eq(GiftMoneyDetailsDO::getId, id)
|
||||
.eq(GiftMoneyDetailsDO::getDeleted, deleted));
|
||||
if (dictType == null) {
|
||||
throw exception(RECHARGE_ACTIVE_NO_EXIST);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void delete(Long id) {
|
||||
validateRechargeActiveExists(id, false);
|
||||
giftMoneyDetailsMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GiftMoneyDetailsDO get(Long id) {
|
||||
validateRechargeActiveExists(id, false);
|
||||
return giftMoneyDetailsMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<GiftMoneyDetailsDO> getPage(RechargePageReqVO pageReqVO) {
|
||||
return giftMoneyDetailsMapper.selectPage(pageReqVO);
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package com.cf.imes.module.system.util;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
||||
@Component
|
||||
public class SnowflakeIdWorker3rd {
|
||||
/** 初始时间 (2024-01-01 毫秒数: 1704038400000L) */
|
||||
private final long twepoch = 1704038400000L;
|
||||
/** 序列号占位数 */
|
||||
private final long sequenceBits = 12L;
|
||||
/** 时间戳左移位数 */
|
||||
private final long timestampLeftShift = 22L; // 12位序列号 + 10位预留
|
||||
/** 序列号掩码 */
|
||||
private final long sequenceMask = -1L ^ (-1L << sequenceBits);
|
||||
/** 当前序列号 */
|
||||
private long sequence = 0L;
|
||||
/** 上次生成ID的时间戳 */
|
||||
private long lastTimestamp = -1L;
|
||||
|
||||
public synchronized long nextId() {
|
||||
long timestamp = timeGen();
|
||||
if (timestamp < lastTimestamp) {
|
||||
throw new RuntimeException("时钟回拨,无法生成ID。回拨时间:" + (lastTimestamp - timestamp) + "ms");
|
||||
}
|
||||
|
||||
// 同一毫秒内生成序列号
|
||||
if (timestamp == lastTimestamp) {
|
||||
sequence = (sequence + 1) & sequenceMask;
|
||||
// 序列号溢出,等待下一毫秒
|
||||
if (sequence == 0) {
|
||||
timestamp = tilNextMillis(lastTimestamp);
|
||||
}
|
||||
} else {
|
||||
sequence = 0L;
|
||||
}
|
||||
|
||||
lastTimestamp = timestamp;
|
||||
// 组合时间戳和序列号生成ID
|
||||
return ((timestamp - twepoch) << timestampLeftShift) | sequence;
|
||||
}
|
||||
|
||||
/** 等待至下一毫秒 */
|
||||
private long tilNextMillis(long lastTimestamp) {
|
||||
long timestamp = timeGen();
|
||||
while (timestamp <= lastTimestamp) {
|
||||
timestamp = timeGen();
|
||||
}
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
/** 获取当前毫秒时间 */
|
||||
private long timeGen() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SnowflakeIdWorker3rd idWorker = new SnowflakeIdWorker3rd();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
System.out.println(idWorker.nextId());
|
||||
}
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.cf.imes.module.system.validation.advertisement;
|
||||
|
||||
|
||||
import javax.validation.Constraint;
|
||||
import javax.validation.Payload;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 广告状态校验注解
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@Target({
|
||||
ElementType.FIELD,
|
||||
})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Constraint(
|
||||
validatedBy = {AdvertisementStatusValidator.class}
|
||||
)
|
||||
public @interface AdvertisementStatus {
|
||||
String message() default "广告状态不合法,0:全部、1:未发布、2:已发布、3:已结束";
|
||||
|
||||
Class<?>[] groups() default {};
|
||||
|
||||
Class<? extends Payload>[] payload() default {};
|
||||
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.cf.imes.module.system.validation.advertisement;
|
||||
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.cf.imes.module.system.enums.advertisement.AdvertisementStatusEnum;
|
||||
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 广告状态校验器
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
public class AdvertisementStatusValidator implements ConstraintValidator<AdvertisementStatus, Integer> {
|
||||
|
||||
@Override
|
||||
public boolean isValid(Integer value, ConstraintValidatorContext context) {
|
||||
if (ObjectUtil.isNull(value)) {
|
||||
return true;
|
||||
}
|
||||
for (AdvertisementStatusEnum statusEnum : AdvertisementStatusEnum.values()) {
|
||||
if (Objects.equals(statusEnum.getStatus(), value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.cf.imes.module.system.validation.products;
|
||||
|
||||
|
||||
import javax.validation.Constraint;
|
||||
import javax.validation.Payload;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 产品状态校验注解
|
||||
*/
|
||||
@Target({
|
||||
ElementType.FIELD,
|
||||
})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Constraint(
|
||||
validatedBy = {ProductStatusValidator.class}
|
||||
)
|
||||
public @interface ProductStatus {
|
||||
|
||||
String message() default "产品状态不合法,0:待上架 1:已上架 2:已下架";
|
||||
|
||||
Class<?>[] groups() default {};
|
||||
|
||||
Class<? extends Payload>[] payload() default {};
|
||||
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.cf.imes.module.system.validation.products;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.cf.imes.module.system.enums.products.ProductStatusEnum;
|
||||
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 产品状态校验器
|
||||
*/
|
||||
public class ProductStatusValidator implements ConstraintValidator<ProductStatus, Integer> {
|
||||
|
||||
@Override
|
||||
public boolean isValid(Integer value, ConstraintValidatorContext context) {
|
||||
if (ObjectUtil.isNull(value)) {
|
||||
return true;
|
||||
}
|
||||
for (ProductStatusEnum statusEnum : ProductStatusEnum.values()) {
|
||||
if (Objects.equals(statusEnum.getStatus(), value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.cf.imes.module.system.validation.products;
|
||||
|
||||
import javax.validation.Constraint;
|
||||
import javax.validation.Payload;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 产品详情购买方式校验注解
|
||||
*/
|
||||
@Target({
|
||||
ElementType.FIELD,
|
||||
})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Constraint(
|
||||
validatedBy = {ProductTypeValidator.class}
|
||||
)
|
||||
public @interface ProductType {
|
||||
|
||||
String message() default "购买方式:0 时长;1 产量";
|
||||
|
||||
Class<?>[] groups() default {};
|
||||
|
||||
Class<? extends Payload>[] payload() default {};
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.cf.imes.module.system.validation.products;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.cf.imes.module.system.enums.products.ProductsPurchaseTypeEnum;
|
||||
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 产品详情购买方式校验器
|
||||
*/
|
||||
public class ProductTypeValidator implements ConstraintValidator<ProductType, Integer> {
|
||||
|
||||
@Override
|
||||
public boolean isValid(Integer value, ConstraintValidatorContext context) {
|
||||
if (ObjectUtil.isNull(value)) {
|
||||
return true;
|
||||
}
|
||||
for (ProductsPurchaseTypeEnum statusEnum : ProductsPurchaseTypeEnum.values()) {
|
||||
if (Objects.equals(statusEnum.getStatus(), value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package com.cf.imes.module.system.validation.recharge;
|
||||
|
||||
import javax.validation.Constraint;
|
||||
import javax.validation.Payload;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 自定义Double校验注解
|
||||
*
|
||||
*/
|
||||
@Target({
|
||||
ElementType.METHOD,
|
||||
ElementType.FIELD,
|
||||
ElementType.ANNOTATION_TYPE,
|
||||
ElementType.CONSTRUCTOR,
|
||||
ElementType.PARAMETER,
|
||||
ElementType.TYPE_USE
|
||||
})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Constraint(
|
||||
validatedBy = MoneyValidator.class
|
||||
)
|
||||
public @interface MoneyValid {
|
||||
|
||||
/**
|
||||
* 字段中文名
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* 校验提示信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String message() default "数字不合法";
|
||||
|
||||
Class<?>[] groups() default {};
|
||||
|
||||
Class<? extends Payload>[] payload() default {};
|
||||
|
||||
/**
|
||||
* 整数最大位数
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int integer() default 7;
|
||||
|
||||
/**
|
||||
* 小数点后的最大位数
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int fraction() default 3;
|
||||
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
package com.cf.imes.module.system.validation.recharge;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* Double类型校验器
|
||||
*/
|
||||
public class MoneyValidator implements ConstraintValidator<MoneyValid, Number> {
|
||||
|
||||
private static final String ZERO = "0";
|
||||
private static final String GREATER_THAN_ZERO_NOTIFICATION = "%s必须大于0";
|
||||
private static final String LENGTH_ERROR_NOTIFICATION = "%s长度不合法,总长度不超过%d位,小数点后不超过%d位";
|
||||
|
||||
private String name;
|
||||
private int maxIntegerDigits;
|
||||
private int maxFractionDigits;
|
||||
|
||||
@Override
|
||||
public void initialize(MoneyValid constraintAnnotation) {
|
||||
this.name = constraintAnnotation.name();
|
||||
this.maxIntegerDigits = constraintAnnotation.integer();
|
||||
this.maxFractionDigits = constraintAnnotation.fraction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(Number value, ConstraintValidatorContext context) {
|
||||
if (ObjectUtil.isNull(value)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String errorMessage = null;
|
||||
if (value instanceof Integer) {
|
||||
errorMessage = handleInteger((Integer) value);
|
||||
} else if (value instanceof Long) {
|
||||
errorMessage = handleLong((Long) value);
|
||||
} else if (value instanceof Double) {
|
||||
errorMessage = handleDouble((Double) value);
|
||||
} else if (value instanceof BigDecimal) {
|
||||
errorMessage = handleBigDecimal((BigDecimal) value);
|
||||
}
|
||||
|
||||
if (StringUtils.isNotEmpty(errorMessage)) {
|
||||
context.disableDefaultConstraintViolation();
|
||||
context.buildConstraintViolationWithTemplate(errorMessage).addConstraintViolation();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private String handleInteger(Integer value) {
|
||||
if (value <= 0) {
|
||||
return String.format(GREATER_THAN_ZERO_NOTIFICATION, name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String handleLong(Long value) {
|
||||
if (value <= 0) {
|
||||
return String.format(GREATER_THAN_ZERO_NOTIFICATION, name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String handleDouble(Double value) {
|
||||
return handleBigDecimal(new BigDecimal(value.toString()));
|
||||
}
|
||||
|
||||
private String handleBigDecimal(BigDecimal value) {
|
||||
if (value.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
return String.format(GREATER_THAN_ZERO_NOTIFICATION, name);
|
||||
}
|
||||
|
||||
String[] parts = value.toPlainString().split("\\.");
|
||||
int integerPartLength = parts[0].length();
|
||||
int fractionalPartLength = parts.length > 1 ? parts[1].length() : 0;
|
||||
|
||||
if (integerPartLength > maxIntegerDigits || fractionalPartLength > maxFractionDigits) {
|
||||
return String.format(LENGTH_ERROR_NOTIFICATION, name, maxIntegerDigits + maxFractionDigits, maxFractionDigits);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.cf.imes.module.system.validation.recharge;
|
||||
|
||||
import javax.validation.Constraint;
|
||||
import javax.validation.Payload;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 赠送类型校验注解
|
||||
*/
|
||||
@Target({
|
||||
ElementType.FIELD,
|
||||
})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Constraint(
|
||||
validatedBy = {PurchaseTypeValidator.class}
|
||||
)
|
||||
public @interface PurchaseType {
|
||||
|
||||
String message() default "赠送类型不合法,0:满X送X; 1:每满X送X";
|
||||
|
||||
Class<?>[] groups() default {};
|
||||
|
||||
Class<? extends Payload>[] payload() default {};
|
||||
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.cf.imes.module.system.validation.recharge;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.cf.imes.module.system.enums.recharge.PurchaseTypeEnum;
|
||||
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 赠送类型校验器
|
||||
*/
|
||||
public class PurchaseTypeValidator implements ConstraintValidator<PurchaseType, Integer> {
|
||||
|
||||
@Override
|
||||
public boolean isValid(Integer value, ConstraintValidatorContext context) {
|
||||
if (ObjectUtil.isNull(value)) {
|
||||
return true;
|
||||
}
|
||||
for (PurchaseTypeEnum statusEnum : PurchaseTypeEnum.values()) {
|
||||
if (Objects.equals(statusEnum.getStatus(), value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.cf.imes.module.system.validation.recharge;
|
||||
|
||||
import javax.validation.Constraint;
|
||||
import javax.validation.Payload;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 充值类型校验注解
|
||||
*/
|
||||
@Target({
|
||||
ElementType.FIELD,
|
||||
})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Constraint(
|
||||
validatedBy = {RechargeTypeValidator.class}
|
||||
)
|
||||
public @interface RechargeType {
|
||||
|
||||
String message() default "充值类型不合法, 0:微信、支付宝 1:微信 2:支付宝";
|
||||
|
||||
Class<?>[] groups() default {};
|
||||
|
||||
Class<? extends Payload>[] payload() default {};
|
||||
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.cf.imes.module.system.validation.recharge;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.cf.imes.module.system.enums.recharge.RechargeTypeEnum;
|
||||
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 充值类型校验器
|
||||
*/
|
||||
public class RechargeTypeValidator implements ConstraintValidator<RechargeType, Integer> {
|
||||
@Override
|
||||
public boolean isValid(Integer value, ConstraintValidatorContext context) {
|
||||
if (ObjectUtil.isNull(value)) {
|
||||
return true;
|
||||
}
|
||||
for (RechargeTypeEnum statusEnum : RechargeTypeEnum.values()) {
|
||||
if (Objects.equals(statusEnum.getStatus(), value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -138,6 +138,7 @@ chenfeng:
|
||||
info:
|
||||
version: 1.0.0
|
||||
base-package: com.cf.imes.module.system
|
||||
name: 晨丰
|
||||
web:
|
||||
admin-ui:
|
||||
url: http://dashboard.chenfeng.iocoder.cn # Admin 管理后台 UI 的地址
|
||||
@@ -204,6 +205,10 @@ chenfeng:
|
||||
- system_machine_brand
|
||||
- system_machine_limit
|
||||
- system_config_token
|
||||
- products_detail
|
||||
- products
|
||||
- advertisement
|
||||
- system_advertisement_task
|
||||
use-data-code: imes_prod #动态数据源标识,后期添加的数据源需要修改此值
|
||||
|
||||
sms-code: # 短信验证码相关的配置项
|
||||
|
||||
Reference in New Issue
Block a user