New file |
| | |
| | | FROM openjdk:8-jdk-alpine |
| | | ENV LANG en_US.UTF-8 |
| | | ENV LANGUAGE en_US:en |
| | | ENV LC_ALL en_US.UTF-8 |
| | | ENV TIME_ZONE Asia/Shanghai |
| | | RUN apk add --no-cache tzdata \ |
| | | ############设置时区 |
| | | && echo "Asia/Shanghai" > /etc/timezone \ |
| | | && ln -sf /usr/share/zoneinfo/${TIME_ZONE} /etc/localtime |
| | | RUN apk add --no-cache font-adobe-100dpi ttf-dejavu fontconfig |
| | | WORKDIR application |
| | | ARG JAR_FILE=target/*.jar |
| | | COPY ${JAR_FILE} application.jar |
| | | COPY src/main/resources/cert /root/test/hxsl/cert |
| | | |
| | | EXPOSE 8088 |
| | | |
| | | ENTRYPOINT ["java","-XX:+UnlockExperimentalVMOptions","-XX:+UseCGroupMemoryLimitForHeap", "-jar","/application/application.jar","--spring.profiles.active=prod"] |
New file |
| | |
| | | FROM openjdk:8-jdk-alpine |
| | | ENV LANG en_US.UTF-8 |
| | | ENV LANGUAGE en_US:en |
| | | ENV LC_ALL en_US.UTF-8 |
| | | ENV TIME_ZONE Asia/Shanghai |
| | | RUN apk add --no-cache tzdata \ |
| | | ############设置时区 |
| | | && echo "Asia/Shanghai" > /etc/timezone \ |
| | | && ln -sf /usr/share/zoneinfo/${TIME_ZONE} /etc/localtime |
| | | RUN apk add --no-cache font-adobe-100dpi ttf-dejavu fontconfig |
| | | WORKDIR application |
| | | ARG JAR_FILE=target/*.jar |
| | | COPY ${JAR_FILE} application.jar |
| | | COPY src/main/resources/cert /root/test/hxsl/cert |
| | | |
| | | EXPOSE 8088 |
| | | |
| | | ENTRYPOINT ["java","-XX:+UnlockExperimentalVMOptions","-XX:+UseCGroupMemoryLimitForHeap", "-jar","/application/application.jar","--spring.profiles.active=test"] |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform; |
| | | |
| | | |
| | | import org.springframework.boot.SpringApplication; |
| | | import org.springframework.boot.autoconfigure.SpringBootApplication; |
| | | import org.springframework.boot.builder.SpringApplicationBuilder; |
| | | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; |
| | | import org.springframework.context.annotation.ComponentScan; |
| | | |
| | | /** |
| | | * @author lgh |
| | | */ |
| | | @SpringBootApplication |
| | | @ComponentScan("com.yami.shop") |
| | | public class PlatformApplication extends SpringBootServletInitializer{ |
| | | |
| | | public static void main(String[] args) { |
| | | SpringApplication.run(PlatformApplication.class, args); |
| | | } |
| | | |
| | | @Override |
| | | protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { |
| | | return builder.sources(PlatformApplication.class); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.config; |
| | | |
| | | /** |
| | | * @author Yami |
| | | */ |
| | | public enum FlowUserAnalysisType { |
| | | /** 团购商品类型 */ |
| | | WEEK(1), |
| | | |
| | | /** 近30天 */ |
| | | MONTH(2), |
| | | |
| | | /** 自定义 */ |
| | | CUSTOM(3); |
| | | |
| | | private Integer num; |
| | | |
| | | public Integer value() { |
| | | return num; |
| | | } |
| | | |
| | | FlowUserAnalysisType(Integer num){ |
| | | this.num = num; |
| | | } |
| | | |
| | | public static FlowUserAnalysisType instance(Integer value) { |
| | | FlowUserAnalysisType[] enums = values(); |
| | | for (FlowUserAnalysisType statusEnum : enums) { |
| | | if (statusEnum.value().equals(value)) { |
| | | return statusEnum; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.config; |
| | | |
| | | /** |
| | | * 常量 |
| | | * @author yami |
| | | */ |
| | | public class PlatformConstant { |
| | | |
| | | /** 最大分类层级 */ |
| | | public static final int MAX_CATEGORY_GRADE = 2; |
| | | |
| | | /** |
| | | * 短信包上限数量 |
| | | */ |
| | | public static final long SMS_PACKAGE_MAX_NUM = 10; |
| | | /** |
| | | * 6 |
| | | */ |
| | | public static final long SIX_MAONTH = 6; |
| | | /** |
| | | * 2 |
| | | */ |
| | | public static final int TWO = 2; |
| | | /** |
| | | * 3 |
| | | */ |
| | | public static final int THREE = 3; |
| | | /** |
| | | * 4 |
| | | */ |
| | | public static final int FOUR = 4; |
| | | /** |
| | | * 5 |
| | | */ |
| | | public static final long FIVE = 5; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.config; |
| | | |
| | | import io.swagger.v3.oas.models.OpenAPI; |
| | | import io.swagger.v3.oas.models.info.Info; |
| | | import io.swagger.v3.oas.models.info.License; |
| | | import org.springdoc.core.GroupedOpenApi; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | /** |
| | | * //@Profile("dev") |
| | | * Swagger文档,只有在测试环境才会使用 |
| | | * @author LGH |
| | | */ |
| | | @Configuration |
| | | public class SwaggerConfiguration { |
| | | |
| | | @Bean |
| | | public GroupedOpenApi publicApi() { |
| | | return GroupedOpenApi.builder() |
| | | .group("公共接口") |
| | | .packagesToScan("com.yami.shop.platform") |
| | | .pathsToMatch("/**") |
| | | .build(); |
| | | } |
| | | |
| | | @Bean |
| | | public OpenAPI springShopOpenAPI() { |
| | | return new OpenAPI() |
| | | .info(new Info().title("Mall4j接口文档") |
| | | .description("Mall4j宇宙版接口文档,openapi3.0 接口,用于平台端对接") |
| | | .version("v0.0.1") |
| | | .license(new License().name("使用请遵守商用授权协议").url("https://www.mall4j.com"))); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.config; |
| | | |
| | | import com.xxl.job.core.executor.impl.XxlJobSpringExecutor; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.cloud.commons.util.InetUtils; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | /** |
| | | * xxl-job config |
| | | * |
| | | * @author FrozenWatermelon |
| | | * @date 2021/1/18 |
| | | */ |
| | | @Configuration |
| | | public class XxlJobConfig { |
| | | private final Logger logger = LoggerFactory.getLogger(XxlJobConfig.class); |
| | | |
| | | @Value("${xxl-job.admin.addresses}") |
| | | private String adminAddresses; |
| | | |
| | | @Value("${xxl-job.accessToken}") |
| | | private String accessToken; |
| | | |
| | | @Value("${xxl-job.logPath}") |
| | | private String logPath; |
| | | |
| | | @Value("${server.port}") |
| | | private int port; |
| | | |
| | | @Autowired |
| | | private InetUtils inetUtils; |
| | | |
| | | @Bean |
| | | public XxlJobSpringExecutor xxlJobExecutor() { |
| | | |
| | | logger.info(">>>>>>>>>>> xxl-job config init."); |
| | | XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor(); |
| | | xxlJobSpringExecutor.setAdminAddresses(adminAddresses); |
| | | xxlJobSpringExecutor.setAppname("mall4j-bbc"); |
| | | // 针对多网卡、容器内部署等情况,可借助 "spring-cloud-commons" 提供的 "InetUtils" 组件灵活定制注册IP |
| | | xxlJobSpringExecutor.setIp(inetUtils.findFirstNonLoopbackAddress().getHostAddress()); |
| | | xxlJobSpringExecutor.setPort(port + 1000); |
| | | xxlJobSpringExecutor.setAccessToken(accessToken); |
| | | xxlJobSpringExecutor.setLogPath(logPath); |
| | | xxlJobSpringExecutor.setLogRetentionDays(3); |
| | | return xxlJobSpringExecutor; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import cn.hutool.poi.excel.ExcelUtil; |
| | | import cn.hutool.poi.excel.ExcelWriter; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.param.CustomerReqParam; |
| | | import com.yami.shop.bean.vo.AccountDetailVO; |
| | | import com.yami.shop.bean.vo.ShopAccountDetailVO; |
| | | import com.yami.shop.bean.vo.ShopAccountVO; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.i18n.I18nMessage; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.common.util.PoiExcelUtil; |
| | | import com.yami.shop.service.PayInfoService; |
| | | import com.yami.shop.service.RefundInfoService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.apache.poi.ss.usermodel.Sheet; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * @author lhd |
| | | * @date 2021/8/11 15:57 |
| | | */ |
| | | @RestController("platformAccountDetailController") |
| | | @RequestMapping("/platform/accountDetail") |
| | | @Tag(name = "账户详情") |
| | | public class AccountDetailController { |
| | | |
| | | @Autowired |
| | | private PayInfoService payInfoService; |
| | | @Autowired |
| | | private RefundInfoService refundInfoService; |
| | | |
| | | @GetMapping("/getIncomeAccountDetail") |
| | | @Operation(summary = "获取收入账户详情" , description = "根据时间获取") |
| | | public ServerResponseEntity<AccountDetailVO> getIncomeAccountDetail(@ParameterObject CustomerReqParam accountSearchDTO){ |
| | | AccountDetailVO accountDetailVO = payInfoService.getIncomeAccountDetail(accountSearchDTO.getStartTime(), accountSearchDTO.getEndTime(), accountSearchDTO.getShopName()); |
| | | return ServerResponseEntity.success(accountDetailVO); |
| | | } |
| | | |
| | | @GetMapping("/getRefundAccountDetail") |
| | | @Operation(summary = "获取退款账户详情" , description = "根据时间获取") |
| | | public ServerResponseEntity<AccountDetailVO> getRefundAccountDetail(@ParameterObject CustomerReqParam accountSearchDTO){ |
| | | AccountDetailVO accountDetailVO = refundInfoService.getRefundAccountDetail(accountSearchDTO.getStartTime(), accountSearchDTO.getEndTime(), accountSearchDTO.getShopName()); |
| | | return ServerResponseEntity.success(accountDetailVO); |
| | | } |
| | | |
| | | @GetMapping("/getIncomeAccountDetailInfo") |
| | | @Operation(summary = "分页获取收入账户详情" , description = "分页获取收入账户详情") |
| | | public ServerResponseEntity<IPage<ShopAccountVO>> getIncomeAccountDetailInfo(PageParam<ShopAccountVO> page, @ParameterObject CustomerReqParam accountSearchDTO) { |
| | | IPage<ShopAccountVO> accountDetailPage = payInfoService.pageIncomeAccountDetail(page, accountSearchDTO); |
| | | return ServerResponseEntity.success(accountDetailPage); |
| | | } |
| | | |
| | | @GetMapping("/getRefundAccountDetailInfo") |
| | | @Operation(summary = "分页获取退款账户详情" , description = "分页获取退款账户详情") |
| | | public ServerResponseEntity<IPage<ShopAccountVO>> getRefundAccountDetailInfo(PageParam<ShopAccountVO> page, @ParameterObject CustomerReqParam accountSearchDTO) { |
| | | IPage<ShopAccountVO> accountDetailPage = refundInfoService.listRefundAccountDetail(page, accountSearchDTO); |
| | | return ServerResponseEntity.success(accountDetailPage); |
| | | } |
| | | |
| | | @GetMapping("/pageShopIncomeAccountDetail") |
| | | @Operation(summary = "分页获取指定店铺的收入结算明细" , description = "根据店铺id,时间获取") |
| | | public ServerResponseEntity<IPage<ShopAccountDetailVO>> pageShopIncomeAccountDetail(PageParam<ShopAccountDetailVO> page, @ParameterObject CustomerReqParam customerReqParam) { |
| | | IPage<ShopAccountDetailVO> accountDetailPage = payInfoService.pageShopIncomeAccountDetail(page, customerReqParam); |
| | | return ServerResponseEntity.success(accountDetailPage); |
| | | } |
| | | |
| | | @GetMapping("/pageShopRefundAccountDetail") |
| | | @Operation(summary = "分页获取指定店铺的退款结算明细" , description = "根据店铺id,时间获取") |
| | | public ServerResponseEntity<IPage<ShopAccountDetailVO>> pageShopRefundAccountDetail(PageParam<ShopAccountDetailVO> page, @ParameterObject CustomerReqParam customerReqParam) { |
| | | IPage<ShopAccountDetailVO> accountDetailPage = refundInfoService.pageShopRefundAccountDetail(page, customerReqParam); |
| | | return ServerResponseEntity.success(accountDetailPage); |
| | | } |
| | | |
| | | @GetMapping("/getPayAndRefundInfoForm") |
| | | @Operation(summary = "导出报表" , description = "导出收入以及退款报表") |
| | | @PreAuthorize("@pms.hasPermission('pay:refund:excel')") |
| | | public void getPayAndRefundInfoForm(@ParameterObject CustomerReqParam customerReqParam, HttpServletResponse response) { |
| | | if (Objects.isNull(customerReqParam.getStartTime()) || Objects.isNull(customerReqParam.getEndTime())) { |
| | | // 请选择导出报表的交易时间 |
| | | throw new YamiShopBindException("yami.finance.form.excel"); |
| | | } |
| | | List<ShopAccountDetailVO> incomeAccountDetails = payInfoService.listIncomeAccountDetail(customerReqParam); |
| | | List<ShopAccountDetailVO> refundAccountDetails = refundInfoService.listRefundAccountDetail(customerReqParam); |
| | | Map<Integer, List<ShopAccountDetailVO>> shopAccountDetailMap = new HashMap<>(2); |
| | | shopAccountDetailMap.put(0, incomeAccountDetails); |
| | | shopAccountDetailMap.put(1, refundAccountDetails); |
| | | excelMultiSheet(response, shopAccountDetailMap); |
| | | } |
| | | |
| | | public void excelMultiSheet(HttpServletResponse response, Map<Integer, List<ShopAccountDetailVO>> shopAccountDetailMap) { |
| | | ExcelWriter writer = ExcelUtil.getBigWriter(); |
| | | writer.renameSheet(0, I18nMessage.getMessage("yami.pay.info.reportTitle")); |
| | | for (int i = 0; i < shopAccountDetailMap.size(); i++) { |
| | | writer.setSheet(i == 0 ? I18nMessage.getMessage("yami.pay.info.reportTitle") : I18nMessage.getMessage("yami.refund.info.reportTitle")); |
| | | handleSheet(writer); |
| | | List<ShopAccountDetailVO> shopAccountDetails = shopAccountDetailMap.get(i); |
| | | int row = 1; |
| | | for (ShopAccountDetailVO shopAccountDetail : shopAccountDetails) { |
| | | int firstRow = ++row; |
| | | int col = -1; |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, row - 1); |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, shopAccountDetail.getShopName()); |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, shopAccountDetail.getPayTime()); |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, shopAccountDetail.getOrderNumber()); |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, shopAccountDetail.getPayNo()); |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, shopAccountDetail.getBizPayNo()); |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, I18nMessage.getMessage("yami.payType.pay" + shopAccountDetail.getPayType())); |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, shopAccountDetail.getAlipayAmount()); |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, shopAccountDetail.getWechatAmount()); |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, shopAccountDetail.getScoreCount()); |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, shopAccountDetail.getBalanceAmount()); |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, shopAccountDetail.getPaypalAmount()); |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, shopAccountDetail.getTotal()); |
| | | } |
| | | } |
| | | PoiExcelUtil.writeExcel(response, writer); |
| | | } |
| | | |
| | | private void handleSheet(ExcelWriter writer) { |
| | | String[] headerCn = {"序号","店铺名称","支付时间","订单编号","支付单号","外部流水号","支付方式","支付宝","微信","支付积分","余额支付","PayPal支付","合计"}; |
| | | String[] headerEn = {"Serial Number", "Store Name", "Payment Time", "Order Number", "Payment Order Number", "External Streaming Number", "Payment Method", "Alipay", "WeChat", "Payment Credits", "Balance Payment", "PayPal Payment", "Total"}; |
| | | List<String> header = Arrays.asList(Objects.equals(I18nMessage.getDbLang(), 0) ? headerCn : headerEn); |
| | | writer.merge(header.size() - 1, I18nMessage.getMessage("yami.account.info.reportTitle")); |
| | | writer.writeRow(header); |
| | | Sheet sheet = writer.getSheet(); |
| | | for (int j = 1; j < header.size() - 1; j++) { |
| | | sheet.setColumnWidth(j, 20 * 256); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.model.Agent; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.AgentService; |
| | | import com.yami.shop.task.common.model.TaskDetail; |
| | | import com.yami.shop.task.common.service.TaskDetailService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.List; |
| | | |
| | | |
| | | @RestController |
| | | @RequestMapping("/platform/agent") |
| | | @Tag(name = "代理商") |
| | | public class AgentController { |
| | | |
| | | @Autowired |
| | | private AgentService agentService; |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "分页获取代理商" , description = "分页获取代理商") |
| | | public ServerResponseEntity<IPage<Agent>> page(@ParameterObject Agent agent, PageParam<Agent> page){ |
| | | IPage<Agent> agentPage = agentService.page(page,new LambdaQueryWrapper<Agent>() |
| | | .like(StrUtil.isNotBlank(agent.getAgentName()), Agent::getAgentName,agent.getAgentName()) |
| | | .like(StrUtil.isNotBlank(agent.getAgentRegion()), Agent::getAgentRegion,agent.getAgentRegion()) |
| | | .like(StrUtil.isNotBlank(agent.getAgentRegion()), Agent::getAgentRegion,agent.getAgentRegion()) |
| | | .like(StrUtil.isNotBlank(agent.getRemark()), Agent::getRemark,agent.getRemark()) |
| | | .eq(agent.getAgentMobile()!=null, Agent::getAgentMobile,agent.getAgentMobile()) |
| | | .orderByAsc(Agent::getCreatTime) |
| | | ); |
| | | return ServerResponseEntity.success(agentPage); |
| | | } |
| | | |
| | | @GetMapping("/info/{id}") |
| | | @Operation(summary = "获取信息" , description = "获取信息") |
| | | @Parameter(name = "id", description = "任务id" ) |
| | | public ServerResponseEntity<Agent> info(@PathVariable("id") Long id){ |
| | | Agent agent = agentService.getById(id); |
| | | return ServerResponseEntity.success(agent); |
| | | } |
| | | |
| | | @PostMapping |
| | | @Operation(summary = "保存" , description = "保存") |
| | | public ServerResponseEntity<Void> save(@RequestBody @Valid Agent agent){ |
| | | agentService.save(agent); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping |
| | | @Operation(summary = "修改" , description = "修改") |
| | | public ServerResponseEntity<Void> update(@RequestBody @Valid Agent agent){ |
| | | agentService.updateById(agent); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @DeleteMapping |
| | | @Operation(summary = "删除" , description = "删除") |
| | | @Parameter(name = "ids", description = "任务id列表" ) |
| | | public ServerResponseEntity<Void> delete(@RequestBody List<Long> ids){ |
| | | agentService.removeByIds(ids); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.dto.AreaDto; |
| | | import com.yami.shop.bean.enums.AreaLevelEnum; |
| | | import com.yami.shop.bean.model.Area; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.AreaService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * @author lgh on 2018/10/26. |
| | | */ |
| | | @RestController |
| | | @Tag(name = "省市区") |
| | | @RequestMapping("/admin/area") |
| | | public class AreaController { |
| | | |
| | | @Autowired |
| | | private AreaService areaService; |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "分页查询" , description = "分页查询") |
| | | public ServerResponseEntity<IPage<Area>> page(@ParameterObject Area area, PageParam<Area> page) { |
| | | IPage<Area> sysUserPage = areaService.page(page, new LambdaQueryWrapper<Area>()); |
| | | return ServerResponseEntity.success(sysUserPage); |
| | | } |
| | | |
| | | @GetMapping("/list") |
| | | @Operation(summary = "获取列表" , description = "获取列表") |
| | | public ServerResponseEntity<List<Area>> list(@ParameterObject Area area) { |
| | | List<Area> areas = areaService.list(new LambdaQueryWrapper<Area>() |
| | | .like(area.getAreaName() != null, Area::getAreaName, area.getAreaName()) |
| | | .lt(!Objects.isNull(area.getMaxGrade()),Area::getLevel,area.getMaxGrade()) |
| | | ); |
| | | return ServerResponseEntity.success(areas); |
| | | } |
| | | |
| | | @GetMapping("/listByPid") |
| | | @Operation(summary = "通过父级id获取列表" , description = "通过父级id获取列表") |
| | | public ServerResponseEntity<List<Area>> listByPid(Long pid, Integer level) { |
| | | List<Area> list = areaService.listByPid(pid, level); |
| | | return ServerResponseEntity.success(list); |
| | | } |
| | | |
| | | @GetMapping("/info/{id}") |
| | | @Operation(summary = "获取信息" , description = "获取信息") |
| | | public ServerResponseEntity<Area> info(@PathVariable("id") Long id) { |
| | | Area area = areaService.getById(id); |
| | | return ServerResponseEntity.success(area); |
| | | } |
| | | |
| | | @PostMapping |
| | | @Operation(summary = "保存" , description = "保存") |
| | | public ServerResponseEntity<Void> save(@Valid @RequestBody Area area) { |
| | | if (area.getParentId() != null && !Objects.equals(area.getParentId(), 0L)) { |
| | | areaService.removeAreaCacheByParentId(null, 1); |
| | | Area parentArea = areaService.getById(area.getParentId()); |
| | | area.setLevel(parentArea.getLevel() + 1); |
| | | areaService.removeAreaCacheByParentId(area.getParentId(), null); |
| | | // 因为获取地址的时候,过滤掉了没有三级地址的一级地址,情况缓存的时候,一级地址也需要清空一下 |
| | | if (Objects.equals(area.getLevel(), AreaLevelEnum.THIRD_LEVEL.value())) { |
| | | areaService.removeAreaCacheByParentId(0L, null); |
| | | } |
| | | } |
| | | hasSameName(area); |
| | | areaService.removeAreaListCache(); |
| | | areaService.save(area); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping |
| | | @Operation(summary = "修改" , description = "修改") |
| | | public ServerResponseEntity<Void> update(@Valid @RequestBody Area area) { |
| | | Area areaDb = areaService.getById(area.getAreaId()); |
| | | // 判断当前省市区级别,如果是1级、2级则不能修改级别,不能修改成别人的下级 |
| | | if(Objects.equals(areaDb.getLevel(),AreaLevelEnum.FIRST_LEVEL.value()) && !Objects.equals(area.getLevel(),AreaLevelEnum.FIRST_LEVEL.value())){ |
| | | throw new YamiShopBindException("不能改变一级行政地区的级别"); |
| | | } |
| | | if(Objects.equals(areaDb.getLevel(),AreaLevelEnum.SECOND_LEVEL.value()) && !Objects.equals(area.getLevel(),AreaLevelEnum.SECOND_LEVEL.value())){ |
| | | throw new YamiShopBindException("不能改变二级行政地区的级别"); |
| | | } |
| | | hasSameName(area); |
| | | areaService.updateById(area); |
| | | areaService.removeAreaCacheByParentId(null, 1); |
| | | areaService.removeAreaCacheByParentId(area.getParentId(), null); |
| | | areaService.removeAreaListCache(); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @DeleteMapping("/{id}") |
| | | @Operation(summary = "删除" , description = "删除") |
| | | public ServerResponseEntity<Void> delete(@PathVariable Long id) { |
| | | if (areaService.count(new LambdaQueryWrapper<Area>().eq(Area::getParentId,id)) > 0) { |
| | | // 请先删除子地区 |
| | | throw new YamiShopBindException("yami.area.delete"); |
| | | } |
| | | |
| | | Area area = areaService.getById(id); |
| | | if(area==null){ |
| | | throw new YamiShopBindException("地址不存在或已被删除"); |
| | | } |
| | | areaService.removeById(id); |
| | | areaService.removeAreaCacheByParentId(null, 1); |
| | | areaService.removeAreaCacheByParentId(area.getParentId(), null); |
| | | areaService.removeAreaListCache(); |
| | | // 因为获取地址的时候,过滤掉了没有三级地址的一级地址,情况缓存的时候,一级地址也需要清空一下 |
| | | if (Objects.equals(area.getLevel(), AreaLevelEnum.THIRD_LEVEL.value())) { |
| | | areaService.removeAreaCacheByParentId(0L, null); |
| | | } |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @GetMapping("/areaListInfo") |
| | | @Operation(summary = "获取省市信息" , description = "获取省市信息") |
| | | public ServerResponseEntity<List<AreaDto>> getAreaListInfo() { |
| | | return ServerResponseEntity.success(areaService.getAreaListInfo()); |
| | | } |
| | | |
| | | @GetMapping("/listAreaOfEnable") |
| | | @Operation(summary = "获取可用的省市区列表(完整路径)" , description = "获取可用的省市区列表(完整路径)") |
| | | public ServerResponseEntity<List<AreaDto>> listAreaOfEnable() { |
| | | return ServerResponseEntity.success(areaService.listAreaOfEnable()); |
| | | } |
| | | |
| | | @GetMapping("/areaList") |
| | | @Operation(summary = "获取可用的区域省市区信息(四级地址列表)" , description = "获取可用的区域省市区信息") |
| | | public ServerResponseEntity<List<AreaDto>> getAllAreaList() { |
| | | return ServerResponseEntity.success(areaService.getAllAreaList()); |
| | | } |
| | | |
| | | private void hasSameName(Area area) { |
| | | int count = areaService.count(new LambdaQueryWrapper<Area>() |
| | | .eq(Area::getParentId, area.getParentId()) |
| | | .eq(Area::getAreaName, area.getAreaName()) |
| | | .ne(Objects.nonNull(area.getAreaId()) && !Objects.equals(area.getAreaId(), Constant.ZERO_LONG), Area::getAreaId, area.getAreaId()) |
| | | ); |
| | | if (count > 0) { |
| | | throw new YamiShopBindException("该地区已存在"); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.yami.shop.bean.model.AttachFileGroup; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.service.AttachFileGroupService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * @author chendt |
| | | * @date 2021/7/7 17:18 |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/admin/fileGroup") |
| | | @Tag(name = "文件分组") |
| | | public class AttachFileGroupController { |
| | | |
| | | @Autowired |
| | | private AttachFileGroupService attachFileGroupService; |
| | | |
| | | @GetMapping("/list") |
| | | @Operation(summary = "获取列表" , description = "分页获取列表") |
| | | @Parameter(name = "type", description = "文件类型: 1:图片 2:视频 3:文件" ) |
| | | public ServerResponseEntity<List<AttachFileGroup>> list(@RequestParam(value = "type", defaultValue = "1") Integer type) { |
| | | List<AttachFileGroup> attachFileGroupPage = attachFileGroupService.list(Constant.PLATFORM_SHOP_ID,type); |
| | | return ServerResponseEntity.success(attachFileGroupPage); |
| | | } |
| | | |
| | | @GetMapping |
| | | @Operation(summary = "获取" , description = "根据attachFileGroupId获取") |
| | | @Parameter(name = "attachFileGroupId", description = "文件分组id" ) |
| | | public ServerResponseEntity<AttachFileGroup> getByAttachFileGroupId(@RequestParam Long attachFileGroupId) { |
| | | return ServerResponseEntity.success(attachFileGroupService.getByAttachFileGroupId(attachFileGroupId)); |
| | | } |
| | | |
| | | @PostMapping |
| | | @Operation(summary = "保存" , description = "保存") |
| | | public ServerResponseEntity<Void> save(@Valid @RequestBody AttachFileGroup attachFileGroup) { |
| | | attachFileGroup.setAttachFileGroupId(null); |
| | | attachFileGroup.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | attachFileGroupService.saveGroup(attachFileGroup); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping |
| | | @Operation(summary = "更新" , description = "更新") |
| | | public ServerResponseEntity<Void> update(@Valid @RequestBody AttachFileGroup attachFileGroup) { |
| | | attachFileGroup.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | attachFileGroupService.update(attachFileGroup); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @DeleteMapping |
| | | @Operation(summary = "删除" , description = "根据id删除") |
| | | @Parameter(name = "attachFileGroupId", description = "文件分组id" ) |
| | | public ServerResponseEntity<Void> delete(@RequestParam Long attachFileGroupId) { |
| | | AttachFileGroup dbAttachFileGroup = attachFileGroupService.getByAttachFileGroupId(attachFileGroupId); |
| | | if (!Objects.equals(dbAttachFileGroup.getShopId(), Constant.PLATFORM_SHOP_ID)) { |
| | | throw new YamiShopBindException("未授权"); |
| | | } |
| | | attachFileGroupService.deleteById(attachFileGroupId); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.dto.BrandShopDTO; |
| | | import com.yami.shop.bean.dto.BrandSigningDTO; |
| | | import com.yami.shop.bean.model.Brand; |
| | | import com.yami.shop.bean.vo.BrandShopVO; |
| | | import com.yami.shop.bean.vo.BrandSigningVO; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.*; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Parameters; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | |
| | | /** |
| | | * 品牌管理 |
| | | * |
| | | * @author lgh |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/brand") |
| | | @Tag(name = "品牌相关接口") |
| | | public class BrandController { |
| | | |
| | | @Autowired |
| | | private BrandService brandService; |
| | | @Autowired |
| | | private BrandShopService brandShopService; |
| | | @Autowired |
| | | private CategoryService categoryService; |
| | | @Autowired |
| | | private ProductService productService; |
| | | @Autowired |
| | | private CategoryBrandService categoryBrandService; |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "分页获取品牌信息列表" , description = "分页获取品牌信息列表") |
| | | public ServerResponseEntity<IPage<Brand>> page( PageParam<Brand> pageDTO, @ParameterObject Brand brandDTO) { |
| | | brandDTO.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | IPage<Brand> brandPage = brandService.page(pageDTO, brandDTO); |
| | | return ServerResponseEntity.success(brandPage); |
| | | } |
| | | |
| | | @GetMapping("/list") |
| | | @Operation(summary = "获取平台品牌列表(不分页)" , description = "获取平台品牌列表(不分页)") |
| | | public ServerResponseEntity<List<Brand>> list(@ParameterObject Brand brand) { |
| | | brand.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | List<Brand> brandList = brandService.listByParams(brand); |
| | | return ServerResponseEntity.success(brandList); |
| | | } |
| | | |
| | | @GetMapping("/info/{brandId}") |
| | | @Operation(summary = "获取品牌信息" , description = "根据brandId获取品牌信息") |
| | | @Parameter(name = "brandId", description = "品牌id" ) |
| | | public ServerResponseEntity<Brand> getByBrandId(@PathVariable Long brandId) { |
| | | Brand brand = brandService.getInfo(brandId); |
| | | categoryService.getPathNames(brand.getCategories()); |
| | | return ServerResponseEntity.success(brand); |
| | | } |
| | | |
| | | @PostMapping |
| | | @Operation(summary = "保存品牌信息" , description = "保存品牌信息") |
| | | public ServerResponseEntity<Void> save(@Valid @RequestBody Brand brand) { |
| | | brand.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | brandService.saveBrand(brand); |
| | | brandService.removeCache(brand.getCategoryIds()); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping |
| | | @Operation(summary = "更新品牌信息" , description = "更新品牌信息") |
| | | public ServerResponseEntity<Void> update(@Valid @RequestBody Brand brand) { |
| | | if (Objects.isNull(brand.getCategoryIds())) { |
| | | brand.setCategoryIds(new ArrayList<>()); |
| | | } |
| | | List<Long> prodIds = brandService.updateBrand(brand); |
| | | // 清除缓存 |
| | | List<Long> categoryIds = categoryBrandService.getCategoryIdBrandId(brand.getBrandId()); |
| | | categoryIds.addAll(brand.getCategoryIds()); |
| | | productService.removeProductCacheByProdIds(prodIds); |
| | | brandService.removeCache(categoryIds); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @DeleteMapping |
| | | @Operation(summary = "删除品牌信息" , description = "根据品牌信息id删除品牌信息") |
| | | @Parameter(name = "brandId", description = "品牌id" ) |
| | | public ServerResponseEntity<Void> delete(@RequestParam Long brandId) { |
| | | List<Long> prodIds = brandService.deleteById(brandId); |
| | | productService.removeProductCacheByProdIds(prodIds); |
| | | brandService.removeCache(categoryBrandService.getCategoryIdBrandId(brandId)); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping(value = "/updateBrandStatus") |
| | | @Operation(summary = "更新品牌状态(启用或禁用)" , description = "更新品牌状态(启用或禁用)") |
| | | public ServerResponseEntity<Void> updateBrandStatus(@RequestBody Brand brand) { |
| | | if (Objects.isNull(brand.getStatus())) { |
| | | throw new YamiShopBindException("状态不能为空"); |
| | | } |
| | | if (Objects.isNull(brand.getBrandId())) { |
| | | throw new YamiShopBindException("品牌id不能为空"); |
| | | } |
| | | List<Long> prodIds = brandService.updateBrandStatus(brand); |
| | | productService.removeProductCacheByProdIds(prodIds); |
| | | // 清楚缓存 |
| | | List<Long> categoryIds = categoryBrandService.getCategoryIdBrandId(brand.getBrandId()); |
| | | // 获取当前节点所有父节点的分类ids,以及当前分类节点的父级节点的父级几点的分类ids |
| | | List<Long> parentCategoryIds = categoryService.getParentIdsByCategoryId(categoryIds); |
| | | if (CollUtil.isNotEmpty(parentCategoryIds)) { |
| | | categoryIds.addAll(parentCategoryIds); |
| | | } |
| | | brandService.removeCache(CollUtil.isNotEmpty(categoryIds) ? categoryIds : new ArrayList<>()); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @GetMapping("/listSigningByShopId") |
| | | @Operation(summary = "根据店铺id获取签约的品牌列表" , description = "根据店铺id获取签约的品牌列表") |
| | | @Parameters(value = { |
| | | @Parameter(name = "shopId", description = "店铺id" , required = true), |
| | | @Parameter(name = "status", description = "状态 1:启用, 0:禁用" ) |
| | | }) |
| | | public ServerResponseEntity<BrandSigningVO> listSigningByShopId(@RequestParam(value = "shopId") Long shopId, @RequestParam(value = "status", required = false) Integer status) { |
| | | BrandSigningVO brandSigningVO = brandShopService.listSigningByShopId(shopId, status); |
| | | return ServerResponseEntity.success(brandSigningVO); |
| | | } |
| | | |
| | | @GetMapping("/pageSigningByShopId") |
| | | @Operation(summary = "根据店铺id分页获取签约的品牌列表" , description = "根据店铺id分页获取签约的品牌列表") |
| | | public ServerResponseEntity<IPage<BrandShopVO>> pageSigningByShopId(PageParam<BrandShopVO> page, @ParameterObject BrandShopDTO brandShop) { |
| | | IPage<BrandShopVO> brandShopPage = brandShopService.pageSigningByShopId(page, brandShop); |
| | | return ServerResponseEntity.success(brandShopPage); |
| | | } |
| | | |
| | | @PutMapping("/signing") |
| | | @Operation(summary = "根据店铺id更新店铺下的签约品牌" , description = "根据店铺id更新店铺下的签约品牌") |
| | | @Parameter(name = "shopId", description = "店铺id" ) |
| | | public ServerResponseEntity<Void> signingBrands(@RequestBody BrandSigningDTO brandSigningDTO, @RequestParam(value = "shopId") Long shopId) { |
| | | brandShopService.signingBrands(brandSigningDTO, shopId, true); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.service.BrandShopService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Parameters; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.DeleteMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | /** |
| | | * @Author lth |
| | | * @Date 2021/8/23 11:18 |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/brandShop") |
| | | @Tag(name = "签约品牌相关接口") |
| | | public class BrandShopController { |
| | | |
| | | @Autowired |
| | | private BrandShopService brandShopService; |
| | | |
| | | @DeleteMapping |
| | | @Operation(summary = "删除签约品牌" , description = "删除签约品牌") |
| | | @Parameters(value = { |
| | | @Parameter(name = "shopId", description = "店铺id" ), |
| | | @Parameter(name = "brandId", description = "品牌id" ) |
| | | }) |
| | | public ServerResponseEntity<Void> delete(@RequestParam("shopId") Long shopId, @RequestParam("brandId") Long brandId) { |
| | | brandShopService.deleteByShopIdAndBrandId(shopId, brandId); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.app.dto.CategoryDto; |
| | | import com.yami.shop.bean.dto.CategoryShopDTO; |
| | | import com.yami.shop.bean.enums.EsOperationType; |
| | | import com.yami.shop.bean.event.EsProductUpdateEvent; |
| | | import com.yami.shop.bean.model.Category; |
| | | import com.yami.shop.bean.model.CategoryShop; |
| | | import com.yami.shop.bean.model.Product; |
| | | import com.yami.shop.bean.param.ProductExportParam; |
| | | import com.yami.shop.bean.vo.CategoryShopVO; |
| | | import com.yami.shop.common.annotation.SysLog; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.i18n.I18nMessage; |
| | | import com.yami.shop.common.i18n.LanguageEnum; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.platform.config.PlatformConstant; |
| | | import com.yami.shop.service.CategoryExcelService; |
| | | import com.yami.shop.service.CategoryService; |
| | | import com.yami.shop.service.CategoryShopService; |
| | | import com.yami.shop.service.ProductService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Parameters; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import ma.glasnost.orika.MapperFacade; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.context.ApplicationEventPublisher; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import javax.validation.Valid; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | import java.util.stream.Collectors; |
| | | |
| | | |
| | | /** |
| | | * 分类管理 |
| | | * @author lgh |
| | | * |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/prod/category") |
| | | @Tag(name = "分类相关接口") |
| | | public class CategoryController { |
| | | |
| | | @Autowired |
| | | private CategoryService categoryService; |
| | | @Autowired |
| | | private ProductService productService; |
| | | @Autowired |
| | | private CategoryShopService categoryShopService; |
| | | |
| | | @Autowired |
| | | private ApplicationEventPublisher eventPublisher; |
| | | @Autowired |
| | | private MapperFacade mapperFacade; |
| | | @Autowired |
| | | private CategoryExcelService categoryExcelService; |
| | | |
| | | @GetMapping("/info/{categoryId}") |
| | | @Operation(summary = "获取分类信息" , description = "获取分类信息") |
| | | @Parameter(name = "categoryId", description = "分类id" ) |
| | | public ServerResponseEntity<Category> info(@PathVariable("categoryId") Long categoryId){ |
| | | Category category = categoryService.getCategoryByCategoryId(categoryId); |
| | | |
| | | return ServerResponseEntity.success(category); |
| | | } |
| | | |
| | | @SysLog("保存分类") |
| | | @PostMapping |
| | | @PreAuthorize("@pms.hasPermission('prod:category:save')") |
| | | @Operation(summary = "保存分类" , description = "保存分类") |
| | | public ServerResponseEntity<Long> save(@RequestBody Category category){ |
| | | category.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | category.setRecTime(new Date()); |
| | | // int count = categoryService.count(new LambdaQueryWrapper<Category>().eq(Category::getCategoryName, category.getCategoryName()) |
| | | // .eq(Category::getParentId, category.getParentId()).eq(Category::getShopId,Constant.PLATFORM_SHOP_ID)) |
| | | Integer count = categoryService.getCategoryName(category); |
| | | if(count > 0){ |
| | | // 类目名称已存在 |
| | | throw new YamiShopBindException(I18nMessage.getMessage("yami.category.name.exist")); |
| | | } |
| | | category.setGrade(getGradeByParentId(category.getParentId())); |
| | | category.setSuperiorId(-1L); |
| | | // 获取上级的上级 |
| | | if(category.getGrade() == PlatformConstant.MAX_CATEGORY_GRADE) { |
| | | Long superiorId = categoryService.getParentCategoryByParentId(category.getParentId()); |
| | | category.setSuperiorId(superiorId); |
| | | } |
| | | categoryService.saveCategroy(category); |
| | | // 清除缓存 |
| | | removeCategoryCacheByParentId(category); |
| | | return ServerResponseEntity.success(category.getCategoryId()); |
| | | } |
| | | |
| | | @SysLog("更新分类") |
| | | @PutMapping |
| | | @PreAuthorize("@pms.hasPermission('prod:category:update')") |
| | | @Operation(summary = "更新分类" , description = "更新分类") |
| | | public ServerResponseEntity<String> update(@RequestBody Category category){ |
| | | category.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | Category categoryDb = categoryService.getCategoryByCategoryId(category.getCategoryId()); |
| | | if (!Objects.equals(category.getGrade(), categoryDb.getGrade())) { |
| | | throw new YamiShopBindException("不能改变分类层级"); |
| | | } |
| | | |
| | | Integer count = categoryService.getCategoryName(category); |
| | | if(count > 0){ |
| | | // 类目名称已存在 |
| | | throw new YamiShopBindException(I18nMessage.getMessage("yami.category.name.exist")); |
| | | } |
| | | // 如果从下线改成正常,则需要判断上级的状态 |
| | | if (Objects.equals(categoryDb.getStatus(),0) && Objects.equals(category.getStatus(),1) && !Objects.equals(category.getParentId(),0L)){ |
| | | Category parentCategory = categoryService.getOne(new LambdaQueryWrapper<Category>().eq(Category::getCategoryId, category.getParentId())); |
| | | if(Objects.isNull(parentCategory) || Objects.equals(parentCategory.getStatus(),0)){ |
| | | // 修改失败,上级分类不存在或者不为正常状态 |
| | | throw new YamiShopBindException("yami.category.status.check"); |
| | | } |
| | | } |
| | | category.setGrade(getGradeByParentId(category.getParentId())); |
| | | category.setOldCategoryName(categoryDb.getCategoryName()); |
| | | category.setOldCategoryNameEn(categoryDb.getCategoryNameEn()); |
| | | category.setSuperiorId(-1L); |
| | | // 获取上级的上级 |
| | | if(category.getGrade() == PlatformConstant.MAX_CATEGORY_GRADE) { |
| | | Long superiorId = categoryService.getParentCategoryByParentId(category.getParentId()); |
| | | category.setSuperiorId(superiorId); |
| | | } |
| | | categoryService.updateCategroy(category); |
| | | // 清除缓存 |
| | | removeCategoryCacheByParentId(category); |
| | | eventPublisher.publishEvent(new EsProductUpdateEvent(category.getCategoryId(), null, EsOperationType.UPDATE_BY_CATEGORY_ID)); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @SysLog("删除分类") |
| | | @DeleteMapping("/{categoryId}") |
| | | @PreAuthorize("@pms.hasPermission('prod:category:delete')") |
| | | @Operation(summary = "删除分类" , description = "删除分类") |
| | | @Parameter(name = "categoryId", description = "分类id" ) |
| | | public ServerResponseEntity<String> delete(@PathVariable("categoryId") Long categoryId){ |
| | | if (categoryService.count(new LambdaQueryWrapper<Category>().eq(Category::getParentId,categoryId)) >0) { |
| | | // 请删除子分类,再删除该分类 |
| | | return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.category.delete.child")); |
| | | } |
| | | int categoryProdCount = productService.count(new LambdaQueryWrapper<Product>().eq(Product::getCategoryId, categoryId).ne(Product::getStatus, -1)); |
| | | if (categoryProdCount>0){ |
| | | // 该分类下还有商品,请先删除该分类下的商品 |
| | | return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.category.delete.check")); |
| | | } |
| | | Category category = categoryService.getById(categoryId); |
| | | category.setSuperiorId(-1L); |
| | | // 获取上级的上级 |
| | | if(category.getGrade() == PlatformConstant.MAX_CATEGORY_GRADE) { |
| | | Long superiorId = categoryService.getParentCategoryByParentId(category.getParentId()); |
| | | category.setSuperiorId(superiorId); |
| | | } |
| | | categoryService.deleteCategroy(category); |
| | | // 清除缓存 |
| | | removeCategoryCacheByParentId(category); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @GetMapping("/listCategory") |
| | | @Operation(summary = "获取全部分类" , description = "获取全部分类") |
| | | @Parameters(value = { |
| | | @Parameter(name = "maxGrade", description = "0:一级分类,1:二级分类,2:三级分类(后面的包含前面等级的分类)" ), |
| | | @Parameter(name = "status", description = "默认是1,表示正常状态,0为下线状态" ) |
| | | }) |
| | | public ServerResponseEntity<List<Category>> listCategory(@RequestParam(value = "maxGrade", required = false, defaultValue = "2") Integer maxGrade, |
| | | @RequestParam(value = "status", required = false) Integer status) { |
| | | |
| | | List<Category> categories = categoryService.listByLang(I18nMessage.getLang(),maxGrade,null,status,Constant.PLATFORM_SHOP_ID); |
| | | return ServerResponseEntity.success(categories); |
| | | } |
| | | |
| | | @GetMapping("/listCategoryByGrade") |
| | | @Operation(summary = "根据等级与状态获取平台分类列表" , description = "根据等级与状态获取平台分类列表") |
| | | @Parameters(value = { |
| | | @Parameter(name = "grade", description = "0:一级分类,1:二级分类,2:三级分类" ), |
| | | @Parameter(name = "status", description = "默认是1,表示正常状态,0为下线状态" ) |
| | | }) |
| | | public ServerResponseEntity<List<Category>> listCategoryByGrade(@RequestParam(value = "grade", defaultValue = "2") Integer grade, @RequestParam(value = "status", required = false) Integer status) { |
| | | List<Category> categories = categoryService.listByGrade(I18nMessage.getLang(), grade, status, Constant.PLATFORM_SHOP_ID); |
| | | return ServerResponseEntity.success(categories); |
| | | } |
| | | |
| | | @GetMapping("/upAndCurrCategoryList/{categoryId}") |
| | | @Operation(summary = "获取上架分类和当前选中分类的父类" , description = "获取上架分类和当前选中分类的父类") |
| | | @Parameters(value = { |
| | | @Parameter(name = "maxGrade", description = "0:一级分类,1:二级分类,2:三级分类" ), |
| | | @Parameter(name = "categoryId", description = "分类id" ) |
| | | }) |
| | | public ServerResponseEntity<List<Category>> upAndCurrCategoryList( |
| | | @RequestParam(value = "maxGrade", required = false, defaultValue = "2") Integer maxGrade, |
| | | @PathVariable("categoryId") Long categoryId){ |
| | | Category category = new Category(); |
| | | category.setLang(I18nMessage.getDbLang()); |
| | | category.setStatus(1); |
| | | category.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | category.setGrade(maxGrade); |
| | | //获取上架的分类 |
| | | List<Category> upList = categoryService.categoryList(category); |
| | | |
| | | //如果是新增的,直接返回上架的分类即可 |
| | | if (categoryId==0){ |
| | | return ServerResponseEntity.success(upList); |
| | | } |
| | | Category currCategory = categoryService.getCategoryByCategoryId(categoryId); |
| | | if (currCategory == null) { |
| | | return ServerResponseEntity.success(upList); |
| | | } |
| | | while (currCategory.getParentId() != 0) { |
| | | currCategory=categoryService.getCategoryByCategoryId(currCategory.getParentId()); |
| | | if (!Objects.equals(currCategory.getStatus(), 1)) { |
| | | upList.add(currCategory); |
| | | } |
| | | } |
| | | return ServerResponseEntity.success(upList); |
| | | } |
| | | |
| | | private int getGradeByParentId(Long parentId) { |
| | | // 如果上级为id为0,则设置分类等级为0 |
| | | if (Objects.equals(parentId,0L)) { |
| | | return 0; |
| | | } |
| | | Category parentCategory = categoryService.getById(parentId); |
| | | return parentCategory.getGrade() + 1; |
| | | } |
| | | |
| | | @GetMapping("/platformCategory") |
| | | @Operation(summary = "平台可用分类-必须是启用分类且分类下包含启动的三级分类" , description = "平台可用分类-必须是启用分类且分类下包含启动的三级分类") |
| | | public ServerResponseEntity<List<Category>> platformCategory(){ |
| | | List<Category> list = categoryService.platformCategory(); |
| | | return ServerResponseEntity.success(list); |
| | | } |
| | | |
| | | @GetMapping("/signingInfoByShopId") |
| | | @Operation(summary = "获取签约的分类列表(状态参数为空则返回所有)" , description = "获取签约的分类列表(状态参数为空则返回所有)") |
| | | @Parameters(value = { |
| | | @Parameter(name = "shopId", description = "店铺id" ), |
| | | @Parameter(name = "status", description = "签约状态:1:已通过 0待审核 -1未通过" ) |
| | | }) |
| | | public ServerResponseEntity<List<CategoryShopVO>> listSigningByShopId(@RequestParam(value = "shopId") Long shopId, @RequestParam(value = "status", required = false) Integer status) { |
| | | List<CategoryShopVO> categoryShopList = categoryShopService.listSigningCategoryByShopId(shopId, I18nMessage.getLang()); |
| | | if (Objects.nonNull(status)) { |
| | | categoryShopList = categoryShopList.stream().filter(item -> Objects.equals(item.getStatus(), status)).collect(Collectors.toList()); |
| | | } |
| | | return ServerResponseEntity.success(categoryShopList); |
| | | } |
| | | |
| | | @GetMapping("/pageSigningInfo") |
| | | @Operation(summary = "分页获取签约的分类列表" , description = "分页获取签约的分类列表") |
| | | public ServerResponseEntity<IPage<CategoryShopVO>> pageSigningInfo(PageParam<CategoryShopVO> page, @ParameterObject CategoryShopDTO categoryShop) { |
| | | IPage<CategoryShopVO> categoryShopPage = categoryShopService.pageSigningInfo(page, categoryShop); |
| | | return ServerResponseEntity.success(categoryShopPage); |
| | | } |
| | | |
| | | @PutMapping("/signing") |
| | | @Operation(summary = "更新店铺签约分类" , description = "更新店铺签约分类") |
| | | @Parameter(name = "shopId", description = "店铺id" ) |
| | | public ServerResponseEntity<Void> signing(@Valid @RequestBody List<CategoryShop> categoryShopDTOList, @RequestParam(value = "shopId") Long shopId) { |
| | | categoryShopService.signingCategory(categoryShopDTOList, shopId, true); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | private void removeCategoryCacheByParentId(Category category) { |
| | | categoryService.removeListRateCache(); |
| | | categoryService.removeCacheByParentIdAndLang(category.getParentId(), category.getShopId(), LanguageEnum.LANGUAGE_ZH_CN.getLang()); |
| | | categoryService.removeCacheByParentIdAndLang(category.getParentId(), category.getShopId(), LanguageEnum.LANGUAGE_EN.getLang()); |
| | | categoryService.removeCacheByParentIdAndLang(category.getSuperiorId(), category.getShopId(), LanguageEnum.LANGUAGE_ZH_CN.getLang()); |
| | | categoryService.removeCacheByParentIdAndLang(category.getSuperiorId(), category.getShopId(), LanguageEnum.LANGUAGE_EN.getLang()); |
| | | // 如果是2/3级分类,第一分类也需要清空缓存数据 |
| | | if(category.getGrade() == 1 || category.getGrade() == PlatformConstant.MAX_CATEGORY_GRADE) { |
| | | categoryService.removeCacheByParentIdAndLang(Constant.CATEGORY_ID, Constant.PLATFORM_SHOP_ID, LanguageEnum.LANGUAGE_ZH_CN.getLang()); |
| | | categoryService.removeCacheByParentIdAndLang(Constant.CATEGORY_ID, Constant.PLATFORM_SHOP_ID, LanguageEnum.LANGUAGE_EN.getLang()); |
| | | } |
| | | } |
| | | |
| | | @GetMapping("/categoryInfo") |
| | | @Operation(summary = "分类信息列表" , description = "获取所有的产品分类信息,顶级分类的parentId为0,默认为顶级分类") |
| | | @Parameters({ |
| | | @Parameter(name = "parentId", description = "分类ID" ), |
| | | @Parameter(name = "shopId", description = "店铺id" ) |
| | | }) |
| | | public ServerResponseEntity<List<CategoryDto>> categoryInfo(@RequestParam(value = "parentId", defaultValue = "0") Long parentId, |
| | | @RequestParam(value = "shopId", defaultValue = "0") Long shopId) { |
| | | List<Category> categories = categoryService.listByParentIdAndShopId(parentId, shopId, I18nMessage.getDbLang()); |
| | | List<CategoryDto> categoryDtos = mapperFacade.mapAsList(categories, CategoryDto.class); |
| | | return ServerResponseEntity.success(categoryDtos); |
| | | } |
| | | |
| | | @GetMapping("/getCategoryAndParent") |
| | | @Operation(summary = "获取平台分类及所有上级分类" , description = "获取平台分类及所有上级分类") |
| | | public ServerResponseEntity<List<Category>> getCategoryAndParent(@RequestParam(value = "categoryId") Long categoryId){ |
| | | List<Category> categories = categoryService.getCategoryAndParent(categoryId); |
| | | return ServerResponseEntity.success(categories); |
| | | } |
| | | |
| | | @GetMapping("/export") |
| | | @PreAuthorize("@pms.hasPermission('prod:prod:exportProd')") |
| | | @Operation(summary = "导出分类" , description = "导出分类") |
| | | public void export(HttpServletResponse response) { |
| | | categoryExcelService.export(response, Constant.PLATFORM_SHOP_ID); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.service.CategoryShopService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Parameters; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | /** |
| | | * @Author lth |
| | | * @Date 2021/8/23 9:44 |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/categoryShop") |
| | | @Tag(name = "签约分类相关接口") |
| | | public class CategoryShopController { |
| | | |
| | | @Autowired |
| | | private CategoryShopService categoryShopService; |
| | | |
| | | @DeleteMapping |
| | | @Operation(summary = "删除签约分类" , description = "删除签约分类") |
| | | @Parameters(value = { |
| | | @Parameter(name = "shopId", description = "店铺id" ), |
| | | @Parameter(name = "categoryId", description = "分类id" ) |
| | | }) |
| | | public ServerResponseEntity<Void> delete(@RequestParam("shopId") Long shopId, @RequestParam("categoryId") Long categoryId) { |
| | | categoryShopService.delete(shopId, categoryId); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping("updateRate") |
| | | @Operation(summary = "更新自定义扣率" , description = "更新自定义扣率") |
| | | @Parameters(value = { |
| | | @Parameter(name = "shopId", description = "店铺id" ), |
| | | @Parameter(name = "rate", description = "扣率" ) |
| | | }) |
| | | public ServerResponseEntity<Void> updateRate(@RequestParam("shopId") Long shopId, @RequestParam("categoryId") Long categoryId, |
| | | @RequestParam(value = "rate", required = false) Double rate) { |
| | | categoryShopService.updateRate(shopId, categoryId, rate); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.model.CompanyAuditing; |
| | | import com.yami.shop.bean.param.CompanyInfoAuditParam; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.security.platform.util.SecurityUtils; |
| | | import com.yami.shop.service.CompanyAuditingService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import javax.validation.Valid; |
| | | |
| | | |
| | | /** |
| | | * @author chiley |
| | | * @date 2022/9/21 10:23 |
| | | */ |
| | | |
| | | @RestController |
| | | @RequestMapping("/platform/companyAuditing") |
| | | @Tag(name = "审核工商信息接口") |
| | | public class CompanyAuditingController { |
| | | |
| | | @Autowired |
| | | private CompanyAuditingService companyAuditingService; |
| | | |
| | | @GetMapping("/page") |
| | | @PreAuthorize("@pms.hasPermission('shop:companyAuditing:page')") |
| | | @Operation(summary = "分页获取待审核的工商信息" , description = "分页获取待审核的工商信息") |
| | | public ServerResponseEntity<IPage<CompanyAuditing>> getCompanyAuditingPage(PageParam<CompanyAuditing> page, @ParameterObject CompanyInfoAuditParam auditParam) { |
| | | return ServerResponseEntity.success(companyAuditingService.page(page, auditParam)); |
| | | } |
| | | |
| | | @PutMapping("/audit") |
| | | @Operation(summary = "审核签约信息" , description = "审核签约信息") |
| | | @PreAuthorize("@pms.hasPermission('shop:companyAuditing:audit')") |
| | | public ServerResponseEntity<Void> audit(@Valid @RequestBody CompanyAuditing companyAuditing) { |
| | | companyAuditing.setAuditorId(SecurityUtils.getSysUser().getUserId()); |
| | | companyAuditingService.audit(companyAuditing); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @GetMapping("/auditInfo") |
| | | @Operation(summary = "查看申请审核情况" , description = "查看申请审核情况") |
| | | public ServerResponseEntity<CompanyAuditing> auditInfo(@RequestParam("shopId") Long shopId) { |
| | | return ServerResponseEntity.success(companyAuditingService.getAuditInfo(shopId)); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.date.DateField; |
| | | import cn.hutool.core.date.DateTime; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import com.yami.shop.bean.enums.RetainedDateType; |
| | | import com.yami.shop.bean.param.*; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.i18n.I18nMessage; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.Arith; |
| | | import com.yami.shop.common.util.DateParam; |
| | | import com.yami.shop.common.util.DateUtils; |
| | | import com.yami.shop.coupon.common.service.CouponUserService; |
| | | import com.yami.shop.dao.FlowPageAnalyseUserMapper; |
| | | import com.yami.shop.dao.OrderMapper; |
| | | import com.yami.shop.dao.UserExtensionMapper; |
| | | import com.yami.shop.platform.config.PlatformConstant; |
| | | import com.yami.shop.service.*; |
| | | import com.yami.shop.user.common.dao.UserLevelLogMapper; |
| | | import com.yami.shop.user.common.service.UserLevelLogService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.AllArgsConstructor; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static java.util.stream.Collectors.toMap; |
| | | |
| | | /** |
| | | * 顾客分析接口 |
| | | * @author |
| | | */ |
| | | @Tag(name = "客户分析接口") |
| | | @RestController |
| | | @RequestMapping("/platform/customerAnalysis") |
| | | @AllArgsConstructor |
| | | public class CustomerAnalysisController { |
| | | |
| | | private final UserService userService; |
| | | private final UserExtensionService userExtensionService; |
| | | private final UserExtensionMapper userExtensionMapper; |
| | | private final UserLevelLogService userLevelLogService; |
| | | private final UserLevelLogMapper userLevelLogMapper; |
| | | private final OrderDataAnalysisService orderDataAnalysisService; |
| | | private final OrderMapper orderMapper; |
| | | private final CouponUserService couponUserService; |
| | | private final FlowPageAnalyseUserMapper flowPageAnalyseUserMapper; |
| | | private final CustomerAnalysisService customerAnalysisService; |
| | | private final FlowLogService flowLogService; |
| | | private final FlowUserAnalysisService flowUserAnalysisService; |
| | | private final FlowService flowService; |
| | | |
| | | /** |
| | | * 客户分析,客户概况及趋势(会员概览) |
| | | */ |
| | | @Operation(summary = "客户分析,客户概况及趋势" , description = "客户分析,客户概况及趋势") |
| | | @GetMapping("/getCustomerAnalysis") |
| | | public ServerResponseEntity<CustomerRespParam> getCustomerAnalysis(@ParameterObject CustomerReqParam param) { |
| | | Date startTime = param.getStartTime(); |
| | | Date endTime = param.getEndTime(); |
| | | param.setAppId(1); |
| | | // 访客数,统计时间类进入商城的所有访客 |
| | | Integer visitor; |
| | | Integer preVisitor; |
| | | if (Objects.equals(1,param.getDateType())) { |
| | | flowLogService.getFlowLogListByCache(); |
| | | visitor = flowLogService.countAllVisitor(null,startTime,endTime); |
| | | preVisitor = flowLogService.countAllVisitor(endTime,null,null); |
| | | } else { |
| | | visitor = flowPageAnalyseUserMapper.countAllVisitor(param.getEndTime(),null,null); |
| | | preVisitor = visitor; |
| | | } |
| | | // 累积粉丝数 平台为商城所有的用户数;商家端为用户收藏该店铺的人数 |
| | | Integer allPersonNum = userExtensionMapper.countAllPersonNum(param.getEndTime(),null,null,null); |
| | | Integer preAllPersonNum = userExtensionMapper.countAllPersonNum(param.getStartTime(),null,null,null); |
| | | // 累积会员数 |
| | | CustomerRespParam respParam = userService.countUserByParam(param); |
| | | // 成交客户数 |
| | | param.setStartTime(startTime); |
| | | param.setEndTime(endTime); |
| | | CustomerRespParam res = orderDataAnalysisService.countPayNum(param); |
| | | respParam.setPayNum(res.getPayNum()); |
| | | respParam.setPrePayNum(res.getPrePayNum()); |
| | | respParam.setPayNumRate(res.getPayNumRate()); |
| | | respParam.setVisitor(visitor); |
| | | respParam.setPreVisitor(preVisitor); |
| | | respParam.setVisitorRate(divAverage(visitor-preVisitor,preVisitor,4)); |
| | | respParam.setMember(allPersonNum); |
| | | respParam.setPreMember(preAllPersonNum); |
| | | respParam.setMemberRate(divAverage(allPersonNum-preAllPersonNum,preAllPersonNum,4)); |
| | | param.setStartTime(startTime); |
| | | param.setEndTime(endTime); |
| | | List<CustomerPayParam> levelParams = userLevelLogMapper.countGrowthMemberByTime(param); |
| | | respParam.setFashNum(userLevelLogMapper.countPayUserByTime(param)); |
| | | Map<Date, Integer> levelMap = levelParams.stream().collect(toMap(CustomerPayParam::getCreateDate, CustomerPayParam::getNumber)); |
| | | respParam.setCustomerTrend(orderDataAnalysisService.countCustomerParam(param, levelMap)); |
| | | if (Objects.equals(1, param.getDateType())) { |
| | | for (CustomerPayParam customerPayParam : respParam.getCustomerTrend()) { |
| | | customerPayParam.setVisitor(respParam.getVisitor()); |
| | | } |
| | | } |
| | | return ServerResponseEntity.success(respParam); |
| | | } |
| | | |
| | | /** |
| | | * 微信粉丝统计 |
| | | * 累积粉丝数:截至到筛选时间的最后一天,店铺的微信粉丝累积人数 |
| | | * 新增粉丝数: 筛选时间内,新关注的粉丝去重人数 |
| | | * 跑路粉丝数:筛选时间内,取消关注的粉丝去重人数 |
| | | * 净增粉丝数:筛选时间内,实际增长的粉丝人数,新增粉丝数减去跑路粉丝数 |
| | | */ |
| | | @Operation(summary = "微信粉丝统计,暂时不统计" , description = "客户分析,微信粉丝统计") |
| | | @GetMapping("/getCustomerWxFash") |
| | | public ServerResponseEntity<?> getCustomerWxFash(@ParameterObject CustomerReqParam param) { |
| | | // 暂不统计,bbc小程序没有店铺关注的接口,b2c 暂不适用, |
| | | return ServerResponseEntity.success(null); |
| | | } |
| | | |
| | | /** |
| | | * 会员统计 ,商城分成普通会员和付费会员,普通会员注册就是普通会员 |
| | | * 累积会员数:截至到筛选时间的最后一天,店铺的会员累积人数 |
| | | * 新增会员数: 筛选时间内,通过领取会员卡,新成为会员的客户数量 |
| | | * 升级会员数:筛选时间内,通过会员规则升级的会员数量, 一人多次升级记为一人 |
| | | * 储值会员数:筛选时间内,进行储值的会员数量,一人多次储值记为一人。我们商城没有储值设计, |
| | | * 将储值会员数,改为付费会员数 |
| | | */ |
| | | @Operation(summary = "会员统计" , description = "客户分析,会员统计") |
| | | @GetMapping("/getMemberCount") |
| | | public ServerResponseEntity<CustomerMemberRespParam> getMemberCount(@ParameterObject MemberReqParam param) { |
| | | Date startTime = param.getStartTime(); |
| | | Date endTime = param.getEndTime(); |
| | | CustomerMemberRespParam respParam = new CustomerMemberRespParam(); |
| | | // 会员统计 |
| | | CustomerMemberParam res = userLevelLogService.countMemberNum(param); |
| | | respParam.setMemberCount(res); |
| | | // 会员活跃 |
| | | param.setStartTime(startTime); |
| | | param.setEndTime(endTime); |
| | | CustomerMemberLivelyParam memberLivelyParam = getCustomerMemberLively(param); |
| | | memberLivelyParam.setMemberVRate(divAverage(memberLivelyParam.getMemberV(),res.getAccumulate(),4)); |
| | | respParam.setMemberLively(memberLivelyParam); |
| | | return ServerResponseEntity.success(respParam); |
| | | } |
| | | private CustomerMemberLivelyParam getCustomerMemberLively(CustomerReqParam param) { |
| | | CustomerMemberLivelyParam res = new CustomerMemberLivelyParam(); |
| | | List<DateParam> everyDays = DateUtils.findEveryDays(param.getStartTime(), param.getEndTime()); |
| | | param.setDateTime(null); |
| | | Integer num = 0; |
| | | Integer addCartUserNum = 0; |
| | | if(Objects.equals(1,param.getDateType())) { |
| | | num = flowLogService.countUserNum(param.getStartTime(), param.getEndTime()); |
| | | addCartUserNum = flowLogService.countAddCartUserNum(param.getStartTime(), param.getEndTime()); |
| | | } else { |
| | | num = userExtensionMapper.countVisitMemberNum(param.getDateTime(), param.getStartTime(), param.getEndTime()); |
| | | addCartUserNum = flowUserAnalysisService.countAddCartUserNum(param.getStartTime(), param.getEndTime()); |
| | | } |
| | | // 访问会员数 |
| | | res.setMemberV(num); |
| | | Integer allPersonNum = userExtensionMapper.countAllPersonNum(param.getEndTime(), null, null,null); |
| | | res.setMemberVRate(divAverage(res.getMemberV(),allPersonNum,4)); |
| | | // 加购会员数 |
| | | res.setMemberAddCat(addCartUserNum); |
| | | res.setMemberAddCatRate(divAverage(res.getMemberAddCat(),res.getMemberV(),4)); |
| | | // 领券会员数 |
| | | res.setMemberGetCoupon(couponUserService.countMemberGetCoupon(param)); |
| | | res.setMemberGetCouponRate(divAverage(res.getMemberGetCoupon(),res.getMemberV(),4)); |
| | | |
| | | // 成交会员数 |
| | | res.setMemberPay(orderDataAnalysisService.countMemberPayNum(param)); |
| | | res.setMemberPayRate(divAverage(res.getMemberPay(),res.getMemberV(),4)); |
| | | List<CustomerMemberLivelyTrendParam> resList = new ArrayList<>(); |
| | | for (DateParam everyDay : everyDays) { |
| | | CustomerMemberLivelyTrendParam liveParam = new CustomerMemberLivelyTrendParam(); |
| | | param.setStartTime(everyDay.getStartTime()); |
| | | param.setEndTime(everyDay.getEndTime()); |
| | | liveParam.setCurrentDay(DateUtils.dateToStrYmd(param.getEndTime())); |
| | | // 访问会员数、加购会员数 |
| | | if(Objects.equals(1,param.getDateType())) { |
| | | liveParam.setMemberV(num); |
| | | liveParam.setMemberAddCat(addCartUserNum); |
| | | } else { |
| | | liveParam.setMemberV(userExtensionMapper.countVisitMemberNum(null,param.getStartTime(),param.getEndTime())); |
| | | liveParam.setMemberAddCat(userExtensionMapper.countAddCartMemberNum(null,param.getStartTime(),param.getEndTime())); |
| | | } |
| | | // 领券会员数 |
| | | liveParam.setMemberGetCoupon(couponUserService.countMemberGetCoupon(param)); |
| | | // 成交会员数 |
| | | liveParam.setMemberPay(orderDataAnalysisService.countMemberPayNum(param)); |
| | | resList.add(liveParam); |
| | | } |
| | | res.setMemberLivelyTrend(resList); |
| | | return res; |
| | | } |
| | | |
| | | /** |
| | | * 客户分析,成交客户分析 |
| | | */ |
| | | @Operation(summary = "客户分析,成交客户分析" , description = "客户分析,成交客户分析") |
| | | @GetMapping("/getCustomerDeal") |
| | | public ServerResponseEntity<CustomerDealRespParam> getCustomerDeal(@ParameterObject CustomerReqParam param) { |
| | | CustomerDealRespParam res = orderDataAnalysisService.getCustomerDeal(param); |
| | | return ServerResponseEntity.success(res); |
| | | } |
| | | |
| | | /** |
| | | * 客户分析,客户留存分析 |
| | | */ |
| | | @Operation(summary = "客户分析,客户留存分析" , description = "客户分析,客户留存分析,不做周留存数据") |
| | | @GetMapping("/getCustomerRetained") |
| | | public ServerResponseEntity<List<CustomerRetainRespParam>> refreshRetainedData(@ParameterObject CustomerRetainedReqParam param) { |
| | | Integer dateType = param.getDateType(); |
| | | Integer dateRetainType = param.getDateRetainType(); |
| | | List<CustomerRetainRespParam> respParam = new ArrayList<>(); |
| | | if (Objects.equals(1,dateType) && !Objects.equals(1,dateRetainType)) { |
| | | // 最近一月,月留存。此时不显示数据 |
| | | return ServerResponseEntity.success(respParam); |
| | | } |
| | | Integer retainType = param.getRetainType(); |
| | | if (Objects.equals(1,retainType)) { |
| | | // 访问留存 |
| | | respParam = getVisitRetained(param); |
| | | } else if (Objects.equals(PlatformConstant.TWO,retainType)) { |
| | | // 成交留存 |
| | | respParam = getTradeRetained(param); |
| | | } |
| | | return ServerResponseEntity.success(respParam); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 客户分析,客户留存分析 |
| | | */ |
| | | @Operation(summary = "客户分析,客户留存分析,刷新数据缓存" , description = "刷新数据缓存,重新拉取数据") |
| | | @GetMapping("/refreshRetainedData") |
| | | public ServerResponseEntity<List<CustomerRetainRespParam>> refreshRetainedData() { |
| | | flowService.refreshRetainedData(); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | private List<CustomerRetainRespParam> getVisitRetained(CustomerRetainedReqParam param) { |
| | | // 访问留存,包含未注册了的用户访问留存数 |
| | | List<CustomerRetainRespParam> list = flowUserAnalysisService.getVisitRetained(param); |
| | | list = retainedAnalysis(list, param); |
| | | return list; |
| | | } |
| | | |
| | | private List<CustomerRetainRespParam> getTradeRetained(CustomerRetainedReqParam param) { |
| | | List<CustomerRetainRespParam> list = orderDataAnalysisService.getTradeRetained(param); |
| | | list = retainedAnalysis(list, param); |
| | | return list; |
| | | } |
| | | |
| | | private List<CustomerRetainRespParam> retainedAnalysis(List<CustomerRetainRespParam> list,CustomerRetainedReqParam param) { |
| | | // 不在sql中统计了,在代码中来计算留存率 |
| | | // 因为最多就统计一年的留存数据,最多12行数据 |
| | | // 保留位数 |
| | | int scale = 2; |
| | | // 放大倍数 |
| | | Integer percentage = 100; |
| | | int size = list.size(); |
| | | int avgNewCustomers = 0; |
| | | int avgFirstMonthRemain = 0; |
| | | int avgSecondMonthRemain = 0; |
| | | int avgThirdMonthRemain = 0; |
| | | int avgFourthMonthRemain = 0; |
| | | int avgFifthMonthRemain = 0; |
| | | int avgSixthMonthRemain = 0; |
| | | // 可能有一些不存在的数据 |
| | | List<String> rangeDate = getRangeDate(param.getStartTime(), param.getEndTime()); |
| | | List<String> collect = list.stream().map(CustomerRetainRespParam::getCurrentMonth).collect(Collectors.toList()); |
| | | rangeDate.removeAll(collect); |
| | | if (CollUtil.isNotEmpty(rangeDate)) { |
| | | // 初始化未有新增月份的情况 |
| | | List<CustomerRetainRespParam> customerRetainRespParams = initCustomerRetain(rangeDate); |
| | | list.addAll(customerRetainRespParams); |
| | | list = list.stream().sorted(Comparator.comparing(CustomerRetainRespParam::getCurrentMonth)).collect(Collectors.toList()); |
| | | } |
| | | for (CustomerRetainRespParam customerRetain : list) { |
| | | Integer newCustomers = customerRetain.getNewCustomers(); |
| | | avgNewCustomers += newCustomers; |
| | | Integer firstMonthRemain = customerRetain.getFirstMonthRemain(); |
| | | avgFirstMonthRemain += firstMonthRemain; |
| | | customerRetain.setFirstMonthRemainRate(Arith.calculatePercentage(firstMonthRemain,newCustomers,scale, percentage)); |
| | | Integer secondMonthRemain = customerRetain.getSecondMonthRemain(); |
| | | avgSecondMonthRemain += secondMonthRemain; |
| | | customerRetain.setSecondMonthRemainRate(Arith.calculatePercentage(secondMonthRemain,newCustomers,scale, percentage)); |
| | | Integer thirdMonthRemain = customerRetain.getThirdMonthRemain(); |
| | | avgThirdMonthRemain += thirdMonthRemain; |
| | | customerRetain.setThirdMonthRemainRate(Arith.calculatePercentage(thirdMonthRemain,newCustomers,scale, percentage)); |
| | | Integer fourthMonthRemain = customerRetain.getFourthMonthRemain(); |
| | | avgFourthMonthRemain += fourthMonthRemain; |
| | | customerRetain.setFourthMonthRemainRate(Arith.calculatePercentage(fourthMonthRemain,newCustomers,scale, percentage)); |
| | | Integer fifthMonthRemain = customerRetain.getFifthMonthRemain(); |
| | | avgFifthMonthRemain += fifthMonthRemain; |
| | | customerRetain.setFifthMonthRemainRate(Arith.calculatePercentage(fifthMonthRemain,newCustomers,scale, percentage)); |
| | | Integer sixthMonthRemain = customerRetain.getSixthMonthRemain(); |
| | | avgSixthMonthRemain += sixthMonthRemain; |
| | | customerRetain.setSixthMonthRemainRate(Arith.calculatePercentage(sixthMonthRemain,newCustomers,scale, percentage)); |
| | | } |
| | | |
| | | // 平均留存率 |
| | | CustomerRetainRespParam avgCustomerRetain = new CustomerRetainRespParam(); |
| | | avgNewCustomers = ceil(avgNewCustomers,size); |
| | | avgCustomerRetain.setCurrentMonth(I18nMessage.getMessage("yami.average.retention.rate")); |
| | | avgCustomerRetain.setNewCustomers(avgNewCustomers); |
| | | avgCustomerRetain.setFirstMonthRemain(ceil(avgFirstMonthRemain,size)); |
| | | avgCustomerRetain.setFirstMonthRemainRate(Arith.calculatePercentage(avgCustomerRetain.getFirstMonthRemain(),avgNewCustomers,scale, percentage)); |
| | | avgCustomerRetain.setSecondMonthRemain(ceil(avgSecondMonthRemain,size)); |
| | | avgCustomerRetain.setSecondMonthRemainRate(Arith.calculatePercentage(avgCustomerRetain.getSecondMonthRemain(),avgNewCustomers,scale, percentage)); |
| | | avgCustomerRetain.setThirdMonthRemain(ceil(avgThirdMonthRemain,size)); |
| | | avgCustomerRetain.setThirdMonthRemainRate(Arith.calculatePercentage(avgCustomerRetain.getThirdMonthRemain(),avgNewCustomers,scale, percentage)); |
| | | avgCustomerRetain.setFourthMonthRemain(ceil(avgFourthMonthRemain,size)); |
| | | avgCustomerRetain.setFourthMonthRemainRate(Arith.calculatePercentage(avgCustomerRetain.getFourthMonthRemain(),avgNewCustomers,scale, percentage)); |
| | | avgCustomerRetain.setFifthMonthRemain(ceil(avgFifthMonthRemain,size)); |
| | | avgCustomerRetain.setFifthMonthRemainRate(Arith.calculatePercentage(avgCustomerRetain.getFifthMonthRemain(),avgNewCustomers,scale, percentage)); |
| | | avgCustomerRetain.setSixthMonthRemain(ceil(avgSixthMonthRemain,size)); |
| | | avgCustomerRetain.setSixthMonthRemainRate(Arith.calculatePercentage(avgCustomerRetain.getSixthMonthRemain(),avgNewCustomers,scale, percentage)); |
| | | list.add(avgCustomerRetain); |
| | | return list; |
| | | } |
| | | |
| | | private List<CustomerRetainRespParam> initCustomerRetain(List<String> rangeDate) { |
| | | if (CollUtil.isEmpty(rangeDate)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | List<CustomerRetainRespParam> list = new ArrayList<>(); |
| | | BigDecimal zero = new BigDecimal("0"); |
| | | for (String date : rangeDate) { |
| | | CustomerRetainRespParam customerRetainRespParam = new CustomerRetainRespParam(); |
| | | customerRetainRespParam.setCurrentMonth(date); |
| | | customerRetainRespParam.setNewCustomers(0); |
| | | customerRetainRespParam.setFirstMonthRemain(0); |
| | | customerRetainRespParam.setFirstMonthRemainRate(zero); |
| | | customerRetainRespParam.setSecondMonthRemain(0); |
| | | customerRetainRespParam.setSecondMonthRemainRate(zero); |
| | | customerRetainRespParam.setThirdMonthRemain(0); |
| | | customerRetainRespParam.setThirdMonthRemainRate(zero); |
| | | customerRetainRespParam.setFourthMonthRemain(0); |
| | | customerRetainRespParam.setFourthMonthRemainRate(zero); |
| | | customerRetainRespParam.setFifthMonthRemain(0); |
| | | customerRetainRespParam.setFifthMonthRemainRate(zero); |
| | | customerRetainRespParam.setSixthMonthRemain(0); |
| | | customerRetainRespParam.setSixthMonthRemainRate(zero); |
| | | list.add(customerRetainRespParam); |
| | | } |
| | | return list; |
| | | } |
| | | |
| | | private List<String> getRangeDate(Date startTime, Date endTime) { |
| | | List<DateTime> dateTimes = DateUtil.rangeToList(DateUtil.beginOfMonth(startTime), endTime, DateField.MONTH); |
| | | List<String> list = new ArrayList<>(); |
| | | for (DateTime dateTime : dateTimes) { |
| | | list.add(DateUtil.format(dateTime,"yyyy-MM")); |
| | | } |
| | | // 控制月在最近 3 、6、 12个月 |
| | | int size = list.size(); |
| | | boolean isReduce = size == RetainedDateType.THREE_MONTH.getMonthNum() + 1 || |
| | | size == RetainedDateType.SIX_MONTH.getMonthNum() + 1 || |
| | | size == RetainedDateType.ONE_YEAR.getMonthNum() + 1; |
| | | if (isReduce) { |
| | | list.remove(list.get(0)); |
| | | } |
| | | return list; |
| | | } |
| | | |
| | | /** |
| | | * @param a dividend |
| | | * @param b divisor |
| | | * @return 向上取整 |
| | | */ |
| | | private int ceil(int a, int b) { |
| | | if (a==0 || b==0) { |
| | | return 0; |
| | | } |
| | | BigDecimal dividend = new BigDecimal(Integer.toString(a)); |
| | | BigDecimal divisor = new BigDecimal(Integer.toString(b)); |
| | | BigDecimal divide = dividend.divide(divisor,0,BigDecimal.ROUND_UP); |
| | | return divide.intValue(); |
| | | } |
| | | |
| | | |
| | | // ------------------------------------------------------------------------------------------------ |
| | | // 客户洞察 |
| | | |
| | | /** |
| | | * 客户洞察,RFM模型分析 |
| | | */ |
| | | @Operation(summary = "客户洞察,RFM模型分析" , description = "客户洞察,RFM模型分析") |
| | | @GetMapping("/getCustomerRFM") |
| | | public ServerResponseEntity<List<CustomerRFMRespParam>> getCustomerRfm(@ParameterObject CustomerRFMReqParam param) { |
| | | Date recentTime = param.getRecentTime(); |
| | | if (Objects.isNull(recentTime)) { |
| | | // 请选择起止时间 |
| | | throw new YamiShopBindException("yami.form.time.check"); |
| | | } |
| | | List<CustomerRFMRespParam> list = orderDataAnalysisService.countPayNumRfm(param); |
| | | return ServerResponseEntity.success(list); |
| | | } |
| | | /** |
| | | * 客户洞察,RFM模型分析 |
| | | * 目前设计是只统计最近两年时间的数据 |
| | | */ |
| | | @Operation(summary = "客户洞察,RFM模型分析" , description = "客户洞察,RFM模型分析,直接返回表格数据,最最后一行合计行除外") |
| | | @GetMapping("/getCustomerRFMSecond") |
| | | public ServerResponseEntity<List<CustomerRFMRespTableParam>> getCustomerRfmSecond(@ParameterObject CustomerRFMReqParam param) { |
| | | Date recentTime = param.getRecentTime(); |
| | | if (Objects.isNull(recentTime)) { |
| | | // 请选择起止时间 |
| | | throw new YamiShopBindException("yami.form.time.check"); |
| | | } |
| | | List<CustomerRFMRespTableParam> dateList = orderDataAnalysisService.countPayNumRfm2(param); |
| | | |
| | | //最后一行的统计数据 |
| | | CustomerRFMRespTableParam statistics = new CustomerRFMRespTableParam(); |
| | | statistics.setRecencyName("列合计"); |
| | | //Map<recency(消费时间), CustomerRFMRespTableParam> |
| | | List<CustomerRFMRespTableParam> list = new ArrayList<>(); |
| | | Map<Integer, List<CustomerRFMRespTableParam>> collect = dateList.stream().filter(a->!Objects.equals(a.getRecency(), 6)).collect(Collectors.groupingBy(CustomerRFMRespTableParam::getRecency)); |
| | | String[] recencyNameArray = {"","R<=30","30<R<=90","90<R<=180","180<R<=365","R > 365"}; |
| | | Integer userNum = 0; |
| | | Double amount = 0.0; |
| | | for (int i=1;i <= PlatformConstant.FIVE;i++){ |
| | | CustomerRFMRespTableParam customer = new CustomerRFMRespTableParam(); |
| | | customer.setRecencyName(recencyNameArray[i]); |
| | | if(collect.containsKey(i)){ |
| | | List<CustomerRFMRespTableParam> customerRfmRespTableList = collect.get(i); |
| | | for (CustomerRFMRespTableParam rfm:customerRfmRespTableList) { |
| | | calculation(statistics, customer, rfm); |
| | | userNum += rfm.getUserNum(); |
| | | amount = Arith.add(amount,rfm.getAmount()); |
| | | } |
| | | } |
| | | list.add(customer); |
| | | } |
| | | //最后一列的数据统计 |
| | | statistics.setPayBuyersTotal(userNum); |
| | | statistics.setPayAmountTotal(amount); |
| | | statistics.setPriceSingle1(divAverage(statistics.getPayAmount1(),statistics.getPayBuyers1(),2)); |
| | | statistics.setPriceSingle2(divAverage(statistics.getPayAmount2(),statistics.getPayBuyers2(),2)); |
| | | statistics.setPriceSingle3(divAverage(statistics.getPayAmount3(),statistics.getPayBuyers3(),2)); |
| | | statistics.setPriceSingle4(divAverage(statistics.getPayAmount4(),statistics.getPayBuyers4(),2)); |
| | | statistics.setPriceSingle5(divAverage(statistics.getPayAmount5(),statistics.getPayBuyers5(),2)); |
| | | list.add(statistics); |
| | | for (CustomerRFMRespTableParam tableParam : list) { |
| | | tableParam.setPayBuyers1Rate(divAverage(tableParam.getPayBuyers1(),tableParam.getPayBuyersTotal(),4)); |
| | | tableParam.setPayBuyers2Rate(divAverage(tableParam.getPayBuyers2(),tableParam.getPayBuyersTotal(),4)); |
| | | tableParam.setPayBuyers3Rate(divAverage(tableParam.getPayBuyers3(),tableParam.getPayBuyersTotal(),4)); |
| | | tableParam.setPayBuyers4Rate(divAverage(tableParam.getPayBuyers4(),tableParam.getPayBuyersTotal(),4)); |
| | | tableParam.setPayBuyers5Rate(divAverage(tableParam.getPayBuyers5(),tableParam.getPayBuyersTotal(),4)); |
| | | tableParam.setPayBuyersTotalRate(divAverage(tableParam.getPayBuyersTotal(),userNum,4)); |
| | | tableParam.setPriceSingleTotal(divAverage(tableParam.getPayAmountTotal(),tableParam.getPayBuyersTotal(),2)); |
| | | } |
| | | return ServerResponseEntity.success(list); |
| | | } |
| | | |
| | | private void calculation(CustomerRFMRespTableParam statistics, CustomerRFMRespTableParam customer, CustomerRFMRespTableParam rfm) { |
| | | Integer frequency = rfm.getFrequency(); |
| | | if (frequency == 1) { |
| | | customer.setPayBuyers1(rfm.getUserNum()); |
| | | customer.setPayAmount1(rfm.getAmount()); |
| | | customer.setPriceSingle1(divAverage(customer.getPayAmount1(),customer.getPayBuyers1(),2)); |
| | | statistics.setPayBuyers1(statistics.getPayBuyers1() + rfm.getUserNum()); |
| | | statistics.setPayAmount1(Arith.add(statistics.getPayAmount1(), rfm.getAmount())); |
| | | } else if (frequency == PlatformConstant.TWO) { |
| | | customer.setPayBuyers2(rfm.getUserNum()); |
| | | customer.setPayAmount2(rfm.getAmount()); |
| | | customer.setPriceSingle2(divAverage(customer.getPayAmount2(),customer.getPayBuyers2(),2)); |
| | | statistics.setPayBuyers2(statistics.getPayBuyers2() + rfm.getUserNum()); |
| | | statistics.setPayAmount2(Arith.add(statistics.getPayAmount2(), rfm.getAmount())); |
| | | } else if (frequency == PlatformConstant.THREE) { |
| | | customer.setPayBuyers3(rfm.getUserNum()); |
| | | customer.setPayAmount3(rfm.getAmount()); |
| | | customer.setPriceSingle3(divAverage(customer.getPayAmount3(),customer.getPayBuyers3(),2)); |
| | | statistics.setPayBuyers3(statistics.getPayBuyers3() + rfm.getUserNum()); |
| | | statistics.setPayAmount3(Arith.add(statistics.getPayAmount3(), rfm.getAmount())); |
| | | } else if (frequency == PlatformConstant.FOUR) { |
| | | customer.setPayBuyers4(rfm.getUserNum()); |
| | | customer.setPayAmount4(rfm.getAmount()); |
| | | customer.setPriceSingle4(divAverage(customer.getPayAmount4(),customer.getPayBuyers4(),2)); |
| | | statistics.setPayBuyers4(statistics.getPayBuyers4() + rfm.getUserNum()); |
| | | statistics.setPayAmount4(Arith.add(statistics.getPayAmount4(), rfm.getAmount())); |
| | | } else { |
| | | customer.setPayBuyers5(rfm.getUserNum()); |
| | | customer.setPayAmount5(rfm.getAmount()); |
| | | customer.setPriceSingle5(divAverage(customer.getPayAmount5(),customer.getPayBuyers5(),2)); |
| | | statistics.setPayBuyers5(statistics.getPayBuyers5() + rfm.getUserNum()); |
| | | statistics.setPayAmount5(Arith.add(statistics.getPayAmount5(), rfm.getAmount())); |
| | | } |
| | | customer.setPayBuyersTotal(customer.getPayBuyersTotal() + rfm.getUserNum()); |
| | | customer.setPayAmountTotal(Arith.add(customer.getPayAmountTotal(), rfm.getAmount())); |
| | | } |
| | | |
| | | /** |
| | | * 客户洞察,消费能力分析 |
| | | */ |
| | | @Operation(summary = "客户洞察,消费能力分析" , description = "客户洞察,消费能力分析") |
| | | @GetMapping("/getConsumePower") |
| | | public ServerResponseEntity<CustomerConsumeRespParam> getConsumePower(@ParameterObject CustomerConsumeReqParam param) { |
| | | CustomerConsumeRespParam respParam = orderDataAnalysisService.getConsumePower(param); |
| | | return ServerResponseEntity.success(respParam); |
| | | } |
| | | /** |
| | | * 客户洞察,消费频次分析 |
| | | */ |
| | | @Operation(summary = "客户洞察,消费频次分析" , description = "客户洞察,消费频次分析") |
| | | @GetMapping("/getConsumeFrequency") |
| | | public ServerResponseEntity<CustomerConsumeRespParam> getConsumeFrequency(@ParameterObject CustomerConsumeReqParam param) { |
| | | CustomerConsumeRespParam respParam = orderDataAnalysisService.getConsumeFrequency(param); |
| | | return ServerResponseEntity.success(respParam); |
| | | } |
| | | |
| | | /** |
| | | * 客户洞察,回购周期分析 |
| | | */ |
| | | @Operation(summary = "客户洞察,回购周期分析" , description = "客户洞察,回购周期分析") |
| | | @GetMapping("/getConsumeRepurchaseCount") |
| | | public ServerResponseEntity<CustomerRepurchaseRespParam> getConsumeRepurchaseCount(@ParameterObject CustomerConsumeReqParam param) { |
| | | CustomerRepurchaseRespParam respParam = orderDataAnalysisService.getConsumeRepurchaseCount(param); |
| | | return ServerResponseEntity.success(respParam); |
| | | } |
| | | // ----------------------------------------------------------------------------------------------- |
| | | // 会员分析 CustomerReqParam |
| | | /** |
| | | * 会员分析,会员概况 |
| | | */ |
| | | @Operation(summary = "会员分析,会员概况" , description = "会员分析,会员概况") |
| | | @GetMapping("/getMemberSurvey") |
| | | public ServerResponseEntity<MemberSurveyRespParam> getMemberSurvey(@ParameterObject MemberReqParam param) { |
| | | MemberSurveyRespParam customerRespParam = customerAnalysisService.generalize(param); |
| | | // MemberSurveyRespParam res = getMemberAnalysisSurvey(param); |
| | | customerRespParam.setMemberOverviewModelList(getMemberAnalysisSurvey(param)); |
| | | return ServerResponseEntity.success(customerRespParam); |
| | | } |
| | | |
| | | private List<MemberOverviewListParam> getMemberAnalysisSurvey(MemberReqParam param) { |
| | | Date startTime = param.getStartTime(); |
| | | Date endTime = param.getEndTime(); |
| | | List<DateParam> everyDays = DateUtils.findEveryDays(startTime,endTime); |
| | | MemberSurveyRespParam respParam = new MemberSurveyRespParam(); |
| | | MemberOverviewParam resParam = new MemberOverviewParam(); |
| | | List<MemberOverviewListParam> resList = new ArrayList<>(); |
| | | if (Objects.isNull(param.getMemberType())){ |
| | | param.setMemberType(0); |
| | | } |
| | | if (everyDays.size() == 1 ) { |
| | | Date beforeDate = DateUtils.getBeforeDate(everyDays.get(0).getStartTime()); |
| | | everyDays = DateUtils.findEveryDays(beforeDate, param.getEndTime()); |
| | | } |
| | | for (DateParam everyDay : everyDays) { |
| | | MemberOverviewListParam res = new MemberOverviewListParam(); |
| | | // 累积会员数 |
| | | param.setDateTime(everyDay.getEndTime()); |
| | | res.setCurrentDay(DateUtils.dateToNumber(everyDay.getEndTime())); |
| | | res.setTotalMember(userExtensionMapper.countMemberByParam(param)); |
| | | // 新增会员数 |
| | | param.setDateTime(everyDay.getStartTime()); |
| | | Integer preAccumulate = userExtensionMapper.countMemberByParam(param); |
| | | res.setNewMember(res.getTotalMember() - preAccumulate); |
| | | // 支付会员数,再筛选时间内,购买商品的会员人数 |
| | | param.setDateTime(null); |
| | | param.setStartTime(everyDay.getStartTime()); |
| | | param.setEndTime(everyDay.getEndTime()); |
| | | res.setPayMember(orderMapper.countPaidMemberByParam(param,null)); |
| | | // 领券会员数 |
| | | res.setCouponMember(couponUserService.countMemberCouponByParam(param)); |
| | | // 会员支付金额 |
| | | res.setMemberPayAmount(handleDouble(orderMapper.countMemberPaidAmount(param))); |
| | | // 会员支付订单数 |
| | | res.setMemberPayOrder(orderMapper.countMemberPayOrder(param)); |
| | | // 会员客单价 |
| | | Integer payMemberNum = orderMapper.countPayMemberNum(param); |
| | | res.setMemberSingleAmount(divAverage(res.getMemberPayAmount(),payMemberNum,2)); |
| | | resList.add(res); |
| | | } |
| | | return resList; |
| | | // respParam.setMemberOverviewModelList(resList); |
| | | // MemberOverviewListParam first = resList.get(0); |
| | | // MemberOverviewListParam last = resList.get(resList.size() - 1); |
| | | // resParam.setCurrentDay(DateUtils.dateToNumber(endTime)); |
| | | // resParam.setTotalMember(last.getTotalMember()); |
| | | // resParam.setTotalMemberRate(divAverage(last.getTotalMember()-first.getTotalMember(),first.getTotalMember(),4)); |
| | | // resParam.setNewMember(last.getNewMember()); |
| | | // resParam.setNewMemberRate(divAverage(last.getNewMember(),first.getNewMember(),4)); |
| | | // // |
| | | // param.setDateTime(endTime); |
| | | // param.setStartTime(null); |
| | | // resParam.setPayMember(orderMapper.countPaidMemberByParam(param)); |
| | | // // 会员支付金额 |
| | | // resParam.setMemberPayAmount(handleDouble(orderMapper.countMemberPaidAmount(param))); |
| | | // // 领券会员数 |
| | | // resParam.setCouponMember(couponUserService.countMemberCouponByParam(param)); |
| | | // // 会员支付订单数 |
| | | // resParam.setMemberPayOrder(orderMapper.countMemberPayOrder(param)); |
| | | // // 会员客单价 |
| | | // Integer payMemberNum = orderMapper.countPayMemberNum(param); |
| | | // resParam.setMemberSingleAmount(divAverage(resParam.getMemberPayAmount(),payMemberNum,2)); |
| | | // |
| | | // param.setDateTime(startTime); |
| | | // Integer prePayMember = orderMapper.countPaidMemberByParam(param); |
| | | // Double prePaidAmount = handleDouble(orderMapper.countMemberPaidAmount(param)); |
| | | // Integer preMemberCoupon = couponUserService.countMemberCouponByParam(param); |
| | | // Integer prePayOrder = orderMapper.countMemberPayOrder(param); |
| | | // Integer payMemberNum1 = orderMapper.countPayMemberNum(param); |
| | | // resParam.setPayMemberRate(divAverage(resParam.getPayMember()-prePayMember,prePayMember,4)); |
| | | // resParam.setMemberPayAmountRate(divAverage(Arith.sub(resParam.getMemberPayAmount(),prePaidAmount),prePaidAmount,4)); |
| | | // resParam.setCouponMemberRate(divAverage(resParam.getCouponMember()-preMemberCoupon,preMemberCoupon,4)); |
| | | // resParam.setMemberPayOrderRate(divAverage(resParam.getMemberPayOrder()-prePayOrder,prePayOrder,4)); |
| | | // resParam.setMemberSingleAmountRate(divAverage(payMemberNum1-payMemberNum,payMemberNum,4)); |
| | | // respParam.setMemberOverviewModel(resParam); |
| | | // return respParam; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 会员分析,会员升级分析 |
| | | */ |
| | | @Operation(summary = "会员分析,会员升级分析" , description = "会员分析,会员升级分析") |
| | | @GetMapping("/getGrowthMember") |
| | | public ServerResponseEntity<List<MemberGrowthDetailParam>> getGrowthMember(@ParameterObject MemberGrowthReqParam param) { |
| | | List<MemberGrowthDetailParam> res = userLevelLogMapper.countGrowthMemberByParam(param); |
| | | if (CollectionUtils.isEmpty(res)) { |
| | | return ServerResponseEntity.success(null); |
| | | } |
| | | Integer total = res.stream().collect(Collectors.summingInt(MemberGrowthDetailParam::getMemberNum)); |
| | | |
| | | for (MemberGrowthDetailParam re : res) { |
| | | re.setRate(divAverage(re.getMemberNum(),total,4)); |
| | | } |
| | | return ServerResponseEntity.success(res); |
| | | } |
| | | |
| | | /** |
| | | * // bbc平台/b2c商家 接口 |
| | | * 会员分析,会员人数趋势/ 会员占比趋势 |
| | | */ |
| | | @Operation(summary = "会员分析,会员人数趋势/ 会员占比趋势" , description = "会员分析,会员人数趋势/ 会员占比趋势") |
| | | @GetMapping("/getMemberTrend") |
| | | public ServerResponseEntity<List<MemberTrendRespParam>> getMemberTrend(@ParameterObject MemberReqParam param) { |
| | | // 筛选时间类的每一天注册的会员数数据,不是每一天平台的总会员数 |
| | | List<MemberTrendRespParam> respParam = userExtensionService.getMemberTrend(param); |
| | | return ServerResponseEntity.success(respParam); |
| | | } |
| | | |
| | | /** |
| | | * // bbc平台/b2c商家 接口 |
| | | * 会员分析,会员贡献价值分析 |
| | | */ |
| | | @Operation(summary = "会员分析,会员贡献价值分析" , description = "会员分析,会员贡献价值分析") |
| | | @GetMapping("/getMemberContributeValue") |
| | | public ServerResponseEntity<MemberContributeRespParam> getMemberContributeValue(@ParameterObject MemberReqParam param) { |
| | | MemberContributeRespParam respParam = orderDataAnalysisService.getMemberContributeValue(param); |
| | | return ServerResponseEntity.success(respParam); |
| | | } |
| | | |
| | | /** |
| | | * // bbc平台/b2c商家 接口 |
| | | * 会员分析,新老会员成交分析 |
| | | */ |
| | | @GetMapping("/getMemberDeal") |
| | | @Operation(summary = "会员分析,新老会员成交分析" , description = "会员分析,新老会员成交分析") |
| | | public ServerResponseEntity<MemberDealRespParam> getMemberDeal(@ParameterObject MemberReqParam param) { |
| | | MemberDealRespParam respParam = orderDataAnalysisService.getMemberDeal(param); |
| | | return ServerResponseEntity.success(respParam); |
| | | } |
| | | |
| | | private Double handleDouble(Double value){ |
| | | if (Objects.isNull(value)){ |
| | | return 0.0; |
| | | } |
| | | return value; |
| | | } |
| | | |
| | | private Double divAverage(Double a, Integer b, Integer scale) { |
| | | if (Objects.isNull(b) || b == 0 || Objects.isNull(a)) { |
| | | return 0.0; |
| | | } |
| | | return Arith.div(a, b, scale); |
| | | } |
| | | private Double divAverage(Double a, Double b, Integer scale) { |
| | | if (Objects.isNull(b) || b == 0 || Objects.isNull(a)) { |
| | | return 0.0; |
| | | } |
| | | return Arith.div(a, b, scale); |
| | | } |
| | | private Double divAverage(Integer a, Integer b,Integer scale) { |
| | | if (Objects.isNull(b) || b == 0 || Objects.isNull(a)) { |
| | | return 0.0; |
| | | } |
| | | return Arith.div(a,b,scale); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.yami.shop.bean.model.Delivery; |
| | | import com.yami.shop.common.enums.StatusEnum; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.DeliveryService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.util.ObjectUtils; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | |
| | | /** |
| | | * 物流公司 |
| | | * |
| | | * @author LGH |
| | | * @date 2019-10-29 11:42:24 |
| | | */ |
| | | @RestController |
| | | @AllArgsConstructor |
| | | @RequestMapping("/platform/delivery") |
| | | @Tag(name = "物流公司") |
| | | public class DeliveryController { |
| | | |
| | | private final DeliveryService deliveryService; |
| | | |
| | | @GetMapping("/page") |
| | | @PreAuthorize("@pms.hasPermission('platform:delivery:page')") |
| | | @Operation(summary = "分页查询" , description = "分页查询") |
| | | public ServerResponseEntity<IPage<Delivery>> getDeliveryPage(PageParam<Delivery> page, @ParameterObject Delivery delivery) { |
| | | return ServerResponseEntity.success(deliveryService.page(page, new LambdaQueryWrapper<Delivery>() |
| | | .eq(!ObjectUtils.isEmpty(delivery.getDvyId()), Delivery::getDvyId, delivery.getDvyId()) |
| | | .like(StrUtil.isNotBlank(delivery.getDvyName()), Delivery::getDvyName, delivery.getDvyName()) |
| | | .like(StrUtil.isNotBlank(delivery.getDvyNo()), Delivery::getDvyNo, delivery.getDvyNo()) |
| | | .like(StrUtil.isNotBlank(delivery.getDvyNoHd()), Delivery::getDvyNoHd, delivery.getDvyNoHd()) |
| | | .gt(Delivery::getStatus, StatusEnum.DELETE.value()) |
| | | )); |
| | | } |
| | | |
| | | |
| | | @GetMapping("/info/{dvyId}") |
| | | @Operation(summary = "查询物流公司信息" , description = "查询物流公司信息") |
| | | @Parameter(name = "dvyId", description = "物流id" ) |
| | | public ServerResponseEntity<Delivery> getById(@PathVariable("dvyId") Long dvyId) { |
| | | return ServerResponseEntity.success(deliveryService.getById(dvyId)); |
| | | } |
| | | |
| | | @PostMapping |
| | | @PreAuthorize("@pms.hasPermission('platform:delivery:save')") |
| | | @Operation(summary = "新增物流公司" , description = "新增物流公司") |
| | | public ServerResponseEntity<Boolean> save(@RequestBody @Valid Delivery delivery) { |
| | | delivery.setRecTime(new Date()); |
| | | delivery.setModifyTime(new Date()); |
| | | List<Delivery> deliveryList = deliveryService.list(new LambdaQueryWrapper<Delivery>().eq(Delivery::getDvyName, delivery.getDvyName())); |
| | | if (CollUtil.isNotEmpty(deliveryList)) { |
| | | // 物流名称不能重复 |
| | | throw new YamiShopBindException("yami.platform.delivery.name.repeat"); |
| | | } |
| | | return ServerResponseEntity.success(deliveryService.save(delivery)); |
| | | } |
| | | |
| | | @PutMapping |
| | | @PreAuthorize("@pms.hasPermission('platform:delivery:update')") |
| | | @Operation(summary = "修改物流公司信息" , description = "修改物流公司信息") |
| | | public ServerResponseEntity<Boolean> updateById(@RequestBody @Valid Delivery delivery) { |
| | | delivery.setModifyTime(new Date()); |
| | | delivery.setQueryUrl(null); |
| | | List<Delivery> deliveryList = deliveryService.list(new LambdaQueryWrapper<Delivery>().eq(Delivery::getDvyName, delivery.getDvyName()) |
| | | .ne(Delivery::getDvyId, delivery.getDvyId())); |
| | | if (CollUtil.isNotEmpty(deliveryList)) { |
| | | // 物流名称不能重复 |
| | | throw new YamiShopBindException("yami.platform.delivery.name.repeat"); |
| | | } |
| | | boolean updateRes = deliveryService.update(delivery, Wrappers.lambdaUpdate(Delivery.class) |
| | | .eq(Delivery::getDvyId, delivery.getDvyId()) |
| | | .gt(Delivery::getStatus, StatusEnum.DELETE.value()) |
| | | ); |
| | | if (!updateRes) { |
| | | throw new YamiShopBindException("修改失败,当前物流公司信息可能已经被删除"); |
| | | } |
| | | return ServerResponseEntity.success(Boolean.TRUE); |
| | | } |
| | | |
| | | @DeleteMapping("/{dvyId}") |
| | | @PreAuthorize("@pms.hasPermission('platform:delivery:delete')") |
| | | @Operation(summary = "删除物流公司" , description = "删除物流公司") |
| | | @Parameter(name = "dvyId", description = "物流id" ) |
| | | public ServerResponseEntity<Boolean> removeById(@PathVariable Long dvyId) { |
| | | // 逻辑删除 |
| | | deliveryService.update(Wrappers.lambdaUpdate(Delivery.class) |
| | | .set(Delivery::getStatus, StatusEnum.DELETE.value()) |
| | | .eq(Delivery::getDvyId, dvyId) |
| | | ); |
| | | return ServerResponseEntity.success(Boolean.TRUE); |
| | | } |
| | | |
| | | @GetMapping("/list") |
| | | @Operation(summary = "获取物流公司列表" , description = "获取物流公司列表") |
| | | public ServerResponseEntity<List<Delivery>> page() { |
| | | List<Delivery> list = deliveryService.list(Wrappers.lambdaQuery(Delivery.class) |
| | | .eq(Delivery::getStatus, StatusEnum.ENABLE.value()) |
| | | ); |
| | | return ServerResponseEntity.success(list); |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.model.CdnDeviceRelease; |
| | | import com.yami.shop.bean.model.Device; |
| | | import com.yami.shop.bean.param.DeviceIncomeParam; |
| | | import com.yami.shop.bean.param.TypeParam; |
| | | import com.yami.shop.common.annotation.SysLog; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.DeviceService; |
| | | import com.yami.shop.service.QRCodeService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import javax.validation.Valid; |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | @RestController |
| | | @RequestMapping("/device") |
| | | @Tag(name = "设备库存接口") |
| | | public class DeviceController { |
| | | |
| | | @Autowired |
| | | private DeviceService deviceService; |
| | | |
| | | @Autowired |
| | | private QRCodeService cdnService; |
| | | |
| | | /** |
| | | * 分页查询 |
| | | * @param page 分页对象 |
| | | * @param device |
| | | * @return 分页数据 |
| | | */ |
| | | @GetMapping("/page" ) |
| | | @Operation(summary = "分页查询" , description = "分页查询") |
| | | public ServerResponseEntity<IPage<Device>> getPurchaseProdPage(PageParam<Device> page, @ParameterObject Device device) { |
| | | IPage<Device> deviceIPage = deviceService.pageDevice(page, device); |
| | | return ServerResponseEntity.success(deviceIPage); |
| | | } |
| | | |
| | | /** |
| | | * 设备分类(店铺分类) |
| | | * @return |
| | | */ |
| | | @GetMapping("/deviceType" ) |
| | | @Operation(summary = "设备分类" , description = "设备分类") |
| | | public ServerResponseEntity<List<TypeParam>> deviceType() { |
| | | List<TypeParam> list = deviceService.selectdeviceTypeList(); |
| | | return ServerResponseEntity.success(list); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 用户扫码激活设备 |
| | | * @return |
| | | */ |
| | | // @GetMapping("/qrcodeBind" ) |
| | | // @Operation(summary = "用户扫码激活设备" , description = "用户扫码激活设备") |
| | | // public ServerResponseEntity<?> qrcodeBind(@RequestParam("sn") String sn) { |
| | | // return cdnService.qrcodeBind(sn); |
| | | // } |
| | | |
| | | |
| | | @Operation(summary = "导入设备文件" , description = "导入设备文件") |
| | | @PostMapping("/exportDeviceExcel") |
| | | @ResponseBody |
| | | public ServerResponseEntity<String> exportDeviceExcel(@RequestParam("deviceExcelFile") MultipartFile deviceExcelFile) throws Exception { |
| | | if (Objects.isNull(deviceExcelFile)) { |
| | | throw new YamiShopBindException("yami.network.busy"); |
| | | } |
| | | List<Device> list = new ArrayList<>(); |
| | | String errorMsg = deviceService.exportOrderExcel(deviceExcelFile, list); |
| | | if (Objects.nonNull(errorMsg)) { |
| | | return ServerResponseEntity.success(errorMsg); |
| | | } |
| | | return ServerResponseEntity.success("导入成功!"); |
| | | } |
| | | |
| | | @GetMapping(value = "/downloadModel") |
| | | @Operation(summary = "下载设备导入模板" , description = "下载设备导入模板") |
| | | public void downloadModel(HttpServletResponse response) { |
| | | deviceService.downloadModel(response); |
| | | } |
| | | |
| | | /** |
| | | * 通过id查询 |
| | | * @param id |
| | | * @return 单个数据 |
| | | */ |
| | | @GetMapping("/info/{id}" ) |
| | | @Operation(summary = "通过id查询" , description = "通过id查询") |
| | | public ServerResponseEntity<Device> getById(@PathVariable("id") Long id) { |
| | | Device device = deviceService.getById(id); |
| | | if (device != null) { |
| | | CdnDeviceRelease cdnDevice =deviceService.selectSnById(id); |
| | | if(cdnDevice != null){ |
| | | device.setSn(cdnDevice.getSn()); |
| | | } |
| | | } |
| | | return ServerResponseEntity.success(device); |
| | | } |
| | | |
| | | /** |
| | | * 新增 |
| | | * @param device |
| | | * @return 是否新增成功 |
| | | */ |
| | | @SysLog("新增" ) |
| | | @PostMapping |
| | | @Operation(summary = "新增" , description = "新增") |
| | | public ServerResponseEntity<?> save(@RequestBody Device device) { |
| | | deviceService.saveDevice(device); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | /** |
| | | * 修改 |
| | | * @param device |
| | | * @return 是否修改成功 |
| | | */ |
| | | @SysLog("修改" ) |
| | | @PutMapping |
| | | @Operation(summary = "修改" , description = "修改") |
| | | public ServerResponseEntity<?> updateById(@RequestBody @Valid Device device) { |
| | | device.setUpdateTime(new Date()); |
| | | return ServerResponseEntity.success(deviceService.updateById(device)); |
| | | } |
| | | |
| | | /** |
| | | * 通过id删除 |
| | | * @param id |
| | | * @return 是否删除成功 |
| | | */ |
| | | @SysLog("删除" ) |
| | | @DeleteMapping("/{id}" ) |
| | | @Operation(summary = "通过id删除" , description = "通过id删除") |
| | | public ServerResponseEntity<?> removeById(@PathVariable Long id) { |
| | | deviceService.deleteById(id); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | /** |
| | | * 绑定设备 |
| | | * @param cdnDeviceRelease |
| | | * @return |
| | | */ |
| | | @GetMapping("/setSnDevice" ) |
| | | @Operation(summary = "绑定设备" , description = "绑定设备") |
| | | public ServerResponseEntity<?> setSnDevice(@ParameterObject CdnDeviceRelease cdnDeviceRelease) { |
| | | deviceService.setSnDevice(cdnDeviceRelease); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | /** |
| | | * 设备实际收益 |
| | | * @return |
| | | */ |
| | | @GetMapping("/selectSnDeviceIncome" ) |
| | | @Operation(summary = "设备实际收益" , description = "设备实际收益") |
| | | public ServerResponseEntity<IPage<DeviceIncomeParam>> selectSnDeviceIncome(PageParam<DeviceIncomeParam> page,@ParameterObject DeviceIncomeParam param) { |
| | | return ServerResponseEntity.success(deviceService.selectSnDeviceIncome(page,param)); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 托管设备撤销 |
| | | * @param sn |
| | | * @return |
| | | */ |
| | | @GetMapping("/setDeviceRepeal" ) |
| | | @Operation(summary = "SN托管设备撤销" , description = "托管设备撤销") |
| | | public ServerResponseEntity<?> setDeviceRepeal(@ParameterObject String sn) { |
| | | return ServerResponseEntity.success(deviceService.setDeviceRepeal(sn)); |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.service.DeviceProfitLogService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | @RestController |
| | | @RequestMapping("/deviceIncome") |
| | | @Tag(name = "设备收益日志接口") |
| | | public class DeviceProfitLogController { |
| | | @Autowired |
| | | private DeviceProfitLogService deviceProfitLogService; |
| | | |
| | | @PostMapping("/excute") |
| | | public ServerResponseEntity<Integer> excute(){ |
| | | return deviceProfitLogService.excute(); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import cn.hutool.core.io.FileUtil; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.model.AttachFile; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.config.ShopConfig; |
| | | import com.yami.shop.service.AttachFileService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 文件上传 controller |
| | | * @author lgh |
| | | * |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/admin/file") |
| | | @Tag(name = "文件上传") |
| | | public class FileController { |
| | | |
| | | @Autowired |
| | | private AttachFileService attachFileService; |
| | | @Autowired |
| | | private ShopConfig shopConfig; |
| | | |
| | | @PostMapping("/upload/element") |
| | | @Operation(summary = "视频上传" , description = "视频上传") |
| | | public ServerResponseEntity<Long> uploadElementFile(@RequestParam("file") MultipartFile file) throws IOException{ |
| | | if(file.isEmpty()){ |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | AttachFile attachFile = new AttachFile(); |
| | | //视频上传 |
| | | attachFile.setType(2); |
| | | attachFile.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | attachFile.setUploadTime(new Date()); |
| | | Long fileId = attachFileService.mpUploadFile(file.getBytes(),file.getOriginalFilename(),attachFile); |
| | | return ServerResponseEntity.success(fileId); |
| | | } |
| | | |
| | | /** |
| | | * 上传聊天时的文件 |
| | | * @param file |
| | | * @return |
| | | * @throws IOException |
| | | */ |
| | | @PostMapping("/upload/imFile") |
| | | @Operation(summary = "图片上传(返回图片名)" , description = "图片上传(返回图片名)") |
| | | public ServerResponseEntity<String> uploadImFile(@RequestParam("file") MultipartFile file) throws IOException{ |
| | | if(file.isEmpty()){ |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | AttachFile attachFile = new AttachFile(); |
| | | attachFile.setFileType(FileUtil.extName(file.getOriginalFilename())); |
| | | attachFile.setFileName(FileUtil.mainName(file.getOriginalFilename())); |
| | | attachFile.setType(1); |
| | | attachFile.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | attachFile.setUploadTime(new Date()); |
| | | String fileName = attachFileService.uploadImFile(file.getBytes(),file.getOriginalFilename()); |
| | | return ServerResponseEntity.success(fileName); |
| | | } |
| | | |
| | | @PostMapping("/upload/img") |
| | | @Operation(summary = "图片上传(返回文件id)" , description = "图片上传(返回文件id)") |
| | | public ServerResponseEntity<Long> uploadImg(@RequestParam("file") MultipartFile file) throws IOException{ |
| | | if(file.isEmpty()){ |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | AttachFile attachFile = new AttachFile(); |
| | | String extName = FileUtil.extName(file.getOriginalFilename()); |
| | | attachFile.setFileType(extName); |
| | | attachFile.setFileName(FileUtil.mainName(file.getOriginalFilename())); |
| | | attachFile.setType(1); |
| | | attachFile.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | attachFile.setUploadTime(new Date()); |
| | | Long fileId = attachFileService.uploadImg(file.getBytes(),attachFile,extName); |
| | | return ServerResponseEntity.success(fileId); |
| | | } |
| | | |
| | | @PostMapping("/upload/tinymceEditor") |
| | | @Operation(summary = "上传文件(返回文件名)" , description = "上传文件(返回文件名)") |
| | | public ServerResponseEntity<String> uploadTinymceEditorImages(@RequestParam("editorFile") MultipartFile editorFile) throws IOException{ |
| | | String fileName = attachFileService.uploadFile(editorFile.getBytes(),editorFile.getOriginalFilename()); |
| | | return ServerResponseEntity.success(shopConfig.getDomain().getResourcesDomainName() + "/" + fileName); |
| | | } |
| | | |
| | | @GetMapping("/attachFilePage") |
| | | @Operation(summary = "分页获取文件" , description = "分页获取文件") |
| | | public ServerResponseEntity<IPage<AttachFile>> attachFilePage(PageParam<AttachFile> page, @ParameterObject AttachFile attachFile) { |
| | | attachFile.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | IPage<AttachFile> attachFilePage = attachFileService.getPage(page,attachFile); |
| | | |
| | | return ServerResponseEntity.success(attachFilePage); |
| | | } |
| | | |
| | | @DeleteMapping("/deleteFile/{fileId}") |
| | | @Operation(summary = "删除文件" , description = "删除文件") |
| | | @Parameter(name = "fileId", description = "文件id" ) |
| | | public ServerResponseEntity<Void> deleteFile(@PathVariable("fileId") Long fileId){ |
| | | AttachFile attachFile = attachFileService.getById(fileId); |
| | | attachFileService.deleteFile(attachFile.getFilePath()); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping("/updateFile") |
| | | @Operation(summary = "更改图片名称" , description = "更改图片名称") |
| | | public ServerResponseEntity<Boolean> updateFile(@RequestBody AttachFile attachFile) { |
| | | if (Objects.isNull(attachFile.getFileName())){ |
| | | // 图片名称不能为空 |
| | | throw new YamiShopBindException("yami.img.name.exist"); |
| | | } |
| | | attachFile.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | return ServerResponseEntity.success(attachFileService.updateFile(attachFile)); |
| | | } |
| | | |
| | | @DeleteMapping("/deleteByIds") |
| | | @Operation(summary = "根据文件id列表批量删除文件记录" , description = "根据文件id列表批量删除文件记录") |
| | | @Parameter(name = "ids", description = "文件id列表" ) |
| | | public ServerResponseEntity<Void> deleteByIds(@RequestBody List<Long> ids) { |
| | | Long shopId = Constant.PLATFORM_SHOP_ID; |
| | | attachFileService.deleteByIdsAndShopId(ids, shopId); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping("/batchMove") |
| | | @Operation(summary = "根据文件id列表与分组id批量移动文件" , description = "根据文件id列表与分组id批量移动文件") |
| | | public ServerResponseEntity<Void> batchMove(@RequestBody AttachFile attachFile) { |
| | | Long shopId = Constant.PLATFORM_SHOP_ID; |
| | | attachFileService.batchMoveByShopIdAndIdsAndGroupId(shopId, attachFile); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.yami.shop.bean.dto.FlowAnalysisDto; |
| | | import com.yami.shop.bean.dto.SystemDto; |
| | | import com.yami.shop.bean.param.FlowAnalysisParam; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.service.FlowUserAnalysisExcelService; |
| | | import com.yami.shop.service.FlowUserAnalysisService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.util.List; |
| | | |
| | | |
| | | /** |
| | | * @author lgh on 2018/11/26. |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/flowAnalysis") |
| | | @Tag(name = "流量概况") |
| | | public class FlowAnalysisController { |
| | | |
| | | @Autowired |
| | | private FlowUserAnalysisService flowUserAnalysisService; |
| | | |
| | | @Autowired |
| | | private FlowUserAnalysisExcelService flowUserAnalysisExcelService; |
| | | |
| | | @GetMapping("/getAnalysisData") |
| | | @Operation(summary = "流量总览" , description = "流量总览") |
| | | public ServerResponseEntity<FlowAnalysisDto> getAnalysisData(@ParameterObject FlowAnalysisParam flowAnalysisParam) { |
| | | //获取开始和结束时间 |
| | | flowAnalysisParam.setTime(1); |
| | | FlowAnalysisDto flowAnalysisDto = flowUserAnalysisService.getFlowAnalysisData(flowAnalysisParam); |
| | | return ServerResponseEntity.success(flowAnalysisDto); |
| | | } |
| | | |
| | | @GetMapping("/analysisDataExport") |
| | | @PreAuthorize("@pms.hasPermission('flow:data:export')") |
| | | @Operation(summary = "导出流量总览" , description = "导出流量总览") |
| | | public void analysisDataExport(@ParameterObject FlowAnalysisParam flowAnalysisParam, HttpServletResponse response) { |
| | | //获取开始和结束时间 |
| | | flowAnalysisParam.setTime(1); |
| | | flowUserAnalysisExcelService.analysisDataExport(flowAnalysisParam, response); |
| | | } |
| | | |
| | | @GetMapping("/flowTrend") |
| | | @Operation(summary = "流量趋势" , description = "流量趋势") |
| | | public ServerResponseEntity<List<FlowAnalysisDto>> flowTrend(@ParameterObject FlowAnalysisParam flowAnalysisParam) { |
| | | // 获取开始和结束时间 |
| | | flowAnalysisParam.setTime(2); |
| | | List<FlowAnalysisDto> flowAnalysisDtoList = flowUserAnalysisService.flowTrend(flowAnalysisParam); |
| | | return ServerResponseEntity.success(flowAnalysisDtoList); |
| | | } |
| | | |
| | | |
| | | @GetMapping("/flowTrendExport") |
| | | @PreAuthorize("@pms.hasPermission('flow:trend:export')") |
| | | @Operation(summary = "导出流量趋势" , description = "导出流量趋势") |
| | | public void flowTrendExport(@ParameterObject FlowAnalysisParam flowAnalysisParam, HttpServletResponse response) { |
| | | //获取开始和结束时间 |
| | | flowAnalysisParam.setTime(2); |
| | | flowUserAnalysisExcelService.flowTrendExport(flowAnalysisParam, response); |
| | | } |
| | | |
| | | @GetMapping("/flowSour") |
| | | @Operation(summary = "成交转换" , description = "成交转换") |
| | | public ServerResponseEntity<List<FlowAnalysisDto>> flowSour(@ParameterObject FlowAnalysisParam flowAnalysisParam) { |
| | | flowAnalysisParam.setTime(1); |
| | | List<FlowAnalysisDto> flowAnalysisDtoList = flowUserAnalysisService.flowSour(flowAnalysisParam); |
| | | return ServerResponseEntity.success(flowAnalysisDtoList); |
| | | } |
| | | |
| | | |
| | | @GetMapping("/flowSourExport") |
| | | @PreAuthorize("@pms.hasPermission('flow:sour:export')") |
| | | @Operation(summary = "导出成交转换" , description = "导出成交转换") |
| | | public void flowSourExport(@ParameterObject FlowAnalysisParam flowAnalysisParam, HttpServletResponse response) { |
| | | //获取开始和结束时间 |
| | | flowAnalysisParam.setTime(1); |
| | | flowUserAnalysisExcelService.flowSour(flowAnalysisParam, response); |
| | | } |
| | | |
| | | @GetMapping("/systemTypeNums") |
| | | @Operation(summary = "系统访客数量" , description = "系统访客数量") |
| | | public ServerResponseEntity<SystemDto> systemTypeNums(@ParameterObject FlowAnalysisParam flowAnalysisParam) { |
| | | flowAnalysisParam.setTime(1); |
| | | SystemDto systemDto = flowUserAnalysisService.systemTypeNums(flowAnalysisParam); |
| | | return ServerResponseEntity.success(systemDto); |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.yami.shop.bean.dto.flow.CustomerRetainedDTO; |
| | | import com.yami.shop.bean.dto.flow.MemberReqDTO; |
| | | import com.yami.shop.bean.vo.flow.*; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.service.CustomerAnalysisService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 顾客分析接口 |
| | | * @author |
| | | */ |
| | | @Tag(name = "顾客分析接口") |
| | | @RestController("flowCustomerAnalysisController") |
| | | @RequestMapping("/platform/flowCustomerAnalysis") |
| | | public class FlowCustomerAnalysisController { |
| | | |
| | | @Autowired |
| | | private CustomerAnalysisService customerAnalysisService; |
| | | |
| | | |
| | | /** |
| | | * 会员分析,会员概况 |
| | | */ |
| | | @Operation(summary = "会员分析,会员概况" , description = "会员分析,会员概况") |
| | | @GetMapping("/getMemberSurvey") |
| | | public ServerResponseEntity<MemberSurveyRespVO> getMemberSurvey(@ParameterObject MemberReqDTO param) { |
| | | MemberSurveyRespVO memberSurveyRespVO = customerAnalysisService.getMemberSurvey(param); |
| | | return ServerResponseEntity.success(memberSurveyRespVO); |
| | | } |
| | | |
| | | /** |
| | | * // bbc平台/b2c商家 接口 |
| | | * 会员分析,会员人数趋势/ 会员占比趋势 |
| | | */ |
| | | @Operation(summary = "会员分析,会员人数趋势/ 会员占比趋势" , description = "会员分析,会员人数趋势/ 会员占比趋势") |
| | | @GetMapping("/getMemberTrend") |
| | | public ServerResponseEntity<List<MemberTrendRespVO>> getMemberTrend(@ParameterObject MemberReqDTO param) { |
| | | List<MemberTrendRespVO> resList = customerAnalysisService.getMemberTrend(param); |
| | | return ServerResponseEntity.success(resList); |
| | | } |
| | | |
| | | /** |
| | | * // bbc平台/b2c商家 接口 |
| | | * 导出会员分析,会员人数趋势 |
| | | */ |
| | | @Operation(summary = "导出导出会员分析,会员人数趋势/ 会员占比趋势" , description = "导出会员分析,会员人数趋势/ 会员占比趋势") |
| | | @GetMapping("/memberTrendExport") |
| | | @PreAuthorize("@pms.hasPermission('member:analysis:export')") |
| | | public void memberTrendExport(@ParameterObject MemberReqDTO param, HttpServletResponse response) { |
| | | customerAnalysisService.memberTrendExport(param, response); |
| | | } |
| | | |
| | | /** |
| | | * // bbc平台/b2c商家 接口 |
| | | * 会员分析,会员贡献价值分析 |
| | | */ |
| | | @Operation(summary = "会员分析,会员贡献价值分析" , description = "会员分析,会员贡献价值分析") |
| | | @GetMapping("/getMemberVontributeValue") |
| | | public ServerResponseEntity<MemberContributeRespVO> getMemberContributeValue(@ParameterObject MemberReqDTO param) { |
| | | MemberContributeRespVO contributeRespVO = customerAnalysisService.getMemberContributeValue(param); |
| | | return ServerResponseEntity.success(contributeRespVO); |
| | | } |
| | | |
| | | /** |
| | | * // bbc平台/b2c商家 接口 |
| | | * 会员分析,新老会员成交分析 |
| | | */ |
| | | @GetMapping("/getMemberDeal") |
| | | @Operation(summary = "会员分析,新老会员成交分析" , description = "会员分析,新老会员成交分析") |
| | | public ServerResponseEntity<MemberDealRespVO> getMemberDeal(@ParameterObject MemberReqDTO param) { |
| | | MemberDealRespVO respParam = customerAnalysisService.getMemberDeal(param); |
| | | return ServerResponseEntity.success(respParam); |
| | | } |
| | | |
| | | /** |
| | | * 客户分析,客户留存分析 |
| | | */ |
| | | @Operation(summary = "客户分析-客户留存分析" , description = "客户分析,客户留存分析,不做周留存数据") |
| | | @GetMapping("/getCustomerRetained") |
| | | public ServerResponseEntity<List<CustomerRetainVO>> getCustomerRetained(@ParameterObject CustomerRetainedDTO customerRetainedDTO) { |
| | | Integer dateType = customerRetainedDTO.getDateType(); |
| | | Integer dateRetainType = customerRetainedDTO.getDateRetainType(); |
| | | List<CustomerRetainVO> respList = new ArrayList<>(); |
| | | if (Objects.equals(1,dateType) && !Objects.equals(1,dateRetainType)) { |
| | | // 最近一月,月留存。此时不显示数据 |
| | | return ServerResponseEntity.success(respList); |
| | | } |
| | | Integer retainType = customerRetainedDTO.getRetainType(); |
| | | respList = customerAnalysisService.getTradeRetained(customerRetainedDTO); |
| | | // if (Objects.equals(1,retainType)) { |
| | | // // 访问留存 |
| | | // respList = customerAnalysisService.getVisitRetained(customerRetainedDTO); |
| | | // } else { |
| | | // // 成交留存 |
| | | // } |
| | | return ServerResponseEntity.success(respList); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.dto.PageAnalysisDto; |
| | | import com.yami.shop.bean.param.FlowAnalysisParam; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.FlowPageAnalysisService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | |
| | | /** |
| | | * @author lgh on 2018/11/26. |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/flowPageAnalysis") |
| | | @Tag(name = "流量页面分析") |
| | | public class FlowPageAnalysisController { |
| | | |
| | | @Autowired |
| | | private FlowPageAnalysisService flowPageAnalysisService; |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "分页获取页面统计数据" , description = "分页获取页面统计数据") |
| | | public ServerResponseEntity<IPage<PageAnalysisDto>> page(PageParam<PageAnalysisDto> page, @ParameterObject FlowAnalysisParam flowAnalysisParam) { |
| | | return ServerResponseEntity.success(flowPageAnalysisService.getPageOrProdAnalysis(page, flowAnalysisParam)); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.yami.shop.bean.dto.SankeyDto; |
| | | import com.yami.shop.bean.param.FlowRouteAnalysisParam; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.service.FlowRouteAnalysisService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | |
| | | /** |
| | | * @author lgh on 2018/11/26. |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/flowRouteAnalysis") |
| | | @Tag(name = "用户访问路径") |
| | | public class FlowRouteAnalysisController { |
| | | |
| | | @Autowired |
| | | private FlowRouteAnalysisService flowRouteAnalysisService; |
| | | |
| | | @GetMapping("/getRoutData") |
| | | @Operation(summary = "分页获取用户访问路径数据" , description = "分页获取用户访问路径数据") |
| | | public ServerResponseEntity<FlowRouteAnalysisParam> getRoutData(@ParameterObject FlowRouteAnalysisParam flowRouteAnalysisParam) { |
| | | flowRouteAnalysisParam.setTime(); |
| | | SankeyDto sankeyDto = flowRouteAnalysisService.getRoutData(flowRouteAnalysisParam); |
| | | flowRouteAnalysisParam.setSankeyDto(sankeyDto); |
| | | return ServerResponseEntity.success(flowRouteAnalysisParam); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import cn.hutool.core.date.DateUtil; |
| | | import com.yami.shop.bean.dto.FlowAnalysisDto; |
| | | import com.yami.shop.bean.param.FlowAnalysisParam; |
| | | import com.yami.shop.bean.param.FlowUserAnalysisParam; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.platform.config.FlowUserAnalysisType; |
| | | import com.yami.shop.service.FlowUserAnalysisExcelService; |
| | | import com.yami.shop.service.FlowUserAnalysisService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.util.Date; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * @author lgh on 2018/11/26. |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/flowUserAnalysis") |
| | | @Tag(name = "用户数据分析") |
| | | public class FlowUserAnalysisController { |
| | | |
| | | @Autowired |
| | | private FlowUserAnalysisService flowUserAnalysisService; |
| | | |
| | | @Autowired |
| | | private FlowUserAnalysisExcelService flowUserAnalysisExcelService; |
| | | |
| | | @GetMapping("/getUserAnalysisData") |
| | | @Operation(summary = "获取会员分析数据" , description = "获取会员分析数据") |
| | | public ServerResponseEntity<FlowUserAnalysisParam> getUserAnalysisData(@ParameterObject FlowUserAnalysisParam flowUserAnalysisParam) { |
| | | handleTime(flowUserAnalysisParam); |
| | | flowUserAnalysisService.getUserAnalysisData(flowUserAnalysisParam); |
| | | return ServerResponseEntity.success(flowUserAnalysisParam); |
| | | } |
| | | |
| | | |
| | | @GetMapping("/userAnalysisDataExport") |
| | | @PreAuthorize("@pms.hasPermission('user:analysis:data:export')") |
| | | @Operation(summary = "导出会员分析数据-地图" , description = "导出会员分析数据-地图") |
| | | public void userAnalysisDataExport(@ParameterObject FlowUserAnalysisParam flowUserAnalysisParam, HttpServletResponse response) { |
| | | handleTime(flowUserAnalysisParam); |
| | | flowUserAnalysisExcelService.userAnalysisDataExport(flowUserAnalysisParam, response); |
| | | } |
| | | |
| | | private void handleTime(FlowUserAnalysisParam flowUserAnalysisParam) { |
| | | Integer type = flowUserAnalysisParam.getType(); |
| | | if (!Objects.equals(type,FlowUserAnalysisType.CUSTOM.value())){ |
| | | int day = 0; |
| | | if (type == 1){ |
| | | day = -7; |
| | | }else { |
| | | day = -30; |
| | | } |
| | | Date endTime = DateUtil.beginOfDay(new Date()); |
| | | flowUserAnalysisParam.setEndTime(endTime); |
| | | flowUserAnalysisParam.setStartTime(DateUtil.offsetDay(endTime,day)); |
| | | flowUserAnalysisParam.setStart(flowUserAnalysisParam.getStartTime().getTime()); |
| | | flowUserAnalysisParam.setEnd(DateUtil.offsetDay(endTime,-1).getTime()); |
| | | }else { |
| | | if (Objects.isNull(flowUserAnalysisParam.getEnd()) || Objects.isNull(flowUserAnalysisParam.getStart())){ |
| | | flowUserAnalysisParam.setEndTime(DateUtil.endOfDay(new Date())); |
| | | flowUserAnalysisParam.setStartTime(DateUtil.beginOfDay(new Date())); |
| | | }else { |
| | | flowUserAnalysisParam.setEndTime(DateUtil.endOfDay(new Date(flowUserAnalysisParam.getEnd()))); |
| | | flowUserAnalysisParam.setStartTime(new Date(flowUserAnalysisParam.getStart())); |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.model.Form; |
| | | import com.yami.shop.bean.model.FormItem; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.i18n.I18nMessage; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.FormService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import javax.validation.Valid; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * @author lgh on 2018/11/26. |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/form") |
| | | @Tag(name = "数据报表") |
| | | public class FormController { |
| | | |
| | | @Autowired |
| | | private FormService formService; |
| | | |
| | | @GetMapping("/page") |
| | | @PreAuthorize("@pms.hasPermission('platform:form:page')") |
| | | @Operation(summary = "分页获取报表" , description = "分页获取报表") |
| | | public ServerResponseEntity<IPage<Form>> page(@ParameterObject Form form, PageParam<Form> page) { |
| | | IPage<Form> formPage = formService.page(page, new LambdaQueryWrapper<Form>() |
| | | .eq(Form::getShopId,Constant.PLATFORM_SHOP_ID) |
| | | .like(StrUtil.isNotBlank(form.getFormName()),Form::getFormName,form.getFormName()) |
| | | .eq(Objects.nonNull(form.getTimeType()),Form::getTimeType,form.getTimeType()) |
| | | .orderByAsc(Form::getSeq) |
| | | .orderByDesc(Form::getUpdateTime) |
| | | ); |
| | | return ServerResponseEntity.success(formPage); |
| | | } |
| | | |
| | | @GetMapping("/info/{formId}") |
| | | @PreAuthorize("@pms.hasPermission('platform:form:info')") |
| | | @Operation(summary = "获取信息" , description = "获取信息") |
| | | @Parameter(name = "formId", description = "报表id" ) |
| | | public ServerResponseEntity<Form> info(@PathVariable("formId") Long formId) { |
| | | Form form = formService.getById(formId); |
| | | return ServerResponseEntity.success(form); |
| | | } |
| | | |
| | | @PostMapping |
| | | @PreAuthorize("@pms.hasPermission('platform:form:save')") |
| | | @Operation(summary = "保存" , description = "保存") |
| | | public ServerResponseEntity<Void> save(@RequestBody @Valid Form form) { |
| | | Date date = new Date(); |
| | | form.setCreateTime(date); |
| | | form.setUpdateTime(date); |
| | | if (!form.getRecommendForm()){ |
| | | Long shopId = Constant.PLATFORM_SHOP_ID; |
| | | form.setShopId(shopId); |
| | | } |
| | | formService.save(form); |
| | | //如果是推荐报表,则清除缓存 |
| | | if (form.getRecommendForm()){ |
| | | formService.removeCache(); |
| | | } |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping |
| | | @PreAuthorize("@pms.hasPermission('platform:form:update')") |
| | | @Operation(summary = "修改" , description = "修改") |
| | | public ServerResponseEntity<Void> update(@RequestBody @Valid Form form) { |
| | | if (!form.getRecommendForm()){ |
| | | Form formDb = formService.getById(form.getFormId()); |
| | | if (!Objects.equals(formDb.getShopId(),Constant.PLATFORM_SHOP_ID)){ |
| | | // 该报表数据有误,请刷新后重新输入 |
| | | throw new YamiShopBindException("yami.form.data.error"); |
| | | } |
| | | } |
| | | form.setUpdateTime(new Date()); |
| | | formService.saveOrUpdate(form); |
| | | //如果是推荐报表,则清除缓存 |
| | | if (form.getRecommendForm()){ |
| | | formService.removeCache(); |
| | | } |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @DeleteMapping("/{formId}") |
| | | @PreAuthorize("@pms.hasPermission('platform:form:delete')") |
| | | @Operation(summary = "删除报表" , description = "删除报表") |
| | | @Parameter(name = "formId", description = "报表id" ) |
| | | public ServerResponseEntity<Void> delete(@PathVariable("formId") Long formId) { |
| | | Form formDb = formService.getById(formId); |
| | | formService.removeById(formId); |
| | | //如果是推荐报表,则清除缓存 |
| | | if (Objects.isNull(formDb.getShopId())){ |
| | | formService.removeCache(); |
| | | } |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @GetMapping("/getFormItem") |
| | | @Operation(summary = "获取报表项列表" , description = "获取报表项列表") |
| | | @Parameter(name = "type", description = "1:平台端 2:商家端" ) |
| | | public ServerResponseEntity<List<FormItem>> getFormItem(@RequestParam("type")Integer type) { |
| | | List<FormItem> formItemEnumList = formService.getFormItem(type, I18nMessage.getDbLang()); |
| | | return ServerResponseEntity.success(formItemEnumList); |
| | | } |
| | | |
| | | @GetMapping("/formExcel") |
| | | @PreAuthorize("@pms.hasPermission('platform:form:excel')") |
| | | @Operation(summary = "生成报表" , description = "生成报表") |
| | | public void formExcel(@RequestParam("formId") Long formId, HttpServletResponse response) { |
| | | formService.formExcel(formId,response); |
| | | } |
| | | |
| | | @GetMapping("/getRecommendFormPage") |
| | | @Operation(summary = "分页获取推荐报表" , description = "分页获取推荐报表") |
| | | public ServerResponseEntity<IPage<Form>> getRecommendFormPage(@ParameterObject Form form, PageParam<Form> page) { |
| | | IPage<Form> formPage = formService.getRecommendFormPage(page,form); |
| | | return ServerResponseEntity.success(formPage); |
| | | } |
| | | |
| | | @GetMapping("/getRecommendFormList") |
| | | @Operation(summary = "获取推荐报表" , description = "获取推荐报表") |
| | | public ServerResponseEntity<List<Form>> getRecommendFormList() { |
| | | List<Form> formList = formService.getRecommendFormList(); |
| | | return ServerResponseEntity.success(formList); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.model.HotSearch; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.HotSearchService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * |
| | | * @author lgh on 2019/03/27. |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/hotSearch") |
| | | @Tag(name = "热搜") |
| | | public class HotSearchController { |
| | | |
| | | @Autowired |
| | | private HotSearchService hotSearchService; |
| | | |
| | | @GetMapping("/page") |
| | | @PreAuthorize("@pms.hasPermission('platform:hotSearch:page')") |
| | | @Operation(summary = "分页获取热搜" , description = "分页获取热搜") |
| | | public ServerResponseEntity<IPage<HotSearch>> page(@ParameterObject HotSearch hotSearch, PageParam<HotSearch> page){ |
| | | IPage<HotSearch> hotSearchs = hotSearchService.page(page,new LambdaQueryWrapper<HotSearch>() |
| | | .eq(HotSearch::getShopId, Constant.PLATFORM_SHOP_ID) |
| | | .like(StrUtil.isNotBlank(hotSearch.getContent()), HotSearch::getContent,hotSearch.getContent()) |
| | | .like(StrUtil.isNotBlank(hotSearch.getTitle()), HotSearch::getTitle,hotSearch.getTitle()) |
| | | .eq(hotSearch.getStatus()!=null, HotSearch::getStatus,hotSearch.getStatus()) |
| | | .orderByAsc(HotSearch::getSeq) |
| | | ); |
| | | return ServerResponseEntity.success(hotSearchs); |
| | | } |
| | | |
| | | @GetMapping("/info/{id}") |
| | | @PreAuthorize("@pms.hasPermission('platform:hotSearch:info')") |
| | | @Operation(summary = "获取信息" , description = "获取信息") |
| | | @Parameter(name = "id", description = "热搜id" ) |
| | | public ServerResponseEntity<HotSearch> info(@PathVariable("id") Long id){ |
| | | HotSearch hotSearch = hotSearchService.getById(id); |
| | | return ServerResponseEntity.success(hotSearch); |
| | | } |
| | | |
| | | @PostMapping |
| | | @PreAuthorize("@pms.hasPermission('platform:hotSearch:save')") |
| | | @Operation(summary = "保存" , description = "保存") |
| | | public ServerResponseEntity<Void> save(@RequestBody @Valid HotSearch hotSearch){ |
| | | hotSearch.setRecDate(new Date()); |
| | | hotSearch.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | hotSearchService.save(hotSearch); |
| | | //清除缓存 |
| | | hotSearchService.removeHotSearchDtoCacheByshopId(Constant.PLATFORM_SHOP_ID); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping |
| | | @PreAuthorize("@pms.hasPermission('platform:hotSearch:update')") |
| | | @Operation(summary = "修改" , description = "修改") |
| | | public ServerResponseEntity<Void> update(@RequestBody @Valid HotSearch hotSearch){ |
| | | hotSearchService.updateById(hotSearch); |
| | | //清除缓存 |
| | | hotSearchService.removeHotSearchDtoCacheByshopId(Constant.PLATFORM_SHOP_ID); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @DeleteMapping |
| | | @PreAuthorize("@pms.hasPermission('platform:hotSearch:delete')") |
| | | @Operation(summary = "删除" , description = "删除") |
| | | @Parameter(name = "ids", description = "热搜id列表" ) |
| | | public ServerResponseEntity<Void> delete(@RequestBody List<Long> ids){ |
| | | hotSearchService.removeByIds(ids); |
| | | //清除缓存 |
| | | hotSearchService.removeHotSearchDtoCacheByshopId(Constant.PLATFORM_SHOP_ID); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.model.IndexImg; |
| | | import com.yami.shop.bean.model.Product; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.i18n.I18nMessage; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.AttachFileService; |
| | | import com.yami.shop.service.IndexImgService; |
| | | import com.yami.shop.service.ProductService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.Date; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * @author lgh on 2018/11/26. |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/indexImg") |
| | | @Tag(name = "轮播图") |
| | | public class IndexImgController { |
| | | |
| | | @Autowired |
| | | private IndexImgService indexImgService; |
| | | |
| | | @Autowired |
| | | private ProductService productService; |
| | | |
| | | @Autowired |
| | | private AttachFileService attachFileService; |
| | | |
| | | @GetMapping("/page") |
| | | @PreAuthorize("@pms.hasPermission('platform:indexImg:page')") |
| | | @Operation(summary = "分页获取" , description = "分页获取") |
| | | public ServerResponseEntity<IPage<IndexImg>> page(@ParameterObject IndexImg indexImg, PageParam<IndexImg> page) { |
| | | IPage<IndexImg> indexImgPage = indexImgService.page(page, |
| | | new LambdaQueryWrapper<IndexImg>() |
| | | .eq(indexImg.getStatus() != null,IndexImg::getStatus,indexImg.getStatus()) |
| | | .eq(IndexImg::getShopId, Constant.PLATFORM_SHOP_ID) |
| | | .eq(!Objects.isNull(indexImg.getImgType()),IndexImg::getImgType,indexImg.getImgType()) |
| | | .orderByAsc(IndexImg::getSeq) |
| | | .orderByDesc(IndexImg::getStatus) |
| | | .orderByAsc(IndexImg::getImgType)); |
| | | return ServerResponseEntity.success(indexImgPage); |
| | | } |
| | | |
| | | @GetMapping("/info/{imgId}") |
| | | @PreAuthorize("@pms.hasPermission('platform:indexImg:info')") |
| | | @Operation(summary = "获取信息" , description = "获取信息") |
| | | @Parameter(name = "imgId", description = "轮播图id" ) |
| | | public ServerResponseEntity<IndexImg> info(@PathVariable("imgId") Long imgId) { |
| | | Long shopId = Constant.PLATFORM_SHOP_ID; |
| | | IndexImg indexImg = indexImgService.getOne(new LambdaQueryWrapper<IndexImg>().eq(IndexImg::getShopId, shopId).eq(IndexImg::getImgId, imgId)); |
| | | if (Objects.nonNull(indexImg.getRelation())) { |
| | | Product product = productService.getProductByProdId(indexImg.getRelation(), I18nMessage.getDbLang()); |
| | | if (product !=null) { |
| | | indexImg.setPic(product.getPic()); |
| | | indexImg.setProdName(product.getProdName()); |
| | | } |
| | | } |
| | | return ServerResponseEntity.success(indexImg); |
| | | } |
| | | |
| | | @PostMapping |
| | | @PreAuthorize("@pms.hasPermission('platform:indexImg:save')") |
| | | @Operation(summary = "保存" , description = "保存") |
| | | public ServerResponseEntity<Void> save(@RequestBody @Valid IndexImg indexImg) { |
| | | Long shopId = Constant.PLATFORM_SHOP_ID; |
| | | indexImg.setShopId(shopId); |
| | | indexImg.setUploadTime(new Date()); |
| | | int count = indexImgService.count(new LambdaQueryWrapper<IndexImg>() |
| | | .eq(IndexImg::getImgType, indexImg.getImgType()) |
| | | .eq(IndexImg::getShopId, shopId) |
| | | ); |
| | | if (count >= Constant.MAX_INDEX_IMG_NUM) { |
| | | // 该平台的轮播图已达到最大数量,不能再进行新增操作 |
| | | throw new YamiShopBindException("yami.index.img.reached.limit"); |
| | | } |
| | | indexImgService.save(indexImg); |
| | | indexImgService.removeIndexImgCacheByShopId(shopId); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping |
| | | @PreAuthorize("@pms.hasPermission('platform:indexImg:update')") |
| | | @Operation(summary = "修改" , description = "修改") |
| | | public ServerResponseEntity<Void> update(@RequestBody @Valid IndexImg indexImg) { |
| | | indexImgService.saveOrUpdate(indexImg); |
| | | // 移除缓存 |
| | | indexImgService.removeIndexImgCacheByShopId(Constant.PLATFORM_SHOP_ID); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @DeleteMapping |
| | | @PreAuthorize("@pms.hasPermission('platform:indexImg:delete')") |
| | | @Operation(summary = "删除" , description = "删除") |
| | | @Parameter(name = "ids", description = "轮播图id" ) |
| | | public ServerResponseEntity<Void> delete(@RequestBody Long[] ids) { |
| | | indexImgService.deleteIndexImgsByIds(ids, Constant.PLATFORM_SHOP_ID); |
| | | // 移除缓存 |
| | | indexImgService.removeIndexImgCacheByShopId(Constant.PLATFORM_SHOP_ID); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.model.MarsBlackLog; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.MarsBlackLogService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author LGH |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/blacklog") |
| | | @Tag(name = "黑名单日志接口") |
| | | @AllArgsConstructor |
| | | public class MarsBlackLogController { |
| | | |
| | | private final MarsBlackLogService marsBlackLogService; |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "分页查询黑名单日志列表信息") |
| | | public ServerResponseEntity<IPage<MarsBlackLog>> getMarsTranOrderPage(PageParam<MarsBlackLog> page, MarsBlackLog marsBlackLog) { |
| | | IPage<MarsBlackLog> userInvoicePage = marsBlackLogService.getMarsTranOrderPage(page,marsBlackLog); |
| | | return ServerResponseEntity.success(userInvoicePage); |
| | | } |
| | | |
| | | |
| | | @GetMapping("/selectUserBlack") |
| | | @Operation(summary = "查询用户黑名单") |
| | | public ServerResponseEntity<List<MarsBlackLog>> selectUserBlack(@Parameter(name = "page", description = "用户Id") String userId) { |
| | | List<MarsBlackLog> list =marsBlackLogService.selectUserBlack(userId); |
| | | return ServerResponseEntity.success(list); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.model.MarsHandCard; |
| | | import com.yami.shop.bean.vo.MarsHandCardVo; |
| | | import com.yami.shop.common.response.ResponseEnum; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.MarsHandCardService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author LGH |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/mars/handCard") |
| | | @Tag(name = "刮刮卡接口") |
| | | @AllArgsConstructor |
| | | public class MarsHandCardController { |
| | | |
| | | @Resource |
| | | private MarsHandCardService marsHandCardService; |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "分页查询刮刮卡列表信息") |
| | | public ServerResponseEntity<IPage<MarsHandCard>> getMarsHandCardPage(PageParam<MarsHandCard> page,MarsHandCard card) { |
| | | IPage<MarsHandCard> userInvoicePage = marsHandCardService.getMarsHandCardPage(page,card ); |
| | | return ServerResponseEntity.success(userInvoicePage); |
| | | } |
| | | |
| | | @GetMapping("/info/{id}") |
| | | @Operation(summary = "通过刮刮卡id查询刮刮卡信息") |
| | | @Parameter(name = "id", description = "刮刮卡id" , required = true) |
| | | public ServerResponseEntity<MarsHandCard> getMarsHandCardById(@PathVariable("id") Long id) { |
| | | MarsHandCard card = marsHandCardService.getById(id); |
| | | return ServerResponseEntity.success(card); |
| | | } |
| | | |
| | | @PostMapping("/getMarsHandCards") |
| | | @Operation(summary = "获取刮刮卡信息") |
| | | public ServerResponseEntity<List<MarsHandCard>> getMarsHandCards(@RequestBody MarsHandCard card) { |
| | | List<MarsHandCard> list = marsHandCardService.getMarsHandCards(card); |
| | | return ServerResponseEntity.success(list); |
| | | } |
| | | |
| | | @PostMapping("/saveMarsHandCard") |
| | | @Operation(summary = "新增刮刮卡信息") |
| | | public ServerResponseEntity<String> saveMarsHandCard(@RequestBody MarsHandCardVo card) { |
| | | Integer num = marsHandCardService.saveMarsHandCards(card); |
| | | if(num >0 ){ |
| | | return ServerResponseEntity.success(ResponseEnum.OK.getMsg()); |
| | | }else{ |
| | | return ServerResponseEntity.showFailMsg(ResponseEnum.ERROR.getMsg()); |
| | | } |
| | | } |
| | | |
| | | @PostMapping("/updateMarsHandCard") |
| | | @Operation(summary = "修改刮刮卡信息") |
| | | public ServerResponseEntity<String> updateMarsHandCard(@RequestBody MarsHandCard card) { |
| | | Integer num = marsHandCardService.updateMarsHandCard(card); |
| | | if(num >0 ){ |
| | | return ServerResponseEntity.success(ResponseEnum.OK.getMsg()); |
| | | }else{ |
| | | return ServerResponseEntity.showFailMsg(ResponseEnum.ERROR.getMsg()); |
| | | } |
| | | } |
| | | |
| | | @GetMapping("/delete/{id}") |
| | | @Operation(summary = "通过刮刮卡id删除流水信息") |
| | | @Parameter(name = "id", description = "寄售流水id" , required = true) |
| | | public ServerResponseEntity<String> deleteMarsHandCardById(@PathVariable("id") Long id) { |
| | | Integer num = marsHandCardService.deleteMarsHandCard(id); |
| | | if(num >0 ){ |
| | | return ServerResponseEntity.success(ResponseEnum.OK.getMsg()); |
| | | }else{ |
| | | return ServerResponseEntity.showFailMsg(ResponseEnum.ERROR.getMsg()); |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.model.MarsTranOrder; |
| | | import com.yami.shop.bean.param.MarsTranOrderParam; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.MarsTranOrderService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.PathVariable; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | /** |
| | | * @author LGH |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/tranOrder") |
| | | @Tag(name = "寄售异常订单接口") |
| | | @AllArgsConstructor |
| | | public class MarsTranOrderController { |
| | | |
| | | private final MarsTranOrderService marsTranOrderService; |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "分页查询寄售异常订单列表信息") |
| | | public ServerResponseEntity<IPage<MarsTranOrder>> getMarsTranOrderPage(PageParam<MarsTranOrder> page, MarsTranOrder marsTranOrder) { |
| | | IPage<MarsTranOrder> userInvoicePage = marsTranOrderService.getMarsTranOrderPage(page,marsTranOrder ); |
| | | return ServerResponseEntity.success(userInvoicePage); |
| | | } |
| | | |
| | | @GetMapping("/info/{id}") |
| | | @Operation(summary = "通过寄售(交易明细表)id查询寄售(交易明细表)信息") |
| | | @Parameter(name = "id", description = "寄售(交易明细表)id" , required = true) |
| | | public ServerResponseEntity<MarsTranOrder> getMarsTranOrderById(@PathVariable("id") Long id) { |
| | | MarsTranOrder card = marsTranOrderService.getById(id); |
| | | return ServerResponseEntity.success(card); |
| | | } |
| | | |
| | | @GetMapping("/settleDisputes") |
| | | @Operation(summary = "争议订单处理") |
| | | public ServerResponseEntity<?> settleDisputes(MarsTranOrderParam marsTranOrderParam) { |
| | | return marsTranOrderService.settleDisputes(marsTranOrderParam); |
| | | } |
| | | |
| | | |
| | | @GetMapping("/removeBlack") |
| | | @Operation(summary = "解除黑名单") |
| | | public ServerResponseEntity<?> removeBlack(@Parameter(name = "page", description = "申请用户Id") String userId) { |
| | | int num =marsTranOrderService.removeBlack(userId); |
| | | if(num>0){ |
| | | return ServerResponseEntity.success(); |
| | | } else |
| | | return ServerResponseEntity.showFailMsg("解除黑名单失败!"); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.img.gif.NeuQuant; |
| | | import cn.hutool.core.util.ArrayUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.yami.shop.bean.app.dto.NoticeDto; |
| | | import com.yami.shop.bean.enums.NoticeType; |
| | | import com.yami.shop.bean.model.Notice; |
| | | import com.yami.shop.common.annotation.SysLog; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.enums.StatusEnum; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.security.platform.util.SecurityUtils; |
| | | import com.yami.shop.service.NoticeService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.AllArgsConstructor; |
| | | import ma.glasnost.orika.MapperFacade; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 公告管理 |
| | | * |
| | | * @author hzm |
| | | * @date |
| | | */ |
| | | @RestController |
| | | @AllArgsConstructor |
| | | @RequestMapping("/platform/notice") |
| | | @Tag(name = "公告") |
| | | public class NoticeController { |
| | | |
| | | @Autowired |
| | | private NoticeService noticeService; |
| | | |
| | | @Autowired |
| | | private MapperFacade mapperFacade; |
| | | |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "分页查询" , description = "分页查询") |
| | | public ServerResponseEntity<IPage<NoticeDto>> getNoticePage(Page<NoticeDto> page, @ParameterObject Notice notice) { |
| | | notice.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | notice.setAccountId(String.valueOf(Constant.PLATFORM_SHOP_ID)); |
| | | Page<NoticeDto> noticeDtoPage = noticeService.pageNotice(page, notice); |
| | | return ServerResponseEntity.success(noticeDtoPage); |
| | | } |
| | | |
| | | @GetMapping("/info/{id}") |
| | | @Operation(summary = "公告信息" , description = "公告信息") |
| | | @Parameter(name = "id", description = "公告id" ) |
| | | public ServerResponseEntity<Notice> getById(@PathVariable("id") Long id) { |
| | | return ServerResponseEntity.success(noticeService.getInfoById(id)); |
| | | } |
| | | |
| | | @SysLog("新增公告管理") |
| | | @PostMapping |
| | | @PreAuthorize("@pms.hasPermission('platform:notice:save')") |
| | | @Operation(summary = "新增公告" , description = "新增公告") |
| | | public ServerResponseEntity<Void> save(@RequestBody @Valid Notice notice) { |
| | | notice.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | if (notice.getStatus() == 1) { |
| | | notice.setPublishTime(new Date()); |
| | | } |
| | | notice.setUpdateTime(new Date()); |
| | | noticeService.save(notice); |
| | | noticeService.removeTopNoticeListCacheByShopId(Constant.PLATFORM_SHOP_ID); |
| | | noticeService.removeNoticeCacheById(notice.getId()); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @SysLog("修改公告管理") |
| | | @PutMapping |
| | | @PreAuthorize("@pms.hasPermission('platform:notice:update')") |
| | | @Operation(summary = "修改公告" , description = "修改公告") |
| | | public ServerResponseEntity<Void> updateById(@RequestBody @Valid NoticeDto noticeDto) { |
| | | Notice oldNotice = noticeService.getById(noticeDto.getId()); |
| | | Notice notice = mapperFacade.map(noticeDto, Notice.class); |
| | | noticeDto.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | if (oldNotice.getStatus() == 0 && notice.getStatus() == 1) { |
| | | notice.setPublishTime(new Date()); |
| | | } |
| | | notice.setUpdateTime(new Date()); |
| | | noticeService.updateById(notice); |
| | | noticeService.removeTopNoticeListCacheByShopId(Constant.PLATFORM_SHOP_ID); |
| | | noticeService.removeNoticeCacheById(notice.getId()); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @SysLog("删除公告管理") |
| | | @DeleteMapping("/{id}") |
| | | @PreAuthorize("@pms.hasPermission('platform:notice:delete')") |
| | | @Operation(summary = "删除公告" , description = "删除公告") |
| | | @Parameter(name = "id", description = "公告id" ) |
| | | public ServerResponseEntity<Void> removeById(@PathVariable Long id) { |
| | | noticeService.removeByIdAndShopId(id,Constant.PLATFORM_SHOP_ID); |
| | | noticeService.removeTopNoticeListCacheByShopId(Constant.PLATFORM_SHOP_ID); |
| | | noticeService.removeNoticeCacheById(id); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import cn.hutool.core.util.BooleanUtil; |
| | | import cn.hutool.core.util.PhoneUtil; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.model.NotifyLog; |
| | | import com.yami.shop.bean.param.OrderParam; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.NotifyLogService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.NoArgsConstructor; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.util.Objects; |
| | | |
| | | |
| | | /** |
| | | * |
| | | * |
| | | * @author lhd |
| | | * @date 2020-08-10 15:20:53 |
| | | */ |
| | | @RestController |
| | | @RequiredArgsConstructor |
| | | @RequestMapping("/platform/notifyLog" ) |
| | | @Tag(name = "消息记录") |
| | | public class NotifyLogController { |
| | | |
| | | @Value("${yami.expose.operation.auth:}") |
| | | private Boolean permission; |
| | | |
| | | private final NotifyLogService notifyLogService; |
| | | |
| | | |
| | | |
| | | @GetMapping("/page" ) |
| | | // @PreAuthorize("@pms.hasPermission('platform:notifyLog:list')" ) |
| | | @Operation(summary = "分页查询" , description = "分页查询") |
| | | public ServerResponseEntity<IPage<NotifyLog>> getNotifyLogPage(PageParam<NotifyLog> page, @ParameterObject OrderParam orderParam) { |
| | | IPage<NotifyLog> notifyLogPage = notifyLogService.pageByParam(page, orderParam); |
| | | if (BooleanUtil.isFalse(permission)){ |
| | | for (NotifyLog record : notifyLogPage.getRecords()) { |
| | | if (Objects.nonNull(record.getUserMobile())) { |
| | | record.setUserMobile(PhoneUtil.hideBetween(record.getUserMobile()).toString()); |
| | | } |
| | | } |
| | | } |
| | | return ServerResponseEntity.success(notifyLogPage); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.enums.RemindType; |
| | | import com.yami.shop.bean.enums.SendType; |
| | | import com.yami.shop.bean.model.NotifyTemplate; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.NotifyTemplateService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.AllArgsConstructor; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.*; |
| | | |
| | | |
| | | /** |
| | | * |
| | | * |
| | | * @author lhd |
| | | * @date 2020-07-01 16:13:08 |
| | | */ |
| | | @RestController |
| | | @AllArgsConstructor |
| | | @RequestMapping("/platform/notifyTemplate") |
| | | @Tag(name = "消息模板") |
| | | public class NotifyTemplateController { |
| | | |
| | | private final NotifyTemplateService notifyTemplateService; |
| | | |
| | | @GetMapping("/page" ) |
| | | @PreAuthorize("@pms.hasPermission('platform:notifyTemplate:page')" ) |
| | | @Operation(summary = "分页查询" , description = "分页查询") |
| | | public ServerResponseEntity<IPage<NotifyTemplate>> getNotifyTemplatePage(PageParam<NotifyTemplate> page, @ParameterObject NotifyTemplate notifyTemplate) { |
| | | |
| | | IPage<NotifyTemplate> templatePage = notifyTemplateService.page(page, new LambdaQueryWrapper<NotifyTemplate>() |
| | | .eq(Objects.nonNull(notifyTemplate.getSendType()),NotifyTemplate::getSendType,notifyTemplate.getSendType()) |
| | | .eq(Objects.nonNull(notifyTemplate.getMsgType()), NotifyTemplate::getMsgType, notifyTemplate.getMsgType()) |
| | | .ne(NotifyTemplate::getSendType, SendType.CUSTOMIZE.getValue()) |
| | | .orderByDesc(NotifyTemplate::getStatus).orderByDesc(NotifyTemplate::getCreateTime)); |
| | | if(CollectionUtils.isEmpty(templatePage.getRecords())){ |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | for (NotifyTemplate template: templatePage.getRecords()) { |
| | | List<Integer> templateList = getTemplateList(template.getTemplateTypes()); |
| | | for (Integer type : templateList) { |
| | | template.setSms(Objects.equals(type,RemindType.SMS.value()) || template.getSms()); |
| | | template.setSub(Objects.equals(type,RemindType.MP.value()) || template.getSub()); |
| | | template.setApp(Objects.equals(type,RemindType.MINI.value()) || template.getApp()); |
| | | } |
| | | template.setTemplateTypeList(templateList); |
| | | } |
| | | return ServerResponseEntity.success(templatePage); |
| | | } |
| | | |
| | | private List<Integer> getTemplateList(String templateTypes) { |
| | | String[] templateTypeList = templateTypes.split(StrUtil.COMMA); |
| | | List<Integer> templates = new ArrayList<>(); |
| | | for (String templateStr : templateTypeList) { |
| | | if (StrUtil.isBlank(templateStr)) { |
| | | continue; |
| | | } |
| | | templates.add(Integer.valueOf(templateStr)); |
| | | } |
| | | return templates; |
| | | } |
| | | |
| | | @GetMapping("/info/{templateId}" ) |
| | | @Operation(summary = "查询模板信息" , description = "查询模板信息") |
| | | @Parameter(name = "templateId", description = "模板id" ) |
| | | public ServerResponseEntity<NotifyTemplate> getById(@PathVariable("templateId") Long templateId) { |
| | | NotifyTemplate template = notifyTemplateService.getById(templateId); |
| | | template.setTemplateTypeList(getTemplateList(template.getTemplateTypes())); |
| | | return ServerResponseEntity.success(template); |
| | | } |
| | | @PutMapping |
| | | @PreAuthorize("@pms.hasPermission('platform:notifyTemplate:update')" ) |
| | | @Operation(summary = "修改模板" , description = "修改模板") |
| | | public ServerResponseEntity<Boolean> updateById(@RequestBody @Valid NotifyTemplate notifyTemplate) { |
| | | List<NotifyTemplate> notifyTemplates = notifyTemplateService.list(new LambdaQueryWrapper<NotifyTemplate>() |
| | | .eq(NotifyTemplate::getSendType, notifyTemplate.getSendType()).ne(NotifyTemplate::getTemplateId,notifyTemplate.getTemplateId())); |
| | | if(CollectionUtils.isNotEmpty(notifyTemplates)){ |
| | | // 已经存在当前消息类型的短信,请去进行修改操作 |
| | | throw new YamiShopBindException("yami.select.notify.type.check"); |
| | | } |
| | | if (CollUtil.isNotEmpty(notifyTemplate.getTemplateTypeList())) { |
| | | notifyTemplate.setTemplateTypes(arrayChangeList(notifyTemplate.getTemplateTypeList())); |
| | | } |
| | | notifyTemplate.setMsgType(null); |
| | | notifyTemplate.setSendType(null); |
| | | return ServerResponseEntity.success(notifyTemplateService.updateById(notifyTemplate)); |
| | | } |
| | | |
| | | private String getRepeatValue(List<Integer> templateTypeList,List<Integer> shopTemplateTypeList){ |
| | | ArrayList<Integer> repeatValue = new ArrayList<>(); |
| | | for (Integer integer : templateTypeList) { |
| | | if (shopTemplateTypeList.contains(integer)){ |
| | | repeatValue.add(integer); |
| | | } |
| | | } |
| | | String s = repeatValue.toString().replace(" ",""); |
| | | return s.substring(1,s.length()-1); |
| | | } |
| | | private String arrayChangeList(List<Integer> templateTypeList) { |
| | | StringBuilder templateTypes = new StringBuilder(); |
| | | for (Integer templateType : templateTypeList) { |
| | | templateTypes.append(templateType); |
| | | templateTypes.append(StrUtil.COMMA); |
| | | } |
| | | templateTypes.deleteCharAt(templateTypes.length() - 1); |
| | | return templateTypes.toString(); |
| | | } |
| | | |
| | | @DeleteMapping("/{templateId}" ) |
| | | @PreAuthorize("@pms.hasPermission('platform:notifyTemplate:updateSts')" ) |
| | | @Operation(summary = "状态变更" , description = "状态变更") |
| | | @Parameter(name = "templateId", description = "模板id" ) |
| | | public ServerResponseEntity<Boolean> removeById(@PathVariable Long templateId) { |
| | | NotifyTemplate template = notifyTemplateService.getById(templateId); |
| | | template.setStatus(template.getStatus() == 1? 0:1); |
| | | return ServerResponseEntity.success(notifyTemplateService.updateById(template)); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.model.Order; |
| | | import com.yami.shop.bean.model.OrderItem; |
| | | import com.yami.shop.bean.model.UserAddrOrder; |
| | | import com.yami.shop.bean.param.OrderParam; |
| | | import com.yami.shop.bean.param.OrderPayParam; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.i18n.I18nMessage; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.*; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Parameters; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author lgh on 2018/09/15. |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/order") |
| | | @AllArgsConstructor |
| | | @Tag(name = "订单") |
| | | public class OrderController { |
| | | |
| | | private final OrderService orderService; |
| | | private final OrderItemService orderItemService; |
| | | private final UserAddrOrderService userAddrOrderService; |
| | | private final StatisticsOrderService statisticsOrderService; |
| | | private final OrderExcelService orderExcelService; |
| | | |
| | | @GetMapping("/page") |
| | | @PreAuthorize("@pms.hasPermission('platform:order:page')") |
| | | @Operation(summary = "分页获取" , description = "分页获取") |
| | | public ServerResponseEntity<IPage<Order>> page(@ParameterObject OrderParam orderParam, PageParam<Order> page) { |
| | | orderParam.setLang(I18nMessage.getDbLang()); |
| | | IPage<Order> orderPage = orderService.pageOrdersDetailByOrderParam(page, orderParam); |
| | | return ServerResponseEntity.success(orderPage); |
| | | } |
| | | |
| | | @GetMapping("/orderPayByShopId") |
| | | @Operation(summary = "根据商家id获取支付信息" , description = "根据商家id获取支付信息") |
| | | @Parameters(value = { |
| | | @Parameter(name = "startTime", description = "开始时间" ), |
| | | @Parameter(name = "endTime", description = "结束时间" ) |
| | | }) |
| | | public ServerResponseEntity<OrderPayParam> orderPayByShopId(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")@RequestParam("startTime") Date startTime, |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")@RequestParam("endTime") Date endTime) { |
| | | OrderPayParam actualTotal = statisticsOrderService.getPayUserCountByshopId(null,startTime,endTime); |
| | | return ServerResponseEntity.success(actualTotal); |
| | | } |
| | | |
| | | @GetMapping("/orderInfo/{orderNumber}") |
| | | @PreAuthorize("@pms.hasPermission('platform:order:info')") |
| | | @Operation(summary = "获取信息" , description = "获取信息") |
| | | @Parameter(name = "orderNumber", description = "订单编号" ) |
| | | public ServerResponseEntity<Order> info(@PathVariable("orderNumber") String orderNumber) { |
| | | |
| | | Order order = orderService.getOne(new LambdaUpdateWrapper<Order>().eq(Order::getOrderNumber, orderNumber)); |
| | | if (order == null) { |
| | | // 未找到所在的订单 |
| | | throw new YamiShopBindException("yami.order.no.exist"); |
| | | } |
| | | UserAddrOrder userAddrOrder = userAddrOrderService.getById(order.getAddrOrderId()); |
| | | order.setUserAddrOrder(userAddrOrder); |
| | | |
| | | List<OrderItem> orderItems = orderItemService.getOrderItemsByOrderNumber(orderNumber, I18nMessage.getDbLang()); |
| | | order.setOrderItems(orderItems); |
| | | return ServerResponseEntity.success(order); |
| | | } |
| | | |
| | | @GetMapping("/soldExcel") |
| | | @PreAuthorize("@pms.hasPermission('platform:order:exportExcel')") |
| | | @Operation(summary = "导出已销售订单" , description = "导出已销售订单") |
| | | public void soldExcel(@ParameterObject OrderParam orderParam, HttpServletResponse response) { |
| | | orderExcelService.soldExcel(orderParam,response); |
| | | } |
| | | |
| | | @GetMapping("/getOrderByUserId") |
| | | @Operation(summary = "分页获取用户订单列表" , description = "分页获取用户订单列表") |
| | | @Parameter(name = "userId", description = "用户id" ) |
| | | public ServerResponseEntity<IPage<Order>> getOrderByUserId(PageParam<Order> page, String userId){ |
| | | IPage<Order> pages = orderService.pageByUserId(page,userId); |
| | | return ServerResponseEntity.success(pages); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.yami.shop.bean.vo.OrderDetailVO; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.service.OrderItemService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Parameters; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | /** |
| | | * @author Pineapple |
| | | * @date 2021/6/9 9:19 |
| | | */ |
| | | @RestController("platformOrderItemController") |
| | | @RequestMapping("/platform/order_item") |
| | | @Tag(name = "platform-订单项信息") |
| | | public class OrderItemController { |
| | | |
| | | @Autowired |
| | | private OrderItemService orderItemService; |
| | | |
| | | @GetMapping("/get_order_detail") |
| | | @Operation(summary = "查询订单项、退款详情" , description = "根据id查询") |
| | | @Parameters(value = { |
| | | @Parameter(name = "orderNumber", description = "订单编号" ), |
| | | @Parameter(name = "refundSn", description = "退款编号" ) |
| | | }) |
| | | public ServerResponseEntity<OrderDetailVO> getOrderItemDetail(String orderNumber, String refundSn){ |
| | | OrderDetailVO orderDetailVO = orderItemService.listDetailByParam(orderNumber, refundSn); |
| | | return ServerResponseEntity.success(orderDetailVO); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.dto.OrderRefundDto; |
| | | import com.yami.shop.bean.model.OrderRefund; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.OrderRefundService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Parameters; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | /** |
| | | * @author yami |
| | | */ |
| | | @RestController |
| | | @AllArgsConstructor |
| | | @RequestMapping("/platform/orderRefund") |
| | | @Tag(name = "订单退款") |
| | | public class OrderRefundController { |
| | | |
| | | private final OrderRefundService orderRefundService; |
| | | |
| | | @GetMapping("/page") |
| | | @PreAuthorize("@pms.hasPermission('platform:orderRefund:page')") |
| | | @Operation(summary = "分页查询" , description = "分页查询") |
| | | @Parameters(value = { |
| | | @Parameter(name = "startTime", description = "开始时间" ), |
| | | @Parameter(name = "endTime", description = "结束时间" ) |
| | | }) |
| | | public ServerResponseEntity<IPage<OrderRefundDto>> getOrderRefundPage(PageParam<OrderRefundDto> page, @ParameterObject OrderRefundDto orderRefundDto, |
| | | @RequestParam(required = false) String startTime, |
| | | @RequestParam(required = false) String endTime) { |
| | | IPage<OrderRefundDto> resp = orderRefundService.getPage(page, orderRefundDto, startTime, endTime, 1); |
| | | return ServerResponseEntity.success(resp); |
| | | } |
| | | |
| | | @GetMapping("/info") |
| | | @PreAuthorize("@pms.hasPermission('platform:orderRefund:info')") |
| | | @Operation(summary = "获取订单退款信息" , description = "获取订单退款信息") |
| | | @Parameters(value = { |
| | | @Parameter(name = "refundId", description = "退款id" ), |
| | | @Parameter(name = "shopId", description = "店铺id" ) |
| | | }) |
| | | public ServerResponseEntity<OrderRefund> info(@RequestParam("refundId") Long refundId, @RequestParam("shopId") Long shopId) { |
| | | OrderRefund orderRefund = orderRefundService.getOrderRefundById(refundId, shopId); |
| | | return ServerResponseEntity.success(orderRefund); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.enums.SendType; |
| | | import com.yami.shop.bean.model.NotifyTemplate; |
| | | import com.yami.shop.common.annotation.SysLog; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.NotifyTemplateService; |
| | | import com.yami.shop.user.common.service.UserTagService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.AllArgsConstructor; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.Date; |
| | | |
| | | |
| | | /** |
| | | * |
| | | * |
| | | * @author lhd |
| | | * @date 2020-07-01 16:13:08 |
| | | */ |
| | | @RestController |
| | | @AllArgsConstructor |
| | | @RequestMapping("/platform/sendTagNotify") |
| | | @Tag(name = "平台消息模板") |
| | | public class PlatformNotifyController { |
| | | |
| | | private final NotifyTemplateService notifyTemplateService; |
| | | private final UserTagService userTagService; |
| | | |
| | | @GetMapping("/page" ) |
| | | @Operation(summary = "分页查询" , description = "分页查询") |
| | | public ServerResponseEntity<IPage<NotifyTemplate>> getNotifyTemplatePage(PageParam<NotifyTemplate> page, @ParameterObject NotifyTemplate notifyTemplate) { |
| | | IPage<NotifyTemplate> templatePage = notifyTemplateService.pageTagNotify(page); |
| | | return ServerResponseEntity.success(templatePage); |
| | | } |
| | | |
| | | @GetMapping("/info/{templateId}" ) |
| | | @Operation(summary = "获取模板信息" , description = "获取模板信息") |
| | | @Parameter(name = "templateId", description = "模板id" ) |
| | | public ServerResponseEntity<NotifyTemplate> getById(@PathVariable("templateId") Long templateId) { |
| | | NotifyTemplate template = notifyTemplateService.getInfoById(templateId); |
| | | return ServerResponseEntity.success(template); |
| | | } |
| | | |
| | | @SysLog("新增" ) |
| | | @PostMapping |
| | | @PreAuthorize("@pms.hasPermission('platform:notifyTemplate:save')" ) |
| | | @Operation(summary = "新增" , description = "新增") |
| | | public ServerResponseEntity<Boolean> save(@RequestBody @Valid NotifyTemplate notifyTemplate) { |
| | | if(CollectionUtils.isEmpty(notifyTemplate.getSelTagIds())){ |
| | | throw new YamiShopBindException("yami.notify.tag.msg"); |
| | | } |
| | | notifyTemplate.setCreateTime(new Date()); |
| | | notifyTemplate.setStatus(1); |
| | | notifyTemplate.setSendType(SendType.CUSTOMIZE.getValue()); |
| | | // 站内消息1 |
| | | notifyTemplate.setTemplateTypes("3"); |
| | | notifyTemplateService.saveTagNotify(notifyTemplate); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @SysLog("修改" ) |
| | | @PutMapping |
| | | @PreAuthorize("@pms.hasPermission('platform:notifyTemplate:update')" ) |
| | | @Operation(summary = "修改" , description = "修改") |
| | | public ServerResponseEntity<Boolean> updateById(@RequestBody @Valid NotifyTemplate notifyTemplate) { |
| | | notifyTemplateService.updateInfoById(notifyTemplate); |
| | | return ServerResponseEntity.success(true); |
| | | } |
| | | |
| | | @DeleteMapping("/{templateId}" ) |
| | | @Operation(summary = "删除消息模板" , description = "删除消息模板") |
| | | @Parameter(name = "templateId", description = "模板id" ) |
| | | public ServerResponseEntity<Boolean> deleteUserTag(@PathVariable Long templateId) { |
| | | notifyTemplateService.deleteTemplateInfoById(templateId); |
| | | return ServerResponseEntity.success(true); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.model.OrderItem; |
| | | import com.yami.shop.bean.model.Product; |
| | | import com.yami.shop.bean.param.*; |
| | | import com.yami.shop.common.i18n.I18nMessage; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.coupon.common.service.CouponUserService; |
| | | import com.yami.shop.service.*; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 商品分析接口 |
| | | * @author |
| | | */ |
| | | @Tag(name = "商品分析接口") |
| | | @RestController |
| | | @RequestMapping("/platform/prodAnalysis") |
| | | @AllArgsConstructor |
| | | public class ProdAnalysisController { |
| | | |
| | | private final ProductService productService; |
| | | private final ProductExcelService productExcelService; |
| | | private final CouponUserService couponUserService; |
| | | private final FlowProductAnalysisService flowProductAnalysisService; |
| | | |
| | | |
| | | /** |
| | | * 获取商品概况 |
| | | */ |
| | | @GetMapping("/getProdSurvey") |
| | | @Operation(summary = "获取商品概况" , description = "获取商品概况") |
| | | public ServerResponseEntity<ProdAnalysisParam> getProdSurvey(@ParameterObject ProdAnalysisSurveyParam param) { |
| | | ProdAnalysisParam analysis = flowProductAnalysisService.getProdSurvey(param); |
| | | return ServerResponseEntity.success(analysis); |
| | | } |
| | | /** |
| | | * 导出商品概况 |
| | | */ |
| | | @GetMapping("/prodSurveyExport") |
| | | @Operation(summary = "导出商品概况" , description = "导出商品概况") |
| | | public void prodSurveyExport(HttpServletResponse response, @ParameterObject ProdAnalysisSurveyParam param) { |
| | | flowProductAnalysisService.prodSurveyExport(response, param); |
| | | } |
| | | |
| | | /** |
| | | * 获取商品趋势分析 |
| | | */ |
| | | @GetMapping("/getProdTrendAnalysis") |
| | | @Operation(summary = "获取商品趋势分析" , description = "获取商品趋势分析") |
| | | public ServerResponseEntity<List<ProdAnalysisDataParam>> getProdTrendAnalysis(@ParameterObject ProdAnalysisSurveyParam param) { |
| | | List<ProdAnalysisDataParam> trendAnalysisa = productService.getProdTrendAnalysis(param); |
| | | return ServerResponseEntity.success(trendAnalysisa); |
| | | } |
| | | |
| | | /** |
| | | * 支付金额TOP |
| | | * 访客数TOP |
| | | */ |
| | | @GetMapping("/getPayAmountTop") |
| | | @Operation(summary = "支付金额TOP、访客数TOP" , description = "支付金额TOP、访客数TOP") |
| | | public ServerResponseEntity<VisitorAndPayTopParam> getPayAmountTop(PageParam<OrderItem> page, @ParameterObject ProdAnalysisSurveyParam param) { |
| | | param.setShopId(null); |
| | | VisitorAndPayTopParam visitorAndPayTopParam = flowProductAnalysisService.getPayAmountTop(page, param); |
| | | return ServerResponseEntity.success(visitorAndPayTopParam); |
| | | } |
| | | |
| | | /** |
| | | * 导出支付金额TOP |
| | | * 导出访客数TOP |
| | | */ |
| | | @GetMapping("/payAmountTopExport") |
| | | @PreAuthorize("@pms.hasPermission('flow:pay:visit:top')") |
| | | @Operation(summary = "导出支付金额TOP、访客数TOP" , description = "导出支付金额TOP、访客数TOP") |
| | | public void payAmountTopExport(HttpServletResponse response, @ParameterObject ProdAnalysisSurveyParam param) { |
| | | param.setShopId(null); |
| | | flowProductAnalysisService.payAmountTopExport(response, param); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取商品效果分析数据 |
| | | */ |
| | | @GetMapping("/getProdEffect") |
| | | @Operation(summary = "获取商品效果分析数据" , description = "获取商品效果分析数据") |
| | | public ServerResponseEntity<IPage<ProdEffectRespParam>> getProdEffect(PageParam<Product> page, @ParameterObject ProdEffectParam param) { |
| | | if (Objects.equals(1,param.getGroup())) { |
| | | IPage<ProdEffectRespParam> map = new PageParam<>(); |
| | | map.setCurrent(page.getCurrent()); |
| | | map.setSize(page.getSize()); |
| | | map.setPages(page.getPages()); |
| | | map.setRecords(new ArrayList<>()); |
| | | return ServerResponseEntity.success(map); |
| | | } |
| | | IPage<ProdEffectRespParam> resPage = productService.pageProdEffect(page,param,I18nMessage.getDbLang(), false); |
| | | return ServerResponseEntity.success(resPage); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 导出商品洞察数据 |
| | | */ |
| | | @GetMapping("/prodEffectExport") |
| | | @PreAuthorize("@pms.hasPermission('flow:prod:effect')") |
| | | @Operation(summary = "导出商品洞察数据" , description = "导出商品洞察数据") |
| | | public void prodEffectExport(HttpServletResponse response, @ParameterObject ProdEffectParam param) { |
| | | productExcelService.prodEffectExport(response,param,I18nMessage.getDbLang()); |
| | | } |
| | | |
| | | /** |
| | | * 单个商品的趋势分析 |
| | | */ |
| | | @GetMapping("/getSingleProdTrend") |
| | | @Operation(summary = "获取商品效果分析数据" , description = "获取商品效果分析数据") |
| | | public ServerResponseEntity<List<ProdSingleTrendParam>> getSingleProdTrend(Long prodId, @ParameterObject ProdEffectParam param) { |
| | | List<ProdSingleTrendParam> resList = productService.getSingleProdTrend(prodId,param); |
| | | return ServerResponseEntity.success(resList); |
| | | } |
| | | |
| | | /** |
| | | * 卡券分析,卡券昨日关键指标 |
| | | */ |
| | | @Operation(summary = "卡券分析,卡券昨日关键指标" , description = "卡券分析,卡券昨日关键指标") |
| | | @GetMapping("/getCouponAnalysis") |
| | | public ServerResponseEntity<List<CouponAnalysisParam>> getCouponAnalysis(@ParameterObject ProdEffectParam param) { |
| | | // 统计近7天的数据 |
| | | List<CouponAnalysisParam> resList = couponUserService.getCouponAnalysis(param); |
| | | return ServerResponseEntity.success(resList); |
| | | } |
| | | |
| | | @GetMapping("/getCouponAnalysisParamByDate") |
| | | @Operation(summary = "根据日期获得优惠券详情信息" , description = "根据日期获得优惠券详情信息") |
| | | public ServerResponseEntity<IPage<CouponAnalysisParam>> getCouponAnalysisParamByDate(PageParam<CouponAnalysisParam> page, @ParameterObject ProdEffectParam param){ |
| | | return ServerResponseEntity.success(couponUserService.getCouponAnalysisParamByDate(page,param)); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.enums.*; |
| | | import com.yami.shop.bean.event.*; |
| | | import com.yami.shop.bean.model.OfflineHandleEvent; |
| | | import com.yami.shop.bean.model.ProdParameter; |
| | | import com.yami.shop.bean.model.Product; |
| | | import com.yami.shop.bean.model.Sku; |
| | | import com.yami.shop.bean.param.NotifyTemplateParam; |
| | | import com.yami.shop.bean.param.OfflineHandleEventAuditParam; |
| | | import com.yami.shop.bean.param.ProductExportParam; |
| | | import com.yami.shop.bean.param.ProductParam; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.i18n.I18nMessage; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.delivery.common.model.SameCity; |
| | | import com.yami.shop.seckill.common.service.SeckillService; |
| | | import com.yami.shop.security.platform.util.SecurityUtils; |
| | | import com.yami.shop.service.*; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.AllArgsConstructor; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.context.ApplicationContext; |
| | | import org.springframework.context.ApplicationEventPublisher; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | import java.util.stream.Collectors; |
| | | |
| | | |
| | | /** |
| | | * 商品列表、商品发布controller |
| | | * |
| | | * @author lgh |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/prod/prod") |
| | | @AllArgsConstructor |
| | | @Tag(name = "商品") |
| | | public class ProductController { |
| | | |
| | | private final SkuService skuService; |
| | | private final BasketService basketService; |
| | | private final ProductService productService; |
| | | private final ProductExcelService productExcelService; |
| | | private final ApplicationEventPublisher eventPublisher; |
| | | private final ApplicationContext applicationContext; |
| | | private final OfflineHandleEventService offlineHandleEventService; |
| | | private final SupplierProdService supplierProdService; |
| | | private final ProdParameterService prodParameterService; |
| | | private final SeckillService seckillService; |
| | | |
| | | @GetMapping("/seckills") |
| | | @Operation(summary = "分页获取秒杀商品信息") |
| | | public ServerResponseEntity<IPage<Product>> seckills(@ParameterObject ProductParam product, PageParam<Product> page){ |
| | | product.setLang(I18nMessage.getLang()); |
| | | IPage<Product> productIPage = seckillService.pageSeckillNormalProd(page, product); |
| | | return ServerResponseEntity.success(productIPage); |
| | | } |
| | | |
| | | /** |
| | | * 处理下活动商品的价格 |
| | | * |
| | | * @param product |
| | | * @param products |
| | | */ |
| | | private void processActivityProdPrice(ProductParam product, List<Product> products) { |
| | | Map<Integer, List<Product>> prodMap = products.stream().collect(Collectors.groupingBy(Product::getProdType)); |
| | | if (prodMap.containsKey(ProdType.PROD_TYPE_SECKILL.value())) { |
| | | applicationContext.publishEvent(new ProcessActivityProdPriceEvent(product, prodMap.get(ProdType.PROD_TYPE_SECKILL.value()))); |
| | | } |
| | | |
| | | if (prodMap.containsKey(ProdType.PROD_TYPE_GROUP.value())) { |
| | | applicationContext.publishEvent(new ProcessActivityProdPriceEvent(product, prodMap.get(ProdType.PROD_TYPE_GROUP.value()))); |
| | | } |
| | | } |
| | | |
| | | @GetMapping("/info/{prodId}") |
| | | @PreAuthorize("@pms.hasPermission('prod:prod:info')") |
| | | @Operation(summary = "获取商品信息" , description = "获取商品信息") |
| | | @Parameter(name = "prodId", description = "商品id" ) |
| | | public ServerResponseEntity<Product> info(@PathVariable("prodId") Long prodId) { |
| | | Product prod = productService.getProductById(prodId); |
| | | List<Sku> skuList = skuService.listSkuAndSkuStock(prodId, I18nMessage.getDbLang()); |
| | | prod.setSkuList(skuList); |
| | | // // 获取语言列表 |
| | | // List<ProdLang> prodLangList = prodLangService.list(new LambdaQueryWrapper<ProdLang>().eq(ProdLang::getProdId, prodId)); |
| | | // prod.setProdLangList(prodLangList); |
| | | List<ProdParameter> prodParameters = prodParameterService.listParameter(prodId, I18nMessage.getDbLang()); |
| | | prod.setProdParameterList(prodParameters); |
| | | return ServerResponseEntity.success(prod); |
| | | } |
| | | |
| | | @DeleteMapping("/{prodId}") |
| | | @PreAuthorize("@pms.hasPermission('prod:prod:update')") |
| | | @Operation(summary = "平台删除商品" , description = "平台删除商品") |
| | | @Parameter(name = "prodId", description = "商品id" ) |
| | | public ServerResponseEntity<Void> delete(@PathVariable("prodId") Long prodId) { |
| | | this.checkBeforeDeleteProduct(prodId); |
| | | Product dbProduct = productService.getProductByProdId(prodId, I18nMessage.getDbLang()); |
| | | List<Sku> dbSkus = skuService.listByProdId(dbProduct.getProdId(), I18nMessage.getDbLang()); |
| | | List<Long> supplierIds = supplierProdService.listSupplierIdByProdId(prodId); |
| | | // 没用到,又不知道干嘛的,先注释掉 |
| | | // List<Long> takeStockIds = takeStockProdService.listInventoryByProdId(prodId); |
| | | // 删除商品 |
| | | productService.removeProductByProdId(prodId); |
| | | //清除供应商商品列表缓存 |
| | | if (CollectionUtils.isNotEmpty(supplierIds)) { |
| | | for (Long supplierId : supplierIds) { |
| | | supplierProdService.removeCacheBySupplierId(supplierId); |
| | | } |
| | | } |
| | | // 商品状态改变时的发送事件,让活动下线 |
| | | applicationContext.publishEvent(new ProdChangeStatusEvent(dbProduct, ProdStatusEnums.DELETE.getValue())); |
| | | //清除商品缓存 |
| | | productService.removeProdCacheByProdId(prodId); |
| | | |
| | | //清除sku缓存 |
| | | for (Sku sku : dbSkus) { |
| | | skuService.removeSkuCacheBySkuId(sku.getSkuId(), sku.getProdId()); |
| | | } |
| | | List<String> userIds = basketService.listUserIdByProdId(prodId); |
| | | |
| | | //清除购物车缓存 |
| | | basketService.removeCacheByUserIds(userIds); |
| | | // 删除商品时,改变分销设置,团购订单处理。。。 |
| | | applicationContext.publishEvent(new ProdChangeEvent(dbProduct)); |
| | | eventPublisher.publishEvent(new EsProductUpdateEvent(prodId, null, EsOperationType.DELETE)); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @GetMapping("/listProdByIdsAndType") |
| | | @Operation(summary = "获取商品信息列表" , description = "获取商品信息列表") |
| | | public ServerResponseEntity<List<Product>> listProdByIdsAndType(@ParameterObject ProductParam product) { |
| | | product.setLang(I18nMessage.getDbLang()); |
| | | List<Product> products = productService.listProdByIdsAndType(product); |
| | | processActivityProdPrice(product, products); |
| | | return ServerResponseEntity.success(products); |
| | | } |
| | | |
| | | @PutMapping("/waterSoldNum") |
| | | @Operation(summary = "更新注水销量" , description = "更新注水销量") |
| | | @Parameter(name = "prodId", description = "商品id" ) |
| | | public ServerResponseEntity<Void> updateWaterSoldNum(Integer waterSoldNum, Long prodId) { |
| | | if (waterSoldNum == null) { |
| | | waterSoldNum = 0; |
| | | } |
| | | productService.updateWaterSaleNum(waterSoldNum, prodId); |
| | | eventPublisher.publishEvent(new EsProductUpdateEvent(prodId, null, EsOperationType.UPDATE_SOLD_NUM)); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PostMapping("/offline") |
| | | @PreAuthorize("@pms.hasPermission('prod:prod:update')") |
| | | @Operation(summary = "下线商品" , description = "下线商品") |
| | | public ServerResponseEntity<Void> offline(@RequestBody OfflineHandleEvent offlineHandleEvent) { |
| | | Product dbProduct = productService.getProductByProdId(offlineHandleEvent.getHandleId(), I18nMessage.getDbLang()); |
| | | if (dbProduct == null) { |
| | | // 未找到刚商品的信息 |
| | | throw new YamiShopBindException("yami.product.not.exist"); |
| | | } |
| | | Long sysUserId = SecurityUtils.getSysUser().getUserId(); |
| | | productService.offline(offlineHandleEvent.getHandleId(), offlineHandleEvent.getOfflineReason(), sysUserId); |
| | | |
| | | // 商品状态改变时的发送事件,让活动下线 |
| | | applicationContext.publishEvent(new ProdChangeStatusEvent(dbProduct, ProdStatusEnums.PLATFORM_OFFLINE.getValue())); |
| | | List<String> userIds = basketService.listUserIdByProdId(dbProduct.getProdId()); |
| | | //清除购物车缓存 |
| | | basketService.removeCacheByUserIds(userIds); |
| | | // 移除缓存 |
| | | productService.removeProdCacheByProdId(dbProduct.getProdId()); |
| | | eventPublisher.publishEvent(new EsProductUpdateEvent(dbProduct.getProdId(), null, EsOperationType.UPDATE)); |
| | | //发送商品下架提醒给商家 |
| | | NotifyTemplateParam shopParam = new NotifyTemplateParam(); |
| | | shopParam.setShopId(dbProduct.getShopId()); |
| | | shopParam.setProdId(offlineHandleEvent.getHandleId()); |
| | | shopParam.setProdName(dbProduct.getProdName()); |
| | | shopParam.setSendType(SendType.PRODUCT_OFFLINE.getValue()); |
| | | applicationContext.publishEvent(new SendMessageEvent(shopParam)); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @GetMapping("/getOfflineHandleEventByProdId/{prodId}") |
| | | @Operation(summary = "获取最新下线商品的事件" , description = "获取最新下线商品的事件") |
| | | @Parameter(name = "prodId", description = "商品id" ) |
| | | public ServerResponseEntity<OfflineHandleEvent> getOfflineHandleEventByProdId(@PathVariable Long prodId) { |
| | | OfflineHandleEvent offlineHandleEvent = offlineHandleEventService.getProcessingEventByHandleTypeAndHandleId(OfflineHandleEventType.PROD.getValue(), prodId); |
| | | return ServerResponseEntity.success(offlineHandleEvent); |
| | | } |
| | | |
| | | @PostMapping("/prodOfflineAudit") |
| | | @Operation(summary = "审核违规下架的商品" , description = "审核违规下架的商品") |
| | | public ServerResponseEntity<Void> prodOfflineAudit(@RequestBody OfflineHandleEventAuditParam offlineHandleEventAuditParam) { |
| | | Long userId = SecurityUtils.getSysUser().getUserId(); |
| | | productService.prodAudit(offlineHandleEventAuditParam, userId); |
| | | |
| | | // 移除缓存 |
| | | productService.removeProdCacheByProdId(offlineHandleEventAuditParam.getHandleId()); |
| | | eventPublisher.publishEvent(new EsProductUpdateEvent(offlineHandleEventAuditParam.getHandleId(), null, EsOperationType.UPDATE)); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PostMapping("/auditProd") |
| | | @Operation(summary = "审核待审核的商品" , description = "商品审核开关打开后,新发布的或要上架的商品处于的待审核状态") |
| | | public ServerResponseEntity<Void> auditProd(@RequestBody OfflineHandleEvent offlineHandleEvent) { |
| | | Long prodId = offlineHandleEvent.getHandleId(); |
| | | Product dbProduct = productService.getProductByProdId(prodId, I18nMessage.getDbLang()); |
| | | if (Objects.isNull(dbProduct)) { |
| | | // 未找到刚商品的信息 |
| | | throw new YamiShopBindException("yami.product.not.exist"); |
| | | } |
| | | if (!Objects.equals(dbProduct.getStatus(), ProdStatusEnums.AUDIT.getValue())) { |
| | | // 商品状态已改变,请刷新页面 |
| | | throw new YamiShopBindException("yami.prod.status.change"); |
| | | } |
| | | offlineHandleEvent.setHandlerId(SecurityUtils.getSysUser().getUserId()); |
| | | productService.handleAuditProd(dbProduct, offlineHandleEvent); |
| | | // 移除缓存 |
| | | productService.removeProdCacheByProdId(dbProduct.getProdId()); |
| | | eventPublisher.publishEvent(new EsProductUpdateEvent(dbProduct.getProdId(), null, EsOperationType.UPDATE)); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping("/toTop/{id}") |
| | | @Operation(summary = "置顶商品" , description = "置顶商品") |
| | | @Parameter(name = "id", description = "商品id" ) |
| | | public ServerResponseEntity<Void> removeById(@PathVariable Long id) { |
| | | Product product = productService.getProductByProdId(id, I18nMessage.getDbLang()); |
| | | if (!Objects.equals(product.getStatus(), ProdStatusEnums.NORMAL.getValue())) { |
| | | // 只能置顶已上架的商品 |
| | | throw new YamiShopBindException("yami.prod.set.top.check"); |
| | | } |
| | | product.setIsTop(Objects.equals(product.getIsTop(), 0) ? 1 : 0); |
| | | productService.updateById(product); |
| | | // 移除缓存 |
| | | productService.removeProdCacheByProdId(id); |
| | | eventPublisher.publishEvent(new EsProductUpdateEvent(product.getProdId(), null, EsOperationType.UPDATE)); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | private void checkBeforeDeleteProduct(Long prodId) { |
| | | GetComboProdCountEvent getComboProdCountEvent = new GetComboProdCountEvent(); |
| | | getComboProdCountEvent.setProdId(prodId); |
| | | applicationContext.publishEvent(getComboProdCountEvent); |
| | | if (getComboProdCountEvent.getCount() > 0) { |
| | | //参加以下活动的商品不能被删除:优惠套餐 |
| | | throw new YamiShopBindException("yami.combo.prod.not.delete"); |
| | | } |
| | | GetGiveawayProdCountEvent getGiveawayProdCountEvent = new GetGiveawayProdCountEvent(); |
| | | getGiveawayProdCountEvent.setProdId(prodId); |
| | | applicationContext.publishEvent(getGiveawayProdCountEvent); |
| | | if (getGiveawayProdCountEvent.getCount() > 0) { |
| | | //参加以下活动的商品不能被删除:赠品 |
| | | throw new YamiShopBindException("yami.giveaway.prod.not.delete"); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.dto.FinanceDetailsDto; |
| | | import com.yami.shop.bean.dto.RevenueOverviewDto; |
| | | import com.yami.shop.bean.param.FinanceDetailsParam; |
| | | import com.yami.shop.bean.param.RevenueOverviewParam; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.RevenueOverviewService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.text.ParseException; |
| | | |
| | | /** |
| | | * 财务管理—营收概况 |
| | | * |
| | | * @author SJL |
| | | * @date 2020-08-17 |
| | | */ |
| | | |
| | | @RestController |
| | | @RequestMapping("/platform/financialManagement") |
| | | @Tag(name = "营收概况") |
| | | public class RevenueOverviewController { |
| | | |
| | | @Autowired |
| | | private RevenueOverviewService revenueOverviewService; |
| | | |
| | | @GetMapping("/getIncomeProfile") |
| | | @Operation(summary = "获取商家和日期的收入金额和退款金额" , description = "获取商家和日期的收入金额和退款金额") |
| | | public ServerResponseEntity<RevenueOverviewDto> getIncomeProfile(@ParameterObject RevenueOverviewParam param) throws ParseException { |
| | | RevenueOverviewDto result = revenueOverviewService.getData(param); |
| | | return ServerResponseEntity.success(result); |
| | | } |
| | | |
| | | @GetMapping("/getFinanceDetail") |
| | | @Operation(summary = "分页获取财务明细" , description = "分页获取财务明细") |
| | | public ServerResponseEntity<IPage<FinanceDetailsDto>> getFinanceDetails(PageParam<FinanceDetailsDto> page, @ParameterObject FinanceDetailsParam param) { |
| | | IPage<FinanceDetailsDto> result = revenueOverviewService.getPageDetail(page, param); |
| | | return ServerResponseEntity.success(result); |
| | | } |
| | | |
| | | @GetMapping("/getFinanceDetailForm") |
| | | @Operation(summary = "导出报表" , description = "导出报表") |
| | | @PreAuthorize("@pms.hasPermission('finance:detail:excel')") |
| | | public void getFinanceDetailForm(@ParameterObject FinanceDetailsParam param, HttpServletResponse response) { |
| | | revenueOverviewService.excelFianceDetail(param, response); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.enums.*; |
| | | import com.yami.shop.bean.event.EsProductUpdateEvent; |
| | | import com.yami.shop.bean.model.OfflineHandleEvent; |
| | | import com.yami.shop.bean.model.ProdLang; |
| | | import com.yami.shop.bean.model.Product; |
| | | import com.yami.shop.bean.model.Sku; |
| | | import com.yami.shop.bean.param.ProductParam; |
| | | import com.yami.shop.bean.param.ProductScoreParam; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.i18n.I18nMessage; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.delivery.common.model.Transport; |
| | | import com.yami.shop.delivery.common.service.TransportService; |
| | | import com.yami.shop.service.*; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.AllArgsConstructor; |
| | | import ma.glasnost.orika.MapperFacade; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.context.ApplicationEventPublisher; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | |
| | | /** |
| | | * 商品列表、商品发布controller |
| | | * |
| | | * @author lgh |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/scoreProduct") |
| | | @AllArgsConstructor |
| | | @Tag(name = "积分商品") |
| | | public class ScoreProductController { |
| | | |
| | | private final ProductService productService; |
| | | private final SkuService skuService; |
| | | private final ProdLangService prodLangService; |
| | | private final BasketService basketService; |
| | | private final ApplicationEventPublisher eventPublisher; |
| | | private final OfflineHandleEventService offlineHandleEventService; |
| | | private final MapperFacade mapperFacade; |
| | | private final TransportService transportService; |
| | | |
| | | |
| | | @GetMapping("/page") |
| | | @PreAuthorize("@pms.hasPermission('score:prod:page')") |
| | | @Operation(summary = "分页获取积分商品信息" , description = "分页获取积分商品信息") |
| | | public ServerResponseEntity<IPage<Product>> page(@ParameterObject ProductParam product, PageParam<Product> page) { |
| | | product.setLang(I18nMessage.getDbLang()); |
| | | product.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | product.setProdType(ProdType.PROD_TYPE_SCORE.value()); |
| | | IPage<Product> products = productService.pageByLang(page,product); |
| | | return ServerResponseEntity.success(products); |
| | | } |
| | | |
| | | @GetMapping("/info/{prodId}") |
| | | @PreAuthorize("@pms.hasPermission('score:prod:info')") |
| | | @Operation(summary = "获取信息" , description = "获取信息") |
| | | @Parameter(name = "prodId", description = "商品id" ) |
| | | public ServerResponseEntity<Product> info(@PathVariable("prodId") Long prodId) { |
| | | Product prod = productService.getProductByProdId(prodId, I18nMessage.getDbLang()); |
| | | List<Sku> skuList = skuService.listSkuAndSkuStock(prodId, I18nMessage.getDbLang()); |
| | | prod.setSkuList(skuList); |
| | | // 获取语言列表 |
| | | List<ProdLang> prodLangList = prodLangService.list(new LambdaQueryWrapper<ProdLang>().eq(ProdLang::getProdId, prodId)); |
| | | prod.setProdLangList(prodLangList); |
| | | return ServerResponseEntity.success(prod); |
| | | } |
| | | |
| | | @DeleteMapping("/{prodId}") |
| | | @PreAuthorize("@pms.hasPermission('score:prod:delete')") |
| | | @Operation(summary = "删除积分商品" , description = "删除积分商品") |
| | | @Parameter(name = "prodId", description = "商品id" ) |
| | | public ServerResponseEntity<Void> delete(@PathVariable("prodId") Long prodId) { |
| | | Product dbProduct = productService.getProductByProdId(prodId, I18nMessage.getDbLang()); |
| | | if (Objects.equals(dbProduct.getStatus(), ProdStatusEnums.DELETE.getValue())) { |
| | | // 该商品已经被删除 |
| | | throw new YamiShopBindException("yami.product.already.deleted"); |
| | | } |
| | | List<Sku> dbSkus = skuService.listByProdId(dbProduct.getProdId(), I18nMessage.getDbLang()); |
| | | // 删除商品 |
| | | productService.removeProductByProdId(prodId); |
| | | |
| | | // 清除缓存 |
| | | productService.removeProdCacheByProdId(prodId); |
| | | |
| | | for (Sku sku : dbSkus) { |
| | | skuService.removeSkuCacheBySkuId(sku.getSkuId(), sku.getProdId()); |
| | | } |
| | | |
| | | List<String> userIds = basketService.listUserIdByProdId(prodId); |
| | | //清除购物车缓存 |
| | | basketService.removeCacheByUserIds(userIds); |
| | | eventPublisher.publishEvent(new EsProductUpdateEvent(prodId, null, EsOperationType.DELETE)); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @GetMapping("/getOfflineHandleEventByProdId/{prodId}") |
| | | @Operation(summary = "获取最新下线商品的事件" , description = "获取最新下线商品的事件") |
| | | @Parameter(name = "prodId", description = "商品id" ) |
| | | public ServerResponseEntity<OfflineHandleEvent> getOfflineHandleEventByProdId(@PathVariable Long prodId) { |
| | | OfflineHandleEvent offlineHandleEvent = offlineHandleEventService.getProcessingEventByHandleTypeAndHandleId(OfflineHandleEventType.PROD.getValue(), prodId); |
| | | return ServerResponseEntity.success(offlineHandleEvent); |
| | | } |
| | | |
| | | @PutMapping("/prodStatus") |
| | | @Operation(summary = "更新商品状态" , description = "更新商品状态") |
| | | public ServerResponseEntity<Void> shopStatus(@RequestBody ProductParam productParam) { |
| | | Long prodId = productParam.getProdId(); |
| | | Integer prodStatus = productParam.getStatus(); |
| | | Product dbProduct = productService.getProductByProdId(prodId, I18nMessage.getDbLang()); |
| | | if (!(Objects.equals(dbProduct.getStatus(), ProdStatusEnums.NORMAL.getValue()) |
| | | || Objects.equals(dbProduct.getStatus(), ProdStatusEnums.SHOP_OFFLINE.getValue()))) { |
| | | // 商品不在正常状态,修改失败 |
| | | throw new YamiShopBindException("yami.product.on.normal"); |
| | | } |
| | | Product product = new Product(); |
| | | product.setProdId(prodId); |
| | | product.setStatus(prodStatus); |
| | | if (prodStatus == 1) { |
| | | product.setPutawayTime(new Date()); |
| | | } |
| | | dbProduct.setStatus(prodStatus); |
| | | // 商品状态改变时的发送事件,让活动下线 |
| | | // applicationContext.publishEvent(new ProdChangeStatusEvent(dbProduct, dbProduct.getStatus())); |
| | | |
| | | productService.updateById(product); |
| | | List<String> userIds = basketService.listUserIdByProdId(prodId); |
| | | productService.removeProdCacheByProdId(prodId); |
| | | //清除购物车缓存 |
| | | basketService.removeCacheByUserIds(userIds); |
| | | eventPublisher.publishEvent(new EsProductUpdateEvent(prodId, null, EsOperationType.UPDATE)); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PostMapping |
| | | @PreAuthorize("@pms.hasPermission('score:prod:save')") |
| | | @Operation(summary = "保存积分商品" , description = "保存积分商品") |
| | | public ServerResponseEntity<Long> save(@Valid @RequestBody ProductScoreParam productScoreParam) { |
| | | checkParam(productScoreParam); |
| | | ProductParam productParam = mapperFacade.map(productScoreParam,ProductParam.class); |
| | | productParam.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | //积分商品类型 |
| | | productParam.setProdType(ProdType.PROD_TYPE_SCORE.value()); |
| | | productService.saveProduct(productParam); |
| | | eventPublisher.publishEvent(new EsProductUpdateEvent(productParam.getProdId(), null, EsOperationType.SAVE)); |
| | | return ServerResponseEntity.success(productParam.getProdId()); |
| | | } |
| | | |
| | | @PutMapping |
| | | @PreAuthorize("@pms.hasPermission('score:prod:update')") |
| | | @Operation(summary = "修改积分商品" , description = "修改积分商品") |
| | | public ServerResponseEntity<String> update(@Valid @RequestBody ProductScoreParam productScoreParam) { |
| | | checkParam(productScoreParam); |
| | | Product dbProduct = productService.getProductInfo(productScoreParam.getProdId(), I18nMessage.getDbLang()); |
| | | if (Objects.equals(dbProduct.getStatus(), ProdStatusEnums.DELETE.getValue())) { |
| | | // 该商品已经被删除 |
| | | throw new YamiShopBindException("yami.product.already.deleted"); |
| | | } |
| | | List<String> userIds = basketService.listUserIdByProdId(productScoreParam.getProdId()); |
| | | List<Sku> dbSkus = skuService.listByProdId(dbProduct.getProdId(), I18nMessage.getDbLang()); |
| | | dbProduct.setSkuList(dbSkus); |
| | | productScoreParam.setProdType(ProdType.PROD_TYPE_SCORE.value()); |
| | | ProductParam productParam = mapperFacade.map(productScoreParam,ProductParam.class); |
| | | productParam.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | productService.updateProduct(productParam, dbProduct); |
| | | productService.removeProdCacheByProdId(productParam.getProdId()); |
| | | //清除缓存 |
| | | for (Sku sku : dbSkus) { |
| | | skuService.removeSkuCacheBySkuId(sku.getSkuId(), sku.getProdId()); |
| | | } |
| | | //清除购物车缓存 |
| | | basketService.removeCacheByUserIds(userIds); |
| | | eventPublisher.publishEvent(new EsProductUpdateEvent(dbProduct.getProdId(), null, EsOperationType.UPDATE)); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | |
| | | private void checkParam(ProductScoreParam productScoreParam) { |
| | | //运费模板 |
| | | Transport transport = transportService.getTransportAndAllItems(productScoreParam.getDeliveryTemplateId()); |
| | | if (Objects.isNull(transport) && !DeliveryTemplateType.isUnifiedTemplate(productScoreParam.getDeliveryTemplateId())) { |
| | | // 产品运费模板不存在 |
| | | throw new YamiShopBindException("yami.prod.transport.not.exist"); |
| | | } |
| | | boolean isAllUnUse = true; |
| | | List<Sku> skuList = productScoreParam.getSkuList(); |
| | | for (Sku sku : skuList) { |
| | | if (sku.getStatus() == 1) { |
| | | isAllUnUse = false; |
| | | } |
| | | } |
| | | if (isAllUnUse) { |
| | | // 至少要启用一种商品规格 |
| | | throw new YamiShopBindException("yami.product.enable.sku"); |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.StringUtils; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.yami.shop.bean.app.param.ShopAuditingParam; |
| | | import com.yami.shop.bean.dto.ShopAuditingInfoDto; |
| | | import com.yami.shop.bean.enums.ShopStatus; |
| | | import com.yami.shop.bean.model.ShopAuditing; |
| | | import com.yami.shop.bean.model.ShopDetail; |
| | | import com.yami.shop.bean.param.AuditingInfoParam; |
| | | import com.yami.shop.bean.param.ShopTypeParam; |
| | | import com.yami.shop.common.annotation.SysLog; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.common.util.RedisUtil; |
| | | import com.yami.shop.security.common.manager.PasswordManager; |
| | | import com.yami.shop.security.platform.util.SecurityUtils; |
| | | import com.yami.shop.service.ShopAuditingService; |
| | | import com.yami.shop.service.ShopDetailService; |
| | | import com.yami.shop.sys.common.model.ShopEmployee; |
| | | import com.yami.shop.sys.common.service.ShopEmployeeService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Parameters; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.security.crypto.password.PasswordEncoder; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.Objects; |
| | | |
| | | |
| | | /** |
| | | * 商家审核信息 |
| | | * |
| | | * @author Dwl |
| | | * @date 2019-09-19 14:02:57 |
| | | */ |
| | | @RestController |
| | | @AllArgsConstructor |
| | | @RequestMapping("/shop/shopAuditing") |
| | | @Tag(name = "店铺审核信息") |
| | | public class ShopAuditingController { |
| | | |
| | | private final ShopAuditingService shopAuditingService; |
| | | private final ShopDetailService shopDetailService; |
| | | private final ShopEmployeeService shopEmployeeService; |
| | | private final PasswordEncoder passwordEncoder; |
| | | private final PasswordManager passwordManager; |
| | | |
| | | @GetMapping("/page") |
| | | @PreAuthorize("@pms.hasPermission('shop:shopAuditing:page')") |
| | | @Operation(summary = "分页查询" , description = "分页查询") |
| | | public ServerResponseEntity<IPage<ShopAuditingInfoDto>> getShopAuditingPage(PageParam<ShopAuditingInfoDto> page, @ParameterObject AuditingInfoParam auditingInfoParam) { |
| | | return ServerResponseEntity.success(shopAuditingService.auditingInfoList(page, auditingInfoParam)); |
| | | } |
| | | |
| | | @GetMapping("/shopDetail/{shopId}") |
| | | @PreAuthorize("@pms.hasPermission('shop:shopAuditing:info')") |
| | | @Operation(summary = "查询详情信息" , description = "查询详情信息") |
| | | @Parameter(name = "shopId", description = "店铺id" ) |
| | | public ServerResponseEntity<ShopDetail> auditingDetail(@PathVariable Long shopId) { |
| | | ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(shopId); |
| | | return ServerResponseEntity.success(shopDetail); |
| | | } |
| | | |
| | | @GetMapping("/{shopId}") |
| | | @Operation(summary = "根据店铺id查询审核信息" , description = "根据店铺id查询审核信息") |
| | | @Parameter(name = "shopId", description = "店铺id" ) |
| | | public ServerResponseEntity<ShopAuditing> getShopAuditing(@PathVariable Long shopId) { |
| | | ShopAuditing shopAuditing = shopAuditingService.getOne(new LambdaQueryWrapper<ShopAuditing>().eq(ShopAuditing::getShopId, shopId)); |
| | | ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(shopId); |
| | | if (Objects.isNull(shopAuditing)){ |
| | | shopAuditing = new ShopAuditing(); |
| | | } |
| | | if (Objects.equals(shopDetail.getShopStatus(), ShopStatus.OFFLINE.value())) { |
| | | shopAuditing.setStatus(2); |
| | | } else if (Objects.equals(shopDetail.getShopStatus(), ShopStatus.OFFLINE_AUDIT.value())) { |
| | | shopAuditing.setStatus(0); |
| | | } |
| | | return ServerResponseEntity.success(shopAuditing); |
| | | } |
| | | |
| | | @SysLog("审核商家信息") |
| | | @PutMapping("/audit") |
| | | @PreAuthorize("@pms.hasPermission('shop:shopAuditing:audit')") |
| | | @Operation(summary = "审核信息(审核商家)" , description = "审核信息(审核商家)") |
| | | public ServerResponseEntity<Void> audit(@Valid @RequestBody ShopAuditingParam shopAuditingParam) { |
| | | String limitKey = "AUDIT_"+shopAuditingParam.getShopId(); |
| | | Long incr = RedisUtil.incr(limitKey, 1); |
| | | if(incr==1){ |
| | | RedisUtil.expire(limitKey,1); |
| | | }else{ |
| | | throw new YamiShopBindException("已提交审核请求"); |
| | | } |
| | | shopAuditingParam.setAuditorId(SecurityUtils.getSysUser().getUserId()); |
| | | shopDetailService.audit(shopAuditingParam); |
| | | shopDetailService.removeShopDetailCacheByShopId(shopAuditingParam.getShopId()); |
| | | shopEmployeeService.update(Wrappers.<ShopEmployee>lambdaUpdate().set(ShopEmployee::getStatus, 1).eq(ShopEmployee::getShopId, shopAuditingParam.getShopId())); |
| | | |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PostMapping |
| | | @Operation(summary = "新建店铺" , description = "新建店铺") |
| | | public ServerResponseEntity<ShopDetail> insertDetail(@RequestBody ShopDetail shopDetail) { |
| | | // 判断是账号是否已存在 |
| | | int count = shopEmployeeService.checkUserName(shopDetail.getShopId(), shopDetail.getMobile()); |
| | | |
| | | shopDetail.setPassword(passwordEncoder.encode(passwordManager.decryptPassword(shopDetail.getPassword()))); |
| | | shopDetailService.insertDetail(shopDetail,count); |
| | | return ServerResponseEntity.success(shopDetail); |
| | | } |
| | | |
| | | @GetMapping("/checkMobile") |
| | | @Operation(summary = "校验账号" , description = "校验账号") |
| | | @Parameters(value = { |
| | | @Parameter(name = "mobile", description = "账号" ), |
| | | @Parameter(name = "shopId", description = "店铺id" ), |
| | | }) |
| | | public ServerResponseEntity<Boolean> checkMobile(@RequestParam("mobile") String mobile,@RequestParam("shopId")Long shopId) { |
| | | boolean isTrue = true; |
| | | if (Objects.isNull(shopId)){ |
| | | shopId = 0L; |
| | | } |
| | | int count = shopDetailService.checkMobile(mobile,Long.valueOf(shopId)); |
| | | // 加多了一个表,并且为了适配,保证数据的唯一性,需要同时验证两个表的数据 |
| | | count = count + shopEmployeeService.checkUserName(shopId, mobile); |
| | | if (count > 0){ |
| | | isTrue = false; |
| | | } |
| | | return ServerResponseEntity.success(isTrue); |
| | | } |
| | | |
| | | @GetMapping("/checkUsername") |
| | | @Operation(summary = "检查用户名是否可用" , description = "检查用户名是否可用") |
| | | @Parameters(value = { |
| | | @Parameter(name = "username", description = "用户名" ), |
| | | @Parameter(name = "shopId", description = "店铺id" ), |
| | | }) |
| | | public ServerResponseEntity<Boolean> checkUsername(@RequestParam("username") String username, @RequestParam("shopId") Long shopId) { |
| | | if (StringUtils.isBlank(username)) { |
| | | return ServerResponseEntity.success(Boolean.FALSE); |
| | | } |
| | | int count = 0; |
| | | if (Objects.isNull(shopId)) { |
| | | // shopId为空,判断用户名是否重复 |
| | | count = shopEmployeeService.count(Wrappers.lambdaQuery(ShopEmployee.class) |
| | | .eq(ShopEmployee::getUsername, username) |
| | | ); |
| | | } else { |
| | | // 更改店铺商家用户名时,判断username是否重复 |
| | | count = shopEmployeeService.count(Wrappers.lambdaQuery(ShopEmployee.class) |
| | | .eq(ShopEmployee::getUsername, username) |
| | | .ne(ShopEmployee::getShopId, shopId) |
| | | ); |
| | | } |
| | | return ServerResponseEntity.success(count == 0); |
| | | } |
| | | |
| | | @PutMapping("/updatePasswordOrMobile") |
| | | @Operation(summary = "重置密码或者修改账号" , description = "重置密码或者修改账号") |
| | | public ServerResponseEntity<Boolean> updatePasswordOrMobile(@RequestBody ShopDetail shopDetail) { |
| | | // 判断是账号是否已存在 |
| | | String decryptPassword = passwordManager.decryptPassword(shopDetail.getPassword()); |
| | | int count = shopEmployeeService.checkUserName(shopDetail.getShopId(), shopDetail.getMobile()); |
| | | if (Objects.nonNull(decryptPassword)) { |
| | | //前端传过来密码如果为空,就不set |
| | | shopDetail.setPassword(passwordEncoder.encode(decryptPassword)); |
| | | } |
| | | shopDetailService.updatePasswordOrMobile(shopDetail.getShopId(),decryptPassword,shopDetail.getMobile(),count); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping("/updateShopType") |
| | | @Operation(summary = "修改店铺类型" , description = "修改店铺类型") |
| | | public ServerResponseEntity<Boolean> updateShopType(@RequestBody ShopTypeParam shopTypeParam) { |
| | | shopDetailService.batchUpdateShopType(shopTypeParam); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.yami.shop.bean.model.ShopBankCard; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.service.ShopBankCardService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @Author lth |
| | | * @Date 2021/8/11 15:04 |
| | | */ |
| | | @RestController |
| | | @AllArgsConstructor |
| | | @RequestMapping("/platform/shopBankCard" ) |
| | | @Tag(name = "银行卡相关接口") |
| | | public class ShopBankCardController { |
| | | |
| | | private final ShopBankCardService shopBankCardService; |
| | | |
| | | @GetMapping("/listByShopId") |
| | | @Operation(summary = "根据店铺id批量获取银行卡信息") |
| | | @Parameter(name = "shopId", description = "店铺id" ) |
| | | public ServerResponseEntity<List<ShopBankCard>> getShopBankCardList(@RequestParam(value = "shopId") Long shopId) { |
| | | List<ShopBankCard> list = shopBankCardService.list(new LambdaQueryWrapper<ShopBankCard>().eq(ShopBankCard::getShopId, shopId).eq(ShopBankCard::getStatus,1)); |
| | | return ServerResponseEntity.success(list); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.yami.shop.bean.enums.AuditStatus; |
| | | import com.yami.shop.bean.model.ShopCompany; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.service.ShopCompanyService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * @Author lth |
| | | * @Date 2021/8/4 14:44 |
| | | */ |
| | | @RestController |
| | | @AllArgsConstructor |
| | | @RequestMapping("/platform/shopCompany") |
| | | @Tag(name = "商家工商信息") |
| | | public class ShopCompanyController { |
| | | |
| | | private final ShopCompanyService shopCompanyService; |
| | | |
| | | @GetMapping |
| | | @Operation(summary = "根据店铺id获取店铺工商信息" , description = "根据店铺id获取店铺工商信息") |
| | | @Parameter(name = "shopId", description = "店铺id" ) |
| | | public ServerResponseEntity<ShopCompany> getShopCompanyByShopId(@RequestParam("shopId") Long shopId) { |
| | | ShopCompany shopCompany = shopCompanyService.getOne(Wrappers.lambdaQuery(ShopCompany.class).eq(ShopCompany::getShopId, shopId).eq(ShopCompany::getStatus, AuditStatus.SUCCESSAUDIT.value())); |
| | | if (Objects.isNull(shopCompany)) { |
| | | shopCompany = new ShopCompany(); |
| | | } |
| | | return ServerResponseEntity.success(shopCompany); |
| | | } |
| | | |
| | | @PutMapping |
| | | @Operation(summary = "更新店铺工商信息" , description = "更新店铺工商信息") |
| | | public ServerResponseEntity<Void> editShopCompany(@RequestBody @Valid ShopCompany shopCompany) { |
| | | shopCompanyService.updateByShopId(shopCompany); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @GetMapping("/checkCreditCode") |
| | | @Operation(summary = "检查统一信用码是否已存在" , description = "检查统一信用码是否已存在") |
| | | @Parameter(name = "creditCode", description = "信用码" ) |
| | | public ServerResponseEntity<Boolean> checkCreditCode(@RequestParam(value = "creditCode") String creditCode) { |
| | | int count = shopCompanyService.count(Wrappers.lambdaQuery(ShopCompany.class) |
| | | .eq(ShopCompany::getCreditCode, creditCode).eq(ShopCompany::getStatus, AuditStatus.SUCCESSAUDIT.value()) |
| | | ); |
| | | return ServerResponseEntity.success(count > 0); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import cn.hutool.core.util.BooleanUtil; |
| | | import cn.hutool.core.util.PhoneUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.google.common.collect.Maps; |
| | | import com.yami.shop.bean.app.dto.ShopHeadInfoDto; |
| | | import com.yami.shop.bean.app.param.SendSmsParam; |
| | | import com.yami.shop.bean.dto.ShopCreateInfoDTO; |
| | | import com.yami.shop.bean.dto.ShopSigningInfoDTO; |
| | | import com.yami.shop.bean.enums.*; |
| | | import com.yami.shop.bean.event.EsProductUpdateEvent; |
| | | import com.yami.shop.bean.model.OfflineHandleEvent; |
| | | import com.yami.shop.bean.model.ShopDetail; |
| | | import com.yami.shop.bean.param.AuditingInfoParam; |
| | | import com.yami.shop.bean.param.OfflineHandleEventAuditParam; |
| | | import com.yami.shop.bean.param.ShopSearchParam; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.common.util.PrincipalUtil; |
| | | import com.yami.shop.security.platform.util.SecurityUtils; |
| | | import com.yami.shop.service.OfflineHandleEventService; |
| | | import com.yami.shop.service.ShopDetailService; |
| | | import com.yami.shop.service.SmsLogService; |
| | | import com.yami.shop.sys.common.model.ShopEmployee; |
| | | import com.yami.shop.sys.common.service.ShopEmployeeService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.context.ApplicationEventPublisher; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import javax.validation.Valid; |
| | | import java.math.BigInteger; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.security.MessageDigest; |
| | | import java.security.NoSuchAlgorithmException; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | |
| | | |
| | | /** |
| | | * 商家详细信息 |
| | | * @author yami |
| | | */ |
| | | @RestController |
| | | @RequiredArgsConstructor |
| | | @RequestMapping("/platform/shopDetail") |
| | | @Tag(name = "店铺基本信息相关接口") |
| | | public class ShopDetailController { |
| | | |
| | | @Value("${yami.expose.operation.auth:}") |
| | | private Boolean permission; |
| | | |
| | | private final ShopDetailService shopDetailService; |
| | | private final OfflineHandleEventService offlineHandleEventService; |
| | | private final ApplicationEventPublisher eventPublisher; |
| | | private final SmsLogService smsLogService; |
| | | private final ShopEmployeeService shopEmployeeService; |
| | | |
| | | |
| | | @GetMapping("/info") |
| | | @Operation(summary = "根据店铺id获取店铺基本信息" , description = "根据店铺id获取店铺基本信息") |
| | | @Parameter(name = "shopId", description = "店铺id" ) |
| | | public ServerResponseEntity<ShopDetail> getInfo(@RequestParam Long shopId) { |
| | | ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(shopId); |
| | | ShopEmployee shopEmployee = shopEmployeeService.getOne(Wrappers.lambdaQuery(ShopEmployee.class).eq(ShopEmployee::getShopId, shopId).eq(ShopEmployee::getType, PositionType.ADMIN.value())); |
| | | if (Objects.nonNull(shopEmployee)) { |
| | | shopDetail.setMerchantAccount(shopEmployee.getUsername()); |
| | | shopDetail.setAccountStatus(shopEmployee.getStatus()); |
| | | if (BooleanUtil.isFalse(permission)) { |
| | | if (StrUtil.isNotBlank(shopDetail.getTel())){ |
| | | shopDetail.setTel(PhoneUtil.hideBetween(shopDetail.getTel()).toString()); |
| | | } |
| | | if (PrincipalUtil.isMobile(shopDetail.getMerchantAccount())) { |
| | | shopDetail.setMerchantAccount(PhoneUtil.hideBetween(shopDetail.getMerchantAccount()).toString()); |
| | | } |
| | | } |
| | | } |
| | | return ServerResponseEntity.success(shopDetail); |
| | | } |
| | | |
| | | @GetMapping("/getMerchantInfo") |
| | | @Operation(summary = "根据店铺id获取店铺商家账号信息" , description = "根据店铺id获取店铺商家账号信息") |
| | | @Parameter(name = "shopId", description = "店铺id" ) |
| | | public ServerResponseEntity<ShopEmployee> getMerchantInfo(@RequestParam Long shopId) { |
| | | ShopEmployee shopEmployee = shopEmployeeService.getMerchantInfoByShopId(shopId); |
| | | return ServerResponseEntity.success(shopEmployee); |
| | | } |
| | | |
| | | @PutMapping("/updateMerchantInfo") |
| | | @Operation(summary = "更新店铺商家账号信息" , description = "更新店铺商家账号信息") |
| | | public ServerResponseEntity<Void> updateMerchantInfo(@RequestBody ShopEmployee shopEmployee) { |
| | | if (Objects.equals(shopEmployee.getShopId(), Constant.MAIN_SHOP) && BooleanUtil.isFalse(permission)) { |
| | | throw new YamiShopBindException("yami.no.auth"); |
| | | } |
| | | shopEmployeeService.updateMerchantInfo(shopEmployee); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PostMapping("/createShop") |
| | | @Operation(summary = "新建店铺" , description = "新建店铺") |
| | | public ServerResponseEntity<Void> createShop(@RequestBody @Valid ShopCreateInfoDTO shopCreateInfoDTO) { |
| | | Long userId = SecurityUtils.getSysUser().getUserId(); |
| | | shopDetailService.platformCreateShop(shopCreateInfoDTO, userId); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PostMapping("/sendCode") |
| | | @Operation(summary = "发送申请开店验证码" , description = "发送申请开店验证码") |
| | | public ServerResponseEntity<Void> sendCode(@Valid @RequestBody SendSmsParam sendSmsParam) { |
| | | int count = shopEmployeeService.count(Wrappers.lambdaQuery(ShopEmployee.class).eq(ShopEmployee::getMobile, sendSmsParam.getMobile())); |
| | | if (count > 0) { |
| | | // 手机号已存在 |
| | | throw new YamiShopBindException("yami.phone.number.already.exists"); |
| | | } |
| | | smsLogService.sendSms(SendType.VALID, null, sendSmsParam.getMobile(), Maps.newHashMap()); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping |
| | | @Operation(summary = "编辑店铺基本信息" , description = "编辑店铺基本信息") |
| | | public ServerResponseEntity<Void> editShop(@RequestBody ShopDetail shopDetail) { |
| | | if (Objects.isNull(shopDetail.getShopId())) { |
| | | throw new YamiShopBindException("店铺id不能为空"); |
| | | } |
| | | shopDetailService.updateShopDetail(shopDetail); |
| | | eventPublisher.publishEvent(new EsProductUpdateEvent(shopDetail.getShopId(), null, EsOperationType.UPDATE_BY_SHOP_ID)); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping("/updateSigningInfo") |
| | | @Operation(summary = "更新店铺签约信息" , description = "更新店铺签约信息") |
| | | public ServerResponseEntity<Void> updateSigningInfo(@RequestBody @Valid ShopSigningInfoDTO shopSigningInfoDTO) { |
| | | if (Objects.isNull(shopSigningInfoDTO.getShopId())) { |
| | | throw new YamiShopBindException("店铺id不能为空"); |
| | | } |
| | | shopDetailService.updateSigningInfo(shopSigningInfoDTO); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @GetMapping("/getOfflineHandleEventByShopId/{shopId}") |
| | | @PreAuthorize("@pms.hasPermission('shop:shopAuditing:info')") |
| | | @Parameter(name = "shopId", description = "店铺id" ) |
| | | public ServerResponseEntity<OfflineHandleEvent> getOfflineHandleEventByShopId(@PathVariable("shopId") Long shopId) { |
| | | OfflineHandleEvent offlineHandleEvent = offlineHandleEventService.getProcessingEventByHandleTypeAndHandleId(OfflineHandleEventType.SHOP.getValue(), shopId); |
| | | return ServerResponseEntity.success(offlineHandleEvent); |
| | | } |
| | | |
| | | /** |
| | | * 下线店铺 |
| | | */ |
| | | @PostMapping("/offline") |
| | | @PreAuthorize("@pms.hasPermission('shop:shopAuditing:audit')") |
| | | public ServerResponseEntity<Void> offline(@RequestBody OfflineHandleEvent offlineHandleEvent) { |
| | | Long sysUserId = SecurityUtils.getSysUser().getUserId(); |
| | | ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(offlineHandleEvent.getHandleId()); |
| | | if (shopDetail == null) { |
| | | // 未找到该店铺信息 |
| | | throw new YamiShopBindException("yami.store.not.exist"); |
| | | } |
| | | if (!Objects.equals(shopDetail.getShopStatus(), ShopStatus.OPEN.value()) && !Objects.equals(shopDetail.getShopStatus(), ShopStatus.STOP.value())) { |
| | | // 店铺不处于营业或停业状态,不能进行下线 |
| | | throw new YamiShopBindException("yami.store.offline.check"); |
| | | } |
| | | shopDetailService.offline(shopDetail, offlineHandleEvent.getOfflineReason(), sysUserId); |
| | | |
| | | eventPublisher.publishEvent(new EsProductUpdateEvent(shopDetail.getShopId(), null, EsOperationType.UPDATE_BY_SHOP_ID)); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | /** |
| | | * 店铺审核重新开店 |
| | | */ |
| | | @PostMapping("/auditShop") |
| | | @PreAuthorize("@pms.hasPermission('shop:shopAuditing:audit')") |
| | | @Operation(summary = "店铺违规审核" , description = "店铺违规审核") |
| | | public ServerResponseEntity<Void> auditOfflineShop(@RequestBody OfflineHandleEventAuditParam offlineHandleEventAuditParam) { |
| | | Long sysUserId = SecurityUtils.getSysUser().getUserId(); |
| | | shopDetailService.auditOfflineShop(offlineHandleEventAuditParam, sysUserId); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @GetMapping("/checkShopName") |
| | | @Operation(summary = "检查店铺名称是否已存在" , description = "检查店铺名称是否已存在") |
| | | public ServerResponseEntity<Boolean> checkShopName(@RequestParam(value = "shopName") String shopName) { |
| | | int count = shopDetailService.count(Wrappers.lambdaQuery(ShopDetail.class) |
| | | .eq(ShopDetail::getShopName, shopName) |
| | | .ne(ShopDetail::getShopStatus, ShopStatus.NOTOPEN.value()) |
| | | ); |
| | | return ServerResponseEntity.success(count > 0); |
| | | } |
| | | |
| | | @GetMapping("/exportShop") |
| | | @Operation(summary = "导出店铺列表" , description = "导出店铺列表") |
| | | public void exportShop(@ParameterObject AuditingInfoParam auditingInfoParam, HttpServletResponse response) { |
| | | shopDetailService.exportShop(auditingInfoParam, response); |
| | | } |
| | | |
| | | private String generateKey(Map<String, String> values) { |
| | | MessageDigest digest; |
| | | try { |
| | | digest = MessageDigest.getInstance("MD5"); |
| | | byte[] bytes = digest.digest(values.toString().getBytes(StandardCharsets.UTF_8)); |
| | | return String.format("%032x", new BigInteger(1, bytes)); |
| | | } catch (NoSuchAlgorithmException nsae) { |
| | | throw new IllegalStateException("MD5 algorithm not available. Fatal (should be in the JDK).", nsae); |
| | | } |
| | | } |
| | | |
| | | @GetMapping("/searchShops") |
| | | @Operation(summary = "搜索店铺" , description = "根据店铺名称搜索店铺") |
| | | public ServerResponseEntity<IPage<ShopHeadInfoDto>> searchShops(PageParam<ShopDetail> page, @ParameterObject ShopSearchParam shopSearchParam) { |
| | | IPage<ShopHeadInfoDto> shopPage = shopDetailService.renovationShopPage(page, shopSearchParam); |
| | | return ServerResponseEntity.success(shopPage); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.enums.RenovationType; |
| | | import com.yami.shop.bean.model.ShopRenovation; |
| | | import com.yami.shop.common.annotation.SysLog; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.ShopRenovationService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.Objects; |
| | | |
| | | |
| | | /** |
| | | * 店铺装修信息 |
| | | * |
| | | * @author lhd |
| | | * @date 2021-01-05 11:03:38 |
| | | */ |
| | | @RestController |
| | | @AllArgsConstructor |
| | | @RequestMapping("/platform/shopRenovation" ) |
| | | @Tag(name = "店铺装修页面接口") |
| | | public class ShopRenovationController { |
| | | |
| | | |
| | | private final ShopRenovationService shopRenovationService; |
| | | |
| | | @GetMapping("/pagePC" ) |
| | | @PreAuthorize("@pms.hasPermission('platform:shopRenovation:pagePC')") |
| | | @Operation(summary = "PC端分页获取店铺装修信息" , description = "PC端分页获取店铺装修信息") |
| | | public ServerResponseEntity<IPage<ShopRenovation>> getShopRenovationPagePC(PageParam<ShopRenovation> page, @ParameterObject ShopRenovation shopRenovation) { |
| | | return ServerResponseEntity.success(shopRenovationService.page(page, new LambdaQueryWrapper<ShopRenovation>() |
| | | .eq(ShopRenovation::getShopId,Constant.PLATFORM_SHOP_ID) |
| | | .eq(Objects.nonNull(shopRenovation.getRenovationType()), ShopRenovation::getRenovationType, shopRenovation.getRenovationType()) |
| | | .like(Objects.nonNull(shopRenovation.getName()), ShopRenovation::getName, shopRenovation.getName()) |
| | | .eq(ShopRenovation::getRenovationType,shopRenovation.getRenovationType()) |
| | | .orderByDesc(ShopRenovation::getHomeStatus, ShopRenovation::getCreateTime)) |
| | | ); |
| | | } |
| | | |
| | | @GetMapping("/pageMove" ) |
| | | @PreAuthorize("@pms.hasPermission('platform:shopRenovation:pageMove')") |
| | | @Operation(summary = "移动端分页获取店铺装修信息" , description = "移动端分页获取店铺装修信息") |
| | | public ServerResponseEntity<IPage<ShopRenovation>> getShopRenovationPageMove(PageParam<ShopRenovation> page, @ParameterObject ShopRenovation shopRenovation) { |
| | | return ServerResponseEntity.success(shopRenovationService.page(page, new LambdaQueryWrapper<ShopRenovation>() |
| | | .eq(ShopRenovation::getShopId,Constant.PLATFORM_SHOP_ID) |
| | | .eq(Objects.nonNull(shopRenovation.getRenovationType()), ShopRenovation::getRenovationType, shopRenovation.getRenovationType()) |
| | | .like(Objects.nonNull(shopRenovation.getName()), ShopRenovation::getName, shopRenovation.getName()) |
| | | .eq(ShopRenovation::getRenovationType,shopRenovation.getRenovationType()) |
| | | .orderByDesc(ShopRenovation::getHomeStatus, ShopRenovation::getCreateTime) |
| | | )); |
| | | } |
| | | |
| | | @GetMapping("/info/{renovationId}" ) |
| | | @Operation(summary = "查询店铺装修信息" , description = "查询店铺装修信息") |
| | | @Parameter(name = "renovationId", description = "店铺装修id" ) |
| | | public ServerResponseEntity<ShopRenovation> getById(@PathVariable("renovationId") Long renovationId) { |
| | | return ServerResponseEntity.success(shopRenovationService.getById(renovationId)); |
| | | } |
| | | |
| | | @SysLog("新增店铺装修信息" ) |
| | | @PostMapping("/savePC") |
| | | @PreAuthorize("@pms.hasPermission('platform:shopRenovation:savePC')") |
| | | @Operation(summary = "PC端新增店铺装修信息" , description = "PC端新增店铺装修信息") |
| | | public ServerResponseEntity<Long> savePC(@RequestBody @Valid ShopRenovation shopRenovation) { |
| | | shopRenovation.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | if (Objects.isNull(shopRenovation.getRenovationType())) { |
| | | shopRenovation.setRenovationType(RenovationType.H5.value()); |
| | | } |
| | | shopRenovationService.save(shopRenovation); |
| | | return ServerResponseEntity.success(shopRenovation.getRenovationId()); |
| | | } |
| | | |
| | | @SysLog("新增店铺装修信息" ) |
| | | @PostMapping("/saveMove") |
| | | @PreAuthorize("@pms.hasPermission('platform:shopRenovation:saveMove')") |
| | | @Operation(summary = "移动端新增店铺装修信息" , description = "移动端新增店铺装修信息") |
| | | public ServerResponseEntity<Long> saveMove(@RequestBody @Valid ShopRenovation shopRenovation) { |
| | | shopRenovation.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | if (Objects.isNull(shopRenovation.getRenovationType())) { |
| | | shopRenovation.setRenovationType(RenovationType.H5.value()); |
| | | } |
| | | shopRenovationService.save(shopRenovation); |
| | | return ServerResponseEntity.success(shopRenovation.getRenovationId()); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.yami.shop.bean.model.ShopRenovation; |
| | | import com.yami.shop.common.annotation.SysLog; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.service.ShopRenovationService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.Objects; |
| | | |
| | | |
| | | /** |
| | | * 店铺装修信息 |
| | | * |
| | | * @author lhd |
| | | * @date 2021-01-05 11:03:38 |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/shopRenovation/operate" ) |
| | | @ConditionalOnProperty(prefix = "yami", name = "expose.operation.auth", havingValue = "true", matchIfMissing = true) |
| | | @Tag(name = "店铺页面-修改、删除、设为主页") |
| | | public class ShopRenovationUpDelController { |
| | | |
| | | @Autowired |
| | | private ShopRenovationService shopRenovationService; |
| | | |
| | | |
| | | @SysLog("修改店铺装修信息" ) |
| | | @PutMapping("/updatePC") |
| | | @PreAuthorize("@pms.hasPermission('platform:shopRenovation:updatePC')") |
| | | @Operation(summary = "PC端修改店铺装修页面信息" , description = "PC端修改店铺装修页面信息") |
| | | public ServerResponseEntity<Boolean> updatePCById(@RequestBody @Valid ShopRenovation shopRenovation) { |
| | | ShopRenovation shopRenovationDb = shopRenovationService.getById(shopRenovation.getRenovationId()); |
| | | if(!Objects.equals(shopRenovationDb.getShopId() ,Constant.PLATFORM_SHOP_ID)){ |
| | | // 没有权限进行操作 |
| | | throw new YamiShopBindException("yami.no.auth"); |
| | | } |
| | | shopRenovationService.checkShopRenovation(shopRenovation); |
| | | shopRenovationService.removeCache(shopRenovationDb.getShopId(), shopRenovationDb.getRenovationType(), shopRenovationDb.getRenovationId()); |
| | | return ServerResponseEntity.success(shopRenovationService.updateById(shopRenovation)); |
| | | } |
| | | |
| | | @SysLog("修改店铺装修信息" ) |
| | | @PutMapping("/updateMove") |
| | | @PreAuthorize("@pms.hasPermission('platform:shopRenovation:updateMove')") |
| | | @Operation(summary = "移动端修改店铺装修页面信息" , description = "移动端修改店铺装修页面信息") |
| | | public ServerResponseEntity<Boolean> updateMoveById(@RequestBody @Valid ShopRenovation shopRenovation) { |
| | | ShopRenovation shopRenovationDb = shopRenovationService.getById(shopRenovation.getRenovationId()); |
| | | if(!Objects.equals(shopRenovationDb.getShopId() ,Constant.PLATFORM_SHOP_ID)){ |
| | | // 没有权限进行操作 |
| | | throw new YamiShopBindException("yami.no.auth"); |
| | | } |
| | | shopRenovationService.checkShopRenovation(shopRenovation); |
| | | shopRenovationService.removeCache(shopRenovationDb.getShopId(), shopRenovationDb.getRenovationType(), shopRenovationDb.getRenovationId()); |
| | | return ServerResponseEntity.success(shopRenovationService.updateById(shopRenovation)); |
| | | } |
| | | |
| | | @SysLog("删除店铺装修信息" ) |
| | | @DeleteMapping("/deletePC/{renovationId}" ) |
| | | @PreAuthorize("@pms.hasPermission('platform:shopRenovation:deletePC')") |
| | | @Operation(summary = "PC端删除店铺装修页面信息" , description = "PC端删除店铺装修页面信息") |
| | | @Parameter(name = "renovationId", description = "店铺装修id" ) |
| | | public ServerResponseEntity<Boolean> removePCById(@PathVariable("renovationId") Long renovationId) { |
| | | ShopRenovation shopRenovation = shopRenovationService.getById(renovationId); |
| | | if(!Objects.equals(shopRenovation.getShopId() ,Constant.PLATFORM_SHOP_ID)){ |
| | | // 没有权限进行操作 |
| | | throw new YamiShopBindException("yami.no.auth"); |
| | | } |
| | | shopRenovationService.removeCache(shopRenovation.getShopId(), shopRenovation.getRenovationType(), shopRenovation.getRenovationId()); |
| | | return ServerResponseEntity.success(shopRenovationService.removeById(renovationId)); |
| | | } |
| | | |
| | | @SysLog("删除店铺装修信息" ) |
| | | @DeleteMapping("/deleteMove/{renovationId}" ) |
| | | @PreAuthorize("@pms.hasPermission('platform:shopRenovation:deleteMove')") |
| | | @Operation(summary = "移动端删除店铺装修页面信息" , description = "移动端删除店铺装修页面信息") |
| | | @Parameter(name = "renovationId", description = "店铺装修id" ) |
| | | public ServerResponseEntity<Boolean> removeMoveById(@PathVariable("renovationId") Long renovationId) { |
| | | ShopRenovation shopRenovation = shopRenovationService.getById(renovationId); |
| | | if(!Objects.equals(shopRenovation.getShopId() ,Constant.PLATFORM_SHOP_ID)){ |
| | | // 没有权限进行操作 |
| | | throw new YamiShopBindException("yami.no.auth"); |
| | | } |
| | | shopRenovationService.removeCache(shopRenovation.getShopId(), shopRenovation.getRenovationType(), shopRenovation.getRenovationId()); |
| | | return ServerResponseEntity.success(shopRenovationService.removeById(renovationId)); |
| | | } |
| | | |
| | | @PutMapping("/updateHomePagePC/{id}" ) |
| | | @PreAuthorize("@pms.hasPermission('platform:shopRenovation:updateHomePagePC')") |
| | | @Operation(summary = "PC端修改主页标识" , description = "PC端修改主页标识") |
| | | @Parameter(name = "id", description = "店铺装修id" ) |
| | | public ServerResponseEntity<Void> updateHomePagePC(@PathVariable("id") Long id) { |
| | | ShopRenovation shopRenovation = shopRenovationService.getById(id); |
| | | if(!Objects.equals(shopRenovation.getShopId() ,Constant.PLATFORM_SHOP_ID)){ |
| | | // 没有权限进行操作 |
| | | throw new YamiShopBindException("yami.no.auth"); |
| | | } |
| | | |
| | | shopRenovationService.updateToHomePage(shopRenovation); |
| | | shopRenovationService.removeCache(shopRenovation.getShopId(), shopRenovation.getRenovationType(), shopRenovation.getRenovationId()); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping("/updateHomePageMove/{id}" ) |
| | | @PreAuthorize("@pms.hasPermission('platform:shopRenovation:updateHomePageMove')") |
| | | @Operation(summary = "移动端修改主页标识" , description = "移动端修改主页标识") |
| | | @Parameter(name = "id", description = "店铺装修id" ) |
| | | public ServerResponseEntity<Void> updateHomePageMove(@PathVariable("id") Long id) { |
| | | ShopRenovation shopRenovation = shopRenovationService.getById(id); |
| | | if(!Objects.equals(shopRenovation.getShopId() ,Constant.PLATFORM_SHOP_ID)){ |
| | | // 没有权限进行操作 |
| | | throw new YamiShopBindException("yami.no.auth"); |
| | | } |
| | | |
| | | shopRenovationService.updateToHomePage(shopRenovation); |
| | | shopRenovationService.removeCache(shopRenovation.getShopId(), shopRenovation.getRenovationType(), shopRenovation.getRenovationId()); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.enums.TemplateType; |
| | | import com.yami.shop.bean.model.ShopTemplate; |
| | | import com.yami.shop.common.annotation.SysLog; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.ShopTemplateService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.Date; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * |
| | | * |
| | | * @author LGH |
| | | * @date 2022-07-29 16:54:02 |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/shopTemplate") |
| | | @Tag(name = "店铺装修模板接口") |
| | | public class ShopTemplateController { |
| | | |
| | | @Autowired |
| | | private ShopTemplateService shopTemplateService; |
| | | |
| | | @GetMapping("/pagePC") |
| | | @PreAuthorize("@pms.hasPermission('platform:shopTemplate:pagePC')") |
| | | @Operation(summary = "PC端分页查询店铺模板信息" , description = "PC端分页查询店铺模板信息") |
| | | public ServerResponseEntity<IPage<ShopTemplate>> getShopTemplatePagePC(PageParam<ShopTemplate> page, @ParameterObject ShopTemplate shopTemplate) { |
| | | return ServerResponseEntity.success(shopTemplateService.page(page, new LambdaQueryWrapper<ShopTemplate>() |
| | | .eq(ShopTemplate::getShopId, Constant.PLATFORM_SHOP_ID) |
| | | .eq(Objects.nonNull(shopTemplate.getType()), ShopTemplate::getType, shopTemplate.getType()) |
| | | .eq(ShopTemplate::getType,shopTemplate.getType()) |
| | | .orderByDesc(ShopTemplate::getUpdateTime) |
| | | )); |
| | | } |
| | | |
| | | @GetMapping("/pageMove") |
| | | @PreAuthorize("@pms.hasPermission('platform:shopTemplate:pageMove')") |
| | | @Operation(summary = "移动端分页查询店铺模板信息" , description = "移动端分页查询店铺模板信息") |
| | | public ServerResponseEntity<IPage<ShopTemplate>> getShopTemplatePageMove(PageParam<ShopTemplate> page, @ParameterObject ShopTemplate shopTemplate) { |
| | | return ServerResponseEntity.success(shopTemplateService.page(page, new LambdaQueryWrapper<ShopTemplate>() |
| | | .eq(ShopTemplate::getShopId, Constant.PLATFORM_SHOP_ID) |
| | | .eq(Objects.nonNull(shopTemplate.getType()), ShopTemplate::getType, shopTemplate.getType()) |
| | | .eq(ShopTemplate::getType,shopTemplate.getType()) |
| | | .orderByDesc(ShopTemplate::getUpdateTime) |
| | | )); |
| | | } |
| | | |
| | | /** |
| | | * 通过id查询店铺模板信息 |
| | | * @param templateId id |
| | | * @return 单个数据 |
| | | */ |
| | | @GetMapping("/info/{templateId}" ) |
| | | @Operation(summary = "通过id查询店铺装修模板信息" , description = "通过id查询店铺装修模板信息") |
| | | public ServerResponseEntity<ShopTemplate> getById(@PathVariable("templateId") Long templateId) { |
| | | return ServerResponseEntity.success(shopTemplateService.getById(templateId)); |
| | | } |
| | | |
| | | @SysLog("新增店铺模板信息" ) |
| | | @PostMapping("/savePC") |
| | | @PreAuthorize("@pms.hasPermission('platform:shopTemplate:savePC')") |
| | | @Operation(summary = "PC端新增店铺模板信息" , description = "PC端新增店铺模板信息") |
| | | public ServerResponseEntity<Long> savePC(@RequestBody @Valid ShopTemplate shopTemplate) { |
| | | shopTemplate.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | if (Objects.isNull(shopTemplate.getType())) { |
| | | shopTemplate.setType(TemplateType.PC.value()); |
| | | } |
| | | shopTemplateService.save(shopTemplate); |
| | | return ServerResponseEntity.success(shopTemplate.getTemplateId()); |
| | | } |
| | | |
| | | @SysLog("新增店铺模板信息" ) |
| | | @PostMapping("/saveMove") |
| | | @PreAuthorize("@pms.hasPermission('platform:shopTemplate:saveMove')") |
| | | @Operation(summary = "移动端新增店铺模板信息" , description = "移动端新增店铺模板信息") |
| | | public ServerResponseEntity<Long> saveMove(@RequestBody @Valid ShopTemplate shopTemplate) { |
| | | shopTemplate.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | if (Objects.isNull(shopTemplate.getType())) { |
| | | shopTemplate.setType(TemplateType.H5.value()); |
| | | } |
| | | shopTemplateService.save(shopTemplate); |
| | | return ServerResponseEntity.success(shopTemplate.getTemplateId()); |
| | | } |
| | | |
| | | @PostMapping("/copyPC/{templateId}") |
| | | @PreAuthorize("@pms.hasPermission('platform:shopTemplate:copyPC')") |
| | | @Operation(summary = "PC端复制模板信息" , description = "PC端复制模板信息") |
| | | public ServerResponseEntity<Long> copyTemplatePC(@PathVariable Long templateId){ |
| | | ShopTemplate shopTemplate = shopTemplateService.getById(templateId); |
| | | shopTemplate.setTemplateId(null); |
| | | shopTemplate.setName(shopTemplate.getName()+"副本"); |
| | | shopTemplate.setCreateTime(new Date()); |
| | | shopTemplate.setUpdateTime(new Date()); |
| | | shopTemplateService.save(shopTemplate); |
| | | return ServerResponseEntity.success(shopTemplate.getTemplateId()); |
| | | } |
| | | |
| | | @PostMapping("/copyMove/{templateId}") |
| | | @PreAuthorize("@pms.hasPermission('platform:shopTemplate:copyMove')") |
| | | @Operation(summary = "PC端复制模板信息" , description = "PC端复制模板信息") |
| | | public ServerResponseEntity<Long> copyTemplateMove(@PathVariable Long templateId){ |
| | | ShopTemplate shopTemplate = shopTemplateService.getById(templateId); |
| | | shopTemplate.setTemplateId(null); |
| | | shopTemplate.setName(shopTemplate.getName()+"副本"); |
| | | shopTemplate.setCreateTime(new Date()); |
| | | shopTemplate.setUpdateTime(new Date()); |
| | | shopTemplateService.save(shopTemplate); |
| | | return ServerResponseEntity.success(shopTemplate.getTemplateId()); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import cn.hutool.core.util.BooleanUtil; |
| | | import com.yami.shop.bean.model.ShopRenovation; |
| | | import com.yami.shop.bean.model.ShopTemplate; |
| | | import com.yami.shop.common.annotation.SysLog; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.service.ShopTemplateService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.Date; |
| | | import java.util.Objects; |
| | | |
| | | |
| | | /** |
| | | * |
| | | * |
| | | * @author LGH |
| | | * @date 2022-07-29 16:54:02 |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/shopTemplate") |
| | | //@ConditionalOnProperty(prefix = "yami", name = "expose.operation.auth", havingValue = "true", matchIfMissing = true) |
| | | @Tag(name = "店铺模板-修改、删除、设为主页") |
| | | public class ShopTemplateUpDelController { |
| | | |
| | | @Value("${yami.expose.operation.auth:}") |
| | | private Boolean permission; |
| | | |
| | | @Autowired |
| | | private ShopTemplateService shopTemplateService; |
| | | |
| | | @SysLog("修改店铺模板信息" ) |
| | | @PutMapping("/updatePC") |
| | | @PreAuthorize("@pms.hasPermission('platform:shopTemplate:updatePC')") |
| | | @Operation(summary = "PC端修改店铺模板信息" , description = "PC端修改店铺模板信息") |
| | | public ServerResponseEntity<Boolean> updatePCById(@RequestBody @Valid ShopTemplate shopTemplate) { |
| | | ShopTemplate shopTemplateDb = shopTemplateService.getById(shopTemplate.getTemplateId()); |
| | | if(BooleanUtil.isFalse(permission) || !Objects.equals(shopTemplateDb.getShopId() , Constant.PLATFORM_SHOP_ID)){ |
| | | // 没有权限进行操作 |
| | | throw new YamiShopBindException("yami.no.auth"); |
| | | } |
| | | shopTemplate.setUpdateTime(new Date()); |
| | | return ServerResponseEntity.success(shopTemplateService.updateById(shopTemplate)); |
| | | } |
| | | |
| | | @SysLog("修改店铺模板信息" ) |
| | | @PutMapping("/updateMove") |
| | | @PreAuthorize("@pms.hasPermission('platform:shopTemplate:updateMove')") |
| | | @Operation(summary = "移动端修改店铺模板信息" , description = "移动端修改店铺模板信息") |
| | | public ServerResponseEntity<Boolean> updateMoveById(@RequestBody @Valid ShopTemplate shopTemplate) { |
| | | ShopTemplate shopTemplateDb = shopTemplateService.getById(shopTemplate.getTemplateId()); |
| | | if(BooleanUtil.isFalse(permission) || !Objects.equals(shopTemplateDb.getShopId() , Constant.PLATFORM_SHOP_ID)){ |
| | | // 没有权限进行操作 |
| | | throw new YamiShopBindException("yami.no.auth"); |
| | | } |
| | | shopTemplate.setUpdateTime(new Date()); |
| | | return ServerResponseEntity.success(shopTemplateService.updateById(shopTemplate)); |
| | | } |
| | | |
| | | @SysLog("删除店铺模板信息" ) |
| | | @DeleteMapping("/deletePC/{templateId}") |
| | | @PreAuthorize("@pms.hasPermission('platform:shopTemplate:deletePC')") |
| | | @Operation(summary = "PC端通过id删除店铺模板信息" , description = "PC端通过id删除店铺模板信息") |
| | | @Parameter(name = "templateId", description = "店铺模板id" ) |
| | | public ServerResponseEntity<Boolean> removePCById(@PathVariable Long templateId) { |
| | | ShopTemplate shopTemplate = shopTemplateService.getById(templateId); |
| | | if(BooleanUtil.isFalse(permission) || !Objects.equals(shopTemplate.getShopId() ,Constant.PLATFORM_SHOP_ID)){ |
| | | // 没有权限进行操作 |
| | | throw new YamiShopBindException("yami.no.auth"); |
| | | } |
| | | return ServerResponseEntity.success(shopTemplateService.removeById(templateId)); |
| | | } |
| | | |
| | | @SysLog("删除店铺模板信息" ) |
| | | @DeleteMapping("/deleteMove/{templateId}") |
| | | @PreAuthorize("@pms.hasPermission('platform:shopTemplate:deleteMove')") |
| | | @Operation(summary = "移动端通过id删除店铺模板信息" , description = "移动端通过id删除店铺模板信息") |
| | | @Parameter(name = "templateId", description = "店铺模板id" ) |
| | | public ServerResponseEntity<Boolean> removeMoveById(@PathVariable Long templateId) { |
| | | ShopTemplate shopTemplate = shopTemplateService.getById(templateId); |
| | | if(BooleanUtil.isFalse(permission) || !Objects.equals(shopTemplate.getShopId() ,Constant.PLATFORM_SHOP_ID)){ |
| | | // 没有权限进行操作 |
| | | throw new YamiShopBindException("yami.no.auth"); |
| | | } |
| | | return ServerResponseEntity.success(shopTemplateService.removeById(templateId)); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.model.ShopWallet; |
| | | import com.yami.shop.bean.model.ShopWalletLog; |
| | | import com.yami.shop.bean.param.CustomerReqParam; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.ShopWalletLogService; |
| | | import com.yami.shop.service.ShopWalletService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | |
| | | |
| | | /** |
| | | * 商家钱包信息 |
| | | * |
| | | * @author LGH |
| | | * @date 2019-09-29 11:10:12 |
| | | */ |
| | | @RestController |
| | | @AllArgsConstructor |
| | | @RequestMapping("/shop/shopWallet" ) |
| | | @Tag(name = "商家钱包") |
| | | public class ShopWalletController { |
| | | |
| | | private final ShopWalletService shopWalletService; |
| | | private final ShopWalletLogService shopWalletLogService; |
| | | |
| | | @GetMapping("/page" ) |
| | | @Operation(summary = "分页查询" , description = "分页查询") |
| | | public ServerResponseEntity<IPage<ShopWallet>> getShopWalletPage(PageParam<ShopWallet> page, @ParameterObject ShopWallet shopWallet) { |
| | | return ServerResponseEntity.success(shopWalletService.pageShopWallet(page, shopWallet)); |
| | | } |
| | | |
| | | @GetMapping("/getShopWallet") |
| | | @Operation(summary = "查看店铺钱包信息" , description = "根据店铺id查看店铺钱包信息") |
| | | public ServerResponseEntity<ShopWallet> getShopWalletVoByShopId(){ |
| | | ShopWallet shopWallet = shopWalletService.getShopWalletByShopId(Constant.PLATFORM_SHOP_ID); |
| | | return ServerResponseEntity.success(shopWallet); |
| | | } |
| | | |
| | | @GetMapping("/pagePlatformInfo") |
| | | @Operation(summary = "分页查询平台收入明细" , description = "分页查询平台收入明细") |
| | | public ServerResponseEntity<IPage<ShopWalletLog>> getShopWalletLogPage(PageParam<ShopWalletLog> page, @ParameterObject ShopWalletLog shopWalletLog){ |
| | | shopWalletLog.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | IPage<ShopWalletLog> shopWalletLogPage = shopWalletLogService.pageByParam(page, shopWalletLog); |
| | | return ServerResponseEntity.success(shopWalletLogPage); |
| | | } |
| | | |
| | | @GetMapping("/getAllShopWallet") |
| | | @Operation(summary = "查看店铺钱包总信息") |
| | | public ServerResponseEntity<ShopWallet> getAllShopWalletVoByShopId(@ParameterObject CustomerReqParam customerReqParam) { |
| | | ShopWallet shopWallet = shopWalletService.getAllShop(customerReqParam); |
| | | return ServerResponseEntity.success(shopWallet); |
| | | } |
| | | |
| | | @GetMapping("/pageShopWalletByTime") |
| | | @Operation(summary = "分页查看店铺钱包总信息") |
| | | public ServerResponseEntity<IPage<ShopWallet>> pageShopWalletByTime(PageParam<ShopWallet> page, @ParameterObject CustomerReqParam customerReqParam) { |
| | | IPage<ShopWallet> shopWalletPage = shopWalletService.pageShopWalletByTime(page, customerReqParam); |
| | | return ServerResponseEntity.success(shopWalletPage); |
| | | } |
| | | |
| | | @GetMapping("/pageAllShop") |
| | | @Operation(summary = "查看所有店铺的日志") |
| | | public ServerResponseEntity<IPage<ShopWalletLog>> getAllShopWalletLogPage(PageParam<ShopWallet> page, @ParameterObject ShopWalletLog shopWalletLog) { |
| | | IPage<ShopWalletLog> shopWalletLogPage = shopWalletLogService.pageAllShop(page, shopWalletLog); |
| | | return ServerResponseEntity.success(shopWalletLogPage); |
| | | } |
| | | |
| | | @GetMapping("/getShopWalletLogForm") |
| | | @Operation(summary = "导出报表" , description = "导出店铺结算报表") |
| | | @PreAuthorize("@pms.hasPermission('shop:wallet:excel')") |
| | | public void getShopWalletLogForm(@ParameterObject CustomerReqParam customerReqParam, HttpServletResponse response) { |
| | | shopWalletLogService.excelShopWalletLog(customerReqParam, response); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.dto.ShopWithdrawCashConfigDto; |
| | | import com.yami.shop.bean.model.ShopDetail; |
| | | import com.yami.shop.bean.model.ShopWithdrawCash; |
| | | import com.yami.shop.common.annotation.SysLog; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.security.platform.util.SecurityUtils; |
| | | import com.yami.shop.service.ShopDetailService; |
| | | import com.yami.shop.service.ShopWithdrawCashService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | |
| | | |
| | | /** |
| | | * 商家提现申请信息 |
| | | * |
| | | * @author LGH |
| | | * @date 2019-09-29 11:10:12 |
| | | */ |
| | | @RestController |
| | | @AllArgsConstructor |
| | | @RequestMapping("/shop/shopWithdrawCash") |
| | | @Tag(name = "商家提现申请信息") |
| | | public class ShopWithdrawCashController { |
| | | |
| | | private final ShopWithdrawCashService shopWithdrawCashService; |
| | | |
| | | private final ShopDetailService shopDetailService; |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "分页查询" , description = "分页查询") |
| | | public ServerResponseEntity<IPage<ShopWithdrawCash>> getShopWithdrawCashPage(PageParam<ShopWithdrawCash> page, @ParameterObject ShopWithdrawCash shopWithdrawCash) { |
| | | return ServerResponseEntity.success(shopWithdrawCashService.pageShopWithdrawCash(page, shopWithdrawCash)); |
| | | } |
| | | |
| | | @GetMapping("/exportShopWithdrawCash") |
| | | @Operation(summary = "导出商家提现信息" , description = "导出商家提现信息") |
| | | public void exportShopWithdrawCash(@ParameterObject ShopWithdrawCash shopWithdrawCash, HttpServletResponse response) { |
| | | shopWithdrawCashService.exportShopWithdrawCash(shopWithdrawCash, response); |
| | | } |
| | | |
| | | @GetMapping("/info/{cashId}") |
| | | @Operation(summary = "查询商家提现申请信息" , description = "查询商家提现申请信息") |
| | | @Parameter(name = "cashId", description = "商家提现申请id" ) |
| | | public ServerResponseEntity<ShopWithdrawCash> getById(@PathVariable("cashId") Long cashId) { |
| | | return ServerResponseEntity.success(shopWithdrawCashService.getById(cashId)); |
| | | } |
| | | |
| | | @SysLog("审核商家提现信息") |
| | | @PutMapping("/audit") |
| | | @PreAuthorize("@pms.hasPermission('shop:shopWithdrawCash:audit')") |
| | | @Operation(summary = "审核信息" , description = "审核信息") |
| | | public ServerResponseEntity<Void> audit(@RequestBody ShopWithdrawCash shopWithdrawCash) { |
| | | ShopWithdrawCash dbShopWithdrawCash = shopWithdrawCashService.getById(shopWithdrawCash.getCashId()); |
| | | if (dbShopWithdrawCash == null) { |
| | | // 未找到申请信息 |
| | | throw new YamiShopBindException("yami.store.apply.no.exist"); |
| | | } |
| | | ShopDetail shopdetail = shopDetailService.getShopDetailByShopId(dbShopWithdrawCash.getShopId()); |
| | | if (shopdetail == null) { |
| | | // 未找到该店铺信息 |
| | | throw new YamiShopBindException("yami.store.not.exist"); |
| | | } |
| | | shopWithdrawCash.setCreateTime(null); |
| | | |
| | | shopWithdrawCashService.auditWithdrawCash(shopWithdrawCash.getCashId(), shopWithdrawCash, SecurityUtils.getSysUser().getUserId(), null); |
| | | // 减少冻结金额 |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PostMapping("/save") |
| | | @Operation(summary = "设置提现金额" , description = "设置提现金额") |
| | | public ServerResponseEntity<Void> saveWithdrawCashConfig(@RequestBody ShopWithdrawCashConfigDto shopWithdrawCashDto) { |
| | | shopWithdrawCashService.saveConfig(shopWithdrawCashDto); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | @GetMapping("/getWithdrawCash") |
| | | public ServerResponseEntity<ShopWithdrawCashConfigDto> getWithdrawCashConfig(){ |
| | | return ServerResponseEntity.success(shopWithdrawCashService.getConfig()); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.dto.BrandShopDTO; |
| | | import com.yami.shop.bean.model.*; |
| | | import com.yami.shop.common.i18n.I18nMessage; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.security.platform.util.SecurityUtils; |
| | | import com.yami.shop.service.SigningAuditingService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Parameters; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * @Author lth |
| | | * @Date 2021/8/19 13:51 |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/signingAuditing") |
| | | @Tag(name = "签约信息相关接口") |
| | | public class SigningAuditingController { |
| | | |
| | | @Autowired |
| | | private SigningAuditingService signingAuditingService; |
| | | |
| | | @GetMapping("/listApplySigningCategory") |
| | | @Operation(summary = "获取可以签约的平台分类列表(已经签约的平台分类不会返回)" , description = "获取可以签约的平台分类列表(已经签约的平台分类不会返回)") |
| | | @Parameter(name = "shopId", description = "店铺id" ) |
| | | public ServerResponseEntity<List<Category>> listApplySigningCategory(@RequestParam("shopId") Long shopId) { |
| | | List<Category> categoryList = signingAuditingService.listApplySigningCategory(shopId, I18nMessage.getLang()); |
| | | return ServerResponseEntity.success(categoryList); |
| | | } |
| | | |
| | | @GetMapping("/listApplySigningBrand") |
| | | @Operation(summary = "获取可以签约的平台品牌列表(已经签约的平台品牌不会返回)" , description = "获取可以签约的平台品牌列表(已经签约的平台品牌不会返回)") |
| | | public ServerResponseEntity<List<Brand>> listApplySigningBrand(@ParameterObject Brand brand) { |
| | | Long shopId = brand.getShopId(); |
| | | if (Objects.isNull(shopId)) { |
| | | return ServerResponseEntity.success(new ArrayList<>()); |
| | | } |
| | | brand.setShopId(null); |
| | | List<Brand> brandList = signingAuditingService.listApplySigningBrand(shopId, brand, I18nMessage.getLang()); |
| | | return ServerResponseEntity.success(brandList); |
| | | } |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "分页获取待审核的签约信息" , description = "分页获取待审核的签约信息") |
| | | public ServerResponseEntity<IPage<SigningAuditing>> page(PageParam<SigningAuditing> page, @ParameterObject SigningAuditing signingAuditing) { |
| | | IPage<SigningAuditing> signingAuditingPage = signingAuditingService.pageSigningAuditing(page, signingAuditing); |
| | | return ServerResponseEntity.success(signingAuditingPage); |
| | | } |
| | | |
| | | @PutMapping("/audit") |
| | | @Operation(summary = "审核签约信息" , description = "审核签约信息") |
| | | public ServerResponseEntity<Void> audit(@Valid @RequestBody SigningAuditing signingAuditing) { |
| | | signingAuditing.setAuditorId(SecurityUtils.getSysUser().getUserId()); |
| | | signingAuditingService.audit(signingAuditing); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping("/updateCategoryRate") |
| | | @Operation(summary = "更新店铺签约分类自定义扣率" , description = "更新店铺签约分类自定义扣率") |
| | | @Parameters(value = { |
| | | @Parameter(name = "categoryShopId", description = "店铺签约分类id" ), |
| | | @Parameter(name = "rate", description = "扣率" ) |
| | | }) |
| | | public ServerResponseEntity<Void> updateCategoryRate(@RequestParam("categoryShopId") Long categoryShopId, @RequestParam("rate") Double rate) { |
| | | signingAuditingService.updateCategoryRate(categoryShopId, rate); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PostMapping("/addSigningCategory") |
| | | @Operation(summary = "增加签约分类" , description = "增加签约分类") |
| | | @Parameters(value = { |
| | | @Parameter(name = "categoryShopList", description = "店铺签约分类id列表" ), |
| | | @Parameter(name = "shopId", description = "店铺id" ) |
| | | }) |
| | | public ServerResponseEntity<Void> addSigningCategory(@RequestBody List<CategoryShop> categoryShopList, @RequestParam("shopId") Long shopId) { |
| | | signingAuditingService.addSigningCategory(categoryShopList, shopId); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PostMapping("/addSigningBrand") |
| | | @Operation(summary = "增加签约品牌" , description = "增加签约品牌") |
| | | @Parameters(value = { |
| | | @Parameter(name = "brandShopList", description = "店铺签约品牌id列表" ), |
| | | @Parameter(name = "shopId", description = "店铺id" ) |
| | | }) |
| | | public ServerResponseEntity<Void> addSigningBrand(@RequestBody List<BrandShopDTO> brandShopList, @RequestParam("shopId") Long shopId) { |
| | | signingAuditingService.addSigningBrand(brandShopList, shopId); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.yami.shop.bean.model.Sku; |
| | | import com.yami.shop.common.i18n.I18nMessage; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.service.SkuService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author yami |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/sku") |
| | | @AllArgsConstructor |
| | | @Tag(name = "商品sku") |
| | | public class SkuController { |
| | | |
| | | private final SkuService skuService; |
| | | |
| | | @GetMapping("/getAllSkuList") |
| | | @PreAuthorize("@pms.hasPermission('plateform:sku:list')") |
| | | @Operation(summary = "获取指定商品sku列表" , description = "获取指定商品sku列表") |
| | | @Parameter(name = "prodId", description = "商品id" ) |
| | | public ServerResponseEntity<List<Sku>> getSkuListByProdId(Long prodId) { |
| | | List<Sku> skus = skuService.listSkuAndSkuStock(prodId, I18nMessage.getDbLang()); |
| | | return ServerResponseEntity.success(skus); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.enums.ProdPropRule; |
| | | import com.yami.shop.bean.model.ProdProp; |
| | | import com.yami.shop.bean.model.ProdPropValue; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.ProdPropService; |
| | | import com.yami.shop.service.ProdPropValueService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 规格管理 |
| | | * |
| | | * @author lgh |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/prod/spec") |
| | | @Tag(name = "规格") |
| | | public class SpecController { |
| | | |
| | | @Autowired |
| | | private ProdPropService prodPropService; |
| | | @Autowired |
| | | private ProdPropValueService prodPropValueService; |
| | | |
| | | @GetMapping("/list") |
| | | @Operation(summary = "获取所有的规格" , description = "获取所有的规格") |
| | | public ServerResponseEntity<List<ProdProp>> list() { |
| | | // List<ProdProp> list = prodPropService.list(new LambdaQueryWrapper<ProdProp>() |
| | | // .eq(ProdProp::getRule, ProdPropRule.SPEC.value()). |
| | | // eq(ProdProp::getShopId, Constant.PLATFORM_SHOP_ID)); |
| | | ProdProp prodProp = new ProdProp(); |
| | | prodProp.setShopId( Constant.PLATFORM_SHOP_ID); |
| | | prodProp.setRule(ProdPropRule.SPEC.value()); |
| | | List<ProdProp> list = prodPropService.listByLang(prodProp); |
| | | return ServerResponseEntity.success(list); |
| | | } |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "分页获取" , description = "分页获取") |
| | | public ServerResponseEntity<IPage<ProdProp>> page(@ParameterObject ProdProp prodProp, PageParam<ProdProp> page) { |
| | | prodProp.setRule(ProdPropRule.SPEC.value()); |
| | | prodProp.setShopId( Constant.PLATFORM_SHOP_ID); |
| | | IPage<ProdProp> list = prodPropService.pagePropAndValue(prodProp, page); |
| | | return ServerResponseEntity.success(list); |
| | | } |
| | | |
| | | @GetMapping("/listSpecValue/{specId}") |
| | | @Operation(summary = "根据规格id获取规格值" , description = "根据规格id获取规格值") |
| | | @Parameter(name = "specId", description = "规格id" ) |
| | | public ServerResponseEntity<List<ProdPropValue>> listSpecValue(@PathVariable("specId") Long specId) { |
| | | // List<ProdPropValue> list = prodPropValueService.list(new LambdaQueryWrapper<ProdPropValue>().eq(ProdPropValue::getPropId, specId)) |
| | | List<ProdPropValue> list = prodPropValueService.propValueListByPropId(specId); |
| | | return ServerResponseEntity.success(list); |
| | | } |
| | | |
| | | @PostMapping |
| | | @Operation(summary = "保存" , description = "保存") |
| | | public ServerResponseEntity<Void> save(@Valid @RequestBody ProdProp prodProp) { |
| | | prodProp.setRule(ProdPropRule.SPEC.value()); |
| | | prodProp.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | prodPropService.saveProdPropAndValues(prodProp); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping |
| | | @Operation(summary = "修改" , description = "修改") |
| | | public ServerResponseEntity<Void> update(@Valid @RequestBody ProdProp prodProp) { |
| | | prodProp.setRule(ProdPropRule.SPEC.value()); |
| | | prodPropService.updateProdPropAndValues(prodProp); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @DeleteMapping("/{id}") |
| | | @Operation(summary = "删除" , description = "删除") |
| | | @Parameter(name = "id", description = "规格id" ) |
| | | public ServerResponseEntity<Void> delete(@PathVariable Long id) { |
| | | prodPropService.deleteProdPropAndValues(id, ProdPropRule.SPEC.value(), Constant.PLATFORM_SHOP_ID); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.yami.shop.bean.vo.statistics.HotStatisticsVO; |
| | | import com.yami.shop.bean.vo.statistics.PlatformStatisticsVO; |
| | | import com.yami.shop.bean.vo.statistics.TrendStatisticsVO; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.service.StatisticsService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author chiley |
| | | * @create 2022/5/16 15:34 |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/statistics") |
| | | @AllArgsConstructor |
| | | @Tag(name = "平台统计信息") |
| | | public class StatisticsController { |
| | | |
| | | private final StatisticsService statisticsService; |
| | | |
| | | @GetMapping("/getPlatformStatistics") |
| | | @Operation(summary = "获取主页基本信息、今日待办") |
| | | public ServerResponseEntity<PlatformStatisticsVO> getPlatformStatistics() { |
| | | return ServerResponseEntity.success(statisticsService.getPlatformStatistics()); |
| | | } |
| | | |
| | | @GetMapping("/platformRealTimeOverview") |
| | | @Operation(summary = "获取主页实时概括") |
| | | @Parameter(name = "startTime", description = "开始时间" ) |
| | | public ServerResponseEntity<PlatformStatisticsVO> platformRealTimeOverview(@DateTimeFormat(pattern = "yyyy-MM-dd") @RequestParam("startTime") Date startTime) { |
| | | return ServerResponseEntity.success(statisticsService.platformRealTimeOverview(startTime)); |
| | | } |
| | | |
| | | @GetMapping("/prod") |
| | | @Operation(summary = "获取某段时间内的商品销量排行") |
| | | public ServerResponseEntity<List<HotStatisticsVO>> getHotProds(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @RequestParam("startTime") Date startTime, |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @RequestParam("endTime") Date endTime) { |
| | | |
| | | return ServerResponseEntity.success(statisticsService.loadHotProdByDate(startTime, endTime)); |
| | | } |
| | | |
| | | |
| | | @GetMapping("/shop") |
| | | @Operation(summary = "获取某段时间内的店铺销量排行") |
| | | public ServerResponseEntity<List<HotStatisticsVO>> getHotShops(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @RequestParam("startTime") Date startTime, |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @RequestParam("endTime") Date endTime) { |
| | | |
| | | |
| | | return ServerResponseEntity.success(statisticsService.loadHotShopByDate(startTime, endTime)); |
| | | } |
| | | |
| | | @GetMapping("/trendData") |
| | | @Operation(summary = "获取某段时间内的交易数据") |
| | | public ServerResponseEntity<List<TrendStatisticsVO>> getTrendData(@DateTimeFormat(pattern = "yyyy-MM-dd") @RequestParam("startTime") Date startTime, |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd") @RequestParam("endTime") Date endTime) { |
| | | |
| | | |
| | | return ServerResponseEntity.success(statisticsService.loadDataTrend(null, startTime, endTime)); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | |
| | | import cn.hutool.core.date.DateUtil; |
| | | import com.yami.shop.bean.app.dto.OrderCountData; |
| | | import com.yami.shop.bean.dto.StatisticsRefundDto; |
| | | import com.yami.shop.bean.param.OrderPayParam; |
| | | import com.yami.shop.bean.param.StatisticsRefundParam; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.service.StatisticsOrderService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author lhd on 2019/10/19. |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/statisticsOrder") |
| | | @AllArgsConstructor |
| | | @Tag(name = "platform") |
| | | public class StatisticsOrderController { |
| | | |
| | | private final StatisticsOrderService statisticsOrderService; |
| | | |
| | | @GetMapping("/orderCount") |
| | | @Operation(summary = "查询店铺订单各状态数量" , description = "查询店铺订单各状态数量") |
| | | public ServerResponseEntity<OrderCountData> getOrderCount() { |
| | | OrderCountData orderCountData = statisticsOrderService.getOrderCountOfStatusByShopId(null); |
| | | return ServerResponseEntity.success(orderCountData); |
| | | } |
| | | |
| | | @GetMapping("/orderPayByShopId") |
| | | @Operation(summary = "通过时间获取支付信息") |
| | | public ServerResponseEntity<OrderPayParam> orderPayByShopId() { |
| | | OrderPayParam actualTotal = statisticsOrderService.getPayUserCountByshopId(null,DateUtil.beginOfDay(DateUtil.date()), DateUtil.endOfDay(DateUtil.date())); |
| | | return ServerResponseEntity.success(actualTotal); |
| | | } |
| | | |
| | | @GetMapping("/getActualTotalByHour") |
| | | @Operation(summary = "通过24小时分段获取支付金额") |
| | | public ServerResponseEntity<OrderPayParam> getActualTotalByHour() { |
| | | OrderPayParam payList = statisticsOrderService.getActualTotalByHour( |
| | | null,DateUtil.beginOfDay(DateUtil.date()),DateUtil.endOfDay(DateUtil.date())); |
| | | return ServerResponseEntity.success(payList); |
| | | } |
| | | |
| | | @GetMapping("/getActualTotalByDay") |
| | | @Operation(summary = "通过天数分段获取支付金额") |
| | | public ServerResponseEntity<List<OrderPayParam>> getActualTotalByDay() { |
| | | List<OrderPayParam> payList = statisticsOrderService.getActualTotalByDay( |
| | | null,DateUtil.endOfDay(DateUtil.lastMonth()),DateUtil.endOfDay(DateUtil.date())); |
| | | return ServerResponseEntity.success(payList); |
| | | } |
| | | |
| | | @GetMapping("/getOrderRefundByTime") |
| | | @Operation(summary = "通过时间获取比率信息") |
| | | public ServerResponseEntity<StatisticsRefundParam> getOrderRefundByTime() { |
| | | StatisticsRefundParam refundParam = statisticsOrderService.getOrderRefundByShopId( |
| | | null,DateUtil.beginOfDay(DateUtil.date()), DateUtil.endOfDay(DateUtil.date())); |
| | | return ServerResponseEntity.success(refundParam); |
| | | } |
| | | |
| | | @GetMapping("/getOrderRefundDayByTime") |
| | | @Operation(summary = "通过时间获取分段比率信息及退款金额信息") |
| | | public ServerResponseEntity<List<StatisticsRefundParam>> getOrderRefundById() { |
| | | List<StatisticsRefundParam> refundList = statisticsOrderService.getOrderRefundByShopIdAndDay( |
| | | null,DateUtil.endOfDay(DateUtil.lastMonth()),DateUtil.endOfDay(DateUtil.date())); |
| | | return ServerResponseEntity.success(refundList); |
| | | } |
| | | |
| | | @GetMapping("/getRefundRankingByProd") |
| | | @Operation(summary = "根据商品名生成退款排行") |
| | | public ServerResponseEntity<List<StatisticsRefundParam>> getRefundRankingByProd() { |
| | | /* |
| | | * 如果一个订单有多个商品的,整单退款,用户输入退款金额少于支付金额, |
| | | * 无法确认某个商品的准确退款金额,所以就用整个订单来代替 |
| | | * 例如:订单中 商品A 100 元,商品B 8元,共支付108元,整单退款,退款金额为90元, |
| | | * 所以商品的退款金额在这个时候是模糊的,不能准确统计 |
| | | */ |
| | | List<StatisticsRefundParam> refundList = statisticsOrderService.getRefundRankingByProd(new StatisticsRefundDto()); |
| | | return ServerResponseEntity.success(refundList); |
| | | } |
| | | |
| | | @GetMapping("/getRefundRankingByReason") |
| | | @Operation(summary = "根据退款原因生成退款排行") |
| | | public ServerResponseEntity<List<StatisticsRefundParam>> getRefundRankingByReason() { |
| | | List<StatisticsRefundParam> refundList = statisticsOrderService.getRefundRankingByReason( |
| | | null,DateUtil.endOfDay(DateUtil.lastMonth()),DateUtil.endOfDay(DateUtil.date())); |
| | | return ServerResponseEntity.success(refundList); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.yami.shop.bean.model.StockChangeReason; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.StockChangeReasonService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Parameters; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.List; |
| | | |
| | | |
| | | /** |
| | | * |
| | | * 出入库原因 |
| | | * @author LGH |
| | | * @date 2021-09-07 16:04:18 |
| | | */ |
| | | @RestController |
| | | @AllArgsConstructor |
| | | @RequestMapping("/platform/stockChangeReason" ) |
| | | @Tag(name = "platform") |
| | | public class StockChangeReasonController { |
| | | |
| | | private final StockChangeReasonService stockChangeReasonService; |
| | | |
| | | @GetMapping("/page" ) |
| | | @Operation(summary = "分页获取出入库原因" , description = "分页获取出入库原因") |
| | | public ServerResponseEntity<IPage<StockChangeReason>> getStockChangeReasonPage(PageParam<StockChangeReason> page, @ParameterObject StockChangeReason stockChangeReason) { |
| | | stockChangeReason.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | return ServerResponseEntity.success(stockChangeReasonService.pageByParams(page, stockChangeReason)); |
| | | } |
| | | |
| | | @GetMapping("/list") |
| | | @Schema(description = "获取出入库原因列表" ) |
| | | public ServerResponseEntity<List<StockChangeReason>> listResponse(@ParameterObject StockChangeReason stockChangeReason) { |
| | | stockChangeReason.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | return ServerResponseEntity.success(stockChangeReasonService.listByParams(stockChangeReason)); |
| | | } |
| | | |
| | | @GetMapping("/info/{stockChangeReasonId}" ) |
| | | @Operation(summary = "根据id查询出入库原因" , description = "根据id查询出入库原因") |
| | | public ServerResponseEntity<StockChangeReason> getById(@PathVariable("stockChangeReasonId") Long stockChangeReasonId) { |
| | | Long shopId = Constant.PLATFORM_SHOP_ID; |
| | | StockChangeReason stockChangeReason = stockChangeReasonService.getOne(Wrappers.lambdaQuery(StockChangeReason.class) |
| | | .eq(StockChangeReason::getStockChangeReasonId, stockChangeReasonId) |
| | | .eq(StockChangeReason::getShopId, shopId) |
| | | ); |
| | | stockChangeReason.setShopId(null); |
| | | return ServerResponseEntity.success(stockChangeReason); |
| | | } |
| | | |
| | | @PostMapping |
| | | @Operation(summary = "新增出入库原因" , description = "新增出入库原因") |
| | | public ServerResponseEntity<Void> save(@RequestBody @Valid StockChangeReason stockChangeReason) { |
| | | stockChangeReason.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | stockChangeReasonService.saveInfo(stockChangeReason); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping |
| | | @Operation(summary = "修改出入库原因" , description = "修改出入库原因") |
| | | public ServerResponseEntity<Void> updateById(@RequestBody @Valid StockChangeReason stockChangeReason) { |
| | | stockChangeReason.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | stockChangeReasonService.updateInfo(stockChangeReason); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping("/changeStatus" ) |
| | | @Schema(description = "修改出入库原因状态" ) |
| | | @Parameters(value = { |
| | | @Parameter(name = "stockChangeReasonId", description = "出入库原因id" ), |
| | | @Parameter(name = "status", description = "状态,1:启用 0:禁用" ) |
| | | }) |
| | | public ServerResponseEntity<Void> removeById(@RequestParam("stockChangeReasonId") Long stockChangeReasonId, @RequestParam("status") Integer status) { |
| | | Long shopId = Constant.PLATFORM_SHOP_ID; |
| | | stockChangeReasonService.update(Wrappers.lambdaUpdate(StockChangeReason.class) |
| | | .set(StockChangeReason::getStatus, status) |
| | | .eq(StockChangeReason::getStockChangeReasonId, stockChangeReasonId) |
| | | .eq(StockChangeReason::getShopId, shopId) |
| | | ); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.common.response.ResponseEnum; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.task.common.model.Task; |
| | | import com.yami.shop.task.common.model.TaskRule; |
| | | import com.yami.shop.task.common.service.TaskRuleService; |
| | | import com.yami.shop.task.common.service.TaskService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author tz_task_user |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/taskRule") |
| | | @Tag(name = "任务规则表接口") |
| | | @AllArgsConstructor |
| | | public class TaskRuleController { |
| | | |
| | | @Resource |
| | | private TaskRuleService taskRuleService; |
| | | @Resource |
| | | private TaskService taskService; |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "分页查询任务规则表列表信息") |
| | | public ServerResponseEntity<IPage<TaskRule>> getTaskRulePage(PageParam<TaskRule> page, TaskRule taskRule) { |
| | | IPage<TaskRule> resultPage = taskRuleService.getTaskRulePage(page,taskRule ); |
| | | return ServerResponseEntity.success(resultPage); |
| | | } |
| | | |
| | | @GetMapping("/info/{id}") |
| | | @Operation(summary = "通过任务规则表id查询任务规则表信息") |
| | | @Parameter(name = "id", description = "任务规则表id" , required = true) |
| | | public ServerResponseEntity<TaskRule> getTaskRuleById(@PathVariable("id") Long id) { |
| | | TaskRule card = taskRuleService.getById(id); |
| | | return ServerResponseEntity.success(card); |
| | | } |
| | | |
| | | @PostMapping("/saveTaskRule") |
| | | @Operation(summary = "新增任务规则表信息") |
| | | public ServerResponseEntity<String> saveTaskRule(@RequestBody TaskRule taskRule) { |
| | | Integer num = taskRuleService.saveTaskRule(taskRule); |
| | | if(num >0 ){ |
| | | return ServerResponseEntity.success(ResponseEnum.OK.getMsg()); |
| | | }else{ |
| | | return ServerResponseEntity.showFailMsg(ResponseEnum.ERROR.getMsg()); |
| | | } |
| | | } |
| | | @PostMapping("/updateTaskRule") |
| | | @Operation(summary = "修改任务规则表信息") |
| | | public ServerResponseEntity<String> updateTaskRule(@RequestBody TaskRule taskRule) { |
| | | Integer num = taskRuleService.updateTaskRule(taskRule); |
| | | if(num >0 ){ |
| | | return ServerResponseEntity.success(ResponseEnum.OK.getMsg()); |
| | | }else{ |
| | | return ServerResponseEntity.showFailMsg(ResponseEnum.ERROR.getMsg()); |
| | | } |
| | | } |
| | | |
| | | |
| | | @DeleteMapping("/{id}") |
| | | @Operation(summary = "删除任务规则信息") |
| | | public ServerResponseEntity<String> deleteTaskRule(@PathVariable("id") Long ruleId) { |
| | | int num =taskRuleService.deleteTaskRule(ruleId); |
| | | if(num>0){ |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | return ServerResponseEntity.showFailMsg("删除任务规则信息失败!"); |
| | | } |
| | | |
| | | |
| | | @GetMapping("/selectStatusByTaskId") |
| | | @Operation(summary = "根据任务Id获取任务状态") |
| | | public ServerResponseEntity<List<TaskRule>> selectStatusByTaskId(@RequestParam(value = "taskId") Long taskId) { |
| | | List<TaskRule> list = taskRuleService.selectStatusByTaskId(taskId); |
| | | return ServerResponseEntity.success(list); |
| | | } |
| | | |
| | | @GetMapping("/selectTasks") |
| | | @Operation(summary = "查询状态在启动状态下的任务列表") |
| | | public ServerResponseEntity<List<Task>> selectTasks(Task task) { |
| | | List<Task> list = taskService.getTaskList(task); |
| | | return ServerResponseEntity.success(list); |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.common.response.ResponseEnum; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.task.common.model.Task; |
| | | import com.yami.shop.task.common.model.TaskUser; |
| | | import com.yami.shop.task.common.service.TaskService; |
| | | import com.yami.shop.task.common.service.TaskUserService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.annotation.Resource; |
| | | |
| | | /** |
| | | * @author tz_task_user |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/taskUser") |
| | | @Tag(name = "用户任务表接口") |
| | | @AllArgsConstructor |
| | | public class TaskUserController { |
| | | |
| | | @Resource |
| | | private TaskUserService taskUserService; |
| | | |
| | | @Resource |
| | | private TaskService taskService; |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "分页查询用户任务表列表信息") |
| | | public ServerResponseEntity<IPage<TaskUser>> getTaskUserPage(PageParam<TaskUser> page, TaskUser TaskUser) { |
| | | IPage<TaskUser> resultPage = taskUserService.getTaskUserPage(page,TaskUser ); |
| | | return ServerResponseEntity.success(resultPage); |
| | | } |
| | | |
| | | @GetMapping("/info/{id}") |
| | | @Operation(summary = "通过用户任务表id查询用户任务表信息") |
| | | @Parameter(name = "id", description = "用户任务表id" , required = true) |
| | | public ServerResponseEntity<TaskUser> getTaskUserById(@PathVariable("id") Long id) { |
| | | TaskUser card = taskUserService.getById(id); |
| | | Task task =taskService.getById(card.getTaskId()); |
| | | card.setTaskTitle(task.getTaskTitle()); |
| | | return ServerResponseEntity.success(card); |
| | | } |
| | | |
| | | @PostMapping("/saveTaskUser") |
| | | @Operation(summary = "新增用户任务表信息") |
| | | public ServerResponseEntity<String> saveTaskUser(@RequestBody TaskUser taskUser) { |
| | | Integer num = taskUserService.saveTaskUser(taskUser); |
| | | if(num >0 ){ |
| | | return ServerResponseEntity.success(ResponseEnum.OK.getMsg()); |
| | | }else{ |
| | | return ServerResponseEntity.showFailMsg(ResponseEnum.ERROR.getMsg()); |
| | | } |
| | | } |
| | | @PostMapping("/updateTaskUser") |
| | | @Operation(summary = "修改用户任务表信息") |
| | | public ServerResponseEntity<String> updateTaskUser(@RequestBody TaskUser taskUser) { |
| | | Integer num = taskUserService.updateTaskUser(taskUser); |
| | | if(num >0 ){ |
| | | return ServerResponseEntity.success(ResponseEnum.OK.getMsg()); |
| | | }else{ |
| | | return ServerResponseEntity.showFailMsg(ResponseEnum.ERROR.getMsg()); |
| | | } |
| | | } |
| | | |
| | | @GetMapping("/deleteTaskUser/{id}") |
| | | @Operation(summary = "删除用户任务信息") |
| | | public ServerResponseEntity<?> deleteTaskUser(@PathVariable("id") Long id) { |
| | | int num =taskUserService.deleteTaskUser(id); |
| | | if(num>0){ |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | return ServerResponseEntity.showFailMsg("删除用户任务信息失败!"); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import cn.hutool.core.date.DateUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.yami.shop.bean.model.Order; |
| | | import com.yami.shop.bean.model.OrderItem; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.service.*; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * @author yxf on 2022/11/25. |
| | | */ |
| | | @RestController |
| | | @Tag(name = "测试接口-商城代码不要用,给自动化测试用的") |
| | | @RequestMapping("/platform/test") |
| | | public class TestController { |
| | | |
| | | @Autowired |
| | | private OrderService orderService; |
| | | |
| | | @Autowired |
| | | private OrderItemService orderItemService; |
| | | |
| | | @Autowired |
| | | private ProductService productService; |
| | | |
| | | @Autowired |
| | | private SkuService skuService; |
| | | |
| | | @PostMapping("/orderSettlement") |
| | | @Operation(summary = "订单结算" , description = "订单结算") |
| | | public ServerResponseEntity<Void> settlement(@RequestBody Long orderId) { |
| | | Date date = DateUtil.offsetDay(new Date(), -20).toJdkDate(); |
| | | Order order = new Order(); |
| | | order.setOrderId(orderId); |
| | | order.setUpdateTime(date); |
| | | order.setFinallyTime(date); |
| | | orderService.updateById(order); |
| | | order = orderService.getById(orderId); |
| | | List<OrderItem> orderItems = orderItemService.list(new LambdaQueryWrapper<OrderItem>().eq(OrderItem::getOrderNumber, order.getOrderNumber())); |
| | | order.setOrderItems(orderItems); |
| | | List<Order> orderList = Collections.singletonList(order); |
| | | |
| | | // 结算 |
| | | orderService.orderCommissionSettlement(orderList); |
| | | |
| | | // 移除缓存 |
| | | for (OrderItem orderItem : orderItems) { |
| | | productService.removeProdCacheByProdId(orderItem.getProdId()); |
| | | skuService.removeSkuCacheBySkuId(orderItem.getSkuId(), orderItem.getProdId()); |
| | | |
| | | } |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.yami.shop.bean.model.UserAddr; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.UserAddrService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.util.List; |
| | | |
| | | |
| | | /** |
| | | * @author lgh on 2018/10/16. |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/userAddr") |
| | | @Tag(name = "用户地址") |
| | | public class UserAddrController { |
| | | |
| | | @Autowired |
| | | private UserAddrService userAddrService; |
| | | |
| | | @GetMapping("/page") |
| | | @PreAuthorize("@pms.hasPermission('plateform:user:page')") |
| | | @Operation(summary = "分页获取" , description = "分页获取") |
| | | public ServerResponseEntity<List<UserAddr>> page(@ParameterObject UserAddr userAddr, PageParam<UserAddr> page) { |
| | | List<UserAddr> userAddrPage = userAddrService.list(new LambdaQueryWrapper<UserAddr>() |
| | | .eq(UserAddr::getUserId, userAddr.getUserId())); |
| | | return ServerResponseEntity.success(userAddrPage); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import cn.hutool.core.util.BooleanUtil; |
| | | import cn.hutool.core.util.PhoneUtil; |
| | | import cn.hutool.poi.excel.ExcelUtil; |
| | | import cn.hutool.poi.excel.ExcelWriter; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.qiniu.util.StringUtils; |
| | | import com.yami.shop.bean.model.User; |
| | | import com.yami.shop.bean.param.*; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.i18n.I18nMessage; |
| | | import com.yami.shop.common.i18n.LanguageEnum; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.Json; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.common.util.PoiExcelUtil; |
| | | import com.yami.shop.common.util.PrincipalUtil; |
| | | import com.yami.shop.coupon.common.service.CouponUserService; |
| | | import com.yami.shop.platform.task.AnalysisSalseTask; |
| | | import com.yami.shop.security.common.enums.SysTypeEnum; |
| | | import com.yami.shop.security.common.manager.TokenStore; |
| | | import com.yami.shop.security.common.service.AppConnectService; |
| | | import com.yami.shop.service.UserService; |
| | | import com.yami.shop.user.common.model.UserLevel; |
| | | import com.yami.shop.user.common.service.UserLevelService; |
| | | import com.yami.shop.user.common.service.UserTagUserService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.RequiredArgsConstructor; |
| | | import ma.glasnost.orika.MapperFacade; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.apache.poi.ss.usermodel.Sheet; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import javax.validation.constraints.NotNull; |
| | | import java.math.BigDecimal; |
| | | import java.math.BigInteger; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.security.MessageDigest; |
| | | import java.security.NoSuchAlgorithmException; |
| | | import java.util.*; |
| | | import java.util.concurrent.Callable; |
| | | import java.util.concurrent.ExecutorService; |
| | | import java.util.concurrent.Executors; |
| | | import java.util.concurrent.Future; |
| | | |
| | | |
| | | /** |
| | | * @author lgh on 2018/10/16. |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/admin/user") |
| | | @RequiredArgsConstructor |
| | | @Tag(name = "用户") |
| | | public class UserController { |
| | | |
| | | @Value("${yami.expose.operation.auth:}") |
| | | private Boolean permission; |
| | | |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @Autowired |
| | | private AppConnectService appConnectService; |
| | | |
| | | @Autowired |
| | | private TokenStore tokenStore; |
| | | |
| | | @Autowired |
| | | private UserTagUserService userTagUserService; |
| | | |
| | | @Autowired |
| | | private CouponUserService couponUserService; |
| | | |
| | | @Autowired |
| | | private UserLevelService userLevelService; |
| | | |
| | | @Autowired |
| | | private MapperFacade mapperFacade; |
| | | |
| | | @GetMapping("/page") |
| | | @PreAuthorize("@pms.hasPermission('plateform:user:page')") |
| | | @Operation(summary = "分页获取用户基本信息", description = "分页获取用户基本信息") |
| | | public ServerResponseEntity<IPage<User>> page(@ParameterObject User user, PageParam<User> page) { |
| | | IPage<User> userPage = userService.getUserPage(page, user); |
| | | return ServerResponseEntity.success(userPage); |
| | | } |
| | | |
| | | @GetMapping("/list") |
| | | @Operation(summary = "获取用户列表", description = "获取用户列表") |
| | | public ServerResponseEntity<List<User>> list(@ParameterObject String nameOrPhone, String userIds) { |
| | | if (StringUtils.isNullOrEmpty(userIds)){ |
| | | throw new YamiShopBindException("yami.pcdn.device.userId.null"); |
| | | } |
| | | List<User> userList = userService.list(nameOrPhone, userIds); |
| | | return ServerResponseEntity.success(userList); |
| | | } |
| | | |
| | | @GetMapping("/info/{userId}") |
| | | @PreAuthorize("@pms.hasPermission('plateform:user:info')") |
| | | @Operation(summary = "获取信息", description = "获取信息") |
| | | public ServerResponseEntity<UserManagerParam> info(@PathVariable("userId") String userId) { |
| | | UserManagerParam param = userService.getuserInfo(userId); |
| | | List<UserTagParam> userTagParams = userTagUserService.getUserTagsUserByUserId(userId); |
| | | param.setUserTagParam(userTagParams); |
| | | CouponUserParam couponUser = couponUserService.getCouponCountByUserId(userId); |
| | | param.setCouponUserParam(couponUser); |
| | | return ServerResponseEntity.success(param); |
| | | } |
| | | |
| | | @PutMapping |
| | | @PreAuthorize("@pms.hasPermission('plateform:user:update')") |
| | | @Operation(summary = "修改", description = "修改") |
| | | public ServerResponseEntity<Void> update(@RequestBody User user) { |
| | | user.setModifyTime(new Date()); |
| | | user.setNickName(user.getNickName()); |
| | | userService.updateById(user); |
| | | tokenStore.deleteAllToken(SysTypeEnum.ORDINARY.value().toString(), user.getUserId()); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @GetMapping("/userPage") |
| | | @Operation(summary = "分页获取用户及扩展信息", description = "分页获取用户及扩展信息") |
| | | public ServerResponseEntity<IPage<UserManagerParam>> userPage(PageParam<User> page, @ParameterObject UserManagerReqParam user) { |
| | | IPage<UserManagerParam> userPage = userService.getUserInfoPage(page, user); |
| | | return ServerResponseEntity.success(userPage); |
| | | } |
| | | |
| | | @GetMapping("/importUserModel") |
| | | @Operation(summary = "用户导出模板", description = "用户导出模板") |
| | | public void importRetailProdModel(HttpServletResponse response) { |
| | | // 用户导出模板 |
| | | userService.downloadUserModel(response); |
| | | } |
| | | |
| | | @Operation(summary = "导入文件", description = "导入文件") |
| | | @PostMapping("/importExcel") |
| | | @ResponseBody |
| | | @PreAuthorize("@pms.hasPermission('platform:user:import')") |
| | | public ServerResponseEntity importExcel(@RequestParam("excelFile") MultipartFile excelFile) throws Exception { |
| | | if (Objects.isNull(excelFile)) { |
| | | // 网络繁忙,请稍后重试 |
| | | throw new YamiShopBindException("yami.network.busy"); |
| | | } |
| | | // 需要判断成长值所在等级 |
| | | List<UserLevel> list = userLevelService.list(); |
| | | List<UserLevelParam> userLevels = mapperFacade.mapAsList(list, UserLevelParam.class); |
| | | UserExcelParam param = userService.parseUserImportFile(excelFile, userLevels); |
| | | if (param.getImmediately()) { |
| | | return ServerResponseEntity.success(param.getMsg()); |
| | | } |
| | | Integer registerNum = 0; |
| | | //重复数据的set |
| | | Set<String> repeatPhoneSet = new HashSet<>(); |
| | | Set<String> repeatMailSet = new HashSet<>(); |
| | | if (param.getSuccess()) { |
| | | // 获取到参数 |
| | | List<UserRegisterExcelParam> userList = Json.parseArray(param.getParam(), UserRegisterExcelParam[].class); |
| | | // 批量注册用户 |
| | | registerNum = appConnectService.batchRegisterUser(param, userList, repeatPhoneSet, repeatMailSet); |
| | | } |
| | | Integer lang = I18nMessage.getDbLang(); |
| | | param.setMsg(getMsg(param, registerNum, repeatPhoneSet, repeatMailSet, lang)); |
| | | return ServerResponseEntity.success(param.getMsg()); |
| | | } |
| | | |
| | | @GetMapping("/exportUser") |
| | | @Operation(summary = "导出用户信息", description = "导出用户信息") |
| | | public void exportUser(@ParameterObject UserManagerReqParam user, HttpServletResponse response) { |
| | | // 开始时间 |
| | | long start = System.currentTimeMillis(); |
| | | PageParam<User> userPageParam = new PageParam<>(); |
| | | userPageParam.setCurrent(1); |
| | | userPageParam.setSize(10L); |
| | | IPage<UserManagerParam> userPage = userService.getUserInfoPage(userPageParam, user); |
| | | // 总共有多少条数据 |
| | | Long total = userPage.getTotal(); |
| | | // 用户有很多,考虑2000条以上数据的导出 一个最多104w 行数据 |
| | | Long rowMaxCount = 500000L; |
| | | // 每一次查询条数 |
| | | Long eachCount = 1000L; |
| | | // 这里不用PageParam<User> ,为了方便自由调整查询条数 |
| | | Page<User> pages = new Page<>(); |
| | | pages.setCurrent(1); |
| | | |
| | | List<UserManagerParam> list = new ArrayList<>(); |
| | | // 查询记录数 |
| | | //通过工具类创建writer |
| | | ExcelWriter writer = ExcelUtil.getBigWriter(); |
| | | // |
| | | String fileName = I18nMessage.getMessage("yami.excel.user.info") + ".xlsx"; |
| | | if (total <= rowMaxCount) { |
| | | if (total <= eachCount) { |
| | | pages.setSize(total); |
| | | userPage = userService.getUserInfoPage(pages, user); |
| | | exportExcel(userPage.getRecords(), 1, 1, response, writer); |
| | | // 导出 |
| | | PoiExcelUtil.writeExcel(fileName, writer, response); |
| | | } else { |
| | | // 开启多线程查询,每eachCount(100)行数据为一个线程开始 |
| | | int pageSize = getPageSize(total, eachCount); |
| | | // ExecutorService execservice = new ThreadPoolExecutor(4,10,200L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10)); |
| | | ExecutorService execservice = Executors.newFixedThreadPool(15); |
| | | try { |
| | | List<Callable<List<UserManagerParam>>> tasks = new ArrayList<Callable<List<UserManagerParam>>>(); |
| | | for (int i = 1; i <= pageSize; i++) { |
| | | Page<User> pagesIndex = new Page<>(); |
| | | pagesIndex.setCurrent(i); |
| | | pagesIndex.setSize(eachCount); |
| | | Callable<List<UserManagerParam>> task = new AnalysisSalseTask(userService, user, pagesIndex); |
| | | tasks.add(task); |
| | | } |
| | | List<Future<List<UserManagerParam>>> futures = execservice.invokeAll(tasks); |
| | | if (futures != null && futures.size() > 0) { |
| | | for (Future<List<UserManagerParam>> future : futures) { |
| | | list.addAll(future.get()); |
| | | } |
| | | } |
| | | execservice.shutdown(); |
| | | long end = System.currentTimeMillis(); |
| | | System.out.println("线程查询数据用时:" + (end - start) + "ms"); |
| | | } catch (Exception e) { |
| | | System.out.println("多线程查询异常"); |
| | | } |
| | | userPage.setRecords(list); |
| | | exportExcel(list, 1, 1, response, writer); |
| | | // 导出 |
| | | PoiExcelUtil.writeExcel(fileName, writer, response); |
| | | list.clear(); |
| | | } |
| | | } else { |
| | | // 分多少个 sheet |
| | | exportBigData(user, response, total, writer, fileName); |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | private void exportBigData(UserManagerReqParam user, HttpServletResponse response, Long total, ExcelWriter writer, String fileName) { |
| | | Long rowMaxCount = 500000L; |
| | | List<UserManagerParam> list = new ArrayList<>(); |
| | | Long eachCount; |
| | | int pageSize = getPageSize(total, rowMaxCount); |
| | | eachCount = 1000L; |
| | | List<String> filepaths = new ArrayList<>(); |
| | | for (int i = 1; i <= pageSize; i++) { |
| | | list.clear(); |
| | | int size = getPageSize(rowMaxCount, eachCount); |
| | | try { |
| | | ExecutorService execservice = Executors.newFixedThreadPool(15); |
| | | List<Callable<List<UserManagerParam>>> tasks = new ArrayList<Callable<List<UserManagerParam>>>(); |
| | | for (int j = 1; j <= size; j++) { |
| | | Page<User> pagesIndex = new Page<>(); |
| | | pagesIndex.setSize(eachCount); |
| | | pagesIndex.setCurrent((i - 1) * size + j); |
| | | Callable<List<UserManagerParam>> task = new AnalysisSalseTask(userService, user, pagesIndex); |
| | | tasks.add(task); |
| | | } |
| | | List<Future<List<UserManagerParam>>> futures = execservice.invokeAll(tasks); |
| | | if (futures.size() > 0) { |
| | | for (Future<List<UserManagerParam>> future : futures) { |
| | | list.addAll(future.get()); |
| | | } |
| | | } |
| | | tasks.clear(); |
| | | execservice.shutdown(); |
| | | } catch (Exception e) { |
| | | System.out.println("多线程查询异常"); |
| | | } |
| | | // 序号 (i-1) * rowMaxCount + 1 |
| | | int rowStart = new BigDecimal(i - 1).multiply(new BigDecimal(rowMaxCount)).add(new BigDecimal(1)).intValue(); |
| | | //方法1: 导出到一个临时文件, |
| | | // 然后合并小于50W行的Excel到100W行为一个Excel文件,此处逃过,直接是100W行为一个文件 |
| | | // 然后将100W的每一个Excel文件进行压缩 |
| | | |
| | | // 方法2:分多个sheet 导出 |
| | | // 此时达到 rowMaxCount 行数据 list 导出到excel |
| | | exportExcel(list, rowStart, i - 1, response, writer); |
| | | list.clear(); |
| | | } |
| | | // 导出 |
| | | PoiExcelUtil.writeExcel(fileName, writer, response); |
| | | } |
| | | |
| | | private int getPageSize(Long total, Long eachCount) { |
| | | int pageSize = new BigDecimal(total).divide(new BigDecimal(eachCount), 1).intValue(); |
| | | int mod = new BigDecimal(total).divideAndRemainder(new BigDecimal(eachCount))[1].intValue(); |
| | | if (mod > 0) { |
| | | pageSize = pageSize + 1; |
| | | } |
| | | return pageSize; |
| | | } |
| | | |
| | | private String generateKey(Map<String, String> values) { |
| | | MessageDigest digest; |
| | | try { |
| | | digest = MessageDigest.getInstance("MD5"); |
| | | byte[] bytes = digest.digest(values.toString().getBytes(StandardCharsets.UTF_8)); |
| | | return String.format("%032x", new BigInteger(1, bytes)); |
| | | } catch (NoSuchAlgorithmException nsae) { |
| | | throw new IllegalStateException("MD5 algorithm not available. Fatal (should be in the JDK).", nsae); |
| | | } |
| | | } |
| | | |
| | | @NotNull |
| | | private String getMsg(UserExcelParam param, Integer registerNum, Set<String> repeatPhoneSet, Set<String> repeatMailSet, Integer lang) { |
| | | String msg; |
| | | if (Objects.equals(lang, LanguageEnum.LANGUAGE_ZH_CN.getLang())) { |
| | | String str = CollectionUtils.isNotEmpty(param.getErrorRowInfos()) ? "错误数据信息" + Json.toJsonString(param.getErrorRowInfos()) : ""; |
| | | String repeatPhone = CollUtil.isNotEmpty(repeatPhoneSet) ? "重复的手机号" + repeatPhoneSet.toString() + "," : ""; |
| | | String repeatMail = CollUtil.isNotEmpty(repeatMailSet) ? "重复的邮箱" + repeatMailSet.toString() + "," : ""; |
| | | msg = "检查到" + param.getTotal() + "条用户,正确格式数据有" + param.getSuccessNum() + "条!错误" + param.getErrorNum() + "条用户信息!" + |
| | | (param.getSuccessNum() - registerNum) + "条数据已存在!" + repeatPhone + repeatMail + "注册成功" + registerNum + "条数据!" + str; |
| | | } else { |
| | | String str = CollectionUtils.isNotEmpty(param.getErrorRowInfos()) ? "Error data information" + Json.toJsonString(param.getErrorRowInfos()) : ""; |
| | | String repeatPhone = CollUtil.isNotEmpty(repeatPhoneSet) ? "Duplicate cell phone numbers" + repeatPhoneSet.toString() + "," : ""; |
| | | String repeatMail = CollUtil.isNotEmpty(repeatMailSet) ? "Duplicate mailboxes" + repeatMailSet.toString() + "," : ""; |
| | | msg = "Checked" + param.getTotal() + "user with" + param.getSuccessNum() + "piece of correctly formatted data! Error" + param.getErrorNum() + "user information!" + |
| | | (param.getSuccessNum() - registerNum) + "data already exists! " + repeatPhone + repeatMail + "Registration success" + registerNum + "data!" + str; |
| | | } |
| | | return msg; |
| | | } |
| | | |
| | | /** |
| | | * 商品导出or模板 |
| | | * |
| | | * @param list 导出的数据 |
| | | * @param rowStart 开始的行数 |
| | | * @param pages 一共有多少页 |
| | | */ |
| | | private void exportExcel(List<UserManagerParam> list, int rowStart, int pages, HttpServletResponse response, ExcelWriter writer) { |
| | | List<String> headerList = getHeadList(); |
| | | Sheet sheet = writer.getSheet(); |
| | | writer.merge(headerList.size() - 1, I18nMessage.getMessage("yami.excel.user.info")); |
| | | writer.writeRow(headerList); |
| | | for (int i = 0; i < headerList.size(); i++) { |
| | | if (i == 19 || i == 20) { |
| | | sheet.setColumnWidth(i, 30 * 256); |
| | | } else { |
| | | sheet.setColumnWidth(i, 20 * 256); |
| | | } |
| | | } |
| | | // 如果要导出的数据为空,导出一个模板 |
| | | if (CollectionUtils.isEmpty(list)) { |
| | | PoiExcelUtil.writeExcel(response, writer); |
| | | return; |
| | | } |
| | | int row = rowStart; |
| | | for (UserManagerParam param : list) { |
| | | int firstRow = row + 1; |
| | | int lastRow = row + 1; |
| | | int col = -1; |
| | | // 序号 |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, lastRow, ++col, col, rowStart++); |
| | | // 用户昵称 |
| | | String nickName = Objects.isNull(param.getNickName()) ? "" : BooleanUtil.isFalse(permission) && PrincipalUtil.isMobile(param.getNickName()) ? PhoneUtil.hideBetween(param.getNickName()).toString() : param.getNickName(); |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, lastRow, ++col, col, nickName); |
| | | // // 用户名称 |
| | | // String realName = Objects.isNull(param.getRealName())?"":param.getRealName(); |
| | | // PoiExcelUtil.mergeIfNeed(writer, firstRow, lastRow, ++col, col,realName); |
| | | // 联系电话 |
| | | String userMobile = Objects.isNull(param.getUserMobile()) ? "" : BooleanUtil.isFalse(permission) ? PhoneUtil.hideBetween(param.getUserMobile()).toString() : param.getUserMobile(); |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, lastRow, ++col, col, userMobile); |
| | | // 会员等级 |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, lastRow, ++col, col, param.getLevelName()); |
| | | // 会员类型 |
| | | String levelType; |
| | | if (Objects.equals(I18nMessage.getDbLang(), LanguageEnum.LANGUAGE_ZH_CN.getLang())) { |
| | | levelType = param.getLevelType() == 0 ? "普通会员" : "付费会员"; |
| | | } else { |
| | | levelType = param.getLevelType() == 0 ? "Ordinary member" : "Paid membership"; |
| | | } |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, lastRow, ++col, col, levelType); |
| | | // 用户积分 |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, lastRow, ++col, col, param.getScore()); |
| | | // 状态 |
| | | String status; |
| | | if (Objects.equals(I18nMessage.getDbLang(), LanguageEnum.LANGUAGE_ZH_CN.getLang())) { |
| | | status = param.getStatus() == 0 ? "禁用" : "正常"; |
| | | } else { |
| | | status = param.getStatus() == 0 ? "Disable" : "Normal"; |
| | | } |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, lastRow, ++col, col, status); |
| | | // 消费金额 |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, lastRow, ++col, col, param.getConsAmount()); |
| | | // 实付金额 |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, lastRow, ++col, col, param.getActualAmount()); |
| | | // 消费次数 |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, lastRow, ++col, col, param.getConsTimes()); |
| | | // 平均折扣 |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, lastRow, ++col, col, param.getAverDiscount()); |
| | | |
| | | // 充值金额 |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, lastRow, ++col, col, param.getRechargeAmount()); |
| | | // 充值次数 |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, lastRow, ++col, col, param.getRechargeTimes()); |
| | | |
| | | // 退款金额 |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, lastRow, ++col, col, param.getAfterSaleAmount()); |
| | | // 退款次数 |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, lastRow, ++col, col, param.getAfterSaleTimes()); |
| | | // 累计积分 |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, lastRow, ++col, col, param.getSumScore()); |
| | | // 当前余额 |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, lastRow, ++col, col, param.getCurrentBalance()); |
| | | // 累计余额 |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, lastRow, ++col, col, param.getSumBalance()); |
| | | // 注册时间 |
| | | String regTime = ""; |
| | | if (Objects.nonNull(param.getUserRegtime())) { |
| | | regTime = DateUtil.format(param.getUserRegtime(), "yyyy-MM-dd HH:mm:ss"); |
| | | } |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, lastRow, ++col, col, regTime); |
| | | // 最近消费时间 |
| | | String recTime = Objects.nonNull(param.getUserRegtime()) ? DateUtil.format(param.getReConsTime(), "yyyy-MM-dd HH:mm:ss") : ""; |
| | | PoiExcelUtil.mergeIfNeed(writer, firstRow, lastRow, ++col, col, recTime); |
| | | row++; |
| | | } |
| | | } |
| | | |
| | | private List<String> getHeadList() { |
| | | List<String> headerList; |
| | | // ["序号","用户昵称","用户名称","联系电话","会员等级","会员类型","用户积分","状态","消费金额","实付金额", |
| | | // "消费次数","平均折扣","充值金额","充值次数","退款金额","退款次数","累计积分","当前余额","累计余额","注册时间","最近消费时间"] |
| | | String[] header = { |
| | | I18nMessage.getMessage("yami.excel.user.number"), |
| | | I18nMessage.getMessage("yami.excel.user.userNickname"), |
| | | // I18nMessage.getMessage("yami.excel.user.userName"), |
| | | I18nMessage.getMessage("yami.excel.user.contactNumber"), |
| | | I18nMessage.getMessage("yami.excel.user.memberLevel"), |
| | | I18nMessage.getMessage("yami.excel.user.memberType"), |
| | | I18nMessage.getMessage("yami.excel.user.accScore"), |
| | | I18nMessage.getMessage("yami.excel.user.status"), |
| | | I18nMessage.getMessage("yami.excel.user.amountConsum"), |
| | | I18nMessage.getMessage("yami.excel.user.amountActPaid"), |
| | | I18nMessage.getMessage("yami.excel.user.numberConsum"), |
| | | I18nMessage.getMessage("yami.excel.user.aveDiscount"), |
| | | I18nMessage.getMessage("yami.excel.user.rechargeAmount"), |
| | | I18nMessage.getMessage("yami.excel.user.topUpTimes"), |
| | | I18nMessage.getMessage("yami.excel.user.refundAmount"), |
| | | I18nMessage.getMessage("yami.excel.user.numberOfRefund"), |
| | | I18nMessage.getMessage("yami.excel.user.accPoints"), |
| | | I18nMessage.getMessage("yami.excel.user.currBalance"), |
| | | I18nMessage.getMessage("yami.excel.user.accBalance"), |
| | | I18nMessage.getMessage("yami.excel.user.regTime"), |
| | | I18nMessage.getMessage("yami.excel.user.receConsumDate") |
| | | }; |
| | | headerList = Arrays.asList(header); |
| | | return headerList; |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.controller; |
| | | |
| | | |
| | | import cn.hutool.core.util.BooleanUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.yami.shop.bean.enums.WebConfigTypeEnum; |
| | | import com.yami.shop.bean.model.WebConfig; |
| | | import com.yami.shop.common.annotation.SysLog; |
| | | import com.yami.shop.common.bean.SysConfig; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.response.ResponseEnum; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.service.SysConfigService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 由于权限要求不同,所以不能把功能合并到sysController |
| | | * |
| | | * @author SJL |
| | | * @date 2021-02-20 09:44:42 |
| | | * @description: 平台网站配置、商家网站配置、PC配置、H5配置、自提点网站配置 |
| | | */ |
| | | |
| | | @RestController |
| | | @RequestMapping("/sys/webConfig") |
| | | @Tag(name = "网站配置") |
| | | public class WebConfigController { |
| | | |
| | | @Autowired |
| | | private SysConfigService sysConfigService; |
| | | |
| | | @Value("${yami.expose.operation.auth:}") |
| | | private Boolean permission; |
| | | |
| | | @SysLog("获取配置信息") |
| | | @GetMapping("/info/{key}") |
| | | @Operation(summary = "获取配置信息" , description = "获取配置信息") |
| | | @Parameter(name = "key", description = "参数名" ) |
| | | public ServerResponseEntity<String> info(@PathVariable("key") String key) { |
| | | return ServerResponseEntity.success(sysConfigService.getValue(key)); |
| | | } |
| | | |
| | | @SysLog("保存配置") |
| | | @PostMapping("/save") |
| | | @Operation(summary = "保存配置" , description = "保存配置") |
| | | @PreAuthorize("@pms.hasPermission('sys:webConfig:save')") |
| | | public ServerResponseEntity<Void> save(@RequestBody @Valid SysConfig sysConfig) { |
| | | if (BooleanUtil.isFalse(permission)) { |
| | | return ServerResponseEntity.fail(ResponseEnum.NOT_FOUND); |
| | | } |
| | | String paramValue = sysConfig.getParamValue(); |
| | | String paramKey = sysConfig.getParamKey(); |
| | | if (Objects.isNull(paramKey) || Objects.isNull(paramValue)) { |
| | | throw new YamiShopBindException("参数不完整,请准确填写后重试"); |
| | | } |
| | | int count = sysConfigService.count(new LambdaQueryWrapper<SysConfig>().eq(SysConfig::getParamKey, paramKey)); |
| | | if (count > 0) { |
| | | sysConfigService.updateValueByKey(paramKey, paramValue); |
| | | } else { |
| | | sysConfigService.save(sysConfig); |
| | | sysConfigService.removeSysConfig(paramKey); |
| | | } |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | /** |
| | | * 获取当前激活的后台网站配置 |
| | | * |
| | | * @return |
| | | */ |
| | | @GetMapping("/getActivity") |
| | | public ServerResponseEntity<WebConfig> getActivityWebConfig() { |
| | | WebConfig webConfig = sysConfigService.getSysConfigObject(WebConfigTypeEnum.PLATFROM.value(), WebConfig.class); |
| | | webConfig.setParamKey(WebConfigTypeEnum.PLATFROM.value()); |
| | | return ServerResponseEntity.success(webConfig); |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.platform.controller.cdn; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.yami.shop.bean.model.C2cRealName; |
| | | import com.yami.shop.bean.model.CdnRealName; |
| | | import com.yami.shop.bean.model.User; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.C2cRealNameService; |
| | | import com.yami.shop.service.UserService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | @RestController |
| | | @RequestMapping("/c2c/realName") |
| | | @Tag(name = "C2c实名认证接口") |
| | | public class C2cRealNameAuditController { |
| | | @Autowired |
| | | private C2cRealNameService c2cRealNameService; |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @GetMapping("/getList") |
| | | @Operation(summary = "根据条件分页查询实名认证列表", description = "根据条件分页查询实名认证列表") |
| | | public ServerResponseEntity<IPage<C2cRealName>> page(PageParam<C2cRealName> page, @ParameterObject C2cRealName c2cRealName) { |
| | | return ServerResponseEntity.success(c2cRealNameService.getC2cRealNamePage(page, c2cRealName)); |
| | | } |
| | | |
| | | /** |
| | | * 通过id查询 |
| | | * @param id id |
| | | * @return 单个数据 |
| | | */ |
| | | @GetMapping("/info/{id}" ) |
| | | @Operation(summary = "通过id查询" , description = "通过id查询") |
| | | public ServerResponseEntity<C2cRealName> getById(@PathVariable("id") Long id) { |
| | | return ServerResponseEntity.success(c2cRealNameService.getById(id)); |
| | | } |
| | | |
| | | /** |
| | | * 通过id查询 |
| | | * @param id id |
| | | * @return 单个数据 |
| | | */ |
| | | @GetMapping("/infoByUserId/{id}" ) |
| | | @Operation(summary = "通过用户id查询" , description = "通过用户id查询") |
| | | public ServerResponseEntity<C2cRealName> getById(@PathVariable("id") String id) { |
| | | return ServerResponseEntity.success(c2cRealNameService.getOne(Wrappers.lambdaQuery(C2cRealName.class).eq(C2cRealName::getUserId, id))); |
| | | } |
| | | |
| | | @PostMapping("/edit") |
| | | @Operation(summary = "编辑保存", description = "编辑保存") |
| | | public ServerResponseEntity save(@RequestBody C2cRealName c2cRealName) { |
| | | c2cRealNameService.updateById(c2cRealName); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PostMapping("/audit") |
| | | @Operation(summary = "审核", description = "审核") |
| | | public ServerResponseEntity audit(@RequestBody C2cRealName c2cRealName) { |
| | | c2cRealNameService.audit(c2cRealName); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PostMapping("/del") |
| | | @Operation(summary = "删除", description = "删除") |
| | | public ServerResponseEntity delete(@RequestParam Long id) { |
| | | c2cRealNameService.removeById(id); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.platform.controller.cdn; |
| | | |
| | | import com.yami.shop.bean.CdnConfigWrapper; |
| | | import com.yami.shop.bean.model.CdnConfig; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.service.CdnConfigService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Parameters; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.List; |
| | | |
| | | @RestController |
| | | @RequestMapping("/cdn/config") |
| | | @Tag(name = "cdn配置项接口") |
| | | public class CdnConfigController { |
| | | @Autowired |
| | | private CdnConfigService cdnConfigService; |
| | | |
| | | @GetMapping("/getCdnConfig") |
| | | @Operation(summary = "获取cdn配置项", description = "获取cdn配置项") |
| | | @Parameters( |
| | | {@Parameter(name = "group", description = "配置分组 充值:recharge,提现:withdrawal,转账:transferAccounts,划转:convert 支付:pay, 积分:rebate, 托管协议:agreement", required = true),} |
| | | ) |
| | | public ServerResponseEntity<List<CdnConfig>> getCdnConfig(@RequestParam String group) { |
| | | return ServerResponseEntity.success(cdnConfigService.getList(group)); |
| | | } |
| | | |
| | | @PostMapping |
| | | @Operation(summary = "保存cdn配置项", description = "保存cdn配置项") |
| | | public ServerResponseEntity getCdnConfig(@RequestBody CdnConfigWrapper wrappers) { |
| | | List<CdnConfig> cdnConfigList = wrappers.getCdnConfigList(); |
| | | for (CdnConfig cdnConfig : cdnConfigList){ |
| | | cdnConfigService.updateConfig(cdnConfig); |
| | | } |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.yami.shop.platform.controller.cdn; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.yami.shop.bean.model.CdnRealName; |
| | | import com.yami.shop.bean.model.User; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.CdnRealNameService; |
| | | import com.yami.shop.service.UserService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @RestController |
| | | @RequestMapping("/cdn/realName") |
| | | @Tag(name = "Cdn实名认证接口") |
| | | public class CdnRealNameController { |
| | | @Autowired |
| | | private CdnRealNameService cdnRealNameService; |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @GetMapping("/getList") |
| | | @Operation(summary = "根据条件分页查询实名认证列表", description = "根据条件分页查询实名认证列表") |
| | | public ServerResponseEntity<IPage<CdnRealName>> page(PageParam<CdnRealName> page, @ParameterObject CdnRealName cdnRealName) { |
| | | LambdaQueryWrapper<CdnRealName> wrapper = new LambdaQueryWrapper<>(CdnRealName.class); |
| | | if (cdnRealName.getId() != null) wrapper.eq(CdnRealName::getId, cdnRealName.getId()); |
| | | if (cdnRealName.getUserId() != null && !cdnRealName.getUserId().equals("")) wrapper.eq(CdnRealName::getUserId, cdnRealName.getUserId()); |
| | | if (cdnRealName.getName() != null && !cdnRealName.getName().equals("")) wrapper.like(CdnRealName::getName, cdnRealName.getName()); |
| | | if (cdnRealName.getCard() != null && !cdnRealName.getCard().equals("")) wrapper.eq(CdnRealName::getCard, cdnRealName.getCard()); |
| | | if (cdnRealName.getBankName() != null && !cdnRealName.getBankName().equals("")) wrapper.like(CdnRealName::getBankName, cdnRealName.getBankName()); |
| | | if (cdnRealName.getBankCode() != null && !cdnRealName.getBankCode().equals("")) wrapper.eq(CdnRealName::getBankCode, cdnRealName.getBankCode()); |
| | | if (cdnRealName.getBankAddr() != null && !cdnRealName.getBankAddr().equals("")) wrapper.like(CdnRealName::getBankAddr, cdnRealName.getBankAddr()); |
| | | if (cdnRealName.getWxName() != null && !cdnRealName.getWxName().equals("")) wrapper.like(CdnRealName::getWxName, cdnRealName.getWxName()); |
| | | if (cdnRealName.getAliName() != null && !cdnRealName.getAliName().equals("")) wrapper.like(CdnRealName::getAliName, cdnRealName.getAliName()); |
| | | wrapper.orderByDesc(CdnRealName::getCreateTime); |
| | | if (cdnRealName.getId() != null) wrapper.eq(CdnRealName::getId, cdnRealName.getId()); |
| | | if (cdnRealName.getMobile() != null && !cdnRealName.getMobile().equals("")){ |
| | | List<User> list = userService.list(Wrappers.lambdaQuery(User.class).like(User::getUserMobile, cdnRealName.getMobile())); |
| | | if (!list.isEmpty()){ |
| | | wrapper.in(CdnRealName::getUserId, list.stream().map(User::getUserId).collect(Collectors.toList())); |
| | | }else { |
| | | return ServerResponseEntity.success(new PageParam<>()); |
| | | } |
| | | } |
| | | if (cdnRealName.getNickName() != null && !cdnRealName.getNickName().equals("")){ |
| | | List<User> list = userService.list(Wrappers.lambdaQuery(User.class).like(User::getNickName, cdnRealName.getNickName())); |
| | | if (!list.isEmpty()){ |
| | | wrapper.in(CdnRealName::getUserId, list.stream().map(User::getUserId).collect(Collectors.toList())); |
| | | }else { |
| | | return ServerResponseEntity.success(new PageParam<>()); |
| | | } |
| | | } |
| | | PageParam<CdnRealName> page1 = cdnRealNameService.page(page, wrapper); |
| | | if (!page1.getRecords().isEmpty()) { |
| | | for (CdnRealName cdnRealName1 : page1.getRecords()) { |
| | | User user = userService.getUserByUserId(cdnRealName1.getUserId()); |
| | | if (user != null) { |
| | | cdnRealName1.setUserName(user.getUserName()); |
| | | cdnRealName1.setNickName(user.getNickName()); |
| | | cdnRealName1.setMobile(user.getUserMobile()); |
| | | } |
| | | } |
| | | } |
| | | return ServerResponseEntity.success(page1); |
| | | } |
| | | |
| | | /** |
| | | * 通过id查询 |
| | | * @param id id |
| | | * @return 单个数据 |
| | | */ |
| | | @GetMapping("/info/{id}" ) |
| | | @Operation(summary = "通过id查询" , description = "通过id查询") |
| | | public ServerResponseEntity<CdnRealName> getById(@PathVariable("id") Long id) { |
| | | CdnRealName cdnRealName = cdnRealNameService.getById(id); |
| | | User user = userService.getUserByUserId(cdnRealName.getUserId()); |
| | | cdnRealName.setUserName(user.getUserName()); |
| | | cdnRealName.setNickName(user.getNickName()); |
| | | cdnRealName.setMobile(user.getUserMobile()); |
| | | return ServerResponseEntity.success(cdnRealName); |
| | | } |
| | | |
| | | /** |
| | | * 通过id查询 |
| | | * @param id id |
| | | * @return 单个数据 |
| | | */ |
| | | @GetMapping("/infoByUserId/{id}" ) |
| | | @Operation(summary = "通过用户id查询" , description = "通过用户id查询") |
| | | public ServerResponseEntity<CdnRealName> getById(@PathVariable("id") String id) { |
| | | CdnRealName cdnRealName = cdnRealNameService.getOne(Wrappers.lambdaQuery(CdnRealName.class).eq(CdnRealName::getUserId, id)); |
| | | return ServerResponseEntity.success(cdnRealName); |
| | | } |
| | | |
| | | @PostMapping("/edit") |
| | | @Operation(summary = "编辑保存", description = "编辑保存") |
| | | public ServerResponseEntity save(@RequestBody CdnRealName cdnRelease) { |
| | | cdnRealNameService.updateById(cdnRelease); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PostMapping("/del") |
| | | @Operation(summary = "删除", description = "删除") |
| | | public ServerResponseEntity delete(@RequestParam Long id) { |
| | | cdnRealNameService.removeById(id); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.platform.controller.cdn; |
| | | |
| | | import com.yami.shop.bean.vo.CdnUserAtlasVO; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.service.UserService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.util.List; |
| | | |
| | | @RestController |
| | | @RequestMapping("/cdn/userAtlas") |
| | | @Tag(name = "cdn会员图谱接口") |
| | | public class CdnUserAtlasController { |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | |
| | | @GetMapping |
| | | @Operation(summary = "获取会员图谱", description = "获取会员图谱") |
| | | public ServerResponseEntity<List<CdnUserAtlasVO>> getDownLevel(@RequestParam("nickName") String nickName,@RequestParam("userId") String userId ,@RequestParam("userMobile") String userMobile) { |
| | | List<CdnUserAtlasVO> list = userService.getLevel(nickName,userMobile,userId); |
| | | return ServerResponseEntity.success(list); |
| | | } |
| | | |
| | | @GetMapping("/getHeadUser") |
| | | @Operation(summary = "获取用户", description = "获取用户") |
| | | public ServerResponseEntity<List<CdnUserAtlasVO>> getHeadUser(@RequestParam("uid") String uid,@RequestParam("nickName") String nickName,@RequestParam("userId") String userId ,@RequestParam("userMobile") String userMobile) { |
| | | if (userId != null && !userId.equals("") && uid != null && !uid.equals("")){ |
| | | userId = ""; |
| | | } |
| | | if (nickName != null && !nickName.equals("") && uid != null && !uid.equals("")){ |
| | | nickName = ""; |
| | | } |
| | | if (userMobile != null && !userMobile.equals("") && uid != null && !uid.equals("")){ |
| | | userMobile = ""; |
| | | } |
| | | if ((uid == null || uid.equals("")) && (userId == null || userId.equals("")) && (userMobile == null || userMobile.equals("")) && (nickName == null || nickName.equals(""))){ |
| | | uid = "0"; |
| | | } |
| | | List<CdnUserAtlasVO> list = userService.getNoPidUser(uid,nickName,userId,userMobile); |
| | | return ServerResponseEntity.success(list); |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.platform.controller.cdn; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.yami.shop.bean.model.*; |
| | | import com.yami.shop.bean.param.CdnShiftPidParam; |
| | | import com.yami.shop.bean.param.CdnUserParam; |
| | | import com.yami.shop.bean.param.CdnWalletInfoParam; |
| | | import com.yami.shop.bean.vo.CdnUserAtlasVO; |
| | | import com.yami.shop.common.enums.WalletEnum; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.security.common.enums.SysTypeEnum; |
| | | import com.yami.shop.security.common.manager.TokenStore; |
| | | import com.yami.shop.service.*; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import ma.glasnost.orika.MapperFacade; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.crypto.password.PasswordEncoder; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.math.BigInteger; |
| | | import java.math.RoundingMode; |
| | | import java.security.MessageDigest; |
| | | import java.security.NoSuchAlgorithmException; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @RestController |
| | | @RequestMapping("/cdn/user") |
| | | @Tag(name = "cdn用户管理") |
| | | public class CdnUserController { |
| | | @Autowired |
| | | private UserService userService; |
| | | @Autowired |
| | | private CdnTeamRelationService cdnTeamRelationService; |
| | | @Autowired |
| | | private CdnUserWalletService cdnUserWalletService; |
| | | @Autowired |
| | | private UserExtensionService userExtensionService; |
| | | @Autowired |
| | | private CdnFlowService cdnFlowService; |
| | | @Autowired |
| | | private CdnReleaseService cdnReleaseService; |
| | | @Autowired |
| | | private CdnRealNameService cdnRealNameService; |
| | | @Autowired |
| | | private PasswordEncoder passwordEncoder; |
| | | @Autowired |
| | | private MapperFacade mapperFacade; |
| | | @Autowired |
| | | private DeviceService deviceService; |
| | | @Autowired |
| | | private TokenStore tokenStore; |
| | | |
| | | @GetMapping("/getUserList") |
| | | @Operation(summary = "获取会员列表", description = "获取会员列表") |
| | | public ServerResponseEntity<IPage<User>> page(PageParam<User> page, @ParameterObject User user) { |
| | | LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>(User.class); |
| | | if (user.getUserId() != null && !user.getUserId().equals("")) wrapper.eq(User::getUserId, user.getUserId()); |
| | | if (user.getNickName() != null && !user.getNickName().equals("")) wrapper.like(User::getNickName, user.getNickName()); |
| | | if (user.getUserMobile() != null && !user.getUserMobile().equals("")) wrapper.like(User::getUserMobile, user.getUserMobile()); |
| | | if (user.getStatus() != null) wrapper.eq(User::getStatus, user.getStatus()); |
| | | if (user.getStartRegisterTime() != null && !user.getStartRegisterTime().equals("") && !user.getEndRegisterTime().equals("") && user.getEndRegisterTime() != null) { |
| | | wrapper.between(User::getUserRegtime, user.getStartRegisterTime(), user.getEndRegisterTime()); |
| | | } |
| | | if (user.getAgentLevelId() != null) { |
| | | List<CdnTeamRelation> cdnTeamRelations = cdnTeamRelationService.list(Wrappers.lambdaQuery(CdnTeamRelation.class).eq(CdnTeamRelation::getAgentLevelId, user.getAgentLevelId())); |
| | | if (!cdnTeamRelations.isEmpty()) { |
| | | List<String> userIds = cdnTeamRelations.stream().map(CdnTeamRelation::getUserId).collect(Collectors.toList()); |
| | | if (!userIds.isEmpty()) { |
| | | wrapper.in(User::getUserId, userIds); |
| | | }else { |
| | | return ServerResponseEntity.success(new PageParam<>()); |
| | | } |
| | | } else { |
| | | return ServerResponseEntity.success(new PageParam<>()); |
| | | } |
| | | } |
| | | if (user.getCenterLevelId() != null) { |
| | | List<CdnTeamRelation> cdnTeamRelations = cdnTeamRelationService.list(Wrappers.lambdaQuery(CdnTeamRelation.class).eq(CdnTeamRelation::getCenterLevelId, user.getCenterLevelId())); |
| | | if (!cdnTeamRelations.isEmpty()) { |
| | | List<String> userIds = cdnTeamRelations.stream().map(CdnTeamRelation::getUserId).collect(Collectors.toList()); |
| | | if (!userIds.isEmpty()) { |
| | | wrapper.in(User::getUserId, userIds); |
| | | }else { |
| | | return ServerResponseEntity.success(new PageParam<>()); |
| | | } |
| | | } else { |
| | | return ServerResponseEntity.success(new PageParam<>()); |
| | | } |
| | | } |
| | | if (user.getPid() != null && !user.getPid().equals("")) { |
| | | List<CdnTeamRelation> cdnTeamRelations = cdnTeamRelationService.list(Wrappers.lambdaQuery(CdnTeamRelation.class).eq(CdnTeamRelation::getPid, user.getPid())); |
| | | if (!cdnTeamRelations.isEmpty()) { |
| | | List<String> userIds = cdnTeamRelations.stream().map(CdnTeamRelation::getUserId).collect(Collectors.toList()); |
| | | if (!userIds.isEmpty()) { |
| | | wrapper.in(User::getUserId, userIds); |
| | | }else { |
| | | return ServerResponseEntity.success(new PageParam<>()); |
| | | } |
| | | } else { |
| | | return ServerResponseEntity.success(new PageParam<>()); |
| | | } |
| | | } |
| | | if (user.getPNickName() != null && !user.getPNickName().equals("")) { |
| | | List<User> users = userService.list(Wrappers.lambdaQuery(User.class).like(User::getNickName, user.getPNickName())); |
| | | if (!users.isEmpty()) { |
| | | List<CdnTeamRelation> list = cdnTeamRelationService.list(Wrappers.lambdaQuery(CdnTeamRelation.class).in(CdnTeamRelation::getPid, users.stream().map(User::getUserId).collect(Collectors.toList()))); |
| | | if (!list.isEmpty()) { |
| | | wrapper.in(User::getUserId, list.stream().map(CdnTeamRelation::getUserId).collect(Collectors.toList())); |
| | | }else { |
| | | return ServerResponseEntity.success(new PageParam<>()); |
| | | } |
| | | } else { |
| | | return ServerResponseEntity.success(new PageParam<>()); |
| | | } |
| | | } |
| | | if (user.getPMobile() != null && !user.getPMobile().equals("")) { |
| | | List<User> users = userService.list(Wrappers.lambdaQuery(User.class).like(User::getUserMobile, user.getPMobile())); |
| | | if (!users.isEmpty()) { |
| | | List<CdnTeamRelation> list = cdnTeamRelationService.list(Wrappers.lambdaQuery(CdnTeamRelation.class).in(CdnTeamRelation::getPid, users.stream().map(User::getUserId).collect(Collectors.toList()))); |
| | | if (!list.isEmpty()) { |
| | | wrapper.in(User::getUserId, list.stream().map(CdnTeamRelation::getUserId).collect(Collectors.toList())); |
| | | }else { |
| | | return ServerResponseEntity.success(new PageParam<>()); |
| | | } |
| | | } else { |
| | | return ServerResponseEntity.success(new PageParam<>()); |
| | | } |
| | | } |
| | | wrapper.eq(User::getDelStatus, 0); |
| | | wrapper.orderByDesc(User::getUserRegtime); |
| | | PageParam<User> page1 = userService.page(page, wrapper); |
| | | |
| | | if (!page1.getRecords().isEmpty()) { |
| | | page1.getRecords().forEach(user1 -> { |
| | | User userInfo = cdnTeamRelationService.getInfoByUserId(user1.getUserId()); |
| | | user1.setPayPassword(null); |
| | | user1.setLoginPassword(null); |
| | | user1.setPid(userInfo.getPid()); |
| | | user1.setMeall(userInfo.getMeall()); |
| | | user1.setTeamall(userInfo.getTeamall()); |
| | | user1.setAgentLevelId(userInfo.getAgentLevelId()); |
| | | user1.setCenterLevelId(userInfo.getCenterLevelId()); |
| | | user1.setAgentLevelName(userInfo.getAgentLevelName()); |
| | | user1.setCenterLevelName(userInfo.getCenterLevelName()); |
| | | user1.setPNickName(userInfo.getPNickName()); |
| | | user1.setPMobile(userInfo.getPMobile()); |
| | | user1.setTotalRecharge(userInfo.getTotalRecharge()); |
| | | user1.setTotalConsumption(userInfo.getTotalConsumption()); |
| | | user1.setTotalWithdrawal(userInfo.getTotalWithdrawal()); |
| | | CdnRealName cdnRealName = cdnRealNameService.getOne(Wrappers.lambdaQuery(CdnRealName.class).eq(CdnRealName::getUserId, user1.getUserId())); |
| | | if (cdnRealName != null) { |
| | | user1.setIsRealName(1); |
| | | } else { |
| | | user1.setIsRealName(0); |
| | | } |
| | | }); |
| | | }else { |
| | | return ServerResponseEntity.success(new PageParam<>()); |
| | | } |
| | | return ServerResponseEntity.success(page1); |
| | | } |
| | | /** |
| | | * 通过id查询 |
| | | * @param id id |
| | | * @return 单个数据 |
| | | */ |
| | | @GetMapping("/info/{id}") |
| | | @Operation(summary = "通过id查询", description = "通过id查询") |
| | | public ServerResponseEntity<User> getById(@PathVariable("id") String id) { |
| | | CdnTeamRelation cdnTeamRelation = cdnTeamRelationService.getOne(Wrappers.lambdaQuery(CdnTeamRelation.class).eq(CdnTeamRelation::getUserId, id)); |
| | | User user = userService.getById(id); |
| | | user.setAgentLevelId(cdnTeamRelation != null ? cdnTeamRelation.getAgentLevelId() : 0); |
| | | user.setCenterLevelId(cdnTeamRelation != null ? cdnTeamRelation.getCenterLevelId() : 0); |
| | | user.setPid(cdnTeamRelation != null ? cdnTeamRelation.getPid() : ""); |
| | | User pUser = userService.getById(cdnTeamRelation.getPid()); |
| | | if(null != pUser){ |
| | | user.setPMobile(pUser.getUserMobile()); |
| | | user.setPUserName(pUser.getUserName()); |
| | | user.setPNickName(pUser.getNickName()); |
| | | } |
| | | return ServerResponseEntity.success(user); |
| | | } |
| | | |
| | | @PostMapping("/edit") |
| | | @Operation(summary = "编辑保存", description = "编辑保存") |
| | | public ServerResponseEntity save(@RequestBody CdnUserParam cdnUserParam) { |
| | | if (cdnUserParam.getPayPassword().length() > 6) { |
| | | return ServerResponseEntity.showFailMsg("支付密码格式错误"); |
| | | } |
| | | String ppw = encryptWithMD5(cdnUserParam.getPayPassword()); |
| | | User user = mapperFacade.map(cdnUserParam, User.class); |
| | | user.setPayPassword(ppw); |
| | | user.setLoginPassword(passwordEncoder.encode(cdnUserParam.getLoginPassword())); |
| | | CdnTeamRelation cdnTeamRelation = cdnTeamRelationService.geteamRelationByUserId(user.getUserId()); |
| | | if (cdnUserParam.getStatus() == 0) { |
| | | cdnTeamRelation.setMeall(BigDecimal.ZERO); // 个人设备清零,收益清零 |
| | | cdnTeamRelation.setDongjing(BigDecimal.ZERO); |
| | | // 设备状态改为撤销 |
| | | List<CdnRelease> releases = cdnReleaseService.list(Wrappers.lambdaQuery(CdnRelease.class).eq(CdnRelease::getUserId, user.getUserId())); |
| | | //计算失效的设备数量 |
| | | Integer num = 0; |
| | | if (!releases.isEmpty()) { |
| | | for (CdnRelease release : releases) { |
| | | release.setStatus(2); |
| | | cdnReleaseService.updateById(release); |
| | | //删除SN绑定的设备号 |
| | | deviceService.deleteBySn(release.getSn()); |
| | | num += release.getNum(); |
| | | } |
| | | } |
| | | //根据userId和数量 减少个人数量和团队数量 |
| | | updateTmall(user.getUserId(), num); |
| | | } |
| | | if (!cdnTeamRelation.getPid().equals(cdnUserParam.getPid())) { |
| | | CdnShiftPidParam cdnShiftPidParam = new CdnShiftPidParam(); |
| | | cdnShiftPidParam.setUserId(cdnUserParam.getUserId()); |
| | | cdnShiftPidParam.setPid(cdnUserParam.getPid()); |
| | | cdnTeamRelationService.shiftPid(cdnShiftPidParam); |
| | | } else { |
| | | cdnTeamRelationService.update(cdnTeamRelation, Wrappers.lambdaUpdate(CdnTeamRelation.class).eq(CdnTeamRelation::getUserId, user.getUserId())); |
| | | } |
| | | if (cdnUserParam.getAgentLevelId() != null){ |
| | | cdnTeamRelation.setAgentLevelId(cdnUserParam.getAgentLevelId()); |
| | | } |
| | | if (cdnUserParam.getCenterLevelId() != null){ |
| | | cdnTeamRelation.setCenterLevelId(cdnUserParam.getCenterLevelId()); |
| | | } |
| | | if (cdnUserParam.getPid() != null && !cdnUserParam.getPid().equals("")){ |
| | | cdnTeamRelation.setPid(cdnUserParam.getPid()); |
| | | } |
| | | cdnTeamRelationService.updateById(cdnTeamRelation); |
| | | User userByUserId = userService.getUserByUserId(cdnUserParam.getUserId()); |
| | | if(!userByUserId.getUserMobile().equals(cdnUserParam.getUserMobile())){ |
| | | if (cdnUserParam.getUserMobile() != null && !"".equals(cdnUserParam.getUserMobile())){ |
| | | if (cdnUserParam.getUserMobile().length() != 11){ |
| | | return ServerResponseEntity.showFailMsg("手机号格式错误"); |
| | | } |
| | | List<User> mUser = userService.list(Wrappers.lambdaQuery(User.class).eq(User::getUserMobile, cdnUserParam.getUserMobile())); |
| | | if (!mUser.isEmpty()){ |
| | | return ServerResponseEntity.showFailMsg("手机号已存在"); |
| | | } |
| | | } |
| | | } |
| | | userService.updateById(user); |
| | | tokenStore.deleteAllToken(SysTypeEnum.ORDINARY.value().toString(), user.getUserId()); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PostMapping("/modifyTixianStatus") |
| | | @Operation(summary = "修改提现/转账/划转状态", description = "修改提现状态") |
| | | public ServerResponseEntity modifyStatus(@RequestBody User user) { |
| | | userService.update(Wrappers.lambdaUpdate(User.class) |
| | | .eq(User::getUserId, user.getUserId()) |
| | | .set(User::getTixian, user.getTixian()) |
| | | .set(User::getHuazhuan, user.getHuazhuan()) |
| | | .set(User::getZhuanzhang, user.getZhuanzhang())); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @GetMapping("/lookWallet") |
| | | @Operation(summary = "查看钱包", description = "查看钱包") |
| | | public ServerResponseEntity<CdnWalletInfoParam> lookWallet(@RequestParam String userId) { |
| | | // 查询钱包币种数额 |
| | | CdnWalletInfoParam cdnWalletInfoParam = new CdnWalletInfoParam(); |
| | | // 根据币种查询钱包相关币种余额 |
| | | CdnUserWallet flow = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId, userId) |
| | | .eq(CdnUserWallet::getWalletId, WalletEnum.FLOW.value())); |
| | | CdnUserWallet goldCowBean = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId, userId) |
| | | .eq(CdnUserWallet::getWalletId, WalletEnum.GOLDCOWBEAN.value())); |
| | | CdnUserWallet luckPool = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId, userId) |
| | | .eq(CdnUserWallet::getWalletId, WalletEnum.LUCKPOOL.value())); |
| | | CdnUserWallet integral = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId, userId) |
| | | .eq(CdnUserWallet::getWalletId, WalletEnum.INTEGRAL.value())); |
| | | CdnUserWallet credit = cdnUserWalletService.getWalletByUserId(userId,WalletEnum.CREDIT.value()); |
| | | CdnUserWallet alloy = cdnUserWalletService.getWalletByUserId(userId,WalletEnum.ALLOY.value()); |
| | | BigDecimal b = new BigDecimal(0); |
| | | cdnWalletInfoParam.setFlow(flow != null ? flow.getMoney() : b); |
| | | cdnWalletInfoParam.setGoldCowBean(goldCowBean != null ? goldCowBean.getMoney() : b); |
| | | cdnWalletInfoParam.setLuckPool(luckPool != null ? luckPool.getMoney() : b); |
| | | cdnWalletInfoParam.setIntegral(integral != null ? integral.getMoney() : b); |
| | | cdnWalletInfoParam.setCredit(credit != null ? credit.getMoney() : b); |
| | | cdnWalletInfoParam.setAlloy(alloy != null ? alloy.getMoney() : b); |
| | | cdnWalletInfoParam.setUserId(userId); |
| | | return ServerResponseEntity.success(cdnWalletInfoParam); |
| | | } |
| | | |
| | | @PostMapping("/edit/userWallet") |
| | | @Operation(summary = "编辑保存用户钱包", description = "编辑保存用户钱包") |
| | | public ServerResponseEntity saveUserWallet(@RequestBody CdnWalletInfoParam cdnWalletInfoParam) { |
| | | // 根据币种查询钱包相关币种余额 |
| | | cdnWalletInfoParam.setFlow(cdnWalletInfoParam.getFlow().setScale(2, RoundingMode.HALF_UP)); |
| | | cdnWalletInfoParam.setGoldCowBean(cdnWalletInfoParam.getGoldCowBean().setScale(2, RoundingMode.HALF_UP)); |
| | | cdnWalletInfoParam.setLuckPool(cdnWalletInfoParam.getLuckPool().setScale(2, RoundingMode.HALF_UP)); |
| | | cdnWalletInfoParam.setIntegral(cdnWalletInfoParam.getIntegral().setScale(2, RoundingMode.HALF_UP)); |
| | | CdnUserWallet flow = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId, cdnWalletInfoParam.getUserId()) |
| | | .eq(CdnUserWallet::getWalletId, WalletEnum.FLOW.value())); |
| | | CdnUserWallet goldCowBean = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId, cdnWalletInfoParam.getUserId()) |
| | | .eq(CdnUserWallet::getWalletId, WalletEnum.GOLDCOWBEAN.value())); |
| | | CdnUserWallet luckPool = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId, cdnWalletInfoParam.getUserId()) |
| | | .eq(CdnUserWallet::getWalletId, WalletEnum.LUCKPOOL.value())); |
| | | CdnUserWallet integral = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId, cdnWalletInfoParam.getUserId()) |
| | | .eq(CdnUserWallet::getWalletId, WalletEnum.INTEGRAL.value())); |
| | | CdnUserWallet credit = cdnUserWalletService.getWalletByUserId(cdnWalletInfoParam.getUserId(),WalletEnum.CREDIT.value()); |
| | | CdnUserWallet alloy = cdnUserWalletService.getWalletByUserId(cdnWalletInfoParam.getUserId(),WalletEnum.ALLOY.value()); |
| | | CdnFlow cdnFlow = new CdnFlow(); |
| | | cdnFlow.setDate(new Date()); |
| | | cdnFlow.setMemo("后台操作钱包余额调整"); |
| | | cdnFlow.setUserId(cdnWalletInfoParam.getUserId()); |
| | | cdnFlow.setCreateTime(new Date()); |
| | | cdnFlow.setFlownameId(4); //后台操作 |
| | | if (!cdnWalletInfoParam.getFlow().equals(BigDecimal.ZERO) && !cdnWalletInfoParam.getFlow().equals(flow.getMoney())) { |
| | | BigDecimal money = cdnWalletInfoParam.getFlow().subtract(flow.getMoney()); |
| | | cdnFlow.setWalletId(WalletEnum.FLOW.value()); |
| | | cdnFlow.setMoney(money); |
| | | cdnFlow.setOldmoney(flow.getMoney()); |
| | | cdnFlowService.save(cdnFlow); |
| | | cdnUserWalletService.update(Wrappers.lambdaUpdate(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId, cdnWalletInfoParam.getUserId()) |
| | | .eq(CdnUserWallet::getWalletId, WalletEnum.FLOW.value()) |
| | | .set(CdnUserWallet::getMoney, cdnWalletInfoParam.getFlow()) |
| | | .set(CdnUserWallet::getUpdateTime, new Date())); |
| | | } |
| | | if (!cdnWalletInfoParam.getGoldCowBean().equals(BigDecimal.ZERO) && !cdnWalletInfoParam.getGoldCowBean().equals(goldCowBean.getMoney())) { |
| | | BigDecimal money = cdnWalletInfoParam.getGoldCowBean().subtract(goldCowBean.getMoney()); |
| | | cdnFlow.setWalletId(WalletEnum.GOLDCOWBEAN.value()); |
| | | cdnFlow.setMoney(money); |
| | | cdnFlow.setOldmoney(goldCowBean.getMoney()); |
| | | cdnFlowService.save(cdnFlow); |
| | | cdnUserWalletService.update(Wrappers.lambdaUpdate(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId, cdnWalletInfoParam.getUserId()) |
| | | .eq(CdnUserWallet::getWalletId, WalletEnum.GOLDCOWBEAN.value()) |
| | | .set(CdnUserWallet::getMoney, cdnWalletInfoParam.getGoldCowBean()) |
| | | .set(CdnUserWallet::getUpdateTime, new Date())); |
| | | } |
| | | if (!cdnWalletInfoParam.getLuckPool().equals(BigDecimal.ZERO) && !cdnWalletInfoParam.getLuckPool().equals(luckPool.getMoney())) { |
| | | BigDecimal money = cdnWalletInfoParam.getLuckPool().subtract(luckPool.getMoney()); |
| | | cdnFlow.setWalletId(WalletEnum.LUCKPOOL.value()); |
| | | cdnFlow.setMoney(money); |
| | | cdnFlow.setOldmoney(luckPool.getMoney()); |
| | | cdnFlowService.save(cdnFlow); |
| | | cdnUserWalletService.update(Wrappers.lambdaUpdate(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId, cdnWalletInfoParam.getUserId()) |
| | | .eq(CdnUserWallet::getWalletId, WalletEnum.LUCKPOOL.value()) |
| | | .set(CdnUserWallet::getMoney, cdnWalletInfoParam.getLuckPool()) |
| | | .set(CdnUserWallet::getUpdateTime, new Date())); |
| | | } |
| | | if (!cdnWalletInfoParam.getIntegral().equals(BigDecimal.ZERO) && !cdnWalletInfoParam.getIntegral().equals(integral.getMoney())) { |
| | | BigDecimal money = cdnWalletInfoParam.getIntegral().subtract(integral.getMoney()); |
| | | cdnFlow.setWalletId(WalletEnum.INTEGRAL.value()); |
| | | cdnFlow.setMoney(money); |
| | | cdnFlow.setOldmoney(integral.getMoney()); |
| | | cdnFlowService.save(cdnFlow); |
| | | cdnUserWalletService.update(Wrappers.lambdaUpdate(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId, cdnWalletInfoParam.getUserId()) |
| | | .eq(CdnUserWallet::getWalletId, WalletEnum.INTEGRAL.value()) |
| | | .set(CdnUserWallet::getMoney, cdnWalletInfoParam.getIntegral()) |
| | | .set(CdnUserWallet::getUpdateTime, new Date())); |
| | | } |
| | | |
| | | if (!cdnWalletInfoParam.getCredit().equals(BigDecimal.ZERO) && !cdnWalletInfoParam.getCredit().equals(credit.getMoney())) { |
| | | BigDecimal money = cdnWalletInfoParam.getCredit().subtract(credit.getMoney()); |
| | | cdnFlow.setWalletId(WalletEnum.CREDIT.value()); |
| | | cdnFlow.setMoney(money); |
| | | cdnFlow.setOldmoney(credit.getMoney()); |
| | | cdnFlowService.save(cdnFlow); |
| | | cdnUserWalletService.update(Wrappers.lambdaUpdate(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId, cdnWalletInfoParam.getUserId()) |
| | | .eq(CdnUserWallet::getWalletId, WalletEnum.CREDIT.value()) |
| | | .set(CdnUserWallet::getMoney, cdnWalletInfoParam.getCredit()) |
| | | .set(CdnUserWallet::getUpdateTime, new Date())); |
| | | } |
| | | |
| | | if (!cdnWalletInfoParam.getAlloy().equals(BigDecimal.ZERO) && !cdnWalletInfoParam.getAlloy().equals(alloy.getMoney())) { |
| | | BigDecimal money = cdnWalletInfoParam.getAlloy().subtract(alloy.getMoney()); |
| | | cdnFlow.setWalletId(WalletEnum.ALLOY.value()); |
| | | cdnFlow.setMoney(money); |
| | | cdnFlow.setOldmoney(alloy.getMoney()); |
| | | cdnFlowService.save(cdnFlow); |
| | | cdnUserWalletService.update(Wrappers.lambdaUpdate(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId, cdnWalletInfoParam.getUserId()) |
| | | .eq(CdnUserWallet::getWalletId, WalletEnum.ALLOY.value()) |
| | | .set(CdnUserWallet::getMoney, cdnWalletInfoParam.getAlloy()) |
| | | .set(CdnUserWallet::getUpdateTime, new Date())); |
| | | } |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | |
| | | @GetMapping("/getDownLevel") |
| | | @Operation(summary = "获取下级用户", description = "获取下级用户") |
| | | public ServerResponseEntity<List<CdnUserAtlasVO>> getDownLevel(@RequestParam String userId) { |
| | | List<CdnUserAtlasVO> list = userService.getDownLevel(userId); |
| | | return ServerResponseEntity.success(list); |
| | | } |
| | | |
| | | @GetMapping("/getUpLevel") |
| | | @Operation(summary = "获取上级用户", description = "获取上级用户") |
| | | public ServerResponseEntity<List<CdnUserAtlasVO>> getUpLevel(@RequestParam String userId) { |
| | | List<CdnUserAtlasVO> list = userService.getUpLevel(userId); |
| | | return ServerResponseEntity.success(list); |
| | | } |
| | | |
| | | /** |
| | | * 释放后减少个人业绩和团队业绩 |
| | | * @param userId |
| | | * @param num |
| | | */ |
| | | public void updateTmall(String userId, Integer num) { |
| | | CdnTeamRelation cdnTeamRelation = cdnTeamRelationService.geteamRelationByUserId(userId); |
| | | if (cdnTeamRelation != null && StringUtils.isNotEmpty(cdnTeamRelation.getPids() )) { |
| | | //减去个人业绩 |
| | | cdnTeamRelation.setMeall(cdnTeamRelation.getMeall().subtract(BigDecimal.valueOf(num))); |
| | | cdnTeamRelationService.updateById(cdnTeamRelation); |
| | | String[] pids = cdnTeamRelation.getPids().split(","); |
| | | for (String pid : pids) { |
| | | if (StringUtils.isNotBlank(pid)) { |
| | | CdnTeamRelation cdnTeamRelation1 = cdnTeamRelationService.geteamRelationByUserId(pid); |
| | | cdnTeamRelation1.setTeamall(cdnTeamRelation1.getTeamall().subtract(BigDecimal.valueOf(num))); |
| | | cdnTeamRelationService.updateById(cdnTeamRelation1); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | @GetMapping("/delUser/{userId}") |
| | | @Operation(summary = "删除用户", description = "删除用户") |
| | | public ServerResponseEntity delFlow(@PathVariable("userId") String userId) { |
| | | List<CdnTeamRelation> list = cdnTeamRelationService.getTeamRelationListSort(userId); |
| | | if(list.size() > 0){ |
| | | return ServerResponseEntity.showFailMsg("该会员存在下级用户,无法删除!"); |
| | | } |
| | | CdnTeamRelation cdnTeamRelation1 = cdnTeamRelationService.geteamRelationByUserId(userId); |
| | | if(cdnTeamRelation1.getMeall().compareTo(BigDecimal.ZERO) >0 || cdnTeamRelation1.getTeamall().compareTo(BigDecimal.ZERO) >0){ |
| | | return ServerResponseEntity.showFailMsg("该会员存在cdn托管设备业绩,无法删除!"); |
| | | } |
| | | if(cdnTeamRelation1.getMeallOwn().compareTo(BigDecimal.ZERO) >0 || cdnTeamRelation1.getTeamallOwn().compareTo(BigDecimal.ZERO) >0){ |
| | | return ServerResponseEntity.showFailMsg("该会员存在cdn自主设备业绩,无法删除!"); |
| | | } |
| | | //User user = userService.getById(userId); |
| | | userService.removeById(userId); |
| | | userExtensionService.remove(new LambdaQueryWrapper<UserExtension>().eq(UserExtension::getUserId,userId)); |
| | | cdnTeamRelationService.removeById(cdnTeamRelation1.getId()); |
| | | cdnUserWalletService.remove(new LambdaQueryWrapper<CdnUserWallet>().eq(CdnUserWallet::getUserId,userId)); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | // 支付密码加密 |
| | | public static String encryptWithMD5(String password) { |
| | | try { |
| | | // 创建一个MD5的消息摘要对象 |
| | | MessageDigest md = MessageDigest.getInstance("MD5"); |
| | | |
| | | // 将密码转换为字节数组并进行MD5摘要 |
| | | byte[] messageDigest = md.digest(password.getBytes()); |
| | | |
| | | // 将摘要转换为16进制字符串 |
| | | BigInteger no = new BigInteger(1, messageDigest); |
| | | String hashtext = no.toString(16); |
| | | |
| | | // 补齐长度到32位 |
| | | while (hashtext.length() < 32) { |
| | | hashtext = "0" + hashtext; |
| | | } |
| | | |
| | | return hashtext; |
| | | } catch (NoSuchAlgorithmException e) { |
| | | throw new RuntimeException("MD5 hashing algorithm not found", e); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.platform.controller.cdn; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.yami.shop.bean.model.*; |
| | | import com.yami.shop.bean.param.CdnFlowParam; |
| | | import com.yami.shop.bean.vo.UserVO; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.*; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.text.ParseException; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @RestController |
| | | @RequestMapping("/cdn/flow") |
| | | @Tag(name = "cdn用户流水") |
| | | public class CdnUserFlowController { |
| | | @Autowired |
| | | private CdnFlowService cdnFlowService; |
| | | @Autowired |
| | | private UserService userService; |
| | | @Autowired |
| | | private CdnFlownameService cdnFlownameService; |
| | | @Autowired |
| | | private CdnTeamRelationService cdnTeamRelationService; |
| | | @Autowired |
| | | private CdnWalletService cdnWalletService; |
| | | @Autowired |
| | | private CdnUserWalletService cdnUserWalletService; |
| | | @Autowired |
| | | private DeviceService deviceService; |
| | | |
| | | @GetMapping("/getUserFlowList") |
| | | @Operation(summary = "根据条件分页查询会员流水列表", description = "根据条件分页查询会员流水列表") |
| | | public ServerResponseEntity<CdnFlowParam> page(PageParam<CdnFlow> page, @ParameterObject CdnFlow cdnFlow) { |
| | | LambdaQueryWrapper<CdnFlow> wrapper = new LambdaQueryWrapper<>(CdnFlow.class); |
| | | if (cdnFlow.getId() != null) wrapper.eq(CdnFlow::getId, cdnFlow.getId()); |
| | | if (cdnFlow.getUserId() != null && !cdnFlow.getUserId().equals("")) |
| | | wrapper.eq(CdnFlow::getUserId, cdnFlow.getUserId()); |
| | | if (cdnFlow.getWalletId() != null) wrapper.eq(CdnFlow::getWalletId, cdnFlow.getWalletId()); |
| | | if (cdnFlow.getXmoney() != null || cdnFlow.getDmoney() != null) |
| | | wrapper.between(CdnFlow::getMoney, cdnFlow.getXmoney(), cdnFlow.getDmoney()); |
| | | if (cdnFlow.getMemo() != null && !cdnFlow.getMemo().equals("")) |
| | | wrapper.like(CdnFlow::getMemo, cdnFlow.getMemo()); |
| | | if (cdnFlow.getStartCreateTime() != null && !cdnFlow.getStartCreateTime().equals("") && !cdnFlow.getEndCreateTime().equals("") && cdnFlow.getEndCreateTime() != null) { |
| | | wrapper.between(CdnFlow::getCreateTime, cdnFlow.getStartCreateTime(), cdnFlow.getEndCreateTime()); |
| | | } |
| | | if (cdnFlow.getMobile() != null && !cdnFlow.getMobile().equals("")) { |
| | | List<User> list = userService.list(Wrappers.lambdaQuery(User.class).like(User::getUserMobile, cdnFlow.getMobile())); |
| | | if (!list.isEmpty()) { |
| | | wrapper.in(CdnFlow::getUserId, list.stream().map(User::getUserId).collect(Collectors.toList())); |
| | | } else { |
| | | return ServerResponseEntity.success(new CdnFlowParam()); |
| | | } |
| | | } |
| | | if (cdnFlow.getFlownameIdList() != null && !cdnFlow.getFlownameIdList().equals("")) { |
| | | String flownameIdList = cdnFlow.getFlownameIdList(); |
| | | String[] split = flownameIdList.split(","); |
| | | wrapper.in(CdnFlow::getFlownameId, split); |
| | | } |
| | | wrapper.eq(CdnFlow::getDelStatus, 0); |
| | | wrapper.orderByDesc(CdnFlow::getCreateTime); |
| | | PageParam<CdnFlow> page1 = cdnFlowService.page(page, wrapper); |
| | | if (!page1.getRecords().isEmpty()) { |
| | | for (CdnFlow cdnFlow1 : page1.getRecords()) { |
| | | CdnUserWallet info = userService.getInfo(cdnFlow1.getUserId(), cdnFlow1.getWalletId()); |
| | | if (info != null) { |
| | | cdnFlow1.setPid(info.getPid()); |
| | | cdnFlow1.setPNickName(info.getPNickName()); |
| | | cdnFlow1.setPMobile(info.getPMobile()); |
| | | cdnFlow1.setUserName(info.getUserName()); |
| | | cdnFlow1.setNickName(info.getNickName()); |
| | | cdnFlow1.setMobile(info.getMobile()); |
| | | cdnFlow1.setWalletName(info.getWalletName()); |
| | | } |
| | | } |
| | | } |
| | | CdnFlowParam cdnFlowParam = new CdnFlowParam(); |
| | | cdnFlowParam.setCdnFlowPageParam(page1); |
| | | if(cdnFlow.getWalletId() != null && cdnFlow.getMemo() != null && !cdnFlow.getMemo().equals("")) { |
| | | List<CdnFlow> list = cdnFlowService.list(wrapper); |
| | | // 统计 |
| | | if (!list.isEmpty()) { |
| | | BigDecimal count = list.stream().map(CdnFlow::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | cdnFlowParam.setCount(count); |
| | | } |
| | | }else{ |
| | | cdnFlowParam.setCount(BigDecimal.ZERO); |
| | | } |
| | | return ServerResponseEntity.success(cdnFlowParam); |
| | | } |
| | | |
| | | /** |
| | | * 通过id查询 |
| | | * @param id id |
| | | * @return 单个数据 |
| | | */ |
| | | @GetMapping("/info/{id}") |
| | | @Operation(summary = "通过id查询", description = "通过id查询") |
| | | public ServerResponseEntity<CdnFlow> getById(@PathVariable("id") Long id) { |
| | | CdnFlow cdnFlow = cdnFlowService.getById(id); |
| | | User user = userService.getUserByUserId(cdnFlow.getUserId()); |
| | | cdnFlow.setUserName(user.getUserName()); |
| | | cdnFlow.setNickName(user.getNickName()); |
| | | cdnFlow.setMobile(user.getUserMobile()); |
| | | return ServerResponseEntity.success(cdnFlow); |
| | | } |
| | | |
| | | @PostMapping("/edit") |
| | | @Operation(summary = "编辑保存", description = "编辑保存") |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public ServerResponseEntity save(@RequestBody CdnFlow cdnFlow) throws ParseException { |
| | | // if (cdnFlow.getMoney().compareTo(BigDecimal.ZERO) <= 0) { |
| | | // return ServerResponseEntity.showFailMsg("金额必须大于0"); |
| | | // } |
| | | Device device = deviceService.list(Wrappers.lambdaQuery(Device.class).eq(Device::getDeviceName, cdnFlow.getDeviceName())).get(0); |
| | | if (device == null) { |
| | | return ServerResponseEntity.showFailMsg("设备不存在"); |
| | | } |
| | | CdnUserWallet cdnUserWallet = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class).eq(CdnUserWallet::getUserId, cdnFlow.getUserId()).eq(CdnUserWallet::getWalletId, cdnFlow.getWalletId())); |
| | | if (cdnUserWallet == null){ |
| | | return ServerResponseEntity.showFailMsg("用户不存在"); |
| | | } |
| | | SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); |
| | | List<CdnFlow> cdnFlowList = cdnFlowService.list(Wrappers.lambdaQuery(CdnFlow.class) |
| | | .eq(CdnFlow::getUserId,device.getUserId()) |
| | | .eq(CdnFlow::getBizSource,device.getId()) |
| | | .like(CdnFlow::getDate,cdnFlow.getDate()) |
| | | .orderByDesc(CdnFlow::getUpdateTime)); |
| | | if (!cdnFlowList.isEmpty()) { |
| | | CdnFlow flow = cdnFlowList.get(0); |
| | | // 插入流水 |
| | | cdnFlow.setId(flow.getId()); |
| | | cdnFlow.setFlownameId(49); |
| | | cdnFlow.setMoney(cdnFlow.getMoney().add(flow.getMoney())); |
| | | cdnFlow.setMemo("后台操作设备收益"); |
| | | cdnFlow.setBizData(3L); |
| | | cdnFlow.setOldmoney(cdnUserWallet.getMoney()); |
| | | cdnFlow.setBizType("AI淘金"); |
| | | cdnFlow.setUpdateTime(new Date()); |
| | | cdnFlow.setDate(simpleDateFormat.parse(cdnFlow.getCreateTimeStr())); |
| | | cdnFlowService.updateById(cdnFlow); |
| | | }else{ |
| | | // 插入流水 |
| | | cdnFlow.setFlownameId(49); |
| | | cdnFlow.setMemo("后台操作设备收益"); |
| | | cdnFlow.setBizData(3L); |
| | | cdnFlow.setOldmoney(cdnUserWallet.getMoney()); |
| | | cdnFlow.setBizType("AI淘金"); |
| | | cdnFlow.setCreateTime(new Date()); |
| | | cdnFlow.setDate(simpleDateFormat.parse(cdnFlow.getCreateTimeStr())); |
| | | cdnFlow.setBizSource(device.getId()); |
| | | cdnFlowService.save(cdnFlow); |
| | | } |
| | | // 修改钱包 |
| | | cdnUserWallet.setMoney(cdnUserWallet.getMoney().add(cdnFlow.getMoney())); |
| | | cdnUserWalletService.updateById(cdnUserWallet); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @GetMapping("/getFlowNameList") |
| | | @Operation(summary = "获取流水名称列表", description = "获取流水名称列表") |
| | | public ServerResponseEntity<List<CdnFlowname>> getFlowNameList() { |
| | | return ServerResponseEntity.success(cdnFlownameService.list()); |
| | | } |
| | | |
| | | @GetMapping("/delFlow/{id}") |
| | | @Operation(summary = "删除流水", description = "删除流水") |
| | | public ServerResponseEntity delFlow(@PathVariable("id") Long id) { |
| | | CdnFlow cdnFlow = cdnFlowService.getById(id); |
| | | cdnFlow.setDelStatus(1); |
| | | cdnFlowService.updateById(cdnFlow); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | // 获取用户列表 |
| | | @GetMapping("/getUserList") |
| | | @Operation(summary = "获取用户列表", description = "获取用户列表") |
| | | public ServerResponseEntity<List<UserVO>> getUserList() { |
| | | List<User> list = userService.list(Wrappers.lambdaQuery(User.class).eq(User::getStatus, 1)); |
| | | return ServerResponseEntity.success(list.stream().map(user -> { |
| | | UserVO userVO = new UserVO(); |
| | | userVO.setUserId(user.getUserId()); |
| | | userVO.setNickName(user.getNickName()); |
| | | userVO.setUserMobile(user.getUserMobile()); |
| | | userVO.setPic(user.getPic()); |
| | | userVO.setStatus(user.getStatus()); |
| | | return userVO; |
| | | }).collect(Collectors.toList())); |
| | | } |
| | | |
| | | @GetMapping("/getDeviceList") |
| | | @Operation(summary = "获取设备列表", description = "获取设备列表") |
| | | public ServerResponseEntity<List<Device>> getDeviceList() { |
| | | return ServerResponseEntity.success(deviceService.list()); |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.platform.controller.cdn; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.model.CdnAgentLevel; |
| | | import com.yami.shop.bean.model.CdnCenterLevel; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.CdnAgentLevelService; |
| | | import com.yami.shop.service.CdnCenterLevelService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | @RestController |
| | | @RequestMapping("/cdn/userLevel") |
| | | @Tag(name = "Cdn会员等级接口") |
| | | public class CdnUserLevelController { |
| | | @Autowired |
| | | private CdnCenterLevelService cdnCenterLevelService; |
| | | @Autowired |
| | | private CdnAgentLevelService cdnAgentLevelService; |
| | | |
| | | @GetMapping("/center") |
| | | @Operation(summary = "查询加权等级列表",description = "查询加权等级列表") |
| | | public ServerResponseEntity<IPage<CdnCenterLevel>> page(PageParam<CdnCenterLevel> page, @ParameterObject CdnCenterLevel centerLevel) { |
| | | LambdaQueryWrapper<CdnCenterLevel> wrapper = new LambdaQueryWrapper<>(CdnCenterLevel.class); |
| | | if (centerLevel.getId() != null) wrapper.eq(CdnCenterLevel::getId, centerLevel.getId()); |
| | | PageParam<CdnCenterLevel> page1 = cdnCenterLevelService.page(page, wrapper); |
| | | return ServerResponseEntity.success(page1); |
| | | } |
| | | @GetMapping("/agent") |
| | | @Operation(summary = "查询会员等级列表",description = "查询会员等级列表") |
| | | public ServerResponseEntity<IPage<CdnAgentLevel>> page(PageParam<CdnAgentLevel> page, @ParameterObject CdnAgentLevel cdnAgentLevel) { |
| | | LambdaQueryWrapper<CdnAgentLevel> wrapper = new LambdaQueryWrapper<>(CdnAgentLevel.class); |
| | | if (cdnAgentLevel.getId() != null) wrapper.eq(CdnAgentLevel::getId, cdnAgentLevel.getId()); |
| | | PageParam<CdnAgentLevel> page1 = cdnAgentLevelService.page(page, wrapper); |
| | | return ServerResponseEntity.success(page1); |
| | | } |
| | | |
| | | @GetMapping("/center/info/{id}") |
| | | @Operation(summary = "根据id获取加权详情" , description = "根据id获取加权详情") |
| | | public ServerResponseEntity<CdnCenterLevel> centerInfo(@PathVariable("id") Long id) { |
| | | CdnCenterLevel cdnCenterLevel = cdnCenterLevelService.getById(id); |
| | | return ServerResponseEntity.success(cdnCenterLevel); |
| | | } |
| | | @GetMapping("/agent/info/{id}") |
| | | @Operation(summary = "根据id获取代理详情" , description = "根据id获取代理详情") |
| | | public ServerResponseEntity<CdnAgentLevel> agentInfo(@PathVariable("id") Long id) { |
| | | CdnAgentLevel cdnAgentLevel = cdnAgentLevelService.getById(id); |
| | | return ServerResponseEntity.success(cdnAgentLevel); |
| | | } |
| | | |
| | | @PostMapping("/center") |
| | | @Operation(summary = "保存加权信息" , description = "保存加权信息") |
| | | public ServerResponseEntity<Void> save(@RequestBody CdnCenterLevel cdnCenterLevel) { |
| | | cdnCenterLevelService.save(cdnCenterLevel); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | @PostMapping("/agent") |
| | | @Operation(summary = "保存代理信息" , description = "保存代理信息") |
| | | public ServerResponseEntity<Void> save(@RequestBody CdnAgentLevel cdnAgentLevel) { |
| | | cdnAgentLevelService.save(cdnAgentLevel); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | @PutMapping("/center") |
| | | @Operation(summary = "修改加权信息" , description = "修改加权信息") |
| | | public ServerResponseEntity<Void> update(@RequestBody CdnCenterLevel cdnCenterLevel) { |
| | | cdnCenterLevelService.updateById(cdnCenterLevel); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | @PutMapping("/agent") |
| | | @Operation(summary = "修改代理信息" , description = "修改代理信息") |
| | | public ServerResponseEntity<Void> update(@RequestBody CdnAgentLevel cdnAgentLevel) { |
| | | cdnAgentLevelService.updateById(cdnAgentLevel); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | @DeleteMapping("/center/{id}") |
| | | @Operation(summary = "删除加权信息" , description = "删除加权信息") |
| | | public ServerResponseEntity<Void> deleteCenter(@PathVariable Integer id) { |
| | | cdnCenterLevelService.removeById(id); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | @DeleteMapping("/agent/{id}") |
| | | @Operation(summary = "删除代理信息" , description = "删除代理信息") |
| | | public ServerResponseEntity<Void> deleteAgent(@PathVariable Integer id) { |
| | | cdnAgentLevelService.removeById(id); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.yami.shop.platform.controller.cdn; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.yami.shop.bean.model.CdnTeamRelation; |
| | | import com.yami.shop.bean.model.CdnUserWallet; |
| | | import com.yami.shop.bean.model.User; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.CdnTeamRelationService; |
| | | import com.yami.shop.service.CdnUserWalletService; |
| | | import com.yami.shop.service.CdnWalletService; |
| | | import com.yami.shop.service.UserService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @RestController |
| | | @RequestMapping("/cdn/Wallet") |
| | | @Tag(name = "cdn用户钱包") |
| | | public class CdnUserWalletController { |
| | | @Autowired |
| | | private CdnUserWalletService cdnUserWalletService; |
| | | @Autowired |
| | | private UserService userService; |
| | | @Autowired |
| | | private CdnWalletService cdnWalletService; |
| | | @Autowired |
| | | private CdnTeamRelationService cdnTeamRelationService; |
| | | |
| | | @GetMapping("/getUserWalletList") |
| | | @Operation(summary = "根据条件分页查询会员钱包列表123", description = "根据条件分页查询会员钱包列表") |
| | | public ServerResponseEntity<IPage<CdnUserWallet>> page(PageParam<CdnUserWallet> page, @ParameterObject CdnUserWallet cdnUserWallet) { |
| | | LambdaQueryWrapper<CdnUserWallet> wrapper = new LambdaQueryWrapper<>(CdnUserWallet.class); |
| | | if (cdnUserWallet.getUserId() != null && !cdnUserWallet.getUserId().equals("")) |
| | | wrapper.eq(CdnUserWallet::getUserId, cdnUserWallet.getUserId()); |
| | | if (cdnUserWallet.getWalletId() != null) wrapper.eq(CdnUserWallet::getWalletId, cdnUserWallet.getWalletId()); |
| | | if (cdnUserWallet.getXmoney() != null || cdnUserWallet.getDmoney() != null) |
| | | wrapper.between(CdnUserWallet::getMoney, cdnUserWallet.getXmoney(), cdnUserWallet.getDmoney()); |
| | | if (cdnUserWallet.getCreateTimeStr() != null && !cdnUserWallet.getCreateTimeStr().equals("")) |
| | | wrapper.like(CdnUserWallet::getCreateTime, cdnUserWallet.getCreateTimeStr()); |
| | | if (cdnUserWallet.getUpdateTimeStr() != null && !cdnUserWallet.getUpdateTimeStr().equals("")) |
| | | wrapper.like(CdnUserWallet::getUpdateTime, cdnUserWallet.getUpdateTimeStr()); |
| | | if (cdnUserWallet.getUserName() != null && !cdnUserWallet.getUserName().equals("")) { |
| | | List<User> list = userService.list(Wrappers.lambdaQuery(User.class).like(User::getUserName, cdnUserWallet.getUserName())); |
| | | if (!list.isEmpty()) { |
| | | wrapper.in(CdnUserWallet::getUserId, list.stream().map(User::getUserId).collect(Collectors.toList())); |
| | | } else { |
| | | return ServerResponseEntity.success(new PageParam<>()); |
| | | } |
| | | } |
| | | if (cdnUserWallet.getNickName() != null && !cdnUserWallet.getNickName().equals("")) { |
| | | List<User> list = userService.list(Wrappers.lambdaQuery(User.class).like(User::getNickName, cdnUserWallet.getNickName())); |
| | | if (!list.isEmpty()) { |
| | | wrapper.in(CdnUserWallet::getUserId, list.stream().map(User::getUserId).collect(Collectors.toList())); |
| | | } else { |
| | | return ServerResponseEntity.success(new PageParam<>()); |
| | | } |
| | | } |
| | | if (cdnUserWallet.getMobile() != null && !cdnUserWallet.getMobile().equals("")) { |
| | | List<User> list = userService.list(Wrappers.lambdaQuery(User.class).like(User::getUserMobile, cdnUserWallet.getMobile())); |
| | | if (!list.isEmpty()) { |
| | | wrapper.in(CdnUserWallet::getUserId, list.stream().map(User::getUserId).collect(Collectors.toList())); |
| | | } else { |
| | | return ServerResponseEntity.success(new PageParam<>()); |
| | | } |
| | | } |
| | | if (cdnUserWallet.getPid() != null && !cdnUserWallet.getPid().equals("")) { |
| | | List<CdnTeamRelation> users = cdnTeamRelationService.list(Wrappers.lambdaQuery(CdnTeamRelation.class).eq(CdnTeamRelation::getPid, cdnUserWallet.getPid())); |
| | | if (!users.isEmpty()) { |
| | | wrapper.in(CdnUserWallet::getUserId, users.stream().map(CdnTeamRelation::getUserId).collect(Collectors.toList())); |
| | | } else { |
| | | return ServerResponseEntity.success(new PageParam<>()); |
| | | } |
| | | } |
| | | if (cdnUserWallet.getPNickName() != null && !cdnUserWallet.getPNickName().equals("")) { |
| | | List<User> users = userService.list(Wrappers.lambdaQuery(User.class).like(User::getNickName, cdnUserWallet.getPNickName())); |
| | | if (!users.isEmpty()) { |
| | | List<CdnTeamRelation> list = cdnTeamRelationService.list(Wrappers.lambdaQuery(CdnTeamRelation.class).in(CdnTeamRelation::getPid, users.stream().map(User::getUserId).collect(Collectors.toList()))); |
| | | if (!list.isEmpty()) { |
| | | wrapper.in(CdnUserWallet::getUserId, list.stream().map(CdnTeamRelation::getUserId).collect(Collectors.toList())); |
| | | } else { |
| | | return ServerResponseEntity.success(new PageParam<>()); |
| | | } |
| | | } else { |
| | | return ServerResponseEntity.success(new PageParam<>()); |
| | | } |
| | | } |
| | | if (cdnUserWallet.getPMobile() != null && !cdnUserWallet.getPMobile().equals("")) { |
| | | User users = userService.getOne(Wrappers.lambdaQuery(User.class).eq(User::getUserMobile, cdnUserWallet.getPMobile())); |
| | | if (users != null) { |
| | | List<CdnTeamRelation> list = cdnTeamRelationService.list(Wrappers.lambdaQuery(CdnTeamRelation.class).eq(CdnTeamRelation::getPid, users.getUserId())); |
| | | if (!list.isEmpty()) { |
| | | wrapper.in(CdnUserWallet::getUserId, list.stream().map(CdnTeamRelation::getUserId).collect(Collectors.toList())); |
| | | } else { |
| | | return ServerResponseEntity.success(new PageParam<>()); |
| | | } |
| | | } else { |
| | | return ServerResponseEntity.success(new PageParam<>()); |
| | | } |
| | | } |
| | | wrapper.orderByDesc(CdnUserWallet::getCreateTime); |
| | | PageParam<CdnUserWallet> page1 = cdnUserWalletService.page(page, wrapper); |
| | | if (!page1.getRecords().isEmpty()) { |
| | | for (CdnUserWallet cdnUserWallet1 : page1.getRecords()) { |
| | | CdnUserWallet info = userService.getInfo(cdnUserWallet1.getUserId(), cdnUserWallet1.getWalletId()); |
| | | if (info != null) { |
| | | cdnUserWallet1.setPid(info.getPid()); |
| | | cdnUserWallet1.setPNickName(info.getPNickName()); |
| | | cdnUserWallet1.setPMobile(info.getPMobile()); |
| | | cdnUserWallet1.setUserName(info.getUserName()); |
| | | cdnUserWallet1.setNickName(info.getNickName()); |
| | | cdnUserWallet1.setMobile(info.getMobile()); |
| | | cdnUserWallet1.setWalletName(info.getWalletName()); |
| | | } |
| | | } |
| | | } |
| | | return ServerResponseEntity.success(page1); |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.multishop.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.yami.shop.bean.model.*; |
| | | import com.yami.shop.bean.param.CdnUserWithdrawalParam; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.service.*; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.math.BigDecimal; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @RestController |
| | | @RequestMapping("/cdn/Withdrawal") |
| | | @Tag(name = "cdn提现") |
| | | public class CdnUserWithdrawalController { |
| | | @Autowired |
| | | private CdnWithdrawalService cdnWithdrawalService; |
| | | @Autowired |
| | | private UserService userService; |
| | | @Autowired |
| | | private CdnUserBankService cdnUserBankService; |
| | | @Autowired |
| | | private CdnWalletService cdnWalletService; |
| | | @Autowired |
| | | private CdnTeamRelationService cdnTeamRelationService; |
| | | |
| | | @GetMapping("/getWithdrawalList") |
| | | @Operation(summary = "根据条件分页查询提现列表", description = "根据条件分页查询提现列表") |
| | | public ServerResponseEntity<CdnUserWithdrawalParam> page(PageParam<CdnWithdrawal> page, @ParameterObject CdnWithdrawal cdnWithdrawal) { |
| | | LambdaQueryWrapper<CdnWithdrawal> wrapper = new LambdaQueryWrapper<>(CdnWithdrawal.class); |
| | | if (cdnWithdrawal.getUserId() != null && !cdnWithdrawal.getUserId().equals("")) { |
| | | wrapper.eq(CdnWithdrawal::getUserId, cdnWithdrawal.getUserId()); |
| | | } |
| | | if (cdnWithdrawal.getTeam() != null && !cdnWithdrawal.getTeam().equals("")) { |
| | | List<CdnTeamRelation> cdnTeamRelation = cdnTeamRelationService.list(Wrappers.lambdaQuery(CdnTeamRelation.class).like(CdnTeamRelation::getPids, "," + cdnWithdrawal.getTeam() + ",")); |
| | | if (!cdnTeamRelation.isEmpty()) { |
| | | List<String> collect = new ArrayList<>(); |
| | | collect.add(cdnWithdrawal.getTeam()); |
| | | collect.addAll(cdnTeamRelation.stream().map(CdnTeamRelation::getUserId).collect(Collectors.toList())); |
| | | wrapper.in(CdnWithdrawal::getUserId,collect); |
| | | } else { |
| | | return ServerResponseEntity.success(new CdnUserWithdrawalParam()); |
| | | } |
| | | } |
| | | if (cdnWithdrawal.getWalletId() != null) wrapper.eq(CdnWithdrawal::getWalletId, cdnWithdrawal.getWalletId()); |
| | | if (cdnWithdrawal.getUserBankId() != null) |
| | | wrapper.eq(CdnWithdrawal::getUserBankId, cdnWithdrawal.getUserBankId()); |
| | | if (cdnWithdrawal.getXmoney() != null || cdnWithdrawal.getDmoney() != null) |
| | | wrapper.between(CdnWithdrawal::getMoney, cdnWithdrawal.getXmoney(), cdnWithdrawal.getDmoney()); |
| | | if (cdnWithdrawal.getXsxf() != null || cdnWithdrawal.getDsxf() != null) |
| | | wrapper.between(CdnWithdrawal::getSxf, cdnWithdrawal.getXsxf(), cdnWithdrawal.getDsxf()); |
| | | if (cdnWithdrawal.getXpoint() != null || cdnWithdrawal.getDpoint() != null) |
| | | wrapper.between(CdnWithdrawal::getPoint, cdnWithdrawal.getXpoint(), cdnWithdrawal.getDpoint()); |
| | | if (cdnWithdrawal.getStatus() != null) wrapper.eq(CdnWithdrawal::getStatus, cdnWithdrawal.getStatus()); |
| | | if (cdnWithdrawal.getStartCreateTime() != null && !cdnWithdrawal.getStartCreateTime().equals("") && !cdnWithdrawal.getEndCreateTime().equals("") && cdnWithdrawal.getEndCreateTime() != null) { |
| | | wrapper.between(CdnWithdrawal::getCreateTime, cdnWithdrawal.getStartCreateTime(), cdnWithdrawal.getEndCreateTime()); |
| | | } |
| | | if (cdnWithdrawal.getStartUpdateTime() != null && !cdnWithdrawal.getStartUpdateTime().equals("") && !cdnWithdrawal.getEndUpdateTime().equals("") && cdnWithdrawal.getEndUpdateTime() != null) { |
| | | wrapper.between(CdnWithdrawal::getUpdateTime, cdnWithdrawal.getStartUpdateTime(), cdnWithdrawal.getEndUpdateTime()); |
| | | } |
| | | wrapper.orderByDesc(CdnWithdrawal::getCreateTime); |
| | | if (cdnWithdrawal.getUserName() != null && !cdnWithdrawal.getUserName().equals("")) { |
| | | List<User> list = userService.list(Wrappers.lambdaQuery(User.class).like(User::getUserName, cdnWithdrawal.getUserName())); |
| | | if (!list.isEmpty()) { |
| | | wrapper.in(CdnWithdrawal::getUserId, list.stream().map(User::getUserId).collect(Collectors.toList())); |
| | | } else { |
| | | return ServerResponseEntity.success(new CdnUserWithdrawalParam()); |
| | | } |
| | | } |
| | | if (cdnWithdrawal.getNickName() != null && !cdnWithdrawal.getNickName().equals("")) { |
| | | List<User> list = userService.list(Wrappers.lambdaQuery(User.class).like(User::getNickName, cdnWithdrawal.getNickName())); |
| | | if (!list.isEmpty()) { |
| | | wrapper.in(CdnWithdrawal::getUserId, list.stream().map(User::getUserId).collect(Collectors.toList())); |
| | | } else { |
| | | return ServerResponseEntity.success(new CdnUserWithdrawalParam()); |
| | | } |
| | | } |
| | | // if (cdnWithdrawal.getRealName() != null && !cdnWithdrawal.getRealName().equals("")) { |
| | | // List<User> list = userService.list(Wrappers.lambdaQuery(User.class).like(User::getRealName, cdnWithdrawal.getRealName())); |
| | | // if (!list.isEmpty()) { |
| | | // wrapper.in(CdnWithdrawal::getUserId, list.stream().map(User::getUserId).collect(Collectors.toList())); |
| | | // } else { |
| | | // return ServerResponseEntity.success(new CdnUserWithdrawalParam()); |
| | | // } |
| | | // } |
| | | if (cdnWithdrawal.getMobile() != null && !cdnWithdrawal.getMobile().equals("")) { |
| | | List<User> list = userService.list(Wrappers.lambdaQuery(User.class).like(User::getUserMobile, cdnWithdrawal.getMobile())); |
| | | if (!list.isEmpty()) { |
| | | wrapper.in(CdnWithdrawal::getUserId, list.stream().map(User::getUserId).collect(Collectors.toList())); |
| | | } else { |
| | | return ServerResponseEntity.success(new CdnUserWithdrawalParam()); |
| | | } |
| | | } |
| | | if (cdnWithdrawal.getBank() != null && !cdnWithdrawal.getBank().equals("")) { |
| | | List<CdnUserBank> list = cdnUserBankService.list(Wrappers.lambdaQuery(CdnUserBank.class).like(CdnUserBank::getBank, cdnWithdrawal.getBank())); |
| | | if (!list.isEmpty()) { |
| | | wrapper.in(CdnWithdrawal::getUserId, list.stream().map(CdnUserBank::getUserId).collect(Collectors.toList())); |
| | | } else { |
| | | return ServerResponseEntity.success(new CdnUserWithdrawalParam()); |
| | | } |
| | | } |
| | | if (cdnWithdrawal.getRealName() != null && !cdnWithdrawal.getRealName().equals("")) { |
| | | List<CdnUserBank> list = cdnUserBankService.list(Wrappers.lambdaQuery(CdnUserBank.class).like(CdnUserBank::getName, cdnWithdrawal.getRealName())); |
| | | if (!list.isEmpty()) { |
| | | wrapper.in(CdnWithdrawal::getUserId, list.stream().map(CdnUserBank::getUserId).collect(Collectors.toList())); |
| | | } else { |
| | | return ServerResponseEntity.success(new CdnUserWithdrawalParam()); |
| | | } |
| | | } |
| | | if (cdnWithdrawal.getType() != null && !cdnWithdrawal.getType().equals("")) { |
| | | List<CdnUserBank> list = cdnUserBankService.list(Wrappers.lambdaQuery(CdnUserBank.class).eq(CdnUserBank::getType, cdnWithdrawal.getType())); |
| | | if (!list.isEmpty()) { |
| | | wrapper.in(CdnWithdrawal::getUserBankId, list.stream().map(CdnUserBank::getId).collect(Collectors.toList())); |
| | | } else { |
| | | return ServerResponseEntity.success(new CdnUserWithdrawalParam()); |
| | | } |
| | | } |
| | | if (cdnWithdrawal.getBankCode() != null && !cdnWithdrawal.getBankCode().equals("")) { |
| | | List<CdnUserBank> list = cdnUserBankService.list(Wrappers.lambdaQuery(CdnUserBank.class).like(CdnUserBank::getBankcode, cdnWithdrawal.getBankCode())); |
| | | if (!list.isEmpty()) { |
| | | wrapper.in(CdnWithdrawal::getUserId, list.stream().map(CdnUserBank::getUserId).collect(Collectors.toList())); |
| | | } else { |
| | | return ServerResponseEntity.success(new CdnUserWithdrawalParam()); |
| | | } |
| | | } |
| | | if (cdnWithdrawal.getPid() != null && !cdnWithdrawal.getPid().equals("")) { |
| | | List<CdnTeamRelation> cdnTeamRelation = cdnTeamRelationService.list(Wrappers.lambdaQuery(CdnTeamRelation.class).eq(CdnTeamRelation::getPid, cdnWithdrawal.getPid())); |
| | | if (!cdnTeamRelation.isEmpty()) { |
| | | wrapper.in(CdnWithdrawal::getUserId, cdnTeamRelation.stream().map(CdnTeamRelation::getUserId).collect(Collectors.toList())); |
| | | } else { |
| | | return ServerResponseEntity.success(new CdnUserWithdrawalParam()); |
| | | } |
| | | } |
| | | if (cdnWithdrawal.getPMobile() != null && !cdnWithdrawal.getPMobile().equals("")) { |
| | | User user = userService.getOne(Wrappers.lambdaQuery(User.class).eq(User::getUserMobile, cdnWithdrawal.getPMobile())); |
| | | if (user != null) { |
| | | List<CdnTeamRelation> cdnTeamRelation = cdnTeamRelationService.list(Wrappers.lambdaQuery(CdnTeamRelation.class).eq(CdnTeamRelation::getPid, user.getUserId())); |
| | | if (!cdnTeamRelation.isEmpty()) { |
| | | wrapper.in(CdnWithdrawal::getUserId, cdnTeamRelation.stream().map(CdnTeamRelation::getUserId).collect(Collectors.toList())); |
| | | }else { |
| | | return ServerResponseEntity.success(new CdnUserWithdrawalParam()); |
| | | } |
| | | }else { |
| | | return ServerResponseEntity.success(new CdnUserWithdrawalParam()); |
| | | } |
| | | } |
| | | if (cdnWithdrawal.getPNickName() != null && !cdnWithdrawal.getPNickName().equals("")) { |
| | | List<User> users = userService.list(Wrappers.lambdaQuery(User.class).like(User::getNickName, cdnWithdrawal.getPNickName())); |
| | | if (!users.isEmpty()) { |
| | | List<CdnTeamRelation> list = cdnTeamRelationService.list(Wrappers.lambdaQuery(CdnTeamRelation.class).in(CdnTeamRelation::getPid, users.stream().map(User::getUserId).collect(Collectors.toList()))); |
| | | if (!list.isEmpty()) { |
| | | wrapper.in(CdnWithdrawal::getUserId, list.stream().map(CdnTeamRelation::getUserId).collect(Collectors.toList())); |
| | | }else { |
| | | return ServerResponseEntity.success(new CdnUserWithdrawalParam()); |
| | | } |
| | | }else { |
| | | return ServerResponseEntity.success(new CdnUserWithdrawalParam()); |
| | | } |
| | | } |
| | | wrapper.orderByDesc(CdnWithdrawal::getCreateTime); |
| | | List<CdnWithdrawal> lists = cdnWithdrawalService.list(wrapper); |
| | | List<CdnWithdrawal> equalUserIdRecords = lists.stream() |
| | | .filter(cdnWithdrawal2 -> cdnWithdrawal2.getUserId().equals(cdnWithdrawal.getTeam())) |
| | | .collect(Collectors.toList()); |
| | | |
| | | List<CdnWithdrawal> otherRecords = lists.stream() |
| | | .filter(cdnWithdrawal2 -> !cdnWithdrawal2.getUserId().equals(cdnWithdrawal.getTeam())) |
| | | .collect(Collectors.toList()); |
| | | // 合并两个列表 |
| | | List<CdnWithdrawal> sortedRecords = new ArrayList<>(equalUserIdRecords); |
| | | sortedRecords.addAll(otherRecords); |
| | | |
| | | // 如果需要更新原始列表 |
| | | lists.clear(); |
| | | lists.addAll(sortedRecords); |
| | | |
| | | // 创建分页对象 |
| | | PageParam<CdnWithdrawal> page1 = new PageParam<>(); |
| | | page1.setSize(page.getSize()); |
| | | page1.setCurrent(page.getCurrent()); |
| | | if (!lists.isEmpty()) { |
| | | // 设置分页对象的总记录数 |
| | | page1.setTotal(lists.size()); |
| | | |
| | | // 设置分页对象的当前页数据 |
| | | int start = (int) ((page1.getCurrent() - 1) * page1.getSize()); |
| | | int end = (int) Math.min(start + page1.getSize(), sortedRecords.size()); |
| | | List<CdnWithdrawal> pageRecords = sortedRecords.subList(start, end); |
| | | |
| | | // 更新分页对象中的记录 |
| | | page1.setRecords(pageRecords); |
| | | // PageParam<CdnWithdrawal> page1 = cdnWithdrawalService.page(page, wrapper); |
| | | // if (!page1.getRecords().isEmpty()) { |
| | | List<CdnWithdrawal> records = page1.getRecords(); |
| | | for (CdnWithdrawal cdnWithdrawal1 : records) { |
| | | CdnUserWallet info = userService.getInfo(cdnWithdrawal1.getUserId(), cdnWithdrawal1.getWalletId()); |
| | | if (info != null) { |
| | | cdnWithdrawal1.setNickName(info.getNickName()); |
| | | cdnWithdrawal1.setMobile(info.getMobile()); |
| | | cdnWithdrawal1.setWalletName(info.getWalletName()); |
| | | } |
| | | CdnUserBank cdnUserBank = cdnUserBankService.getById(cdnWithdrawal1.getUserBankId()); |
| | | if (cdnUserBank != null) { |
| | | cdnWithdrawal1.setBankCode(cdnUserBank.getBankcode()); |
| | | cdnWithdrawal1.setBank(cdnUserBank.getBank()); |
| | | cdnWithdrawal1.setType(cdnUserBank.getType()); |
| | | cdnWithdrawal1.setRealName(cdnUserBank.getName()); |
| | | cdnWithdrawal1.setImage(cdnUserBank.getImage()); |
| | | } |
| | | } |
| | | } |
| | | CdnUserWithdrawalParam cdnUserWithdrawalParam = new CdnUserWithdrawalParam(); |
| | | cdnUserWithdrawalParam.setCdnWithdrawalPageParam(page1); |
| | | List<CdnWithdrawal> list = cdnWithdrawalService.list(wrapper); |
| | | // 统计 |
| | | if (!list.isEmpty()) { |
| | | BigDecimal count = list.stream().map(CdnWithdrawal::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | cdnUserWithdrawalParam.setCount(count); |
| | | } |
| | | BigDecimal applying = list.stream() |
| | | .filter(c -> c != null && c.getStatus() != null && c.getStatus().equals(0)) |
| | | .map(CdnWithdrawal::getMoney) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | cdnUserWithdrawalParam.setApplying(applying); |
| | | |
| | | BigDecimal checked = list.stream() |
| | | .filter(c -> c != null && c.getStatus() != null && c.getStatus().equals(1)) |
| | | .map(CdnWithdrawal::getMoney) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | cdnUserWithdrawalParam.setChecked(checked); |
| | | |
| | | BigDecimal refuse = list.stream() |
| | | .filter(c -> c != null && c.getStatus() != null && c.getStatus().equals(2)) |
| | | .map(CdnWithdrawal::getMoney) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | cdnUserWithdrawalParam.setRefuse(refuse); |
| | | return ServerResponseEntity.success(cdnUserWithdrawalParam); |
| | | } |
| | | |
| | | /** |
| | | * 通过id查询 |
| | | * @param id id |
| | | * @return 单个数据 |
| | | */ |
| | | @GetMapping("/info/{id}") |
| | | @Operation(summary = "通过id查询", description = "通过id查询") |
| | | public ServerResponseEntity<CdnWithdrawal> getById(@PathVariable("id") Long id) { |
| | | CdnWithdrawal cdnWithdrawal = cdnWithdrawalService.getById(id); |
| | | return ServerResponseEntity.success(cdnWithdrawal); |
| | | } |
| | | |
| | | @PostMapping("/edit") |
| | | @Operation(summary = "编辑保存", description = "编辑保存") |
| | | public ServerResponseEntity save(@RequestBody CdnWithdrawal cdnWithdrawal) { |
| | | CdnWithdrawal cdnWithdrawal1 = cdnWithdrawalService.getById(cdnWithdrawal.getId()); |
| | | if (cdnWithdrawal.getStatus() == 1) { |
| | | if (cdnWithdrawal1.getStatus() == 1){ |
| | | return ServerResponseEntity.showFailMsg("已通过,不能重复通过!"); |
| | | } |
| | | return cdnWithdrawalService.doWithdrawal(cdnWithdrawal); |
| | | } else if (cdnWithdrawal.getStatus() == 2) { |
| | | if (cdnWithdrawal1.getStatus() == 2){ |
| | | return ServerResponseEntity.showFailMsg("已拒绝,不能重复拒绝!"); |
| | | } |
| | | return cdnWithdrawalService.returnWithdrawal(cdnWithdrawal); |
| | | } |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PostMapping("/saveBatch") |
| | | @Operation(summary = "批量保存", description = "批量保存") |
| | | public ServerResponseEntity saveBatch(@RequestBody List<CdnWithdrawal> cdnWithdrawals) { |
| | | for (CdnWithdrawal cdnWithdrawal : cdnWithdrawals){ |
| | | if (cdnWithdrawal == null){ |
| | | continue; |
| | | } |
| | | cdnWithdrawal.setStatus(1); |
| | | cdnWithdrawalService.doWithdrawal(cdnWithdrawal); |
| | | } |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @GetMapping("/exportWithdrawal") |
| | | @Schema(description = "导出提现列表") |
| | | public void prodExport(HttpServletResponse response, @ParameterObject CdnWithdrawal cdnWithdrawal) { |
| | | cdnWithdrawalService.export(response, cdnWithdrawal); |
| | | } |
| | | |
| | | @GetMapping("/exportWithdrawals") |
| | | @Schema(description = "导出提现列表") |
| | | public void prodExports(HttpServletResponse response, @ParameterObject CdnWithdrawal cdnWithdrawal) { |
| | | cdnWithdrawalService.exports(response, cdnWithdrawal); |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.platform.controller.cdn; |
| | | |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.yami.shop.bean.model.CdnAgentLevel; |
| | | import com.yami.shop.bean.model.CdnCenterLevel; |
| | | import com.yami.shop.bean.model.CdnFlowname; |
| | | import com.yami.shop.bean.model.CdnWallet; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.service.CdnAgentLevelService; |
| | | import com.yami.shop.service.CdnCenterLevelService; |
| | | import com.yami.shop.service.CdnFlownameService; |
| | | import com.yami.shop.service.CdnWalletService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.util.List; |
| | | |
| | | @RestController |
| | | @RequestMapping("/cdn/typeName") |
| | | @Tag(name = "cdn获取类型字典列表") |
| | | public class CdnWalletController { |
| | | @Autowired |
| | | private CdnWalletService cdnWalletService; |
| | | @Autowired |
| | | private CdnAgentLevelService cdnAgentLevelService; |
| | | @Autowired |
| | | private CdnCenterLevelService cdnCenterLevelService; |
| | | @Autowired |
| | | private CdnFlownameService cdnFlownameService; |
| | | @GetMapping("/getWalletList") |
| | | @Operation(summary = "获取币种列表", description = "获取币种列表") |
| | | public ServerResponseEntity<List<CdnWallet>> getWalletList() { |
| | | List<CdnWallet> list = cdnWalletService.list(Wrappers.lambdaQuery(CdnWallet.class).eq(CdnWallet::getStatus, "1")); |
| | | return ServerResponseEntity.success(list); |
| | | } |
| | | |
| | | @GetMapping("/getAgentList") |
| | | @Operation(summary = "获取代理列表", description = "获取代理列表") |
| | | public ServerResponseEntity<List<CdnAgentLevel>> getAgentList() { |
| | | return ServerResponseEntity.success(cdnAgentLevelService.list(Wrappers.lambdaQuery())); |
| | | } |
| | | |
| | | @GetMapping("/getCenterList") |
| | | @Operation(summary = "获取加权列表", description = "获取加权列表") |
| | | public ServerResponseEntity<List<CdnCenterLevel>> getCenterList() { |
| | | return ServerResponseEntity.success(cdnCenterLevelService.list(Wrappers.lambdaQuery())); |
| | | } |
| | | |
| | | @GetMapping("/getFlowTypeList") |
| | | @Operation(summary = "获取流水类型列表", description = "获取流水类型列表") |
| | | public ServerResponseEntity<List<CdnFlowname>> getFlowTypeList() { |
| | | return ServerResponseEntity.success(cdnFlownameService.list(Wrappers.lambdaQuery())); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.yami.shop.platform.controller.test; |
| | | |
| | | import cn.hutool.core.date.DateTime; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.alipay.api.AlipayApiException; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.yami.shop.bean.model.CdnFlow; |
| | | import com.yami.shop.bean.model.CdnUserWallet; |
| | | import com.yami.shop.bean.model.MarsAdverIncome; |
| | | import com.yami.shop.bean.model.User; |
| | | import com.yami.shop.bean.pay.TransferDto; |
| | | import com.yami.shop.common.constants.DictConstant; |
| | | import com.yami.shop.common.enums.WalletEnum; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.manager.impl.TransferManager; |
| | | import com.yami.shop.service.CdnFlowService; |
| | | import com.yami.shop.service.CdnUserWalletService; |
| | | import com.yami.shop.service.MarsAdverIncomeService; |
| | | import com.yami.shop.service.UserService; |
| | | import com.yami.shop.task.common.model.TaskProvideRecord; |
| | | import com.yami.shop.task.common.model.TaskProvideUser; |
| | | import com.yami.shop.task.common.service.TaskProvideRecordService; |
| | | import com.yami.shop.task.common.service.TaskProvideUserService; |
| | | import lombok.AllArgsConstructor; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestBody; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Random; |
| | | |
| | | @RequestMapping("/platform/test") |
| | | @RestController |
| | | @AllArgsConstructor |
| | | public class TestTaskController { |
| | | |
| | | private final Logger logger = LoggerFactory.getLogger(this.getClass()); |
| | | |
| | | @Autowired |
| | | private TaskProvideRecordService taskProvideRecordService; |
| | | @Autowired |
| | | private TaskProvideUserService taskProvideUserService; |
| | | @Autowired |
| | | private UserService userService; |
| | | @Autowired |
| | | private CdnUserWalletService cdnUserWalletService; |
| | | @Autowired |
| | | private CdnFlowService cdnFlowService; |
| | | @Autowired |
| | | private MarsAdverIncomeService marsAdverIncomeService; |
| | | |
| | | private final TransferManager transferManager; |
| | | |
| | | |
| | | |
| | | @RequestMapping("/statusModify") |
| | | public ServerResponseEntity cancelPointRelease() { |
| | | Date now = new Date(); |
| | | logger.info("任务状态修改开始。。。" + DateUtil.format(now, "yyyy-MM-dd HH:mm:ss")); |
| | | // 查询已激活的任务释放 |
| | | List<TaskProvideUser> taskProvideUserList = taskProvideUserService.list(Wrappers.lambdaQuery(TaskProvideUser.class).gt(TaskProvideUser::getStatus, 0).lt(TaskProvideUser::getStatus, 4)); |
| | | |
| | | for (TaskProvideUser taskProvideUser : taskProvideUserList) { |
| | | switch (taskProvideUser.getStatus()) { |
| | | case 1: |
| | | taskProvideUser.setStatus(2); |
| | | |
| | | Random random = new Random(); |
| | | // 生成0到1之间的随机小数 |
| | | double randomFloat = random.nextDouble(); |
| | | // 将随机小数映射到1到20之间 |
| | | double randomFloat1To20 = randomFloat * 19 + 1; |
| | | System.out.println(randomFloat1To20); |
| | | // 以50%的概率添加负号 |
| | | if (random.nextBoolean()) { |
| | | randomFloat1To20 = -randomFloat1To20; |
| | | } |
| | | // 使用String.format()保留两位小数 |
| | | String formattedString = String.format("%.2f", randomFloat1To20); |
| | | // 如果你确实需要double类型,但注意这会丢失不必要的零 |
| | | double formattedDouble = Double.parseDouble(formattedString); |
| | | taskProvideUser.setProcess(50 + formattedDouble); |
| | | taskProvideUser.setProcess(50 + randomFloat1To20); |
| | | taskProvideUserService.updateById(taskProvideUser); |
| | | break; |
| | | case 2: |
| | | taskProvideUser.setStatus(3); |
| | | taskProvideUser.setProcess(100.00); |
| | | taskProvideUserService.updateById(taskProvideUser); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @RequestMapping("/init") |
| | | public ServerResponseEntity cancelGeneral() { |
| | | Date now = new Date(); |
| | | logger.info("任务提供释放初始化开始。。。" + DateUtil.format(now, "yyyy-MM-dd HH:mm:ss")); |
| | | // 查询任务提供释放记录。开始和结束时间在当前时间段内 |
| | | // Date date = DateUtil.parse(DateUtil.format(new Date(), "yyyy-MM-dd"), "yyyy-MM-dd"); |
| | | // 将Date对象格式化为字符串 |
| | | String formattedDate = DateUtil.format(now, "yyyy-MM-dd"); |
| | | List<TaskProvideRecord> taskProvideRecordList = taskProvideRecordService.list(Wrappers.lambdaQuery(TaskProvideRecord.class) |
| | | .le(TaskProvideRecord::getStartTime,formattedDate) |
| | | .ge(TaskProvideRecord::getEndTime, formattedDate)); |
| | | // 遍历任务提供记录 |
| | | for (TaskProvideRecord taskProvideRecord : taskProvideRecordList) { |
| | | |
| | | // 查询所有激活任务大厅的用户 |
| | | List<User> users = userService.list(Wrappers.lambdaQuery(User.class).eq(User::getActiveStatus, 1)); |
| | | // 遍历初始化用户 |
| | | for (User user : users) { |
| | | |
| | | // 查询用户的金牛豆释放总额 |
| | | CdnUserWallet cdnUserWallet = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class).eq(CdnUserWallet::getUserId, user.getUserId()).eq(CdnUserWallet::getWalletId, WalletEnum.LUCKPOOL.value())); |
| | | BigDecimal releaseCount = cdnUserWallet.getReleaseCount() != null ? cdnUserWallet.getReleaseCount() : BigDecimal.ZERO; |
| | | if (releaseCount.compareTo(BigDecimal.ZERO) > 0) { |
| | | // 创建任务提供用户 |
| | | TaskProvideUser taskProvideUser = new TaskProvideUser(); |
| | | taskProvideUser.setUserId(user.getUserId()); |
| | | taskProvideUser.setProvideRecordId(taskProvideRecord.getProvideRecordId()); |
| | | taskProvideUser.setDateTime(formattedDate + ""); |
| | | taskProvideUser.setCreateTime(new Date()); |
| | | taskProvideUser.setTaskId(taskProvideRecord.getTaskId()); |
| | | taskProvideUser.setStatus(0); |
| | | taskProvideUser.setProcess(0.00); |
| | | taskProvideUser.setStartTime(new Date()); |
| | | taskProvideUser.setReleaseCount(cdnUserWallet.getReleaseCount()); |
| | | |
| | | // 根据释放百分比算出本次释放的幸运池数量 |
| | | BigDecimal release = cdnUserWallet.getReleaseCount().multiply(taskProvideRecord.getReleaseRate()); |
| | | Random random = new Random(); |
| | | // 生成0到1之间的随机小数(不包括1) |
| | | double randomFloat = random.nextDouble(); |
| | | // 以50%的概率添加负号 |
| | | if (random.nextBoolean()) { |
| | | randomFloat = -randomFloat; |
| | | } |
| | | // 使用String.format()保留两位小数 |
| | | String formattedString = String.format("%.2f", randomFloat); |
| | | // 如果你确实需要double类型,但注意这会丢失不必要的零 |
| | | double formattedDouble = Double.parseDouble(formattedString); |
| | | release = release.add(BigDecimal.valueOf(formattedDouble)); |
| | | |
| | | taskProvideUser.setReleases(release); |
| | | taskProvideUserService.save(taskProvideUser); |
| | | } |
| | | } |
| | | } |
| | | logger.info("任务提供释放初始化结束。。。" + DateUtil.format(now, "yyyy-MM-dd HH:mm:ss")); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @RequestMapping("/releaseMoney") |
| | | public ServerResponseEntity releaseMoney() { |
| | | try { |
| | | logger.info("AI+自主掘金分润计算开始。。。" + DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")); |
| | | List<TaskProvideUser> list = taskProvideUserService.list(new LambdaQueryWrapper<TaskProvideUser>().eq(TaskProvideUser::getStatus, 3)); |
| | | for (TaskProvideUser taskProvideUser : list) { |
| | | if(ObjectUtil.isNotEmpty(taskProvideUser.getReleases())){ |
| | | if(taskProvideUser.getReleases().compareTo(BigDecimal.ZERO) > 0){ |
| | | setFlowLog(taskProvideUser.getUserId(),taskProvideUser.getUserId(),taskProvideUser.getReleases(), DictConstant.WALLET_ID_10,"AI+自主掘金分润",DictConstant.FLOWNAME_ID_50); |
| | | taskProvideUser.setStatus(4); |
| | | taskProvideUserService.updateById(taskProvideUser); |
| | | MarsAdverIncome marsAdverIncome = MarsAdverIncome.builder() |
| | | .userId(taskProvideUser.getUserId()) |
| | | .money(taskProvideUser.getReleases()) |
| | | .date(new Date()) |
| | | .build(); |
| | | marsAdverIncomeService.save(marsAdverIncome); |
| | | } |
| | | } |
| | | } |
| | | |
| | | logger.info("AI+自主掘金分润计算结束。。。" + DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")); |
| | | }catch (Exception e) { |
| | | logger.error("AI+自主掘金分润计算失败", e); |
| | | } |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * |
| | | * @param userId 受益人 |
| | | * @param userIds 贡献人 |
| | | * @param money 收益金额 |
| | | * @param walletId 钱包类型 |
| | | * @param desc 收益描述 |
| | | * @param flownameId 流水类型 |
| | | */ |
| | | private void setFlowLog(String userId, String userIds, BigDecimal money, Integer walletId, String desc, Integer flownameId){ |
| | | CdnFlow cdnFlow = new CdnFlow(); |
| | | cdnFlow.setUserIds(userIds); |
| | | cdnFlow.setUserId(userId); |
| | | cdnFlow.setFlownameId(flownameId); |
| | | cdnFlow.setWalletId(walletId); |
| | | //钱包更改 |
| | | CdnUserWallet cdnUserWallet = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId,userId) |
| | | .eq(CdnUserWallet::getWalletId,walletId)); |
| | | if(cdnUserWallet.getMoney().compareTo(BigDecimal.ZERO) == 0){ |
| | | return; |
| | | } |
| | | if(money.compareTo(BigDecimal.ZERO) <= 0){//幸运池已经释放完毕 |
| | | return; |
| | | }else{ |
| | | if(money.compareTo(cdnUserWallet.getMoney()) >= 0){ |
| | | cdnFlow.setMoney(cdnUserWallet.getMoney().negate()); |
| | | }else{ |
| | | cdnFlow.setMoney(money.negate()); |
| | | } |
| | | } |
| | | cdnFlow.setMemo(desc+":释放用户"+userIds); |
| | | cdnFlow.setCreateTime(new Date()); |
| | | cdnFlow.setDate(new Date()); |
| | | cdnFlow.setOldmoney(cdnUserWallet.getMoney()); |
| | | cdnFlowService.save(cdnFlow); |
| | | cdnUserWallet.setUserId(userId); |
| | | cdnUserWallet.setWalletId(walletId); |
| | | cdnUserWallet.setMoney(cdnUserWallet.getMoney().add(cdnFlow.getMoney())); |
| | | cdnUserWallet.setUpdateTime(new Date()); |
| | | cdnUserWallet.setReleaseCount(cdnUserWallet.getReleaseCount().add(cdnFlow.getMoney())); |
| | | cdnUserWalletService.updateById(cdnUserWallet); |
| | | //释放完进入流量 |
| | | CdnFlow cdnFlows = new CdnFlow(); |
| | | BeanUtils.copyProperties(cdnFlow, cdnFlows); |
| | | cdnFlows.setMoney(cdnFlow.getMoney().negate()); |
| | | cdnFlows.setWalletId(DictConstant.WALLET_ID_8); |
| | | cdnFlows.setFlownameId(flownameId); |
| | | CdnUserWallet cdnUserWallets = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId,userId) |
| | | .eq(CdnUserWallet::getWalletId,DictConstant.WALLET_ID_8)); |
| | | if(null == cdnUserWallets){ |
| | | return; |
| | | } |
| | | cdnFlows.setOldmoney(cdnUserWallets.getMoney() == null?BigDecimal.ZERO:cdnUserWallets.getMoney()); |
| | | cdnFlows.setMemo(desc+"-->流量:相关用户"+userIds); |
| | | cdnFlowService.save(cdnFlows); |
| | | //钱包更改 |
| | | cdnUserWallets.setUserId(userId); |
| | | cdnUserWallets.setWalletId(DictConstant.WALLET_ID_8); |
| | | cdnUserWallets.setMoney(cdnUserWallets.getMoney()== null?cdnFlow.getMoney().negate():cdnUserWallets.getMoney().add(cdnFlow.getMoney().negate())); |
| | | cdnUserWallets.setUpdateTime(new Date()); |
| | | cdnUserWalletService.updateById(cdnUserWallets); |
| | | } |
| | | |
| | | |
| | | @PostMapping("/test/transfer") |
| | | public ServerResponseEntity<?> test(@RequestBody TransferDto transferDto){ |
| | | transferDto.setOutBizNo("20241012112121"); |
| | | // transferDto.setTransAmount("0.2"); |
| | | transferDto.setOrderTitle("测试转账"); |
| | | // transferDto.setIdentity("3673245879@qq.com"); |
| | | transferDto.setIdentityType("ALIPAY_LOGON_ID"); |
| | | // transferDto.setName("上海门也科技股份有限公司"); |
| | | |
| | | try { |
| | | return transferManager.aliTransfer(transferDto); |
| | | } catch (AlipayApiException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.task; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.yami.shop.bean.model.User; |
| | | import com.yami.shop.bean.param.UserManagerParam; |
| | | import com.yami.shop.bean.param.UserManagerReqParam; |
| | | import com.yami.shop.service.UserService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import java.util.List; |
| | | import java.util.concurrent.Callable; |
| | | |
| | | /** |
| | | * @author yami |
| | | */ |
| | | @Slf4j |
| | | public class AnalysisSalseTask implements Callable<List<UserManagerParam>> { |
| | | |
| | | private UserService userService; |
| | | private UserManagerReqParam user; |
| | | private Page<User> pages; |
| | | |
| | | public AnalysisSalseTask(UserService userService, UserManagerReqParam user, Page<User> pages) { |
| | | this.userService = userService; |
| | | this.user = user; |
| | | this.pages = pages; |
| | | } |
| | | |
| | | @Override |
| | | public List<UserManagerParam> call() throws Exception { |
| | | IPage<UserManagerParam> userPage = userService.getUserInfoPage(pages,user); |
| | | return userPage.getRecords(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.platform.task; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.xxl.job.core.handler.annotation.XxlJob; |
| | | import com.yami.shop.bean.model.*; |
| | | import com.yami.shop.common.config.BigSellerConfig; |
| | | import com.yami.shop.cps.commom.client.DtkApiClient; |
| | | import com.yami.shop.cps.commom.request.putstorage.DtkNewestGoodsRequest; |
| | | import com.yami.shop.cps.commom.request.putstorage.DtkPullGoodsByTimeRequest; |
| | | import com.yami.shop.cps.commom.request.putstorage.DtkStaleGoodsByTimeRequest; |
| | | import com.yami.shop.cps.commom.response.base.DtkApiResponse; |
| | | import com.yami.shop.cps.commom.response.base.DtkPageResponse; |
| | | import com.yami.shop.cps.commom.response.mastertool.DtkGetOrderDetailsResultsItemsResponse; |
| | | import com.yami.shop.cps.commom.response.mastertool.DtkGetOrderDetailsResultsResponse; |
| | | import com.yami.shop.cps.commom.response.mastertool.DtkJdOrderQueryV2Response; |
| | | import com.yami.shop.cps.commom.response.mastertool.MtOrderResponse; |
| | | import com.yami.shop.cps.commom.response.putstorage.DtkGoodsListItemResponse; |
| | | import com.yami.shop.cps.commom.response.putstorage.DtkNewestGoodsResponse; |
| | | import com.yami.shop.cps.commom.response.putstorage.DtkStaleGoodsByTimeResponse; |
| | | import com.yami.shop.cps.commom.service.*; |
| | | import com.yami.shop.cps.commom.utils.DTKUtils; |
| | | import com.yami.shop.cps.commom.utils.MTUtils; |
| | | import com.yami.shop.cps.commom.vo.*; |
| | | import com.yami.shop.service.CpsConfigService; |
| | | import com.yami.shop.service.UserService; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.Duration; |
| | | import java.time.LocalDateTime; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * cps商品订单定时任务 |
| | | */ |
| | | @Component |
| | | public class CpsShopOrderTask { |
| | | |
| | | private final Logger logger = LoggerFactory.getLogger(this.getClass()); |
| | | |
| | | @Autowired |
| | | private CpsConfigService cpsConfigService; |
| | | |
| | | @Autowired |
| | | private CpsShopService cpsShopService; |
| | | |
| | | @Autowired |
| | | private CpsOrderService cpsOrderService; |
| | | |
| | | @Autowired |
| | | private CpsJdOrderService cpsJdOrderService; |
| | | |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @Autowired |
| | | private CpsMtActitvityService cpsMtActitvityService; |
| | | |
| | | @Autowired |
| | | private CpsMtOrderService cpsMtOrderService; |
| | | |
| | | @Autowired |
| | | private CpsDdOrderService cpsDdOrderService; |
| | | @Autowired |
| | | private CpsJtkOrderService cpsJtkOrderService; |
| | | |
| | | /** |
| | | * 淘宝商品定时拉取 1小时执行一次 |
| | | */ |
| | | @XxlJob("pushGoodByTime") |
| | | public void pushGoodByTime(String startTime,String endTime,String pageId) { |
| | | LocalDateTime currentDateTime = LocalDateTime.now(); |
| | | //计算开始时间和结束时间 |
| | | if(StringUtils.isBlank(startTime) || StringUtils.isBlank(endTime)){ |
| | | //初次计算时间 |
| | | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); |
| | | // 计算前1小时时间 |
| | | LocalDateTime hourAgo = currentDateTime.minusHours(1); |
| | | endTime = currentDateTime.format(formatter)+":00"; |
| | | startTime= hourAgo.format(formatter)+":01"; |
| | | }else{ |
| | | startTime = startTime; |
| | | endTime = endTime; |
| | | } |
| | | TaoBaoVo taoBaoVo = cpsConfigService.getCpsConfigObject(BigSellerConfig.CPS_TAOBAO_CONFIG, TaoBaoVo.class); |
| | | DtkApiClient client = DtkApiClient.getInstance(taoBaoVo.getAppKey(),taoBaoVo.getAppSecret()); |
| | | DtkPullGoodsByTimeRequest request = new DtkPullGoodsByTimeRequest(); |
| | | request.setVersion("v1.2.3"); |
| | | if(StringUtils.isNotBlank(pageId)){ |
| | | request.setPageId(pageId); |
| | | }else{ |
| | | request.setPageId("1"); |
| | | } |
| | | request.setPageSize(100); |
| | | DtkApiResponse<DtkPageResponse<DtkGoodsListItemResponse>> execute = client.execute(request); |
| | | //创建实体类 |
| | | List<DtkGoodsListItemResponse> list = execute.getData().getList(); |
| | | List<CpsShop> cpsShopList = new ArrayList<>(); |
| | | for (DtkGoodsListItemResponse shop : list) { |
| | | CpsShop cpsShop = new CpsShop(); |
| | | BeanUtils.copyProperties(shop, cpsShop); |
| | | cpsShop.setShopId(shop.getId()); |
| | | cpsShop.setConnect(shop.getDesc()); |
| | | cpsShopList.add(cpsShop); |
| | | } |
| | | int count = cpsShopService.insertCpsShops(cpsShopList); |
| | | if(count == 100){ |
| | | pushGoodByTime(startTime,endTime,execute.getData().getPageId()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 失效淘宝商品定时处理 5分钟执行一次 |
| | | */ |
| | | @XxlJob("getStateGoodByTime") |
| | | public void getStateGoodByTime(String startTime,String endTime,String pageId) { |
| | | LocalDateTime currentDateTime = LocalDateTime.now(); |
| | | //计算开始时间和结束时间 |
| | | if(StringUtils.isBlank(startTime) || StringUtils.isBlank(endTime)){ |
| | | //初次计算时间 |
| | | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); |
| | | // 计算前20分钟时间 |
| | | LocalDateTime halfHourAgo = currentDateTime.minus(Duration.ofMinutes(5)); |
| | | endTime = currentDateTime.format(formatter)+":00"; |
| | | startTime= halfHourAgo.format(formatter)+":01"; |
| | | }else{ |
| | | startTime = startTime; |
| | | endTime = endTime; |
| | | } |
| | | |
| | | TaoBaoVo taoBaoVo = cpsConfigService.getCpsConfigObject(BigSellerConfig.CPS_TAOBAO_CONFIG, TaoBaoVo.class); |
| | | DtkApiClient client = DtkApiClient.getInstance(taoBaoVo.getAppKey(),taoBaoVo.getAppSecret()); |
| | | DtkStaleGoodsByTimeRequest request = new DtkStaleGoodsByTimeRequest(); |
| | | request.setVersion("v1.0.1"); |
| | | if(StringUtils.isNotBlank(pageId)){ |
| | | request.setPageId(pageId); |
| | | }else{ |
| | | request.setPageId("1"); |
| | | } |
| | | request.setPageSize(100); |
| | | DtkApiResponse<DtkPageResponse<DtkStaleGoodsByTimeResponse>> execute = client.execute(request); |
| | | //创建实体类 |
| | | List<DtkStaleGoodsByTimeResponse> list = execute.getData().getList(); |
| | | for (DtkStaleGoodsByTimeResponse shop : list) { |
| | | cpsShopService.deleteCpsShopAndValues((long)shop.getId()); |
| | | } |
| | | if(list.size() == 100){ |
| | | getStateGoodByTime(startTime,endTime,execute.getData().getPageId()); |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 淘宝商品定时更新 2分钟执行一次 |
| | | */ |
| | | @XxlJob("getNewestGoods") |
| | | public void getNewestGoods(String startTime,String endTime,String pageId) { |
| | | LocalDateTime currentDateTime = LocalDateTime.now(); |
| | | //计算开始时间和结束时间 |
| | | if(StringUtils.isBlank(startTime) || StringUtils.isBlank(endTime)){ |
| | | //初次计算时间 |
| | | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); |
| | | // 计算前20分钟时间 |
| | | LocalDateTime halfHourAgo = currentDateTime.minus(Duration.ofMinutes(2)); |
| | | endTime = currentDateTime.format(formatter)+":00"; |
| | | startTime= halfHourAgo.format(formatter)+":01"; |
| | | }else{ |
| | | startTime = startTime; |
| | | endTime = endTime; |
| | | } |
| | | |
| | | TaoBaoVo taoBaoVo = cpsConfigService.getCpsConfigObject(BigSellerConfig.CPS_TAOBAO_CONFIG, TaoBaoVo.class); |
| | | DtkApiClient client = DtkApiClient.getInstance(taoBaoVo.getAppKey(),taoBaoVo.getAppSecret()); |
| | | DtkNewestGoodsRequest request = new DtkNewestGoodsRequest(); |
| | | request.setVersion("v1.2.0"); |
| | | if(StringUtils.isNotBlank(pageId)){ |
| | | request.setPageId(pageId); |
| | | }else{ |
| | | request.setPageId("1"); |
| | | } |
| | | request.setPageSize(100); |
| | | DtkApiResponse<DtkPageResponse<DtkNewestGoodsResponse>> execute = client.execute(request); |
| | | //创建实体类 |
| | | List<DtkNewestGoodsResponse> list = execute.getData().getList(); |
| | | for (DtkNewestGoodsResponse shop : list) { |
| | | CpsShop cpsShop = cpsShopService.getBaseMapper().selectOne(new LambdaQueryWrapper<CpsShop>().eq(CpsShop::getShopId, shop.getId())); |
| | | BeanUtils.copyProperties(shop, cpsShop); |
| | | cpsShopService.updateById(cpsShop); |
| | | } |
| | | if(list.size() == 100){ |
| | | getNewestGoods(startTime,endTime,execute.getData().getPageId()); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 淘宝订单定时获取 20分钟执行一次 |
| | | */ |
| | | @XxlJob("getOrderDetails") |
| | | public void getOrderDetails(String startTime,String endTime) { |
| | | LocalDateTime currentDateTime = LocalDateTime.now(); |
| | | //计算开始时间和结束时间 |
| | | if(StringUtils.isBlank(startTime) || StringUtils.isBlank(endTime)){ |
| | | //初次计算时间 |
| | | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); |
| | | // 计算前20分钟时间 |
| | | LocalDateTime halfHourAgo = currentDateTime.minus(Duration.ofMinutes(20)); |
| | | endTime = currentDateTime.format(formatter)+":00"; |
| | | startTime= halfHourAgo.format(formatter)+":01"; |
| | | }else{ |
| | | startTime = startTime; |
| | | endTime = endTime; |
| | | } |
| | | TaoBaoVo taoBaoVo = cpsConfigService.getCpsConfigObject(BigSellerConfig.CPS_TAOBAO_CONFIG, TaoBaoVo.class); |
| | | DtkGetOrderDetailsResultsResponse result = DTKUtils.getTBOrderList(startTime,endTime,1,taoBaoVo); |
| | | if(result != null) { |
| | | //插入cps订单表 |
| | | List<DtkGetOrderDetailsResultsItemsResponse> list = result.getPublisherOrderDto(); |
| | | for (DtkGetOrderDetailsResultsItemsResponse item : list){ |
| | | //存在的话 更新订单 不存在 |
| | | CpsOrder order = cpsOrderService.select(item.getTradeParentId()); |
| | | User user =userService.getBaseMapper().selectOne(new LambdaQueryWrapper<User>().eq(User::getSpecialId, item.getSpecialId())); |
| | | if(order != null){ |
| | | BeanUtils.copyProperties(item, order); |
| | | order.setUserId(user.getUserId()); |
| | | cpsOrderService.updateById(order); |
| | | }else{ |
| | | CpsOrder cpsOrder = new CpsOrder(); |
| | | BeanUtils.copyProperties(item, cpsOrder); |
| | | cpsOrder.setUserId(user.getUserId()); |
| | | cpsOrderService.insert(cpsOrder); |
| | | } |
| | | } |
| | | //批量插入订单 |
| | | if(result.getPublisherOrderDto().size() >= 20){ |
| | | getOrderDetails(startTime,endTime); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 京东订单定时获取 20分钟执行一次 |
| | | */ |
| | | @XxlJob("getJdOrderDetails") |
| | | public void getJdOrderDetails(String startTime,String endTime) { |
| | | LocalDateTime currentDateTime = LocalDateTime.now(); |
| | | //计算开始时间和结束时间 |
| | | if(StringUtils.isBlank(startTime) || StringUtils.isBlank(endTime)){ |
| | | //初次计算时间 |
| | | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); |
| | | // 计算前20分钟时间 |
| | | LocalDateTime halfHourAgo = currentDateTime.minus(Duration.ofMinutes(20)); |
| | | endTime = currentDateTime.format(formatter)+":00"; |
| | | startTime= halfHourAgo.format(formatter)+":01"; |
| | | }else{ |
| | | startTime = startTime; |
| | | endTime = endTime; |
| | | } |
| | | JingDongVo jingDongVo = cpsConfigService.getCpsConfigObject(BigSellerConfig.CPS_JINGDONG_CONFIG, JingDongVo.class); |
| | | DtkJdOrderQueryV2Response result = DTKUtils.getJDOrderList(startTime,endTime,1,jingDongVo); |
| | | if(result != null) { |
| | | //插入cps京东订单表 |
| | | List<DtkJdOrderQueryV2Response.OrderRow> list = result.getList(); |
| | | for (DtkJdOrderQueryV2Response.OrderRow item : list){ |
| | | //存在的话 更新订单 不存在 |
| | | CpsJdOrder order = cpsJdOrderService.select(item.getId()); |
| | | User user =userService.getBaseMapper().selectOne(new LambdaQueryWrapper<User>().eq(User::getUserCode, item.getPositionId())); |
| | | if(order != null){ |
| | | BeanUtils.copyProperties(item, order); |
| | | order.setUserId(user.getUserId()); |
| | | cpsJdOrderService.updateById(order); |
| | | }else { |
| | | CpsJdOrder cpsJdOrder = new CpsJdOrder(); |
| | | BeanUtils.copyProperties(item, cpsJdOrder); |
| | | cpsJdOrder.setImageUrl(item.getGoodsInfo().getImageUrl()); |
| | | cpsJdOrder.setShopName(item.getGoodsInfo().getShopName()); |
| | | cpsJdOrder.setUserId(user.getUserId()); |
| | | cpsJdOrderService.insert(cpsJdOrder); |
| | | } |
| | | } |
| | | //批量插入订单 |
| | | if(result.getHasMore() == 1){ |
| | | getJdOrderDetails(startTime,endTime); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 美团订单定时获取 2分钟执行一次 |
| | | */ |
| | | @XxlJob("getMtOrderDetails") |
| | | public void getMtOrderDetails(String startTime,String endTime) { |
| | | long timestamp13Bit = System.currentTimeMillis(); |
| | | //计算开始时间和结束时间 |
| | | if(StringUtils.isBlank(startTime) || StringUtils.isBlank(endTime)){ |
| | | // 计算前20分钟时间 |
| | | endTime = timestamp13Bit / 1000 +""; |
| | | startTime= (timestamp13Bit - 2 * 60 * 1000)/1000 +""; |
| | | }else{ |
| | | startTime = startTime; |
| | | endTime = endTime; |
| | | } |
| | | MtlmVo mtlmVo = cpsConfigService.getCpsConfigObject(BigSellerConfig.CPS_MTLM_CONFIG, MtlmVo.class); |
| | | List<CpsMtActitvity> list = cpsMtActitvityService.getMtActivityList(); |
| | | for (CpsMtActitvity item : list){ |
| | | MtOrderResponse response = MTUtils.getMtOrderList(startTime, endTime, item, mtlmVo); |
| | | List<CpsMtOrder> cpsMtOrders = response.getMtOrderList(); |
| | | for (CpsMtOrder cpsMtOrder:cpsMtOrders){ |
| | | User user = userService.getOne(Wrappers.<User>lambdaQuery().eq(User::getUserCode, cpsMtOrder.getSid())); |
| | | CpsMtOrder order = cpsMtOrderService.getBaseMapper().selectOne(new LambdaQueryWrapper<CpsMtOrder>().eq(CpsMtOrder::getOrderid, cpsMtOrder.getOrderid())); |
| | | if(order == null){ |
| | | BeanUtils.copyProperties(cpsMtOrder, order); |
| | | order.setUserId(user.getUserId()); |
| | | cpsMtOrderService.insert(order); |
| | | }else { |
| | | BeanUtils.copyProperties(cpsMtOrder, order); |
| | | order.setUserId(user.getUserId()); |
| | | cpsMtOrderService.updateById(order); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 拼多多订单定时获取 2分钟执行一次 |
| | | */ |
| | | @XxlJob("getPddOrderDetails") |
| | | public void getPddOrderDetails() throws Exception { |
| | | //计算开始时间和结束时间 |
| | | SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | Date nowdate=new Date(); |
| | | long c=nowdate.getTime()-1000*60*2;//1000*60*1 是1分钟 |
| | | Date olddate=new Date(c); |
| | | String startTime = sdf.format(nowdate); |
| | | String endTime = sdf.format(olddate); |
| | | PddVo pddVo = cpsConfigService.getCpsConfigObject(BigSellerConfig.CPS_PDD_CONFIG, PddVo.class); |
| | | cpsDdOrderService.savePddOrderList(startTime,endTime,1,pddVo); |
| | | } |
| | | |
| | | /** |
| | | * 聚推客订单定时获取 2分钟执行一次 |
| | | */ |
| | | @XxlJob("getJtkOrderDetails") |
| | | public void getJtkOrderDetails(Date startTime,Date endTime,int page) throws Exception { |
| | | if(page < 1){ |
| | | page = 1; |
| | | } |
| | | //计算开始时间和结束时间 |
| | | if(startTime == null || endTime == null){ |
| | | endTime=new Date(); |
| | | long c=endTime.getTime()-1000*60*2;//1000*60*1 是1分钟 |
| | | startTime=new Date(c); |
| | | }else{ |
| | | startTime = startTime; |
| | | endTime = endTime; |
| | | } |
| | | JtkVo jtkVo = cpsConfigService.getCpsConfigObject(BigSellerConfig.CPS_JTK_CONFIG, JtkVo.class); |
| | | int total =cpsJtkOrderService.saveJtkOrderList(startTime,endTime,page,jtkVo); |
| | | if(total == 100){ |
| | | page++; |
| | | getJtkOrderDetails(startTime,endTime,page); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.task; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.github.binarywang.wxpay.bean.entpay.EntPayQueryResult; |
| | | import com.github.binarywang.wxpay.exception.WxPayException; |
| | | import com.xxl.job.core.handler.annotation.XxlJob; |
| | | import com.yami.shop.bean.model.EnterprisePay; |
| | | import com.yami.shop.config.WxConfig; |
| | | import com.yami.shop.service.EnterprisePayService; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.List; |
| | | |
| | | |
| | | /** |
| | | * 微信要关掉这个接口,所以这个接口要废弃了 |
| | | * @author yami |
| | | */ |
| | | @Slf4j |
| | | @Component("enterprisePay") |
| | | @AllArgsConstructor |
| | | @Deprecated |
| | | public class EnterprisePayTask { |
| | | |
| | | private final EnterprisePayService enterprisePayService; |
| | | |
| | | private final WxConfig wxConfig; |
| | | /** |
| | | * 企业支付 |
| | | */ |
| | | @XxlJob("sendEnterprisePay") |
| | | public void sendEnterprisePay() { |
| | | log.info("开始执行发送企业付款任务》》》》》》》》》》》》》》》》》》》》》"); |
| | | |
| | | List<EnterprisePay> enterprisePayList = enterprisePayService.listApplyEnterprisePay(); |
| | | enterprisePayService.sendEnterprisePay(enterprisePayList); |
| | | |
| | | log.info("结束执行发送企业付款任务》》》》》》》》》》》》》》》》》》》》》"); |
| | | } |
| | | |
| | | /** |
| | | * 查询支付情况 |
| | | */ |
| | | @XxlJob("queryAndUpdateEntPay") |
| | | public void queryAndUpdateEntPay() { |
| | | log.info("开始查询企业付款任务》》》》》》》》》》》》》》》》》》》》》》》"); |
| | | |
| | | List<EnterprisePay> enterprisePayList = enterprisePayService.listApplyEnterprisePay(); |
| | | if (CollectionUtils.isNotEmpty(enterprisePayList)) { |
| | | for (EnterprisePay enterprisePay : enterprisePayList) { |
| | | try { |
| | | EntPayQueryResult entPayQueryResult = wxConfig.getEntPayService().queryEntPay(String.valueOf(enterprisePay.getEntPayOrderNo())); |
| | | // PROCESSING:处理中 |
| | | if (StrUtil.equalsIgnoreCase(entPayQueryResult.getStatus(), "PROCESSING")) { |
| | | } |
| | | // SUCCESS: 转账成功 |
| | | if (StrUtil.equalsIgnoreCase(entPayQueryResult.getStatus(), "SUCCESS")) { |
| | | enterprisePayService.paySuccess(enterprisePay); |
| | | } |
| | | // FAILED: 转账失败 |
| | | if (StrUtil.equalsIgnoreCase(entPayQueryResult.getStatus(), "FAILED")) { |
| | | enterprisePayService.payFailed(enterprisePay); |
| | | log.error(entPayQueryResult.getReason()); |
| | | } |
| | | |
| | | } catch (WxPayException e) { |
| | | log.error("WxPayException:", e); |
| | | } |
| | | } |
| | | } |
| | | log.info("结束查询企业付款任务》》》》》》》》》》》》》》》》》》》》》》》"); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.task; |
| | | |
| | | import com.xxl.job.core.handler.annotation.XxlJob; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.util.RedisUtil; |
| | | import com.yami.shop.service.FlowLogService; |
| | | import com.yami.shop.service.FlowService; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | |
| | | /** |
| | | * @author yami |
| | | */ |
| | | @Component |
| | | public class FlowAnalysisTask { |
| | | |
| | | |
| | | @Autowired |
| | | private FlowLogService flowLogService; |
| | | @Autowired |
| | | private FlowService flowService; |
| | | |
| | | |
| | | /** |
| | | * 根据设置的时间,将缓存中的记录插入到数据库 |
| | | */ |
| | | @XxlJob("insertFlowAnalysisLog") |
| | | public void insertFlowAnalysisLog(){ |
| | | if (RedisUtil.hasKey(Constant.FLOW_ANALYSIS_LOG)){ |
| | | flowLogService.insertBatch(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 统计记录数据,储存到对应的数据表中 |
| | | */ |
| | | @XxlJob("statisticalFlowData") |
| | | public void statisticalFlowData(){ |
| | | //更新数据再统计 |
| | | insertFlowAnalysisLog(); |
| | | flowService.statisticalData(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.platform.task; |
| | | |
| | | import cn.hutool.core.date.DateUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.xxl.job.core.handler.annotation.XxlJob; |
| | | import com.yami.shop.bean.model.CdnFlow; |
| | | import com.yami.shop.bean.model.CdnUserWallet; |
| | | import com.yami.shop.bean.model.MarsAdverIncome; |
| | | import com.yami.shop.common.constants.DictConstant; |
| | | import com.yami.shop.service.CdnFlowService; |
| | | import com.yami.shop.service.CdnUserWalletService; |
| | | import com.yami.shop.service.MarsAdverIncomeService; |
| | | import com.yami.shop.task.common.model.TaskProvideUser; |
| | | import com.yami.shop.task.common.service.TaskProvideUserService; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | @Component |
| | | public class FossickTask { |
| | | |
| | | private final Logger logger = LoggerFactory.getLogger(this.getClass()); |
| | | |
| | | @Autowired |
| | | private TaskProvideUserService taskProvideUserService; |
| | | |
| | | @Autowired |
| | | private CdnFlowService cdnFlowService; |
| | | |
| | | @Autowired |
| | | private CdnUserWalletService cdnUserWalletService; |
| | | |
| | | @Autowired |
| | | private MarsAdverIncomeService marsAdverIncomeService; |
| | | |
| | | /** |
| | | * AI+自主掘金分润 |
| | | */ |
| | | @XxlJob("fossickCancel") |
| | | public void fossickCancel() { |
| | | try { |
| | | logger.info("AI+自主掘金分润计算开始。。。" + DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")); |
| | | List<TaskProvideUser> list = taskProvideUserService.list(new LambdaQueryWrapper<TaskProvideUser>().eq(TaskProvideUser::getStatus, 3)); |
| | | for (TaskProvideUser taskProvideUser : list) { |
| | | if(ObjectUtil.isNotEmpty(taskProvideUser.getReleases())){ |
| | | if(taskProvideUser.getReleases().compareTo(BigDecimal.ZERO) > 0){ |
| | | setFlowLog(taskProvideUser.getUserId(),taskProvideUser.getUserId(),taskProvideUser.getReleases(), DictConstant.WALLET_ID_10,"AI+自主掘金分润",DictConstant.FLOWNAME_ID_50); |
| | | taskProvideUser.setStatus(4); |
| | | taskProvideUserService.updateById(taskProvideUser); |
| | | MarsAdverIncome marsAdverIncome = MarsAdverIncome.builder() |
| | | .userId(taskProvideUser.getUserId()) |
| | | .money(taskProvideUser.getReleases()) |
| | | .date(new Date()) |
| | | .build(); |
| | | marsAdverIncomeService.save(marsAdverIncome); |
| | | } |
| | | } |
| | | } |
| | | |
| | | logger.info("AI+自主掘金分润计算结束。。。" + DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")); |
| | | }catch (Exception e) { |
| | | logger.error("AI+自主掘金分润计算失败", e); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * |
| | | * @param userId 受益人 |
| | | * @param userIds 贡献人 |
| | | * @param money 收益金额 |
| | | * @param walletId 钱包类型 |
| | | * @param desc 收益描述 |
| | | * @param flownameId 流水类型 |
| | | */ |
| | | private void setFlowLog(String userId, String userIds, BigDecimal money, Integer walletId, String desc, Integer flownameId){ |
| | | CdnFlow cdnFlow = new CdnFlow(); |
| | | cdnFlow.setUserIds(userIds); |
| | | cdnFlow.setUserId(userId); |
| | | cdnFlow.setFlownameId(flownameId); |
| | | cdnFlow.setWalletId(walletId); |
| | | //钱包更改 |
| | | CdnUserWallet cdnUserWallet = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId,userId) |
| | | .eq(CdnUserWallet::getWalletId,walletId)); |
| | | if(cdnUserWallet.getMoney().compareTo(BigDecimal.ZERO) == 0){ |
| | | return; |
| | | } |
| | | if(money.compareTo(BigDecimal.ZERO) <= 0){//幸运池已经释放完毕 |
| | | return; |
| | | }else{ |
| | | if(money.compareTo(cdnUserWallet.getMoney()) >= 0){ |
| | | cdnFlow.setMoney(cdnUserWallet.getMoney().negate()); |
| | | }else{ |
| | | cdnFlow.setMoney(money.negate()); |
| | | } |
| | | } |
| | | cdnFlow.setMemo(desc+":释放用户"+userIds); |
| | | cdnFlow.setCreateTime(new Date()); |
| | | cdnFlow.setDate(new Date()); |
| | | cdnFlow.setOldmoney(cdnUserWallet.getMoney()); |
| | | cdnFlowService.save(cdnFlow); |
| | | cdnUserWallet.setUserId(userId); |
| | | cdnUserWallet.setWalletId(walletId); |
| | | cdnUserWallet.setMoney(cdnUserWallet.getMoney().add(cdnFlow.getMoney())); |
| | | cdnUserWallet.setUpdateTime(new Date()); |
| | | cdnUserWallet.setReleaseCount(cdnUserWallet.getReleaseCount().add(cdnFlow.getMoney())); |
| | | cdnUserWalletService.updateById(cdnUserWallet); |
| | | //释放完进入流量 |
| | | CdnFlow cdnFlows = new CdnFlow(); |
| | | BeanUtils.copyProperties(cdnFlow, cdnFlows); |
| | | cdnFlows.setMoney(cdnFlow.getMoney().negate()); |
| | | cdnFlows.setWalletId(DictConstant.WALLET_ID_8); |
| | | cdnFlows.setFlownameId(flownameId); |
| | | CdnUserWallet cdnUserWallets = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId,userId) |
| | | .eq(CdnUserWallet::getWalletId,DictConstant.WALLET_ID_8)); |
| | | if(null == cdnUserWallets){ |
| | | return; |
| | | } |
| | | cdnFlows.setOldmoney(cdnUserWallets.getMoney() == null?BigDecimal.ZERO:cdnUserWallets.getMoney()); |
| | | cdnFlows.setMemo(desc+"-->流量:相关用户"+userIds); |
| | | cdnFlowService.save(cdnFlows); |
| | | //钱包更改 |
| | | cdnUserWallets.setUserId(userId); |
| | | cdnUserWallets.setWalletId(DictConstant.WALLET_ID_8); |
| | | cdnUserWallets.setMoney(cdnUserWallets.getMoney()== null?cdnFlow.getMoney().negate():cdnUserWallets.getMoney().add(cdnFlow.getMoney().negate())); |
| | | cdnUserWallets.setUpdateTime(new Date()); |
| | | cdnUserWalletService.updateById(cdnUserWallets); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.task; |
| | | |
| | | import cn.hutool.core.collection.CollectionUtil; |
| | | import com.xxl.job.core.handler.annotation.XxlJob; |
| | | import com.yami.shop.bean.model.NotifyLog; |
| | | import com.yami.shop.service.NotifyLogService; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.List; |
| | | |
| | | |
| | | /** |
| | | * @author yami |
| | | */ |
| | | @Component |
| | | public class NotifyTask { |
| | | |
| | | |
| | | private Logger logger = LoggerFactory.getLogger(getClass()); |
| | | |
| | | @Autowired |
| | | private NotifyLogService notifyLogService; |
| | | |
| | | |
| | | @XxlJob("sendMessage") |
| | | public void sendMessage(){ |
| | | logger.info("获取还未进行消息推送的通知。。。"); |
| | | // 获取还未进行消息推送的通知 |
| | | List<NotifyLog> logList = notifyLogService.listUnSendMsgList(); |
| | | if (CollectionUtil.isEmpty(logList)) { |
| | | return; |
| | | } |
| | | // 修改成已发送 |
| | | logList.forEach(notifyLog -> notifyLog.setStatus(1)); |
| | | notifyLogService.updateBatchById(logList); |
| | | // 推送消息 |
| | | notifyLogService.sendMessage(logList); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.task; |
| | | |
| | | import cn.hutool.core.date.DateUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.xxl.job.core.handler.annotation.XxlJob; |
| | | import com.yami.shop.bean.dto.OrderRefundDto; |
| | | import com.yami.shop.bean.enums.ReturnMoneyStsType; |
| | | import com.yami.shop.bean.enums.SendType; |
| | | import com.yami.shop.bean.model.OrderRefund; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.service.NotifyTemplateService; |
| | | import com.yami.shop.service.OrderRefundService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import ma.glasnost.orika.MapperFacade; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.function.Function; |
| | | import java.util.function.Predicate; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * @author yami |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | public class OrderRefundTask { |
| | | |
| | | @Autowired |
| | | private OrderRefundService orderRefundService; |
| | | @Autowired |
| | | private NotifyTemplateService notifyTemplateService; |
| | | @Autowired |
| | | private MapperFacade mapperFacade; |
| | | |
| | | |
| | | |
| | | /** |
| | | * 取消申请超时的订单,无论该超时订单处于任何状态 |
| | | */ |
| | | @XxlJob("cancelWhenTimeOut") |
| | | public void cancelWhenTimeOut() { |
| | | log.info("==============订单退款超时处理开始==================="); |
| | | // 设定时间值 |
| | | Date date = DateUtil.offsetDay(new Date(), -Constant.MAX_REFUND_APPLY_TIME); |
| | | // 获取待处理的退款订单 |
| | | List<OrderRefund> orderRefundList = orderRefundService.list(new LambdaQueryWrapper<OrderRefund>() |
| | | .in(OrderRefund::getReturnMoneySts, Arrays.asList(ReturnMoneyStsType.APPLY.value(),ReturnMoneyStsType.PROCESSING.value(),ReturnMoneyStsType.CONSIGNMENT.value(),ReturnMoneyStsType.RECEIVE.value())) |
| | | .lt(OrderRefund::getApplyTime, date)); |
| | | if (CollectionUtils.isNotEmpty(orderRefundList)) { |
| | | orderRefundService.cancelWhenTimeOut(orderRefundList); |
| | | } |
| | | log.info("==============订单退款超时处理结束==================="); |
| | | } |
| | | |
| | | /** |
| | | * 退款临近超时提醒,每12小时执行发送一次的提醒 |
| | | */ |
| | | @XxlJob("pressRefundOrder") |
| | | public void pressRefundOrder(){ |
| | | log.info("==============订单退款超时提醒开始==================="); |
| | | // 临时超时时间为 最大申请时间 - 12小时 |
| | | Integer overTime = Constant.MAX_REFUND_APPLY_TIME * 24; |
| | | Date date = DateUtil.offsetHour(new Date(), Constant.MAX_REFUND_HOUR - overTime); |
| | | Date overDate = DateUtil.offsetDay(new Date(), -Constant.MAX_REFUND_APPLY_TIME); |
| | | // 获取临近超时的退款订单,大于超时时间,小于临时时间 |
| | | List<OrderRefund> orderRefundList = orderRefundService.list(new LambdaQueryWrapper<OrderRefund>() |
| | | .in(OrderRefund::getReturnMoneySts, Arrays.asList(ReturnMoneyStsType.APPLY.value(),ReturnMoneyStsType.PROCESSING.value(),ReturnMoneyStsType.CONSIGNMENT.value(),ReturnMoneyStsType.RECEIVE.value())) |
| | | .gt(OrderRefund::getApplyTime,overDate) |
| | | .lt(OrderRefund::getApplyTime, date)); |
| | | if (CollectionUtils.isNotEmpty(orderRefundList)) { |
| | | List<OrderRefundDto> orderRefundDtos = mapperFacade.mapAsList(orderRefundList, OrderRefundDto.class); |
| | | orderRefundDtos = orderRefundDtos.stream().filter(distinctByKey(OrderRefundDto::getUserId)).collect(Collectors.toList()); |
| | | for (OrderRefundDto orderRefundDto : orderRefundDtos) { |
| | | notifyTemplateService.sendNotifyByRefund(orderRefundDto,SendType.REFUND_OUT_TIME); |
| | | } |
| | | } |
| | | log.info("==============退款临近超时提醒结束==================="); |
| | | } |
| | | |
| | | private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) { |
| | | Set<Object> seen = ConcurrentHashMap.newKeySet(); |
| | | return t -> seen.add(keyExtractor.apply(t)); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.task; |
| | | |
| | | import cn.hutool.core.collection.CollectionUtil; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.xxl.job.core.handler.annotation.XxlJob; |
| | | import com.yami.shop.bean.bo.PayInfoResultBO; |
| | | import com.yami.shop.bean.enums.OrderStatus; |
| | | import com.yami.shop.bean.enums.PayStatus; |
| | | import com.yami.shop.bean.enums.SendType; |
| | | import com.yami.shop.bean.model.Order; |
| | | import com.yami.shop.bean.model.OrderItem; |
| | | import com.yami.shop.bean.model.OrderSettlement; |
| | | import com.yami.shop.bean.model.PayInfo; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.enums.PayType; |
| | | import com.yami.shop.manager.impl.PayManager; |
| | | import com.yami.shop.service.*; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.*; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.function.Function; |
| | | import java.util.function.Predicate; |
| | | import java.util.stream.Collectors; |
| | | |
| | | |
| | | /** |
| | | * @author yami |
| | | */ |
| | | @Component |
| | | public class OrderTask { |
| | | |
| | | |
| | | private final Logger logger = LoggerFactory.getLogger(this.getClass()); |
| | | |
| | | @Autowired |
| | | private OrderService orderService; |
| | | @Autowired |
| | | private NotifyTemplateService notifyTemplateService; |
| | | @Autowired |
| | | private ProductService productService; |
| | | @Autowired |
| | | private SkuService skuService; |
| | | @Autowired |
| | | private PayInfoService payInfoService; |
| | | @Autowired |
| | | private OrderSettlementService orderSettlementService; |
| | | @Autowired |
| | | private PayManager payManager; |
| | | @Autowired |
| | | private NotifyLogService notifyLogService; |
| | | |
| | | @XxlJob("cancelOrder") |
| | | public void cancelOrder() { |
| | | Date now = new Date(); |
| | | logger.info("取消超时未支付订单。。。"); |
| | | // 获取30分钟之前未支付的订单 |
| | | List<Order> orders = orderService.listUnRefundOrderAndOrderItems(OrderStatus.UNPAY.value(), DateUtil.offsetMinute(now, -30)); |
| | | if (CollectionUtil.isEmpty(orders)) { |
| | | return; |
| | | } |
| | | |
| | | List<Order> cancelOrderList = this.checkOrders(orders); |
| | | orderService.cancelOrders(cancelOrderList); |
| | | // 移除缓存 |
| | | this.removeCache(cancelOrderList); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 确认收货15天后执行订单结算 |
| | | */ |
| | | @XxlJob("orderCommissionSettlement") |
| | | public void orderCommissionSettlement() { |
| | | logger.info("开始执行订单结算任务》》》》》》》》》》》》》》》》》》》》》"); |
| | | Date now = new Date(); |
| | | // 确认收货15天的订单,进行结算(更新时间为15天前的订单) |
| | | List<Order> orders = orderService.listPendingSettlementOrders(OrderStatus.SUCCESS.value(), DateUtil.beginOfDay(DateUtil.offsetDay(now, -Constant.DISTRIBUTION_SETTLEMENT_TIME))); |
| | | if (CollectionUtil.isEmpty(orders)) { |
| | | return; |
| | | } |
| | | orderService.orderCommissionSettlement(orders); |
| | | // 移除缓存 |
| | | this.removeCache(orders); |
| | | logger.info("结束执行订单结算任务》》》》》》》》》》》》》》》》》》》》》"); |
| | | } |
| | | |
| | | /** |
| | | * 订单催付提醒,每1分钟执行发送一次订单未支付的提醒 |
| | | */ |
| | | @XxlJob("pressPayOrder") |
| | | public void pressPayOrder() { |
| | | Date now = new Date(); |
| | | logger.info("执行订单催付提醒"); |
| | | // 获取15分钟之前未支付的订单 |
| | | List<Order> orders = orderService.listUnRefundOrderAndOrderItems(OrderStatus.UNPAY.value(), DateUtil.offsetMinute(now, -15)); |
| | | if (CollectionUtil.isEmpty(orders)) { |
| | | return; |
| | | } |
| | | // 消息推送-订单催付提醒 |
| | | // 对相同用户id进行去重 |
| | | orders = orders.stream().filter(distinctByKey(Order::getUserId)).collect(Collectors.toList()); |
| | | for (Order order : orders) { |
| | | Integer num = notifyLogService.countMsgNum(order.getOrderNumber()); |
| | | if (num < 1) { |
| | | //没发过催付消息才会发送 |
| | | notifyTemplateService.sendNotifyOfDelivery(order, null, SendType.PRESS_PAY); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) { |
| | | Set<Object> seen = ConcurrentHashMap.newKeySet(); |
| | | return t -> seen.add(keyExtractor.apply(t)); |
| | | } |
| | | |
| | | /** |
| | | * 确认收货 |
| | | */ |
| | | @XxlJob("confirmOrder") |
| | | public void confirmOrder() { |
| | | Date now = new Date(); |
| | | logger.info("系统自动确认收货订单。。。"); |
| | | // 获取15天之前等待确认收货的订单 |
| | | List<Order> orders = orderService.listUnRefundOrderAndOrderItems(OrderStatus.CONSIGNMENT.value(), DateUtil.offsetDay(now, -15)); |
| | | if (CollectionUtil.isEmpty(orders)) { |
| | | return; |
| | | } |
| | | orderService.receiptOrder(orders); |
| | | // 移除缓存 |
| | | this.removeCache(orders); |
| | | } |
| | | |
| | | /** |
| | | * 查询订单,去除已支付的订单 |
| | | * |
| | | * @param orders |
| | | */ |
| | | private List<Order> checkOrders(List<Order> orders) { |
| | | List<String> orderNumbers = orders.stream().map(Order::getOrderNumber).collect(Collectors.toList()); |
| | | // 收集未支付的订单 |
| | | List<Order> orderList = new ArrayList<>(); |
| | | //获取订单对应的订单结算数据 |
| | | List<OrderSettlement> orderSettlementList = orderSettlementService.list(new LambdaQueryWrapper<OrderSettlement>() |
| | | .in(OrderSettlement::getOrderNumber, orderNumbers)); |
| | | Map<String, OrderSettlement> orderSettlementMap = orderSettlementList.stream() |
| | | .collect(Collectors.toMap(OrderSettlement::getOrderNumber, orderSettlement -> orderSettlement)); |
| | | for (Order order : orders) { |
| | | OrderSettlement orderSettlement = orderSettlementMap.get(order.getOrderNumber()); |
| | | if (Objects.isNull(orderSettlement) || Objects.isNull(orderSettlement.getPayType()) || Objects.isNull(orderSettlement.getPayNo())) { |
| | | orderList.add(order); |
| | | continue; |
| | | } |
| | | String bizPayNo = null; |
| | | if (Objects.nonNull(orderSettlement.getPayNo())) { |
| | | PayInfo payInfo = payInfoService.getOne(Wrappers.lambdaQuery(PayInfo.class).eq(PayInfo::getPayNo, orderSettlement.getPayNo())); |
| | | bizPayNo = payInfo.getBizPayNo(); |
| | | } |
| | | PayInfoResultBO payInfoResultBO = payManager.getPayInfo(PayType.instance(orderSettlement.getPayType()), orderSettlement.getPayNo(), bizPayNo); |
| | | if (!payInfoResultBO.getIsPaySuccess()) { |
| | | // 根据内部订单号更新order settlement |
| | | PayInfo payInfo = payInfoService.getOne(new LambdaQueryWrapper<PayInfo>().eq(PayInfo::getPayNo, orderSettlement.getPayNo())); |
| | | if (Objects.equals(payInfo.getPayStatus(), PayStatus.UNPAY.value())) { |
| | | payInfoService.noticeOrder(payInfoResultBO, payInfo); |
| | | } |
| | | } else { |
| | | orderList.add(order); |
| | | } |
| | | } |
| | | return orderList; |
| | | } |
| | | |
| | | /** |
| | | * 移除缓存 |
| | | */ |
| | | private void removeCache(List<Order> orders) { |
| | | for (Order order : orders) { |
| | | List<OrderItem> orderItems = order.getOrderItems(); |
| | | for (OrderItem orderItem : orderItems) { |
| | | productService.removeProdCacheByProdId(orderItem.getProdId()); |
| | | skuService.removeSkuCacheBySkuId(orderItem.getSkuId(), orderItem.getProdId()); |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.task; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import com.xxl.job.core.handler.annotation.XxlJob; |
| | | import com.yami.shop.bean.bo.ProductBO; |
| | | import com.yami.shop.bean.enums.EsOperationType; |
| | | import com.yami.shop.bean.event.EsProductUpdateEvent; |
| | | import com.yami.shop.bean.model.Product; |
| | | import com.yami.shop.bean.param.EsProductParam; |
| | | import com.yami.shop.bean.vo.search.ProductSearchVO; |
| | | import com.yami.shop.dao.OrderMapper; |
| | | import com.yami.shop.search.common.service.SearchProductService; |
| | | import com.yami.shop.service.ProductService; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.context.ApplicationContext; |
| | | import org.springframework.context.ApplicationEventPublisher; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | |
| | | /** |
| | | * @author yami |
| | | */ |
| | | @Component |
| | | public class ProdTask { |
| | | private Logger logger = LoggerFactory.getLogger(getClass()); |
| | | @Autowired |
| | | private OrderMapper orderMapper; |
| | | @Autowired |
| | | private ProductService productService; |
| | | @Autowired |
| | | private ApplicationContext applicationContext; |
| | | @Autowired |
| | | private SearchProductService searchProductService; |
| | | @Autowired |
| | | private ApplicationEventPublisher eventPublisher;; |
| | | |
| | | |
| | | @XxlJob("recoveryPreSaleProd") |
| | | public void recoveryPreSaleProd(){ |
| | | logger.info("过了预售时间的商品,恢复成普通商品状态。。。"); |
| | | // 获取30分钟之前未支付的订单 |
| | | List<Product> products = productService.recoveryPreSaleProd(); |
| | | if(CollectionUtils.isEmpty(products)){ |
| | | return; |
| | | } |
| | | for (Product product : products) { |
| | | //清除缓存 |
| | | productService.removeProdCacheByProdId(product.getProdId()); |
| | | } |
| | | } |
| | | |
| | | @XxlJob("offlineExpireVirtualProd") |
| | | public void offlineExpireVirtualProd(){ |
| | | logger.info("过了核销时间的虚拟商品,进行下架操作。"); |
| | | // 获取30分钟之前未支付的订单 |
| | | List<Product> products = productService.handleExpireVirtualProd(); |
| | | if(CollectionUtils.isEmpty(products)){ |
| | | return; |
| | | } |
| | | List<Long> ids = new ArrayList<>(); |
| | | for (Product product : products) { |
| | | //清除缓存 |
| | | productService.removeProdCacheByProdId(product.getProdId()); |
| | | ids.add(product.getProdId()); |
| | | } |
| | | applicationContext.publishEvent(new EsProductUpdateEvent(null, ids, EsOperationType.UPDATE_BATCH)); |
| | | } |
| | | |
| | | /** |
| | | * 校验商品数量是否完整 |
| | | * 商品数据是否为最新的:根据商品更新时间判断 |
| | | */ |
| | | @XxlJob("verifyProdStockAndSold") |
| | | public void verifySpuStockAndSold(){ |
| | | // 获取6分钟内提交订单中的商品列表 |
| | | List<Long> prodIds = orderMapper.listProdIdByTime(DateUtil.offsetDay(new Date(), -6)); |
| | | if (CollUtil.isEmpty(prodIds)) { |
| | | return; |
| | | } |
| | | |
| | | // 从es中查询商品的库存和销量数据 |
| | | EsProductParam productParam = new EsProductParam(); |
| | | productParam.setProdIds(prodIds); |
| | | productParam.setFetchSource(new String[]{"prodId", "totalStocks", "soldNum", "actualSoldNum"}); |
| | | List<ProductSearchVO> esProdList = searchProductService.listSpuByProdIds(productParam); |
| | | Map<Long, ProductSearchVO> prodMap = esProdList.stream().collect(Collectors.toMap(ProductSearchVO::getProdId, p -> p)); |
| | | |
| | | |
| | | // 从mysql中查询商品的库存和销量数据 |
| | | List<ProductBO> prodList = productService.listProdStockAndSold(prodIds); |
| | | List<Long> updateList = new ArrayList<>(); |
| | | //比较es和mysql的商品数据 |
| | | for (ProductBO productBO : prodList) { |
| | | ProductSearchVO productSearchVO = prodMap.get(productBO.getProdId()); |
| | | if (Objects.isNull(productSearchVO)) { |
| | | continue; |
| | | } |
| | | boolean change = !Objects.equals(productBO.getTotalStocks(), productSearchVO.getTotalStocks()) || |
| | | !Objects.equals(productBO.getActualSoldNum() + productBO.getWaterSoldNum(), productSearchVO.getSoldNum()) || |
| | | !Objects.equals(productBO.getActualSoldNum(), productSearchVO.getActualSoldNum()); |
| | | if (change) { |
| | | updateList.add(productBO.getProdId()); |
| | | } |
| | | } |
| | | // 数据不一致的商品,更新es中的数据 |
| | | if (CollUtil.isNotEmpty(updateList)) { |
| | | eventPublisher.publishEvent(new EsProductUpdateEvent(null, updateList, EsOperationType.UPDATE_SOLD_NUM_BATCH)); |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.platform.task; |
| | | |
| | | import com.xxl.job.core.handler.annotation.XxlJob; |
| | | import com.yami.shop.service.ShopDetailService; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * @Author lth |
| | | * @Date 2021/8/9 14:45 |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | @AllArgsConstructor |
| | | public class ShopTask { |
| | | |
| | | private final ShopDetailService shopDetailService; |
| | | |
| | | /** |
| | | * 根据签约时间改变店铺状态 |
| | | */ |
| | | @XxlJob("changeShopStatusByContractTime") |
| | | public void changeShopStatusByContractTime() { |
| | | log.info("根据签约时间改变店铺状态"); |
| | | Date now = new Date(); |
| | | shopDetailService.changeShopStatusByContractTime(now); |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.platform.task; |
| | | |
| | | import cn.hutool.core.date.DateUtil; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.xxl.job.core.handler.annotation.XxlJob; |
| | | import com.yami.shop.bean.model.CdnUserWallet; |
| | | import com.yami.shop.bean.model.User; |
| | | import com.yami.shop.common.enums.WalletEnum; |
| | | import com.yami.shop.service.CdnUserWalletService; |
| | | import com.yami.shop.service.UserService; |
| | | import com.yami.shop.task.common.model.TaskProvideRecord; |
| | | import com.yami.shop.task.common.model.TaskProvideUser; |
| | | import com.yami.shop.task.common.service.TaskProvideRecordService; |
| | | import com.yami.shop.task.common.service.TaskProvideUserService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.scheduling.annotation.Scheduled; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Random; |
| | | |
| | | @Slf4j |
| | | @Component |
| | | public class TaskReleaseTask { |
| | | private final Logger logger = LoggerFactory.getLogger(this.getClass()); |
| | | |
| | | @Autowired |
| | | private TaskProvideRecordService taskProvideRecordService; |
| | | @Autowired |
| | | private TaskProvideUserService taskProvideUserService; |
| | | @Autowired |
| | | private UserService userService; |
| | | @Autowired |
| | | private CdnUserWalletService cdnUserWalletService; |
| | | |
| | | |
| | | @XxlJob("cancelTaskRelease") |
| | | public void cancelRelease() { |
| | | Date now = new Date(); |
| | | logger.info("任务状态修改开始。。。" + DateUtil.format(now, "yyyy-MM-dd HH:mm:ss")); |
| | | // 查询已激活的任务释放 |
| | | List<TaskProvideUser> taskProvideUserList = taskProvideUserService.list(Wrappers.lambdaQuery(TaskProvideUser.class).gt(TaskProvideUser::getStatus, 0).lt(TaskProvideUser::getStatus, 4)); |
| | | |
| | | |
| | | for (TaskProvideUser taskProvideUser : taskProvideUserList) { |
| | | switch (taskProvideUser.getStatus()) { |
| | | case 1: |
| | | taskProvideUser.setStatus(2); |
| | | |
| | | Random random = new Random(); |
| | | // 生成0到1之间的随机小数 |
| | | double randomFloat = random.nextDouble(); |
| | | // 将随机小数映射到1到20之间 |
| | | double randomFloat1To20 = randomFloat * 19 + 1; |
| | | System.out.println(randomFloat1To20); |
| | | // 以50%的概率添加负号 |
| | | if (random.nextBoolean()) { |
| | | randomFloat1To20 = -randomFloat1To20; |
| | | } |
| | | // 使用String.format()保留两位小数 |
| | | String formattedString = String.format("%.2f", randomFloat1To20); |
| | | // 如果你确实需要double类型,但注意这会丢失不必要的零 |
| | | double formattedDouble = Double.parseDouble(formattedString); |
| | | taskProvideUser.setProcess(50 + formattedDouble); |
| | | taskProvideUserService.updateById(taskProvideUser); |
| | | break; |
| | | case 2: |
| | | taskProvideUser.setStatus(3); |
| | | taskProvideUser.setProcess(100.00); |
| | | taskProvideUserService.updateById(taskProvideUser); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | @XxlJob("cancelTaskUserGeneral") |
| | | public void cancelGeneral() { |
| | | Date now = new Date(); |
| | | logger.info("任务提供释放初始化开始。。。" + DateUtil.format(now, "yyyy-MM-dd HH:mm:ss")); |
| | | // 查询任务提供释放记录。开始和结束时间在当前时间段内 |
| | | String formattedDate = DateUtil.format(now, "yyyy-MM-dd"); |
| | | List<TaskProvideRecord> taskProvideRecordList = taskProvideRecordService.list(Wrappers.lambdaQuery(TaskProvideRecord.class) |
| | | .le(TaskProvideRecord::getStartTime,formattedDate) |
| | | .ge(TaskProvideRecord::getEndTime, formattedDate)); |
| | | // 遍历任务提供记录 |
| | | for (TaskProvideRecord taskProvideRecord : taskProvideRecordList) { |
| | | |
| | | // 查询所有激活任务大厅的用户 |
| | | List<User> users = userService.list(Wrappers.lambdaQuery(User.class).eq(User::getActiveStatus, 1)); |
| | | // 遍历初始化用户 |
| | | for (User user : users) { |
| | | |
| | | // 查询用户的金牛豆释放总额 |
| | | CdnUserWallet cdnUserWallet = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class).eq(CdnUserWallet::getUserId, user.getUserId()).eq(CdnUserWallet::getWalletId, WalletEnum.LUCKPOOL.value())); |
| | | BigDecimal releaseCount = cdnUserWallet.getReleaseCount() != null ? cdnUserWallet.getReleaseCount() : BigDecimal.ZERO; |
| | | if (releaseCount.compareTo(BigDecimal.ZERO) > 0) { |
| | | // 创建任务提供用户 |
| | | TaskProvideUser taskProvideUser = new TaskProvideUser(); |
| | | taskProvideUser.setUserId(user.getUserId()); |
| | | taskProvideUser.setProvideRecordId(taskProvideRecord.getProvideRecordId()); |
| | | taskProvideUser.setDateTime(formattedDate + ""); |
| | | taskProvideUser.setCreateTime(new Date()); |
| | | taskProvideUser.setTaskId(taskProvideRecord.getTaskId()); |
| | | taskProvideUser.setStatus(0); |
| | | taskProvideUser.setProcess(0.00); |
| | | taskProvideUser.setStartTime(new Date()); |
| | | taskProvideUser.setReleaseCount(cdnUserWallet.getReleaseCount()); |
| | | |
| | | // 根据释放百分比算出本次释放的幸运池数量 |
| | | BigDecimal release = cdnUserWallet.getReleaseCount().multiply(taskProvideRecord.getReleaseRate()); |
| | | Random random = new Random(); |
| | | // 生成0到1之间的随机小数(不包括1) |
| | | double randomFloat = random.nextDouble(); |
| | | // 以50%的概率添加负号 |
| | | if (random.nextBoolean()) { |
| | | randomFloat = -randomFloat; |
| | | } |
| | | // 使用String.format()保留两位小数 |
| | | String formattedString = String.format("%.2f", randomFloat); |
| | | // 如果你确实需要double类型,但注意这会丢失不必要的零 |
| | | double formattedDouble = Double.parseDouble(formattedString); |
| | | release = release.add(BigDecimal.valueOf(formattedDouble)); |
| | | |
| | | taskProvideUser.setReleases(release); |
| | | taskProvideUserService.save(taskProvideUser); |
| | | } |
| | | } |
| | | } |
| | | logger.info("任务提供释放初始化结束。。。" + DateUtil.format(now, "yyyy-MM-dd HH:mm:ss")); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.yami.shop.platform.task; |
| | | |
| | | |
| | | import cn.hutool.core.date.DateUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.xxl.job.core.handler.annotation.XxlJob; |
| | | import com.yami.shop.bean.model.*; |
| | | import com.yami.shop.common.constants.DictConstant; |
| | | import com.yami.shop.common.util.DateUtils; |
| | | import com.yami.shop.service.*; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.text.ParseException; |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.LocalDateTime; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.*; |
| | | |
| | | @Slf4j |
| | | @Component |
| | | public class UserLevelTask { |
| | | |
| | | private final Logger logger = LoggerFactory.getLogger(this.getClass()); |
| | | |
| | | @Autowired |
| | | private CdnTeamRelationService cdnTeamRelationService; |
| | | |
| | | @Autowired |
| | | private CdnAgentLevelService cdnAgentLevelService; |
| | | |
| | | @Autowired |
| | | private AgentLevelService agentLevelService; |
| | | |
| | | @Autowired |
| | | private CdnFlowService cdnFlowService; |
| | | |
| | | @Autowired |
| | | private CdnUserWalletService cdnUserWalletService; |
| | | |
| | | @Autowired |
| | | private CdnReleaseService cdnReleaseService; |
| | | |
| | | @Autowired |
| | | private CdnConfigService cdnConfigService; |
| | | |
| | | @Autowired |
| | | private DeviceService deviceService; |
| | | |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @Autowired |
| | | private MarsAdverIncomeService marsAdverIncomeService; |
| | | |
| | | @Autowired |
| | | private CdnReleaseTempService cdnReleaseTempService; |
| | | |
| | | |
| | | @XxlJob("cancelPointRelease") |
| | | public void cancelPointRelease() { |
| | | Double bpointReleaseBl = Double.valueOf( cdnConfigService.selectValueByName("point_release_bl_hb")); |
| | | Double zpointReleaseBl = Double.valueOf(cdnConfigService.selectValueByName("point_release_bl")); |
| | | cdnReleaseTempService.deleteAll(); |
| | | List<CdnRelease> list = cdnReleaseService.list(new LambdaQueryWrapper<CdnRelease>().eq(CdnRelease::getIsAct,2)); |
| | | for (CdnRelease release : list) { |
| | | CdnReleaseTemp cdnReleaseTemp = new CdnReleaseTemp(); |
| | | cdnReleaseTemp.setId(release.getId()); |
| | | if(release.getMoney().compareTo(release.getBalance()) > 0){ |
| | | cdnReleaseTemp.setPointRelease(BigDecimal.valueOf(bpointReleaseBl)); |
| | | }else{ |
| | | cdnReleaseTemp.setPointRelease(BigDecimal.valueOf(zpointReleaseBl)); |
| | | } |
| | | cdnReleaseTempService.insert(cdnReleaseTemp); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 用户等级 判定算法(手机卡) |
| | | */ |
| | | @XxlJob("cancelUserLevel") |
| | | public void cancelUserLevel() { |
| | | try { |
| | | Date now = new Date(); |
| | | logger.info("用户等级调整开始。。。"+ DateUtil.format(now, "yyyy-MM-dd HH:mm:ss")); |
| | | List<CdnTeamRelation> cdnTeamRelationList = cdnTeamRelationService.list(new LambdaQueryWrapper<CdnTeamRelation>()); |
| | | List<AgentLevel> agentLevelList = agentLevelService.getCdnAgentLevelList(); |
| | | List<CdnTeamRelation> lists = new ArrayList<>(); |
| | | for (CdnTeamRelation relation : cdnTeamRelationList) { |
| | | for (AgentLevel agentLevel : agentLevelList) { |
| | | if(relation.getLevel() >= agentLevel.getId()){//等级只能升 不能降 |
| | | continue; |
| | | }else{ |
| | | //直推人 |
| | | Integer num = 0;//直推会员人数 |
| | | Integer total = 0;//激活账号数 |
| | | List<CdnTeamRelation> cdnTeamRelations = cdnTeamRelationService.getTeamRelationListSort(relation.getUserId()); |
| | | if(cdnTeamRelations.size() >= agentLevel.getInvite()){//判断直推人条件 |
| | | for (CdnTeamRelation c:cdnTeamRelations){//直推会员人数 |
| | | if(c.getLevel() == (agentLevel.getId()-1)){ |
| | | num++; |
| | | } |
| | | } |
| | | String pids = null; |
| | | if (StringUtils.isNotBlank(relation.getPids())) { |
| | | pids = relation.getPids() + relation.getUserId() + ","; |
| | | } else { |
| | | pids = "," + relation.getUserId() + ","; |
| | | } |
| | | CdnTeamRelation cdns = new CdnTeamRelation(); |
| | | cdns.setPids(pids); |
| | | List<CdnTeamRelation> cdnTeamList = cdnTeamRelationService.getDividendList(cdns); |
| | | for (CdnTeamRelation c:cdnTeamList){ |
| | | User d = new User(); |
| | | d.setUserId(c.getUserId()); |
| | | d.setActiveStatus("1"); |
| | | total += userService.getctiveStatusCount(d); |
| | | } |
| | | if(num >= agentLevel.getMember() && total >= agentLevel.getDeviceActive()){ |
| | | relation.setLevel(agentLevel.getId()); |
| | | if("V7".equals(agentLevel.getName())){ |
| | | User user = userService.getUserByUserId(relation.getUserId()); |
| | | if(user != null && user.getActiveTime() != null){ |
| | | if(DateUtils.flagIn30DayDate(new SimpleDateFormat("yyyy-MM-dd").format(user.getActiveTime()))){ |
| | | user.setActiveStatus("1"); |
| | | userService.updateById(user); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | lists.add(relation); |
| | | } |
| | | cdnTeamRelationService.updateBatchById(lists); |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 帮扶、分享 、平级(CND托管) |
| | | */ |
| | | @XxlJob("cancelAssists") |
| | | public void cancelAssists() { |
| | | Date now = new Date(); |
| | | logger.info("帮扶费用计算开始。。。"+DateUtil.format(now, "yyyy-MM-dd HH:mm:ss")); |
| | | //分享比例 |
| | | Double share =Double.valueOf(cdnConfigService.selectValueByName("share")) ; |
| | | Double zpointReleaseBl = Double.valueOf(cdnConfigService.selectValueByName("point_release_bl")); |
| | | List<CdnTeamRelation> cdnTeamRelationLists = cdnTeamRelationService.getTeamRelationListSort(null); |
| | | //循环所有完整线 分享、平级、帮扶 |
| | | for (CdnTeamRelation cdnTeamRelation :cdnTeamRelationLists){ |
| | | //基础比例 |
| | | if(cdnTeamRelation.getMeall().compareTo(BigDecimal.ZERO) == 0){ |
| | | continue; |
| | | } |
| | | if(cdnTeamRelation.getPids() != null){ |
| | | String[] pidsArrays = Arrays.copyOfRange(cdnTeamRelation.getPids().split(StrUtil.COMMA), 1, cdnTeamRelation.getPids().split(StrUtil.COMMA).length); |
| | | CdnAgentLevel cdnPAgentLevel = cdnAgentLevelService.getById(cdnTeamRelation.getAgentLevelId()); |
| | | List<CdnRelease> list = cdnReleaseService.list(new LambdaQueryWrapper<CdnRelease>().eq(CdnRelease::getUserId,cdnTeamRelation.getUserId()).eq(CdnRelease::getStatus,1).eq(CdnRelease::getIsAct,2)); |
| | | if(list.size() == 0){ |
| | | continue; |
| | | } |
| | | |
| | | //加速释放比例 |
| | | Integer id = 1; |
| | | BigDecimal releases= BigDecimal.ZERO; |
| | | //个人业绩总价钱 |
| | | BigDecimal mellTotalPrice = BigDecimal.ZERO; |
| | | for (CdnRelease cdnRelease : list){ |
| | | CdnReleaseTemp cdnReleaseTemp = cdnReleaseTempService.getById(cdnRelease.getId()); |
| | | if(cdnReleaseTemp == null){ |
| | | mellTotalPrice = mellTotalPrice.add(cdnRelease.getMoney().multiply(BigDecimal.valueOf(zpointReleaseBl))); |
| | | }else{ |
| | | mellTotalPrice = mellTotalPrice.add(cdnRelease.getMoney().multiply(cdnReleaseTemp.getPointRelease())); |
| | | } |
| | | } |
| | | //从后往前循环遍历 |
| | | for (int i = pidsArrays.length - 1; i >= 0; i--) { |
| | | CdnTeamRelation cdnTeamRelationPids = cdnTeamRelationService.getOne(new LambdaQueryWrapper<CdnTeamRelation>().eq(CdnTeamRelation::getUserId,pidsArrays[i])); |
| | | CdnAgentLevel cdnPAgentLevels = cdnAgentLevelService.getById(cdnTeamRelationPids.getAgentLevelId()); |
| | | if(i==pidsArrays.length - 1) {//不计算帮扶 算分享 |
| | | BigDecimal fxmoney = mellTotalPrice.multiply(BigDecimal.valueOf(share)); |
| | | if(fxmoney.compareTo(BigDecimal.valueOf(0.01)) >= 0){ |
| | | if(cdnTeamRelation.getMeall().compareTo(BigDecimal.ZERO) > 0){//没有个人设备 无法分享助力 |
| | | if(fxmoney.compareTo(BigDecimal.valueOf(0.01)) >= 0){ |
| | | if(!cdnTeamRelation.getPid().equals("0")){ |
| | | setFlowLog(cdnTeamRelation.getPid(),cdnTeamRelation.getUserId(),fxmoney,5,"分享助力",19); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | if(id < cdnPAgentLevels.getId()){//帮扶 |
| | | BigDecimal pfmoney = mellTotalPrice.multiply((cdnPAgentLevels.getReleases().subtract(releases))); |
| | | if(pfmoney.compareTo(BigDecimal.valueOf(0.01)) >= 0){ |
| | | setFlowLog(cdnTeamRelationPids.getUserId(),cdnTeamRelation.getUserId(),pfmoney,5,"帮扶助力",20); |
| | | } |
| | | releases = cdnPAgentLevels.getReleases(); |
| | | id = cdnPAgentLevels.getId(); |
| | | } |
| | | } |
| | | //平级奖 |
| | | Integer ids = cdnPAgentLevel.getId(); |
| | | Integer parallels = 1; |
| | | BigDecimal income = BigDecimal.ZERO; |
| | | BigDecimal releasess= cdnPAgentLevel.getReleases(); |
| | | for (int i = pidsArrays.length - 1; i >= 0; i--) { |
| | | CdnTeamRelation cdnTeamRelationPids = cdnTeamRelationService.getOne(new LambdaQueryWrapper<CdnTeamRelation>().eq(CdnTeamRelation::getUserId,pidsArrays[i])); |
| | | CdnAgentLevel cdnPAgentLevels = cdnAgentLevelService.getById(cdnTeamRelationPids.getAgentLevelId()); |
| | | if(cdnTeamRelationPids.getAgentLevelId() == ids && cdnTeamRelationPids.getAgentLevelId() > parallels){ |
| | | //平级金额 |
| | | BigDecimal pjmoney = income.multiply(cdnPAgentLevels.getParallels()); |
| | | if(pjmoney.compareTo(BigDecimal.valueOf(0.01)) >= 0){ |
| | | setFlowLog(cdnTeamRelationPids.getUserId(),cdnTeamRelation.getUserId(),pjmoney,5,"管理津贴",21); |
| | | } |
| | | ids = cdnTeamRelationPids.getAgentLevelId(); |
| | | parallels = ids; |
| | | }else{ |
| | | if(cdnTeamRelationPids.getAgentLevelId() > ids){ |
| | | income = mellTotalPrice.multiply((cdnPAgentLevels.getReleases().subtract(releasess))); |
| | | ids = cdnTeamRelationPids.getAgentLevelId(); |
| | | } |
| | | } |
| | | } |
| | | // } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 加权分红费用 计算(CND托管) |
| | | */ |
| | | @XxlJob("cancelWeightedDividend") |
| | | public void cancelWeightedDividend() throws ParseException { |
| | | Date now = new Date(); |
| | | logger.info("加权分红费用计算开始。。。"+DateUtil.format(now, "yyyy-MM-dd HH:mm:ss")); |
| | | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); |
| | | SimpleDateFormat forms = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | LocalDateTime currentDateTime = LocalDateTime.now(); |
| | | String nowDateTime = currentDateTime.format(formatter); |
| | | LocalDateTime pastDateTime = currentDateTime.minusHours(24); |
| | | String formattedDateTime = pastDateTime.format(formatter); |
| | | Map<String,BigDecimal> map = new HashMap<>(); |
| | | //加权分红(级差部分) |
| | | List<CdnTeamRelation> cdnTeamRelationList = cdnTeamRelationService.list(new LambdaQueryWrapper<CdnTeamRelation>() |
| | | .gt(CdnTeamRelation::getTodayQuantity,0).orderByDesc(CdnTeamRelation::getSort)); |
| | | //循环所有完整线 |
| | | for (CdnTeamRelation cdnTeamRelation :cdnTeamRelationList){ |
| | | if(StringUtils.isNotBlank(cdnTeamRelation.getPids())){ |
| | | if(cdnTeamRelation.getTodayQuantity() == 0){ |
| | | continue; |
| | | } |
| | | //加速释放比例 |
| | | Integer id = 1; |
| | | BigDecimal rebate= BigDecimal.ZERO; |
| | | BigDecimal mellTotalPrice = BigDecimal.ZERO; |
| | | List<CdnRelease> list = cdnReleaseService.list(new LambdaQueryWrapper<CdnRelease>() |
| | | .eq(CdnRelease::getUserId,cdnTeamRelation.getUserId()).eq(CdnRelease::getIsAct,2) |
| | | .between(CdnRelease::getCreateTime, forms.parse(formattedDateTime), forms.parse(nowDateTime))); |
| | | for (CdnRelease cdnRelease:list){ |
| | | mellTotalPrice = mellTotalPrice.add(cdnRelease.getMoney()); |
| | | } |
| | | if(mellTotalPrice.compareTo(BigDecimal.ZERO) == 0){ |
| | | continue; |
| | | } |
| | | String[] pidsArrays = Arrays.copyOfRange(cdnTeamRelation.getPids().split(StrUtil.COMMA), 1, cdnTeamRelation.getPids().split(StrUtil.COMMA).length); |
| | | //从后往前循环遍历 |
| | | for (int i = pidsArrays.length - 1; i >= 0; i--) { |
| | | CdnTeamRelation cdnTeamRelationPids = cdnTeamRelationService.getOne(new LambdaQueryWrapper<CdnTeamRelation>().eq(CdnTeamRelation::getUserId,pidsArrays[i])); |
| | | if(cdnTeamRelationPids != null){ |
| | | if(cdnTeamRelationPids.getAgentLevelId() < 4) {//市级以下不用算 |
| | | continue; |
| | | } |
| | | CdnAgentLevel cdnPAgentLevels = cdnAgentLevelService.getById(cdnTeamRelationPids.getAgentLevelId()); |
| | | if(id < cdnPAgentLevels.getId()) { |
| | | BigDecimal pfmoney = mellTotalPrice.multiply(cdnPAgentLevels.getRebate().subtract(rebate)); |
| | | if (pfmoney.compareTo(BigDecimal.valueOf(0.01)) >= 0) { |
| | | if(map.containsKey(cdnTeamRelationPids.getUserId())){ |
| | | BigDecimal value = map.get(cdnTeamRelationPids.getUserId()).add(pfmoney); |
| | | map.put(cdnTeamRelationPids.getUserId(),value); |
| | | }else{ |
| | | BigDecimal value = pfmoney; |
| | | map.put(cdnTeamRelationPids.getUserId(),value); |
| | | } |
| | | id = cdnPAgentLevels.getId(); |
| | | rebate =cdnPAgentLevels.getRebate(); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | //大区、省、市 |
| | | CdnTeamRelation cdns = new CdnTeamRelation(); |
| | | cdns.setAgentLevelId(3); |
| | | List<CdnTeamRelation> cdnTeamRelationLists = cdnTeamRelationService.selectByAgentLevelId(cdns); |
| | | BigDecimal money = cdnTeamRelationService.selectCountMoney(); |
| | | if (money == null || money.compareTo(BigDecimal.ZERO) == 0) { |
| | | return; |
| | | } |
| | | //市级集合 |
| | | List<CdnTeamRelation> cityTeamRelationList = new ArrayList<>(); |
| | | //市级团队业绩之和 |
| | | BigDecimal cityMall = BigDecimal.ZERO; |
| | | //省级集合 |
| | | List<CdnTeamRelation> provinceTeamRelationList = new ArrayList<>(); |
| | | //省级团队业绩之和 |
| | | BigDecimal provinceMall = BigDecimal.ZERO; |
| | | //大区集合 |
| | | List<CdnTeamRelation> regionTeamRelationList = new ArrayList<>(); |
| | | //大区团队业绩之和 |
| | | BigDecimal regionMall = BigDecimal.ZERO; |
| | | //循环所有市、省、大区用户 |
| | | for (CdnTeamRelation cdnTeamRelation :cdnTeamRelationLists){ |
| | | //新增设备 |
| | | CdnAgentLevel cdnPAgentLevel = cdnAgentLevelService.getById(cdnTeamRelation.getAgentLevelId()); |
| | | //省市 大区 分组 |
| | | if(cdnPAgentLevel.getName().indexOf("市级") >= 0){ |
| | | cityTeamRelationList.add(cdnTeamRelation); |
| | | cityMall = cityMall.add(cdnTeamRelation.getTeamall()); |
| | | }else if(cdnPAgentLevel.getName().indexOf("省级") >= 0){ |
| | | provinceTeamRelationList.add(cdnTeamRelation); |
| | | provinceMall=provinceMall.add(cdnTeamRelation.getTeamall()); |
| | | }else if(cdnPAgentLevel.getName().indexOf("大区") >= 0){ |
| | | regionTeamRelationList.add(cdnTeamRelation); |
| | | regionMall=regionMall.add(cdnTeamRelation.getTeamall()); |
| | | } |
| | | } |
| | | //市级代理 |
| | | CdnFlow cdnFlow = new CdnFlow(); |
| | | if(cityTeamRelationList.size() > 0){ |
| | | for (CdnTeamRelation teamRelation : cityTeamRelationList){ |
| | | CdnAgentLevel cdnAgentLevels = cdnAgentLevelService.getById(teamRelation.getAgentLevelId()); |
| | | BigDecimal price = money.multiply(cdnAgentLevels.getRebates()).multiply(teamRelation.getTeamall()).divide(cityMall,BigDecimal.ROUND_CEILING); |
| | | if(map.containsKey(teamRelation.getUserId())){ |
| | | BigDecimal value = map.get(teamRelation.getUserId()).add(price); |
| | | map.put(teamRelation.getUserId(),value); |
| | | }else{ |
| | | BigDecimal value = price; |
| | | map.put(teamRelation.getUserId(),value); |
| | | } |
| | | } |
| | | } |
| | | |
| | | //省级代理 |
| | | if(provinceTeamRelationList.size() > 0){ |
| | | for (CdnTeamRelation teamRelation : provinceTeamRelationList){ |
| | | CdnAgentLevel cdnAgentLevels = cdnAgentLevelService.getById(teamRelation.getAgentLevelId()); |
| | | BigDecimal price = money.multiply(cdnAgentLevels.getRebates()).multiply(teamRelation.getTeamall()).divide(provinceMall,BigDecimal.ROUND_CEILING); |
| | | if(map.containsKey(teamRelation.getUserId())){ |
| | | BigDecimal value = map.get(teamRelation.getUserId()).add(price); |
| | | map.put(teamRelation.getUserId(),value); |
| | | }else{ |
| | | BigDecimal value = price; |
| | | map.put(teamRelation.getUserId(),value); |
| | | } |
| | | } |
| | | } |
| | | |
| | | //大区代理 |
| | | if(regionTeamRelationList.size() > 0){ |
| | | for (CdnTeamRelation teamRelation : regionTeamRelationList){ |
| | | CdnAgentLevel cdnAgentLevels = cdnAgentLevelService.getById(teamRelation.getAgentLevelId()); |
| | | BigDecimal price = money.multiply(cdnAgentLevels.getRebates()).multiply(teamRelation.getTeamall()).divide(regionMall,BigDecimal.ROUND_CEILING); |
| | | if(map.containsKey(teamRelation.getUserId())){ |
| | | BigDecimal value = map.get(teamRelation.getUserId()).add(price); |
| | | map.put(teamRelation.getUserId(),value); |
| | | }else{ |
| | | BigDecimal value = price; |
| | | map.put(teamRelation.getUserId(),value); |
| | | } |
| | | } |
| | | } |
| | | map.forEach((key, value) -> { |
| | | CdnFlow cdnFlows = new CdnFlow(); |
| | | CdnUserWallet cdnUserWallets = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId, key) |
| | | .eq(CdnUserWallet::getWalletId, 6)); |
| | | cdnFlows.setUserId(key); |
| | | cdnFlows.setMemo("加权分红"); |
| | | cdnFlows.setMoney(value); |
| | | cdnFlows.setOldmoney(cdnUserWallets != null ? cdnUserWallets.getMoney() : BigDecimal.ZERO); |
| | | cdnFlows.setFlownameId(22); |
| | | cdnFlows.setCreateTime(new Date()); |
| | | cdnFlows.setWalletId(6); |
| | | cdnFlows.setDate(new Date()); |
| | | cdnFlowService.save(cdnFlows); |
| | | cdnUserWallets.setMoney(cdnFlows.getOldmoney().add(cdnFlows.getMoney())); |
| | | cdnUserWallets.setUpdateTime(new Date()); |
| | | cdnUserWalletService.updateById(cdnUserWallets); |
| | | }); |
| | | cdnTeamRelationService.updateTodayQuantity(); |
| | | } |
| | | |
| | | /** |
| | | * 普通分润(CND托管) |
| | | */ |
| | | @XxlJob("cancelDividend") |
| | | public void cancelDividend() { |
| | | Date now = new Date(); |
| | | logger.info("普通分润计算费用。。。"+DateUtil.format(now, "yyyy-MM-dd HH:mm:ss")); |
| | | CdnTeamRelation relation = new CdnTeamRelation(); |
| | | relation.setMeall(BigDecimal.ZERO); |
| | | List<CdnTeamRelation> cdnTeamRelationList = cdnTeamRelationService.selectByAgentLevelId(relation); |
| | | Double zpointReleaseBl = Double.valueOf(cdnConfigService.selectValueByName("point_release_bl")); |
| | | for (CdnTeamRelation cdnTeamRelation :cdnTeamRelationList){ |
| | | //基础比例 |
| | | List<CdnRelease> list = cdnReleaseService.list(new LambdaQueryWrapper<CdnRelease>().eq(CdnRelease::getUserId,cdnTeamRelation.getUserId()).eq(CdnRelease::getStatus,1).eq(CdnRelease::getIsAct,2)); |
| | | if(list.size() == 0){ |
| | | continue; |
| | | } |
| | | CdnFlow cdnFlow = new CdnFlow(); |
| | | cdnFlow.setUserIds(cdnTeamRelation.getUserId()); |
| | | cdnFlow.setUserId(cdnTeamRelation.getUserId()); |
| | | cdnFlow.setFlownameId(18); |
| | | cdnFlow.setWalletId(5); |
| | | BigDecimal totalPrice = BigDecimal.ZERO; |
| | | for (CdnRelease cdnRelease : list){ |
| | | BigDecimal price = BigDecimal.ZERO; |
| | | CdnReleaseTemp cdnReleaseTemp = cdnReleaseTempService.getById(cdnRelease.getId()); |
| | | if(cdnReleaseTemp == null){ |
| | | price = cdnRelease.getMoney().multiply(BigDecimal.valueOf(zpointReleaseBl)); |
| | | }else{ |
| | | price = cdnRelease.getMoney().multiply(cdnReleaseTemp.getPointRelease()); |
| | | } |
| | | |
| | | CdnRelease cdnReleases = cdnReleaseService.getById(cdnRelease.getId()); |
| | | if(cdnReleases.getBalance().compareTo(BigDecimal.ZERO) == 0){//绿积分清空 已释放 直接 |
| | | continue; |
| | | } |
| | | if(cdnRelease.getBalance().compareTo(price) < 0){//剩余率积分小于分润 扣除剩余积分余额 |
| | | cdnRelease.setBalance(BigDecimal.ZERO); |
| | | cdnRelease.setStatus(0); |
| | | //updateTmall(cdnRelease.getUserId(),cdnRelease.getNum()); |
| | | //修改个人数量和上级团队数量 |
| | | totalPrice=totalPrice.add(cdnRelease.getBalance()); |
| | | }else{//否则正常扣除 |
| | | cdnRelease.setBalance(cdnRelease.getBalance().subtract(price)); |
| | | totalPrice = totalPrice.add(price); |
| | | } |
| | | cdnReleaseService.updateById(cdnRelease); |
| | | } |
| | | cdnFlow.setMemo("普通分润:相关用户"+cdnTeamRelation.getUserId()); |
| | | if(totalPrice.compareTo(BigDecimal.ZERO) == 0){ |
| | | continue; |
| | | } |
| | | cdnFlow.setMoney(totalPrice.negate()); |
| | | cdnFlow.setCreateTime(new Date()); |
| | | cdnFlow.setDate(new Date()); |
| | | //钱包更改 |
| | | CdnUserWallet cdnUserWallet = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId,cdnTeamRelation.getUserId()) |
| | | .eq(CdnUserWallet::getWalletId,5)); |
| | | cdnFlow.setOldmoney(cdnUserWallet.getMoney()); |
| | | cdnFlowService.save(cdnFlow); |
| | | cdnUserWallet.setMoney(cdnFlow.getOldmoney().add(cdnFlow.getMoney())); |
| | | cdnUserWallet.setUpdateTime(new Date()); |
| | | cdnUserWalletService.updateById(cdnUserWallet); |
| | | CdnFlow cdnFlows = new CdnFlow(); |
| | | BeanUtils.copyProperties(cdnFlow, cdnFlows); |
| | | cdnFlows.setMoney(cdnFlow.getMoney().negate()); |
| | | cdnFlows.setWalletId(3); |
| | | cdnFlows.setFlownameId(18); |
| | | CdnUserWallet cdnUserWallets = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId,cdnTeamRelation.getUserId()) |
| | | .eq(CdnUserWallet::getWalletId,3)); |
| | | cdnFlows.setOldmoney(cdnUserWallets.getMoney() == null ? BigDecimal.ZERO:cdnUserWallets.getMoney()); |
| | | cdnFlows.setMemo("普通分润-->余额:相关用户"+cdnTeamRelation.getUserId()); |
| | | cdnFlowService.save(cdnFlows); |
| | | cdnUserWallets.setUserId(cdnTeamRelation.getUserId()); |
| | | cdnUserWallets.setWalletId(3); |
| | | cdnUserWallets.setMoney(cdnUserWallets.getMoney().add(cdnFlow.getMoney().negate())); |
| | | cdnUserWallets.setUpdateTime(new Date()); |
| | | cdnUserWalletService.updateById(cdnUserWallets); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 帮扶、分享 、平级(手机卡) |
| | | */ |
| | | @XxlJob("cancelAssist") |
| | | public void cancelAssist() { |
| | | try { |
| | | Date now = new Date(); |
| | | logger.info("团队奖励计算开始。。。"+DateUtil.format(now, "yyyy-MM-dd HH:mm:ss")); |
| | | //先计算合伙人分红 查询 |
| | | BigDecimal companyPoint = BigDecimal.valueOf(Double.valueOf( cdnConfigService.selectValueByName("company_point")));//公司沉淀 |
| | | BigDecimal teamPoint = BigDecimal.valueOf(Double.valueOf( cdnConfigService.selectValueByName("team_point")));//团队奖比例 |
| | | BigDecimal partnerPoint = BigDecimal.valueOf(Double.valueOf( cdnConfigService.selectValueByName("partner_point")));//合伙人 |
| | | BigDecimal directPoint = BigDecimal.valueOf(Double.valueOf( cdnConfigService.selectValueByName("share")));//直推奖 |
| | | BigDecimal jcPoint = BigDecimal.valueOf(Double.valueOf( cdnConfigService.selectValueByName("team_range_point")));//团队中的级差比例 |
| | | BigDecimal incomeCount = marsAdverIncomeService.selectAllIncome(null); |
| | | if(incomeCount != null){ |
| | | //合伙人总数 |
| | | List<User> userList = userService.list(new LambdaQueryWrapper<User>().eq(User::getIsPartner,1)); |
| | | for (User user:userList){ |
| | | //全天的总收益 *(1-公司沉淀0.3) * 50%(团队奖) * 8% / 合伙人(查询)的总数 |
| | | BigDecimal money = incomeCount.multiply(BigDecimal.valueOf(1).subtract(companyPoint)).multiply(teamPoint).multiply(partnerPoint).divide(BigDecimal.valueOf(userList.size()),2, RoundingMode.HALF_UP); |
| | | if(money.compareTo(BigDecimal.valueOf(0.01)) >= 0) { |
| | | setFlowLogs(user.getUserId(), user.getUserId(), money, DictConstant.WALLET_ID_10, "合伙人分成", DictConstant.FLOWNAME_ID_30); |
| | | } |
| | | } |
| | | } |
| | | List<CdnTeamRelation> cdnTeamRelationLists = cdnTeamRelationService.getTeamRelationListSort(null); |
| | | Map<Integer,BigDecimal> map =new HashMap<>(); |
| | | for (CdnTeamRelation cdnTeamRelation :cdnTeamRelationLists){ |
| | | //查询个人的幸运池 没有直接无收益 |
| | | CdnUserWallet cdnUserWallet = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId,cdnTeamRelation.getUserId()) |
| | | .eq(CdnUserWallet::getWalletId,10)); |
| | | if(cdnUserWallet.getMoney().compareTo(BigDecimal.ZERO) == 0){ |
| | | continue; |
| | | } |
| | | BigDecimal income = marsAdverIncomeService.selectAllIncome(cdnTeamRelation.getUserId()); |
| | | if(income == null || income.compareTo(BigDecimal.ZERO) == 0){//没有业绩的 |
| | | continue; |
| | | } |
| | | CdnTeamRelation pCdnTeamRelation = cdnTeamRelationService.geteamRelationByUserId(cdnTeamRelation.getPid()); |
| | | if(pCdnTeamRelation != null){ |
| | | //直推奖 个人业绩 * (1-公司沉淀0.3) * 50%(团队奖) * 10% |
| | | BigDecimal ztmoney = income.multiply(BigDecimal.valueOf(1).subtract(companyPoint)).multiply(teamPoint).multiply(directPoint); |
| | | if(ztmoney.compareTo(BigDecimal.valueOf(0.01)) >= 0) { |
| | | setFlowLogs(pCdnTeamRelation.getUserId(), cdnTeamRelation.getUserId(), ztmoney, DictConstant.WALLET_ID_10, "直推奖励", DictConstant.FLOWNAME_ID_30); |
| | | } |
| | | //循环所有上级用户 计算平级奖 直到1毛为止 |
| | | if(cdnTeamRelation.getPids() != null) { |
| | | String[] pidsArrays = Arrays.copyOfRange(cdnTeamRelation.getPids().split(StrUtil.COMMA), 1, cdnTeamRelation.getPids().split(StrUtil.COMMA).length); |
| | | AgentLevel agentLevel = agentLevelService.getById(cdnTeamRelation.getLevel()); |
| | | //加速释放比例 |
| | | Integer id = 0; |
| | | BigDecimal releases= BigDecimal.ZERO; |
| | | if(agentLevel != null){ |
| | | releases= agentLevel.getReleases(); |
| | | } |
| | | Integer ids = 0; |
| | | // if(agentLevel != null){ |
| | | // ids= agentLevel.getId(); |
| | | // } |
| | | Integer parallels = 0; |
| | | // 将各个会员等级的收益全部汇总 个人今日收益 * (1-公司沉淀0.3) * 50%(团队奖) * 10% |
| | | BigDecimal countPoint = income.multiply(BigDecimal.valueOf(1).subtract(companyPoint)).multiply(teamPoint); |
| | | BigDecimal djPoint = countPoint.multiply(BigDecimal.valueOf(1).subtract(jcPoint)); |
| | | BigDecimal pjCount = countPoint; |
| | | for (int i = pidsArrays.length - 1; i >= 0; i--) { |
| | | BigDecimal childMoeny = BigDecimal.ZERO; |
| | | CdnTeamRelation cdnTeamRelationPids = cdnTeamRelationService.getOne(new LambdaQueryWrapper<CdnTeamRelation>().eq(CdnTeamRelation::getUserId, pidsArrays[i])); |
| | | AgentLevel agentLevels = agentLevelService.getById(cdnTeamRelationPids.getLevel()); |
| | | if(agentLevels != null){ |
| | | if(map.containsKey(agentLevels.getId())){ |
| | | BigDecimal value = map.get(agentLevels.getId()).add(djPoint); |
| | | map.put(agentLevels.getId(),value); |
| | | }else{ |
| | | BigDecimal value = djPoint; |
| | | map.put(agentLevels.getId(),value); |
| | | } |
| | | //获取收益 |
| | | if(id < agentLevels.getId()) { |
| | | childMoeny = countPoint.multiply(jcPoint).multiply((agentLevels.getReleases().subtract(releases))); |
| | | if(childMoeny.compareTo(BigDecimal.valueOf(0.01)) >= 0){ |
| | | setFlowLogs(cdnTeamRelationPids.getUserId(),cdnTeamRelation.getUserId(),childMoeny,DictConstant.WALLET_ID_10,"团队奖(级差)",DictConstant.FLOWNAME_ID_30); |
| | | } |
| | | releases = agentLevels.getReleases(); |
| | | id = agentLevels.getId(); |
| | | } |
| | | |
| | | if (cdnTeamRelationPids.getLevel() == ids && cdnTeamRelationPids.getLevel() > parallels && ids != 0) { |
| | | //平级奖 本用户收益的10% 贡献给上级 |
| | | BigDecimal pjmoney = pjCount.multiply(agentLevels.getParallels()); |
| | | if (pjmoney.compareTo(BigDecimal.valueOf(0.01)) >= 0) { |
| | | setFlowLogs(cdnTeamRelationPids.getUserId(), cdnTeamRelation.getUserId(), pjmoney, DictConstant.WALLET_ID_10, "管理津贴", DictConstant.FLOWNAME_ID_30); |
| | | } |
| | | ids = cdnTeamRelationPids.getLevel(); |
| | | parallels = ids; |
| | | pjCount = pjmoney; |
| | | } else { |
| | | ids = cdnTeamRelationPids.getLevel(); |
| | | } |
| | | }else{ |
| | | ids = 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | //计算团队奖的业绩部分 例如:V1总业绩(是否带团队的收益) |
| | | List<AgentLevel> list = agentLevelService.list(); |
| | | for (AgentLevel agentLevel : list) { |
| | | //根据会员等级计算今日总业绩 |
| | | BigDecimal count = cdnTeamRelationService.selectTMell(agentLevel.getId()); |
| | | if(count == null || count.compareTo(BigDecimal.ZERO) == 0){//没有业绩的 |
| | | continue; |
| | | } |
| | | //循环所有会员(V1会员) |
| | | List<CdnTeamRelation> cdnTeamRelations = cdnTeamRelationService.getTeamRelationListByAgentLevel(agentLevel.getId()); |
| | | for (CdnTeamRelation c :cdnTeamRelations){ |
| | | //查询个人的幸运池 没有直接无收益 |
| | | CdnUserWallet cdnUserWallet = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId,c.getUserId()) |
| | | .eq(CdnUserWallet::getWalletId,10)); |
| | | if(cdnUserWallet.getMoney().compareTo(BigDecimal.ZERO) == 0){ |
| | | continue; |
| | | } |
| | | if(c.getTeamTodayMobile() > 0){ |
| | | BigDecimal pjmoney = map.get(c.getLevel()).multiply(BigDecimal.valueOf(c.getTeamTodayMobile())).divide(count,BigDecimal.ROUND_CEILING); |
| | | if (pjmoney.compareTo(BigDecimal.valueOf(0.01)) >= 0) { |
| | | setFlowLogs(c.getUserId(), null, pjmoney, DictConstant.WALLET_ID_10, "团队奖(业绩部分)", DictConstant.FLOWNAME_ID_30); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | |
| | | // @XxlJob("/cancelGeneral") |
| | | public void cancelGeneral() { |
| | | try { |
| | | Date now = new Date(); |
| | | logger.info("个人分成计算开始。。。"+DateUtil.format(now, "yyyy-MM-dd HH:mm:ss")); |
| | | BigDecimal companyPoint = BigDecimal.valueOf(Double.valueOf( cdnConfigService.selectValueByName("company_point")));//公司沉淀 |
| | | BigDecimal mellPoint = BigDecimal.valueOf(Double.valueOf( cdnConfigService.selectValueByName("mell_point")));//个人比例 |
| | | List<CdnTeamRelation> cdnTeamRelationLists = cdnTeamRelationService.getTeamRelationListSort(null); |
| | | for (CdnTeamRelation cdnTeamRelation : cdnTeamRelationLists) { |
| | | //查询个人的幸运池 没有直接无收益 |
| | | CdnUserWallet cdnUserWallet = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId,cdnTeamRelation.getUserId()) |
| | | .eq(CdnUserWallet::getWalletId,DictConstant.WALLET_ID_10)); |
| | | if(cdnUserWallet.getMoney().compareTo(BigDecimal.ZERO) == 0){ |
| | | continue; |
| | | } |
| | | BigDecimal income = marsAdverIncomeService.selectAllIncome(cdnTeamRelation.getUserId()); |
| | | if(income != null && income.compareTo(BigDecimal.ZERO) > 0){ |
| | | setFlowLogs(cdnTeamRelation.getUserId(), cdnTeamRelation.getUserId(), income.multiply(BigDecimal.valueOf(1).subtract(companyPoint)).multiply(mellPoint), DictConstant.WALLET_ID_10, "个人分润", DictConstant.FLOWNAME_ID_30); |
| | | } |
| | | } |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * |
| | | * @param userId 受益人 |
| | | * @param userIds 贡献人 |
| | | * @param money 收益金额 |
| | | * @param walletId 钱包类型 |
| | | * @param desc 收益描述 |
| | | * @param flownameId 流水类型 |
| | | */ |
| | | private void setFlowLog(String userId,String userIds,BigDecimal money,Integer walletId,String desc,Integer flownameId){ |
| | | CdnFlow cdnFlow = new CdnFlow(); |
| | | cdnFlow.setUserIds(userIds); |
| | | cdnFlow.setUserId(userId); |
| | | cdnFlow.setFlownameId(flownameId); |
| | | cdnFlow.setWalletId(walletId); |
| | | //钱包更改 |
| | | CdnUserWallet cdnUserWallet = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId,userId) |
| | | .eq(CdnUserWallet::getWalletId,walletId)); |
| | | if(money.compareTo(BigDecimal.ZERO) <= 0){//绿积分为0 已经释放完毕 |
| | | return; |
| | | }else{ |
| | | if(money.compareTo(cdnUserWallet.getMoney()) >= 0){//分润超过剩余绿积分 释放最后的绿积分 并将SN改为结束 |
| | | cdnFlow.setMoney(cdnUserWallet.getMoney().negate()); |
| | | //updateResouce(userId,BigDecimal.ZERO); |
| | | }else{ |
| | | cdnFlow.setMoney(money.negate()); |
| | | //updateResouce(userId,money); |
| | | } |
| | | } |
| | | cdnFlow.setMemo(desc+":相关用户"+userIds); |
| | | cdnFlow.setCreateTime(new Date()); |
| | | cdnFlow.setDate(new Date()); |
| | | cdnFlow.setOldmoney(cdnUserWallet.getMoney()); |
| | | cdnFlowService.save(cdnFlow); |
| | | cdnUserWallet.setUserId(userId); |
| | | cdnUserWallet.setWalletId(walletId); |
| | | cdnUserWallet.setMoney(cdnUserWallet.getMoney().add(cdnFlow.getMoney())); |
| | | cdnUserWallet.setUpdateTime(new Date()); |
| | | cdnUserWalletService.updateById(cdnUserWallet); |
| | | CdnFlow cdnFlows = new CdnFlow(); |
| | | BeanUtils.copyProperties(cdnFlow, cdnFlows); |
| | | cdnFlows.setMoney(cdnFlow.getMoney().negate()); |
| | | cdnFlows.setWalletId(3); |
| | | cdnFlows.setFlownameId(flownameId); |
| | | CdnUserWallet cdnUserWallets = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId,userId) |
| | | .eq(CdnUserWallet::getWalletId,3)); |
| | | if(null == cdnUserWallets){ |
| | | return; |
| | | } |
| | | cdnFlows.setOldmoney(cdnUserWallets.getMoney() == null?BigDecimal.ZERO:cdnUserWallets.getMoney()); |
| | | cdnFlows.setMemo(desc+"-->余额:相关用户"+userIds); |
| | | cdnFlowService.save(cdnFlows); |
| | | //钱包更改 |
| | | cdnUserWallets.setUserId(userId); |
| | | cdnUserWallets.setWalletId(3); |
| | | cdnUserWallets.setMoney(cdnUserWallets.getMoney()== null?cdnFlow.getMoney().negate():cdnUserWallets.getMoney().add(cdnFlow.getMoney().negate())); |
| | | cdnUserWallets.setUpdateTime(new Date()); |
| | | cdnUserWalletService.updateById(cdnUserWallets); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * |
| | | * @param userId 受益人 |
| | | * @param userIds 贡献人 |
| | | * @param money 收益金额 |
| | | * @param walletId 钱包类型 |
| | | * @param desc 收益描述 |
| | | * @param flownameId 流水类型 |
| | | */ |
| | | private void setFlowLogs(String userId,String userIds,BigDecimal money,Integer walletId,String desc,Integer flownameId){ |
| | | CdnFlow cdnFlow = new CdnFlow(); |
| | | cdnFlow.setUserIds(userIds); |
| | | cdnFlow.setUserId(userId); |
| | | cdnFlow.setFlownameId(flownameId); |
| | | cdnFlow.setWalletId(walletId); |
| | | //钱包更改 |
| | | CdnUserWallet cdnUserWallet = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId,userId) |
| | | .eq(CdnUserWallet::getWalletId,walletId)); |
| | | if(cdnUserWallet.getMoney().compareTo(BigDecimal.ZERO) == 0){ |
| | | return; |
| | | } |
| | | if(money.compareTo(BigDecimal.ZERO) <= 0){//幸运池已经释放完毕 |
| | | return; |
| | | }else{ |
| | | if(money.compareTo(cdnUserWallet.getMoney()) >= 0){ |
| | | cdnFlow.setMoney(cdnUserWallet.getMoney().negate()); |
| | | }else{ |
| | | cdnFlow.setMoney(money.negate()); |
| | | } |
| | | } |
| | | cdnFlow.setMemo(desc+":释放用户"+userIds); |
| | | cdnFlow.setCreateTime(new Date()); |
| | | cdnFlow.setDate(new Date()); |
| | | cdnFlow.setOldmoney(cdnUserWallet.getMoney()); |
| | | cdnFlowService.save(cdnFlow); |
| | | cdnUserWallet.setUserId(userId); |
| | | cdnUserWallet.setWalletId(walletId); |
| | | cdnUserWallet.setMoney(cdnUserWallet.getMoney().add(cdnFlow.getMoney())); |
| | | cdnUserWallet.setUpdateTime(new Date()); |
| | | cdnUserWalletService.updateById(cdnUserWallet); |
| | | //释放完进入流量 |
| | | CdnFlow cdnFlows = new CdnFlow(); |
| | | BeanUtils.copyProperties(cdnFlow, cdnFlows); |
| | | cdnFlows.setMoney(cdnFlow.getMoney().negate()); |
| | | cdnFlows.setWalletId(DictConstant.WALLET_ID_8); |
| | | cdnFlows.setFlownameId(flownameId); |
| | | CdnUserWallet cdnUserWallets = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId,userId) |
| | | .eq(CdnUserWallet::getWalletId,DictConstant.WALLET_ID_8)); |
| | | if(null == cdnUserWallets){ |
| | | return; |
| | | } |
| | | cdnFlows.setOldmoney(cdnUserWallets.getMoney() == null?BigDecimal.ZERO:cdnUserWallets.getMoney()); |
| | | cdnFlows.setMemo(desc+"-->流量:相关用户"+userIds); |
| | | cdnFlowService.save(cdnFlows); |
| | | //钱包更改 |
| | | cdnUserWallets.setUserId(userId); |
| | | cdnUserWallets.setWalletId(DictConstant.WALLET_ID_8); |
| | | cdnUserWallets.setMoney(cdnUserWallets.getMoney()== null?cdnFlow.getMoney().negate():cdnUserWallets.getMoney().add(cdnFlow.getMoney().negate())); |
| | | cdnUserWallets.setUpdateTime(new Date()); |
| | | cdnUserWalletService.updateById(cdnUserWallets); |
| | | } |
| | | |
| | | /** |
| | | * 流量分佣 |
| | | */ |
| | | @XxlJob("cancelFlowPoint") |
| | | public void cancelFlowPoint() { |
| | | Date now = new Date(); |
| | | logger.info("流量分佣计算开始。。。"+DateUtil.format(now, "yyyy-MM-dd HH:mm:ss")); |
| | | List<CdnTeamRelation> cdnTeamRelationList = cdnTeamRelationService.getTeamRelationListSort(null); |
| | | //循环所有完整线 |
| | | for (CdnTeamRelation cdnTeamRelation :cdnTeamRelationList){ |
| | | if(StringUtils.isNotBlank(cdnTeamRelation.getPids())){ |
| | | CdnAgentLevel cdnPAgentLevel = cdnAgentLevelService.getById(cdnTeamRelation.getAgentLevelId()); |
| | | //加速释放比例 |
| | | Integer id = 1; |
| | | BigDecimal flowPoint= cdnPAgentLevel.getFlowPoint(); |
| | | BigDecimal mellTotalPrice = BigDecimal.ZERO; |
| | | List<CdnRelease> list = cdnReleaseService.list(new LambdaQueryWrapper<CdnRelease>().eq(CdnRelease::getUserId,cdnTeamRelation.getUserId()).eq(CdnRelease::getStatus,1).eq(CdnRelease::getIsAct,1)); |
| | | if (list.isEmpty()){ |
| | | continue; |
| | | } |
| | | for (CdnRelease cdnRelease:list){ |
| | | List<V1BoxIncome> incomeList = deviceService.getMoneyListBySn(cdnRelease.getSn()); |
| | | if(incomeList.size() >0){ |
| | | for (V1BoxIncome v1BoxIncome:incomeList){ |
| | | mellTotalPrice = mellTotalPrice.add(v1BoxIncome.getAmount()); |
| | | if(v1BoxIncome.getUserAmount() != null){ |
| | | CdnFlow cdnFlow = new CdnFlow(); |
| | | CdnUserWallet cdnUserWallets = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId, cdnTeamRelation.getUserId()) |
| | | .eq(CdnUserWallet::getWalletId, 6)); |
| | | cdnFlow.setUserId(cdnTeamRelation.getUserId()); |
| | | cdnFlow.setUserIds(cdnTeamRelation.getUserId()); |
| | | cdnFlow.setMemo("流量分佣-->相关用户:" + cdnTeamRelation.getUserId()); |
| | | cdnFlow.setMoney(v1BoxIncome.getUserAmount()); |
| | | cdnFlow.setOldmoney(cdnUserWallets != null ? cdnUserWallets.getMoney() : BigDecimal.ZERO); |
| | | cdnFlow.setFlownameId(26); |
| | | cdnFlow.setCreateTime(new Date()); |
| | | cdnFlow.setWalletId(6); |
| | | cdnFlow.setDate(new Date()); |
| | | cdnFlowService.save(cdnFlow); |
| | | cdnUserWallets.setWalletId(6); |
| | | cdnUserWallets.setMoney(cdnUserWallets.getMoney().add(cdnFlow.getMoney())); |
| | | cdnUserWallets.setCreateTime(new Date()); |
| | | cdnUserWalletService.updateById(cdnUserWallets); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | String[] pidsArrays = Arrays.copyOfRange(cdnTeamRelation.getPids().split(StrUtil.COMMA), 1, cdnTeamRelation.getPids().split(StrUtil.COMMA).length); |
| | | //从后往前循环遍历 |
| | | for (int i = pidsArrays.length - 1; i >= 0; i--) { |
| | | CdnTeamRelation cdnTeamRelationPids = cdnTeamRelationService.getOne(new LambdaQueryWrapper<CdnTeamRelation>().eq(CdnTeamRelation::getUserId,pidsArrays[i])); |
| | | CdnAgentLevel cdnPAgentLevels = cdnAgentLevelService.getById(cdnTeamRelationPids.getAgentLevelId()); |
| | | if(id < cdnPAgentLevels.getId()) {// |
| | | String sdMoney = cdnConfigService.selectValueByName("flow_rebate"); |
| | | BigDecimal pfmoney = mellTotalPrice.multiply(BigDecimal.valueOf(Double.parseDouble(sdMoney))).multiply((cdnPAgentLevels.getFlowPoint().subtract(flowPoint))); |
| | | if (pfmoney.compareTo(BigDecimal.valueOf(0.01)) >= 0) { |
| | | CdnFlow cdnFlows = new CdnFlow(); |
| | | CdnUserWallet cdnUserWallets = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId, cdnTeamRelationPids.getUserId()) |
| | | .eq(CdnUserWallet::getWalletId, 6)); |
| | | cdnFlows.setUserId(cdnTeamRelationPids.getUserId()); |
| | | cdnFlows.setUserIds(cdnTeamRelation.getUserId()); |
| | | cdnFlows.setMemo("流量分佣-->相关用户:" + cdnTeamRelation.getUserId()); |
| | | cdnFlows.setMoney(pfmoney); |
| | | cdnFlows.setOldmoney(cdnUserWallets != null ? cdnUserWallets.getMoney() : BigDecimal.ZERO); |
| | | cdnFlows.setFlownameId(26); |
| | | cdnFlows.setCreateTime(new Date()); |
| | | cdnFlows.setWalletId(6); |
| | | cdnFlows.setDate(new Date()); |
| | | cdnFlowService.save(cdnFlows); |
| | | id = cdnPAgentLevels.getId(); |
| | | flowPoint= cdnPAgentLevels.getFlowPoint(); |
| | | cdnUserWallets.setWalletId(6); |
| | | cdnUserWallets.setMoney(cdnUserWallets.getMoney().add(cdnFlows.getMoney())); |
| | | cdnUserWallets.setCreateTime(new Date()); |
| | | cdnUserWalletService.updateById(cdnUserWallets); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 加权分红(真实设备) |
| | | * 固定部分: 大区代理/省级代理/市区代理分别拿到0.5 |
| | | * 计算方式:各自团队业绩/所有代理团队总业绩 |
| | | * 极差部分:大区1.5%,省级1%,市区0.5% |
| | | */ |
| | | @XxlJob("executeWeightedDividend") |
| | | public void executeWeightedDividend(){ |
| | | Date now = new Date(); |
| | | logger.info("计算加权分红(自主上机)任务。。。"+DateUtil.format(now, "yyyy-MM-dd HH:mm:ss")); |
| | | //大区、省、市 |
| | | CdnTeamRelation cdns = new CdnTeamRelation(); |
| | | cdns.setAgentLevelId(3); |
| | | List<CdnTeamRelation> cdnTeamRelationLists = cdnTeamRelationService.selectByAgentLevelId(cdns); |
| | | // 今日总业绩 |
| | | List<CdnRelease> cdnReleaseList = cdnReleaseService.list(Wrappers.lambdaQuery(CdnRelease.class) |
| | | .eq(CdnRelease::getStatus, 1) |
| | | .eq(CdnRelease::getIsAct, 1) |
| | | .between(CdnRelease::getCreateTime, DateUtil.beginOfDay(DateUtil.yesterday()), DateUtil.endOfDay(DateUtil.yesterday()))); |
| | | if(cdnReleaseList.isEmpty()){ |
| | | return; |
| | | } |
| | | BigDecimal countMoney = cdnReleaseList.stream().map(CdnRelease::getMoney).reduce(BigDecimal.ZERO,BigDecimal::add); |
| | | //市级集合 |
| | | List<CdnTeamRelation> cityTeamRelationList = new ArrayList<>(); |
| | | //市级新增团队业绩之和 |
| | | BigDecimal cityMall = BigDecimal.ZERO; |
| | | //省级集合 |
| | | List<CdnTeamRelation> provinceTeamRelationList = new ArrayList<>(); |
| | | //省级今日新增团队业绩之和 |
| | | BigDecimal provinceMall = BigDecimal.ZERO; |
| | | //大区集合 |
| | | List<CdnTeamRelation> regionTeamRelationList = new ArrayList<>(); |
| | | //大区今日新增团队业绩之和 |
| | | BigDecimal regionMall = BigDecimal.ZERO; |
| | | |
| | | CdnFlow cdnFlow = new CdnFlow(); |
| | | |
| | | //循环所有市、省、大区用户 |
| | | for (CdnTeamRelation cdnTeamRelation :cdnTeamRelationLists) { |
| | | if (cdnTeamRelation.getTeamTodayQuantityOwn() == 0){ |
| | | continue; |
| | | } |
| | | CdnAgentLevel cdnPAgentLevel = cdnAgentLevelService.getById(cdnTeamRelation.getAgentLevelId()); |
| | | //省市 大区 分组 |
| | | if (cdnPAgentLevel.getName().indexOf("市级") >= 0) { |
| | | cityTeamRelationList.add(cdnTeamRelation); |
| | | cityMall = cityMall.add(BigDecimal.valueOf(cdnTeamRelation.getTeamTodayQuantityOwn())); |
| | | } else if (cdnPAgentLevel.getName().indexOf("省级") >= 0) { |
| | | provinceTeamRelationList.add(cdnTeamRelation); |
| | | provinceMall = provinceMall.add(BigDecimal.valueOf(cdnTeamRelation.getTeamTodayQuantityOwn())); |
| | | } else if (cdnPAgentLevel.getName().indexOf("大区") >= 0) { |
| | | regionTeamRelationList.add(cdnTeamRelation); |
| | | regionMall = regionMall.add(BigDecimal.valueOf(cdnTeamRelation.getTeamTodayQuantityOwn())); |
| | | } |
| | | } |
| | | // 获取所有今日新增自主设备不为空用户 |
| | | List<CdnTeamRelation> cdnTeamRelationList = cdnTeamRelationService.list(new LambdaQueryWrapper<CdnTeamRelation>() |
| | | .gt(CdnTeamRelation::getTodayQuantityOwn,0).orderByDesc(CdnTeamRelation::getSort)); |
| | | for (CdnTeamRelation cdnTeamRelation: cdnTeamRelationList){ |
| | | // 获取所有上级 |
| | | List<CdnTeamRelation> puser = cdnTeamRelationService.getUpLevel(cdnTeamRelation); |
| | | // 比例 |
| | | Integer agentLevel = 1; |
| | | BigDecimal rebate = BigDecimal.ZERO; |
| | | // 个人今日新增业绩数额 |
| | | List<CdnRelease> todayMallList = cdnReleaseService.list(Wrappers.lambdaQuery(CdnRelease.class) |
| | | .eq(CdnRelease::getStatus, 1) |
| | | .eq(CdnRelease::getIsAct, 1) |
| | | .eq(CdnRelease::getUserId, cdnTeamRelation.getUserId()) |
| | | .between(CdnRelease::getCreateTime, DateUtil.beginOfDay(DateUtil.yesterday()), DateUtil.endOfDay(DateUtil.yesterday()))); |
| | | if (todayMallList.isEmpty()) { |
| | | continue; |
| | | } |
| | | BigDecimal todayMallMoney = todayMallList.stream().map(CdnRelease::getMoney).reduce(BigDecimal.ZERO,BigDecimal::add); |
| | | for (CdnTeamRelation p : puser){ |
| | | BigDecimal price = BigDecimal.ZERO; |
| | | CdnAgentLevel pAgentLevel = cdnAgentLevelService.getById(p.getAgentLevelId()); |
| | | if (pAgentLevel.getId().compareTo(agentLevel) <= 0) { |
| | | continue; |
| | | } |
| | | if (pAgentLevel.getName().contains("市级") || pAgentLevel.getName().contains("省级") || pAgentLevel.getName().contains("大区")){ |
| | | price = todayMallMoney.multiply(pAgentLevel.getRebateReal().subtract(rebate)); |
| | | agentLevel = pAgentLevel.getId(); |
| | | rebate = pAgentLevel.getRebateReal(); |
| | | } |
| | | cdnFlow.setUserId(p.getUserId()); |
| | | cdnFlow.setFlownameId(22); |
| | | if(price.compareTo(BigDecimal.ZERO) <= 0){ |
| | | continue; |
| | | }else{ |
| | | cdnFlow.setMoney(price); |
| | | } |
| | | cdnFlow.setMemo("自主上级加权收益(级差部分)-->相关用户:" + cdnTeamRelation.getUserId()); |
| | | cdnFlow.setUserIds(cdnTeamRelation.getUserId()); |
| | | //红积分 |
| | | cdnFlow.setWalletId(6); |
| | | CdnUserWallet cdnUserWallet = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId,cdnTeamRelation.getUserId()) |
| | | .eq(CdnUserWallet::getWalletId,6)); |
| | | cdnFlow.setOldmoney(cdnUserWallet != null ? cdnUserWallet.getMoney() : BigDecimal.ZERO); |
| | | cdnFlow.setCreateTime(new Date()); |
| | | cdnFlow.setDate(new Date()); |
| | | cdnFlowService.save(cdnFlow); |
| | | cdnUserWallet.setMoney(cdnFlow.getOldmoney().add(cdnFlow.getMoney())); |
| | | cdnUserWallet.setUpdateTime(new Date()); |
| | | cdnUserWalletService.updateById(cdnUserWallet); |
| | | } |
| | | } |
| | | //省级代理 |
| | | if(provinceTeamRelationList.size() > 0 && provinceMall.compareTo(BigDecimal.ZERO) > 0){ |
| | | Double rebate = Double.valueOf(cdnConfigService.selectValueByName("province_rebate")); |
| | | BigDecimal provinceMoney = countMoney.multiply(BigDecimal.valueOf(rebate)); |
| | | for (CdnTeamRelation teamRelation : provinceTeamRelationList){ |
| | | BigDecimal num = BigDecimal.valueOf(teamRelation.getTeamTodayQuantityOwn()).divide(provinceMall,4, RoundingMode.HALF_UP); |
| | | BigDecimal totalPrice = provinceMoney.multiply(num); |
| | | cdnFlow.setUserId(teamRelation.getUserId()); |
| | | cdnFlow.setFlownameId(22); |
| | | if(totalPrice.compareTo(BigDecimal.ZERO) <= 0){ |
| | | continue; |
| | | }else{ |
| | | cdnFlow.setMoney(totalPrice); |
| | | } |
| | | cdnFlow.setMemo("自主上级加权收益(固定部分)"); |
| | | //红积分 |
| | | cdnFlow.setWalletId(6); |
| | | CdnUserWallet cdnUserWallet = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId,teamRelation.getUserId()) |
| | | .eq(CdnUserWallet::getWalletId,6)); |
| | | cdnFlow.setOldmoney(cdnUserWallet != null ? cdnUserWallet.getMoney() : BigDecimal.ZERO); |
| | | cdnFlow.setCreateTime(new Date()); |
| | | cdnFlow.setDate(new Date()); |
| | | cdnFlowService.save(cdnFlow); |
| | | cdnUserWallet.setMoney(cdnFlow.getOldmoney().add(cdnFlow.getMoney())); |
| | | cdnUserWallet.setUpdateTime(new Date()); |
| | | cdnUserWalletService.updateById(cdnUserWallet); |
| | | } |
| | | } |
| | | //大区代理 |
| | | if(regionTeamRelationList.size() > 0 && regionMall.compareTo(BigDecimal.ZERO) > 0){ |
| | | Double rebate = Double.valueOf(cdnConfigService.selectValueByName("region_rebate")); |
| | | BigDecimal regionMoney = countMoney.multiply(BigDecimal.valueOf(rebate)); |
| | | for (CdnTeamRelation teamRelation : regionTeamRelationList){ |
| | | BigDecimal num = BigDecimal.valueOf(teamRelation.getTeamTodayQuantityOwn()).divide(regionMall,4, RoundingMode.HALF_UP); |
| | | BigDecimal totalPrice = regionMoney.multiply(num); |
| | | cdnFlow.setUserId(teamRelation.getUserId()); |
| | | cdnFlow.setFlownameId(22); |
| | | if(totalPrice.compareTo(BigDecimal.ZERO) <= 0){ |
| | | continue; |
| | | }else{ |
| | | cdnFlow.setMoney(totalPrice); |
| | | } |
| | | cdnFlow.setMemo("自主上级加权收益(固定部分)"); |
| | | //红积分 |
| | | cdnFlow.setWalletId(6); |
| | | CdnUserWallet cdnUserWallet = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId,teamRelation.getUserId()) |
| | | .eq(CdnUserWallet::getWalletId,6)); |
| | | cdnFlow.setOldmoney(cdnUserWallet != null ? cdnUserWallet.getMoney() : BigDecimal.ZERO); |
| | | cdnFlow.setCreateTime(new Date()); |
| | | cdnFlow.setDate(new Date()); |
| | | cdnFlowService.save(cdnFlow); |
| | | cdnUserWallet.setMoney(cdnFlow.getOldmoney().add(cdnFlow.getMoney())); |
| | | cdnUserWallet.setUpdateTime(new Date()); |
| | | cdnUserWalletService.updateById(cdnUserWallet); |
| | | } |
| | | } |
| | | //市级代理 |
| | | if(cityTeamRelationList.size() > 0 && cityMall.compareTo(BigDecimal.ZERO) > 0){ |
| | | Double rebate = Double.valueOf(cdnConfigService.selectValueByName("city_rebate")); |
| | | BigDecimal cityMoney = countMoney.multiply(BigDecimal.valueOf(rebate)); |
| | | for (CdnTeamRelation teamRelation : cityTeamRelationList){ |
| | | BigDecimal num = BigDecimal.valueOf(teamRelation.getTeamTodayQuantityOwn()).divide(cityMall,4, RoundingMode.HALF_UP); |
| | | BigDecimal totalPrice = cityMoney.multiply(num); |
| | | cdnFlow.setUserId(teamRelation.getUserId()); |
| | | cdnFlow.setFlownameId(22); |
| | | if(totalPrice.compareTo(BigDecimal.ZERO) <= 0){ |
| | | continue; |
| | | }else{ |
| | | cdnFlow.setMoney(totalPrice); |
| | | } |
| | | cdnFlow.setMemo("自主上级加权收益(固定部分)"); |
| | | //红积分 |
| | | cdnFlow.setWalletId(6); |
| | | CdnUserWallet cdnUserWallet = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class) |
| | | .eq(CdnUserWallet::getUserId,teamRelation.getUserId()) |
| | | .eq(CdnUserWallet::getWalletId,6)); |
| | | cdnFlow.setOldmoney(cdnUserWallet != null ? cdnUserWallet.getMoney() : BigDecimal.ZERO); |
| | | cdnFlow.setCreateTime(new Date()); |
| | | cdnFlow.setDate(new Date()); |
| | | cdnFlowService.save(cdnFlow); |
| | | cdnUserWallet.setMoney(cdnFlow.getOldmoney().add(cdnFlow.getMoney())); |
| | | cdnUserWallet.setUpdateTime(new Date()); |
| | | cdnUserWalletService.updateById(cdnUserWallet); |
| | | } |
| | | } |
| | | // cdnTeamRelationService.updateTodayOwnQuantity(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * SN释放的时候 先购买的先释放 |
| | | * @param userId |
| | | * @param price |
| | | */ |
| | | public void updateResouce(String userId,BigDecimal price){ |
| | | if(price.compareTo(BigDecimal.ZERO) == 0){ |
| | | List<CdnRelease> list = cdnReleaseService.list(new LambdaQueryWrapper<CdnRelease>().eq(CdnRelease::getUserId,userId).eq(CdnRelease::getStatus,1)); |
| | | for (CdnRelease cdnRelease :list){ |
| | | cdnRelease.setBalance(BigDecimal.valueOf(0.00)); |
| | | cdnRelease.setStatus(0); |
| | | cdnReleaseService.updateById(cdnRelease); |
| | | updateTmall(userId,cdnRelease.getNum()); |
| | | } |
| | | }else{ |
| | | List<CdnRelease> list = cdnReleaseService.list(new LambdaQueryWrapper<CdnRelease>().eq(CdnRelease::getUserId,userId).eq(CdnRelease::getStatus,1).orderByAsc(CdnRelease::getCreateTime)); |
| | | for (CdnRelease cdnRelease :list){ |
| | | if(cdnRelease.getBalance().compareTo(price) > 0){ |
| | | cdnRelease.setBalance(cdnRelease.getBalance().subtract(price)); |
| | | cdnReleaseService.updateById(cdnRelease); |
| | | break; |
| | | }else if(cdnRelease.getBalance().compareTo(price) == 0){ |
| | | cdnRelease.setBalance(BigDecimal.valueOf(0.00)); |
| | | cdnRelease.setStatus(0); |
| | | cdnReleaseService.updateById(cdnRelease); |
| | | updateTmall(userId,cdnRelease.getNum()); |
| | | break; |
| | | }else{ |
| | | cdnRelease.setBalance(BigDecimal.valueOf(0.00)); |
| | | cdnRelease.setStatus(0); |
| | | cdnReleaseService.updateById(cdnRelease); |
| | | updateTmall(userId,cdnRelease.getNum()); |
| | | //updateResouce(userId,price.subtract(cdnRelease.getBalance())); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 释放后减少个人业绩和团队业绩 |
| | | * @param userId |
| | | * @param num |
| | | */ |
| | | public void updateTmall(String userId,Integer num){ |
| | | CdnTeamRelation cdnTeamRelation = cdnTeamRelationService.geteamRelationByUserId(userId); |
| | | if (cdnTeamRelation != null) { |
| | | //减去个人业绩 |
| | | cdnTeamRelation.setMeall(cdnTeamRelation.getMeall().subtract(BigDecimal.valueOf(num))); |
| | | cdnTeamRelationService.updateById(cdnTeamRelation); |
| | | if(StringUtils.isNotBlank(cdnTeamRelation.getPids())){ |
| | | String[] pids = cdnTeamRelation.getPids().split(","); |
| | | for (String pid : pids) { |
| | | if (StringUtils.isNotBlank(pid)) { |
| | | CdnTeamRelation cdnTeamRelation1 = cdnTeamRelationService.geteamRelationByUserId(pid); |
| | | cdnTeamRelation1.setTeamall(cdnTeamRelation1.getTeamall().subtract(BigDecimal.valueOf(num))); |
| | | cdnTeamRelationService.updateById(cdnTeamRelation1); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.platform.task; |
| | | |
| | | import cn.hutool.core.date.DateUtil; |
| | | import com.google.gson.Gson; |
| | | import com.yami.shop.bean.model.V1Box; |
| | | import com.yami.shop.bean.model.V1BoxIncome; |
| | | import com.yami.shop.bean.response.*; |
| | | import com.yami.shop.cdn.common.utils.CdnUtils; |
| | | import com.yami.shop.cdn.common.vo.CdnVo; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.dao.V1BoxIncomeMapper; |
| | | import com.yami.shop.service.SysConfigService; |
| | | import com.yami.shop.service.V1BoxIncomeService; |
| | | import com.yami.shop.service.V1BoxService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import ma.glasnost.orika.MapperFacade; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.io.IOException; |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | import java.util.Date; |
| | | |
| | | @Slf4j |
| | | @Component |
| | | public class V1BoxTask { |
| | | private final Logger logger = LoggerFactory.getLogger(this.getClass()); |
| | | |
| | | @Autowired |
| | | private V1BoxService v1BoxService; |
| | | @Autowired |
| | | private V1BoxIncomeService v1BoxIncomeService; |
| | | @Autowired |
| | | private V1BoxIncomeMapper v1BoxIncomeMapper; |
| | | @Autowired |
| | | private SysConfigService sysConfigService; |
| | | @Autowired |
| | | private MapperFacade mapperFacade; |
| | | |
| | | |
| | | /** |
| | | * 每10分钟拉取盒子列表 |
| | | */ |
| | | // @Scheduled(cron = "0 * * * * ?") |
| | | // @XxlJob("pullAllUserV1Boxes") |
| | | public void pullV1BoxList() throws IOException { |
| | | Date now = new Date(); |
| | | logger.info("拉取盒子列表。。。"+ DateUtil.format(now, "yyyy-MM-dd HH:mm:ss")); |
| | | String value = sysConfigService.getValue(Constant.CDN_CONFIG); |
| | | Gson gson = new Gson(); |
| | | CdnVo cdnVo = gson.fromJson(value, CdnVo.class); |
| | | CdnApiResponse<CdnBoxesResponse> boxes = CdnUtils.getBoxesToPost(null, null, null, null, null, null, null, null, null, null, cdnVo); |
| | | if (boxes.getCode() == 200) { |
| | | CdnBoxesResponse data = boxes.getData(); |
| | | if (data.getTotal() != null && !data.getTotal().equals("0")) { |
| | | for (CdnBoxesResponse.V1BoxInfo item : data.getBoxes()) { |
| | | V1Box box = v1BoxService.getById(item.getBoxId()); |
| | | if (box == null) { |
| | | V1Box v1Box = mapperFacade.map(item, V1Box.class); |
| | | v1Box.setCreateTime(now); |
| | | v1BoxService.save(v1Box); |
| | | } else { |
| | | V1Box v1Box = mapperFacade.map(item, V1Box.class); |
| | | v1Box.setUpdateTime(now); |
| | | v1BoxService.updateById(v1Box); |
| | | } |
| | | } |
| | | } |
| | | logger.info("拉取盒子列表完成... {}", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 每日拉取盒子收益 |
| | | */ |
| | | // @Scheduled(cron = "0 * * * * ?") |
| | | // @XxlJob("pullYesterdayIncome") |
| | | public void pullV1BoxIncome() throws IOException { |
| | | Date now = new Date(); |
| | | logger.info("拉取盒子收益。。。"+ DateUtil.format(now, "yyyy-MM-dd HH:mm:ss")); |
| | | LocalDate today = LocalDate.now(); |
| | | LocalDate yesterday = today.minusDays(7); |
| | | String value = sysConfigService.getValue(Constant.CDN_CONFIG); |
| | | Gson gson = new Gson(); |
| | | CdnVo cdnVo = gson.fromJson(value, CdnVo.class); |
| | | CdnApiResponse<CdnSingleEarningsResponse> boxIncomeToPost = CdnUtils.getBoxIncomeToPost(null, null, null,yesterday.toString() ,today.toString(), cdnVo); |
| | | if (boxIncomeToPost.getCode() == 200) { |
| | | CdnSingleEarningsResponse data = boxIncomeToPost.getData(); |
| | | if (data.getTotal() != null && !data.getTotal().equals("0")) { |
| | | for (CdnSingleEarningsResponse.V1SupplierIncomeV2ResponseItem item : data.getList()) { |
| | | V1BoxIncome map = new V1BoxIncome(); |
| | | map.setBoxId(item.getBoxId()); |
| | | map.setSupplierBoxId(item.getSupplierBoxId()); |
| | | map.setDate(item.getDate()); |
| | | Double amount = Double.valueOf(item.getAmount()); |
| | | map.setAmount(BigDecimal.valueOf(amount / 100)); |
| | | map.setCreateTime(now); |
| | | v1BoxIncomeService.save(map); |
| | | } |
| | | } |
| | | logger.info("拉取盒子收益完成... {}", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | server: |
| | | port: 8088 |
| | | spring: |
| | | datasource: |
| | | url: jdbc:mysql://192.168.1.119:40006/dev_liuliangniu?allowMultiQueries=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true |
| | | username: root |
| | | password: root |
| | | driver-class-name: com.mysql.cj.jdbc.Driver |
| | | type: com.zaxxer.hikari.HikariDataSource |
| | | hikari: |
| | | minimum-idle: 0 |
| | | maximum-pool-size: 20 |
| | | idle-timeout: 10000 |
| | | auto-commit: true |
| | | connection-test-query: SELECT 1 |
| | | redis: |
| | | host: 192.168.1.119 |
| | | port: 6379 |
| | | database: 10 |
| | | password: QpZq2&uX3c |
| | | logging: |
| | | config: classpath:logback-spring.xml |
| | | elastic: |
| | | address: http://127.0.0.1:9200 |
| | | index: product_test |
| | | |
| | | xxl-job: |
| | | accessToken: default_token |
| | | logPath: /data/applogs/xxl-job/jobhandler |
| | | admin: |
| | | addresses: http://127.0.0.1:8080/xxl-job-admin |
New file |
| | |
| | | server: |
| | | port: 8114 |
| | | spring: |
| | | datasource: |
| | | url: jdbc:mysql://${MYSQL_HOST:mall4j-mysql}:${MYSQL_PORT:3306}/${MYSQL_DATABASE:yami_bbc}?allowMultiQueries=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true |
| | | username: ${MYSQL_USERNAME:root} |
| | | password: ${MYSQL_PASSWORD:root} |
| | | driver-class-name: com.mysql.cj.jdbc.Driver |
| | | type: com.zaxxer.hikari.HikariDataSource |
| | | hikari: |
| | | minimum-idle: 0 |
| | | maximum-pool-size: 20 |
| | | idle-timeout: 25000 |
| | | auto-commit: true |
| | | connection-test-query: select 1 |
| | | redis: |
| | | host: ${REDIS_HOST} |
| | | port: ${REDIS_PORT} |
| | | database: ${REDIS_DATABASE:0} |
| | | logging: |
| | | config: classpath:logback/logback-docker.xml |
| | | elastic: |
| | | address: ${ELASTIC_ADDRESS:http://mall4j-elasticsearch:9200} |
| | | xxl-job: |
| | | accessToken: ${XXL_JOB_ACCESS_TOKEN:default_token} |
| | | logPath: ${XXL_JOB_LOG_PATH:/data/applogs/xxl-job/jobhandler} |
| | | admin: |
| | | addresses: ${XXL_JOB_ADDRESS:http://mall4j-job:8080/xxl-job-admin} |
| | | |
| | | management: |
| | | endpoint: |
| | | health: |
| | | probes: |
| | | enabled: true |
| | | endpoints: |
| | | web: |
| | | exposure: |
| | | include: health,startup |
New file |
| | |
| | | server: |
| | | port: 8088 |
| | | spring: |
| | | datasource: |
| | | url: jdbc:mysql://192.168.0.174:3306/yami_bbc?allowMultiQueries=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true |
| | | username: root |
| | | password: ggy6688. |
| | | driver-class-name: com.mysql.cj.jdbc.Driver |
| | | type: com.zaxxer.hikari.HikariDataSource |
| | | hikari: |
| | | minimum-idle: 0 |
| | | maximum-pool-size: 100 |
| | | idle-timeout: 10000 |
| | | auto-commit: true |
| | | connection-test-query: select 1 |
| | | redis: |
| | | host: 192.168.0.171 |
| | | port: 6379 |
| | | password: 'QpZq2&uX3c' |
| | | logging: |
| | | config: classpath:logback-spring.xml |
| | | |
| | | elastic: |
| | | address: http://192.168.0.171:9200 |
| | | index: product |
| | | |
| | | image: |
| | | url: https://img.tbt.ink/ |
| | | |
| | | xxl-job: |
| | | accessToken: default_token |
| | | logPath: /data/applogs/xxl-job/pcdn/jobhandler |
| | | admin: |
| | | addresses: http://192.168.0.171:8080/xxl-job-admin |
New file |
| | |
| | | server: |
| | | port: 8088 |
| | | spring: |
| | | datasource: |
| | | url: jdbc:mysql://192.168.0.174:3306/dev_liuliangniu?allowMultiQueries=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true |
| | | username: root |
| | | password: ggy6688. |
| | | driver-class-name: com.mysql.cj.jdbc.Driver |
| | | type: com.zaxxer.hikari.HikariDataSource |
| | | hikari: |
| | | minimum-idle: 0 |
| | | maximum-pool-size: 100 |
| | | idle-timeout: 10000 |
| | | auto-commit: true |
| | | connection-test-query: select 1 |
| | | redis: |
| | | host: 192.168.0.171 |
| | | port: 6379 |
| | | password: 'QpZq2&uX3c' |
| | | database: 12 |
| | | logging: |
| | | config: classpath:logback-spring-test.xml |
| | | |
| | | elastic: |
| | | address: http://192.168.0.171:9200 |
| | | index: product_test |
| | | |
| | | image: |
| | | url: https://img.tbt.ink/ |
| | | |
| | | xxl-job: |
| | | accessToken: default_token |
| | | logPath: /data/applogs/xxl-job/pcdn/jobhandler |
| | | admin: |
| | | addresses: http://192.168.0.171:8080/xxl-job-admin-test |
New file |
| | |
| | | spring: |
| | | # 环境 dev|prod|docker |
| | | profiles: |
| | | active: dev |
| | | #文件上传设置 |
| | | servlet: |
| | | multipart: |
| | | max-file-size: 100MB |
| | | max-request-size: 100MB |
| | | enabled: true |
| | | jackson: |
| | | date-format: yyyy-MM-dd HH:mm:ss |
| | | time-zone: GMT+8 |
| | | mvc: |
| | | pathmatch: |
| | | matching-strategy: ANT_PATH_MATCHER |
| | | # mybaits-plus配置 |
| | | mybatis-plus: |
| | | # MyBatis Mapper所对应的XML文件位置 |
| | | mapper-locations: classpath*:/mapper/*Mapper.xml |
| | | global-config: |
| | | # 关闭MP3.0自带的banner |
| | | banner: false |
| | | db-config: |
| | | # 主键类型 0:数据库ID自增 1.未定义 2.用户输入 3 id_worker 4.uuid 5.id_worker字符串表示 |
| | | id-type: AUTO |
| | | #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断" |
| | | field-strategy: NOT_NULL |
| | | # 默认数据库表下划线命名 |
| | | table-underline: true |
| | | type-aliases-package: com.yami.shop.bean.model |
| | | type-enums-package: com.yami.shop.bean.enums |
| | | #type-handlers-package: com.yami.shop.cdn.handler |
| | | configuration: |
| | | default-enum-type-handler: com.yami.shop.common.handler.EnumTypeHandler |
| | | server: |
| | | tomcat: |
| | | basedir: /Users/a123/Documents/UthinkJava/hxsl/temp |
| | | # 用于雪花算法生成id |
| | | application: |
| | | datacenterId: ${DATACENTER_ID:2} |
| | | workerId: ${WORKER_ID:1} |
New file |
| | |
| | | .----------------. .----------------. .----------------. .----------------. .----------------. .----------------. |
| | | | .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. | |
| | | | | ____ ____ | || | __ | || | _____ | || | _____ | || | _ _ | || | _____ | | |
| | | | ||_ \ / _|| || | / \ | || | |_ _| | || | |_ _| | || | | | | | | || | |_ _| | | |
| | | | | | \/ | | || | / /\ \ | || | | | | || | | | | || | | |__| |_ | || | | | | | |
| | | | | | |\ /| | | || | / ____ \ | || | | | _ | || | | | _ | || | |____ _| | || | _ | | | | |
| | | | | _| |_\/_| |_ | || | _/ / \ \_ | || | _| |__/ | | || | _| |__/ | | || | _| |_ | || | | |_' | | | |
| | | | ||_____||_____|| || ||____| |____|| || | |________| | || | |________| | || | |_____| | || | `.___.' | | |
| | | | | | || | | || | | || | | || | | || | | | |
| | | | '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' | |
| | | '----------------' '----------------' '----------------' '----------------' '----------------' '----------------' |
New file |
| | |
| | | -----BEGIN CERTIFICATE----- |
| | | MIIDsjCCApqgAwIBAgIQICQQEIkCIVfQHOHjNW3SLDANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UE |
| | | BhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNVBAsMF0NlcnRpZmljYXRpb24gQXV0 |
| | | aG9yaXR5MTkwNwYDVQQDDDBBbnQgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IENs |
| | | YXNzIDIgUjEwHhcNMjQxMDEwMDc0OTA3WhcNMjkxMDA5MDc0OTA3WjCBkjELMAkGA1UEBhMCQ04x |
| | | LTArBgNVBAoMJOS4iua1t+mXqOS5n+enkeaKgOiCoeS7veaciemZkOWFrOWPuDEPMA0GA1UECwwG |
| | | QWxpcGF5MUMwQQYDVQQDDDrmlK/ku5jlrp0o5Lit5Zu9Kee9kee7nOaKgOacr+aciemZkOWFrOWP |
| | | uC0yMDg4NzQxNjYzNTY4MTMwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAloXaafan |
| | | 0cDCkCdFFCV+1EBwJ/UYQvxHE2+jIXKngjGdD2n1voOcV3Xk7pe1CM/SjYNjcIrOgwWl2MmFktUR |
| | | Nzde8MNFHqhJ2xMUrECpvPQTNWAY4T2eflZmP14cePUPWtHUxnLsZpE/CqdgIJGhHkZijzPe9s9v |
| | | ZNyc8oqGqvXSUOho4Z0ajuwt8m5prlHB+Y2IBTOc78bqjGrCrK7H9RsqUCEz47l9lWkVkXn7DRLf |
| | | gfUcrCurydyg8tj18sEkYUL8KYjL5zWZ9x1UYzyDgLcmEVlMddImx8/Vrr4oQw8a0KqNqegRhM64 |
| | | SF0NXix8HKgQLvdK2zhsApjLy6rH3QIDAQABoxIwEDAOBgNVHQ8BAf8EBAMCA/gwDQYJKoZIhvcN |
| | | AQELBQADggEBAAM2ihX55ZsV7roXPz0oMc/CWoc7JmCpdriWNxHfyOjMcyKxBn9nJ3Oxr9gcr1wq |
| | | bGkW+1oTsikUDBaxvQ+nF5OPRfmY+GDajRDHp0MzeQ7KZzR9sk2r4Ru22kYSx0yMUvyIP+f9sIyw |
| | | 8WcnWBGD37jibxURGhqLB9srjMWieYtSTDli6Oy/H3yngk/ww7iYmBRA67T4OcEwKEVj0gCSMhpl |
| | | hj/Wv8ICk1hUGuNKMUlig+H9EHOogKsJVUCAntyxbIwbYktUcsF7QaWiU5bo1+VnSrgLtI9n3gbA |
| | | aFAPyB/kKT6uI9Cymvo3rK5HlbHXJLU6MCgcsvLWqNl9oehznuw= |
| | | -----END CERTIFICATE----- |
| | | -----BEGIN CERTIFICATE----- |
| | | MIIE4jCCAsqgAwIBAgIIYsSr5bKAMl8wDQYJKoZIhvcNAQELBQAwejELMAkGA1UEBhMCQ04xFjAU |
| | | BgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNVBAsMF0NlcnRpZmljYXRpb24gQXV0aG9yaXR5MTEw |
| | | LwYDVQQDDChBbnQgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFIxMB4XDTE4MDMy |
| | | MjE0MzQxNVoXDTM3MTEyNjE0MzQxNVowgYIxCzAJBgNVBAYTAkNOMRYwFAYDVQQKDA1BbnQgRmlu |
| | | YW5jaWFsMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTE5MDcGA1UEAwwwQW50IEZp |
| | | bmFuY2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBDbGFzcyAyIFIxMIIBIjANBgkqhkiG9w0B |
| | | AQEFAAOCAQ8AMIIBCgKCAQEAsLMfYaoRoPRbmDcAfXPCmKf43pWRN5yTXa/KJWO0l+mrgQvs89bA |
| | | NEvbDUxlkGwycwtwi5DgBuBgVhLliXu+R9CYgr2dXs8D8Hx/gsggDcyGPLmVrDOnL+dyeauheARZ |
| | | fA3du60fwEwwbGcVIpIxPa/4n3IS/ElxQa6DNgqxh8J9Xwh7qMGl0JK9+bALuxf7B541Gr4p0WEN |
| | | G8fhgjBV4w4ut9eQLOoa1eddOUSZcy46Z7allwowwgt7b5VFfx/P1iKJ3LzBMgkCK7GZ2kiLrL7R |
| | | iqV+h482J7hkJD+ardoc6LnrHO/hIZymDxok+VH9fVeUdQa29IZKrIDVj65THQIDAQABo2MwYTAf |
| | | BgNVHSMEGDAWgBRfdLQEwE8HWurlsdsio4dBspzhATAdBgNVHQ4EFgQUSqHkYINtUSAtDPnS8Xoy |
| | | oP9p7qEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIB |
| | | AIQ8TzFy4bVIVb8+WhHKCkKNPcJe2EZuIcqvRoi727lZTJOfYy/JzLtckyZYfEI8J0lasZ29wkTt |
| | | a1IjSo+a6XdhudU4ONVBrL70U8Kzntplw/6TBNbLFpp7taRALjUgbCOk4EoBMbeCL0GiYYsTS0mw |
| | | 7xdySzmGQku4GTyqutIGPQwKxSj9iSFw1FCZqr4VP4tyXzMUgc52SzagA6i7AyLedd3tbS6lnR5B |
| | | L+W9Kx9hwT8L7WANAxQzv/jGldeuSLN8bsTxlOYlsdjmIGu/C9OWblPYGpjQQIRyvs4Cc/mNhrh+ |
| | | 14EQgwuemIIFDLOgcD+iISoN8CqegelNcJndFw1PDN6LkVoiHz9p7jzsge8RKay/QW6C03KNDpWZ |
| | | EUCgCUdfHfo8xKeR+LL1cfn24HKJmZt8L/aeRZwZ1jwePXFRVtiXELvgJuM/tJDIFj2KD337iV64 |
| | | fWcKQ/ydDVGqfDZAdcU4hQdsrPWENwPTQPfVPq2NNLMyIH9+WKx9Ed6/WzeZmIy5ZWpX1TtTolo6 |
| | | OJXQFeItMAjHxW/ZSZTok5IS3FuRhExturaInnzjYpx50a6kS34c5+c8hYq7sAtZ/CNLZmBnBCFD |
| | | aMQqT8xFZJ5uolUaSeXxg7JFY1QsYp5RKvj4SjFwCGKJ2+hPPe9UyyltxOidNtxjaknOCeBHytOr |
| | | -----END CERTIFICATE----- |
New file |
| | |
| | | -----BEGIN CERTIFICATE----- |
| | | MIIBszCCAVegAwIBAgIIaeL+wBcKxnswDAYIKoEcz1UBg3UFADAuMQswCQYDVQQG |
| | | EwJDTjEOMAwGA1UECgwFTlJDQUMxDzANBgNVBAMMBlJPT1RDQTAeFw0xMjA3MTQw |
| | | MzExNTlaFw00MjA3MDcwMzExNTlaMC4xCzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVO |
| | | UkNBQzEPMA0GA1UEAwwGUk9PVENBMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE |
| | | MPCca6pmgcchsTf2UnBeL9rtp4nw+itk1Kzrmbnqo05lUwkwlWK+4OIrtFdAqnRT |
| | | V7Q9v1htkv42TsIutzd126NdMFswHwYDVR0jBBgwFoAUTDKxl9kzG8SmBcHG5Yti |
| | | W/CXdlgwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFEwysZfZ |
| | | MxvEpgXBxuWLYlvwl3ZYMAwGCCqBHM9VAYN1BQADSAAwRQIgG1bSLeOXp3oB8H7b |
| | | 53W+CKOPl2PknmWEq/lMhtn25HkCIQDaHDgWxWFtnCrBjH16/W3Ezn7/U/Vjo5xI |
| | | pDoiVhsLwg== |
| | | -----END CERTIFICATE----- |
| | | |
| | | -----BEGIN CERTIFICATE----- |
| | | MIIF0zCCA7ugAwIBAgIIH8+hjWpIDREwDQYJKoZIhvcNAQELBQAwejELMAkGA1UE |
| | | BhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNVBAsMF0NlcnRpZmlj |
| | | YXRpb24gQXV0aG9yaXR5MTEwLwYDVQQDDChBbnQgRmluYW5jaWFsIENlcnRpZmlj |
| | | YXRpb24gQXV0aG9yaXR5IFIxMB4XDTE4MDMyMTEzNDg0MFoXDTM4MDIyODEzNDg0 |
| | | MFowejELMAkGA1UEBhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNV |
| | | BAsMF0NlcnRpZmljYXRpb24gQXV0aG9yaXR5MTEwLwYDVQQDDChBbnQgRmluYW5j |
| | | aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFIxMIICIjANBgkqhkiG9w0BAQEF |
| | | AAOCAg8AMIICCgKCAgEAtytTRcBNuur5h8xuxnlKJetT65cHGemGi8oD+beHFPTk |
| | | rUTlFt9Xn7fAVGo6QSsPb9uGLpUFGEdGmbsQ2q9cV4P89qkH04VzIPwT7AywJdt2 |
| | | xAvMs+MgHFJzOYfL1QkdOOVO7NwKxH8IvlQgFabWomWk2Ei9WfUyxFjVO1LVh0Bp |
| | | dRBeWLMkdudx0tl3+21t1apnReFNQ5nfX29xeSxIhesaMHDZFViO/DXDNW2BcTs6 |
| | | vSWKyJ4YIIIzStumD8K1xMsoaZBMDxg4itjWFaKRgNuPiIn4kjDY3kC66Sl/6yTl |
| | | YUz8AybbEsICZzssdZh7jcNb1VRfk79lgAprm/Ktl+mgrU1gaMGP1OE25JCbqli1 |
| | | Pbw/BpPynyP9+XulE+2mxFwTYhKAwpDIDKuYsFUXuo8t261pCovI1CXFzAQM2w7H |
| | | DtA2nOXSW6q0jGDJ5+WauH+K8ZSvA6x4sFo4u0KNCx0ROTBpLif6GTngqo3sj+98 |
| | | SZiMNLFMQoQkjkdN5Q5g9N6CFZPVZ6QpO0JcIc7S1le/g9z5iBKnifrKxy0TQjtG |
| | | PsDwc8ubPnRm/F82RReCoyNyx63indpgFfhN7+KxUIQ9cOwwTvemmor0A+ZQamRe |
| | | 9LMuiEfEaWUDK+6O0Gl8lO571uI5onYdN1VIgOmwFbe+D8TcuzVjIZ/zvHrAGUcC |
| | | AwEAAaNdMFswCwYDVR0PBAQDAgEGMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFF90 |
| | | tATATwda6uWx2yKjh0GynOEBMB8GA1UdIwQYMBaAFF90tATATwda6uWx2yKjh0Gy |
| | | nOEBMA0GCSqGSIb3DQEBCwUAA4ICAQCVYaOtqOLIpsrEikE5lb+UARNSFJg6tpkf |
| | | tJ2U8QF/DejemEHx5IClQu6ajxjtu0Aie4/3UnIXop8nH/Q57l+Wyt9T7N2WPiNq |
| | | JSlYKYbJpPF8LXbuKYG3BTFTdOVFIeRe2NUyYh/xs6bXGr4WKTXb3qBmzR02FSy3 |
| | | IODQw5Q6zpXj8prYqFHYsOvGCEc1CwJaSaYwRhTkFedJUxiyhyB5GQwoFfExCVHW |
| | | 05ZFCAVYFldCJvUzfzrWubN6wX0DD2dwultgmldOn/W/n8at52mpPNvIdbZb2F41 |
| | | T0YZeoWnCJrYXjq/32oc1cmifIHqySnyMnavi75DxPCdZsCOpSAT4j4lAQRGsfgI |
| | | kkLPGQieMfNNkMCKh7qjwdXAVtdqhf0RVtFILH3OyEodlk1HYXqX5iE5wlaKzDop |
| | | PKwf2Q3BErq1xChYGGVS+dEvyXc/2nIBlt7uLWKp4XFjqekKbaGaLJdjYP5b2s7N |
| | | 1dM0MXQ/f8XoXKBkJNzEiM3hfsU6DOREgMc1DIsFKxfuMwX3EkVQM1If8ghb6x5Y |
| | | jXayv+NLbidOSzk4vl5QwngO/JYFMkoc6i9LNwEaEtR9PhnrdubxmrtM+RjfBm02 |
| | | 77q3dSWFESFQ4QxYWew4pHE0DpWbWy/iMIKQ6UZ5RLvB8GEcgt8ON7BBJeMc+Dyi |
| | | kT9qhqn+lw== |
| | | -----END CERTIFICATE----- |
| | | |
| | | -----BEGIN CERTIFICATE----- |
| | | MIICiDCCAgygAwIBAgIIQX76UsB/30owDAYIKoZIzj0EAwMFADB6MQswCQYDVQQG |
| | | EwJDTjEWMBQGA1UECgwNQW50IEZpbmFuY2lhbDEgMB4GA1UECwwXQ2VydGlmaWNh |
| | | dGlvbiBBdXRob3JpdHkxMTAvBgNVBAMMKEFudCBGaW5hbmNpYWwgQ2VydGlmaWNh |
| | | dGlvbiBBdXRob3JpdHkgRTEwHhcNMTkwNDI4MTYyMDQ0WhcNNDkwNDIwMTYyMDQ0 |
| | | WjB6MQswCQYDVQQGEwJDTjEWMBQGA1UECgwNQW50IEZpbmFuY2lhbDEgMB4GA1UE |
| | | CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxMTAvBgNVBAMMKEFudCBGaW5hbmNp |
| | | YWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRTEwdjAQBgcqhkjOPQIBBgUrgQQA |
| | | IgNiAASCCRa94QI0vR5Up9Yr9HEupz6hSoyjySYqo7v837KnmjveUIUNiuC9pWAU |
| | | WP3jwLX3HkzeiNdeg22a0IZPoSUCpasufiLAnfXh6NInLiWBrjLJXDSGaY7vaokt |
| | | rpZvAdmjXTBbMAsGA1UdDwQEAwIBBjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBRZ |
| | | 4ZTgDpksHL2qcpkFkxD2zVd16TAfBgNVHSMEGDAWgBRZ4ZTgDpksHL2qcpkFkxD2 |
| | | zVd16TAMBggqhkjOPQQDAwUAA2gAMGUCMQD4IoqT2hTUn0jt7oXLdMJ8q4vLp6sg |
| | | wHfPiOr9gxreb+e6Oidwd2LDnC4OUqCWiF8CMAzwKs4SnDJYcMLf2vpkbuVE4dTH |
| | | Rglz+HGcTLWsFs4KxLsq7MuU+vJTBUeDJeDjdA== |
| | | -----END CERTIFICATE----- |
| | | |
| | | -----BEGIN CERTIFICATE----- |
| | | MIIDxTCCAq2gAwIBAgIUEMdk6dVgOEIS2cCP0Q43P90Ps5YwDQYJKoZIhvcNAQEF |
| | | BQAwajELMAkGA1UEBhMCQ04xEzARBgNVBAoMCmlUcnVzQ2hpbmExHDAaBgNVBAsM |
| | | E0NoaW5hIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMMH2lUcnVzQ2hpbmEgQ2xhc3Mg |
| | | MiBSb290IENBIC0gRzMwHhcNMTMwNDE4MDkzNjU2WhcNMzMwNDE4MDkzNjU2WjBq |
| | | MQswCQYDVQQGEwJDTjETMBEGA1UECgwKaVRydXNDaGluYTEcMBoGA1UECwwTQ2hp |
| | | bmEgVHJ1c3QgTmV0d29yazEoMCYGA1UEAwwfaVRydXNDaGluYSBDbGFzcyAyIFJv |
| | | b3QgQ0EgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOPPShpV |
| | | nJbMqqCw6Bz1kehnoPst9pkr0V9idOwU2oyS47/HjJXk9Rd5a9xfwkPO88trUpz5 |
| | | 4GmmwspDXjVFu9L0eFaRuH3KMha1Ak01citbF7cQLJlS7XI+tpkTGHEY5pt3EsQg |
| | | wykfZl/A1jrnSkspMS997r2Gim54cwz+mTMgDRhZsKK/lbOeBPpWtcFizjXYCqhw |
| | | WktvQfZBYi6o4sHCshnOswi4yV1p+LuFcQ2ciYdWvULh1eZhLxHbGXyznYHi0dGN |
| | | z+I9H8aXxqAQfHVhbdHNzi77hCxFjOy+hHrGsyzjrd2swVQ2iUWP8BfEQqGLqM1g |
| | | KgWKYfcTGdbPB1MCAwEAAaNjMGEwHQYDVR0OBBYEFG/oAMxTVe7y0+408CTAK8hA |
| | | uTyRMB8GA1UdIwQYMBaAFG/oAMxTVe7y0+408CTAK8hAuTyRMA8GA1UdEwEB/wQF |
| | | MAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBLnUTfW7hp |
| | | emMbuUGCk7RBswzOT83bDM6824EkUnf+X0iKS95SUNGeeSWK2o/3ALJo5hi7GZr3 |
| | | U8eLaWAcYizfO99UXMRBPw5PRR+gXGEronGUugLpxsjuynoLQu8GQAeysSXKbN1I |
| | | UugDo9u8igJORYA+5ms0s5sCUySqbQ2R5z/GoceyI9LdxIVa1RjVX8pYOj8JFwtn |
| | | DJN3ftSFvNMYwRuILKuqUYSHc2GPYiHVflDh5nDymCMOQFcFG3WsEuB+EYQPFgIU |
| | | 1DHmdZcz7Llx8UOZXX2JupWCYzK1XhJb+r4hK5ncf/w8qGtYlmyJpxk3hr1TfUJX |
| | | Yf4Zr0fJsGuv |
| | | -----END CERTIFICATE----- |
New file |
| | |
| | | -----BEGIN CERTIFICATE----- |
| | | MIIEoDCCA4igAwIBAgIQICQQEIcEFUunEjP4U69f4TANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UE |
| | | BhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNVBAsMF0NlcnRpZmljYXRpb24gQXV0 |
| | | aG9yaXR5MTkwNwYDVQQDDDBBbnQgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IENs |
| | | YXNzIDEgUjEwHhcNMjQxMDEwMDc0OTA3WhcNMjkxMDA5MDc0OTA3WjBoMQswCQYDVQQGEwJDTjEt |
| | | MCsGA1UECgwk5LiK5rW36Zeo5Lmf56eR5oqA6IKh5Lu95pyJ6ZmQ5YWs5Y+4MQ8wDQYDVQQLDAZB |
| | | bGlwYXkxGTAXBgNVBAMMEDIwODg3NDE2NjM1NjgxMzAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw |
| | | ggEKAoIBAQCBrLbho5UUKIKed4JESnNxFhupfxuOV6OGOXgdxF60617NqS5CFmeGnhqJquN1/0wG |
| | | cSiA+4Eon6UPzYKu6q1UAt6xTuzyeHiPM01FoGyXhfU0nrmWX/YW9ZWrAEEajozNA1dMWXTYE317 |
| | | HXcrm4P6Jrc/W9Cv0vz2nsTsX/Qp8z/a8p5YpHihVCcRqmz/Nd/pZ7FCmXqI+8v57CCyA7UhXOVU |
| | | X8P6CH+p58wszL2vRUrE6QQtg53uk/pEfOVZVsvVMY+RAt63qvxzdnN9gMmUzqwSBMj/ICipiTv+ |
| | | GU+s75wfOlrw8AcinI+rjJDb2OBsQVWzzcCkg8Hc1Ja5vcjtAgMBAAGjggEpMIIBJTAfBgNVHSME |
| | | GDAWgBRxB+IEYRbk5fJl6zEPyeD0PJrVkTAdBgNVHQ4EFgQUnHWlZek3k5EJNug6uE3995ffZtsw |
| | | QAYDVR0gBDkwNzA1BgdggRwBbgEBMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9jYS5hbGlwYXkuY29t |
| | | L2Nwcy5wZGYwDgYDVR0PAQH/BAQDAgbAMC8GA1UdHwQoMCYwJKAioCCGHmh0dHA6Ly9jYS5hbGlw |
| | | YXkuY29tL2NybDk0LmNybDBgBggrBgEFBQcBAQRUMFIwKAYIKwYBBQUHMAKGHGh0dHA6Ly9jYS5h |
| | | bGlwYXkuY29tL2NhNi5jZXIwJgYIKwYBBQUHMAGGGmh0dHA6Ly9jYS5hbGlwYXkuY29tOjgzNDAv |
| | | MA0GCSqGSIb3DQEBCwUAA4IBAQCbf27KY3PWP1g1oCecxbIlBAKnjb4Ef0oj3gB+mphlZ/+kHcGl |
| | | chehBMWteZVFUt7od2G6RJh5sqF2lZWq9pvV/+7hK7RAqGLByH9Nj0qElO+449qINo1iYkVH+/H8 |
| | | L8U378w8dQ4xMM0FbY2LzHHSZYE7k3TBAsYJDvPz7IRvVGkTilh4PLIwwyv6+SFR5Wc7C5VzU9FM |
| | | cZjMtqxdEEhTVEafdt3MQrYQzB8MTnEMPjJiBafXBg+a7eUHZc7nixjZHAk7bb05JCuKQS4ylkx4 |
| | | 47VuqvYbZWyI2cchddP2fWn0wKHhq1fBKvCYr168BjHMtuOReIrVJ5DwlUi6iYdk |
| | | -----END CERTIFICATE----- |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <configuration debug="false"> |
| | | <!--定义日志文件的存储地址 --> |
| | | <property name="LOG_HOME" value="./logs/test" /> |
| | | |
| | | <logger name="m-shop-mybatis-sql" level="debug"></logger> |
| | | |
| | | <logger name="com.yami" level="DEBUG"/> |
| | | |
| | | <!--<property name="COLOR_PATTERN" value="%black(%contextName-) %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta( %replace(%caller{1}){'\t|Caller.{1}0|\r\n', ''})- %gray(%msg%xEx%n)" />--> |
| | | <!-- 控制台输出 --> |
| | | <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> |
| | | <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> |
| | | <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 |
| | | <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n</pattern>--> |
| | | <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{50}:%L) - %msg%n</pattern> |
| | | </encoder> |
| | | </appender> |
| | | |
| | | <!-- 按照每天生成日志文件 --> |
| | | <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| | | <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> |
| | | <!--日志文件输出的文件名 --> |
| | | <FileNamePattern>${LOG_HOME}/hxsl-platfprm-%d{yyyy-MM-dd}.%i.log</FileNamePattern> |
| | | <!--日志文件保留天数 --> |
| | | <MaxHistory>30</MaxHistory> |
| | | <maxFileSize>10MB</maxFileSize> |
| | | </rollingPolicy> |
| | | <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> |
| | | <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 --> |
| | | <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n</pattern> |
| | | </encoder> |
| | | </appender> |
| | | |
| | | <!-- 生成 error html格式日志开始 --> |
| | | <appender name="HTML" class="ch.qos.logback.core.FileAppender"> |
| | | <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> |
| | | <!--设置日志级别,过滤掉info日志,只输入error日志--> |
| | | <level>ERROR</level> |
| | | </filter> |
| | | <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> |
| | | <layout class="ch.qos.logback.classic.html.HTMLLayout"> |
| | | <pattern>%p%d%msg%M%F{32}%L</pattern> |
| | | </layout> |
| | | </encoder> |
| | | <file>${LOG_HOME}/hxsl-platfprm-error-log.html</file> |
| | | </appender> |
| | | <!-- 生成 error html格式日志结束 --> |
| | | |
| | | <!-- 每天生成一个html格式的日志开始 --> |
| | | <appender name="FILE_HTML" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| | | <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> |
| | | <!--日志文件输出的文件名 --> |
| | | <FileNamePattern>${LOG_HOME}/hxsl-platfprm-%d{yyyy-MM-dd}.%i.html</FileNamePattern> |
| | | <!--日志文件保留天数 --> |
| | | <MaxHistory>30</MaxHistory> |
| | | <MaxFileSize>10MB</MaxFileSize> |
| | | </rollingPolicy> |
| | | <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> |
| | | <layout class="ch.qos.logback.classic.html.HTMLLayout"> |
| | | <pattern>%p%d%msg%M%F{32}%L</pattern> |
| | | </layout> |
| | | </encoder> |
| | | </appender> |
| | | <!-- 每天生成一个html格式的日志结束 --> |
| | | |
| | | <!--myibatis log configure --> |
| | | <logger name="com.apache.ibatis" level="TRACE" /> |
| | | <logger name="java.sql.Connection" level="DEBUG" /> |
| | | <logger name="java.sql.Statement" level="DEBUG" /> |
| | | <logger name="java.sql.PreparedStatement" level="DEBUG" /> |
| | | |
| | | <!-- 日志输出级别 --> |
| | | <root level="INFO"> |
| | | <appender-ref ref="STDOUT" /> |
| | | <appender-ref ref="FILE" /> |
| | | <appender-ref ref="HTML" /> |
| | | <appender-ref ref="FILE_HTML" /> |
| | | </root> |
| | | |
| | | </configuration> |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <configuration debug="false"> |
| | | <!--定义日志文件的存储地址 --> |
| | | <property name="LOG_HOME" value="./logs" /> |
| | | |
| | | <logger name="m-shop-mybatis-sql" level="debug"></logger> |
| | | |
| | | <logger name="com.yami" level="DEBUG"/> |
| | | |
| | | <!--<property name="COLOR_PATTERN" value="%black(%contextName-) %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta( %replace(%caller{1}){'\t|Caller.{1}0|\r\n', ''})- %gray(%msg%xEx%n)" />--> |
| | | <!-- 控制台输出 --> |
| | | <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> |
| | | <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> |
| | | <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 |
| | | <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n</pattern>--> |
| | | <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{50}:%L) - %msg%n</pattern> |
| | | </encoder> |
| | | </appender> |
| | | |
| | | <!-- 按照每天生成日志文件 --> |
| | | <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| | | <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> |
| | | <!--日志文件输出的文件名 --> |
| | | <FileNamePattern>${LOG_HOME}/hxsl-platfprm-%d{yyyy-MM-dd}.%i.log</FileNamePattern> |
| | | <!--日志文件保留天数 --> |
| | | <MaxHistory>30</MaxHistory> |
| | | <maxFileSize>10MB</maxFileSize> |
| | | </rollingPolicy> |
| | | <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> |
| | | <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 --> |
| | | <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n</pattern> |
| | | </encoder> |
| | | </appender> |
| | | |
| | | <!-- 生成 error html格式日志开始 --> |
| | | <appender name="HTML" class="ch.qos.logback.core.FileAppender"> |
| | | <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> |
| | | <!--设置日志级别,过滤掉info日志,只输入error日志--> |
| | | <level>ERROR</level> |
| | | </filter> |
| | | <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> |
| | | <layout class="ch.qos.logback.classic.html.HTMLLayout"> |
| | | <pattern>%p%d%msg%M%F{32}%L</pattern> |
| | | </layout> |
| | | </encoder> |
| | | <file>${LOG_HOME}/hxsl-platfprm-error-log.html</file> |
| | | </appender> |
| | | <!-- 生成 error html格式日志结束 --> |
| | | |
| | | <!-- 每天生成一个html格式的日志开始 --> |
| | | <appender name="FILE_HTML" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| | | <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> |
| | | <!--日志文件输出的文件名 --> |
| | | <FileNamePattern>${LOG_HOME}/hxsl-platfprm-%d{yyyy-MM-dd}.%i.html</FileNamePattern> |
| | | <!--日志文件保留天数 --> |
| | | <MaxHistory>30</MaxHistory> |
| | | <MaxFileSize>10MB</MaxFileSize> |
| | | </rollingPolicy> |
| | | <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> |
| | | <layout class="ch.qos.logback.classic.html.HTMLLayout"> |
| | | <pattern>%p%d%msg%M%F{32}%L</pattern> |
| | | </layout> |
| | | </encoder> |
| | | </appender> |
| | | <!-- 每天生成一个html格式的日志结束 --> |
| | | |
| | | <!--myibatis log configure --> |
| | | <logger name="com.apache.ibatis" level="TRACE" /> |
| | | <logger name="java.sql.Connection" level="DEBUG" /> |
| | | <logger name="java.sql.Statement" level="DEBUG" /> |
| | | <logger name="java.sql.PreparedStatement" level="DEBUG" /> |
| | | |
| | | <!-- 日志输出级别 --> |
| | | <root level="INFO"> |
| | | <appender-ref ref="STDOUT" /> |
| | | <appender-ref ref="FILE" /> |
| | | <appender-ref ref="HTML" /> |
| | | <appender-ref ref="FILE_HTML" /> |
| | | </root> |
| | | |
| | | </configuration> |
New file |
| | |
| | | <configuration scan="true" scanPeriod="60 seconds" debug="false"> |
| | | |
| | | <include resource="org/springframework/boot/logging/logback/defaults.xml" /> |
| | | <include resource="org/springframework/boot/logging/logback/console-appender.xml" /> |
| | | |
| | | <root level="info"> |
| | | <appender-ref ref="CONSOLE" /> |
| | | </root> |
| | | |
| | | <logger name="com.yami.shop" level="debug"/> |
| | | <logger name="springfox.documentation.swagger2" level="off"/> |
| | | <logger name="io.swagger.models.parameters" level="off"/> |
| | | <logger name="springfox.documentation.swagger.readers.operation.OperationImplicitParameterReader" level="off"/> |
| | | <logger name="springfox.documentation.spring.web.readers.operation" level="off"/> |
| | | </configuration> |
New file |
| | |
| | | <configuration scan="true" scanPeriod="60 seconds" debug="false"> |
| | | <property name="PROJECT_PATH" value="/opt/projects/yami-b2b2c"/> |
| | | <property name="LOG_FILE_MAX_HISTORY" value="30"/> |
| | | <property name="LOG_FILE_MAX_SIZE" value="50MB"/> |
| | | |
| | | |
| | | <include resource="org/springframework/boot/logging/logback/defaults.xml" /> |
| | | <include resource="org/springframework/boot/logging/logback/console-appender.xml" /> |
| | | |
| | | <appender name="DefaultFile" |
| | | class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| | | <append>true</append> |
| | | <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> |
| | | <pattern>${FILE_LOG_PATTERN}</pattern> |
| | | <charset>UTF-8</charset> |
| | | </encoder> |
| | | <file>${PROJECT_PATH}/log/platform.log</file> |
| | | |
| | | <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> |
| | | <level>${logging.level}</level> |
| | | </filter> |
| | | <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> |
| | | <fileNamePattern>${PROJECT_PATH}/log/platform/%d{yyyy-MM}/platform-%d{yyyy-MM-dd}-%i.log.gz</fileNamePattern> |
| | | <maxFileSize>${LOG_FILE_MAX_SIZE}</maxFileSize> |
| | | <maxHistory>${LOG_FILE_MAX_HISTORY}</maxHistory> |
| | | </rollingPolicy> |
| | | </appender> |
| | | |
| | | <appender name="ScheduleFile" |
| | | class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| | | <append>true</append> |
| | | <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> |
| | | <pattern>${FILE_LOG_PATTERN}</pattern> |
| | | <charset>UTF-8</charset> |
| | | </encoder> |
| | | <file>${PROJECT_PATH}/log/schedule.log</file> |
| | | |
| | | <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> |
| | | <level>${logging.level}</level> |
| | | </filter> |
| | | <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> |
| | | <fileNamePattern>${PROJECT_PATH}/log/schedule/%d{yyyy-MM}/schedule-%d{yyyy-MM-dd}-%i.log.gz</fileNamePattern> |
| | | <maxFileSize>${LOG_FILE_MAX_SIZE}</maxFileSize> |
| | | <maxHistory>${LOG_FILE_MAX_HISTORY}</maxHistory> |
| | | </rollingPolicy> |
| | | </appender> |
| | | |
| | | <root level="info"> |
| | | <appender-ref ref="CONSOLE" /> |
| | | <appender-ref ref="DefaultFile" /> |
| | | </root> |
| | | |
| | | <logger name="com.yami.shop.sys.schedule" level="info" additivity="false"> |
| | | <appender-ref ref="ScheduleFile" /> |
| | | </logger> |
| | | |
| | | <logger name="com.yami.shop" level="debug"/> |
| | | <logger name="springfox.documentation.swagger2" level="off"/> |
| | | <logger name="io.swagger.models.parameters" level="off"/> |
| | | <logger name="springfox.documentation.swagger.readers.operation.OperationImplicitParameterReader" level="off"/> |
| | | <logger name="springfox.documentation.spring.web.readers.operation" level="off"/> |
| | | </configuration> |
New file |
| | |
| | | <configuration scan="true" scanPeriod="60 seconds" debug="false"> |
| | | <property name="PROJECT_PATH" value="/opt/projects/yami-b2b2c"/> |
| | | <property name="LOG_FILE_MAX_HISTORY" value="30"/> |
| | | <property name="LOG_FILE_MAX_SIZE" value="50MB"/> |
| | | |
| | | |
| | | <include resource="org/springframework/boot/logging/logback/defaults.xml" /> |
| | | <include resource="org/springframework/boot/logging/logback/console-appender.xml" /> |
| | | |
| | | <appender name="DefaultFile" |
| | | class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| | | <append>true</append> |
| | | <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> |
| | | <pattern>${FILE_LOG_PATTERN}</pattern> |
| | | <charset>UTF-8</charset> |
| | | </encoder> |
| | | <file>${PROJECT_PATH}/log/platform.log</file> |
| | | |
| | | <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> |
| | | <level>${logging.level}</level> |
| | | </filter> |
| | | <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> |
| | | <fileNamePattern>${PROJECT_PATH}/log/platform/%d{yyyy-MM}/platform-%d{yyyy-MM-dd}-%i.log.gz</fileNamePattern> |
| | | <maxFileSize>${LOG_FILE_MAX_SIZE}</maxFileSize> |
| | | <maxHistory>${LOG_FILE_MAX_HISTORY}</maxHistory> |
| | | </rollingPolicy> |
| | | </appender> |
| | | |
| | | <appender name="ScheduleFile" |
| | | class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| | | <append>true</append> |
| | | <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> |
| | | <pattern>${FILE_LOG_PATTERN}</pattern> |
| | | <charset>UTF-8</charset> |
| | | </encoder> |
| | | <file>${PROJECT_PATH}/log/schedule.log</file> |
| | | |
| | | <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> |
| | | <level>${logging.level}</level> |
| | | </filter> |
| | | <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> |
| | | <fileNamePattern>${PROJECT_PATH}/log/schedule/%d{yyyy-MM}/schedule-%d{yyyy-MM-dd}-%i.log.gz</fileNamePattern> |
| | | <maxFileSize>${LOG_FILE_MAX_SIZE}</maxFileSize> |
| | | <maxHistory>${LOG_FILE_MAX_HISTORY}</maxHistory> |
| | | </rollingPolicy> |
| | | </appender> |
| | | |
| | | <root level="info"> |
| | | <appender-ref ref="CONSOLE" /> |
| | | <appender-ref ref="DefaultFile" /> |
| | | </root> |
| | | |
| | | <logger name="com.yami.shop" level="debug"/> |
| | | <logger name="com.yami.shop.sys.schedule" level="info" additivity="false"> |
| | | <appender-ref ref="ScheduleFile" /> |
| | | </logger> |
| | | <logger name="springfox.documentation.swagger2" level="off"/> |
| | | <logger name="io.swagger.models.parameters" level="off"/> |
| | | <logger name="springfox.documentation.swagger.readers.operation.OperationImplicitParameterReader" level="off"/> |
| | | <logger name="springfox.documentation.spring.web.readers.operation" level="off"/> |
| | | |
| | | </configuration> |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <artifactId>yami-shop</artifactId> |
| | | <groupId>com.yami.shop</groupId> |
| | | <version>0.0.1-SNAPSHOT</version> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>yami-shop-search</artifactId> |
| | | <packaging>pom</packaging> |
| | | <modules> |
| | | <module>yami-shop-search-api</module> |
| | | <module>yami-shop-search-multishop</module> |
| | | <module>yami-shop-search-common</module> |
| | | <module>yami-shop-search-platform</module> |
| | | </modules> |
| | | |
| | | |
| | | </project> |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <artifactId>yami-shop-search</artifactId> |
| | | <groupId>com.yami.shop</groupId> |
| | | <version>0.0.1-SNAPSHOT</version> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>yami-shop-search-api</artifactId> |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.yami.shop</groupId> |
| | | <artifactId>yami-shop-search-common</artifactId> |
| | | <version>${yami.shop.version}</version> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.search.api.config; |
| | | |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import org.springdoc.core.GroupedOpenApi; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | /** |
| | | * @author Yami |
| | | */ |
| | | @Configuration("searchSwaggerConfiguration") |
| | | @AllArgsConstructor |
| | | public class SwaggerConfiguration { |
| | | |
| | | @Bean |
| | | public GroupedOpenApi searchRestApi() { |
| | | return GroupedOpenApi.builder() |
| | | .group("搜索接口") |
| | | .packagesToScan("com.yami.shop.search.api.controller") |
| | | .pathsToMatch("/**") |
| | | .build(); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.search.api.controller; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import com.yami.shop.bean.enums.ProdType; |
| | | import com.yami.shop.bean.event.EsProductActivityInfoEvent; |
| | | import com.yami.shop.bean.param.EsProductParam; |
| | | import com.yami.shop.bean.vo.search.EsProductSearchVO; |
| | | import com.yami.shop.bean.vo.search.ProductSearchVO; |
| | | import com.yami.shop.common.constants.CacheNames; |
| | | import com.yami.shop.common.constants.EsCacheNames; |
| | | import com.yami.shop.common.enums.EsRenovationProductSortEnum; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.handler.SensitiveHandler; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.RedisUtil; |
| | | import com.yami.shop.search.common.manager.ProductSearchManager; |
| | | import com.yami.shop.search.common.param.EsPageParam; |
| | | import com.yami.shop.search.common.service.SearchProductService; |
| | | import com.yami.shop.search.common.vo.EsPageVO; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.context.ApplicationEventPublisher; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | |
| | | /** |
| | | * 商品搜索 |
| | | * @author FrozenWatermelon |
| | | * @date 2020/11/16 |
| | | */ |
| | | @RestController("appSearchSpuController") |
| | | @RequestMapping("/search") |
| | | @Tag(name = "商品搜索接口") |
| | | public class ProductSearchController { |
| | | |
| | | @Autowired |
| | | private SearchProductService searchProductService; |
| | | @Autowired |
| | | private ApplicationEventPublisher eventPublisher; |
| | | @Autowired |
| | | private ProductSearchManager productSearchManager; |
| | | @Autowired |
| | | private SensitiveHandler sensitiveHandler; |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "商品搜索接口(仅商品信息)" , description = "商品搜索接口") |
| | | public ServerResponseEntity<EsPageVO<EsProductSearchVO>> page(@Valid EsPageParam pageParam,@ParameterObject EsProductParam productParam) { |
| | | // 敏感词 |
| | | if (Objects.nonNull(productParam.getKeyword()) && sensitiveHandler.isSensitive(productParam.getKeyword())){ |
| | | throw new YamiShopBindException("yami.sensitive.words.reenter"); |
| | | } |
| | | loadSearchProdType(productParam); |
| | | EsPageVO<EsProductSearchVO> esProductSearchVOEsPageVO = simplePage(pageParam, productParam); |
| | | return ServerResponseEntity.success(esProductSearchVOEsPageVO); |
| | | } |
| | | |
| | | @GetMapping("/renovationPage") |
| | | @Operation(summary = "商品信息列表(装修商品列表)" , description = "商品信息列表(装修商品列表)") |
| | | public ServerResponseEntity<EsPageVO<ProductSearchVO>> renovationPage(@Valid EsPageParam pageParam,@ParameterObject EsProductParam productParam) { |
| | | Long size = null; |
| | | if(Objects.equals(productParam.getShowSpuType(),1)){ |
| | | if(Objects.equals(productParam.getEsRenovationSpuSort(), EsRenovationProductSortEnum.CREATE_TIME_ASC.value()) || Objects.equals(productParam.getEsRenovationSpuSort(),EsRenovationProductSortEnum.CREATE_TIME_DESC.value())){ |
| | | productParam.setSort(productParam.getEsRenovationSpuSort()); |
| | | }else { |
| | | // 获取指定规则的商品ids |
| | | size = getSpuIds(pageParam, productParam); |
| | | } |
| | | } |
| | | EsPageVO<ProductSearchVO> searchPage = searchProductService.renovationPage(pageParam, productParam, size); |
| | | return ServerResponseEntity.success(searchPage); |
| | | } |
| | | |
| | | private Long getSpuIds(EsPageParam pageParam, EsProductParam productParam) { |
| | | Long shopId = Objects.isNull(productParam.getShopId()) ? 0L : productParam.getShopId(); |
| | | String key = EsCacheNames.RENOVATION_PRODUCT_IDS_CACHE + CacheNames.UNION + shopId + |
| | | CacheNames.UNION_KEY + productParam.getEsTimeRange() + CacheNames.UNION_KEY + productParam.getEsRenovationSpuSort(); |
| | | if(!RedisUtil.hasKey(key)){ |
| | | productSearchManager.addRenovationSpuCache(key,productParam,shopId, EsCacheNames.RENOVATION_PRODUCT_IDS_CACHE_TIME); |
| | | } |
| | | Long size = RedisUtil.getListSize(key); |
| | | long startNum = (long) (pageParam.getCurrent() - 1) * pageParam.getSize(); |
| | | long endNum = (long) pageParam.getCurrent() * pageParam.getSize() - 1; |
| | | endNum = Math.min(endNum,size); |
| | | List prodIds = RedisUtil.getListRange(key, startNum, endNum); |
| | | productParam.setProdIds(prodIds); |
| | | return size; |
| | | } |
| | | |
| | | private EsPageVO<EsProductSearchVO> simplePage(EsPageParam pageParam, EsProductParam productParam) { |
| | | loadSearchProdType(productParam); |
| | | EsPageVO<EsProductSearchVO> searchPage = searchProductService.page(pageParam, productParam, Boolean.FALSE); |
| | | loadData(productParam, searchPage.getRecords()); |
| | | return searchPage; |
| | | } |
| | | |
| | | /** |
| | | * 处理搜索数据 |
| | | * @param productParam |
| | | * @param list |
| | | */ |
| | | private void loadData(EsProductParam productParam, List<EsProductSearchVO> list) { |
| | | if (CollUtil.isEmpty(list)) { |
| | | return; |
| | | } |
| | | for (EsProductSearchVO productSearchVO : list) { |
| | | // 如果包含秒杀、团购活动商品,就插入活动信息 |
| | | if (containActivityProd(productSearchVO)) { |
| | | eventPublisher.publishEvent(new EsProductActivityInfoEvent(productParam.getProdType(), productSearchVO.getProducts())); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private boolean containActivityProd(EsProductSearchVO productSearchVO) { |
| | | if (CollUtil.isEmpty(productSearchVO.getProducts())) { |
| | | return Boolean.FALSE; |
| | | } |
| | | long count = productSearchVO.getProducts().stream().filter(product -> Objects.equals(product.getProdType(), ProdType.PROD_TYPE_GROUP.value()) || Objects.equals(product.getProdType(), ProdType.PROD_TYPE_SECKILL.value())).count(); |
| | | return count > 0; |
| | | } |
| | | |
| | | private void loadSearchProdType(EsProductParam productParam) { |
| | | // 用户端没有搜索全部商品需求, 当不指定商品类型时默认为非积分商品和活动商品 |
| | | if (Objects.isNull(productParam.getProdType())) { |
| | | List<Integer> prodTypeList = new ArrayList<>(); |
| | | prodTypeList.add(ProdType.PROD_TYPE_SCORE.value()); |
| | | prodTypeList.add(ProdType.PROD_TYPE_ACTIVE.value()); |
| | | productParam.setMustNotProdTypes(prodTypeList); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <artifactId>yami-shop-search</artifactId> |
| | | <groupId>com.yami.shop</groupId> |
| | | <version>0.0.1-SNAPSHOT</version> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>yami-shop-search-common</artifactId> |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>org.elasticsearch.client</groupId> |
| | | <artifactId>elasticsearch-rest-high-level-client</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.elasticsearch</groupId> |
| | | <artifactId>elasticsearch</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.elasticsearch.client</groupId> |
| | | <artifactId>elasticsearch-rest-client</artifactId> |
| | | <exclusions> |
| | | <exclusion> |
| | | <artifactId>commons-logging</artifactId> |
| | | <groupId>commons-logging</groupId> |
| | | </exclusion> |
| | | </exclusions> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.yami.shop</groupId> |
| | | <artifactId>yami-shop-security-common</artifactId> |
| | | <version>${yami.shop.version}</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.yami.shop</groupId> |
| | | <artifactId>yami-shop-service</artifactId> |
| | | <version>${yami.shop.version}</version> |
| | | </dependency> |
| | | </dependencies> |
| | | </project> |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.search.common.config; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import org.apache.http.HttpHost; |
| | | import org.apache.http.HttpResponse; |
| | | import org.apache.http.auth.AuthScope; |
| | | import org.apache.http.auth.UsernamePasswordCredentials; |
| | | import org.apache.http.client.CredentialsProvider; |
| | | import org.apache.http.conn.ConnectionKeepAliveStrategy; |
| | | import org.apache.http.impl.client.BasicCredentialsProvider; |
| | | import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy; |
| | | import org.apache.http.protocol.HttpContext; |
| | | import org.elasticsearch.client.RestClient; |
| | | import org.elasticsearch.client.RestClientBuilder; |
| | | import org.elasticsearch.client.RestHighLevelClient; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author FrozenWatermelon |
| | | * @date 2021/8/4 |
| | | */ |
| | | @Configuration |
| | | public class ElasticConfig { |
| | | |
| | | @Value("${elastic.address}") |
| | | private List<String> addressList; |
| | | |
| | | @Value("${elastic.password:}") |
| | | private String password; |
| | | |
| | | @Bean |
| | | public RestHighLevelClient restHighLevelClient() { |
| | | HttpHost[] httpHosts = new HttpHost[addressList.size()]; |
| | | |
| | | for (int i = 0; i < addressList.size(); i++) { |
| | | httpHosts[i] = HttpHost.create(addressList.get(i)); |
| | | } |
| | | RestClientBuilder builder = RestClient.builder(httpHosts); |
| | | |
| | | // 异步httpclient连接延时配置 |
| | | builder.setRequestConfigCallback(requestConfigBuilder -> { |
| | | requestConfigBuilder.setConnectTimeout(5000); |
| | | requestConfigBuilder.setSocketTimeout(5000); |
| | | requestConfigBuilder.setConnectionRequestTimeout(5000); |
| | | return requestConfigBuilder; |
| | | }); |
| | | // 异步httpclient配置 |
| | | builder.setHttpClientConfigCallback(httpClientBuilder -> { |
| | | // httpclient连接数配置 |
| | | httpClientBuilder.setMaxConnTotal(100); |
| | | httpClientBuilder.setMaxConnPerRoute(100); |
| | | // httpclient保活策略 |
| | | httpClientBuilder.setKeepAliveStrategy((httpResponse, httpContext) -> 10000); |
| | | return httpClientBuilder; |
| | | }); |
| | | |
| | | // 设置es密码 |
| | | if (StrUtil.isNotBlank(password)) { |
| | | CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); |
| | | credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("elastic", password)); |
| | | builder.setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder |
| | | .setDefaultCredentialsProvider(credentialsProvider)); |
| | | } |
| | | return new RestHighLevelClient(builder); |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.search.common.config; |
| | | |
| | | import com.yami.shop.search.common.constant.EsIndexEnum; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | import javax.annotation.PostConstruct; |
| | | |
| | | /** |
| | | * @Author: zz |
| | | * @Description: |
| | | * @Date: 下午 04:48 2024/10/10 0010 |
| | | * @Modified By |
| | | */ |
| | | @Configuration |
| | | public class EsConfig { |
| | | |
| | | @Value("${elastic.index}") |
| | | private String index; |
| | | |
| | | private EsIndexEnum esIndexEnum; // 使用枚举类型来存储有效值 |
| | | |
| | | @PostConstruct |
| | | public void init() { |
| | | this.esIndexEnum = EsIndexEnum.PRODUCT; |
| | | this.esIndexEnum.setValue(index); |
| | | System.out.printf("===================" + EsIndexEnum.PRODUCT.value()); |
| | | } |
| | | |
| | | public EsIndexEnum getEsIndexEnum() { |
| | | return this.esIndexEnum; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.search.common.constant; |
| | | |
| | | import com.yami.shop.common.config.Constant; |
| | | |
| | | /** |
| | | * 配置缓存名字 |
| | | * |
| | | * @author lhd |
| | | * @date 2020/12/30 |
| | | */ |
| | | public interface EsConstant { |
| | | |
| | | /** |
| | | * 商品 |
| | | */ |
| | | String PROD_ID = "prodId"; |
| | | String PROD_NAME_ZH = "prodNameZh"; |
| | | String PROD_NAME_EN = "prodNameEn"; |
| | | String BRIEF_ZH = "briefZh"; |
| | | String BRIEF_EN = "briefEn"; |
| | | String PRICE = "price"; |
| | | String ORI_PRICE = "oriPrice"; |
| | | String ACTIVITY_PRICE = "activityPrice"; |
| | | String ACTIVITY_ORIGINAL_PRICE = "activityOriginalPrice"; |
| | | String SCORE_PRICE = "scorePrice"; |
| | | String PIC = "pic"; |
| | | String IMGS = "imgs"; |
| | | String PROD_TYPE = "prodType"; |
| | | String MOLD = "mold"; |
| | | String PRE_SELL_STATUS = "preSellStatus"; |
| | | String SHOP_NAME = "shopName"; |
| | | String SHOP_ID = "shopId"; |
| | | String SHOP_TYPE = "shopType"; |
| | | String STATUS = "status"; |
| | | String HAS_STOCK = "hasStock"; |
| | | String TOTAL_STOCKS = "totalStocks"; |
| | | String SOLD_NUM = "soldNum"; |
| | | String ACTUAL_SOLD_NUM = "actualSoldNum"; |
| | | String WATER_SOLD_NUM = "waterSoldNum"; |
| | | String COMMENT_NUM = "commentNum"; |
| | | String POSITIVE_RATING = "positiveRating"; |
| | | String DELIVERY_MODE = "deliveryMode"; |
| | | String DELIVERIES = "deliveries"; |
| | | String CREATE_TIME = "createTime"; |
| | | String UPDATE_TIME = "updateTime"; |
| | | String PUTAWAY_TIME = "putawayTime"; |
| | | String ACTIVITY_START_TIME = "activityStartTime"; |
| | | String BRAND = "brand"; |
| | | String SEQ = "seq"; |
| | | String IS_TOP = "isTop"; |
| | | String ACTIVITY_ID = "activityId"; |
| | | String PRIMARY_CATEGORY_ID = "primaryCategoryId"; |
| | | String SECONDARY_CATEGORY_ID = "secondaryCategoryId"; |
| | | String CATEGORY = "category"; |
| | | String SHOP_CATEGORY_ID = "shopCategoryId"; |
| | | String APP_DISPLAY = "appDisplay"; |
| | | |
| | | |
| | | |
| | | /** |
| | | * 品牌 |
| | | */ |
| | | String BRAND_ID = "brandId"; |
| | | String BRAND_IMG = "brandImg"; |
| | | String BRAND_NAME_ZH = "brandNameZh"; |
| | | String BRAND_NAME_EN = "brandNameEn"; |
| | | String BRAND_UNION_ID = BRAND + Constant.PERIOD + BRAND_ID; |
| | | String BRAND_UNION_IMG = BRAND + Constant.PERIOD + BRAND_IMG; |
| | | String BRAND_UNION_NAME_ZH = BRAND + Constant.PERIOD + BRAND_NAME_ZH; |
| | | String BRAND_UNION_NAME_EN = BRAND + Constant.PERIOD + BRAND_NAME_EN; |
| | | |
| | | /** |
| | | * 分类 |
| | | */ |
| | | String CATEGORY_ID = "categoryId"; |
| | | String CATEGORY_NAME_ZH = "categoryNameZh"; |
| | | String CATEGORY_NAME_EN = "categoryNameEn"; |
| | | String CATEGORY_UNION_ID = CATEGORY + Constant.PERIOD + CATEGORY_ID; |
| | | String CATEGORY_UNION_NAME_ZH = CATEGORY + Constant.PERIOD + CATEGORY_NAME_ZH; |
| | | String CATEGORY_UNION_NAME_EN = CATEGORY + Constant.PERIOD + CATEGORY_NAME_EN; |
| | | |
| | | |
| | | /** |
| | | * 其余字段 |
| | | */ |
| | | String TOP_HITS_DATA = "top_hits_data"; |
| | | String SHOP = "shop"; |
| | | String SHOP_CATEGORY = "shopCategory"; |
| | | String PROD_LIST = "prodList"; |
| | | |
| | | /** |
| | | * 指定返回字段 |
| | | */ |
| | | String[] BRAND_INCLUDE = {BRAND_UNION_ID, BRAND_UNION_IMG, BRAND_UNION_NAME_ZH, BRAND_UNION_NAME_EN}; |
| | | String[] CATEGORY_INCLUDE = {CATEGORY_UNION_ID, CATEGORY_UNION_NAME_ZH, CATEGORY_UNION_NAME_EN}; |
| | | String[] APP_FETCH_SOURCE = {PROD_ID,PROD_NAME_ZH,PROD_NAME_EN,BRIEF_ZH,BRIEF_EN,SHOP_ID,PRICE,PROD_TYPE,ORI_PRICE,ACTIVITY_PRICE,SCORE_PRICE,SOLD_NUM,COMMENT_NUM,POSITIVE_RATING,PIC,IMGS,ACTIVITY_ID,ACTIVITY_ORIGINAL_PRICE,ACTIVITY_START_TIME}; |
| | | String[] SHOP_FETCH_SOURCE = {PROD_ID,PROD_NAME_ZH,PROD_NAME_EN,PIC,PRICE,ORI_PRICE,SCORE_PRICE,ACTUAL_SOLD_NUM,TOTAL_STOCKS,SEQ,STATUS,BRIEF_ZH,BRIEF_EN,IS_TOP,DELIVERY_MODE,PROD_TYPE,MOLD}; |
| | | String[] PLATFORM_FETCH_SOURCE = {SHOP_ID,SHOP_NAME,PROD_ID,PROD_NAME_ZH,PROD_NAME_EN,PIC,PRICE,ORI_PRICE,SCORE_PRICE,ACTUAL_SOLD_NUM,TOTAL_STOCKS,SEQ,STATUS,BRIEF_ZH,BRIEF_EN,IS_TOP,MOLD,DELIVERY_MODE,WATER_SOLD_NUM,PROD_TYPE}; |
| | | String[] SIMPLE_FETCH_SOURCE = {PROD_ID,UPDATE_TIME}; |
| | | String[] RENOVATION_FETCH_SOURCE = {PROD_ID,PROD_NAME_ZH,PROD_NAME_EN,PROD_TYPE,STATUS,BRIEF_ZH,BRIEF_EN,SHOP_ID,PRICE,ORI_PRICE,ACTIVITY_PRICE,SCORE_PRICE,SOLD_NUM,PIC,ACTIVITY_ID,ACTIVITY_ORIGINAL_PRICE,SHOP_NAME,TOTAL_STOCKS,ACTIVITY_START_TIME}; |
| | | String[] EXCEL_FETCH_SOURCE = {PROD_ID,PROD_NAME_ZH,PROD_NAME_EN,PROD_TYPE,STATUS,BRIEF_ZH,BRIEF_EN,SHOP_NAME}; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.search.common.constant; |
| | | |
| | | /** |
| | | * es当中的index |
| | | * @author FrozenWatermelon |
| | | * @date 2020/11/12 |
| | | */ |
| | | public enum EsIndexEnum { |
| | | |
| | | /** |
| | | * 商品 |
| | | */ |
| | | PRODUCT("product") |
| | | ; |
| | | |
| | | private String value; |
| | | |
| | | public String value() { |
| | | return value; |
| | | } |
| | | public void setValue(String value) { |
| | | this.value = value; |
| | | } |
| | | |
| | | EsIndexEnum(String value) { |
| | | this.value = value; |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.search.common.constant; |
| | | |
| | | import org.elasticsearch.search.sort.SortOrder; |
| | | |
| | | |
| | | /** |
| | | * 商品排序 |
| | | * @author FrozenWatermelon |
| | | * @date 2020/11/17 |
| | | */ |
| | | public enum EsProductSortEnum { |
| | | |
| | | /** |
| | | * 创建时间正序 |
| | | */ |
| | | CREATE_TIME_ASC(0, EsConstant.CREATE_TIME, SortOrder.ASC), |
| | | |
| | | /** |
| | | * 创建时间倒序 |
| | | */ |
| | | CREATE_TIME_DESC(1, EsConstant.CREATE_TIME, SortOrder.DESC), |
| | | |
| | | /** |
| | | * 销量倒序 |
| | | */ |
| | | SALE_NUM_DESC(2, EsConstant.SOLD_NUM, SortOrder.DESC), |
| | | |
| | | /** |
| | | * 销量正序 |
| | | */ |
| | | SALE_NUM_ASC(3, EsConstant.SOLD_NUM, SortOrder.ASC), |
| | | |
| | | /** |
| | | * 商品价格倒序 |
| | | */ |
| | | PRICE_DESC(4, EsConstant.PRICE, SortOrder.DESC), |
| | | |
| | | /** |
| | | * 商品价格正序 |
| | | */ |
| | | PRICE_ASC(5, EsConstant.PRICE, SortOrder.ASC), |
| | | |
| | | /** |
| | | * 市场价倒序 |
| | | */ |
| | | MARKET_PRICE_DESC(7, EsConstant.ORI_PRICE, SortOrder.DESC), |
| | | |
| | | /** |
| | | * 市场价正序 |
| | | */ |
| | | MARKET_PRICE_ASC(8, EsConstant.ORI_PRICE, SortOrder.ASC), |
| | | |
| | | /** |
| | | * 商品库存倒序 |
| | | */ |
| | | STOCK_DESC(10, EsConstant.TOTAL_STOCKS, SortOrder.DESC), |
| | | |
| | | /** |
| | | * 商品库存正序 |
| | | */ |
| | | STOCK_ASC(11, EsConstant.TOTAL_STOCKS, SortOrder.ASC), |
| | | |
| | | /** |
| | | * 商品序号倒序 |
| | | */ |
| | | SEQ_DESC(12, EsConstant.SEQ, SortOrder.DESC), |
| | | |
| | | /** |
| | | * 商品序号正序 |
| | | */ |
| | | SEQ_ASC(13, EsConstant.SEQ, SortOrder.ASC), |
| | | |
| | | /** |
| | | * 评论数量倒序 |
| | | */ |
| | | COMMENT_NUM_DESC(14, EsConstant.COMMENT_NUM, SortOrder.DESC), |
| | | |
| | | /** |
| | | * 评论数量正序 |
| | | */ |
| | | COMMENT_NUM_ASC(15, EsConstant.COMMENT_NUM, SortOrder.ASC), |
| | | |
| | | /** |
| | | * 根据置顶状态排序 |
| | | */ |
| | | IS_TOP_DESC(16, EsConstant.IS_TOP, SortOrder.DESC), |
| | | |
| | | /** |
| | | * 实际销量倒序 |
| | | */ |
| | | ACTUAL_SOLD_NUM_DESC(17, EsConstant.ACTUAL_SOLD_NUM, SortOrder.DESC), |
| | | |
| | | /** |
| | | * 实际销量正序 |
| | | */ |
| | | ACTUAL_SOLD_NUM_ASC(18, EsConstant.ACTUAL_SOLD_NUM, SortOrder.ASC), |
| | | |
| | | /** |
| | | * 注水销量倒序 |
| | | */ |
| | | WATER_SOLD_NUM_DESC(19, EsConstant.WATER_SOLD_NUM, SortOrder.DESC), |
| | | |
| | | /** |
| | | * 注水销量正序 |
| | | */ |
| | | WATER_SOLD_NUM_ASC(20, EsConstant.WATER_SOLD_NUM, SortOrder.ASC), |
| | | |
| | | /** |
| | | * 发布时间倒序 |
| | | */ |
| | | PUTAWAY_TIME_DESC(21, EsConstant.PUTAWAY_TIME, SortOrder.DESC), |
| | | |
| | | /** |
| | | * 发布时间正序 |
| | | */ |
| | | PUTAWAY_TIME_ASC(22, EsConstant.PUTAWAY_TIME, SortOrder.ASC), |
| | | |
| | | /** |
| | | * 商品ID-倒序 |
| | | */ |
| | | PROD_ID_DESC(23, EsConstant.PROD_ID, SortOrder.DESC) |
| | | |
| | | ; |
| | | |
| | | private final Integer value; |
| | | |
| | | private final String param; |
| | | |
| | | private final SortOrder order; |
| | | |
| | | public Integer value() { |
| | | return value; |
| | | } |
| | | |
| | | EsProductSortEnum(Integer value, String param, SortOrder order) { |
| | | this.value = value; |
| | | this.param = param; |
| | | this.order = order; |
| | | } |
| | | |
| | | public String param() { |
| | | return param; |
| | | } |
| | | |
| | | public SortOrder order() { |
| | | return order; |
| | | } |
| | | |
| | | |
| | | // public static Boolean isAsc(EsProductSortEnum esProductSortEnum) { |
| | | // if (Objects.equals(esProductSortEnum.order(), Boolean.TRUE)) { |
| | | // return Boolean.TRUE; |
| | | // } |
| | | // return Boolean.FALSE; |
| | | // } |
| | | // public static Boolean isDesc(EsProductSortEnum esProductSortEnum) { |
| | | // if (Objects.equals(esProductSortEnum.order(), Boolean.FALSE)) { |
| | | // return Boolean.TRUE; |
| | | // } |
| | | // return Boolean.FALSE; |
| | | // } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.search.common.listener; |
| | | |
| | | import com.yami.shop.bean.enums.EsOperationType; |
| | | import com.yami.shop.bean.event.EsProductUpdateEvent; |
| | | import com.yami.shop.search.common.service.EsProductService; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.context.event.EventListener; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 获取es商品数据事件 |
| | | * @author yami |
| | | */ |
| | | @Component("EsProductUpdateListener") |
| | | @AllArgsConstructor |
| | | public class EsProductUpdateListener { |
| | | |
| | | private final EsProductService esProductService; |
| | | |
| | | @EventListener(EsProductUpdateEvent.class) |
| | | public void defaultEsProductListener(EsProductUpdateEvent event) { |
| | | EsOperationType esOperationType = event.getEsOperationType(); |
| | | Long id = event.getId(); |
| | | List<Long> ids = event.getIds(); |
| | | // 保存 |
| | | if (Objects.equals(esOperationType, EsOperationType.SAVE)) { |
| | | esProductService.save(id); |
| | | } |
| | | // 更新 |
| | | else if (Objects.equals(esOperationType, EsOperationType.UPDATE)) { |
| | | esProductService.update(id); |
| | | } |
| | | // 删除 |
| | | else if (Objects.equals(esOperationType, EsOperationType.DELETE)) { |
| | | esProductService.update(id); |
| | | //esProductService.delete(id); |
| | | } |
| | | // 批量保存 |
| | | else if (Objects.equals(esOperationType, EsOperationType.SAVE_BATCH)) { |
| | | esProductService.saveBatch(ids); |
| | | } |
| | | // 批量更新 |
| | | else if (Objects.equals(esOperationType, EsOperationType.UPDATE_BATCH)) { |
| | | esProductService.updateBatch(ids); |
| | | } |
| | | // 批量删除 |
| | | else if (Objects.equals(esOperationType, EsOperationType.DELETE_BATCH)) { |
| | | esProductService.updateBatch(ids); |
| | | //esProductService.deleteBatch(ids); |
| | | } |
| | | // 更新商品评论 |
| | | else if (Objects.equals(esOperationType, EsOperationType.UPDATE_PROD_COMM)) { |
| | | esProductService.updateProdComm(id); |
| | | } |
| | | // 更新商品销量 |
| | | else if (Objects.equals(esOperationType, EsOperationType.UPDATE_SOLD_NUM)) { |
| | | esProductService.updateSoldNum(id); |
| | | } |
| | | // 批量更新商品销量 |
| | | else if (Objects.equals(esOperationType, EsOperationType.UPDATE_SOLD_NUM_BATCH)) { |
| | | esProductService.updateSoldNumBatch(ids); |
| | | } |
| | | // 批量更新商品库存 |
| | | else if (Objects.equals(esOperationType, EsOperationType.UPDATE_ORDER_STOCK_NUM_BATCH)) { |
| | | esProductService.changeProdStockBatch(event.getProdList()); |
| | | } |
| | | // 批量更新下单单商品销量 |
| | | else if (Objects.equals(esOperationType, EsOperationType.UPDATE_ORDER_SOLD_NUM_BATCH)) { |
| | | esProductService.changeProdSoldBatch(event.getProdList()); |
| | | } |
| | | // 根据分类id,更新商品 |
| | | else if (Objects.equals(esOperationType, EsOperationType.UPDATE_BY_CATEGORY_ID)) { |
| | | esProductService.updateByCategoryId(id); |
| | | } |
| | | // 根据店铺分类id,更新商品 |
| | | else if (Objects.equals(esOperationType, EsOperationType.UPDATE_BY_SHOP_CATEGORY_ID)) { |
| | | esProductService.updateByShopCategoryId(id); |
| | | } |
| | | // 根据店铺id,更新商品 |
| | | else if (Objects.equals(esOperationType, EsOperationType.UPDATE_BY_SHOP_ID)) { |
| | | esProductService.updateByShopId(id); |
| | | } |
| | | // 根据拼团活动id,更新商品 |
| | | else if (Objects.equals(esOperationType, EsOperationType.UPDATE_BY_GROUP_ID)) { |
| | | esProductService.updateByGroupId(id); |
| | | } |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.search.common.listener; |
| | | |
| | | import com.yami.shop.bean.event.ProdChangeEvent; |
| | | import com.yami.shop.bean.model.Product; |
| | | import com.yami.shop.dao.SupplierProdMapper; |
| | | import com.yami.shop.dao.TakeStockProdMapper; |
| | | import com.yami.shop.service.ProdCommService; |
| | | import com.yami.shop.service.PurchaseProdService; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.context.event.EventListener; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | |
| | | |
| | | /** |
| | | * @author Yami |
| | | */ |
| | | @Slf4j |
| | | @Component("multishopProdChangeListener") |
| | | @AllArgsConstructor |
| | | public class ProdChangeListener { |
| | | |
| | | |
| | | private final ProdCommService prodCommService; |
| | | |
| | | private final SupplierProdMapper supplierProdMapper; |
| | | |
| | | private final TakeStockProdMapper takeStockProdMapper; |
| | | |
| | | private final PurchaseProdService purchaseProdService; |
| | | |
| | | |
| | | @EventListener(ProdChangeEvent.class) |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void prodChangeEvent(ProdChangeEvent event) { |
| | | Product product = event.getProduct(); |
| | | Long prodId = product.getProdId(); |
| | | // 删除评价信息 |
| | | Set<Long> prodIds = new HashSet<>(); |
| | | prodIds.add(prodId); |
| | | prodCommService.deleteByProdIds(prodIds); |
| | | // 删除供应商商品信息 |
| | | supplierProdMapper.deleteByProdId(prodId); |
| | | // 删除盘点商品信息 |
| | | takeStockProdMapper.deleteByProdId(prodId); |
| | | // 删除盘点商品信息 |
| | | takeStockProdMapper.deleteByProdId(prodId); |
| | | //采购入库 |
| | | purchaseProdService.deleteByProdId(prodId, null); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.search.common.listener; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.yami.shop.bean.enums.ProdStatusEnums; |
| | | import com.yami.shop.bean.event.ProdChangeStatusEvent; |
| | | import com.yami.shop.bean.model.IndexImg; |
| | | import com.yami.shop.bean.model.Product; |
| | | import com.yami.shop.bean.order.GeneralActivitiesOrder; |
| | | import com.yami.shop.service.IndexImgService; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.context.event.EventListener; |
| | | import org.springframework.core.annotation.Order; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * 商品状态修改监听 |
| | | * @author LGH |
| | | */ |
| | | @Component("prodChangeStatus") |
| | | @AllArgsConstructor |
| | | public class ProdChangeStatusListener { |
| | | private final IndexImgService indexImgService; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @EventListener(ProdChangeStatusEvent.class) |
| | | @Order(GeneralActivitiesOrder.DEFAULT) |
| | | public void prodChangeStatusListener(ProdChangeStatusEvent event) { |
| | | Product product = event.getProduct(); |
| | | Integer status = event.getStatus(); |
| | | // 商品上线,则不进行处理 |
| | | // 或者进入待审核状态6也不处理,因为进入该状态要么是新商品,要么是下架商品 |
| | | if (Objects.equals(status, ProdStatusEnums.NORMAL.getValue()) || Objects.equals(status,ProdStatusEnums.AUDIT.getValue())) { |
| | | return; |
| | | } |
| | | //移除轮播图中绑定的商品 |
| | | List<IndexImg> list = indexImgService.list(new LambdaQueryWrapper<IndexImg>() |
| | | .eq(IndexImg::getType, 0) |
| | | .eq(IndexImg::getRelation, product.getProdId()) |
| | | ); |
| | | List<Long> ids = new ArrayList<>(); |
| | | Set<Long> shopIds = new HashSet<>(); |
| | | for (IndexImg indexImg : list) { |
| | | ids.add(indexImg.getImgId()); |
| | | shopIds.add(indexImg.getShopId()); |
| | | } |
| | | // 更新轮播图数据 |
| | | indexImgService.updateImgProd(ids); |
| | | // 清除缓存 |
| | | for (Long shopId : shopIds) { |
| | | indexImgService.removeIndexImgCacheByShopId(shopId); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.search.common.listener; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.yami.shop.bean.event.SkuDeleteEvent; |
| | | import com.yami.shop.bean.model.StockBillLogItem; |
| | | import com.yami.shop.service.*; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.context.event.EventListener; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.List; |
| | | |
| | | |
| | | /** |
| | | * @author Yami |
| | | */ |
| | | @Slf4j |
| | | @Component("skuDeleteListener") |
| | | @AllArgsConstructor |
| | | public class SkuDeleteListener { |
| | | |
| | | private final PurchaseProdService purchaseProdService; |
| | | private final SupplierProdService supplierProdService; |
| | | private final TakeStockProdService takeStockProdService; |
| | | private final StockBillLogItemService stockBillLogItemService; |
| | | private final StockBillLogService stockBillLogService; |
| | | |
| | | |
| | | @EventListener(SkuDeleteEvent.class) |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void prodChangeEvent(SkuDeleteEvent event) { |
| | | if (CollUtil.isEmpty(event.getSkuIds())) { |
| | | return; |
| | | } |
| | | List<Long> skuIds = event.getSkuIds(); |
| | | // 移除采购订单关联sku信息 |
| | | purchaseProdService.deleteByProdId(null, skuIds); |
| | | List<Long> supplierIds = supplierProdService.listSupplierIdBySkuIds(skuIds); |
| | | List<Long> takeStockIds = takeStockProdService.listTakeStockIdBySkuIds(skuIds); |
| | | // 删除供应商商品关联sku信息 |
| | | supplierProdService.deleteByProdId(null, skuIds); |
| | | // 删除正在盘点的商品的信息 |
| | | takeStockProdService.deleteByProdId(null, skuIds); |
| | | // 删除sku出入库信息 |
| | | stockBillLogItemService.remove(new LambdaQueryWrapper<StockBillLogItem>().in(StockBillLogItem::getSkuId, skuIds)); |
| | | // 清除已经没有商品记录的出入库记录 |
| | | stockBillLogService.removeEmptyLog(); |
| | | //清除缓存 |
| | | for (Long supplierId : supplierIds) { |
| | | supplierProdService.removeCacheBySupplierId(supplierId); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.search.common.manager; |
| | | |
| | | import com.yami.shop.bean.param.EsProductParam; |
| | | import com.yami.shop.bean.vo.search.ProductSearchVO; |
| | | import com.yami.shop.common.constants.EsCacheNames; |
| | | import com.yami.shop.common.enums.EsRenovationProductSortEnum; |
| | | import com.yami.shop.common.util.RedisUtil; |
| | | import com.yami.shop.search.common.param.EsPageParam; |
| | | import com.yami.shop.search.common.service.SearchProductService; |
| | | import com.yami.shop.search.common.vo.EsPageVO; |
| | | import com.yami.shop.service.OrderItemService; |
| | | import com.yami.shop.service.ProdCommService; |
| | | import ma.glasnost.orika.MapperFacade; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | |
| | | /** |
| | | * @author FrozenWatermelon |
| | | * @date 2020/11/16 |
| | | */ |
| | | @Component |
| | | public class ProductSearchManager { |
| | | |
| | | @Autowired |
| | | private MapperFacade mapperFacade; |
| | | @Autowired |
| | | private ProdCommService prodCommService; |
| | | @Autowired |
| | | private OrderItemService orderItemService; |
| | | @Autowired |
| | | private SearchProductService searchProductService; |
| | | |
| | | public void addRenovationSpuCache(String key, EsProductParam productSearchDTO, Long shopId, Integer expireTime) { |
| | | if(Objects.isNull(productSearchDTO.getEsTimeRange()) && Objects.isNull(productSearchDTO.getEsRenovationSpuSort())){ |
| | | return; |
| | | } |
| | | // 计算时间 |
| | | int dayNum = 0; |
| | | switch (productSearchDTO.getEsTimeRange()){ |
| | | case 1: |
| | | dayNum = 365; |
| | | break; |
| | | case 2: |
| | | dayNum = 90; |
| | | break; |
| | | case 3: |
| | | dayNum = 30; |
| | | break; |
| | | case 4: |
| | | dayNum = 7; |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | List<Long> spuIds; |
| | | // 1.获取根据条件的商品ids |
| | | if(Objects.equals(productSearchDTO.getEsRenovationSpuSort(), EsRenovationProductSortEnum.COMMENT_NUM_DESC.value()) || Objects.equals(productSearchDTO.getEsRenovationSpuSort(),EsRenovationProductSortEnum.COMMENT_NUM_ASC.value())){ |
| | | // 获取时间范围内的评论数排序,放入redis |
| | | spuIds = prodCommService.getCommNumRankSpuIdsByShopIdAndTime(key, shopId, dayNum, expireTime,productSearchDTO.getEsRenovationSpuSort()); |
| | | }else { |
| | | // 获取时间范围内的销量排序,放入redis |
| | | spuIds = orderItemService.getSoldNumRankByShopIdAndTime(key, shopId, dayNum, expireTime, productSearchDTO.getEsRenovationSpuSort()); |
| | | } |
| | | // 2.判断数量是否为1000个,没有就按创建时间排序补充剩余 |
| | | if(spuIds.size() >= EsCacheNames.RENOVATION_PRODUCT_IDS_LIMIT){ |
| | | return; |
| | | } |
| | | |
| | | // 不足1000的部分直接查询es数据存入redis |
| | | int surplusNum = EsCacheNames.RENOVATION_PRODUCT_IDS_LIMIT - spuIds.size(); |
| | | EsPageParam pageDTO = new EsPageParam(); |
| | | pageDTO.setCurrent(1); |
| | | pageDTO.setSize(surplusNum); |
| | | EsProductParam productParam = mapperFacade.map(productSearchDTO, EsProductParam.class); |
| | | productParam.setSpuIdsExclude(spuIds); |
| | | productParam.setShowSpuType(0); |
| | | EsPageVO<ProductSearchVO> searchPage = searchProductService.renovationPage(pageDTO, productParam, null); |
| | | List<Long> esSpuIds = searchPage.getRecords().stream().map(ProductSearchVO::getProdId).collect(Collectors.toList()); |
| | | spuIds.addAll(esSpuIds); |
| | | // 放入es缓存 |
| | | RedisUtil.setRightPushAll(key,spuIds,expireTime); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.search.common.param; |
| | | |
| | | import com.yami.shop.common.util.PrincipalUtil; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | |
| | | import javax.validation.constraints.NotNull; |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * @author FrozenWatermelon |
| | | * @date 2020/11/16 |
| | | */ |
| | | public class EsPageParam { |
| | | |
| | | public static final String ASC = "ASC"; |
| | | |
| | | public static final String DESC = "DESC"; |
| | | |
| | | /** |
| | | * 最大分页大小,如果分页大小大于1000,则用1000作为分页的大小。防止有人直接传入一个较大的数,导致服务器内存溢出宕机 |
| | | */ |
| | | public static final Integer MAX_PAGE_SIZE = 1000; |
| | | |
| | | /** |
| | | * 当前页 |
| | | */ |
| | | @NotNull(message = "current 不能为空") |
| | | @Schema(description = "当前页" , required = true) |
| | | private Integer current; |
| | | |
| | | @NotNull(message = "pageSize 不能为空") |
| | | @Schema(description = "每页大小" , required = true) |
| | | private Integer size; |
| | | |
| | | @Schema(description = "排序字段数组,用逗号分割" ) |
| | | private String[] columns; |
| | | |
| | | @Schema(description = "排序字段方式,用逗号分割,ASC正序,DESC倒序" ) |
| | | private String[] orders; |
| | | |
| | | public Integer getCurrent() { |
| | | return current; |
| | | } |
| | | |
| | | public void setCurrent(Integer current) { |
| | | this.current = current; |
| | | } |
| | | |
| | | public Integer getSize() { |
| | | return size; |
| | | } |
| | | |
| | | public void setSize(Integer size) { |
| | | if (size > MAX_PAGE_SIZE) { |
| | | this.size = MAX_PAGE_SIZE; |
| | | return; |
| | | } |
| | | this.size = size; |
| | | } |
| | | |
| | | public String getOrderBy() { |
| | | return order(this.columns, this.orders); |
| | | } |
| | | |
| | | public String[] getColumns() { |
| | | return columns; |
| | | } |
| | | |
| | | public void setColumns(String[] columns) { |
| | | this.columns = columns; |
| | | } |
| | | |
| | | public String[] getOrders() { |
| | | return orders; |
| | | } |
| | | |
| | | public void setOrders(String[] orders) { |
| | | this.orders = orders; |
| | | } |
| | | |
| | | public static String order(String[] columns, String[] orders) { |
| | | |
| | | if (columns == null || columns.length == 0) { |
| | | return ""; |
| | | } |
| | | |
| | | StringBuilder stringBuilder = new StringBuilder(); |
| | | |
| | | for (int x = 0; x < columns.length; x++) { |
| | | |
| | | String column = columns[x]; |
| | | String order; |
| | | |
| | | if (orders != null && orders.length > x) { |
| | | order = orders[x].toUpperCase(); |
| | | if (!(order.equals(ASC) || order.equals(DESC))) { |
| | | throw new IllegalArgumentException("非法的排序策略:" + column); |
| | | } |
| | | }else { |
| | | order = ASC; |
| | | } |
| | | |
| | | // 判断列名称的合法性,防止SQL注入。只能是【字母,数字,下划线】 |
| | | if (!PrincipalUtil.isField(column)) { |
| | | throw new IllegalArgumentException("非法的排序字段名称:" + column); |
| | | } |
| | | |
| | | // 驼峰转换为下划线 |
| | | column = humpConversionUnderscore(column); |
| | | |
| | | if (x != 0) { |
| | | stringBuilder.append(", "); |
| | | } |
| | | stringBuilder.append("`").append(column).append("` ").append(order); |
| | | } |
| | | return stringBuilder.toString(); |
| | | } |
| | | |
| | | public static String humpConversionUnderscore(String value) { |
| | | StringBuilder stringBuilder = new StringBuilder(); |
| | | char[] chars = value.toCharArray(); |
| | | for (char character : chars) { |
| | | if (Character.isUpperCase(character)) { |
| | | stringBuilder.append("_"); |
| | | character = Character.toLowerCase(character); |
| | | } |
| | | stringBuilder.append(character); |
| | | } |
| | | return stringBuilder.toString(); |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | public String toString() { |
| | | return "EsPageDTO{" + |
| | | "current=" + current + |
| | | ", size=" + size + |
| | | ", columns=" + Arrays.toString(columns) + |
| | | ", orders=" + Arrays.toString(orders) + |
| | | '}'; |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.search.common.service; |
| | | |
| | | import com.yami.shop.bean.app.vo.SkuVO; |
| | | import com.yami.shop.bean.param.EsProductParam; |
| | | import com.yami.shop.bean.vo.EsProdUpdateVO; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author Yami |
| | | */ |
| | | public interface EsProductService { |
| | | |
| | | /** |
| | | * 保存 |
| | | * @param prodId |
| | | */ |
| | | void save(Long prodId); |
| | | |
| | | /** |
| | | * 批量保存 |
| | | * @param prodIds |
| | | */ |
| | | void saveBatch(List<Long> prodIds); |
| | | |
| | | /** |
| | | * 更新 |
| | | * @param prodId |
| | | */ |
| | | void update(Long prodId); |
| | | |
| | | /** |
| | | * 批量更新 |
| | | * @param prodIds |
| | | */ |
| | | void updateBatch(List<Long> prodIds); |
| | | |
| | | /** |
| | | * 更新商品评论 |
| | | * @param prodId |
| | | */ |
| | | void updateProdComm(Long prodId); |
| | | |
| | | /** |
| | | * 根据平台分类,更新商品 |
| | | * @param categoryId |
| | | */ |
| | | void updateByCategoryId(Long categoryId); |
| | | |
| | | /** |
| | | * 根据店铺分类,更新商品 |
| | | * @param shopCategoryId |
| | | */ |
| | | void updateByShopCategoryId(Long shopCategoryId); |
| | | |
| | | /** |
| | | * 更新商品销量 |
| | | * @param prodId |
| | | */ |
| | | void updateSoldNum(Long prodId); |
| | | |
| | | |
| | | /** |
| | | * 批量更新商品销量 |
| | | * @param ids |
| | | */ |
| | | void updateSoldNumBatch(List<Long> ids); |
| | | |
| | | /** |
| | | * 根据店铺id, 更新店铺内的商品 |
| | | * @param shopId |
| | | */ |
| | | void updateByShopId(Long shopId); |
| | | |
| | | /** |
| | | * 删除 |
| | | * @param prodId |
| | | */ |
| | | void delete(Long prodId); |
| | | |
| | | /** |
| | | * 批量删除 |
| | | * @param ids |
| | | */ |
| | | void deleteBatch(List<Long> ids); |
| | | |
| | | /** |
| | | * 根据拼团活动id, 更新商品 |
| | | * @param id |
| | | */ |
| | | void updateByGroupId(Long id); |
| | | |
| | | /** |
| | | * 改变商品的库存 |
| | | * @param prodList |
| | | */ |
| | | void changeProdStockBatch(List<EsProdUpdateVO> prodList); |
| | | |
| | | /** |
| | | * 改变商品的销量 |
| | | * @param prodList |
| | | */ |
| | | void changeProdSoldBatch(List<EsProdUpdateVO> prodList); |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.search.common.service; |
| | | |
| | | import com.yami.shop.bean.param.EsProductParam; |
| | | import com.yami.shop.bean.vo.search.EsProductSearchVO; |
| | | import com.yami.shop.bean.vo.search.ProductSearchVO; |
| | | import com.yami.shop.search.common.param.EsPageParam; |
| | | import com.yami.shop.search.common.vo.EsPageVO; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author Yami |
| | | */ |
| | | public interface SearchProductService { |
| | | |
| | | /** |
| | | * 分页搜索 |
| | | * @param pageParam 分页参数 |
| | | * @param productParam 筛选参数 |
| | | * @param isAgg 是否需要聚合 |
| | | * @return 商品列表 |
| | | */ |
| | | EsPageVO<EsProductSearchVO> page(EsPageParam pageParam, EsProductParam productParam, Boolean isAgg); |
| | | |
| | | /** |
| | | * 搜索商品扩展数据(分类、品牌等) |
| | | * @param pageParam 分页参数 |
| | | * @param productParam 筛选参数 |
| | | * @return |
| | | */ |
| | | EsProductSearchVO searchExtension(EsPageParam pageParam, EsProductParam productParam); |
| | | |
| | | /** |
| | | * 根据商品id,获取商品列表 |
| | | * @param productParam 筛选参数 |
| | | * @return 商品信息列表 |
| | | */ |
| | | List<ProductSearchVO> listSpuByProdIds(EsProductParam productParam); |
| | | |
| | | /** |
| | | * 商家、平台端商品管理分页查询 |
| | | * @param pageParam 分页参数 |
| | | * @param productParam 筛选参数 |
| | | * @return 商品信息列表 |
| | | */ |
| | | EsPageVO<ProductSearchVO> adminPage(EsPageParam pageParam, EsProductParam productParam); |
| | | |
| | | /** |
| | | * 定时任务校验商品数据查询 |
| | | * @param spuIds 商品id列表 |
| | | * @return 商品信息列表 |
| | | */ |
| | | List<ProductSearchVO> simpleList(List<Long> spuIds); |
| | | |
| | | /** |
| | | * 装修商品分页 |
| | | * @param pageParam |
| | | * @param productParam |
| | | * @param size |
| | | * @return |
| | | */ |
| | | EsPageVO<ProductSearchVO> renovationPage(EsPageParam pageParam, EsProductParam productParam, Long size); |
| | | |
| | | /** |
| | | * 导出excel |
| | | * @param response |
| | | * @param productParam |
| | | */ |
| | | void export(HttpServletResponse response, EsProductParam productParam); |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.search.common.service.impl; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.yami.shop.bean.bo.ProductBO; |
| | | import com.yami.shop.bean.enums.EsOperationType; |
| | | import com.yami.shop.bean.enums.ProdStatusEnums; |
| | | import com.yami.shop.bean.enums.ProdType; |
| | | import com.yami.shop.bean.event.EsProductEvent; |
| | | import com.yami.shop.bean.model.Product; |
| | | import com.yami.shop.bean.vo.EsProdUpdateVO; |
| | | import com.yami.shop.dao.ProductMapper; |
| | | import com.yami.shop.search.common.service.EsProductService; |
| | | import com.yami.shop.search.common.util.EsSearchUtil; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.elasticsearch.client.RestHighLevelClient; |
| | | import org.elasticsearch.script.Script; |
| | | import org.elasticsearch.script.ScriptType; |
| | | import org.springframework.context.ApplicationEventPublisher; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * @author Yami |
| | | */ |
| | | @Service |
| | | @RequiredArgsConstructor |
| | | @Slf4j |
| | | public class EsProductServiceImpl implements EsProductService { |
| | | |
| | | private final ApplicationEventPublisher eventPublisher; |
| | | private final ProductMapper productMapper; |
| | | private final RestHighLevelClient restHighLevelClient; |
| | | |
| | | @Override |
| | | public void save(Long prodId) { |
| | | ProductBO productBO = getProductBo(prodId); |
| | | if (Objects.equals(productBO.getStatus(), ProdStatusEnums.DELETE.getValue())) { |
| | | return; |
| | | } |
| | | EsSearchUtil.save(productBO.getProdId(), productBO); |
| | | } |
| | | |
| | | @Override |
| | | public void saveBatch(List<Long> prodIds) { |
| | | List<ProductBO> productBOList = getProductBo(prodIds); |
| | | if (CollUtil.isEmpty(productBOList)) { |
| | | return; |
| | | } |
| | | Map<Long, ProductBO> map = productBOList.stream() |
| | | .filter(productBO -> !Objects.equals(productBO.getStatus(), ProdStatusEnums.DELETE.getValue())) |
| | | .collect(Collectors.toMap(ProductBO::getProdId, p -> p)); |
| | | EsSearchUtil.saveBatch(map); |
| | | } |
| | | |
| | | @Override |
| | | public void update(Long prodId) { |
| | | if (Objects.isNull(prodId)) { |
| | | return; |
| | | } |
| | | ProductBO productBO = getProductBo(prodId); |
| | | if (Objects.equals(productBO.getStatus(), ProdStatusEnums.DELETE.getValue())) { |
| | | delete(prodId); |
| | | return; |
| | | } |
| | | EsSearchUtil.update(productBO); |
| | | } |
| | | |
| | | @Override |
| | | public void updateBatch(List<Long> prodIds) { |
| | | if (CollUtil.isEmpty(prodIds)) { |
| | | return; |
| | | } |
| | | List<ProductBO> productBOList = getProductBo(prodIds); |
| | | Map<Long, ProductBO> map = new HashMap<>(productBOList.size()); |
| | | for (ProductBO productBO : productBOList) { |
| | | // if (Objects.equals(productBO.getStatus(), ProdStatusEnums.DELETE.getValue())) { |
| | | // delete(productBO.getProdId()); |
| | | // continue; |
| | | // } |
| | | map.put(productBO.getProdId(), productBO); |
| | | } |
| | | EsSearchUtil.updateBatch(map); |
| | | } |
| | | |
| | | @Override |
| | | public void updateProdComm(Long prodId) { |
| | | if (Objects.isNull(prodId)) { |
| | | return; |
| | | } |
| | | ProductBO productBO = getProductBo(prodId, EsOperationType.UPDATE_PROD_COMM); |
| | | EsSearchUtil.partialUpdate(productBO); |
| | | } |
| | | |
| | | @Override |
| | | public void updateByCategoryId(Long categoryId) { |
| | | if (Objects.isNull(categoryId)) { |
| | | return; |
| | | } |
| | | List<Long> ids = productMapper.listProdId(categoryId, null, null); |
| | | updateBatch(ids); |
| | | } |
| | | |
| | | @Override |
| | | public void updateByShopCategoryId(Long shopCategoryId) { |
| | | if (Objects.isNull(shopCategoryId)) { |
| | | return; |
| | | } |
| | | List<Long> ids = productMapper.listProdId(null, shopCategoryId, null); |
| | | updateBatch(ids); |
| | | } |
| | | |
| | | @Override |
| | | public void updateSoldNum(Long prodId) { |
| | | if (Objects.isNull(prodId)) { |
| | | return ; |
| | | } |
| | | ProductBO productBO = getProductBo(prodId, EsOperationType.UPDATE_SOLD_NUM); |
| | | EsSearchUtil.partialUpdate(productBO); |
| | | } |
| | | |
| | | @Override |
| | | public void updateSoldNumBatch(List<Long> ids) { |
| | | if (CollUtil.isEmpty(ids)) { |
| | | return ; |
| | | } |
| | | List<ProductBO> productList = getProductBo(ids, EsOperationType.UPDATE_SOLD_NUM); |
| | | for (ProductBO productBO : productList) { |
| | | EsSearchUtil.partialUpdate(productBO); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void updateByShopId(Long shopId) { |
| | | if (Objects.isNull(shopId)) { |
| | | return; |
| | | } |
| | | List<Long> ids = productMapper.listProdId(null, null, shopId); |
| | | updateBatch(ids); |
| | | } |
| | | |
| | | @Override |
| | | public void delete(Long prodId) { |
| | | if (Objects.isNull(prodId)) { |
| | | return; |
| | | } |
| | | EsSearchUtil.delete(prodId); |
| | | } |
| | | |
| | | @Override |
| | | public void deleteBatch(List<Long> ids) { |
| | | if (CollUtil.isEmpty(ids)) { |
| | | return; |
| | | } |
| | | EsSearchUtil.deleteBatch(ids); |
| | | } |
| | | |
| | | @Override |
| | | public void updateByGroupId(Long id) { |
| | | if (Objects.isNull(id)) { |
| | | return; |
| | | } |
| | | List<Product> products = productMapper.selectList(new LambdaQueryWrapper<Product>() |
| | | .eq(Product::getProdType, ProdType.PROD_TYPE_GROUP.value()) |
| | | .eq(Product::getActivityId, id)); |
| | | List<Long> prodIds = products.stream().map(Product::getProdId).collect(Collectors.toList()); |
| | | updateBatch(prodIds); |
| | | } |
| | | |
| | | @Override |
| | | public void changeProdStockBatch(List<EsProdUpdateVO> prodList) { |
| | | if (CollUtil.isEmpty(prodList)) { |
| | | return; |
| | | } |
| | | Map<Long, Script> map = new HashMap<>(prodList.size()); |
| | | for (EsProdUpdateVO esProdUpdateVO : prodList) { |
| | | String code = "-= "; |
| | | if (Objects.equals(esProdUpdateVO.getType(), 1)) { |
| | | code = "+= "; |
| | | } |
| | | Script script = new Script(ScriptType.INLINE, |
| | | "painless", |
| | | "ctx._source.totalStocks " + code + esProdUpdateVO.getCount(), |
| | | Collections.emptyMap()); |
| | | map.put(esProdUpdateVO.getProdId(), script); |
| | | } |
| | | EsSearchUtil.updateStockByPainless(map); |
| | | } |
| | | |
| | | @Override |
| | | public void changeProdSoldBatch(List<EsProdUpdateVO> prodList) { |
| | | if (CollUtil.isEmpty(prodList)) { |
| | | return; |
| | | } |
| | | Map<Long, Script> map = new HashMap<>(prodList.size()); |
| | | for (EsProdUpdateVO esProdUpdateVO : prodList) { |
| | | String code = "-= "; |
| | | if (Objects.equals(esProdUpdateVO.getType(), 1)) { |
| | | code = "+= "; |
| | | } |
| | | code = "ctx._source.soldNum " + code + esProdUpdateVO.getCount() + ";" + "ctx._source.actualSoldNum " + code + esProdUpdateVO.getCount(); |
| | | Script script = new Script(ScriptType.INLINE, |
| | | "painless", |
| | | code, |
| | | Collections.emptyMap()); |
| | | map.put(esProdUpdateVO.getProdId(), script); |
| | | } |
| | | EsSearchUtil.updateStockByPainless(map); |
| | | } |
| | | |
| | | /** |
| | | * 获取商品信息 |
| | | * @param prodId 商品id |
| | | * @return |
| | | */ |
| | | private ProductBO getProductBo(Long prodId) { |
| | | if (Objects.isNull(prodId)) { |
| | | return null; |
| | | } |
| | | List<ProductBO> productList = getProductBo(Collections.singletonList(prodId)); |
| | | if (CollUtil.isEmpty(productList)) { |
| | | return null; |
| | | } |
| | | return productList.get(0); |
| | | } |
| | | |
| | | /** |
| | | * 获取商品信息 |
| | | * @param prodId 商品id |
| | | * @return |
| | | */ |
| | | private ProductBO getProductBo(Long prodId, EsOperationType operationType) { |
| | | if (Objects.isNull(prodId)) { |
| | | return null; |
| | | } |
| | | List<ProductBO> productList = getProductBo(Collections.singletonList(prodId), operationType); |
| | | if (CollUtil.isEmpty(productList)) { |
| | | return null; |
| | | } |
| | | return productList.get(0); |
| | | } |
| | | |
| | | /** |
| | | * 获取商品信息 |
| | | * @param prodIds 商品id |
| | | * @return |
| | | */ |
| | | private List<ProductBO> getProductBo(List<Long> prodIds) { |
| | | return listProductBo(prodIds, null); |
| | | } |
| | | |
| | | /** |
| | | * 获取商品信息 |
| | | * @param prodIds 商品id |
| | | * @return |
| | | */ |
| | | private List<ProductBO> getProductBo(List<Long> prodIds, EsOperationType operationType) { |
| | | return listProductBo(prodIds, operationType); |
| | | } |
| | | |
| | | /** |
| | | * 获取商品信息 |
| | | * @param prodIds 商品id列表 |
| | | * @return |
| | | */ |
| | | private List<ProductBO> listProductBo(List<Long> prodIds, EsOperationType operationType) { |
| | | if (CollUtil.isEmpty(prodIds)) { |
| | | return null; |
| | | } |
| | | List<ProductBO> productList = new ArrayList<>(); |
| | | try { |
| | | eventPublisher.publishEvent(new EsProductEvent(prodIds, productList, operationType)); |
| | | } catch (Exception e) { |
| | | log.error("获取es商品数据异常:{}", e); |
| | | } |
| | | if (CollUtil.isEmpty(productList) || Objects.isNull(productList.get(0))) { |
| | | log.error("商品id为:{}, type:{}的商品数据异常!", prodIds, operationType.value()); |
| | | return null; |
| | | } |
| | | return productList; |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.search.common.service.impl; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.collection.CollectionUtil; |
| | | import cn.hutool.core.util.ArrayUtil; |
| | | import cn.hutool.core.util.BooleanUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.hutool.poi.excel.ExcelWriter; |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.yami.shop.bean.enums.ProdStatusEnums; |
| | | import com.yami.shop.bean.enums.ProdType; |
| | | import com.yami.shop.bean.model.Category; |
| | | import com.yami.shop.bean.param.EsProductParam; |
| | | import com.yami.shop.bean.param.ProductExportParam; |
| | | import com.yami.shop.bean.vo.search.EsProductSearchVO; |
| | | import com.yami.shop.bean.vo.search.ProductSearchVO; |
| | | import com.yami.shop.common.enums.StatusEnum; |
| | | import com.yami.shop.common.i18n.I18nMessage; |
| | | import com.yami.shop.common.i18n.LanguageEnum; |
| | | import com.yami.shop.common.util.PoiExcelUtil; |
| | | import com.yami.shop.search.common.constant.EsConstant; |
| | | import com.yami.shop.search.common.constant.EsIndexEnum; |
| | | import com.yami.shop.search.common.constant.EsProductSortEnum; |
| | | import com.yami.shop.search.common.param.EsPageParam; |
| | | import com.yami.shop.search.common.service.SearchProductService; |
| | | import com.yami.shop.search.common.util.EsSearchUtil; |
| | | import com.yami.shop.search.common.util.SearchResponseUtil; |
| | | import com.yami.shop.search.common.vo.EsPageVO; |
| | | import com.yami.shop.service.ProductExcelService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.apache.poi.ss.usermodel.Sheet; |
| | | import org.apache.poi.ss.usermodel.Workbook; |
| | | import org.elasticsearch.action.search.SearchRequest; |
| | | import org.elasticsearch.action.search.SearchResponse; |
| | | import org.elasticsearch.action.search.SearchScrollRequest; |
| | | import org.elasticsearch.common.lucene.search.function.CombineFunction; |
| | | import org.elasticsearch.common.lucene.search.function.FieldValueFactorFunction; |
| | | import org.elasticsearch.common.lucene.search.function.FunctionScoreQuery; |
| | | import org.elasticsearch.core.TimeValue; |
| | | import org.elasticsearch.index.query.BoolQueryBuilder; |
| | | import org.elasticsearch.index.query.QueryBuilders; |
| | | import org.elasticsearch.index.query.functionscore.FieldValueFactorFunctionBuilder; |
| | | import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder; |
| | | import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilder; |
| | | import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders; |
| | | import org.elasticsearch.search.Scroll; |
| | | import org.elasticsearch.search.SearchHit; |
| | | import org.elasticsearch.search.SearchHits; |
| | | import org.elasticsearch.search.aggregations.AggregationBuilders; |
| | | import org.elasticsearch.search.builder.SearchSourceBuilder; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * @author Yami |
| | | */ |
| | | @Service |
| | | @Slf4j |
| | | @RequiredArgsConstructor |
| | | public class SearchProductServiceImpl implements SearchProductService { |
| | | |
| | | private final ProductExcelService productExcelService; |
| | | |
| | | /** |
| | | * 通过搜索信息分页搜索es数据并聚合返回的信息 |
| | | * @param pageParam 分页数据 |
| | | * @param productParam 商品搜索条件 |
| | | * @return 搜索结果 |
| | | */ |
| | | @Override |
| | | public EsPageVO<EsProductSearchVO> page(EsPageParam pageParam, EsProductParam productParam, Boolean isAgg) { |
| | | if (Objects.isNull(productParam.getAppDisplay())) { |
| | | productParam.setAppDisplay(Boolean.TRUE); |
| | | } |
| | | SearchResponse response = pageSearchResult(pageParam, productParam, isAgg); |
| | | return buildSearchResult(pageParam,response); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取搜索扩展信息 |
| | | * @param pageParam 分页数据 |
| | | * @param productParam 商品搜索条件 |
| | | * @return 搜索结果 |
| | | */ |
| | | @Override |
| | | public EsProductSearchVO searchExtension(EsPageParam pageParam, EsProductParam productParam) { |
| | | EsProductParam newEsProductParam = new EsProductParam(); |
| | | newEsProductParam.setKeyword(productParam.getKeyword()); |
| | | newEsProductParam.setPrimaryCategoryId(productParam.getPrimaryCategoryId()); |
| | | newEsProductParam.setSecondaryCategoryId(productParam.getSecondaryCategoryId()); |
| | | newEsProductParam.setShopCategoryId(productParam.getShopCategoryId()); |
| | | pageParam.setSize(0); |
| | | SearchResponse response = pageSearchResult(pageParam, newEsProductParam, Boolean.TRUE); |
| | | return SearchResponseUtil.getProductSearch(response); |
| | | } |
| | | |
| | | /** |
| | | * 根据spuId列表,获取spu信息 |
| | | * @param productParam 商品搜索条件 |
| | | * @return spu列表 |
| | | */ |
| | | @Override |
| | | public List<ProductSearchVO> listSpuByProdIds(EsProductParam productParam) { |
| | | EsPageParam pageParam = new EsPageParam(); |
| | | pageParam.setCurrent(1); |
| | | pageParam.setSize(productParam.getProdIds().size()); |
| | | SearchResponse response = pageSearchResult(pageParam, productParam, Boolean.FALSE); |
| | | return SearchResponseUtil.buildSpuSearchList(response.getHits()); |
| | | } |
| | | |
| | | @Override |
| | | public EsPageVO<ProductSearchVO> adminPage(EsPageParam pageParam, EsProductParam productParam) { |
| | | EsPageVO<ProductSearchVO> result = new EsPageVO<>(); |
| | | SearchResponse response = pageSearchResult(pageParam, productParam, Boolean.FALSE); |
| | | // 商品信息 |
| | | result.setRecords(SearchResponseUtil.buildSpuSearchList(response.getHits())); |
| | | // 分页信息 |
| | | SearchResponseUtil.buildSearchPage(pageParam, result, response); |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | | public List<ProductSearchVO> simpleList(List<Long> spuIds) { |
| | | EsProductParam productParam = new EsProductParam(); |
| | | productParam.setFetchSource(EsConstant.SIMPLE_FETCH_SOURCE); |
| | | productParam.setProdIds(spuIds); |
| | | productParam.setGetDelete(true); |
| | | List<ProductSearchVO> list = listSpuByProdIds(productParam); |
| | | return list; |
| | | } |
| | | |
| | | @Override |
| | | public EsPageVO<ProductSearchVO> renovationPage(EsPageParam pageParam, EsProductParam productParam, Long size) { |
| | | if (Objects.isNull(pageParam.getSize()) || pageParam.getSize() == 0) { |
| | | return new EsPageVO(); |
| | | } |
| | | productParam.setFetchSource(EsConstant.RENOVATION_FETCH_SOURCE); |
| | | // 不需要积分商品和活动商品 |
| | | if (Objects.isNull(productParam.getProdType())) { |
| | | List<Integer> types = new ArrayList<>(); |
| | | types.add(ProdType.PROD_TYPE_ACTIVE.value()); |
| | | types.add(ProdType.PROD_TYPE_SCORE.value()); |
| | | productParam.setMustNotProdTypes(types); |
| | | } |
| | | |
| | | // 如果不是搜索指定商品,就只查询可以在用户端显示的商品 |
| | | if (CollUtil.isEmpty(productParam.getProdIds())) { |
| | | productParam.setAppDisplay(Boolean.TRUE); |
| | | } |
| | | |
| | | EsPageVO<ProductSearchVO> searchPage = this.adminPage(pageParam, productParam); |
| | | long currentTime = System.currentTimeMillis(); |
| | | |
| | | for (ProductSearchVO record : searchPage.getRecords()) { |
| | | // 不是秒杀或者团购商品,或者活动还没开始的商品,就不用处理活动价格 |
| | | boolean notHandleActivityPrice = (!Objects.equals(record.getProdType(), ProdType.PROD_TYPE_GROUP.value()) && |
| | | !Objects.equals(record.getProdType(), ProdType.PROD_TYPE_SECKILL.value())) || |
| | | Objects.isNull(record.getActivityStartTime()) || |
| | | record.getActivityStartTime() > currentTime; |
| | | if (notHandleActivityPrice) { |
| | | continue; |
| | | } |
| | | record.setOriPrice(record.getPrice()); |
| | | record.setPrice(record.getActivityPrice()); |
| | | record.setActivityPrice(null); |
| | | record.setActivityOriginalPrice(null); |
| | | } |
| | | //TODO 以后优化,瀑布流装修商品重新排序 |
| | | handleProds(productParam, searchPage,size); |
| | | return searchPage; |
| | | } |
| | | |
| | | @Override |
| | | public void export(HttpServletResponse response, EsProductParam productParam) { |
| | | productParam.setFetchSource(EsConstant.EXCEL_FETCH_SOURCE); |
| | | productParam.setAppDisplay(Boolean.FALSE); |
| | | ExcelWriter writer = productExcelService.getProdExcelWriter(productParam.getShopId()); |
| | | try (Workbook workbook = writer.getWorkbook()) { |
| | | Sheet sheet = writer.getSheet(); |
| | | // excel下拉数据列表组装 |
| | | productExcelService.dropDownList(productParam.getShopId(), sheet, workbook); |
| | | writerProdToExcel(writer, productParam); |
| | | PoiExcelUtil.writeExcel(response, writer); |
| | | } catch (Exception e) { |
| | | log.error("Exception:", e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 瀑布流装修商品排序 |
| | | * @param productParam |
| | | * @param searchPage |
| | | * @param size |
| | | */ |
| | | private void handleProds(EsProductParam productParam, EsPageVO<ProductSearchVO> searchPage, Long size) { |
| | | if(!Objects.equals(productParam.getShowSpuType(),1) || CollectionUtils.isEmpty(productParam.getProdIds())) { |
| | | return; |
| | | } |
| | | searchPage.setTotal(Objects.isNull(size) ? searchPage.getTotal() : size); |
| | | List<ProductSearchVO> productSearchList = new ArrayList<>(); |
| | | Map<Long, ProductSearchVO> prodMap = searchPage.getRecords().stream().collect(Collectors.toMap(ProductSearchVO::getProdId, prod -> prod)); |
| | | for (Object prodId : productParam.getProdIds()) { |
| | | if(!prodMap.containsKey(Long.valueOf(String.valueOf(prodId)))){ |
| | | continue; |
| | | } |
| | | productSearchList.add(prodMap.get(Long.valueOf(String.valueOf(prodId)))); |
| | | } |
| | | searchPage.setRecords(productSearchList); |
| | | } |
| | | |
| | | /** |
| | | * 写入导出的商品数据 |
| | | * 使用es的scroll方法来滚动查询es的数据,可以有效的解决大数据容量读取的限制 |
| | | * @param writer |
| | | * @param param |
| | | */ |
| | | private void writerProdToExcel(ExcelWriter writer, EsProductParam param) { |
| | | |
| | | int row = 1; |
| | | //设置查询超时时间 |
| | | Scroll scroll = new Scroll(TimeValue.timeValueMinutes(5L)); |
| | | |
| | | Integer lang = I18nMessage.getDbLang(); |
| | | |
| | | SearchRequest searchRequest = buildScrollSearchRequest(param, scroll, lang); |
| | | // 进行第一次滚动查询 |
| | | SearchResponse searchResponse = EsSearchUtil.search(searchRequest); |
| | | |
| | | // 将商品数据写入excel |
| | | List<ProductExportParam> prodList = new ArrayList<>(); |
| | | for (SearchHit hit : searchResponse.getHits().getHits()) { |
| | | prodList.add(JSON.parseObject(hit.getSourceAsString(), ProductExportParam.class)); |
| | | } |
| | | List<Category> platformCategoryList = productExcelService.listPlatformCategory(param.getShopId()); |
| | | Map<Long, String> categoryMap = platformCategoryList.stream().collect(Collectors.toMap(Category::getCategoryId, Category::getCategoryName)); |
| | | row = productExcelService.writerProdToExcel(prodList, writer, param.getShopId(), row, categoryMap); |
| | | |
| | | SearchHits hits= searchResponse.getHits(); |
| | | /** |
| | | *在这个位置已经读到了前一千条数据,可以在这先对这一千数据进行处理。下面滚动查询剩下的数据 |
| | | */ |
| | | //记录要滚动的ID |
| | | String scrollId = searchResponse.getScrollId(); |
| | | //滚动查询部分,将从第1001笔数据开始取 |
| | | SearchHit[] hitsScroll = hits.getHits(); |
| | | while (hitsScroll != null && hitsScroll.length > 0 ) { |
| | | //构造滚动查询条件 |
| | | SearchScrollRequest searchScrollRequest = new SearchScrollRequest(scrollId); |
| | | searchScrollRequest.scroll(scroll); |
| | | searchResponse = EsSearchUtil.scroll(searchScrollRequest); |
| | | scrollId = searchResponse.getScrollId(); |
| | | hits = searchResponse.getHits(); |
| | | hitsScroll = hits.getHits(); |
| | | |
| | | // 将商品数据写入excel |
| | | prodList.clear(); |
| | | for (SearchHit hit : searchResponse.getHits().getHits()) { |
| | | prodList.add(JSON.parseObject(hit.getSourceAsString(), ProductExportParam.class)); |
| | | } |
| | | // 将查询的商品数据插入excel中 |
| | | row = productExcelService.writerProdToExcel(prodList, writer, param.getShopId(), row, categoryMap); |
| | | } |
| | | //清除滚动,否则影响下次查询 |
| | | EsSearchUtil.clearScroll(scrollId); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * 构建搜索结果数据 |
| | | * @param pageParam |
| | | * @param response |
| | | * @return |
| | | */ |
| | | private static EsPageVO<EsProductSearchVO> buildSearchResult(EsPageParam pageParam, SearchResponse response) { |
| | | EsPageVO<EsProductSearchVO> esPageVO = new EsPageVO<>(); |
| | | |
| | | // 1、返回的所有查询到的商品 |
| | | List<EsProductSearchVO> productSearchs = new ArrayList<>(); |
| | | productSearchs.add(SearchResponseUtil.getProductSearch(response)); |
| | | esPageVO.setRecords(productSearchs); |
| | | |
| | | // 2、分页信息 |
| | | SearchResponseUtil.buildSearchPage(pageParam, esPageVO, response); |
| | | return esPageVO; |
| | | } |
| | | |
| | | /** |
| | | * 通过搜索信息分页搜索es数据的信息 |
| | | * @param pageParam 分页数据 |
| | | * @param productParam 商品搜索条件 |
| | | * @param isAgg true:聚合搜索 false:非聚合搜索 null:非聚合搜索 |
| | | * @return 搜索结果 |
| | | */ |
| | | private SearchResponse pageSearchResult(EsPageParam pageParam, EsProductParam productParam, Boolean isAgg) { |
| | | //1、准备检索请求 |
| | | SearchRequest searchRequest = buildSearchRequest(pageParam, productParam, isAgg); |
| | | return EsSearchUtil.search(searchRequest); |
| | | } |
| | | |
| | | /** |
| | | * 准备滚动检索请求 |
| | | * |
| | | * @param param 搜索参数 |
| | | * @param lang |
| | | * @return |
| | | */ |
| | | private SearchRequest buildScrollSearchRequest(EsProductParam param, Scroll scroll, Integer lang) { |
| | | // 构建bool-query |
| | | BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder(); |
| | | |
| | | SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); |
| | | |
| | | // 指定返回数组中的字段 |
| | | if (ArrayUtil.isNotEmpty(param.getFetchSource())) { |
| | | searchSourceBuilder.fetchSource(param.getFetchSource(), null); |
| | | } |
| | | |
| | | // 过滤 |
| | | filterQueryIfNecessary(param, boolQueryBuilder); |
| | | |
| | | // 关键字搜索 |
| | | keywordSearch(param, boolQueryBuilder, lang); |
| | | |
| | | // 排序 |
| | | sort(param, searchSourceBuilder, boolQueryBuilder, lang); |
| | | |
| | | //设置最多一次能够取出1000笔数据,从第1001笔数据开始,将开启滚动查询 |
| | | //PS:滚动查询也属于这一次查询,只不过因为一次查不完,分多次查 |
| | | searchSourceBuilder.size(1000); |
| | | |
| | | |
| | | log.debug("构建的DSL语句 {}",searchSourceBuilder.toString()); |
| | | |
| | | SearchRequest searchRequest = new SearchRequest(new String[]{EsIndexEnum.PRODUCT.value()}, searchSourceBuilder); |
| | | //将滚动放入 |
| | | searchRequest.scroll(scroll); |
| | | return searchRequest; |
| | | } |
| | | |
| | | /** |
| | | * 准备检索请求 |
| | | * @param pageParam 分页参数 |
| | | * @param param 搜索参数 |
| | | * @param isAgg true:聚合搜索 false:非聚合搜索 null:非聚合搜索 |
| | | * @return |
| | | */ |
| | | private SearchRequest buildSearchRequest(EsPageParam pageParam,EsProductParam param, Boolean isAgg) { |
| | | if (Objects.isNull(param.getAppDisplay())) { |
| | | param.setAppDisplay(Boolean.FALSE); |
| | | } |
| | | SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); |
| | | Integer lang = I18nMessage.getLang(); |
| | | |
| | | // 指定返回数组中的字段 |
| | | if (ArrayUtil.isNotEmpty(param.getFetchSource())) { |
| | | searchSourceBuilder.fetchSource(param.getFetchSource(), null); |
| | | } else { |
| | | searchSourceBuilder.fetchSource(EsConstant.APP_FETCH_SOURCE, null); |
| | | } |
| | | |
| | | // 构建bool-query |
| | | BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder(); |
| | | |
| | | // 过滤 |
| | | filterQueryIfNecessary(param, boolQueryBuilder); |
| | | |
| | | // 关键字搜索 |
| | | keywordSearch(param, boolQueryBuilder, lang); |
| | | |
| | | // 排序 |
| | | sort(param, searchSourceBuilder, boolQueryBuilder, lang); |
| | | |
| | | //分页 |
| | | if (Objects.nonNull(pageParam)) { |
| | | if (pageParam.getCurrent() <= 0) { |
| | | pageParam.setCurrent(1); |
| | | } |
| | | searchSourceBuilder.from((pageParam.getCurrent()-1)*pageParam.getSize()); |
| | | searchSourceBuilder.size(pageParam.getSize()); |
| | | } |
| | | |
| | | // 进行聚合分析 |
| | | agg(param, searchSourceBuilder, isAgg); |
| | | |
| | | log.debug("构建的DSL语句 {}",searchSourceBuilder.toString()); |
| | | return new SearchRequest(new String[]{EsIndexEnum.PRODUCT.value()},searchSourceBuilder); |
| | | } |
| | | |
| | | /** |
| | | * 聚合分析 |
| | | */ |
| | | private void agg(EsProductParam param, SearchSourceBuilder searchSourceBuilder, Boolean isAgg) { |
| | | // 店铺进行聚合 |
| | | if (param.getKeyword() != null && param.getKeyword().length() > 0) { |
| | | searchSourceBuilder.aggregation(AggregationBuilders.terms(EsConstant.SHOP).field(EsConstant.SHOP_ID).size(1)); |
| | | } |
| | | if (Objects.isNull(isAgg) || !isAgg) { |
| | | return; |
| | | } |
| | | // 品牌聚合 |
| | | searchSourceBuilder.aggregation(EsSearchUtil.nestedAggregation(EsConstant.BRAND, EsConstant.BRAND_UNION_ID, EsConstant.BRAND_ID, EsConstant.BRAND_INCLUDE)); |
| | | |
| | | // 搜索平台商品,按照平台分类信息进行聚合 |
| | | if (Objects.isNull(param.getShopId()) && Objects.isNull(param.getCategoryId())) { |
| | | searchSourceBuilder.aggregation(EsSearchUtil.nestedAggregation(EsConstant.CATEGORY, EsConstant.CATEGORY_UNION_ID, EsConstant.CATEGORY_ID, EsConstant.CATEGORY_INCLUDE)); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 关键字搜索 |
| | | */ |
| | | private void keywordSearch(EsProductParam param, BoolQueryBuilder boolQueryBuilder, Integer lang) { |
| | | if (StrUtil.isBlank(param.getKeyword())) { |
| | | return; |
| | | } |
| | | // 创建查询语句 ES中must和should不能同时使用 同时使用should失效 嵌套多个must 将should条件拼接在一个must中即可 |
| | | BoolQueryBuilder keywordShouldQuery = QueryBuilders.boolQuery(); |
| | | // 提升商品名称搜索的权重 |
| | | if (Objects.equals(lang, LanguageEnum.LANGUAGE_ZH_CN.getLang())) { |
| | | keywordShouldQuery.should(QueryBuilders.matchQuery(EsConstant.PROD_NAME_ZH, param.getKeyword()).boost(10)); |
| | | } else { |
| | | keywordShouldQuery.should(QueryBuilders.matchQuery(EsConstant.PROD_NAME_EN, param.getKeyword()).boost(10)); |
| | | } |
| | | |
| | | |
| | | if (param.getKeyword().length()>1) { |
| | | // 卖点,不分词 |
| | | if (Objects.equals(lang, LanguageEnum.LANGUAGE_ZH_CN.getLang())) { |
| | | keywordShouldQuery.should(QueryBuilders.matchPhraseQuery(EsConstant.BRIEF_ZH, param.getKeyword()).boost(2)); |
| | | } else { |
| | | keywordShouldQuery.should(QueryBuilders.matchPhraseQuery(EsConstant.BRIEF_EN, param.getKeyword()).boost(2)); |
| | | } |
| | | // 店铺名,不分词 |
| | | keywordShouldQuery.should(QueryBuilders.matchPhraseQuery(EsConstant.SHOP_NAME, param.getKeyword())); |
| | | } |
| | | boolQueryBuilder.must(keywordShouldQuery); |
| | | } |
| | | |
| | | /** |
| | | * 进行排序 |
| | | */ |
| | | private void sort(EsProductParam param, SearchSourceBuilder searchSourceBuilder, BoolQueryBuilder boolQueryBuilder, Integer lang) { |
| | | // 用户端、商家端、平台端自定义排序 |
| | | if (Objects.nonNull(param.getSort())) { |
| | | for (EsProductSortEnum enumValue : EsProductSortEnum.values()) { |
| | | if (!Objects.equals(enumValue.value(), param.getSort())) { |
| | | continue; |
| | | } |
| | | searchSourceBuilder.sort(enumValue.param(), enumValue.order()); |
| | | } |
| | | //封装所有的查询条件(没有function score) |
| | | searchSourceBuilder.query(boolQueryBuilder); |
| | | return; |
| | | } |
| | | |
| | | // 1.关键字排序 -- 没有指定排序规则,且是关键字搜索的查询,统一按关键字优先排序(防止关键字搜素时,关键字的商品没有优先显示) |
| | | // 2.用户端默认排序 -- 如果排序规则设为空,则按照一定的算分规则进行排序,否则按照用户指定排序规则进行排序() |
| | | if (StrUtil.isNotBlank(param.getKeyword()) || param.getAppDisplay()) { |
| | | keywordSort(param, searchSourceBuilder, boolQueryBuilder, lang); |
| | | return; |
| | | } |
| | | if (Objects.equals(param.getShowSpuType(),1)) { |
| | | |
| | | FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(boolQueryBuilder).boostMode(CombineFunction.SUM); |
| | | searchSourceBuilder.query(functionScoreQueryBuilder); |
| | | return; |
| | | } |
| | | |
| | | // 商家、平台默认排序--商品序号 倒序, 创建时间 倒序 |
| | | if (Objects.nonNull(param.getShopId())) { |
| | | // 商家端优先显示序号大的商品 |
| | | searchSourceBuilder.sort(EsProductSortEnum.SEQ_DESC.param(), EsProductSortEnum.SEQ_DESC.order()); |
| | | } else { |
| | | // 平台端优先置顶的商品, 再到销量(实际销量+注水销量) |
| | | searchSourceBuilder.sort(EsProductSortEnum.IS_TOP_DESC.param(), EsProductSortEnum.IS_TOP_DESC.order()); |
| | | searchSourceBuilder.sort(EsProductSortEnum.SALE_NUM_DESC.param(), EsProductSortEnum.SALE_NUM_DESC.order()); |
| | | } |
| | | searchSourceBuilder.sort(EsProductSortEnum.CREATE_TIME_DESC.param(), EsProductSortEnum.CREATE_TIME_DESC.order()); |
| | | searchSourceBuilder.sort(EsProductSortEnum.PROD_ID_DESC.param(), EsProductSortEnum.PROD_ID_DESC.order()); |
| | | searchSourceBuilder.query(boolQueryBuilder); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 关键字搜索排序 |
| | | * @param param |
| | | * @param searchSourceBuilder |
| | | * @param boolQueryBuilder |
| | | * @param lang |
| | | */ |
| | | private void keywordSort(EsProductParam param, SearchSourceBuilder searchSourceBuilder, BoolQueryBuilder boolQueryBuilder, Integer lang) { |
| | | List<FunctionScoreQueryBuilder.FilterFunctionBuilder> filterFunctionBuilders = new ArrayList<>(); |
| | | // 关键字搜索,优先匹配 |
| | | if (StrUtil.isNotBlank(param.getKeyword())) { |
| | | FunctionScoreQueryBuilder.FilterFunctionBuilder spuName; |
| | | // 权重调大,防止销量大的商品排在关键词商品的前面 |
| | | if (Objects.equals(lang, LanguageEnum.LANGUAGE_ZH_CN.getLang())) { |
| | | spuName = new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.termQuery(EsConstant.PROD_NAME_ZH, param.getKeyword()), ScoreFunctionBuilders.weightFactorFunction(200)); |
| | | } else { |
| | | spuName = new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.termQuery(EsConstant.PROD_NAME_EN, param.getKeyword()), ScoreFunctionBuilders.weightFactorFunction(200)); |
| | | } |
| | | filterFunctionBuilders.add(spuName); |
| | | } |
| | | |
| | | // 用户端默认排序优先使用是否置顶参数 |
| | | FunctionScoreQueryBuilder.FilterFunctionBuilder isTop = new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.termQuery(EsConstant.IS_TOP, 50), ScoreFunctionBuilders.weightFactorFunction(1)); |
| | | filterFunctionBuilders.add(isTop); |
| | | |
| | | // 评论数 log1p |
| | | ScoreFunctionBuilder<FieldValueFactorFunctionBuilder> commentNumScoreFunction = new FieldValueFactorFunctionBuilder(EsConstant.COMMENT_NUM).modifier(FieldValueFactorFunction.Modifier.LOG1P).factor(0.5f); |
| | | filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(commentNumScoreFunction)); |
| | | // 销量数 log1p |
| | | ScoreFunctionBuilder<FieldValueFactorFunctionBuilder> saleNumScoreFunction = new FieldValueFactorFunctionBuilder(EsConstant.SOLD_NUM).modifier(FieldValueFactorFunction.Modifier.LOG1P).factor(0.5f); |
| | | filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(saleNumScoreFunction)); |
| | | |
| | | filterFunctionBuilders.toArray(); |
| | | |
| | | FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(boolQueryBuilder, ArrayUtil.toArray(filterFunctionBuilders, FunctionScoreQueryBuilder.FilterFunctionBuilder.class)) |
| | | .scoreMode(FunctionScoreQuery.ScoreMode.SUM).boostMode(CombineFunction.SUM); |
| | | // 封装所有的查询条件(带有function score) |
| | | searchSourceBuilder.query(functionScoreQueryBuilder); |
| | | } |
| | | |
| | | /** |
| | | * 过滤查询条件,如果有必要的话 |
| | | * @param param 查询条件 |
| | | * @param boolQueryBuilder 组合进boolQueryBuilder |
| | | */ |
| | | private void filterQueryIfNecessary(EsProductParam param, BoolQueryBuilder boolQueryBuilder) { |
| | | |
| | | // 用户端搜索 |
| | | if(param.getAppDisplay()) { |
| | | boolQueryBuilder.filter(QueryBuilders.termQuery(EsConstant.APP_DISPLAY, param.getAppDisplay())); |
| | | } |
| | | // 商品(状态、库存、商品类型、商品id、商品id列表, 组合商品,配送方式,是否置顶) |
| | | spuFilterQuery(param, boolQueryBuilder); |
| | | |
| | | // 分类(商家分类,平台一二三级分类) |
| | | categoryFilterQuery(param, boolQueryBuilder); |
| | | |
| | | // 活动 (活动商品id) |
| | | activityFilterQuery(param, boolQueryBuilder); |
| | | |
| | | // 商品扩展信息筛选(店铺id、店铺类型、店铺名称、品牌) |
| | | extensionFilterQuery(param, boolQueryBuilder); |
| | | |
| | | // 范围筛选(价格、销量) |
| | | rangeFilterQuery(param, boolQueryBuilder); |
| | | } |
| | | |
| | | /** |
| | | * 范围过滤 |
| | | * @param param 查询条件 |
| | | * @param boolQueryBuilder |
| | | */ |
| | | private void rangeFilterQuery(EsProductParam param, BoolQueryBuilder boolQueryBuilder) { |
| | | // 价格区间 |
| | | if(param.getMinPrice() != null || param.getMaxPrice() != null){ |
| | | boolQueryBuilder.filter(EsSearchUtil.rangeQuery(EsConstant.PRICE,param.getMinPrice(), param.getMaxPrice())); |
| | | } |
| | | // 销量区间 |
| | | if(param.getMinSaleNum() != null || param.getMaxSaleNum() != null){ |
| | | boolQueryBuilder.filter(EsSearchUtil.rangeQuery(param.getAppDisplay() ? EsConstant.SOLD_NUM : EsConstant.ACTUAL_SOLD_NUM, |
| | | param.getMinSaleNum(), param.getMaxSaleNum())); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 商品扩展信息过滤 |
| | | * @param param 查询条件 |
| | | * @param boolQueryBuilder |
| | | */ |
| | | private void extensionFilterQuery(EsProductParam param, BoolQueryBuilder boolQueryBuilder) { |
| | | // 店铺id |
| | | if(Objects.nonNull(param.getShopId())){ |
| | | boolQueryBuilder.filter(QueryBuilders.termQuery(EsConstant.SHOP_ID, param.getShopId())); |
| | | } |
| | | |
| | | // 店铺类型 |
| | | if(Objects.nonNull(param.getShopType())){ |
| | | boolQueryBuilder.filter(QueryBuilders.termQuery(EsConstant.SHOP_TYPE, param.getShopType())); |
| | | } |
| | | |
| | | // 店铺名称 |
| | | if(StrUtil.isNotBlank(param.getShopName())){ |
| | | BoolQueryBuilder keywordShouldQuery = QueryBuilders.boolQuery() |
| | | .should(QueryBuilders.matchQuery(EsConstant.SHOP_NAME, param.getShopName())); |
| | | boolQueryBuilder.must(keywordShouldQuery); |
| | | } |
| | | |
| | | |
| | | // 品牌 |
| | | if(StrUtil.isNotBlank(param.getBrandIds())){ |
| | | boolQueryBuilder.filter(EsSearchUtil.nestedQueryByArray(EsConstant.BRAND, EsConstant.BRAND_UNION_ID, param.getBrandIds())); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 商品活动信息过滤 |
| | | * @param param 查询条件 |
| | | * @param boolQueryBuilder |
| | | */ |
| | | private void activityFilterQuery(EsProductParam param, BoolQueryBuilder boolQueryBuilder) { |
| | | // 商品活动Id |
| | | if(Objects.nonNull(param.getActivityId())){ |
| | | boolQueryBuilder.filter(QueryBuilders.termQuery(EsConstant.ACTIVITY_ID, param.getActivityId())); |
| | | boolQueryBuilder.filter(QueryBuilders.termQuery(EsConstant.PROD_TYPE, param.getProdType())); |
| | | } |
| | | if (Objects.equals(param.getProdType(), ProdType.PROD_TYPE_GROUP.value()) && param.getAppDisplay()){ |
| | | boolQueryBuilder.filter(EsSearchUtil.rangeQuery(EsConstant.ACTIVITY_START_TIME, null, System.currentTimeMillis())); |
| | | } else if (Objects.equals(param.getProdType(), ProdType.PROD_TYPE_SECKILL.value()) && param.getAppDisplay()){ |
| | | boolQueryBuilder.must(QueryBuilders.existsQuery(EsConstant.ACTIVITY_START_TIME)); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 商品信息过滤 |
| | | * @param param 查询条件 |
| | | * @param boolQueryBuilder |
| | | */ |
| | | private void spuFilterQuery(EsProductParam param, BoolQueryBuilder boolQueryBuilder) { |
| | | // spu状态 |
| | | List<Integer> statusList = new ArrayList<>(); |
| | | if (Objects.nonNull(param.getStatus())) { |
| | | statusList.add(param.getStatus()); |
| | | } |
| | | // 装修以及定时任务获取删除商品 |
| | | else if (!BooleanUtil.isTrue(param.getGetDelete())) { |
| | | statusList.add(StatusEnum.ENABLE.value()); |
| | | statusList.add(StatusEnum.DISABLE.value()); |
| | | statusList.add(StatusEnum.OFFLINE.value()); |
| | | statusList.add(StatusEnum.WAIT_AUDIT.value()); |
| | | statusList.add(ProdStatusEnums.AUDIT.getValue()); |
| | | } |
| | | if(CollUtil.isNotEmpty(statusList)) { |
| | | boolQueryBuilder.filter(QueryBuilders.termsQuery(EsConstant.STATUS, statusList)); |
| | | } |
| | | |
| | | // 是否有库存 |
| | | if(Objects.nonNull(param.getHasStock())){ |
| | | boolQueryBuilder.filter(QueryBuilders.termQuery(EsConstant.HAS_STOCK, BooleanUtil.isTrue(param.getHasStock()))); |
| | | } |
| | | // 商品类型 |
| | | if(Objects.nonNull(param.getProdType())){ |
| | | boolQueryBuilder.filter(QueryBuilders.termQuery(EsConstant.PROD_TYPE, param.getProdType())); |
| | | } |
| | | // 不匹配的商品类型 |
| | | if(CollUtil.isNotEmpty(param.getMustNotProdTypes())){ |
| | | for (Integer prodType : param.getMustNotProdTypes()) { |
| | | boolQueryBuilder.mustNot(QueryBuilders.termQuery(EsConstant.PROD_TYPE, prodType.toString())); |
| | | } |
| | | } |
| | | // 是否过滤活动商品 |
| | | if(Objects.nonNull(param.getIsActive()) && param.getIsActive() == 1){ |
| | | boolQueryBuilder.mustNot(QueryBuilders.termQuery(EsConstant.PROD_TYPE, ProdType.PROD_TYPE_ACTIVE.value())); |
| | | } |
| | | // 商品类别 |
| | | if(Objects.nonNull(param.getMold())){ |
| | | boolQueryBuilder.filter(QueryBuilders.termQuery(EsConstant.MOLD, param.getMold())); |
| | | } |
| | | // spuId |
| | | if(Objects.nonNull(param.getProdId())){ |
| | | boolQueryBuilder.filter(QueryBuilders.termsQuery(EsConstant.PROD_ID,param.getProdId().toString())); |
| | | } |
| | | // spuId列表 |
| | | else if(CollectionUtil.isNotEmpty(param.getProdIds())){ |
| | | boolQueryBuilder.filter(QueryBuilders.termsQuery(EsConstant.PROD_ID,param.getProdIds())); |
| | | } |
| | | // 查询不在该集合中的商品 |
| | | if(Objects.nonNull(param.getSpuIdsExclude())){ |
| | | boolQueryBuilder.mustNot(QueryBuilders.termsQuery(EsConstant.PROD_ID,param.getSpuIdsExclude())); |
| | | } |
| | | // 配送方式 |
| | | if(Objects.nonNull(param.getDeliveryMode())){ |
| | | boolQueryBuilder.filter(QueryBuilders.termsQuery(EsConstant.DELIVERIES,param.getDeliveryMode().toString())); |
| | | } |
| | | // 是否置顶 |
| | | if(Objects.nonNull(param.getIsTop())){ |
| | | boolQueryBuilder.filter(QueryBuilders.termsQuery(EsConstant.IS_TOP,param.getIsTop().toString())); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 商品分类信息过滤 |
| | | * @param param |
| | | * @param boolQueryBuilder |
| | | */ |
| | | private void categoryFilterQuery(EsProductParam param, BoolQueryBuilder boolQueryBuilder) { |
| | | //商家分类 |
| | | if(Objects.nonNull(param.getShopCategoryId())){ |
| | | boolQueryBuilder.filter(QueryBuilders.termQuery(EsConstant.SHOP_CATEGORY_ID, param.getShopCategoryId())); |
| | | } |
| | | |
| | | // 平台一级分类 |
| | | if(Objects.nonNull(param.getPrimaryCategoryId())){ |
| | | boolQueryBuilder.filter(QueryBuilders.termQuery(EsConstant.PRIMARY_CATEGORY_ID, param.getPrimaryCategoryId())); |
| | | } |
| | | |
| | | // 查询不在该集合中的商品 |
| | | if(Objects.nonNull(param.getNotPrimaryCategoryId())) { |
| | | boolQueryBuilder.mustNot(QueryBuilders.termsQuery(EsConstant.PRIMARY_CATEGORY_ID, param.getNotPrimaryCategoryId().toString())); |
| | | } |
| | | |
| | | // 平台二级分类 |
| | | if(Objects.nonNull(param.getSecondaryCategoryId())){ |
| | | boolQueryBuilder.filter(QueryBuilders.termQuery(EsConstant.SECONDARY_CATEGORY_ID, param.getSecondaryCategoryId())); |
| | | } |
| | | |
| | | // 平台三级分类 |
| | | if(Objects.nonNull(param.getCategoryId())){ |
| | | boolQueryBuilder.filter(EsSearchUtil.nestedQuery(EsConstant.CATEGORY, EsConstant.CATEGORY_UNION_ID, param.getCategoryId())); |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.search.common.util; |
| | | |
| | | import cn.hutool.core.util.ArrayUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.yami.shop.bean.app.vo.SkuVO; |
| | | import com.yami.shop.bean.bo.ProductBO; |
| | | import com.yami.shop.bean.enums.ProdStatusEnums; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.util.Json; |
| | | import com.yami.shop.search.common.constant.EsConstant; |
| | | import com.yami.shop.search.common.constant.EsIndexEnum; |
| | | import org.apache.lucene.search.join.ScoreMode; |
| | | import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest; |
| | | import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest; |
| | | import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptRequest; |
| | | import org.elasticsearch.action.bulk.BulkRequest; |
| | | import org.elasticsearch.action.bulk.BulkResponse; |
| | | import org.elasticsearch.action.delete.DeleteRequest; |
| | | import org.elasticsearch.action.delete.DeleteResponse; |
| | | import org.elasticsearch.action.index.IndexRequest; |
| | | import org.elasticsearch.action.index.IndexResponse; |
| | | import org.elasticsearch.action.search.*; |
| | | import org.elasticsearch.action.update.UpdateRequest; |
| | | import org.elasticsearch.action.update.UpdateResponse; |
| | | import org.elasticsearch.client.RequestOptions; |
| | | import org.elasticsearch.client.RestHighLevelClient; |
| | | import org.elasticsearch.common.bytes.BytesReference; |
| | | import org.elasticsearch.index.query.*; |
| | | import org.elasticsearch.index.reindex.BulkByScrollResponse; |
| | | import org.elasticsearch.index.reindex.DeleteByQueryRequest; |
| | | import org.elasticsearch.script.Script; |
| | | import org.elasticsearch.script.ScriptType; |
| | | import org.elasticsearch.script.StoredScriptSource; |
| | | import org.elasticsearch.search.aggregations.AggregationBuilders; |
| | | import org.elasticsearch.search.aggregations.bucket.nested.NestedAggregationBuilder; |
| | | import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; |
| | | import org.elasticsearch.search.aggregations.metrics.TopHitsAggregationBuilder; |
| | | import org.elasticsearch.xcontent.XContentType; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * @author YXF |
| | | * @date 2021/07/29 |
| | | */ |
| | | @Component |
| | | public class EsSearchUtil { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(EsSearchUtil.class); |
| | | private static RestHighLevelClient restHighLevelClient; |
| | | |
| | | /** |
| | | * 正常来说普通方法才是属于实体对象(也就是New出来的对象)的,spring注入是在容器中实例化对象,静态变量是无法注入的 |
| | | * 所以需要通过构造方法的方式来进行注入,或者使用@PostConstruct注解 |
| | | */ |
| | | @Autowired |
| | | public EsSearchUtil(RestHighLevelClient restHighLevelClient) { |
| | | EsSearchUtil.restHighLevelClient = restHighLevelClient; |
| | | } |
| | | |
| | | |
| | | public static void save(Long id, ProductBO productBO) { |
| | | if (Objects.isNull(productBO)) { |
| | | return; |
| | | } |
| | | try { |
| | | IndexRequest request = new IndexRequest(EsIndexEnum.PRODUCT.value()) |
| | | .id(String.valueOf(id)) |
| | | .source(Objects.requireNonNull(Json.toJsonString(productBO)), XContentType.JSON); |
| | | IndexResponse indexResponse = restHighLevelClient.index(request, RequestOptions.DEFAULT); |
| | | log.info("保存商品:{}", indexResponse.toString()); |
| | | } catch (IOException e) { |
| | | log.error(e.toString()); |
| | | throw new YamiShopBindException("保存es信息异常" + e); |
| | | } |
| | | } |
| | | |
| | | |
| | | public static void saveBatch(Map<Long, ProductBO> map) { |
| | | if (map.size() == 0) { |
| | | return; |
| | | } |
| | | try { |
| | | BulkRequest request = new BulkRequest(); |
| | | for (Long id : map.keySet()) { |
| | | IndexRequest indexRequest = new IndexRequest(EsIndexEnum.PRODUCT.value()); |
| | | indexRequest.id(String.valueOf(id)); |
| | | indexRequest.source(Objects.requireNonNull(Json.toJsonString(map.get(id))), XContentType.JSON); |
| | | request.add(indexRequest); |
| | | } |
| | | BulkResponse bulkResponse = restHighLevelClient.bulk(request, RequestOptions.DEFAULT); |
| | | log.info("批量保存商品:{}", bulkResponse.toString()); |
| | | } catch (IOException e) { |
| | | log.error(e.toString()); |
| | | throw new YamiShopBindException("批量保存es信息异常" + e); |
| | | } |
| | | } |
| | | |
| | | |
| | | public static void update(ProductBO productBO) { |
| | | delete(productBO.getProdId()); |
| | | save(productBO.getProdId(), productBO); |
| | | } |
| | | |
| | | |
| | | public static void partialUpdate(ProductBO productBO) { |
| | | if (Objects.equals(productBO.getStatus(), ProdStatusEnums.DELETE.getValue())) { |
| | | delete(productBO.getProdId()); |
| | | return; |
| | | } |
| | | if (Objects.isNull(productBO)) { |
| | | return; |
| | | } |
| | | try { |
| | | UpdateRequest request = new UpdateRequest(EsIndexEnum.PRODUCT.value(), String.valueOf(productBO.getProdId())) |
| | | .doc(Json.toJsonString(productBO), XContentType.JSON); |
| | | UpdateResponse updateResponse = restHighLevelClient.update(request, RequestOptions.DEFAULT); |
| | | log.info("更新商品:{}", updateResponse.toString()); |
| | | } catch (IOException e) { |
| | | log.error("部分更新es信息异常信息:{},商品信息:{}", e, productBO); |
| | | throw new YamiShopBindException("部分更新es信息异常" + e); |
| | | } |
| | | } |
| | | |
| | | |
| | | public static void updateBatch(Map<Long, ProductBO> map) { |
| | | deleteBatch(map.keySet()); |
| | | saveBatch(map); |
| | | } |
| | | |
| | | |
| | | public static void updateStockByPainless(Map<Long, Script> prodMap) { |
| | | BulkRequest request = new BulkRequest(); |
| | | prodMap.forEach( (prodId, script) -> { |
| | | UpdateRequest updateRequest = new UpdateRequest(EsIndexEnum.PRODUCT.value(), String.valueOf(prodId)); |
| | | updateRequest.script(script); |
| | | request.add(updateRequest); |
| | | }); |
| | | try { |
| | | BulkResponse bulkResponse = restHighLevelClient.bulk(request, RequestOptions.DEFAULT); |
| | | log.info("painless脚本更新商品" + Json.toJsonString(bulkResponse)); |
| | | } catch (IOException e) { |
| | | log.error("更新es商品库存信息异常信息:{},商品信息:{}", e, prodMap); |
| | | throw new YamiShopBindException("更新es商品库存信息异常信息" + e); |
| | | } |
| | | } |
| | | |
| | | |
| | | public static void delete(Long id) { |
| | | // 删除数据 |
| | | try { |
| | | DeleteRequest request = new DeleteRequest(EsIndexEnum.PRODUCT.value(),String.valueOf(id)); |
| | | DeleteResponse deleteResponse = restHighLevelClient.delete(request,RequestOptions.DEFAULT); |
| | | log.info("删除商品:{}", deleteResponse.toString()); |
| | | } catch (IOException e) { |
| | | log.error(e.toString()); |
| | | throw new YamiShopBindException("删除es信息异常" + e); |
| | | } |
| | | } |
| | | |
| | | |
| | | public static void deleteBatch(Collection<Long> ids) { |
| | | DeleteByQueryRequest request = new DeleteByQueryRequest(EsIndexEnum.PRODUCT.value()); |
| | | request.setQuery(new TermsQueryBuilder("prodId", ids)); |
| | | try { |
| | | log.info("构建的DSL删除语句 {}", request.toString()); |
| | | BulkByScrollResponse bulkByScrollResponse = restHighLevelClient.deleteByQuery(request, RequestOptions.DEFAULT); |
| | | log.info("批量删除商品:{}", bulkByScrollResponse.toString()); |
| | | } catch (IOException e) { |
| | | log.error(e.toString()); |
| | | throw new YamiShopBindException("批量删除es信息异常:" + e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 分页检索 |
| | | */ |
| | | public static SearchResponse search(SearchRequest searchRequest) { |
| | | SearchResponse response = null; |
| | | try { |
| | | //2、执行检索请求 |
| | | response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT); |
| | | |
| | | log.debug("搜索返回结果:" + response.toString()); |
| | | } catch (IOException e) { |
| | | log.error(e.toString()); |
| | | throw new YamiShopBindException("搜索服务出了点小差,请稍后再试" + e); |
| | | } |
| | | return response; |
| | | } |
| | | |
| | | /** |
| | | * 滚动检索 |
| | | */ |
| | | public static SearchResponse scroll(SearchScrollRequest searchScrollRequest) { |
| | | SearchResponse response = null; |
| | | try { |
| | | //2、执行检索请求 |
| | | response = restHighLevelClient.scroll(searchScrollRequest, RequestOptions.DEFAULT); |
| | | |
| | | log.debug("滚动搜索返回结果:" + response.toString()); |
| | | } catch (IOException e) { |
| | | log.error(e.toString()); |
| | | throw new YamiShopBindException("滚动搜索服务出了点小差,请稍后再试" + e); |
| | | } |
| | | return response; |
| | | } |
| | | |
| | | /** |
| | | * 删除滚动 |
| | | */ |
| | | public static boolean clearScroll(String scrollId) { |
| | | |
| | | ClearScrollRequest clearScrollRequest = new ClearScrollRequest(); |
| | | clearScrollRequest.addScrollId(scrollId); |
| | | ClearScrollResponse clearScrollResponse = null; |
| | | try { |
| | | //2、执行检索请求 |
| | | clearScrollResponse = restHighLevelClient.clearScroll(clearScrollRequest, RequestOptions.DEFAULT); |
| | | } catch (IOException e) { |
| | | log.error(e.toString()); |
| | | throw new YamiShopBindException("删除滚动服务出了点小差,请稍后再试" + e); |
| | | } |
| | | if (!clearScrollResponse.isSucceeded()) { |
| | | log.error("删除滚动返回结果:" + clearScrollResponse); |
| | | throw new YamiShopBindException(""); |
| | | } |
| | | return clearScrollResponse.isSucceeded(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | public static QueryBuilder termsQueryByArray(String name, String data) { |
| | | List<String> array = StrUtil.split(data, Constant.COMMA); |
| | | return QueryBuilders.termsQuery(name, array); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | public static QueryBuilder nestedQuery(String nestedName, String name, Long data) { |
| | | return nestedQuery(nestedName, name, data.toString()); |
| | | } |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | public static QueryBuilder nestedQuery(String nestedName, String name, String data) { |
| | | BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); |
| | | boolQuery.should(QueryBuilders.termsQuery(name, data)); |
| | | return QueryBuilders.nestedQuery(nestedName, boolQuery, ScoreMode.None); |
| | | } |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | public static QueryBuilder nestedQuery(String nestedName, String name, List list) { |
| | | BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); |
| | | boolQuery.should(QueryBuilders.termsQuery(name, list)); |
| | | return QueryBuilders.nestedQuery(nestedName, boolQuery, ScoreMode.None); |
| | | } |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | public static QueryBuilder nestedQueryByArray(String nestedName, String name, String data) { |
| | | String[] ids = data.split(Constant.COMMA); |
| | | BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); |
| | | for (String brandId : ids) { |
| | | boolQuery.should(QueryBuilders.termsQuery(name, brandId)); |
| | | } |
| | | return QueryBuilders.nestedQuery(nestedName,boolQuery, ScoreMode.None); |
| | | } |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | public static RangeQueryBuilder rangeQuery(String name, Long minValue, Long maxValue) { |
| | | RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery(name); |
| | | if (Objects.nonNull(minValue)) { |
| | | rangeQueryBuilder.gte(minValue); |
| | | } |
| | | if (Objects.nonNull(maxValue)) { |
| | | rangeQueryBuilder.lte(maxValue); |
| | | } |
| | | return rangeQueryBuilder; |
| | | } |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | public static NestedAggregationBuilder nestedAggregation(String nestedName, String fieldName, String name) { |
| | | return nestedAggregation(nestedName, fieldName, name, null, null); |
| | | } |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | public static NestedAggregationBuilder nestedAggregation(String nestedName, String fieldName, String name, String[] fetchSource) { |
| | | return nestedAggregation(nestedName, fieldName, name, fetchSource, null); |
| | | } |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | public static NestedAggregationBuilder nestedAggregation(String nestedName, String fieldName, String name, Integer size) { |
| | | return nestedAggregation(nestedName, fieldName, name, null, size); |
| | | } |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | public static NestedAggregationBuilder nestedAggregation(String nestedName, String fieldName, String name, String[] fetchSource, Integer size) { |
| | | if (Objects.isNull(size)) { |
| | | size = 1; |
| | | } |
| | | NestedAggregationBuilder nested = AggregationBuilders.nested(nestedName, nestedName); |
| | | TermsAggregationBuilder terms = AggregationBuilders.terms(name).field(fieldName).size(10); |
| | | TopHitsAggregationBuilder topHits = AggregationBuilders |
| | | .topHits(EsConstant.TOP_HITS_DATA) |
| | | .size(size); |
| | | // 指定响应的数据字段 |
| | | if (ArrayUtil.isNotEmpty(fetchSource)) { |
| | | topHits.fetchSource(fetchSource, null); |
| | | } |
| | | terms.subAggregation(topHits); |
| | | nested.subAggregation(terms); |
| | | return nested; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.search.common.util; |
| | | |
| | | import com.yami.shop.bean.vo.search.*; |
| | | import com.yami.shop.common.i18n.I18nMessage; |
| | | import com.yami.shop.common.i18n.LanguageEnum; |
| | | import com.yami.shop.common.util.Json; |
| | | import com.yami.shop.search.common.constant.EsConstant; |
| | | import com.yami.shop.search.common.param.EsPageParam; |
| | | import com.yami.shop.search.common.vo.EsPageVO; |
| | | import org.elasticsearch.action.search.SearchResponse; |
| | | import org.elasticsearch.search.SearchHit; |
| | | import org.elasticsearch.search.SearchHits; |
| | | import org.elasticsearch.search.aggregations.Aggregations; |
| | | import org.elasticsearch.search.aggregations.bucket.nested.ParsedNested; |
| | | import org.elasticsearch.search.aggregations.bucket.terms.ParsedLongTerms; |
| | | import org.elasticsearch.search.aggregations.bucket.terms.Terms; |
| | | import org.elasticsearch.search.aggregations.metrics.ParsedTopHits; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * @author YXF |
| | | * @date 2021/07/29 |
| | | */ |
| | | @Component |
| | | public class SearchResponseUtil { |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | public static EsProductSearchVO getProductSearch(SearchResponse response) { |
| | | |
| | | // 1、返回的所有查询到的商品 |
| | | EsProductSearchVO esProductSearchVO = new EsProductSearchVO(); |
| | | //===============spu列表信息====================// |
| | | esProductSearchVO.setProducts(buildSpuSearchList(response.getHits())); |
| | | |
| | | //===============聚合信息====================// |
| | | Aggregations aggregations = response.getAggregations(); |
| | | if (Objects.nonNull(aggregations)) { |
| | | processingAggregationsData(esProductSearchVO,aggregations); |
| | | } |
| | | |
| | | return esProductSearchVO; |
| | | } |
| | | |
| | | /** |
| | | * 从es返回的数据中获取spu列表 |
| | | * @param hits es返回的数据 |
| | | * @return |
| | | */ |
| | | public static List<ProductSearchVO> buildSpuSearchList(SearchHits hits) { |
| | | String spuName = null; |
| | | String sellingPoin = null; |
| | | if (Objects.equals(I18nMessage.getLang(), LanguageEnum.LANGUAGE_ZH_CN.getLang())) { |
| | | spuName = EsConstant.PROD_NAME_ZH; |
| | | sellingPoin = EsConstant.BRIEF_ZH; |
| | | } else { |
| | | spuName = EsConstant.PROD_NAME_EN; |
| | | sellingPoin = EsConstant.BRIEF_EN; |
| | | } |
| | | List<ProductSearchVO> prodList = new ArrayList<>(); |
| | | for (SearchHit hit : hits.getHits()) { |
| | | String json = hit.getSourceAsString(); |
| | | ProductSearchVO productSearchVO = Json.parseObject(json, ProductSearchVO.class); |
| | | productSearchVO.setProdName(handleAggregationsLang(json, spuName, EsConstant.PROD_NAME_ZH)); |
| | | productSearchVO.setBrief(handleAggregationsLang(json, sellingPoin, EsConstant.BRIEF_ZH)); |
| | | prodList.add(productSearchVO); |
| | | } |
| | | return prodList; |
| | | } |
| | | /** |
| | | * 处理聚合数据 |
| | | * @param aggregations |
| | | */ |
| | | private static void processingAggregationsData(EsProductSearchVO esProductSearchVO, Aggregations aggregations) { |
| | | String brandName = null; |
| | | String categoryName = null; |
| | | String attrName = null; |
| | | String attrValueName = null; |
| | | if (Objects.equals(I18nMessage.getLang(), LanguageEnum.LANGUAGE_ZH_CN.getLang())) { |
| | | brandName = EsConstant.BRAND_NAME_ZH; |
| | | categoryName = EsConstant.CATEGORY_NAME_ZH; |
| | | } else { |
| | | brandName = EsConstant.BRAND_NAME_EN; |
| | | categoryName = EsConstant.CATEGORY_NAME_EN; |
| | | } |
| | | //===============品牌信息====================// |
| | | ParsedNested brandNested = aggregations.get(EsConstant.BRAND); |
| | | if (Objects.nonNull(brandNested)) { |
| | | esProductSearchVO.setBrands(new ArrayList<>()); |
| | | List<String> brandJson = handleAggregations(brandNested, EsConstant.BRAND_ID); |
| | | for (String json : brandJson) { |
| | | BrandSearchVO brandSearchVO = Json.parseObject(json, BrandSearchVO.class); |
| | | brandSearchVO.setBrandName(handleAggregationsLang(json, brandName, EsConstant.BRAND_NAME_ZH)); |
| | | esProductSearchVO.getBrands().add(brandSearchVO); |
| | | } |
| | | } |
| | | //===============分类信息====================// |
| | | loadCategoryAggregationsData(esProductSearchVO, aggregations, categoryName); |
| | | |
| | | //===============店铺信息====================// |
| | | ParsedLongTerms shopTerms = aggregations.get(EsConstant.SHOP); |
| | | if (Objects.nonNull(shopTerms)) { |
| | | List<? extends Terms.Bucket> shopBuckets = shopTerms.getBuckets(); |
| | | for (Terms.Bucket bucket : shopBuckets) { |
| | | esProductSearchVO.setShopInfo(new ShopSearchVO()); |
| | | esProductSearchVO.getShopInfo().setShopId(Long.valueOf(bucket.getKey().toString())); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private static void loadCategoryAggregationsData(EsProductSearchVO esProductSearchVO, Aggregations aggregations, String categoryName) { |
| | | esProductSearchVO.setCategories(new ArrayList<>()); |
| | | String categoryId = null; |
| | | ParsedNested categoriesNested = null; |
| | | // 平台分类 |
| | | if (Objects.nonNull(aggregations.get(EsConstant.CATEGORY))) { |
| | | categoryId = EsConstant.CATEGORY_ID; |
| | | categoriesNested = aggregations.get(EsConstant.CATEGORY); |
| | | } |
| | | if (Objects.nonNull(categoriesNested)) { |
| | | esProductSearchVO.setCategories(new ArrayList<>()); |
| | | List<String> categoryJson = handleAggregations(categoriesNested, categoryId); |
| | | for (String json : categoryJson) { |
| | | CategorySearchVO categorySearchVO = Json.parseObject(json, CategorySearchVO.class); |
| | | categorySearchVO.setName(handleAggregationsLang(json, categoryName, EsConstant.CATEGORY_NAME_ZH)); |
| | | esProductSearchVO.getCategories().add(categorySearchVO); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 处理聚合数据 |
| | | * @param brandNested |
| | | * @return |
| | | */ |
| | | public static List<String> handleAggregations(ParsedNested brandNested, String id) { |
| | | List<String> dataList = new ArrayList<>(); |
| | | ParsedLongTerms brandLongTerms = brandNested.getAggregations().get(id); |
| | | List<? extends Terms.Bucket> buckets = brandLongTerms.getBuckets(); |
| | | for (Terms.Bucket bucket : buckets) { |
| | | ParsedTopHits parsedTopHits = bucket.getAggregations().get(EsConstant.TOP_HITS_DATA); |
| | | for (SearchHit hit : parsedTopHits.getHits().getHits()) { |
| | | String sourceAsString = hit.getSourceAsString(); |
| | | dataList.add(sourceAsString); |
| | | } |
| | | } |
| | | return dataList; |
| | | } |
| | | |
| | | /** |
| | | * 从聚合数据中获取商品列表 |
| | | * @param response |
| | | * @return |
| | | */ |
| | | public static Map<Long, List<ProductSearchVO>> loadSpuMapByAggregations(SearchResponse response) { |
| | | Aggregations aggregations = response.getAggregations(); |
| | | if (Objects.isNull(aggregations.getAsMap())) { |
| | | return new HashMap<>(0); |
| | | } |
| | | ParsedLongTerms shopTerm = aggregations.get(EsConstant.PROD_LIST); |
| | | Map<Long, List<ProductSearchVO>> prodMap = new HashMap<>(10); |
| | | if (Objects.nonNull(shopTerm)) { |
| | | List<? extends Terms.Bucket> buckets = shopTerm.getBuckets(); |
| | | for (Terms.Bucket bucket : buckets) { |
| | | Aggregations shopAgg = bucket.getAggregations(); |
| | | ParsedTopHits shopHits = shopAgg.get(EsConstant.TOP_HITS_DATA); |
| | | prodMap.put(Long.valueOf(bucket.getKey().toString()), buildSpuSearchList(shopHits.getHits())); |
| | | } |
| | | } |
| | | return prodMap; |
| | | } |
| | | |
| | | /** |
| | | * 构建分页数据 |
| | | * @param pageParam |
| | | * @param esPageVO |
| | | * @param response |
| | | */ |
| | | public static void buildSearchPage(EsPageParam pageParam, EsPageVO<?> esPageVO, SearchResponse response) { |
| | | //总记录数 |
| | | long total = response.getHits().getTotalHits().value; |
| | | esPageVO.setTotal(total); |
| | | // 总页码 |
| | | int totalPages = (int)total % pageParam.getSize() == 0 ? |
| | | (int)total / pageParam.getSize() : ((int)total / pageParam.getSize() + 1); |
| | | esPageVO.setPages(totalPages); |
| | | } |
| | | |
| | | /** |
| | | * 处理聚合国际化信息 |
| | | * @param json 数据 |
| | | * @param field 字段 |
| | | * @return 对应语言的字段 |
| | | */ |
| | | private static String handleAggregationsLang(String json, String field, String defaultField) { |
| | | Map<String, Object> map = Json.parseObject(json, Map.class); |
| | | Object object; |
| | | // 找不到指定语言的数据,就查默认语言 |
| | | if (Objects.isNull(map.get(field))) { |
| | | object = map.get(defaultField); |
| | | } |
| | | // 获取指定语言的数据 |
| | | else { |
| | | object = map.get(field); |
| | | } |
| | | // 没有查到数据 |
| | | if (Objects.isNull(object)) { |
| | | return null; |
| | | } |
| | | return object.toString(); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.search.common.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author FrozenWatermelon |
| | | * @date 2020/11/16 |
| | | */ |
| | | @Data |
| | | public class EsPageVO<T> { |
| | | |
| | | @Schema(description = "总页数" ) |
| | | private Integer pages; |
| | | |
| | | @Schema(description = "总条目数" ) |
| | | private Long total; |
| | | |
| | | @Schema(description = "结果集" ) |
| | | private List<T> records; |
| | | } |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <artifactId>yami-shop-search</artifactId> |
| | | <groupId>com.yami.shop</groupId> |
| | | <version>0.0.1-SNAPSHOT</version> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>yami-shop-search-multishop</artifactId> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.yami.shop</groupId> |
| | | <artifactId>yami-shop-search-common</artifactId> |
| | | <version>${yami.shop.version}</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.yami.shop</groupId> |
| | | <artifactId>yami-shop-security-multishop</artifactId> |
| | | <version>${yami.shop.version}</version> |
| | | </dependency> |
| | | </dependencies> |
| | | </project> |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.search.multishop.config; |
| | | |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import org.springdoc.core.GroupedOpenApi; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | /** |
| | | * @author Yami |
| | | */ |
| | | @Configuration("searchSwaggerConfiguration") |
| | | @AllArgsConstructor |
| | | public class SwaggerConfiguration { |
| | | |
| | | |
| | | @Bean |
| | | public GroupedOpenApi searchRestApi() { |
| | | return GroupedOpenApi.builder() |
| | | .group("搜索接口") |
| | | .packagesToScan("com.yami.shop.search.multishop.controller") |
| | | .pathsToMatch("/**") |
| | | .build(); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.search.multishop.controller; |
| | | |
| | | import com.yami.shop.bean.param.EsProductParam; |
| | | import com.yami.shop.bean.vo.search.ProductSearchVO; |
| | | import com.yami.shop.common.constants.CacheNames; |
| | | import com.yami.shop.common.constants.EsCacheNames; |
| | | import com.yami.shop.common.enums.EsRenovationProductSortEnum; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.RedisUtil; |
| | | import com.yami.shop.search.common.constant.EsConstant; |
| | | import com.yami.shop.search.common.manager.ProductSearchManager; |
| | | import com.yami.shop.search.common.param.EsPageParam; |
| | | import com.yami.shop.search.common.service.SearchProductService; |
| | | import com.yami.shop.search.common.vo.EsPageVO; |
| | | import com.yami.shop.security.multishop.util.SecurityUtils; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import javax.validation.Valid; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * @author lgh |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/admin/search/prod") |
| | | @Tag(name = "商家端商品搜索接口") |
| | | public class EsProductController { |
| | | |
| | | @Autowired |
| | | private SearchProductService searchProductService; |
| | | @Autowired |
| | | private ProductSearchManager productSearchManager; |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "商品信息列表" , description = "商品信息列表") |
| | | public ServerResponseEntity<EsPageVO<ProductSearchVO>> page(@Valid EsPageParam pageParam, @ParameterObject EsProductParam productParam) { |
| | | Long shopId = SecurityUtils.getShopUser().getShopId(); |
| | | productParam.setShopId(shopId); |
| | | productParam.setFetchSource(EsConstant.SHOP_FETCH_SOURCE); |
| | | EsPageVO<ProductSearchVO> searchPage = searchProductService.adminPage(pageParam, productParam); |
| | | return ServerResponseEntity.success(searchPage); |
| | | } |
| | | |
| | | @GetMapping("/renovationPage") |
| | | @Operation(summary = "商品信息列表(装修商品列表)" , description = "商品信息列表(装修商品列表)") |
| | | public ServerResponseEntity<EsPageVO<ProductSearchVO>> renovationPage(@Valid EsPageParam pageParam, @ParameterObject EsProductParam productParam) { |
| | | productParam.setShopId(SecurityUtils.getShopUser().getShopId()); |
| | | Long size = null; |
| | | if(Objects.equals(productParam.getShowSpuType(),1)){ |
| | | if(Objects.equals(productParam.getEsRenovationSpuSort(), EsRenovationProductSortEnum.CREATE_TIME_ASC.value()) || Objects.equals(productParam.getEsRenovationSpuSort(),EsRenovationProductSortEnum.CREATE_TIME_DESC.value())){ |
| | | productParam.setSort(productParam.getEsRenovationSpuSort()); |
| | | }else { |
| | | // 获取指定规则的商品ids |
| | | size = getSpuIds(pageParam, productParam); |
| | | } |
| | | } |
| | | EsPageVO<ProductSearchVO> searchPage = searchProductService.renovationPage(pageParam, productParam, size); |
| | | return ServerResponseEntity.success(searchPage); |
| | | } |
| | | |
| | | @GetMapping("/prodExport") |
| | | @Operation(summary = "商品导出" , description = "商品导出") |
| | | @PreAuthorize("@pms.hasPermission('prod:prod:exportProd')") |
| | | public void prodExport(HttpServletResponse response, @ParameterObject EsProductParam productParam) { |
| | | productParam.setShopId(SecurityUtils.getShopUser().getShopId()); |
| | | searchProductService.export(response, productParam); |
| | | } |
| | | |
| | | private Long getSpuIds(EsPageParam pageParam, EsProductParam productParam) { |
| | | Long shopId = Objects.isNull(productParam.getShopId()) ? 0L : productParam.getShopId(); |
| | | String key = EsCacheNames.RENOVATION_PRODUCT_IDS_CACHE + CacheNames.UNION + shopId + |
| | | CacheNames.UNION_KEY + productParam.getEsTimeRange() + CacheNames.UNION_KEY + productParam.getEsRenovationSpuSort(); |
| | | if(!RedisUtil.hasKey(key)){ |
| | | productSearchManager.addRenovationSpuCache(key,productParam,shopId, EsCacheNames.RENOVATION_PRODUCT_IDS_CACHE_TIME); |
| | | } |
| | | Long size = RedisUtil.getListSize(key); |
| | | long startNum = (long) (pageParam.getCurrent() - 1) * pageParam.getSize(); |
| | | long endNum = (long) pageParam.getCurrent() * pageParam.getSize() - 1; |
| | | endNum = Math.min(endNum,size); |
| | | List<Long> prodIds = RedisUtil.getListRange(key, startNum, endNum); |
| | | productParam.setProdIds(prodIds); |
| | | return size; |
| | | } |
| | | } |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <artifactId>yami-shop-search</artifactId> |
| | | <groupId>com.yami.shop</groupId> |
| | | <version>0.0.1-SNAPSHOT</version> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>yami-shop-search-platform</artifactId> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.yami.shop</groupId> |
| | | <artifactId>yami-shop-search-common</artifactId> |
| | | <version>${yami.shop.version}</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.yami.shop</groupId> |
| | | <artifactId>yami-shop-security-platform</artifactId> |
| | | <version>${yami.shop.version}</version> |
| | | </dependency> |
| | | </dependencies> |
| | | </project> |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.search.platform.config; |
| | | |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import org.springdoc.core.GroupedOpenApi; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | /** |
| | | * @author Yami |
| | | */ |
| | | @Configuration("searchSwaggerConfiguration") |
| | | @AllArgsConstructor |
| | | public class SwaggerConfiguration { |
| | | |
| | | |
| | | @Bean |
| | | public GroupedOpenApi searchRestApi() { |
| | | return GroupedOpenApi.builder() |
| | | .group("搜索接口") |
| | | .packagesToScan("com.yami.shop.search.platform.controller") |
| | | .pathsToMatch("/**") |
| | | .build(); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.search.platform.controller; |
| | | |
| | | import com.yami.shop.bean.param.EsProductParam; |
| | | import com.yami.shop.bean.vo.search.ProductSearchVO; |
| | | import com.yami.shop.common.constants.CacheNames; |
| | | import com.yami.shop.common.constants.EsCacheNames; |
| | | import com.yami.shop.common.enums.EsRenovationProductSortEnum; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.RedisUtil; |
| | | import com.yami.shop.search.common.constant.EsConstant; |
| | | import com.yami.shop.search.common.manager.ProductSearchManager; |
| | | import com.yami.shop.search.common.param.EsPageParam; |
| | | import com.yami.shop.search.common.service.SearchProductService; |
| | | import com.yami.shop.search.common.vo.EsPageVO; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import javax.validation.Valid; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * @author lgh |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/platform/search/prod") |
| | | @Tag(name = "平台端商品搜索接口") |
| | | public class EsProdctController { |
| | | |
| | | @Autowired |
| | | private SearchProductService searchProductService; |
| | | @Autowired |
| | | private ProductSearchManager productSearchManager; |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "商品信息列表" , description = "商品信息列表") |
| | | public ServerResponseEntity<EsPageVO<ProductSearchVO>> page(@Valid EsPageParam pageParam, @ParameterObject EsProductParam productParam) { |
| | | productParam.setFetchSource(EsConstant.PLATFORM_FETCH_SOURCE); |
| | | EsPageVO<ProductSearchVO> searchPage = searchProductService.adminPage(pageParam, productParam); |
| | | return ServerResponseEntity.success(searchPage); |
| | | } |
| | | |
| | | @GetMapping("/scorePage") |
| | | @Operation(summary = "积分商品信息列表" , description = "积分商品信息列表") |
| | | public ServerResponseEntity<EsPageVO<ProductSearchVO>> scorePage(@Valid EsPageParam pageParam, @ParameterObject EsProductParam productParam) { |
| | | productParam.setFetchSource(EsConstant.SHOP_FETCH_SOURCE); |
| | | EsPageVO<ProductSearchVO> searchPage = searchProductService.adminPage(pageParam, productParam); |
| | | return ServerResponseEntity.success(searchPage); |
| | | } |
| | | |
| | | @GetMapping("/renovationPage") |
| | | @Operation(summary = "商品信息列表(装修商品列表)" , description = "商品信息列表(装修商品列表)") |
| | | public ServerResponseEntity<EsPageVO<ProductSearchVO>> renovationPage(@Valid EsPageParam pageParam, @ParameterObject EsProductParam productParam) { |
| | | Long size = null; |
| | | if(Objects.equals(productParam.getShowSpuType(),1)){ |
| | | if(Objects.equals(productParam.getEsRenovationSpuSort(), EsRenovationProductSortEnum.CREATE_TIME_ASC.value()) || Objects.equals(productParam.getEsRenovationSpuSort(),EsRenovationProductSortEnum.CREATE_TIME_DESC.value())){ |
| | | productParam.setSort(productParam.getEsRenovationSpuSort()); |
| | | }else { |
| | | // 获取指定规则的商品ids并返回大小 |
| | | size = getSpuIds(pageParam, productParam); |
| | | } |
| | | } |
| | | EsPageVO<ProductSearchVO> searchPage = searchProductService.renovationPage(pageParam, productParam,size); |
| | | return ServerResponseEntity.success(searchPage); |
| | | } |
| | | |
| | | @GetMapping("/prodExport") |
| | | @Operation(summary = "商品导出" , description = "商品导出") |
| | | @PreAuthorize("@pms.hasPermission('prod:prod:exportProd')") |
| | | public void prodExport(HttpServletResponse response, @ParameterObject EsProductParam productParam) { |
| | | productParam.setShopId(null); |
| | | searchProductService.export(response, productParam); |
| | | } |
| | | |
| | | private Long getSpuIds(EsPageParam pageParam, EsProductParam productParam) { |
| | | Long shopId = Objects.isNull(productParam.getShopId()) ? 0L : productParam.getShopId(); |
| | | String key = EsCacheNames.RENOVATION_PRODUCT_IDS_CACHE + CacheNames.UNION + shopId + |
| | | CacheNames.UNION_KEY + productParam.getEsTimeRange() + CacheNames.UNION_KEY + productParam.getEsRenovationSpuSort(); |
| | | if(!RedisUtil.hasKey(key)){ |
| | | productSearchManager.addRenovationSpuCache(key,productParam,shopId, EsCacheNames.RENOVATION_PRODUCT_IDS_CACHE_TIME); |
| | | } |
| | | Long size = RedisUtil.getListSize(key); |
| | | long startNum = (long) (pageParam.getCurrent() - 1) * pageParam.getSize(); |
| | | long endNum = (long) pageParam.getCurrent() * pageParam.getSize() - 1; |
| | | endNum = Math.min(endNum,size); |
| | | List prodIds = RedisUtil.getListRange(key, startNum, endNum); |
| | | productParam.setProdIds(prodIds); |
| | | return size; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.search.platform.task; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.date.DateTime; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.xxl.job.core.handler.annotation.XxlJob; |
| | | import com.yami.shop.bean.model.Product; |
| | | import com.yami.shop.bean.param.EsProductParam; |
| | | import com.yami.shop.bean.vo.search.ProductSearchVO; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.dao.ProductMapper; |
| | | import com.yami.shop.search.common.constant.EsConstant; |
| | | import com.yami.shop.search.common.constant.EsIndexEnum; |
| | | import com.yami.shop.search.common.param.EsPageParam; |
| | | import com.yami.shop.search.common.service.EsProductService; |
| | | import com.yami.shop.search.common.service.SearchProductService; |
| | | import com.yami.shop.search.common.util.EsSearchUtil; |
| | | import com.yami.shop.search.common.vo.EsPageVO; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.elasticsearch.action.search.SearchRequest; |
| | | import org.elasticsearch.action.search.SearchResponse; |
| | | import org.elasticsearch.action.search.SearchScrollRequest; |
| | | import org.elasticsearch.core.TimeValue; |
| | | import org.elasticsearch.search.Scroll; |
| | | import org.elasticsearch.search.SearchHit; |
| | | import org.elasticsearch.search.SearchHits; |
| | | import org.elasticsearch.search.builder.SearchSourceBuilder; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * 商品定时任务 |
| | | * |
| | | * @author FrozenWatermelon |
| | | */ |
| | | @Component |
| | | @Slf4j |
| | | public class SearchTask { |
| | | @Autowired |
| | | private ProductMapper productMapper; |
| | | @Autowired |
| | | private EsProductService esProductService; |
| | | @Autowired |
| | | private SearchProductService searchProductService; |
| | | |
| | | /** |
| | | * 校验商品数量是否完整 |
| | | * 商品数据是否为最新的:根据商品更新时间判断 |
| | | */ |
| | | @XxlJob("verifySpuData") |
| | | public void verifySpuData(){ |
| | | Date currentTime = new Date(); |
| | | // 数量相同,不需要更新 |
| | | if (verifySpuNum() == 0) { |
| | | return; |
| | | } |
| | | |
| | | //先更新近3个小时的数据 |
| | | DateTime beginTime = DateUtil.beginOfHour(DateUtil.offsetHour(currentTime, -3)); |
| | | updateDbDate(beginTime); |
| | | //更新后校验 |
| | | if (verifySpuNum() == 0) { |
| | | return; |
| | | } |
| | | |
| | | // 更新数据库中的所有商品数据, 保证数据库的数据都更新到es |
| | | updateDbDate(null); |
| | | |
| | | //如果es中的商品数量大于mysql中的商品数量-es有部分已失效的商品数据需要删除 |
| | | if (verifySpuNum() < 0) { |
| | | // 滚动查询es中的数据,删除已失效的 |
| | | updateEsDateByScroll(); |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | private void updateDbDate(Date beginTime){ |
| | | PageParam page = new PageParam(); |
| | | page.setCurrent(1); |
| | | page.setSize(Constant.MAX_PAGE_SIZE); |
| | | List<Long> updateList = new ArrayList<>(); |
| | | boolean update = true; |
| | | while (update) { |
| | | PageParam<Product> prodPage = productMapper.selectPage(page, new LambdaQueryWrapper<Product>() |
| | | // .ne(Product::getStatus, -1) |
| | | .gt(Objects.nonNull(beginTime), Product::getUpdateTime, beginTime) |
| | | ); |
| | | if (Objects.isNull(prodPage) || Objects.isNull(prodPage.getTotal()) || prodPage.getTotal() <= page.getCurrent()){ |
| | | update = false; |
| | | } |
| | | List<Product> records = prodPage.getRecords(); |
| | | if (CollUtil.isEmpty(records)) { |
| | | break; |
| | | } |
| | | List<Long> spuIds = new ArrayList<>(); |
| | | for (Product product : records) { |
| | | spuIds.add(product.getProdId()); |
| | | } |
| | | List<ProductSearchVO> productSearchVOList = searchProductService.simpleList(spuIds); |
| | | Map<Long, Long> prodMap = productSearchVOList.stream() |
| | | .filter(productSearch -> Objects.nonNull(productSearch.getUpdateTime())) |
| | | .collect(Collectors.toMap(ProductSearchVO::getProdId, ProductSearchVO::getUpdateTime) |
| | | ); |
| | | for (Product product : records) { |
| | | boolean isSame = prodMap.containsKey(product.getProdId()) && Objects.equals(product.getUpdateTime().getTime(), prodMap.get(product.getProdId())); |
| | | if (isSame) { |
| | | continue; |
| | | } |
| | | updateList.add(product.getProdId()); |
| | | } |
| | | if (updateList.size() > Constant.MAX_DATA_HANDLE_NUM) { |
| | | esProductService.updateBatch(updateList); |
| | | updateList.clear(); |
| | | } |
| | | page.setCurrent(page.getCurrent() + 1); |
| | | } |
| | | if (CollUtil.isNotEmpty(updateList)) { |
| | | esProductService.updateBatch(updateList); |
| | | } |
| | | } |
| | | |
| | | private void updateEsDateByScroll() { |
| | | // 设置超时时间 |
| | | Scroll scroll = new Scroll(TimeValue.timeValueMinutes(5L)); |
| | | |
| | | SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); |
| | | |
| | | // 指定返回数组中的字段 |
| | | searchSourceBuilder.fetchSource(new String[]{EsConstant.PROD_ID}, null); |
| | | |
| | | // 定时任务使用的所以不会有任何条件查询,只是要查出会不会存在其他环境的商品将其删除 |
| | | // 设置最多一次能够取出1000笔数据,从第1001笔数据开始,将开启滚动查询 |
| | | // PS:滚动查询也属于这一次查询,只不过因为一次查不完,分多次查 |
| | | searchSourceBuilder.size(100); |
| | | |
| | | log.debug("构建的DSL语句 {}", searchSourceBuilder); |
| | | |
| | | SearchRequest searchRequest = new SearchRequest(new String[]{EsIndexEnum.PRODUCT.value()}, searchSourceBuilder); |
| | | // 将滚动放入 |
| | | searchRequest.scroll(scroll); |
| | | |
| | | // 进行第一次滚动查询 |
| | | SearchResponse searchResponse = EsSearchUtil.search(searchRequest); |
| | | |
| | | // 将商品id写入list |
| | | List<Long> prodIds = new ArrayList<>(); |
| | | |
| | | for (SearchHit hit : searchResponse.getHits().getHits()) { |
| | | prodIds.add(Long.parseLong(JSON.parseObject(hit.getSourceAsString()).get("prodId").toString())); |
| | | } |
| | | // 删除不存在商品 |
| | | checkAndDelete(prodIds); |
| | | |
| | | SearchHits hits = searchResponse.getHits(); |
| | | // 记录要滚动的ID |
| | | String scrollId = searchResponse.getScrollId(); |
| | | // 滚动查询从第1001笔数据开始取 |
| | | SearchHit[] hitsScroll = hits.getHits(); |
| | | while (hitsScroll != null && hitsScroll.length > 0) { |
| | | //构造滚动查询条件 |
| | | SearchScrollRequest searchScrollRequest = new SearchScrollRequest(scrollId); |
| | | searchScrollRequest.scroll(scroll); |
| | | searchResponse = EsSearchUtil.scroll(searchScrollRequest); |
| | | scrollId = searchResponse.getScrollId(); |
| | | hits = searchResponse.getHits(); |
| | | hitsScroll = hits.getHits(); |
| | | |
| | | prodIds.clear(); |
| | | // 写入id |
| | | for (SearchHit hit : searchResponse.getHits().getHits()) { |
| | | prodIds.add(Long.parseLong(JSON.parseObject(hit.getSourceAsString()).get("prodId").toString())); |
| | | } |
| | | checkAndDelete(prodIds); |
| | | } |
| | | //清除滚动,否则影响下次查询 |
| | | EsSearchUtil.clearScroll(scrollId); |
| | | } |
| | | |
| | | private void checkAndDelete(List<Long> prodIds) { |
| | | if (CollUtil.isEmpty(prodIds)) { |
| | | return; |
| | | } |
| | | |
| | | List<Long> esProdIds = productMapper.verifySpuExist(prodIds); |
| | | prodIds.removeAll(esProdIds); |
| | | List<Long> deleteList = new ArrayList<>(prodIds); |
| | | esProductService.deleteBatch(deleteList); |
| | | deleteList.clear(); |
| | | } |
| | | |
| | | |
| | | private void updateEsDate(){ |
| | | EsPageParam page = new EsPageParam(); |
| | | page.setCurrent(1); |
| | | page.setSize(Constant.MAX_PAGE_SIZE); |
| | | List<Long> deleteList = new ArrayList<>(); |
| | | boolean update = true; |
| | | EsProductParam esProductParam = new EsProductParam(); |
| | | esProductParam.setFetchSource(new String[]{EsConstant.PROD_ID}); |
| | | while (update) { |
| | | EsPageVO<ProductSearchVO> productPage = searchProductService.adminPage(page, esProductParam); |
| | | if (Objects.isNull(productPage) || Objects.isNull(productPage.getPages()) || productPage.getPages() <= page.getCurrent()){ |
| | | update = false; |
| | | } |
| | | List<ProductSearchVO> records = productPage.getRecords(); |
| | | if (CollUtil.isEmpty(records)) { |
| | | break; |
| | | } |
| | | List<Long> prodIds = records.stream().map(ProductSearchVO::getProdId).collect(Collectors.toList()); |
| | | //List<Long> esProdIds = productMapper.verifySpuHasDelete(prodIds); |
| | | List<Long> esProdIds = productMapper.verifySpuExist(prodIds); |
| | | prodIds.removeAll(esProdIds); |
| | | deleteList.addAll(prodIds); |
| | | if (deleteList.size() > Constant.MAX_DATA_HANDLE_NUM) { |
| | | esProductService.deleteBatch(deleteList); |
| | | deleteList.clear(); |
| | | } |
| | | page.setCurrent(page.getCurrent() + 1); |
| | | } |
| | | if (CollUtil.isNotEmpty(deleteList)) { |
| | | esProductService.deleteBatch(deleteList); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 校验mysql、es中的商品数据是否一致 |
| | | * @return 返回值大于0:数据库有部分数据没同步到es中, 返回值等于0:数据库和es中的商品数据一致, 返回值小于0:es有部分失效的数据未删除 |
| | | */ |
| | | private Long verifySpuNum() { |
| | | // 查找删除的商品一起存进去 |
| | | Integer spuNum = productMapper.selectCount(new LambdaQueryWrapper<>()); |
| | | |
| | | SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); |
| | | // es默认输出最多一万条,设置trackTotalHits为true,取消限制 |
| | | searchSourceBuilder.trackTotalHits(true); |
| | | SearchRequest searchRequest = new SearchRequest(new String[]{EsIndexEnum.PRODUCT.value()}, searchSourceBuilder); |
| | | SearchResponse searchResponse = EsSearchUtil.search(searchRequest); |
| | | Long total = searchResponse.getHits().getTotalHits().value; |
| | | // 数据库商品数量 - es商品数量 |
| | | return Long.valueOf(spuNum) - total; |
| | | } |
| | | } |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | |
| | | <parent> |
| | | <artifactId>yami-shop</artifactId> |
| | | <groupId>com.yami.shop</groupId> |
| | | <version>0.0.1-SNAPSHOT</version> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>yami-shop-seckill</artifactId> |
| | | |
| | | <description>商城满减模块</description> |
| | | <packaging>pom</packaging> |
| | | |
| | | <modules> |
| | | <module>yami-shop-seckill-api</module> |
| | | <module>yami-shop-seckill-multishop</module> |
| | | <module>yami-shop-seckill-platform</module> |
| | | <module>yami-shop-seckill-common</module> |
| | | </modules> |
| | | |
| | | |
| | | </project> |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <artifactId>yami-shop-seckill</artifactId> |
| | | <groupId>com.yami.shop</groupId> |
| | | <version>0.0.1-SNAPSHOT</version> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>yami-shop-seckill-api</artifactId> |
| | | <description>商城满减模块接口部分</description> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.yami.shop</groupId> |
| | | <artifactId>yami-shop-seckill-common</artifactId> |
| | | <version>${yami.shop.version}</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.yami.shop</groupId> |
| | | <artifactId>yami-shop-security-api</artifactId> |
| | | <version>${yami.shop.version}</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.yami.shop</groupId> |
| | | <artifactId>yami-shop-delivery-api</artifactId> |
| | | <version>${yami.shop.version}</version> |
| | | </dependency> |
| | | </dependencies> |
| | | </project> |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.api.config; |
| | | |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import org.springdoc.core.GroupedOpenApi; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | /** |
| | | * 秒杀的swagger文档 |
| | | * @author LGH |
| | | */ |
| | | @Configuration("seckillSwaggerConfiguration") |
| | | @AllArgsConstructor |
| | | public class SwaggerConfiguration { |
| | | |
| | | @Bean |
| | | public GroupedOpenApi seckillRestApi() { |
| | | return GroupedOpenApi.builder() |
| | | .group("秒杀接口") |
| | | .packagesToScan("com.yami.shop.seckill.api.controller") |
| | | .pathsToMatch("/**") |
| | | .build(); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.api.controller; |
| | | |
| | | import cn.hutool.core.collection.CollectionUtil; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import cn.hutool.core.lang.Snowflake; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.google.common.util.concurrent.ThreadFactoryBuilder; |
| | | import com.yami.shop.bean.app.dto.*; |
| | | import com.yami.shop.bean.app.param.SubmitSeckillOrderParam; |
| | | import com.yami.shop.bean.enums.DeliveryType; |
| | | import com.yami.shop.bean.enums.OrderType; |
| | | import com.yami.shop.bean.enums.ShopStatus; |
| | | import com.yami.shop.bean.model.Order; |
| | | import com.yami.shop.bean.model.Product; |
| | | import com.yami.shop.bean.model.ShopDetail; |
| | | import com.yami.shop.bean.vo.UserDeliveryInfoVO; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.i18n.I18nMessage; |
| | | import com.yami.shop.common.response.ResponseEnum; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.delivery.api.manager.DeliveryOrderManager; |
| | | import com.yami.shop.manager.SubmitOrderManager; |
| | | import com.yami.shop.manager.impl.ConfirmOrderManager; |
| | | import com.yami.shop.manager.impl.ShopCartAdapter; |
| | | import com.yami.shop.manager.impl.ShopCartItemAdapter; |
| | | import com.yami.shop.seckill.api.param.SeckillOrderParam; |
| | | import com.yami.shop.seckill.api.service.SeckillCacheManager; |
| | | import com.yami.shop.seckill.common.enums.SeckillEnum; |
| | | import com.yami.shop.seckill.common.model.Seckill; |
| | | import com.yami.shop.seckill.common.model.SeckillOrder; |
| | | import com.yami.shop.seckill.common.model.SeckillSku; |
| | | import com.yami.shop.seckill.common.service.SeckillOrderService; |
| | | import com.yami.shop.seckill.common.service.SeckillService; |
| | | import com.yami.shop.seckill.common.service.SeckillSkuService; |
| | | import com.yami.shop.security.api.util.SecurityUtils; |
| | | import com.yami.shop.service.OrderService; |
| | | import com.yami.shop.service.ProductService; |
| | | import com.yami.shop.service.ShopCustomerService; |
| | | import com.yami.shop.service.ShopDetailService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.Collections; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | import java.util.concurrent.*; |
| | | |
| | | |
| | | /** |
| | | * @author LGH |
| | | * @date 2019-08-28 09:36:59 |
| | | */ |
| | | @RestController |
| | | @AllArgsConstructor |
| | | @RequestMapping("/p/seckill") |
| | | @Tag(name = "秒杀订单接口") |
| | | public class SeckillOrderController { |
| | | |
| | | private final SeckillService seckillService; |
| | | private final SeckillSkuService seckillSkuService; |
| | | private final SeckillOrderService seckillOrderService; |
| | | private final SeckillCacheManager seckillCacheManager; |
| | | private final Snowflake snowflake; |
| | | private final OrderService orderService; |
| | | private final ShopCartAdapter shopCartAdapter; |
| | | private final ShopCartItemAdapter shopCartItemAdapter; |
| | | private final ConfirmOrderManager confirmOrderManager; |
| | | private final DeliveryOrderManager deliveryOrderManager; |
| | | private final SubmitOrderManager submitOrderManager; |
| | | private final ProductService productService; |
| | | private final ShopDetailService shopDetailService; |
| | | |
| | | private final ShopCustomerService shopCustomerService; |
| | | |
| | | private static final Executor EXECUTOR = new ThreadPoolExecutor( |
| | | 5, |
| | | 20, |
| | | 5L, |
| | | TimeUnit.SECONDS, |
| | | new ArrayBlockingQueue<>(1000), |
| | | new ThreadFactoryBuilder() |
| | | .setNameFormat("seckill-redis-listener-pool-%d").build()); |
| | | |
| | | |
| | | @Operation(summary = "获取秒杀订单路径") |
| | | @GetMapping(value = "/orderPath") |
| | | @Parameter(name = "prodId", description = "秒杀商品id" , required = true) |
| | | public ServerResponseEntity<String> getOrderPath(Long prodId) { |
| | | String userId = SecurityUtils.getUser().getUserId(); |
| | | Seckill seckill = seckillService.getByProdId(prodId); |
| | | if (seckill == null || !Objects.equals(seckill.getStatus(), SeckillEnum.NORMAL.getValue()) || seckill.getEndTime().getTime() < System.currentTimeMillis()) { |
| | | // 秒杀活动已结束 |
| | | throw new YamiShopBindException("yami.seckill.has.ended"); |
| | | } |
| | | if (seckill.getStartTime().getTime() > System.currentTimeMillis()) { |
| | | // 秒杀活动未开始 |
| | | throw new YamiShopBindException("yami.seckill.not.start"); |
| | | } |
| | | String orderPath = seckillCacheManager.createOrderPath(userId + prodId); |
| | | return ServerResponseEntity.success(orderPath); |
| | | } |
| | | |
| | | |
| | | @Operation(summary = "确认订单") |
| | | @PostMapping(value = "/{orderPath}/confirm") |
| | | @Parameter(name = "orderPath", description = "订单路径" , required = true) |
| | | public ServerResponseEntity<ShopCartOrderMergerDto> confirm(@PathVariable("orderPath") String orderPath, @Valid @RequestBody SeckillOrderParam seckillOrderParam) { |
| | | String userId = SecurityUtils.getUser().getUserId(); |
| | | Long prodId = seckillOrderParam.getOrderItem().getProdId(); |
| | | seckillCacheManager.checkOrderPath(userId + prodId, orderPath); |
| | | // 秒杀sku(来自缓存),注:千万不要用这里的库存校验 |
| | | SeckillSku seckillSku = seckillSkuService.getSeckillSkuById(seckillOrderParam.getSeckillSkuId()); |
| | | if (seckillSku == null || !Objects.equals(seckillOrderParam.getOrderItem().getSkuId(), seckillSku.getSkuId())) { |
| | | // 购物车包含无法识别的商品 |
| | | throw new YamiShopBindException("yami.shop.cart.prod.unrecognized"); |
| | | } |
| | | List<ShopCartItemDto> shopCartItemsDb = shopCartItemAdapter.getShopCartItem(seckillOrderParam.getOrderItem(), seckillSku.getSeckillPrice(), userId, seckillOrderParam.getAddrId()); |
| | | // 将要返回给前端的完整的订单信息 |
| | | ShopCartOrderMergerDto shopCartOrderMerger = new ShopCartOrderMergerDto(); |
| | | shopCartOrderMerger.setDvyType(seckillOrderParam.getDvyType()); |
| | | shopCartOrderMerger.setOrderType(OrderType.SECKILL); |
| | | shopCartOrderMerger.setSeckillId(seckillSku.getSeckillId()); |
| | | shopCartOrderMerger.setSeckillSkuId(seckillSku.getSeckillSkuId()); |
| | | |
| | | // 筛选过滤掉不同配送的商品 |
| | | List<ShopCartItemDto> shopCartItems = confirmOrderManager.filterShopItemsByType(shopCartOrderMerger, shopCartItemsDb); |
| | | // 该商品不满足任何的配送方式 |
| | | if (CollectionUtil.isEmpty(shopCartItems)) { |
| | | return ServerResponseEntity.fail(ResponseEnum.ORDER_DELIVERY_NOT_SUPPORTED, shopCartOrderMerger); |
| | | } |
| | | |
| | | ShopCartItemDto firstShopCartItem = shopCartItems.get(0); |
| | | // 商品类别 0.实物商品 1. 虚拟商品 |
| | | int mold = 0; |
| | | if (shopCartItems.stream().filter(shopCartItemDto -> shopCartItemDto.getMold() == 1).count() == shopCartItems.size()) { |
| | | // 订单项中的所有商品都为虚拟商品时,才是虚拟订单 |
| | | mold = 1; |
| | | } |
| | | shopCartOrderMerger.setMold(mold); |
| | | // 是否为预售订单 |
| | | seckillOrderParam.setPreSellStatus(firstShopCartItem.getPreSellStatus()); |
| | | shopCartOrderMerger.setPreSellStatus(firstShopCartItem.getPreSellStatus()); |
| | | |
| | | // 购物车 |
| | | List<ShopCartDto> shopCarts = shopCartAdapter.getShopCarts(shopCartItems); |
| | | |
| | | // 计算运费,获取用户地址,自提信息 |
| | | UserDeliveryInfoVO userDeliveryInfo = new UserDeliveryInfoVO(); |
| | | if (Objects.equals(mold, 0)) { |
| | | userDeliveryInfo = deliveryOrderManager.calculateAndGetDeliverInfo(userId, seckillOrderParam.getAddrId(), seckillOrderParam.getDvyType(), shopCartItems); |
| | | } |
| | | |
| | | // 当算完一遍店铺的各种满减活动时,重算一遍订单金额 |
| | | confirmOrderManager.recalculateAmountWhenFinishingCalculateShop(shopCartOrderMerger, shopCarts, userDeliveryInfo); |
| | | |
| | | // 结束平台优惠的计算之后,还要重算一遍金额 |
| | | confirmOrderManager.recalculateAmountWhenFinishingCalculatePlatform(shopCartOrderMerger); |
| | | |
| | | // 计算平台佣金 |
| | | confirmOrderManager.calculatePlatformCommission(shopCartOrderMerger); |
| | | |
| | | // 缓存计算 |
| | | confirmOrderManager.cacheCalculatedInfo(userId, shopCartOrderMerger); |
| | | return ServerResponseEntity.success(shopCartOrderMerger); |
| | | } |
| | | |
| | | /** |
| | | * 购物车/立即购买 提交订单,根据店铺拆单 |
| | | */ |
| | | @PostMapping("/{orderPath}/submit") |
| | | @Operation(summary = "提交订单" , description = "提交之后返回WebSocket路径,请求对应的WebSocket路径,开始等待响应") |
| | | @Parameter(name = "orderPath", description = "订单路径" , required = true) |
| | | public ServerResponseEntity<OrderNumbersDto> submitOrders(@PathVariable("orderPath") String orderPath, |
| | | @Valid @RequestBody SubmitSeckillOrderParam seckillOrderParam) { |
| | | String userId = SecurityUtils.getUser().getUserId(); |
| | | ServerResponseEntity<ShopCartOrderMergerDto> dtoEntity = submitOrderManager.checkSubmitInfo(seckillOrderParam, userId); |
| | | if (!dtoEntity.isSuccess()) { |
| | | return ServerResponseEntity.transform(dtoEntity); |
| | | } |
| | | ShopCartOrderMergerDto dto = dtoEntity.getData(); |
| | | if (dto.getUserAddr() == null && !Objects.equals(dto.getMold(),1) && Objects.equals(dto.getDvyType(), DeliveryType.EXPRESS.getValue())) { |
| | | // 请填写收货地址 |
| | | throw new YamiShopBindException("yami.delivery.address"); |
| | | } |
| | | ShopCartOrderDto shopCartOrderDto = dto.getShopCartOrders().get(0); |
| | | ShopCartItemDto shopCartItemDto = shopCartOrderDto.getShopCartItemDiscounts().get(0).getShopCartItems().get(0); |
| | | seckillCacheManager.checkOrderPath(userId + shopCartItemDto.getProdId(), orderPath); |
| | | |
| | | // 秒杀活动信息(来自缓存) |
| | | Seckill seckill = seckillService.getSeckillById(dto.getSeckillId()); |
| | | // 判断秒杀是否已经下线 |
| | | if (Objects.equals(seckill.getStatus(), SeckillEnum.INVALID.getValue()) |
| | | || DateUtil.compare(seckill.getEndTime(), new Date()) < 0 |
| | | || Objects.equals(seckill.getStatus(), SeckillEnum.OFFLINE.getValue())) { |
| | | // 秒杀活动已结束 |
| | | throw new YamiShopBindException("yami.seckill.has.ended"); |
| | | } |
| | | if (DateUtil.compare(seckill.getStartTime(), new Date()) > 0) { |
| | | // 秒杀活动未开始 |
| | | throw new YamiShopBindException("yami.seckill.not.start"); |
| | | } |
| | | // 判断之前秒杀的商品有没有超过限制,-1表示商品不限制秒杀数量 |
| | | seckillOrderService.checkOrderProdNum(seckill, userId, shopCartItemDto.getProdCount()); |
| | | // 这里一进来就减库存,但是为了防止少卖,120秒会自己更新库存~因为缓存只有60秒 |
| | | seckillCacheManager.decrSeckillSkuStocks(dto.getSeckillSkuId(), dto.getSeckillId(), shopCartItemDto.getProdCount(),shopCartItemDto.getProdId()); |
| | | // shopCartOrderDto.setMsgId(orderPath); |
| | | dto.setVirtualRemarkList(seckillOrderParam.getVirtualRemarkList()); |
| | | dto.setUserId(userId); |
| | | String orderNumber = String.valueOf(snowflake.nextId()); |
| | | shopCartOrderDto.setOrderNumber(orderNumber); |
| | | // // 下单 |
| | | // SendStatus sendStatus = seckillOrderSubmitTemplate.syncSend(RocketMqConstant.SECKILL_ORDER_SUBMIT_TOPIC, new GenericMessage<>(dto)).getSendStatus(); |
| | | // if (!Objects.equals(sendStatus,SendStatus.SEND_OK)) { |
| | | // // 服务器繁忙,请稍后再试 |
| | | // throw new YamiShopBindException("yami.network.busy"); |
| | | // } |
| | | try { |
| | | EXECUTOR.execute(() -> { |
| | | seckillOrderService.submit(dto); |
| | | }); |
| | | } catch (RejectedExecutionException e) { |
| | | // 服务器繁忙,请稍后再试 |
| | | throw new YamiShopBindException("yami.network.busy"); |
| | | } |
| | | seckillOrderService.removeConfirmOrderCache(userId); |
| | | // 店铺客户创建 |
| | | Order order = new Order(); |
| | | order.setUserId(dto.getUserId()); |
| | | order.setShopId(dto.getShopCartOrders().get(0).getShopId()); |
| | | shopCustomerService.saveCustomerByOrders(Collections.singletonList(order)); |
| | | |
| | | return ServerResponseEntity.success(new OrderNumbersDto(orderNumber)); |
| | | } |
| | | |
| | | @GetMapping("/getSeckillIdByOrderNumber") |
| | | @Operation(summary = "根据订单编号获取秒杀id") |
| | | @Parameter(name = "orderNumber", description = "订单编号" , required = true) |
| | | public ServerResponseEntity<Long> getSeckillIdByOrderNumber(@RequestParam("orderNumber") String orderNumber) { |
| | | SeckillOrder seckillOrder = seckillOrderService.getOne(new LambdaQueryWrapper<SeckillOrder>().eq(SeckillOrder::getOrderNumber, orderNumber)); |
| | | if (Objects.isNull(seckillOrder)) { |
| | | throw new YamiShopBindException("yami.data.deleted.or.not.exist"); |
| | | } |
| | | return ServerResponseEntity.success(seckillOrder.getSeckillId()); |
| | | } |
| | | |
| | | @GetMapping("/createOrderStatus") |
| | | @Operation(summary = "根据orderNumber获取订单是否创建成功" , description = "订单数量") |
| | | @Parameter(name = "orderNumber", description = "订单流水号" , required = true) |
| | | public ServerResponseEntity<Integer> getCreateOrderStatus(@RequestParam("orderNumber") String orderNumber) { |
| | | return ServerResponseEntity.success(orderService.countByOrderNumber(orderNumber)); |
| | | } |
| | | |
| | | @GetMapping("/prod") |
| | | @Operation(summary = "获取秒杀商品信息" , description = "根据商品id,获取当前秒杀的商品活动状态 0下线 1活动中") |
| | | @Parameter(name = "prodId", description = "商品id" , required = true) |
| | | public ServerResponseEntity<Integer> getProdActivityStatus(@RequestParam("prodId") Long prodId) { |
| | | // 商品信息 缓存 |
| | | Product product = productService.getProductByProdId(prodId, I18nMessage.getDbLang()); |
| | | if (product == null || !Objects.equals(product.getStatus(), 1)) { |
| | | return ServerResponseEntity.success(0); |
| | | } |
| | | |
| | | // 秒杀活动信息 缓存 |
| | | Seckill seckill = seckillService.getSeckillByProdId(prodId); |
| | | // 秒杀已经下线 |
| | | if (seckill == null || Objects.equals(seckill.getStatus(), 0)) { |
| | | return ServerResponseEntity.success(0); |
| | | } |
| | | // 判断是否删除 |
| | | if(Objects.equals(seckill.getIsDelete(), 1)){ |
| | | return ServerResponseEntity.success(0); |
| | | } |
| | | // 秒杀结束时间 |
| | | if (seckill.getEndTime().getTime() < System.currentTimeMillis()) { |
| | | return ServerResponseEntity.success(0); |
| | | } |
| | | // 店铺详情 缓存 |
| | | ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(product.getShopId()); |
| | | if (!Objects.equals(shopDetail.getShopStatus(), ShopStatus.OPEN.value())) { |
| | | // 店铺不处于营业状态 |
| | | return ServerResponseEntity.success(0); |
| | | } |
| | | return ServerResponseEntity.success(1); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.api.listener; |
| | | |
| | | |
| | | import cn.hutool.core.date.DateUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.yami.shop.bean.event.CheckSecKillOrderEvent; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.seckill.common.model.Seckill; |
| | | import com.yami.shop.seckill.common.model.SeckillOrder; |
| | | import com.yami.shop.seckill.common.service.SeckillOrderService; |
| | | import com.yami.shop.seckill.common.service.SeckillService; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.context.event.EventListener; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * 支付时校验订单过期事件 |
| | | * @author lhd |
| | | */ |
| | | @Component("checkSecKillOrderListener") |
| | | @AllArgsConstructor |
| | | public class CheckSecKillOrderListener { |
| | | |
| | | |
| | | private final SeckillOrderService seckillOrderService; |
| | | private final SeckillService seckillService; |
| | | |
| | | @EventListener(CheckSecKillOrderEvent.class) |
| | | public void checkSecKillOrderHandle(CheckSecKillOrderEvent event) { |
| | | String orderNumber = event.getOrder().getOrderNumber(); |
| | | SeckillOrder seckillOrder = seckillOrderService.getOne(new LambdaQueryWrapper<SeckillOrder>().eq(SeckillOrder::getOrderNumber, orderNumber)); |
| | | Seckill seckill = seckillService.getSeckillById(seckillOrder.getSeckillId()); |
| | | // 订单创建时间经过秒杀限定分钟,如果为true则早于当前时间表示过期,抛出异常 |
| | | // if(!DateUtil.isExpired(seckillOrder.getCreateTime(), DateField.MINUTE, seckill.getMaxCancelTime(), new Date())){ |
| | | boolean isExpired = !DateUtil.offsetMinute(seckillOrder.getCreateTime(),seckill.getMaxCancelTime()).after(new Date()); |
| | | if(isExpired){ |
| | | // 秒杀订单已经过期,无法进行支付 |
| | | throw new YamiShopBindException("yami.order.expired"); |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.api.listener; |
| | | |
| | | import com.yami.shop.bean.app.dto.SeckillSkuDto; |
| | | import com.yami.shop.bean.app.dto.SkuDto; |
| | | import com.yami.shop.bean.app.vo.ProductVO; |
| | | import com.yami.shop.bean.app.vo.SeckillVO; |
| | | import com.yami.shop.bean.enums.ProdType; |
| | | import com.yami.shop.bean.event.LoadProdActivistEvent; |
| | | import com.yami.shop.bean.order.LoadProdActivistOrder; |
| | | import com.yami.shop.common.enums.StatusEnum; |
| | | import com.yami.shop.seckill.common.model.Seckill; |
| | | import com.yami.shop.seckill.common.model.SeckillSku; |
| | | import com.yami.shop.seckill.common.service.SeckillService; |
| | | import com.yami.shop.seckill.common.service.SeckillSkuService; |
| | | import lombok.AllArgsConstructor; |
| | | import ma.glasnost.orika.MapperFacade; |
| | | import org.springframework.context.event.EventListener; |
| | | import org.springframework.core.annotation.Order; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | import java.util.stream.Collectors; |
| | | |
| | | |
| | | /** |
| | | * 加载商品秒杀信息 |
| | | * @author yami |
| | | */ |
| | | @Component("seckillProdActivistListener") |
| | | @AllArgsConstructor |
| | | public class LoadProdActivistListener { |
| | | |
| | | private SeckillSkuService seckillSkuService; |
| | | private SeckillService seckillService; |
| | | private MapperFacade mapperFacade; |
| | | |
| | | |
| | | @EventListener(LoadProdActivistEvent.class) |
| | | @Order(LoadProdActivistOrder.DEFAULT) |
| | | public void loadProdSeckillHandle(LoadProdActivistEvent event) { |
| | | // 不是秒杀商品,不用处理 |
| | | if (!Objects.equals(event.getProdType(), ProdType.PROD_TYPE_SECKILL.value())) { |
| | | return; |
| | | } |
| | | ProductVO productVO = event.getProductVO(); |
| | | |
| | | long currentTimeMillis = System.currentTimeMillis(); |
| | | |
| | | // 秒杀活动信息(来自缓存) |
| | | Seckill seckill = seckillService.getSeckillByProdId(event.getProdId()); |
| | | // 无法获取秒杀信息、秒杀没有启用、当前时间大于活动结束时间, 则不添加活动信息 |
| | | boolean unActivity = Objects.isNull(seckill) || !Objects.equals(seckill.getStatus(), StatusEnum.ENABLE.value()) || currentTimeMillis > seckill.getEndTime().getTime(); |
| | | if (unActivity) { |
| | | return; |
| | | } |
| | | |
| | | // 秒杀活动sku信息(来自缓存) |
| | | List<SeckillSku> seckillSkus = seckillSkuService.listSeckillSkuBySeckillId(seckill.getSeckillId()); |
| | | |
| | | // 获取秒杀sku列表 |
| | | Map<Long, SkuDto> skuMap = productVO.getSkuList().stream().collect(Collectors.toMap(SkuDto::getSkuId, s -> s)); |
| | | List<SeckillSkuDto> seckillSkuDtos = new ArrayList<>(); |
| | | for (SeckillSku seckillSku : seckillSkus) { |
| | | SeckillSkuDto seckillSkuDto = new SeckillSkuDto(); |
| | | if (!skuMap.containsKey(seckillSku.getSkuId())) { |
| | | continue; |
| | | } |
| | | SkuDto sku = skuMap.get(seckillSku.getSkuId()); |
| | | seckillSkuDto.setPic(sku.getPic()); |
| | | seckillSkuDto.setProperties(sku.getProperties()); |
| | | seckillSkuDto.setPrice(sku.getPrice()); |
| | | seckillSkuDto.setSeckillPrice(seckillSku.getSeckillPrice()); |
| | | seckillSkuDto.setSeckillStocks(seckillSku.getSeckillStocks()); |
| | | seckillSkuDto.setSkuId(sku.getSkuId()); |
| | | seckillSkuDto.setSeckillSkuId(seckillSku.getSeckillSkuId()); |
| | | seckillSkuDtos.add(seckillSkuDto); |
| | | } |
| | | |
| | | SeckillVO seckillVO = mapperFacade.map(seckill, SeckillVO.class); |
| | | // 插入秒杀sku列表信息 |
| | | seckillVO.setSeckillSkuList(seckillSkuDtos); |
| | | // 插入秒杀信息 |
| | | productVO.setSeckillVO(seckillVO); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.api.param; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import javax.validation.constraints.Min; |
| | | import javax.validation.constraints.NotNull; |
| | | |
| | | /** |
| | | * @author LGH |
| | | */ |
| | | @Data |
| | | @Schema(description = "秒杀确认订单参数") |
| | | public class ConfirmParam { |
| | | |
| | | @NotNull(message = "产品数量不能为空") |
| | | @Min(value = 1,message = "产品数量不能为空") |
| | | @Schema(description = "产品数量" ,required=true) |
| | | private Integer prodCount; |
| | | |
| | | @NotNull(message = "用户地址id") |
| | | @Schema(description = "用户地址id" ,required=true) |
| | | private Long addrId; |
| | | |
| | | @NotNull(message = "秒杀商品skuId") |
| | | @Schema(description = "秒杀商品skuId" ,required=true) |
| | | private Long seckillSkuId; |
| | | |
| | | @Schema(description = "推广员使用的推销卡号" ) |
| | | private String distributionCardNo; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.api.param; |
| | | |
| | | import com.yami.shop.bean.app.param.OrderParam; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | import javax.validation.constraints.NotNull; |
| | | |
| | | /** |
| | | * 秒杀下单需要的参数 |
| | | * |
| | | * @author Yami |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = false) |
| | | @Schema(description = "秒杀下单参数") |
| | | public class SeckillOrderParam extends OrderParam { |
| | | |
| | | @NotNull(message = "秒杀商品skuId不能为空") |
| | | @Schema(description = "秒杀商品skuId" , required = true) |
| | | private Long seckillSkuId; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.api.service; |
| | | |
| | | /** |
| | | * 秒杀缓存管理 |
| | | * @author LGH |
| | | */ |
| | | public interface SeckillCacheManager { |
| | | |
| | | /** |
| | | * 创建订单路径 |
| | | * @param userId |
| | | * @return |
| | | */ |
| | | String createOrderPath(String userId); |
| | | |
| | | /** |
| | | * 校验订单路径 |
| | | * @param userId |
| | | * @param orderPath |
| | | * @return |
| | | */ |
| | | void checkOrderPath(String userId, String orderPath); |
| | | |
| | | /** |
| | | * 减少秒杀sku库存 |
| | | * @param seckillSkuId |
| | | * @param seckillId |
| | | * @param prodCount |
| | | * @param prodId |
| | | */ |
| | | void decrSeckillSkuStocks(Long seckillSkuId, Long seckillId, Integer prodCount, Long prodId); |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.api.service.impl; |
| | | |
| | | import cn.hutool.core.lang.Snowflake; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.util.IdUtil; |
| | | import com.yami.shop.common.util.RedisUtil; |
| | | import com.yami.shop.seckill.api.service.SeckillCacheManager; |
| | | import com.yami.shop.seckill.common.service.SeckillService; |
| | | import com.yami.shop.seckill.common.service.SeckillSkuService; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.redisson.api.RLock; |
| | | import org.redisson.api.RedissonClient; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.Objects; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | |
| | | /** |
| | | * @author LGH |
| | | */ |
| | | @Slf4j |
| | | @Service |
| | | @AllArgsConstructor |
| | | public class SeckillCacheManagerImpl implements SeckillCacheManager { |
| | | |
| | | private final RedissonClient redissonClient; |
| | | |
| | | private static final String REDISSON_LOCK_PREFIX = "redisson_lock:"; |
| | | /** |
| | | * 秒杀限流前缀 |
| | | */ |
| | | private final static String SECKILL_LIMIT_PREFIX = "SECKILL_LIMIT_"; |
| | | |
| | | /** |
| | | * 秒杀路径前缀 |
| | | */ |
| | | private final static String SECKILL_PATH_PREFIX = "SECKILL_PATH_"; |
| | | |
| | | private final static String SECKILL_SKU_STOCKS_PREFIX = "SECKILL_SKU_STOCKS_"; |
| | | |
| | | private final Snowflake snowflake; |
| | | |
| | | private final SeckillSkuService seckillSkuService; |
| | | private final SeckillService seckillService; |
| | | |
| | | |
| | | @Override |
| | | public String createOrderPath(String userId) { |
| | | |
| | | String limitKey = SECKILL_LIMIT_PREFIX + userId; |
| | | int maxCount = 5; |
| | | |
| | | // 秒杀次数+1 |
| | | long seckillNum = RedisUtil.incr(limitKey, 1); |
| | | |
| | | // 5秒只能提交5次请求 |
| | | if (seckillNum == 1) { |
| | | // 5秒后失效 |
| | | RedisUtil.expire(limitKey, 5); |
| | | } |
| | | if (seckillNum >= maxCount) { |
| | | // 请求过频繁,请稍后再试 |
| | | throw new YamiShopBindException("yami.request.too.much"); |
| | | } |
| | | String orderPath = IdUtil.encode(snowflake.nextId()); |
| | | |
| | | // 保存秒杀路径,5分钟这个路径就失效 |
| | | RedisUtil.set(getPathKey(userId), orderPath, 300); |
| | | |
| | | return orderPath; |
| | | } |
| | | |
| | | @Override |
| | | public void checkOrderPath(String userId, String orderPath) { |
| | | String cacheOrderPath = RedisUtil.get(getPathKey(userId)); |
| | | |
| | | if (!Objects.equals(cacheOrderPath, orderPath)) { |
| | | // 订单已过期,请重新选择商品进行秒杀 |
| | | throw new YamiShopBindException("yami.order.expired"); |
| | | } |
| | | } |
| | | |
| | | private String getPathKey(String userId) { |
| | | return SECKILL_PATH_PREFIX + userId; |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public void decrSeckillSkuStocks(Long seckillSkuId, Long seckillId, Integer prodCount, Long prodId) { |
| | | String key = SECKILL_SKU_STOCKS_PREFIX + seckillSkuId; |
| | | |
| | | Long cacheStocks = RedisUtil.getLongValue(key); |
| | | |
| | | if (cacheStocks != null && cacheStocks <= 0) { |
| | | // 库存不足 |
| | | throw new YamiShopBindException("yami.insufficient.inventory"); |
| | | } |
| | | |
| | | // 如果没有库存就缓存一个库存 |
| | | if (cacheStocks == null || RedisUtil.getExpire(key) < 1) { |
| | | |
| | | // 加锁,防止缓存击穿 |
| | | RLock rLock = redissonClient.getLock(REDISSON_LOCK_PREFIX + ":getSeckillSkuStocks"); |
| | | try { |
| | | int lockWait = 10; |
| | | if (rLock.tryLock(lockWait, lockWait, TimeUnit.SECONDS)) { |
| | | // 再获取一遍缓存 |
| | | cacheStocks = RedisUtil.getLongValue(key); |
| | | if (cacheStocks == null) { |
| | | seckillSkuService.removeSeckillCacheSkuById(seckillSkuId, seckillId); |
| | | seckillService.removeSeckillCache(seckillId, prodId); |
| | | Integer seckillStocks = seckillSkuService.getSeckillSkuById(seckillSkuId).getSeckillStocks(); |
| | | if (seckillStocks > 0) { |
| | | RedisUtil.setLongValue(key, Long.valueOf(seckillStocks), -1); |
| | | } else { |
| | | RedisUtil.setLongValue(key, 0L, 30); |
| | | } |
| | | cacheStocks = Long.valueOf(seckillStocks); |
| | | } |
| | | } else { |
| | | // 网络异常 |
| | | throw new YamiShopBindException("yami.network.exception"); |
| | | } |
| | | } catch (InterruptedException e) { |
| | | log.error("InterruptedException:", e); |
| | | } finally { |
| | | try { |
| | | if (rLock.isLocked()) { |
| | | rLock.unlock(); |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("Exception:", e); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (cacheStocks == null || cacheStocks < prodCount || RedisUtil.decr(key, prodCount) < 0) { |
| | | RedisUtil.expire(key, 30); |
| | | // 本轮商品已被秒杀完毕,还有用户未支付,还有机会哟 |
| | | throw new YamiShopBindException("yami.seckill.complete"); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <artifactId>yami-shop-seckill</artifactId> |
| | | <groupId>com.yami.shop</groupId> |
| | | <version>0.0.1-SNAPSHOT</version> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>yami-shop-seckill-common</artifactId> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.yami.shop</groupId> |
| | | <artifactId>yami-shop-security-common</artifactId> |
| | | <version>${yami.shop.version}</version> |
| | | </dependency> |
| | | </dependencies> |
| | | </project> |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.constant; |
| | | |
| | | /** |
| | | * @author FrozenWatermelon |
| | | * @date 2020/11/23 |
| | | */ |
| | | public interface SeckillCacheNames { |
| | | |
| | | /** |
| | | * 秒杀信息缓存 |
| | | */ |
| | | String SECKILL_BY_PROD_ID = "SeckillByProdId"; |
| | | |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.dao; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.app.vo.SeckillVO; |
| | | import com.yami.shop.bean.model.Product; |
| | | import com.yami.shop.bean.param.ProductParam; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.seckill.common.dto.SeckillProductSimpleDto; |
| | | import com.yami.shop.seckill.common.model.Seckill; |
| | | import com.yami.shop.seckill.common.dto.SeckillPageDto; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 秒杀信息 |
| | | * |
| | | * @author LGH |
| | | * @date 2019-08-28 09:36:59 |
| | | */ |
| | | public interface SeckillMapper extends BaseMapper<Seckill> { |
| | | |
| | | /** |
| | | * 分页获取秒杀商品 |
| | | * @param page |
| | | * @param dbLang |
| | | * @return |
| | | */ |
| | | IPage<SeckillProductSimpleDto> pageSeckillProd(PageParam<SeckillProductSimpleDto> page, @Param("dbLang") Integer dbLang); |
| | | |
| | | /** |
| | | * 平台分页获取秒杀活动 |
| | | * @param page |
| | | * @param seckill |
| | | * @return |
| | | */ |
| | | IPage<SeckillPageDto> getPlatformSeckillPage(@Param("page") PageParam<Seckill> page, @Param("seckill") Seckill seckill); |
| | | |
| | | /** |
| | | * 修改状态 |
| | | * @param seckillId |
| | | * @param status |
| | | * @return |
| | | */ |
| | | int updateStatus(@Param("seckillId") Long seckillId, @Param("status") int status); |
| | | |
| | | /** |
| | | * 还原库存 |
| | | * @param orderNumber |
| | | */ |
| | | void returnStocksByOrderNumber(@Param("orderNumber") String orderNumber); |
| | | |
| | | /** |
| | | * 还原库存 |
| | | * @param now |
| | | */ |
| | | void returnStocks(@Param("now") Date now); |
| | | |
| | | /** |
| | | * 修改库存 |
| | | * @param seckillId |
| | | * @param prodCount |
| | | * @return |
| | | */ |
| | | int updateStocksById(@Param("seckillId") Long seckillId, @Param("prodCount") Integer prodCount); |
| | | |
| | | /** |
| | | * 修改商品类型 |
| | | * @param seckillIds |
| | | */ |
| | | void changeProdTypeBySeckillIdList(@Param("seckillIds") List<Long> seckillIds); |
| | | |
| | | /** |
| | | * 改变秒杀活动状态 |
| | | * @param seckillIds |
| | | */ |
| | | void changeSeckillStatusBySeckillIdList(@Param("seckillIds") List<Long> seckillIds); |
| | | |
| | | /** |
| | | * 获取秒杀活动通过订单号 |
| | | * @param orderNumber |
| | | * @return |
| | | */ |
| | | Seckill getSeckillByOrderNumber(@Param("orderNumber") String orderNumber); |
| | | |
| | | /** |
| | | * 加库存 |
| | | * @param seckillId |
| | | * @param countNum |
| | | */ |
| | | void addInventory(@Param("seckillId") Long seckillId, @Param("countNum") Integer countNum); |
| | | |
| | | /** |
| | | * 获取正常状态下的秒杀商品分页 |
| | | * @param page 分页信息 |
| | | * @param product 筛选参数 |
| | | * @return 正常状态下的秒杀商品分页 |
| | | */ |
| | | IPage<Product> pageSeckillNormalProd(PageParam<Product> page, @Param("product") ProductParam product); |
| | | |
| | | /** |
| | | * 根据参数分页获取秒杀信息 |
| | | * @param page |
| | | * @param seckillVO |
| | | * @return |
| | | */ |
| | | IPage<SeckillPageDto> pageSeckill(PageParam<Seckill> page, @Param("seckill") SeckillVO seckillVO); |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.dao; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.yami.shop.seckill.common.model.SeckillOrder; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | | /** |
| | | * 秒杀订单 |
| | | * |
| | | * @author LGH |
| | | * @date 2019-08-28 09:36:59 |
| | | */ |
| | | public interface SeckillOrderMapper extends BaseMapper<SeckillOrder> { |
| | | |
| | | /** |
| | | * 修改状态 |
| | | * @param orderNumber |
| | | * @param state |
| | | */ |
| | | void updateStateByOrderNumber(@Param("orderNumber") String orderNumber, @Param("state") int state); |
| | | |
| | | /** |
| | | * 取消未支付 |
| | | * @param orderNumber |
| | | */ |
| | | void cancelUnpayOrderByOrderNumber(@Param("orderNumber") String orderNumber); |
| | | |
| | | /** |
| | | * 取消未支付订单 |
| | | */ |
| | | void cancelUnpayOrder(); |
| | | |
| | | /** |
| | | * 获取用户秒杀订单数量 |
| | | * @param seckillId |
| | | * @param prodId |
| | | * @param userId |
| | | * @return |
| | | */ |
| | | int selectNumByUser(@Param("seckillId") Long seckillId, @Param("prodId") Long prodId, @Param("userId") String userId); |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.dao; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.yami.shop.seckill.common.model.SeckillSku; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 秒杀活动sku |
| | | * |
| | | * @author LGH |
| | | * @date 2019-08-28 09:36:59 |
| | | */ |
| | | public interface SeckillSkuMapper extends BaseMapper<SeckillSku> { |
| | | |
| | | /** |
| | | * 修改库存 |
| | | * |
| | | * @param seckillSkuId |
| | | * @param prodCount |
| | | * @return |
| | | */ |
| | | int updateStocks(@Param("seckillSkuId") Long seckillSkuId, @Param("prodCount") Integer prodCount); |
| | | |
| | | /** |
| | | * 还原库存 |
| | | * |
| | | * @param now |
| | | */ |
| | | void returnStocks(@Param("now") Date now); |
| | | |
| | | /** |
| | | * 还原库存由订单号 |
| | | * |
| | | * @param orderNumber |
| | | */ |
| | | void returnStocksByOrderNumber(@Param("orderNumber") String orderNumber); |
| | | |
| | | /** |
| | | * 获取秒杀活动的sku由skuid和订单号 |
| | | * |
| | | * @param skuId |
| | | * @param orderNumber |
| | | * @return |
| | | */ |
| | | SeckillSku getSeckillSkuBySkuIdAndOrderNumber(@Param("skuId") Long skuId, @Param("orderNumber") String orderNumber); |
| | | |
| | | /** |
| | | * 加库存 |
| | | * |
| | | * @param seckillSkuId |
| | | * @param countNum |
| | | */ |
| | | void addInventory(@Param("seckillSkuId") Long seckillSkuId, @Param("countNum") Integer countNum); |
| | | |
| | | /** |
| | | * 找出当前未支付订单的skuId列表,统一删除缓存 |
| | | * |
| | | * @return |
| | | */ |
| | | List<Long> listSkuIds(); |
| | | |
| | | /** |
| | | * 获取秒杀最低原价 |
| | | * |
| | | * @param seckillIds |
| | | * @return |
| | | */ |
| | | List<SeckillSku> listSeckillMinOriginalPrice(@Param("seckillIds") List<Long> seckillIds); |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.dto; |
| | | |
| | | import com.yami.shop.bean.app.dto.UserAddrDto; |
| | | import com.yami.shop.bean.model.OrderInvoice; |
| | | import com.yami.shop.bean.vo.VirtualRemarkVO; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 秒杀订单合并信息 |
| | | * @author LGH |
| | | */ |
| | | @Data |
| | | public class SeckillOrderMergerDto { |
| | | |
| | | @Schema(description = "实际总值" , required = true) |
| | | private Double actualTotal; |
| | | |
| | | @Schema(description = "商品总值" , required = true) |
| | | private Double total; |
| | | |
| | | @Schema(description = "秒杀优惠" , required = true) |
| | | private Double seckillReduce; |
| | | |
| | | @Schema(description = "运费" , required = true) |
| | | private Double transfee; |
| | | |
| | | @Schema(description = "商品总数" , required = true) |
| | | private Integer totalCount; |
| | | |
| | | @Schema(description = "地址Dto" , required = true) |
| | | private UserAddrDto userAddr; |
| | | |
| | | @Schema(description = "商品信息" , required = true) |
| | | private SeckillShopCartItemDto shopCartItem; |
| | | |
| | | @Schema(description = "msgId" ,required=true) |
| | | private String msgId; |
| | | |
| | | @Schema(description = "userId" ,required=true) |
| | | private String userId; |
| | | |
| | | @Schema(description = "订单备注" ,required=true) |
| | | private String remarks; |
| | | |
| | | @Schema(description = "orderNumber" ) |
| | | private String orderNumber; |
| | | |
| | | @Schema(description = "订单发票信息" ) |
| | | private OrderInvoice orderInvoice; |
| | | |
| | | @Schema(description = "商品类别 0.实物商品 1. 虚拟商品" ) |
| | | private Integer mold; |
| | | |
| | | @Schema(description = "虚拟商品留言备注" ) |
| | | private List<VirtualRemarkVO> virtualRemarkList; |
| | | } |
New file |
| | |
| | | package com.yami.shop.seckill.common.dto; |
| | | |
| | | import com.yami.shop.seckill.common.model.Seckill; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | @Schema(description = "秒杀分页展示信息") |
| | | public class SeckillPageDto extends Seckill { |
| | | @Schema(description = "商品名字" , required = true) |
| | | private String prodName; |
| | | @Schema(description = "商品图片" , required = true) |
| | | private String pic; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.dto; |
| | | |
| | | import com.fasterxml.jackson.databind.annotation.JsonSerialize; |
| | | import com.yami.shop.common.serializer.json.ImgJsonSerializer; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * 秒杀商品信息简单版,用于分页 |
| | | * @author LGH |
| | | */ |
| | | @Data |
| | | public class SeckillProductSimpleDto { |
| | | |
| | | @Schema(description = "商品ID" , required = true) |
| | | private Long prodId; |
| | | |
| | | @Schema(description = "商品名称" ) |
| | | private String prodName; |
| | | |
| | | @JsonSerialize(using = ImgJsonSerializer.class) |
| | | @Schema(description = "商品主图" , required = true) |
| | | private String pic; |
| | | |
| | | @Schema(description = "秒杀活动id" , required = true) |
| | | private Long seckillId; |
| | | |
| | | @Schema(description = "活动名称" , required = true) |
| | | private String seckillName; |
| | | |
| | | @Schema(description = "开始时间" , required = true) |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private Date startTime; |
| | | |
| | | @Schema(description = "结束时间" , required = true) |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private Date endTime; |
| | | |
| | | @Schema(description = "秒杀活动剩余总库存" , required = true) |
| | | private Integer seckillTotalStocks; |
| | | |
| | | @Schema(description = "秒杀活动原始库存" , required = true) |
| | | private Integer seckillOriginStocks; |
| | | |
| | | @Schema(description = "商品价格" , required = true) |
| | | private Double price; |
| | | |
| | | @Schema(description = "秒杀活动最低价" , required = true) |
| | | private Double seckillPrice; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.dto; |
| | | |
| | | import com.yami.shop.bean.app.dto.ShopCartItemDto; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | /** |
| | | * 秒杀购物项 dto |
| | | * @author LGH |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = false) |
| | | public class SeckillShopCartItemDto extends ShopCartItemDto { |
| | | |
| | | |
| | | @Schema(description = "秒杀skuId" , required = true) |
| | | private Long seckillSkuId; |
| | | |
| | | @Schema(description = "秒杀活动Id" , required = true) |
| | | private Long seckillId; |
| | | |
| | | @Schema(description = "秒杀价格" , required = true) |
| | | private Double seckillPrice; |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.enums; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * 秒杀状态枚举类型 |
| | | * @author yami |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum SeckillEnum { |
| | | /** 失效 */ |
| | | INVALID(0,"失效"), |
| | | |
| | | /** 正常 */ |
| | | NORMAL(1,"正常"), |
| | | |
| | | /** 违规下架 */ |
| | | OFFLINE(2,"违规下架"), |
| | | |
| | | /** 等待审核 */ |
| | | WAIT_AUDIT(3,"等待审核"), |
| | | ; |
| | | private int value; |
| | | private String desc; |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.listener; |
| | | |
| | | |
| | | import com.yami.shop.bean.enums.OrderType; |
| | | import com.yami.shop.bean.event.CancelOrderEvent; |
| | | import com.yami.shop.bean.order.CancelOrderOrder; |
| | | import com.yami.shop.seckill.common.service.SeckillOrderService; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.context.event.EventListener; |
| | | import org.springframework.core.annotation.Order; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * 取消订单事件 |
| | | * @author yami |
| | | */ |
| | | @Component("seckillCancelOrderListener") |
| | | @AllArgsConstructor |
| | | public class CancelOrderListener { |
| | | |
| | | |
| | | private final SeckillOrderService seckillOrderService; |
| | | |
| | | @EventListener(CancelOrderEvent.class) |
| | | @Order(CancelOrderOrder.SECKILL) |
| | | public void seckillCancelOrderEventListener(CancelOrderEvent event) { |
| | | String orderNumber = event.getOrder().getOrderNumber(); |
| | | // 不是秒杀订单直接返回 |
| | | if (!OrderType.SECKILL.value().equals(event.getOrder().getOrderType())) { |
| | | return; |
| | | } |
| | | |
| | | seckillOrderService.cancelUnpayOrderByOrderNumber(orderNumber); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.yami.shop.seckill.common.listener; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.yami.shop.bean.event.CategoryWordEvent; |
| | | import com.yami.shop.seckill.common.enums.SeckillEnum; |
| | | import com.yami.shop.seckill.common.model.Seckill; |
| | | import com.yami.shop.seckill.common.service.SeckillService; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.context.event.EventListener; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Component("CategorySeckillListener") |
| | | @Slf4j |
| | | @AllArgsConstructor |
| | | public class CategorySeckillListener { |
| | | private final SeckillService seckillService; |
| | | |
| | | @EventListener(CategoryWordEvent.class) |
| | | public void categorySeckillListener(CategoryWordEvent event){ |
| | | List<Long> prodIds = event.getProdIdList(); |
| | | // 失效秒杀活动 |
| | | if(CollUtil.isNotEmpty(prodIds)){ |
| | | seckillService.update(Wrappers.lambdaUpdate(Seckill.class) |
| | | .set(Seckill::getStatus, SeckillEnum.INVALID.getValue()) |
| | | .in(Seckill::getProdId, prodIds) |
| | | .eq(Seckill::getStatus, SeckillEnum.NORMAL.getValue()) |
| | | ); |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.listener; |
| | | |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.yami.shop.bean.enums.ProdType; |
| | | import com.yami.shop.bean.event.EsProductActivityInfoEvent; |
| | | import com.yami.shop.bean.order.EsProductOrder; |
| | | import com.yami.shop.bean.vo.search.ProductSearchVO; |
| | | import com.yami.shop.bean.vo.search.SeckillSearchVO; |
| | | import com.yami.shop.seckill.common.dao.SeckillMapper; |
| | | import com.yami.shop.seckill.common.model.Seckill; |
| | | import lombok.AllArgsConstructor; |
| | | import ma.glasnost.orika.MapperFacade; |
| | | import org.springframework.context.event.EventListener; |
| | | import org.springframework.core.annotation.Order; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * 获取商品团购数据事件 |
| | | * @author yami |
| | | */ |
| | | @Component("seckillEsProductActivityInfoListener") |
| | | @AllArgsConstructor |
| | | public class EsProductActivityInfoListener { |
| | | |
| | | private final SeckillMapper seckillMapper; |
| | | private final MapperFacade mapperFacade; |
| | | |
| | | @EventListener(EsProductActivityInfoEvent.class) |
| | | @Order(EsProductOrder.SECKILL) |
| | | public void seckillEsProductListener(EsProductActivityInfoEvent event) { |
| | | List<ProductSearchVO> productList = event.getProductList(); |
| | | List<Long> ids = productList.stream() |
| | | .filter(productSearchVO -> Objects.equals(productSearchVO.getProdType(), ProdType.PROD_TYPE_SECKILL.value()) && |
| | | Objects.nonNull(productSearchVO.getActivityStartTime())) |
| | | .map(ProductSearchVO::getActivityId).collect(Collectors.toList()); |
| | | // 没有秒杀商品需要处理 |
| | | if (CollUtil.isEmpty(ids)) { |
| | | return; |
| | | } |
| | | List<Seckill> seckillActivities = seckillMapper.selectList(new LambdaQueryWrapper<Seckill>().in(Seckill::getSeckillId, ids)); |
| | | Map<Long, Seckill> groupMap = seckillActivities.stream().collect(Collectors.toMap(Seckill::getSeckillId, s -> s)); |
| | | for (ProductSearchVO productSearchVO : productList) { |
| | | Seckill seckill = groupMap.get(productSearchVO.getActivityId()); |
| | | if (Objects.isNull(seckill)) { |
| | | continue; |
| | | } |
| | | productSearchVO.setActivityInProgress(Boolean.TRUE); |
| | | SeckillSearchVO seckillSearchVO = mapperFacade.map(seckill, SeckillSearchVO.class); |
| | | productSearchVO.setSeckillSearchVO(seckillSearchVO); |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.listener; |
| | | |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.yami.shop.bean.bo.ProductBO; |
| | | import com.yami.shop.bean.enums.ProdType; |
| | | import com.yami.shop.bean.event.EsProductEvent; |
| | | import com.yami.shop.bean.order.EsProductOrder; |
| | | import com.yami.shop.seckill.common.dao.SeckillMapper; |
| | | import com.yami.shop.seckill.common.dao.SeckillSkuMapper; |
| | | import com.yami.shop.seckill.common.model.Seckill; |
| | | import com.yami.shop.seckill.common.model.SeckillSku; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.context.event.EventListener; |
| | | import org.springframework.core.annotation.Order; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * 获取es商品团购数据事件 |
| | | * @author yami |
| | | */ |
| | | @Component("seckillEsProductListener") |
| | | @AllArgsConstructor |
| | | public class EsProductListener { |
| | | |
| | | private final SeckillMapper seckillMapper; |
| | | private final SeckillSkuMapper seckillSkuMapper; |
| | | |
| | | @EventListener(EsProductEvent.class) |
| | | @Order(EsProductOrder.SECKILL) |
| | | public void seckillEsProductListener(EsProductEvent event) { |
| | | List<ProductBO> productList = event.getProductList(); |
| | | if (CollUtil.isEmpty(productList) || Objects.nonNull(event.getOperationType())) { |
| | | return; |
| | | } |
| | | List<ProductBO> seckillProductList = new ArrayList<>(); |
| | | List<Long> seckillIds = new ArrayList<>(); |
| | | for (ProductBO productBO : productList) { |
| | | if (!Objects.equals(productBO.getProdType(), ProdType.PROD_TYPE_SECKILL.value())) { |
| | | continue; |
| | | } |
| | | seckillProductList.add(productBO); |
| | | seckillIds.add(productBO.getActivityId()); |
| | | } |
| | | if (CollUtil.isEmpty(seckillIds)) { |
| | | return; |
| | | } |
| | | // 获取已启用的秒杀商品信息 |
| | | List<Seckill> seckillList = seckillMapper.selectList(new LambdaQueryWrapper<Seckill>().in(Seckill::getSeckillId, seckillIds).eq(Seckill::getStatus, 1)); |
| | | Map<Long, Seckill> seckillMap = seckillList.stream().collect(Collectors.toMap(Seckill::getSeckillId, s -> s)); |
| | | List<SeckillSku> seckillSkus = seckillSkuMapper.listSeckillMinOriginalPrice(seckillIds); |
| | | Map<Long, Double> seckillSkuMap = seckillSkus.stream().collect(Collectors.toMap(SeckillSku::getSeckillId, SeckillSku::getSeckillPrice)); |
| | | Long currentTime = System.currentTimeMillis(); |
| | | for (ProductBO productBO : seckillProductList) { |
| | | if (!seckillMap.containsKey(productBO.getActivityId())) { |
| | | continue; |
| | | } |
| | | Seckill seckill = seckillMap.get(productBO.getActivityId()); |
| | | // 当前时间大于等于活动结束时间, 则不添加活动信息 |
| | | if (seckill.getEndTime().getTime() <= currentTime) { |
| | | continue; |
| | | } |
| | | // 插入活动开始时间 |
| | | productBO.setActivityStartTime(seckill.getStartTime().getTime()); |
| | | // 秒杀最低价 |
| | | productBO.setActivityPrice(seckill.getSeckillPrice()); |
| | | // 秒杀商品规格中最低的sku原价 |
| | | productBO.setActivityOriginalPrice(seckillSkuMap.get(productBO.getActivityId())); |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.listener; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.yami.shop.bean.event.SubmitSeckillOrderEvent; |
| | | import com.yami.shop.bean.model.Order; |
| | | import com.yami.shop.seckill.common.model.Seckill; |
| | | import com.yami.shop.seckill.common.model.SeckillOrder; |
| | | import com.yami.shop.seckill.common.service.SeckillOrderService; |
| | | import com.yami.shop.seckill.common.service.SeckillService; |
| | | import lombok.AllArgsConstructor; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.springframework.context.event.EventListener; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 获取订单相关信息 |
| | | * @author yami |
| | | */ |
| | | @Component("seckillGetSeckillOrderInofListener") |
| | | @AllArgsConstructor |
| | | public class GetSeckillOrderInofListener { |
| | | |
| | | private final SeckillOrderService seckillOrderService; |
| | | private final SeckillService seckillService; |
| | | |
| | | @EventListener(SubmitSeckillOrderEvent.class) |
| | | public void seckillGetSeckillOrderInofListener(SubmitSeckillOrderEvent event) { |
| | | Order order = event.getOrder(); |
| | | event.setMaxCancelTime(0); |
| | | if (Objects.isNull(order)) { |
| | | return; |
| | | } |
| | | String orderNumber = order.getOrderNumber(); |
| | | List<SeckillOrder> list = seckillOrderService.list(new LambdaQueryWrapper<SeckillOrder>().eq(SeckillOrder::getOrderNumber, orderNumber)); |
| | | if (CollectionUtils.isEmpty(list)) { |
| | | return; |
| | | } |
| | | SeckillOrder seckillOrder = list.get(0); |
| | | Seckill seckill = seckillService.getSeckillById(seckillOrder.getSeckillId()); |
| | | if (Objects.isNull(seckill)) { |
| | | return; |
| | | } |
| | | event.setMaxCancelTime(seckill.getMaxCancelTime()); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.listener; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.yami.shop.bean.event.PaySuccessHandleOrderStockEvent; |
| | | import com.yami.shop.bean.model.OrderItem; |
| | | import com.yami.shop.bean.order.PaySuccessOrderOrder; |
| | | import com.yami.shop.seckill.common.dao.SeckillOrderMapper; |
| | | import com.yami.shop.seckill.common.model.Seckill; |
| | | import com.yami.shop.seckill.common.model.SeckillOrder; |
| | | import com.yami.shop.seckill.common.service.SeckillService; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.context.event.EventListener; |
| | | import org.springframework.core.annotation.Order; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 秒杀成功回调 |
| | | * @author LGH |
| | | */ |
| | | @Component("paySuccessHandleOrderStockListener") |
| | | @AllArgsConstructor |
| | | public class PaySuccessHandleOrderStockListener { |
| | | |
| | | private final SeckillService seckillService; |
| | | private final SeckillOrderMapper seckillOrderMapper; |
| | | |
| | | /** |
| | | * 更新秒杀状态 |
| | | */ |
| | | @EventListener(PaySuccessHandleOrderStockEvent.class) |
| | | @Order(PaySuccessOrderOrder.SECKILL) |
| | | public void seckillPaySuccessListener(PaySuccessHandleOrderStockEvent event) { |
| | | com.yami.shop.bean.model.Order order = event.getOrder(); |
| | | OrderItem orderItem = order.getOrderItems().get(0); |
| | | boolean stockCheck = true; |
| | | SeckillOrder seckillOrder = seckillOrderMapper.selectOne(new LambdaQueryWrapper<SeckillOrder>().eq(SeckillOrder::getOrderNumber, orderItem.getOrderNumber())); |
| | | // 秒杀活动信息(来自缓存) |
| | | Seckill seckill = seckillService.getSeckillById(seckillOrder.getSeckillId()); |
| | | // 判断之前秒杀的商品有没有超过限制,-1表示商品不限制秒杀数量 |
| | | if (!Objects.equals(seckill.getMaxNum(), -1)) { |
| | | int dbCount = seckillOrderMapper.selectNumByUser(seckill.getSeckillId(), seckill.getProdId(), order.getUserId()); |
| | | if (seckill.getMaxNum() < orderItem.getProdCount() + dbCount) { |
| | | stockCheck = false; |
| | | } |
| | | } |
| | | // 用户没有达到购买上限,且秒杀商品还有库存,则购买成功 |
| | | boolean deductStock = seckillService.handlerSeckillOrderStock(orderItem,seckillOrder); |
| | | if(deductStock && stockCheck){ |
| | | event.getSuccessOrderList().add(order); |
| | | }else { |
| | | event.getRefundOrderList().add(order); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.listener; |
| | | |
| | | import com.yami.shop.bean.enums.OrderType; |
| | | import com.yami.shop.bean.event.PaySuccessOrderEvent; |
| | | import com.yami.shop.bean.order.PaySuccessOrderOrder; |
| | | import com.yami.shop.seckill.common.dao.SeckillOrderMapper; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.context.event.EventListener; |
| | | import org.springframework.core.annotation.Order; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 秒杀成功回调 |
| | | * @author LGH |
| | | */ |
| | | @Component("seckillPaySuccessListener") |
| | | @AllArgsConstructor |
| | | public class PaySuccessOrderListener { |
| | | |
| | | private SeckillOrderMapper seckillOrderMapper; |
| | | |
| | | /** |
| | | * 更新秒杀状态 |
| | | */ |
| | | @EventListener(PaySuccessOrderEvent.class) |
| | | @Order(PaySuccessOrderOrder.SECKILL) |
| | | public void seckillPaySuccessListener(PaySuccessOrderEvent event) { |
| | | List<com.yami.shop.bean.model.Order> orders = event.getOrders(); |
| | | |
| | | for (com.yami.shop.bean.model.Order order : orders) { |
| | | if (!Objects.equals(order.getOrderType(), OrderType.SECKILL.value())) { |
| | | return; |
| | | } |
| | | // 更新秒杀状态 |
| | | seckillOrderMapper.updateStateByOrderNumber(order.getOrderNumber(), 1); |
| | | |
| | | } |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.listener; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.yami.shop.bean.enums.ProdType; |
| | | import com.yami.shop.bean.event.ProcessActivityProdPriceEvent; |
| | | import com.yami.shop.bean.model.Product; |
| | | import com.yami.shop.bean.param.ProductParam; |
| | | import com.yami.shop.seckill.common.model.Seckill; |
| | | import com.yami.shop.seckill.common.service.SeckillService; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.context.event.EventListener; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * 处理活动商品价格的事件 |
| | | * @author lhd |
| | | */ |
| | | @Component("processSeckillProdPriceListener") |
| | | @AllArgsConstructor |
| | | public class ProcessActivityProdPriceListener { |
| | | |
| | | private final SeckillService seckillService; |
| | | |
| | | @EventListener(ProcessActivityProdPriceEvent.class) |
| | | public void processSeckillProdPrice(ProcessActivityProdPriceEvent event) { |
| | | ProductParam productParam = event.getProduct(); |
| | | if(Objects.isNull(productParam.getProdType()) || !Objects.equals(productParam.getProdType(), ProdType.PROD_TYPE_SECKILL.value())) { |
| | | return; |
| | | } |
| | | List<Product> products = event.getProducts(); |
| | | List<Long> prodIds = new ArrayList<>(); |
| | | products.forEach(product -> prodIds.add(product.getProdId())); |
| | | Date date = new Date(); |
| | | List<Seckill> seckillList = seckillService.list(new LambdaQueryWrapper<Seckill>() |
| | | .eq(Seckill::getStatus, 1).lt(Seckill::getStartTime, date) |
| | | .gt(Seckill::getEndTime, date).in(Seckill::getProdId, prodIds)); |
| | | Map<Long, Double> priceMap = seckillList.stream().collect(Collectors.toMap(Seckill::getProdId, Seckill::getSeckillPrice)); |
| | | for (Product product : products) { |
| | | Double price = priceMap.get(product.getProdId()); |
| | | product.setActivityPrice(price); |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.listener; |
| | | |
| | | import com.yami.shop.bean.enums.ProdStatusEnums; |
| | | import com.yami.shop.bean.enums.ProdType; |
| | | import com.yami.shop.bean.event.ProdChangeStatusEvent; |
| | | import com.yami.shop.bean.model.Product; |
| | | import com.yami.shop.bean.order.GeneralActivitiesOrder; |
| | | import com.yami.shop.seckill.common.model.Seckill; |
| | | import com.yami.shop.seckill.common.service.SeckillService; |
| | | import com.yami.shop.seckill.common.service.SeckillSkuService; |
| | | import com.yami.shop.service.ProductService; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.context.event.EventListener; |
| | | import org.springframework.core.annotation.Order; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 秒杀商品状态修改监听 |
| | | * @author LGH |
| | | */ |
| | | @Component("seckillProdChangeStatus") |
| | | @AllArgsConstructor |
| | | public class ProdChangeStatusListener { |
| | | private final SeckillService seckillService; |
| | | |
| | | private final ProductService productService; |
| | | |
| | | private final SeckillSkuService seckillSkuService; |
| | | |
| | | /** |
| | | * 使秒杀活动失效 |
| | | */ |
| | | @EventListener(ProdChangeStatusEvent.class) |
| | | @Order(GeneralActivitiesOrder.SECKILL) |
| | | public void seckillProdChangeStatusListener(ProdChangeStatusEvent event) { |
| | | Product product = event.getProduct(); |
| | | // 不是秒杀商品,就不用管他 |
| | | if(!Objects.equals(product.getProdType(), ProdType.PROD_TYPE_SECKILL.value())){ |
| | | return; |
| | | } |
| | | |
| | | // 如果是商品上线,就不管他了 |
| | | if (Objects.equals(ProdStatusEnums.NORMAL.getValue(), event.getStatus())) { |
| | | return; |
| | | } |
| | | |
| | | // 平台审核 |
| | | if (Objects.equals(ProdStatusEnums.PLATFORM_AUDIT.getValue(), event.getStatus())) { |
| | | return; |
| | | } |
| | | |
| | | Seckill seckill = seckillService.getById(product.getActivityId()); |
| | | |
| | | seckillService.invalidById(seckill); |
| | | |
| | | productService.removeProdCacheByProdId(seckill.getProdId()); |
| | | seckillSkuService.removeSeckillSkuCacheBySeckillId(seckill.getSeckillId()); |
| | | seckillService.removeSeckillCache(seckill.getSeckillId(), seckill.getProdId()); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.listener; |
| | | |
| | | import com.yami.shop.bean.enums.ShopStatus; |
| | | import com.yami.shop.bean.event.ShopChangeStatusEvent; |
| | | import com.yami.shop.bean.order.GeneralActivitiesOrder; |
| | | import com.yami.shop.seckill.common.model.Seckill; |
| | | import com.yami.shop.seckill.common.service.SeckillService; |
| | | import com.yami.shop.seckill.common.service.SeckillSkuService; |
| | | import com.yami.shop.service.ProductService; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.context.event.EventListener; |
| | | import org.springframework.core.annotation.Order; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * @Author lth |
| | | * @Date 2021/11/23 15:21 |
| | | */ |
| | | @Component("seckillShopChangeStatusListener") |
| | | @AllArgsConstructor |
| | | public class ShopChangeStatusListener { |
| | | |
| | | private final SeckillService seckillService; |
| | | |
| | | private final ProductService productService; |
| | | |
| | | private final SeckillSkuService seckillSkuService; |
| | | |
| | | |
| | | @EventListener(ShopChangeStatusEvent.class) |
| | | @Order(GeneralActivitiesOrder.SECKILL) |
| | | public void seckillShopChangeStatusListener(ShopChangeStatusEvent event) { |
| | | Long shopId = event.getShopId(); |
| | | ShopStatus shopStatus = event.getShopStatus(); |
| | | if (Objects.equals(shopStatus.value(), ShopStatus.OFFLINE.value())) { |
| | | // 店铺下线,把该店铺的秒杀活动失效 |
| | | List<Seckill> invalidSeckillList = seckillService.invalidByShopId(shopId); |
| | | // 清除缓存 |
| | | for (Seckill seckill : invalidSeckillList) { |
| | | productService.removeProdCacheByProdId(seckill.getProdId()); |
| | | seckillSkuService.removeSeckillSkuCacheBySeckillId(seckill.getSeckillId()); |
| | | seckillService.removeSeckillCache(seckill.getSeckillId(), seckill.getProdId()); |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.model; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import javax.validation.constraints.NotNull; |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * 秒杀信息 |
| | | * |
| | | * @author LGH |
| | | * @date 2019-08-28 09:36:59 |
| | | */ |
| | | @Data |
| | | @TableName("tz_seckill") |
| | | public class Seckill implements Serializable{ |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @TableId |
| | | @Schema(description = "秒杀活动id" , required = true) |
| | | private Long seckillId; |
| | | |
| | | @Schema(description = "商品id" , required = true) |
| | | private Long prodId; |
| | | |
| | | @NotNull |
| | | @Schema(description = "活动名称" , required = true) |
| | | private String seckillName; |
| | | |
| | | @NotNull |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | @Schema(description = "开始时间" , required = true) |
| | | private Date startTime; |
| | | |
| | | @NotNull |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | @Schema(description = "结束时间" , required = true) |
| | | private Date endTime; |
| | | |
| | | @Schema(description = "活动标签" , required = true) |
| | | private String seckillTag; |
| | | |
| | | @Schema(description = "限购数量" , required = true) |
| | | private Integer maxNum; |
| | | |
| | | @Schema(description = "取消订单时间" , required = true) |
| | | private Integer maxCancelTime; |
| | | |
| | | @Schema(description = "店铺id" , required = true) |
| | | private Long shopId; |
| | | |
| | | @Schema(description = "是否已删除 0 未删除 1已删除" , required = true) |
| | | private Integer isDelete; |
| | | |
| | | @Schema(description = "状态:0 失效 1正常" , required = true) |
| | | private Integer status; |
| | | |
| | | @Schema(description = "秒杀活动剩余库存" , required = true) |
| | | private Integer seckillTotalStocks; |
| | | |
| | | @Schema(description = "秒杀活动原始库存" , required = true) |
| | | private Integer seckillOriginStocks; |
| | | |
| | | @Schema(description = "秒杀活动最低价" , required = true) |
| | | private Double seckillPrice; |
| | | |
| | | @TableField(exist = false) |
| | | @Schema(description = "店铺名称" ) |
| | | private String shopName; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.model; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * 秒杀订单 |
| | | * |
| | | * @author LGH |
| | | * @date 2019-08-28 09:36:59 |
| | | */ |
| | | @Data |
| | | @TableName("tz_seckill_order") |
| | | public class SeckillOrder implements Serializable{ |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Schema(description = "秒杀订单id" ) |
| | | @TableId |
| | | private Long seckillOrderId; |
| | | |
| | | @Schema(description = "秒杀id" ) |
| | | private Long seckillId; |
| | | |
| | | @Schema(description = "用户id" ) |
| | | private String userId; |
| | | |
| | | @Schema(description = "商品id" ) |
| | | private Long prodId; |
| | | |
| | | @Schema(description = "订单号" ) |
| | | private String orderNumber; |
| | | |
| | | @Schema(description = "状态 -1指无效,0指成功,1指已付款" ) |
| | | private Integer state; |
| | | |
| | | @Schema(description = "秒杀到的商品数量" ) |
| | | private Integer prodCount; |
| | | |
| | | @Schema(description = "创建时间" ) |
| | | private Date createTime; |
| | | |
| | | @Schema(description = "秒杀规格id" ) |
| | | private Long seckillSkuId; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.model; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * 秒杀活动sku |
| | | * |
| | | * @author LGH |
| | | * @date 2019-08-28 09:36:59 |
| | | */ |
| | | @Data |
| | | @TableName("tz_seckill_sku") |
| | | public class SeckillSku implements Serializable{ |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * 秒杀活动单个skuid |
| | | */ |
| | | @TableId |
| | | private Long seckillSkuId; |
| | | /** |
| | | * skuId |
| | | */ |
| | | private Long skuId; |
| | | /** |
| | | * 秒杀活动id |
| | | */ |
| | | private Long seckillId; |
| | | /** |
| | | * 用于秒杀的库存 |
| | | */ |
| | | private Integer seckillStocks; |
| | | /** |
| | | * 秒杀价格 |
| | | */ |
| | | private Double seckillPrice; |
| | | /** |
| | | * 单个sku的状态 |
| | | */ |
| | | @TableField(exist = false) |
| | | private Integer status; |
| | | /** |
| | | * sku图片 |
| | | */ |
| | | @TableField(exist = false) |
| | | private String pic; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.yami.shop.bean.app.dto.ShopCartOrderMergerDto; |
| | | import com.yami.shop.seckill.common.dto.SeckillOrderMergerDto; |
| | | import com.yami.shop.seckill.common.model.Seckill; |
| | | import com.yami.shop.seckill.common.model.SeckillOrder; |
| | | |
| | | /** |
| | | * 秒杀订单 |
| | | * |
| | | * @author LGH |
| | | * @date 2019-08-28 09:36:59 |
| | | */ |
| | | public interface SeckillOrderService extends IService<SeckillOrder> { |
| | | |
| | | /** |
| | | * 将确认的的订单信息缓存起来 |
| | | * @param userId |
| | | * @param dto |
| | | * @return |
| | | */ |
| | | SeckillOrderMergerDto putConfirmOrderCache(String userId , SeckillOrderMergerDto dto); |
| | | |
| | | /** |
| | | * 获取缓存的确认订单信息 |
| | | * @param userId |
| | | * @return |
| | | */ |
| | | SeckillOrderMergerDto getConfirmOrderCache(String userId); |
| | | |
| | | /** |
| | | * 移除确认的订单的缓存 |
| | | * @param userId |
| | | */ |
| | | void removeConfirmOrderCache(String userId); |
| | | |
| | | /** |
| | | * 提交订单返回订单号 |
| | | * @param dto |
| | | * @return |
| | | */ |
| | | String submit(ShopCartOrderMergerDto dto); |
| | | |
| | | /** |
| | | * 校验订单商品数量 |
| | | * @param seckill |
| | | * @param userId |
| | | * @param prodCount |
| | | */ |
| | | void checkOrderProdNum(Seckill seckill,String userId, int prodCount); |
| | | |
| | | /** |
| | | * 取消超时订单未支付订单 |
| | | */ |
| | | void cancelOrderUnpayOrderByTime(); |
| | | |
| | | /** |
| | | * 取消未支付订单 |
| | | * @param orderNumber |
| | | */ |
| | | void cancelUnpayOrderByOrderNumber(String orderNumber); |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.service; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.yami.shop.bean.app.vo.SeckillVO; |
| | | import com.yami.shop.bean.model.OrderItem; |
| | | import com.yami.shop.bean.model.Product; |
| | | import com.yami.shop.bean.param.OfflineHandleEventAuditParam; |
| | | import com.yami.shop.bean.param.ProductParam; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.seckill.common.dto.SeckillProductSimpleDto; |
| | | import com.yami.shop.seckill.common.model.Seckill; |
| | | import com.yami.shop.seckill.common.model.SeckillOrder; |
| | | import com.yami.shop.seckill.common.model.SeckillSku; |
| | | import com.yami.shop.seckill.common.dto.SeckillPageDto; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 秒杀信息 |
| | | * |
| | | * @author LGH |
| | | * @date 2019-08-28 09:36:59 |
| | | */ |
| | | public interface SeckillService extends IService<Seckill> { |
| | | |
| | | /** |
| | | * 分页获取正常状态的秒杀商品 |
| | | * @param page |
| | | * @param product |
| | | * @return |
| | | */ |
| | | IPage<Product> pageSeckillNormalProd(PageParam<Product> page, ProductParam product); |
| | | |
| | | /** |
| | | * 根据参数分页获取秒杀信息 |
| | | * @param page |
| | | * @param seckillVO |
| | | * @return |
| | | */ |
| | | IPage<SeckillPageDto> pageSeckill(PageParam<Seckill> page, SeckillVO seckillVO); |
| | | |
| | | /** |
| | | * 保存秒杀信息 |
| | | * |
| | | * @param seckill |
| | | * @param seckillSkus |
| | | */ |
| | | void saveSeckill(Seckill seckill, List<SeckillSku> seckillSkus); |
| | | |
| | | /** |
| | | * 根据id获取秒杀信息 |
| | | * |
| | | * @param seckillId |
| | | * @return |
| | | */ |
| | | Seckill getSeckillById(Long seckillId); |
| | | |
| | | /** |
| | | * 根据商品id获取秒杀信息 |
| | | * |
| | | * @param prodId |
| | | * @return |
| | | */ |
| | | Seckill getSeckillByProdId(Long prodId); |
| | | |
| | | /** |
| | | * 删除秒杀缓存 |
| | | * @param seckillId |
| | | * @param prodId |
| | | */ |
| | | void removeSeckillCache(Long seckillId, Long prodId); |
| | | |
| | | /** |
| | | * 批量删除秒杀缓存 |
| | | * @param seckillIds |
| | | * @param prodIds |
| | | */ |
| | | void batchRemoveSeckillCache(List<Long> seckillIds, List<Long> prodIds); |
| | | |
| | | /** |
| | | * 验证 |
| | | * @param seckill |
| | | */ |
| | | void invalidById(Seckill seckill); |
| | | |
| | | /** |
| | | * 分页获取秒杀活动商品 |
| | | * @param page |
| | | * @param dbLang |
| | | * @return |
| | | */ |
| | | IPage<SeckillProductSimpleDto> pageSeckillProd(PageParam<SeckillProductSimpleDto> page, Integer dbLang); |
| | | |
| | | /** |
| | | * 平台 --获取分页秒杀数据 |
| | | * @param page |
| | | * @param seckill |
| | | * @return |
| | | */ |
| | | IPage<SeckillPageDto> getPlatformSeckillPage(PageParam<Seckill> page, Seckill seckill); |
| | | |
| | | /** |
| | | * 平台 --下线活动 |
| | | * @param seckill |
| | | * @param offlineReason |
| | | * @param sysUserId |
| | | */ |
| | | void offline(Seckill seckill, String offlineReason, Long sysUserId); |
| | | |
| | | |
| | | /** |
| | | * 平台 --审核秒杀操作 |
| | | * @param offlineHandleEventAuditParam |
| | | * @param sysUserId |
| | | */ |
| | | void auditSeckill(OfflineHandleEventAuditParam offlineHandleEventAuditParam, Long sysUserId); |
| | | |
| | | |
| | | /** |
| | | * 商家申请审核 |
| | | * @param eventId |
| | | * @param seckillId |
| | | * @param reapplyReason |
| | | */ |
| | | void auditApply(Long eventId, Long seckillId, String reapplyReason); |
| | | |
| | | /** |
| | | * 改变秒杀商品类型 |
| | | * @param seckillIds |
| | | */ |
| | | void changeProdTypeBySeckillIdList(List<Long> seckillIds); |
| | | |
| | | /** |
| | | * 获取订单对应的秒杀活动 |
| | | * @param orderNumber |
| | | * @return |
| | | */ |
| | | Seckill getSeckillByOrderNumber(String orderNumber); |
| | | |
| | | /** |
| | | * 加秒杀库存 |
| | | * @param seckillId |
| | | * @param prodCount |
| | | */ |
| | | void addInventory(Long seckillId, Integer prodCount); |
| | | |
| | | /** |
| | | * 根据店铺id失效店铺的秒杀活动 |
| | | * @param shopId |
| | | * @return 失效的秒杀活动 |
| | | */ |
| | | List<Seckill> invalidByShopId(Long shopId); |
| | | |
| | | /** |
| | | * 根据订单项返回库存处理结果 |
| | | * @param orderItem 订单项 |
| | | * @param seckillOrder |
| | | * @return 库存处理结果 |
| | | */ |
| | | Boolean handlerSeckillOrderStock(OrderItem orderItem, SeckillOrder seckillOrder); |
| | | |
| | | /** |
| | | * 根据商品id获取秒杀活动信息 |
| | | * @param prodId |
| | | * @return |
| | | */ |
| | | Seckill getByProdId(Long prodId); |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.yami.shop.seckill.common.model.SeckillSku; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 秒杀活动sku |
| | | * |
| | | * @author LGH |
| | | * @date 2019-08-28 09:36:59 |
| | | */ |
| | | public interface SeckillSkuService extends IService<SeckillSku> { |
| | | |
| | | /** |
| | | * 获取某个活动的秒杀sku列表 |
| | | * @param seckillId |
| | | * @return |
| | | */ |
| | | List<SeckillSku> listSeckillSkuBySeckillId(Long seckillId); |
| | | |
| | | /** |
| | | * 删除秒杀活动商品的缓存 |
| | | * @param seckillId |
| | | */ |
| | | void removeSeckillSkuCacheBySeckillId(Long seckillId); |
| | | |
| | | /** |
| | | * 获取秒杀商品 |
| | | * @param seckillSkuId |
| | | * @return |
| | | */ |
| | | SeckillSku getSeckillSkuById(Long seckillSkuId); |
| | | |
| | | /** |
| | | * 删除缓存 |
| | | * @param seckillSkuId |
| | | * @param seckillId |
| | | */ |
| | | void removeSeckillCacheSkuById(Long seckillSkuId,Long seckillId); |
| | | |
| | | /** |
| | | * 获取秒杀商品sku |
| | | * @param skuId |
| | | * @param orderNumber |
| | | * @return |
| | | */ |
| | | SeckillSku getSeckillSkuBySkuIdAndOrderNumber(Long skuId, String orderNumber); |
| | | |
| | | /** |
| | | * 加库存 |
| | | * @param seckillSkuId |
| | | * @param prodCount |
| | | */ |
| | | void addInventory(Long seckillSkuId, Integer prodCount); |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.yami.shop.bean.app.dto.ShopCartItemDto; |
| | | import com.yami.shop.bean.app.dto.ShopCartOrderDto; |
| | | import com.yami.shop.bean.app.dto.ShopCartOrderMergerDto; |
| | | import com.yami.shop.bean.event.PayManagerEvent; |
| | | import com.yami.shop.bean.model.PayInfo; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.i18n.I18nMessage; |
| | | import com.yami.shop.common.util.RedisUtil; |
| | | import com.yami.shop.dao.OrderMapper; |
| | | import com.yami.shop.dao.PayInfoMapper; |
| | | import com.yami.shop.seckill.common.dao.SeckillMapper; |
| | | import com.yami.shop.seckill.common.dao.SeckillOrderMapper; |
| | | import com.yami.shop.seckill.common.dao.SeckillSkuMapper; |
| | | import com.yami.shop.seckill.common.dto.SeckillOrderMergerDto; |
| | | import com.yami.shop.seckill.common.model.Seckill; |
| | | import com.yami.shop.seckill.common.model.SeckillOrder; |
| | | import com.yami.shop.seckill.common.service.SeckillOrderService; |
| | | import com.yami.shop.seckill.common.service.SeckillService; |
| | | import com.yami.shop.service.OrderService; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.cache.annotation.CacheEvict; |
| | | import org.springframework.cache.annotation.CachePut; |
| | | import org.springframework.cache.annotation.Cacheable; |
| | | import org.springframework.context.ApplicationEventPublisher; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 秒杀订单 |
| | | * |
| | | * @author LGH |
| | | * @date 2019-08-28 09:36:59 |
| | | */ |
| | | @Service |
| | | @AllArgsConstructor |
| | | public class SeckillOrderServiceImpl extends ServiceImpl<SeckillOrderMapper, SeckillOrder> implements SeckillOrderService { |
| | | |
| | | private final SeckillOrderMapper seckillOrderMapper; |
| | | |
| | | private final SeckillSkuMapper seckillSkuMapper; |
| | | |
| | | private final PayInfoMapper payInfoMapper; |
| | | |
| | | private final OrderMapper orderMapper; |
| | | |
| | | private final OrderService orderService; |
| | | |
| | | private final SeckillService seckillService; |
| | | |
| | | private final SeckillMapper seckillMapper; |
| | | |
| | | private final ApplicationEventPublisher eventPublisher; |
| | | |
| | | @Override |
| | | @CachePut(cacheNames = "ConfirmSeckillOrderCache", key = "#userId") |
| | | public SeckillOrderMergerDto putConfirmOrderCache(String userId, SeckillOrderMergerDto seckillOrderMergerDto) { |
| | | return seckillOrderMergerDto; |
| | | } |
| | | |
| | | @Override |
| | | @Cacheable(cacheNames = "ConfirmSeckillOrderCache", key = "#userId") |
| | | public SeckillOrderMergerDto getConfirmOrderCache(String userId) { |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | @CacheEvict(cacheNames = "ConfirmSeckillOrderCache", key = "#userId") |
| | | public void removeConfirmOrderCache(String userId) { |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public String submit(ShopCartOrderMergerDto dto) { |
| | | ShopCartOrderDto shopCartOrderDto = dto.getShopCartOrders().get(0); |
| | | ShopCartItemDto shopCartItemDto = shopCartOrderDto.getShopCartItemDiscounts().get(0).getShopCartItems().get(0); |
| | | |
| | | this.checkOrderProdNum(seckillService.getSeckillById(dto.getSeckillId()), dto.getUserId(), shopCartItemDto.getProdCount()); |
| | | |
| | | // 更新秒杀sku库存,乐观锁 |
| | | if (seckillSkuMapper.updateStocks(dto.getSeckillSkuId(), shopCartItemDto.getProdCount()) != 1) { |
| | | // 本商品已被秒杀完毕,下次记得早点来哟 |
| | | throw new YamiShopBindException("yami.seckill.finish"); |
| | | } |
| | | String orderNumber = shopCartOrderDto.getOrderNumber(); |
| | | // 保存秒杀订单信息 |
| | | SeckillOrder seckillOrder = new SeckillOrder(); |
| | | seckillOrder.setCreateTime(new Date()); |
| | | seckillOrder.setOrderNumber(orderNumber); |
| | | seckillOrder.setProdCount(shopCartItemDto.getProdCount()); |
| | | seckillOrder.setSeckillId(dto.getSeckillId()); |
| | | seckillOrder.setUserId(dto.getUserId()); |
| | | seckillOrder.setProdId(shopCartItemDto.getProdId()); |
| | | seckillOrder.setSeckillSkuId(dto.getSeckillSkuId()); |
| | | // 秒杀成功等待支付 |
| | | seckillOrder.setState(0); |
| | | seckillOrderMapper.insert(seckillOrder); |
| | | // 更新活动剩余库存 |
| | | if (seckillMapper.updateStocksById(dto.getSeckillId(), shopCartItemDto.getProdCount()) < 1) { |
| | | // 本商品已被秒杀完毕,下次记得早点来哟 |
| | | throw new YamiShopBindException("yami.seckill.finish"); |
| | | } |
| | | // 创建订单相关信息 |
| | | orderService.submit(dto); |
| | | return orderNumber; |
| | | } |
| | | |
| | | @Override |
| | | public void checkOrderProdNum(Seckill seckill, String userId, int prodCount) { |
| | | |
| | | // 判断之前秒杀的商品有没有超过限制,-1表示商品不限制秒杀数量 |
| | | if (!Objects.equals(seckill.getMaxNum(), -1)) { |
| | | int dbCount = seckillOrderMapper.selectNumByUser(seckill.getSeckillId(), seckill.getProdId(), userId); |
| | | if (seckill.getMaxNum() < prodCount + dbCount) { |
| | | // 本次秒杀商品限购 |
| | | String limitMsg = I18nMessage.getMessage("yami.seckill.limit.shop"); |
| | | String message = I18nMessage.getMessage("yami.seckill.num"); |
| | | throw new YamiShopBindException(limitMsg + seckill.getMaxNum() + message); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void cancelOrderUnpayOrderByTime() { |
| | | // 查询出微信or支付宝支付并且为二维码支付的,失效掉对应支付二维码 |
| | | List<PayInfo> filterPayInfo = payInfoMapper.listByPayTypeAndTime(); |
| | | Date now = new Date(); |
| | | List<Long> skuIds = seckillSkuMapper.listSkuIds(); |
| | | List<String> keys = new ArrayList<>(); |
| | | for (Long skuId : skuIds) { |
| | | keys.add(Constant.SECKILL_SKU_STOCKS_PREFIX + skuId); |
| | | } |
| | | // 还原库存 |
| | | seckillSkuMapper.returnStocks(now); |
| | | // 还原库存 |
| | | seckillMapper.returnStocks(now); |
| | | // 修改订单状态 |
| | | orderMapper.cancelSeckillOrderByTime(now); |
| | | // 将秒杀订单状态改为失效状态 |
| | | seckillOrderMapper.cancelUnpayOrder(); |
| | | // 删除库存的缓存 |
| | | RedisUtil.del(keys); |
| | | eventPublisher.publishEvent(new PayManagerEvent(filterPayInfo)); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void cancelUnpayOrderByOrderNumber(String orderNumber) { |
| | | SeckillOrder seckillOrder = seckillOrderMapper.selectOne(Wrappers.lambdaQuery(SeckillOrder.class) |
| | | .eq(SeckillOrder::getOrderNumber, orderNumber)); |
| | | if(Objects.isNull(seckillOrder)){ |
| | | return; |
| | | } |
| | | // 还原秒杀库存 |
| | | seckillSkuMapper.returnStocksByOrderNumber(orderNumber); |
| | | |
| | | // 还原秒杀库存 |
| | | seckillMapper.returnStocksByOrderNumber(orderNumber); |
| | | |
| | | seckillOrderMapper.cancelUnpayOrderByOrderNumber(orderNumber); |
| | | |
| | | // 清除库存的缓存 |
| | | RedisUtil.del(Constant.SECKILL_SKU_STOCKS_PREFIX + seckillOrder.getSeckillSkuId()); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.service.impl; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.lang.Snowflake; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.yami.shop.bean.app.vo.SeckillVO; |
| | | import com.yami.shop.bean.enums.EsOperationType; |
| | | import com.yami.shop.bean.enums.OfflineHandleEventStatus; |
| | | import com.yami.shop.bean.enums.OfflineHandleEventType; |
| | | import com.yami.shop.bean.enums.ProdType; |
| | | import com.yami.shop.bean.event.EsProductUpdateEvent; |
| | | import com.yami.shop.bean.event.RemoveDiscountProdByIdsEvent; |
| | | import com.yami.shop.bean.model.OfflineHandleEvent; |
| | | import com.yami.shop.bean.model.OrderItem; |
| | | import com.yami.shop.bean.model.Product; |
| | | import com.yami.shop.bean.param.OfflineHandleEventAuditParam; |
| | | import com.yami.shop.bean.param.ProductParam; |
| | | import com.yami.shop.common.constants.CacheNames; |
| | | import com.yami.shop.common.enums.StatusEnum; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.util.CacheManagerUtil; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.common.util.RedisUtil; |
| | | import com.yami.shop.seckill.common.constant.SeckillCacheNames; |
| | | import com.yami.shop.seckill.common.dao.SeckillMapper; |
| | | import com.yami.shop.seckill.common.dao.SeckillSkuMapper; |
| | | import com.yami.shop.seckill.common.dto.SeckillProductSimpleDto; |
| | | import com.yami.shop.seckill.common.enums.SeckillEnum; |
| | | import com.yami.shop.seckill.common.model.Seckill; |
| | | import com.yami.shop.seckill.common.model.SeckillOrder; |
| | | import com.yami.shop.seckill.common.model.SeckillSku; |
| | | import com.yami.shop.seckill.common.service.SeckillService; |
| | | import com.yami.shop.seckill.common.service.SeckillSkuService; |
| | | import com.yami.shop.seckill.common.dto.SeckillPageDto; |
| | | import com.yami.shop.service.OfflineHandleEventService; |
| | | import com.yami.shop.service.ProductService; |
| | | import lombok.AllArgsConstructor; |
| | | import org.redisson.api.RLock; |
| | | import org.redisson.api.RedissonClient; |
| | | import org.springframework.cache.annotation.CacheEvict; |
| | | import org.springframework.cache.annotation.Cacheable; |
| | | import org.springframework.cache.annotation.Caching; |
| | | import org.springframework.context.ApplicationContext; |
| | | import org.springframework.context.ApplicationEventPublisher; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Propagation; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.*; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | | * 秒杀信息 |
| | | * |
| | | * @author LGH |
| | | * @date 2019-08-28 09:36:59 |
| | | */ |
| | | @Service |
| | | @AllArgsConstructor |
| | | public class SeckillServiceImpl extends ServiceImpl<SeckillMapper, Seckill> implements SeckillService { |
| | | |
| | | private final RedissonClient redissonClient; |
| | | |
| | | private static final String REDISSON_LOCK_PREFIX = "redisson_lock:"; |
| | | |
| | | private final static String SECKILL_SKU_STOCKS_PREFIX = "SECKILL_SKU_STOCKS_"; |
| | | |
| | | private final Snowflake snowflake; |
| | | |
| | | private final SeckillMapper seckillMapper; |
| | | private final SeckillSkuMapper seckillSkuMapper; |
| | | |
| | | private final SeckillSkuService seckillSkuService; |
| | | |
| | | private final ProductService productService; |
| | | |
| | | private final OfflineHandleEventService offlineHandleEventService; |
| | | |
| | | private final ApplicationContext applicationContext; |
| | | |
| | | private final ApplicationEventPublisher eventPublisher; |
| | | private final CacheManagerUtil cacheManagerUtil; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void saveSeckill(Seckill seckill, List<SeckillSku> seckillSkus) { |
| | | |
| | | seckill.setStatus(1); |
| | | seckill.setIsDelete(0); |
| | | // 保存秒杀信息 |
| | | seckillMapper.insert(seckill); |
| | | |
| | | // 这里再查下秒杀商品对应的活动数量,如果大于1,就证明已经有一个跟该商品对应的活动了,本次操作不应该继续下去 |
| | | Integer seckillNum = seckillMapper.selectCount(new LambdaQueryWrapper<Seckill>() |
| | | .eq(Seckill::getProdId, seckill.getProdId()) |
| | | .eq(Seckill::getIsDelete, 0) |
| | | .ge(Seckill::getStatus, StatusEnum.ENABLE.value())); |
| | | if(seckillNum > 1) { |
| | | // 该商品已创建秒杀活动,请勿重复提交 |
| | | throw new YamiShopBindException("yami.product.has.created.seckill"); |
| | | } |
| | | |
| | | seckillSkus.forEach(seckillSku -> seckillSku.setSeckillId(seckill.getSeckillId())); |
| | | |
| | | // 保存秒杀sku信息 |
| | | seckillSkuService.saveBatch(seckillSkus); |
| | | |
| | | // 更新商品信息 |
| | | Product product = new Product(); |
| | | product.setActivityId(seckill.getSeckillId()); |
| | | product.setProdType(ProdType.PROD_TYPE_SECKILL.value()); |
| | | product.setProdId(seckill.getProdId()); |
| | | productService.updateById(product); |
| | | // 发送事件,清除掉如果是限时特惠中的可用商品 |
| | | applicationContext.publishEvent(new RemoveDiscountProdByIdsEvent(Collections.singletonList(seckill.getProdId()))); |
| | | } |
| | | |
| | | /** |
| | | * 这里的缓存时间参考RedisCacheConfig#getRedisCacheConfigurationMap |
| | | * @param seckillId |
| | | * @return |
| | | */ |
| | | @Override |
| | | @Cacheable(cacheNames = "SeckillById", key = "#seckillId") |
| | | public Seckill getSeckillById(Long seckillId) { |
| | | return seckillMapper.selectById(seckillId); |
| | | } |
| | | |
| | | @Override |
| | | @Cacheable(cacheNames = "SeckillByProdId", key = "#prodId") |
| | | public Seckill getSeckillByProdId(Long prodId) { |
| | | return seckillMapper.selectOne(new LambdaQueryWrapper<Seckill>() |
| | | .eq(Seckill::getProdId, prodId) |
| | | .eq(Seckill::getStatus, StatusEnum.ENABLE.value()) |
| | | ); |
| | | } |
| | | |
| | | @Override |
| | | @Caching(evict = { |
| | | @CacheEvict(cacheNames = "SeckillById", key = "#seckillId"), |
| | | @CacheEvict(cacheNames = "SeckillByProdId", key = "#prodId") |
| | | }) |
| | | public void removeSeckillCache(Long seckillId, Long prodId) { |
| | | } |
| | | |
| | | @Override |
| | | public void batchRemoveSeckillCache(List<Long> seckillIds, List<Long> prodIds) { |
| | | List<String> keys = new ArrayList<>(); |
| | | if (CollUtil.isNotEmpty(prodIds)) { |
| | | for (Long prodId : prodIds) { |
| | | keys.add("SeckillByProdId" + CacheNames.UNION + prodId); |
| | | } |
| | | } |
| | | if (CollUtil.isEmpty(seckillIds)) { |
| | | return; |
| | | } |
| | | for (Long seckillId : seckillIds) { |
| | | keys.add("SeckillById" + CacheNames.UNION + seckillId); |
| | | } |
| | | RedisUtil.del(keys); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void invalidById(Seckill seckill) { |
| | | |
| | | Product productParam = new Product(); |
| | | productParam.setProdId(seckill.getProdId()); |
| | | productParam.setActivityId(0L); |
| | | productParam.setProdType(ProdType.PROD_TYPE_NORMAL.value()); |
| | | productService.updateById(productParam); |
| | | |
| | | seckill.setStatus(0); |
| | | seckillMapper.updateById(seckill); |
| | | eventPublisher.publishEvent(new EsProductUpdateEvent(seckill.getProdId(), null, EsOperationType.UPDATE)); |
| | | } |
| | | |
| | | @Override |
| | | public IPage<SeckillProductSimpleDto> pageSeckillProd(PageParam<SeckillProductSimpleDto> page, Integer dbLang) { |
| | | return seckillMapper.pageSeckillProd(page,dbLang); |
| | | } |
| | | |
| | | @Override |
| | | public IPage<SeckillPageDto> getPlatformSeckillPage(PageParam<Seckill> page, Seckill seckill) { |
| | | return seckillMapper.getPlatformSeckillPage(page, seckill); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void offline(Seckill seckill, String offlineReason, Long sysUserId) { |
| | | |
| | | // 添加下线处理记录 |
| | | Date now = new Date(); |
| | | OfflineHandleEvent offlineHandleEvent = new OfflineHandleEvent(); |
| | | offlineHandleEvent.setHandleId(seckill.getSeckillId()); |
| | | offlineHandleEvent.setCreateTime(now); |
| | | offlineHandleEvent.setHandleType(OfflineHandleEventType.SECKILL.getValue()); |
| | | offlineHandleEvent.setHandlerId(sysUserId); |
| | | offlineHandleEvent.setShopId(seckill.getShopId()); |
| | | offlineHandleEvent.setOfflineReason(offlineReason); |
| | | offlineHandleEvent.setStatus(OfflineHandleEventStatus.OFFLINE_BY_PLATFORM.getValue()); |
| | | offlineHandleEvent.setUpdateTime(now); |
| | | offlineHandleEventService.save(offlineHandleEvent); |
| | | |
| | | // 更新活动状态为下线 |
| | | seckillMapper.updateStatus(seckill.getSeckillId(), SeckillEnum.OFFLINE.getValue()); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void auditSeckill(OfflineHandleEventAuditParam offlineHandleEventAuditParam, Long sysUserId) { |
| | | // 审核通过 |
| | | if (Objects.equals(offlineHandleEventAuditParam.getStatus(), OfflineHandleEventStatus.AGREE_BY_PLATFORM.getValue())) { |
| | | // 更新秒杀活动为正常状态 |
| | | seckillMapper.updateStatus(offlineHandleEventAuditParam.getHandleId(), SeckillEnum.NORMAL.getValue()); |
| | | } |
| | | // 审核不通过 |
| | | else if (Objects.equals(offlineHandleEventAuditParam.getStatus(), OfflineHandleEventStatus.DISAGREE_BY_PLATFORM.getValue())) { |
| | | seckillMapper.updateStatus(offlineHandleEventAuditParam.getHandleId(), SeckillEnum.OFFLINE.getValue()); |
| | | } |
| | | // 更新审核时间 |
| | | offlineHandleEventService.auditOfflineEvent(offlineHandleEventAuditParam, sysUserId); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void auditApply(Long eventId, Long seckillId, String reapplyReason) { |
| | | // 更新活动为待审核状态 |
| | | seckillMapper.updateStatus(seckillId, SeckillEnum.WAIT_AUDIT.getValue()); |
| | | |
| | | // 更新事件状态 |
| | | offlineHandleEventService.updateToApply(eventId, reapplyReason); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void changeProdTypeBySeckillIdList(List<Long> seckillIds) { |
| | | seckillMapper.changeProdTypeBySeckillIdList(seckillIds); |
| | | seckillMapper.changeSeckillStatusBySeckillIdList(seckillIds); |
| | | } |
| | | |
| | | @Override |
| | | public Seckill getSeckillByOrderNumber(String orderNumber) { |
| | | return seckillMapper.getSeckillByOrderNumber(orderNumber); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void addInventory(Long seckillId, Integer count) { |
| | | seckillMapper.addInventory(seckillId, count); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public List<Seckill> invalidByShopId(Long shopId) { |
| | | // 获取正在进行中的秒杀活动 |
| | | List<Seckill> seckills = seckillMapper.selectList(Wrappers.lambdaQuery(Seckill.class) |
| | | .select(Seckill::getSeckillId, Seckill::getProdId) |
| | | .eq(Seckill::getShopId, shopId) |
| | | .eq(Seckill::getIsDelete, 0) |
| | | .eq(Seckill::getStatus, SeckillEnum.NORMAL.getValue()) |
| | | ); |
| | | if (CollUtil.isEmpty(seckills)) { |
| | | return new ArrayList<>(); |
| | | } |
| | | List<Long> seckillIds = new ArrayList<>(); |
| | | List<Long> prodIds = new ArrayList<>(); |
| | | for (Seckill seckill : seckills) { |
| | | seckillIds.add(seckill.getSeckillId()); |
| | | prodIds.add(seckill.getProdId()); |
| | | } |
| | | // 将商品变回普通商品 |
| | | productService.update(Wrappers.lambdaUpdate(Product.class) |
| | | .set(Product::getActivityId, 0L) |
| | | .set(Product::getProdType, ProdType.PROD_TYPE_NORMAL.value()) |
| | | .in(Product::getProdId, prodIds) |
| | | ); |
| | | // 失效秒杀活动 |
| | | update(Wrappers.lambdaUpdate(Seckill.class) |
| | | .set(Seckill::getStatus, SeckillEnum.INVALID.getValue()) |
| | | .in(Seckill::getSeckillId, seckillIds) |
| | | ); |
| | | // 更新es中的商品数据 |
| | | eventPublisher.publishEvent(new EsProductUpdateEvent(null, prodIds, EsOperationType.UPDATE_BATCH)); |
| | | return seckills; |
| | | } |
| | | |
| | | @Override |
| | | public Boolean handlerSeckillOrderStock(OrderItem orderItem, SeckillOrder seckillOrder) { |
| | | // 这里一进来就减库存,但是为了防止少卖,120秒会自己更新库存~因为缓存只有60秒 |
| | | boolean removeStockCache = decrSeckillSkuStocks(seckillOrder.getSeckillSkuId(), seckillOrder.getSeckillId(), seckillOrder.getProdCount(),orderItem.getProdId()); |
| | | // 更新活动剩余库存,为false时是本商品已被秒杀完毕,下次记得早点来哟 |
| | | boolean removeStock = seckillMapper.updateStocksById(seckillOrder.getSeckillId(), orderItem.getProdCount()) >= 1; |
| | | // 更新秒杀sku库存,乐观锁 |
| | | boolean removeSkuStock = seckillSkuMapper.updateStocks(seckillOrder.getSeckillSkuId(), orderItem.getProdCount()) >= 1; |
| | | return removeStockCache && removeStock && removeSkuStock; |
| | | } |
| | | |
| | | @Override |
| | | @Cacheable(cacheNames = "SeckillGetByProdId", key = "#prodId", sync = true) |
| | | public Seckill getByProdId(Long prodId) { |
| | | return seckillMapper.selectOne(new LambdaQueryWrapper<Seckill>().eq(Seckill::getProdId, prodId).eq(Seckill::getStatus, SeckillEnum.NORMAL.getValue())); |
| | | } |
| | | |
| | | @Transactional(propagation = Propagation.SUPPORTS) |
| | | @Override |
| | | public IPage<Product> pageSeckillNormalProd(PageParam<Product> page, ProductParam product) { |
| | | return seckillMapper.pageSeckillNormalProd(page, product); |
| | | } |
| | | |
| | | @Override |
| | | public IPage<SeckillPageDto> pageSeckill(PageParam<Seckill> page, SeckillVO seckillVO) { |
| | | return seckillMapper.pageSeckill(page, seckillVO); |
| | | } |
| | | |
| | | private boolean decrSeckillSkuStocks(Long seckillSkuId, Long seckillId, Integer prodCount, Long prodId) { |
| | | String key = SECKILL_SKU_STOCKS_PREFIX + seckillSkuId; |
| | | long var = 10L; |
| | | long var2 = 10L; |
| | | Long cacheStocks = RedisUtil.getLongValue(key); |
| | | |
| | | if (cacheStocks != null && cacheStocks <= 0) { |
| | | return false; |
| | | } |
| | | |
| | | // 如果没有库存就缓存一个库存 |
| | | if (cacheStocks == null || RedisUtil.getExpire(key) < 1) { |
| | | |
| | | // 加锁,防止缓存击穿 |
| | | RLock rLock = redissonClient.getLock(REDISSON_LOCK_PREFIX + ":getSeckillSkuStocks"); |
| | | try { |
| | | if (rLock.tryLock(var,var2, TimeUnit.SECONDS)){ |
| | | // 再获取一遍缓存 |
| | | cacheStocks = RedisUtil.getLongValue(key); |
| | | if (cacheStocks == null) { |
| | | // cacheNames = "SeckillByProdId" |
| | | cacheManagerUtil.evictCache(SeckillCacheNames.SECKILL_BY_PROD_ID, String.valueOf(prodId)); |
| | | seckillSkuService.removeSeckillCacheSkuById(seckillSkuId,seckillId); |
| | | Integer seckillStocks = seckillSkuService.getSeckillSkuById(seckillSkuId).getSeckillStocks(); |
| | | if (seckillStocks > 0) { |
| | | RedisUtil.setLongValue(key, Long.valueOf(seckillStocks),-1); |
| | | } else { |
| | | RedisUtil.setLongValue(key, 0L, 30); |
| | | } |
| | | cacheStocks = Long.valueOf(seckillStocks); |
| | | } |
| | | } else { |
| | | // 网络异常 |
| | | return false; |
| | | } |
| | | } catch (InterruptedException e) { |
| | | log.error("InterruptedException:", e); |
| | | } finally { |
| | | try { |
| | | if (rLock.isLocked()) { |
| | | rLock.unlock(); |
| | | } |
| | | }catch (Exception e){ |
| | | log.error("Exception:", e); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (cacheStocks == null || cacheStocks < prodCount || RedisUtil.decr(key, prodCount) < 0) { |
| | | RedisUtil.expire(key,30); |
| | | // 本轮商品已被秒杀完毕,还有用户未支付,还有机会哟 |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.common.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.yami.shop.common.util.CacheManagerUtil; |
| | | import com.yami.shop.seckill.common.dao.SeckillSkuMapper; |
| | | import com.yami.shop.seckill.common.model.SeckillSku; |
| | | import com.yami.shop.seckill.common.service.SeckillSkuService; |
| | | import lombok.AllArgsConstructor; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.springframework.cache.annotation.CacheEvict; |
| | | import org.springframework.cache.annotation.Cacheable; |
| | | import org.springframework.cache.annotation.Caching; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 秒杀活动sku |
| | | * |
| | | * @author LGH |
| | | * @date 2019-08-28 09:36:59 |
| | | */ |
| | | @Service |
| | | @AllArgsConstructor |
| | | public class SeckillSkuServiceImpl extends ServiceImpl<SeckillSkuMapper, SeckillSku> implements SeckillSkuService { |
| | | |
| | | private final SeckillSkuMapper seckillSkuMapper; |
| | | |
| | | private final CacheManagerUtil cacheManagerUtil; |
| | | |
| | | @Override |
| | | @Cacheable(cacheNames = "SeckillSkuBySeckillId", key = "#seckillId") |
| | | public List<SeckillSku> listSeckillSkuBySeckillId(Long seckillId) { |
| | | return seckillSkuMapper.selectList(new LambdaQueryWrapper<SeckillSku>().eq(SeckillSku::getSeckillId,seckillId)); |
| | | } |
| | | |
| | | @Override |
| | | @CacheEvict(cacheNames = "SeckillSkuBySeckillId", key = "#seckillId") |
| | | public void removeSeckillSkuCacheBySeckillId(Long seckillId) { |
| | | List<SeckillSku> seckillSkus = listSeckillSkuBySeckillId(seckillId); |
| | | //清除缓存 |
| | | if (CollectionUtils.isNotEmpty(seckillSkus)) { |
| | | for (SeckillSku seckillSku : seckillSkus) { |
| | | // 不能采用this清除缓存,因为这样没有aop |
| | | cacheManagerUtil.evictCache("SeckillSkuById", String.valueOf(seckillSku.getSeckillSkuId())); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Cacheable(cacheNames = "SeckillSkuById", key = "#seckillSkuId") |
| | | public SeckillSku getSeckillSkuById(Long seckillSkuId) { |
| | | return seckillSkuMapper.selectById(seckillSkuId); |
| | | } |
| | | |
| | | @Override |
| | | @Caching(evict = { |
| | | @CacheEvict(cacheNames = "SeckillSkuById", key = "#seckillSkuId"), |
| | | @CacheEvict(cacheNames = "SeckillSkuBySeckillId", key = "#seckillId"), |
| | | @CacheEvict(cacheNames = "SeckillById", key = "#seckillId") |
| | | }) |
| | | public void removeSeckillCacheSkuById(Long seckillSkuId,Long seckillId) { |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public SeckillSku getSeckillSkuBySkuIdAndOrderNumber(Long skuId, String orderNumber) { |
| | | return seckillSkuMapper.getSeckillSkuBySkuIdAndOrderNumber(skuId, orderNumber); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void addInventory(Long seckillSkuId, Integer count) { |
| | | seckillSkuMapper.addInventory(seckillSkuId, count); |
| | | } |
| | | } |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | |
| | | <mapper namespace="com.yami.shop.seckill.common.dao.SeckillMapper"> |
| | | |
| | | <resultMap id="seckillMap" type="com.yami.shop.seckill.common.model.Seckill"> |
| | | <id column="seckill_id" property="seckillId"/> |
| | | <result column="seckill_name" property="seckillName"/> |
| | | <result column="start_time" property="startTime"/> |
| | | <result column="end_time" property="endTime"/> |
| | | <result column="seckill_tag" property="seckillTag"/> |
| | | <result column="max_num" property="maxNum"/> |
| | | <result column="max_cancel_time" property="maxCancelTime"/> |
| | | <result column="shop_id" property="shopId"/> |
| | | <result column="is_delete" property="isDelete"/> |
| | | <result column="status" property="status"/> |
| | | <result column="seckill_total_stocks" property="seckillTotalStocks"/> |
| | | <result column="seckill_origin_stocks" property="seckillOriginStocks"/> |
| | | <result column="seckill_price" property="seckillPrice"/> |
| | | </resultMap> |
| | | <select id="pageSeckillProd" resultType="com.yami.shop.seckill.common.dto.SeckillProductSimpleDto"> |
| | | select s.seckill_id,s.seckill_name,s.start_time,s.end_time,s.seckill_total_stocks, |
| | | s.seckill_origin_stocks,s.seckill_price,p.prod_id,ifnull(pl.prod_name,p.prod_name) as prod_name,p.pic,p.price |
| | | from tz_seckill s |
| | | join tz_prod p on s.seckill_id = p.activity_id and p.status = 1 AND p.prod_type = 2 |
| | | join tz_shop_detail sd on s.shop_id = sd.shop_id and sd.shop_status = 1 |
| | | LEFT JOIN tz_prod_lang pl on pl.prod_id = p.prod_id and pl.lang =#{dbLang} |
| | | where s.status = 1 and s.is_delete = 0 AND s.`end_time` >= NOW() |
| | | order by s.start_time desc |
| | | </select> |
| | | <select id="getPlatformSeckillPage" resultType="com.yami.shop.seckill.common.dto.SeckillPageDto"> |
| | | SELECT s.*,sd.`shop_name`, tp.prod_name,tp.pic FROM tz_seckill s |
| | | LEFT JOIN tz_shop_detail sd ON s.`shop_id` = sd.`shop_id` |
| | | LEFT JOIN tz_prod tp on tp.prod_id = s.prod_id |
| | | WHERE s.is_delete = 0 |
| | | <if test="seckill.shopName != null"> |
| | | and trim(replace(sd.shop_name,' ','')) like trim(replace(concat('%',#{seckill.shopName},'%'),' ','')) |
| | | </if> |
| | | <if test="seckill.seckillName != null"> |
| | | and trim(replace(s.seckill_name,' ','')) like trim(replace(concat('%',#{seckill.seckillName},'%'),' ','')) |
| | | </if> |
| | | <if test="seckill.status != null"> |
| | | AND s.status = #{seckill.status} |
| | | </if> |
| | | ORDER BY s.`seckill_id` DESC |
| | | </select> |
| | | <update id="updateStatus"> |
| | | UPDATE tz_seckill s SET s.`status` =#{status} WHERE s.`seckill_id` = #{seckillId} |
| | | </update> |
| | | <update id="returnStocksByOrderNumber"> |
| | | UPDATE tz_seckill s JOIN tz_seckill_order so ON s.seckill_id = so.seckill_id AND so.order_number = #{orderNumber} |
| | | SET s.seckill_total_stocks = s.seckill_total_stocks + so.prod_count |
| | | </update> |
| | | <update id="returnStocks"> |
| | | UPDATE tz_seckill s |
| | | JOIN |
| | | ( |
| | | SELECT so.seckill_id,so.seckill_sku_id,SUM(so.prod_count) AS prod_count |
| | | FROM tz_seckill_order so |
| | | JOIN tz_seckill s ON s.seckill_id = so.seckill_id AND so.state = 0 |
| | | AND (UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(so.`create_time`))/60 > s.`max_cancel_time` |
| | | GROUP BY so.seckill_sku_id |
| | | ) t |
| | | ON s.seckill_id = t.seckill_id |
| | | SET s.seckill_total_stocks = s.seckill_total_stocks + t.prod_count |
| | | </update> |
| | | <update id="updateStocksById"> |
| | | UPDATE tz_seckill set seckill_total_stocks = seckill_total_stocks - #{prodCount} where seckill_id = #{seckillId} and seckill_total_stocks >= #{prodCount} |
| | | </update> |
| | | <update id="changeProdTypeBySeckillIdList"> |
| | | UPDATE tz_prod SET prod_type = 0 WHERE prod_id IN |
| | | (SELECT prod_id FROM tz_seckill WHERE seckill_id IN |
| | | <foreach collection="seckillIds" item="seckillId" separator="," open="(" close=")"> |
| | | #{seckillId} |
| | | </foreach> |
| | | GROUP BY prod_id |
| | | ) |
| | | </update> |
| | | <update id="changeSeckillStatusBySeckillIdList"> |
| | | UPDATE tz_seckill SET `status` = 0 WHERE seckill_id IN |
| | | <foreach collection="seckillIds" item="seckillId" separator="," open="(" close=")"> |
| | | #{seckillId} |
| | | </foreach> |
| | | </update> |
| | | |
| | | <select id="getSeckillByOrderNumber" resultType="com.yami.shop.seckill.common.model.Seckill"> |
| | | SELECT |
| | | s.* |
| | | FROM |
| | | tz_seckill s |
| | | LEFT JOIN tz_seckill_order so ON s.seckill_id = so.seckill_id |
| | | WHERE |
| | | so.order_number = #{orderNumber} |
| | | </select> |
| | | |
| | | <select id="pageSeckillNormalProd" resultType= "com.yami.shop.bean.model.Product"> |
| | | SELECT IFNULL(l.prod_name,p.prod_name) AS prod_name,ts.seckill_price AS activity_price, |
| | | ts.seckill_total_stocks as activity_total_stocks, p.*,s.shop_name FROM tz_prod p |
| | | LEFT JOIN tz_prod_lang l ON l.`prod_id` = p.`prod_id` AND l.lang = 0 |
| | | LEFT JOIN tz_shop_detail s ON p.shop_id = s.shop_id |
| | | JOIN `tz_seckill` ts on ts.prod_id = p.prod_id and ts.status = 1 |
| | | <where> |
| | | <if test="product.shopId != null"> |
| | | and p.`shop_id` =#{product.shopId} |
| | | </if> |
| | | <if test="product.shopCategoryId != null"> |
| | | and p.shop_category_id = #{product.shopCategoryId} |
| | | </if> |
| | | <if test="product.categoryId != null"> |
| | | and p.category_id = #{product.categoryId} |
| | | </if> |
| | | <if test="product.prodName != null and product.prodName != ''"> |
| | | and trim(replace(l.prod_name,' ','')) like trim(replace(concat('%',#{product.prodName},'%'),' ','')) |
| | | </if> |
| | | <if test="product.status != null"> |
| | | and p.status = #{product.status} |
| | | </if> |
| | | </where> |
| | | order by |
| | | <choose> |
| | | <when test="product.sortParam == 1 and product.sortType == 1"> |
| | | seq ASC, |
| | | </when> |
| | | <when test="product.sortParam == 1 and product.sortType == 2"> |
| | | seq DESC, |
| | | </when> |
| | | </choose> |
| | | p.putaway_time desc |
| | | </select> |
| | | <select id="pageSeckill" resultType="com.yami.shop.seckill.common.dto.SeckillPageDto"> |
| | | SELECT ts.*,tp.prod_name,tp.pic |
| | | FROM tz_seckill ts |
| | | JOIN tz_prod tp ON tp.`prod_id` = ts.`prod_id` |
| | | LEFT JOIN tz_prod_lang tpl ON tpl.prod_id = tp.prod_id AND tpl.lang = #{seckill.lang} |
| | | WHERE ts.`is_delete` = 0 AND ts.`shop_id` = #{seckill.shopId} |
| | | <if test="seckill.status != null"> |
| | | AND ts.`status` = #{seckill.status} |
| | | </if> |
| | | <if test="seckill.seckillName != null and seckill.seckillName != ''"> |
| | | AND ts.seckill_name LIKE CONCAT('%', #{seckill.seckillName} ,'%') |
| | | </if> |
| | | <if test="seckill.prodName != null and seckill.prodName != ''"> |
| | | and ifnull(tpl.prod_name,tp.prod_name) like concat('%',#{seckill.prodName},'%') |
| | | </if> |
| | | ORDER BY seckill_id DESC |
| | | </select> |
| | | |
| | | <update id="addInventory"> |
| | | UPDATE tz_seckill SET seckill_total_stocks = seckill_total_stocks + #{countNum} WHERE `seckill_id` = #{seckillId} |
| | | </update> |
| | | </mapper> |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | |
| | | <mapper namespace="com.yami.shop.seckill.common.dao.SeckillOrderMapper"> |
| | | |
| | | <resultMap id="seckillOrderMap" type="com.yami.shop.seckill.common.model.SeckillOrder"> |
| | | <id column="seckill_order_id" property="seckillOrderId" /> |
| | | <result column="seckill_id" property="seckillId"/> |
| | | <result column="user_id" property="userId"/> |
| | | <result column="order_number" property="orderNumber"/> |
| | | <result column="prod_count" property="prodCount"/> |
| | | <result column="create_time" property="createTime"/> |
| | | <result column="prod_id" property="prodId" /> |
| | | <result column="state" property="state" /> |
| | | </resultMap> |
| | | <update id="updateStateByOrderNumber"> |
| | | update tz_seckill_order set state =#{state} where order_number = #{orderNumber} |
| | | |
| | | </update> |
| | | <update id="cancelUnpayOrderByOrderNumber"> |
| | | UPDATE tz_seckill_order so |
| | | set so.state = -1 |
| | | where order_number = #{orderNumber} |
| | | </update> |
| | | <update id="cancelUnpayOrder"> |
| | | UPDATE tz_seckill_order so JOIN tz_seckill s ON s.seckill_id = so.seckill_id AND (UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(so.`create_time`))/60 > s.`max_cancel_time` and so.`state` = 0 |
| | | SET so.`state` = -1 |
| | | </update> |
| | | |
| | | <select id="selectNumByUser" resultType="int"> |
| | | SELECT ifnull(SUM(so.prod_count),0) FROM tz_seckill_order so |
| | | JOIN tz_order o ON so.`order_number` = o.`order_number` AND o.`status` <![CDATA[ <> ]]> 6 |
| | | WHERE so.seckill_id = #{seckillId} AND so.prod_id = #{prodId} |
| | | AND so.user_id = #{userId} AND so.state <![CDATA[ <> ]]> -1 |
| | | </select> |
| | | |
| | | </mapper> |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | |
| | | <mapper namespace="com.yami.shop.seckill.common.dao.SeckillSkuMapper"> |
| | | |
| | | <resultMap id="seckillSkuMap" type="com.yami.shop.seckill.common.model.SeckillSku"> |
| | | <id column="seckill_sku_id" property="seckillSkuId" /> |
| | | <result column="sku_id" property="skuId"/> |
| | | <result column="seckill_id" property="seckillId"/> |
| | | <result column="seckill_stocks" property="seckillStocks"/> |
| | | <result column="seckill_price" property="seckillPrice"/> |
| | | </resultMap> |
| | | <update id="updateStocks"> |
| | | update tz_seckill_sku set seckill_stocks = seckill_stocks - #{prodCount} where seckill_sku_id = #{seckillSkuId} and seckill_stocks >= #{prodCount} |
| | | |
| | | </update> |
| | | <update id="returnStocks"> |
| | | UPDATE tz_seckill_sku ss JOIN ( |
| | | SELECT so.seckill_sku_id,SUM(so.prod_count) AS prod_count |
| | | FROM tz_seckill_order so |
| | | JOIN tz_seckill s ON s.seckill_id = so.seckill_id AND so.state = 0 |
| | | AND (UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(so.`create_time`))/60 > s.`max_cancel_time` |
| | | GROUP BY so.seckill_sku_id |
| | | ) t |
| | | ON ss.seckill_sku_id = t.seckill_sku_id |
| | | set ss.seckill_stocks = ss.seckill_stocks + t.prod_count |
| | | |
| | | </update> |
| | | <update id="returnStocksByOrderNumber"> |
| | | UPDATE tz_seckill_sku ss JOIN ( |
| | | SELECT so.seckill_sku_id,so.prod_count FROM tz_seckill_order so JOIN |
| | | tz_seckill s ON s.seckill_id = so.seckill_id and so.state = 0 |
| | | AND so.order_number = #{orderNumber} ) t |
| | | ON ss.seckill_sku_id = t.seckill_sku_id |
| | | |
| | | set ss.seckill_stocks = ss.seckill_stocks + t.prod_count |
| | | </update> |
| | | <select id="getSeckillSkuBySkuIdAndOrderNumber" resultType="com.yami.shop.seckill.common.model.SeckillSku"> |
| | | SELECT |
| | | ss.* |
| | | FROM |
| | | tz_seckill s |
| | | LEFT JOIN tz_seckill_sku ss ON s.seckill_id = ss.seckill_id |
| | | LEFT JOIN tz_seckill_order so ON s.seckill_id = so.seckill_id |
| | | WHERE so.order_number = #{orderNumber} AND ss.sku_id = #{skuId} |
| | | </select> |
| | | <update id="addInventory"> |
| | | UPDATE tz_seckill_sku set seckill_stocks = seckill_stocks + #{countNum} where seckill_sku_id = #{seckillSkuId} |
| | | </update> |
| | | <select id="listSkuIds" resultType="java.lang.Long"> |
| | | SELECT so.seckill_sku_id |
| | | FROM tz_seckill_order so |
| | | JOIN tz_seckill s ON s.seckill_id = so.seckill_id AND so.state = 0 |
| | | AND (UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(so.`create_time`))/60 > s.`max_cancel_time` |
| | | GROUP BY so.seckill_sku_id |
| | | </select> |
| | | |
| | | <select id="listSeckillMinOriginalPrice" resultType="com.yami.shop.seckill.common.model.SeckillSku"> |
| | | SELECT ss.seckill_id,MIN(s.price) seckill_price FROM tz_seckill_sku ss |
| | | JOIN tz_sku s ON ss.sku_id = s.sku_id |
| | | JOIN tz_seckill seckill ON seckill.seckill_id = ss.seckill_id AND seckill.seckill_price = ss.seckill_price |
| | | WHERE ss.seckill_id IN |
| | | <foreach collection="seckillIds" item="seckillId" open="(" close=")" separator=","> |
| | | #{seckillId} |
| | | </foreach> |
| | | GROUP BY seckill_id |
| | | </select> |
| | | </mapper> |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <groupId>com.yami.shop</groupId> |
| | | <artifactId>yami-shop-seckill</artifactId> |
| | | <version>0.0.1-SNAPSHOT</version> |
| | | </parent> |
| | | |
| | | <artifactId>yami-shop-seckill-multishop</artifactId> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <description>商城满减模块后台管理部分</description> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.yami.shop</groupId> |
| | | <artifactId>yami-shop-seckill-common</artifactId> |
| | | <version>${yami.shop.version}</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.yami.shop</groupId> |
| | | <artifactId>yami-shop-security-multishop</artifactId> |
| | | <version>${yami.shop.version}</version> |
| | | </dependency> |
| | | </dependencies> |
| | | </project> |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.multishop.config; |
| | | |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import org.springdoc.core.GroupedOpenApi; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | /** |
| | | * 秒杀的swagger文档 |
| | | * @author LGH |
| | | */ |
| | | @Configuration("seckillSwaggerConfiguration") |
| | | @AllArgsConstructor |
| | | public class SwaggerConfiguration { |
| | | |
| | | |
| | | @Bean |
| | | public GroupedOpenApi seckillRestApi() { |
| | | return GroupedOpenApi.builder() |
| | | .group("秒杀接口") |
| | | .packagesToScan("com.yami.shop.seckill.multishop.controller") |
| | | .pathsToMatch("/**") |
| | | .build(); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.seckill.multishop.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.app.vo.SeckillVO; |
| | | import com.yami.shop.bean.enums.EsOperationType; |
| | | import com.yami.shop.bean.enums.OfflineHandleEventType; |
| | | import com.yami.shop.bean.enums.ProdType; |
| | | import com.yami.shop.bean.enums.StationEnum; |
| | | import com.yami.shop.bean.event.EsProductUpdateEvent; |
| | | import com.yami.shop.bean.model.OfflineHandleEvent; |
| | | import com.yami.shop.bean.model.Product; |
| | | import com.yami.shop.bean.model.Sku; |
| | | import com.yami.shop.bean.param.OfflineHandleEventAuditParam; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.i18n.I18nMessage; |
| | | import com.yami.shop.common.response.ResponseEnum; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.dao.SkuMapper; |
| | | import com.yami.shop.seckill.common.dto.SeckillPageDto; |
| | | import com.yami.shop.seckill.common.enums.SeckillEnum; |
| | | import com.yami.shop.seckill.common.model.Seckill; |
| | | import com.yami.shop.seckill.common.model.SeckillSku; |
| | | import com.yami.shop.seckill.common.service.SeckillService; |
| | | import com.yami.shop.seckill.common.service.SeckillSkuService; |
| | | import com.yami.shop.seckill.multishop.dto.SeckillProdDto; |
| | | import com.yami.shop.seckill.multishop.param.SeckillParam; |
| | | import com.yami.shop.security.multishop.util.SecurityUtils; |
| | | import com.yami.shop.service.OfflineHandleEventService; |
| | | import com.yami.shop.service.ProductService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.AllArgsConstructor; |
| | | import ma.glasnost.orika.MapperFacade; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springframework.context.ApplicationEventPublisher; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | import java.util.stream.Collectors; |
| | | |
| | | |
| | | /** |
| | | * 秒杀信息 |
| | | * |
| | | * @author LGH |
| | | * @date 2019-08-28 09:36:59 |
| | | */ |
| | | @RestController |
| | | @AllArgsConstructor |
| | | @RequestMapping("/seckill/seckill") |
| | | @Tag(name = "商家端秒杀信息接口") |
| | | public class SeckillController { |
| | | |
| | | private final SeckillService seckillService; |
| | | |
| | | private final MapperFacade mapperFacade; |
| | | |
| | | private final ProductService productService; |
| | | |
| | | private final ApplicationEventPublisher eventPublisher; |
| | | |
| | | private final SeckillSkuService seckillSkuService; |
| | | |
| | | private final OfflineHandleEventService offlineHandleEventService; |
| | | |
| | | private final SkuMapper skuMapper; |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "分页查找秒杀信息") |
| | | public ServerResponseEntity<IPage<SeckillPageDto>> getSeckillPage(PageParam<Seckill> page, @ParameterObject SeckillVO seckill) { |
| | | seckill.setShopId(SecurityUtils.getShopUser().getShopId()); |
| | | seckill.setLang(I18nMessage.getDbLang()); |
| | | IPage<SeckillPageDto> pageSeckill = seckillService.pageSeckill(page, seckill); |
| | | return ServerResponseEntity.success(pageSeckill); |
| | | } |
| | | |
| | | @GetMapping("/info/{seckillId}") |
| | | @Operation(summary = "通过id查询秒杀信息") |
| | | @Parameter(name = "seckillId", description = "秒杀id" , required = true) |
| | | public ServerResponseEntity<SeckillProdDto> getById(@PathVariable("seckillId") Long seckillId) { |
| | | Seckill seckill = seckillService.getById(seckillId); |
| | | if (!Objects.equals(SecurityUtils.getShopUser().getShopId(), seckill.getShopId())) { |
| | | throw new YamiShopBindException("yami.no.auth"); |
| | | } |
| | | SeckillProdDto dto = new SeckillProdDto(); |
| | | dto.setSeckill(seckill); |
| | | Product product = productService.getProductByProdId(seckill.getProdId(), I18nMessage.getDbLang()); |
| | | dto.setProd(product); |
| | | dto.setSeckillSkus(seckillSkuService.listSeckillSkuBySeckillId(seckillId)); |
| | | return ServerResponseEntity.success(dto); |
| | | } |
| | | |
| | | @PostMapping |
| | | @PreAuthorize("@pms.hasPermission('seckill:seckill:save')") |
| | | @Operation(summary = "新增秒杀信息") |
| | | public ServerResponseEntity<Void> save(@RequestBody @Valid SeckillParam seckillParam) { |
| | | Seckill seckill = mapperFacade.map(seckillParam, Seckill.class); |
| | | if(Objects.isNull(seckill.getMaxNum())||Objects.equals(seckill.getMaxNum(),0)){ |
| | | //请输入限购数量 |
| | | throw new YamiShopBindException("yami.seckill.input.maxNum"); |
| | | } |
| | | Integer prodCount = productService.count(new LambdaQueryWrapper<Product>() |
| | | .eq(Product::getShopId, SecurityUtils.getShopUser().getShopId()) |
| | | // .and(wrapper -> wrapper.isNull(Product::getGroupActivityId).or().eq(Product::getGroupActivityId, 0)) |
| | | // .and(wrapper -> wrapper.isNull(Product::getSeckillActivityId).or().eq(Product::getSeckillActivityId, 0)) |
| | | .and(wrapper -> wrapper.isNull(Product::getProdType).or().eq(Product::getProdType, ProdType.PROD_TYPE_NORMAL)) |
| | | .eq(Product::getProdId, seckillParam.getProdId())); |
| | | if (prodCount == 0) { |
| | | // 商品无法参与秒杀活动 |
| | | throw new YamiShopBindException("yami.seckill.prod"); |
| | | } |
| | | List<SeckillSku> seckillSkus = seckillParam.getSeckillSkus(); |
| | | List<Long> skuIds = seckillSkus.stream().map(SeckillSku::getSkuId).collect(Collectors.toList()); |
| | | List<Sku> skuList = skuMapper.getSkuBySkuIds(skuIds); |
| | | Map<Long, Integer> skuStatusMap = skuList.stream().collect(Collectors.toMap(Sku::getSkuId, Sku::getStatus)); |
| | | Integer seckillTotalStocks = 0; |
| | | double seckillPrice = Double.MAX_VALUE; |
| | | for (SeckillSku seckillSku : seckillSkus) { |
| | | //禁用状态的sku不能参与秒杀活动 |
| | | if(skuStatusMap.get(seckillSku.getSkuId()) == 0){ |
| | | continue; |
| | | } |
| | | seckillTotalStocks += seckillSku.getSeckillStocks(); |
| | | seckillPrice = Math.min(seckillPrice, seckillSku.getSeckillPrice()); |
| | | //修改sku状态 |
| | | Sku sku = new Sku(); |
| | | sku.setSkuId(seckillSku.getSkuId()); |
| | | sku.setStatus(seckillSku.getStatus()); |
| | | sku.setPic(seckillSku.getPic()); |
| | | skuMapper.updateSkuById(sku); |
| | | } |
| | | if(seckillTotalStocks == 0){ |
| | | // 商品无法参与秒杀活动 |
| | | throw new YamiShopBindException("yami.seckill.prod"); |
| | | } |
| | | // 库存 |
| | | seckill.setSeckillOriginStocks(seckillTotalStocks); |
| | | seckill.setSeckillTotalStocks(seckillTotalStocks); |
| | | // 配置店铺id |
| | | seckill.setShopId(SecurityUtils.getShopUser().getShopId()); |
| | | seckill.setProdId(seckillParam.getProdId()); |
| | | seckill.setSeckillPrice(seckillPrice); |
| | | seckillService.saveSeckill(seckill, seckillSkus); |
| | | // 清除缓存 |
| | | productService.removeProdCacheByProdId(seckillParam.getProdId()); |
| | | seckillSkuService.removeSeckillSkuCacheBySeckillId(seckill.getSeckillId()); |
| | | seckillService.removeSeckillCache(seckill.getSeckillId(), seckill.getProdId()); |
| | | eventPublisher.publishEvent(new EsProductUpdateEvent(seckill.getProdId(), null, EsOperationType.UPDATE)); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping("/invalid/{seckillId}") |
| | | @PreAuthorize("@pms.hasPermission('seckill:seckill:invalid')") |
| | | @Operation(summary = "通过id使秒杀商品失效") |
| | | @Parameter(name = "seckillId", description = "秒杀id" , required = true) |
| | | public ServerResponseEntity<Void> invalidById(@PathVariable Long seckillId) { |
| | | Seckill seckill = seckillService.getById(seckillId); |
| | | if (!SecurityUtils.getShopUser().getShopId().equals(seckill.getShopId())) { |
| | | throw new YamiShopBindException(ResponseEnum.UNAUTHORIZED); |
| | | } |
| | | if (Objects.equals(seckill.getStatus(), SeckillEnum.OFFLINE.getValue())) { |
| | | throw new YamiShopBindException("yami.seckill.cannot.invalid"); |
| | | } |
| | | seckillService.invalidById(seckill); |
| | | productService.removeProdCacheByProdId(seckill.getProdId()); |
| | | seckillSkuService.removeSeckillSkuCacheBySeckillId(seckill.getSeckillId()); |
| | | seckillService.removeSeckillCache(seckill.getSeckillId(), seckill.getProdId()); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @DeleteMapping("/{seckillId}") |
| | | @PreAuthorize("@pms.hasPermission('seckill:seckill:delete')") |
| | | @Operation(summary = "通过id删除秒杀信息") |
| | | @Parameter(name = "seckillId", description = "秒杀id" , required = true) |
| | | public ServerResponseEntity<Void> removeById(@PathVariable Long seckillId) { |
| | | Seckill seckill = seckillService.getById(seckillId); |
| | | Integer oldStatus = seckill.getStatus(); |
| | | if (Objects.equals(StationEnum.NORMAL.getValue(), seckill.getStatus())) { |
| | | // 秒杀活动未关闭,无法删除 |
| | | throw new YamiShopBindException("yami.seckill.cannot.delete"); |
| | | } |
| | | seckillService.invalidById(seckill); |
| | | seckill.setIsDelete(1); |
| | | seckill.setStatus(oldStatus); |
| | | seckillService.updateById(seckill); |
| | | productService.removeProdCacheByProdId(seckill.getProdId()); |
| | | seckillSkuService.removeSeckillSkuCacheBySeckillId(seckill.getSeckillId()); |
| | | seckillService.removeSeckillCache(seckill.getSeckillId(), seckill.getProdId()); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @GetMapping("/getOfflineHandleEventBySeckillId/{seckillId}") |
| | | @Operation(summary = "通过活动id获取下线信息") |
| | | @Parameter(name = "seckillId", description = "秒杀id" , required = true) |
| | | public ServerResponseEntity<OfflineHandleEvent> getOfflineHandleEventBySeckillId(@PathVariable("seckillId") Long seckillId) { |
| | | OfflineHandleEvent offlineHandleEvent = offlineHandleEventService.getProcessingEventByHandleTypeAndHandleId(OfflineHandleEventType.SECKILL.getValue(), seckillId); |
| | | return ServerResponseEntity.success(offlineHandleEvent); |
| | | } |
| | | |
| | | @PostMapping("/auditApply") |
| | | @PreAuthorize("@pms.hasPermission('seckill:seckill:auditApply')") |
| | | @Operation(summary = "秒杀活动提交审核") |
| | | public ServerResponseEntity<Void> auditApply(@RequestBody OfflineHandleEventAuditParam offlineHandleEventAuditParam) { |
| | | Seckill seckill = seckillService.getById(offlineHandleEventAuditParam.getHandleId()); |
| | | if (seckill == null) { |
| | | // 未找到此活动,请稍后重试 |
| | | throw new YamiShopBindException("yami.activity.cannot.find"); |
| | | } |
| | | seckillService.auditApply(offlineHandleEventAuditParam.getEventId(), offlineHandleEventAuditParam.getHandleId(), offlineHandleEventAuditParam.getReapplyReason()); |
| | | // 移除缓存 |
| | | seckillService.removeSeckillCache(seckill.getSeckillId(), seckill.getProdId()); |
| | | eventPublisher.publishEvent(new EsProductUpdateEvent(seckill.getProdId(), null, EsOperationType.UPDATE)); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | } |
yami-shop-seckill/yami-shop-seckill-multishop/src/main/java/com/yami/shop/seckill/multishop/controller/SeckillOrderController.java
yami-shop-seckill/yami-shop-seckill-multishop/src/main/java/com/yami/shop/seckill/multishop/dto/SeckillProdDto.java
yami-shop-seckill/yami-shop-seckill-multishop/src/main/java/com/yami/shop/seckill/multishop/listener/OrderRefundListener.java
yami-shop-seckill/yami-shop-seckill-multishop/src/main/java/com/yami/shop/seckill/multishop/listener/UpdateSeckillOrderSkuInfoListener.java
yami-shop-seckill/yami-shop-seckill-multishop/src/main/java/com/yami/shop/seckill/multishop/param/SeckillParam.java
yami-shop-seckill/yami-shop-seckill-platform/pom.xml
yami-shop-seckill/yami-shop-seckill-platform/src/main/java/com/yami/shop/seckill/platform/config/SwaggerConfiguration.java
yami-shop-seckill/yami-shop-seckill-platform/src/main/java/com/yami/shop/seckill/platform/controller/SeckillController.java
yami-shop-seckill/yami-shop-seckill-platform/src/main/java/com/yami/shop/seckill/platform/controller/SeckillOrderController.java
yami-shop-seckill/yami-shop-seckill-platform/src/main/java/com/yami/shop/seckill/platform/dto/SeckillProdDto.java
yami-shop-seckill/yami-shop-seckill-platform/src/main/java/com/yami/shop/seckill/platform/task/SeckillOrderTask.java |