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-combo</artifactId> |
| | | <packaging>pom</packaging> |
| | | <modules> |
| | | <module>yami-shop-combo-api</module> |
| | | <module>yami-shop-combo-multishop</module> |
| | | <module>yami-shop-combo-common</module> |
| | | <module>yami-shop-combo-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-combo</artifactId> |
| | | <groupId>com.yami.shop</groupId> |
| | | <version>0.0.1-SNAPSHOT</version> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>yami-shop-combo-multishop</artifactId> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.yami.shop</groupId> |
| | | <artifactId>yami-shop-combo-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.combo.multishop.config; |
| | | |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import org.springdoc.core.GroupedOpenApi; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | /** |
| | | * 套餐、赠品 |
| | | * @author lanhai |
| | | */ |
| | | @Configuration("comboSwaggerConfiguration") |
| | | @AllArgsConstructor |
| | | public class SwaggerConfiguration { |
| | | |
| | | @Bean |
| | | public GroupedOpenApi comboRestApi() { |
| | | return GroupedOpenApi.builder() |
| | | .group("套餐、赠品接口") |
| | | .packagesToScan("com.yami.shop.combo.multishop.controller") |
| | | .pathsToMatch("/**") |
| | | .build(); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.combo.multishop.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.combo.multishop.model.Combo; |
| | | import com.yami.shop.combo.multishop.service.ComboProdService; |
| | | import com.yami.shop.combo.multishop.service.ComboService; |
| | | 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.security.multishop.util.SecurityUtils; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | 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 LGH |
| | | * @date 2021-11-02 10:32:48 |
| | | */ |
| | | @RestController |
| | | @AllArgsConstructor |
| | | @RequestMapping("/shop/combo" ) |
| | | @Tag(name = "套餐接口") |
| | | public class ComboController { |
| | | |
| | | private final ComboService comboService; |
| | | private final ComboProdService comboProdService; |
| | | |
| | | @GetMapping("/page" ) |
| | | @Operation(summary = "分页查询套餐" , description = "分页查询套餐") |
| | | public ServerResponseEntity<IPage<Combo>> getComboPage(PageParam<Combo> page, Combo combo) { |
| | | combo.setLang(I18nMessage.getDbLang()); |
| | | combo.setShopId(SecurityUtils.getShopUser().getShopId()); |
| | | IPage<Combo> pageRes = comboService.pageByParam(page, combo); |
| | | return ServerResponseEntity.success(pageRes); |
| | | } |
| | | |
| | | @GetMapping("/info/{comboId}" ) |
| | | @Operation(summary = "通过id查询套餐" , description = "通过id查询套餐") |
| | | public ServerResponseEntity<Combo> getById(@PathVariable("comboId") Long comboId) { |
| | | Combo combo = comboService.getComboWithProdInfoById(comboId); |
| | | if (!Objects.equals(combo.getShopId(), SecurityUtils.getShopUser().getShopId())) { |
| | | // 当前套餐shopId与用户shopId不相等 |
| | | throw new YamiShopBindException("yami.combo.not.shop"); |
| | | } |
| | | return ServerResponseEntity.success(combo); |
| | | } |
| | | |
| | | @PostMapping |
| | | @Operation(summary = "新增套餐" , description = "新增套餐") |
| | | public ServerResponseEntity<Void> save(@RequestBody @Valid Combo combo) { |
| | | Long shopId = SecurityUtils.getShopUser().getShopId(); |
| | | combo.setShopId(shopId); |
| | | comboService.saveInfo(combo); |
| | | comboProdService.removeComboListCache(combo.getMainProdId()); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping |
| | | @Operation(summary = "修改套餐" , description = "修改套餐Issued") |
| | | public ServerResponseEntity<Void> updateById(@RequestBody @Valid Combo combo) { |
| | | Long shopId = SecurityUtils.getShopUser().getShopId(); |
| | | combo.setShopId(shopId); |
| | | comboService.updateInfo(combo); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping("/changeStatus") |
| | | @Operation(summary = "修改套餐状态" , description = "修改套餐状态") |
| | | public ServerResponseEntity<Void> changeStatus(@RequestParam(value = "status") Integer status, @RequestParam(value = "comboId") Long comboId) { |
| | | Long shopId = SecurityUtils.getShopUser().getShopId(); |
| | | comboService.changeStatus(comboId, shopId, status); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.combo.multishop.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.combo.multishop.model.ComboProd; |
| | | import com.yami.shop.combo.multishop.service.ComboProdService; |
| | | import com.yami.shop.common.annotation.SysLog; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | |
| | | |
| | | /** |
| | | * 套餐商品项 |
| | | * |
| | | * @author LGH |
| | | * @date 2021-11-02 10:35:08 |
| | | */ |
| | | @RestController |
| | | @AllArgsConstructor |
| | | @RequestMapping("/seckill/comboProd" ) |
| | | public class ComboProdController { |
| | | |
| | | private final ComboProdService comboProdService; |
| | | |
| | | /** |
| | | * 分页查询 |
| | | * @param page 分页对象 |
| | | * @param comboProd 套餐商品项 |
| | | * @return 分页数据 |
| | | */ |
| | | @GetMapping("/page" ) |
| | | public ServerResponseEntity<IPage<ComboProd>> getComboProdPage(PageParam<ComboProd> page, ComboProd comboProd) { |
| | | return ServerResponseEntity.success(comboProdService.page(page, new LambdaQueryWrapper<ComboProd>())); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 通过id查询套餐商品项 |
| | | * @param comboProdId id |
| | | * @return 单个数据 |
| | | */ |
| | | @GetMapping("/info/{comboProdId}" ) |
| | | public ServerResponseEntity<ComboProd> getById(@PathVariable("comboProdId") Long comboProdId) { |
| | | return ServerResponseEntity.success(comboProdService.getById(comboProdId)); |
| | | } |
| | | |
| | | /** |
| | | * 新增套餐商品项 |
| | | * @param comboProd 套餐商品项 |
| | | * @return 是否新增成功 |
| | | */ |
| | | @SysLog("新增套餐商品项" ) |
| | | @PostMapping |
| | | @PreAuthorize("@pms.hasPermission('seckill:comboProd:save')" ) |
| | | public ServerResponseEntity<Boolean> save(@RequestBody @Valid ComboProd comboProd) { |
| | | return ServerResponseEntity.success(comboProdService.save(comboProd)); |
| | | } |
| | | |
| | | /** |
| | | * 修改套餐商品项 |
| | | * @param comboProd 套餐商品项 |
| | | * @return 是否修改成功 |
| | | */ |
| | | @SysLog("修改套餐商品项" ) |
| | | @PutMapping |
| | | @PreAuthorize("@pms.hasPermission('seckill:comboProd:update')" ) |
| | | public ServerResponseEntity<Boolean> updateById(@RequestBody @Valid ComboProd comboProd) { |
| | | return ServerResponseEntity.success(comboProdService.updateById(comboProd)); |
| | | } |
| | | |
| | | /** |
| | | * 通过id删除套餐商品项 |
| | | * @param comboProdId id |
| | | * @return 是否删除成功 |
| | | */ |
| | | @SysLog("删除套餐商品项" ) |
| | | @DeleteMapping("/{comboProdId}" ) |
| | | @PreAuthorize("@pms.hasPermission('seckill:comboProd:delete')" ) |
| | | public ServerResponseEntity<Boolean> removeById(@PathVariable Long comboProdId) { |
| | | return ServerResponseEntity.success(comboProdService.removeById(comboProdId)); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.combo.multishop.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.model.Giveaway; |
| | | import com.yami.shop.combo.multishop.service.GiveawayService; |
| | | 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.multishop.util.SecurityUtils; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | 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 LGH |
| | | * @date 2021-11-08 13:29:16 |
| | | */ |
| | | @RestController |
| | | @AllArgsConstructor |
| | | @RequestMapping("/shop/giveaway" ) |
| | | @Tag(name = "赠品接口") |
| | | public class GiveawayController { |
| | | |
| | | private final GiveawayService giveawayService; |
| | | |
| | | @GetMapping("/page" ) |
| | | @Operation(summary = "分页获取赠品信息" , description = "分页获取赠品信息") |
| | | public ServerResponseEntity<IPage<Giveaway>> getGiveawayPage(PageParam<Giveaway> page, Giveaway giveaway) { |
| | | giveaway.setShopId(SecurityUtils.getShopUser().getShopId()); |
| | | IPage<Giveaway> giveawayPage = giveawayService.pageByParam(page, giveaway); |
| | | return ServerResponseEntity.success(giveawayPage); |
| | | } |
| | | |
| | | @GetMapping("/info/{giveawayId}" ) |
| | | @Operation(summary = "通过id查询赠品" , description = "通过id查询赠品") |
| | | public ServerResponseEntity<Giveaway> getById(@PathVariable("giveawayId") Long giveawayId) { |
| | | Long shopId = SecurityUtils.getShopUser().getShopId(); |
| | | Giveaway giveaway = giveawayService.getInfoById(giveawayId); |
| | | if (!Objects.equals(shopId, giveaway.getShopId())) { |
| | | throw new YamiShopBindException("yami.giveaway.not.on.shop"); |
| | | } |
| | | return ServerResponseEntity.success(giveaway); |
| | | } |
| | | |
| | | @PostMapping |
| | | @Operation(summary = "新增赠品" , description = "新增赠品") |
| | | public ServerResponseEntity<Void> save(@RequestBody @Valid Giveaway giveaway) { |
| | | giveaway.setShopId(SecurityUtils.getShopUser().getShopId()); |
| | | giveawayService.saveInfo(giveaway); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping |
| | | @Operation(summary = "修改赠品" , description = "修改赠品") |
| | | public ServerResponseEntity<Void> updateById(@RequestBody @Valid Giveaway giveaway) { |
| | | giveaway.setShopId(SecurityUtils.getShopUser().getShopId()); |
| | | giveawayService.updateInfo(giveaway); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping("/changeStatus") |
| | | @Operation(summary = "修改赠品状态" , description = "修改赠品状态") |
| | | public ServerResponseEntity<Void> changeStatus(@RequestParam(value = "status") Integer status, @RequestParam(value = "giveawayId") Long giveawayId) { |
| | | Long shopId = SecurityUtils.getShopUser().getShopId(); |
| | | giveawayService.changeStatus(giveawayId, shopId, status); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.combo.multishop.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.model.GiveawayProd; |
| | | import com.yami.shop.bean.model.Product; |
| | | import com.yami.shop.combo.multishop.service.GiveawayProdService; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.security.multishop.util.SecurityUtils; |
| | | 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; |
| | | |
| | | |
| | | /** |
| | | * 套装商品项 |
| | | * |
| | | * @author LGH |
| | | * @date 2021-11-08 13:29:16 |
| | | */ |
| | | @RestController |
| | | @AllArgsConstructor |
| | | @RequestMapping("/shop/giveawayProd" ) |
| | | @Tag(name = "赠品商品项接口") |
| | | public class GiveawayProdController { |
| | | |
| | | private final GiveawayProdService giveawayProdService; |
| | | |
| | | /** |
| | | * 分页查询 |
| | | * @param page 分页对象 |
| | | * @param giveawayProd 套装商品项 |
| | | * @return 分页数据 |
| | | */ |
| | | @GetMapping("/page" ) |
| | | @Operation(summary = "分页获取赠品信息" , description = "分页获取赠品信息") |
| | | public ServerResponseEntity<IPage<GiveawayProd>> getGiveawayProdPage(PageParam<GiveawayProd> page, GiveawayProd giveawayProd) { |
| | | return ServerResponseEntity.success(giveawayProdService.page(page, new LambdaQueryWrapper<GiveawayProd>())); |
| | | } |
| | | |
| | | /** |
| | | * 主赠送商品分页查询 |
| | | * @param page 分页对象 |
| | | * @param giveawayProd 套装商品项 |
| | | * @return 分页数据 |
| | | */ |
| | | @GetMapping("/mainProdPage" ) |
| | | @Operation(summary = "分页获取主赠送商品" , description = "分页获取赠品信息") |
| | | public ServerResponseEntity<IPage<Product>> getMainProdPage(PageParam<Product> page, GiveawayProd giveawayProd) { |
| | | Long shopId = SecurityUtils.getShopUser().getShopId(); |
| | | giveawayProd.setShopId(shopId); |
| | | return ServerResponseEntity.success(giveawayProdService.getMainProdPage(page, giveawayProd)); |
| | | } |
| | | |
| | | } |
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-combo</artifactId> |
| | | <groupId>com.yami.shop</groupId> |
| | | <version>0.0.1-SNAPSHOT</version> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>yami-shop-combo-platform</artifactId> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.yami.shop</groupId> |
| | | <artifactId>yami-shop-combo-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.combo.platform.config; |
| | | |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import org.springdoc.core.GroupedOpenApi; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | /** |
| | | * 优惠券 |
| | | * @author lanhai |
| | | */ |
| | | @Configuration("comboSwaggerConfiguration") |
| | | @AllArgsConstructor |
| | | public class SwaggerConfiguration { |
| | | |
| | | @Bean |
| | | public GroupedOpenApi comboRestApi() { |
| | | return GroupedOpenApi.builder() |
| | | .group("套餐接口") |
| | | .packagesToScan("com.yami.shop.coupon.platform.controller") |
| | | .pathsToMatch("/**") |
| | | .build(); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.combo.platform.task; |
| | | |
| | | import com.xxl.job.core.handler.annotation.XxlJob; |
| | | import com.yami.shop.combo.multishop.service.ComboService; |
| | | import com.yami.shop.service.ProductService; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.context.ApplicationEventPublisher; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * @Author lth |
| | | * @Date 2021/11/12 15:07 |
| | | */ |
| | | @Slf4j |
| | | @Component("comboTask") |
| | | @AllArgsConstructor |
| | | public class ComboTask { |
| | | |
| | | private final ComboService comboService; |
| | | private final ProductService productService; |
| | | private final ApplicationEventPublisher eventPublisher; |
| | | |
| | | /** |
| | | * 关闭已经结束的套餐活动 |
| | | */ |
| | | @XxlJob("closeCombo") |
| | | public void closeCombo() { |
| | | comboService.closeComboByEndDate(); |
| | | } |
| | | |
| | | /** |
| | | * 开启到了活动时间未开启的套餐活动 |
| | | */ |
| | | @XxlJob("enableCombo") |
| | | public void enableCombo(){ |
| | | comboService.enableCombo(); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.combo.platform.task; |
| | | |
| | | import com.xxl.job.core.context.XxlJobHelper; |
| | | import com.xxl.job.core.handler.annotation.XxlJob; |
| | | import com.yami.shop.combo.multishop.service.GiveawayService; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * @Author lth |
| | | * @Date 2021/11/12 15:07 |
| | | */ |
| | | @Slf4j |
| | | @Component("giveawayTask") |
| | | @AllArgsConstructor |
| | | public class GiveawayTask { |
| | | |
| | | private final GiveawayService giveawayService; |
| | | |
| | | /** |
| | | * 关闭已经结束的赠品活动 |
| | | */ |
| | | @XxlJob("closeGiveaway") |
| | | public void closeGiveaway() { |
| | | giveawayService.closeGiveawayByEndDate(); |
| | | } |
| | | |
| | | /** |
| | | * 启用赠品活动 |
| | | */ |
| | | @XxlJob("enableGiveaway") |
| | | public void activityStartAndProdChange(){ |
| | | XxlJobHelper.log("赠品活动开启"); |
| | | giveawayService.startGiveawayActivity(); |
| | | } |
| | | |
| | | |
| | | |
| | | } |
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-common</artifactId> |
| | | <packaging>jar</packaging> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.luhuiguo</groupId> |
| | | <artifactId>aspose-words</artifactId> |
| | | <version>23.1</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-aop</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.google.guava</groupId> |
| | | <artifactId>guava</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>cn.hutool</groupId> |
| | | <artifactId>hutool-all</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.fasterxml.jackson.core</groupId> |
| | | <artifactId>jackson-databind</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.baomidou</groupId> |
| | | <artifactId>mybatis-plus-boot-starter</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.qiniu</groupId> |
| | | <artifactId>qiniu-java-sdk</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.qcloud</groupId> |
| | | <artifactId>cos_api</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>io.minio</groupId> |
| | | <artifactId>minio</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>mysql</groupId> |
| | | <artifactId>mysql-connector-java</artifactId> |
| | | </dependency> |
| | | <!-- 开始spring 缓存 --> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-cache</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-validation</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.redisson</groupId> |
| | | <artifactId>redisson-spring-boot-starter</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>ma.glasnost.orika</groupId> |
| | | <artifactId>orika-core</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.aliyun</groupId> |
| | | <artifactId>aliyun-java-sdk-core</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.aliyun.oss</groupId> |
| | | <artifactId>aliyun-sdk-oss</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.alipay.sdk</groupId> |
| | | <artifactId>alipay-sdk-java</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.paypal.sdk</groupId> |
| | | <artifactId>rest-api-sdk</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.paypal.sdk</groupId> |
| | | <artifactId>checkout-sdk</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.github.binarywang</groupId> |
| | | <artifactId>weixin-java-pay</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.github.binarywang</groupId> |
| | | <artifactId>weixin-java-miniapp</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.github.binarywang</groupId> |
| | | <artifactId>weixin-java-mp</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.apache.poi</groupId> |
| | | <artifactId>poi</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.apache.poi</groupId> |
| | | <artifactId>poi-ooxml</artifactId> |
| | | <scope>compile</scope> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.huaweicloud</groupId> |
| | | <artifactId>esdk-obs-java-bundle</artifactId> |
| | | <version>[3.21.8,)</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.lionsoul</groupId> |
| | | <artifactId>ip2region</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.github.ben-manes.caffeine</groupId> |
| | | <artifactId>caffeine</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.alibaba</groupId> |
| | | <artifactId>transmittable-thread-local</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.xuxueli</groupId> |
| | | <artifactId>xxl-job-core</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | </project> |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.annotation; |
| | | |
| | | import java.lang.annotation.*; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | | * 使用redis进行分布式锁 |
| | | * @author yami |
| | | */ |
| | | @Target(ElementType.METHOD) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Documented |
| | | public @interface RedisLock { |
| | | |
| | | /** |
| | | * redis锁 名字 |
| | | */ |
| | | String lockName() default ""; |
| | | |
| | | /** |
| | | * redis锁 key 支持spel表达式 |
| | | */ |
| | | String key() default ""; |
| | | |
| | | /** |
| | | * 过期毫秒数,默认为5000毫秒 |
| | | * |
| | | * @return 轮询锁的时间 |
| | | */ |
| | | int expire() default 5000; |
| | | |
| | | /** |
| | | * 超时时间单位 |
| | | * |
| | | * @return 秒 |
| | | */ |
| | | TimeUnit timeUnit() default TimeUnit.MILLISECONDS; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.annotation; |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /** |
| | | * 自定义日志注解 |
| | | * @author yami |
| | | */ |
| | | @Target(ElementType.METHOD) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Documented |
| | | public @interface SysLog { |
| | | |
| | | String value() default ""; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.aspect; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.yami.shop.common.annotation.RedisLock; |
| | | import com.yami.shop.common.util.SpelUtil; |
| | | import org.aspectj.lang.ProceedingJoinPoint; |
| | | import org.aspectj.lang.Signature; |
| | | import org.aspectj.lang.annotation.Around; |
| | | import org.aspectj.lang.annotation.Aspect; |
| | | import org.aspectj.lang.reflect.MethodSignature; |
| | | import org.redisson.api.RLock; |
| | | import org.redisson.api.RedissonClient; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.lang.reflect.Method; |
| | | |
| | | /** |
| | | * @author lgh |
| | | */ |
| | | @Aspect |
| | | @Component |
| | | public class RedisLockAspect { |
| | | |
| | | @Autowired |
| | | private RedissonClient redissonClient; |
| | | |
| | | private static final String REDISSON_LOCK_PREFIX = "redisson_lock:"; |
| | | |
| | | @Around("@annotation(redisLock)") |
| | | public Object around(ProceedingJoinPoint joinPoint, RedisLock redisLock) throws Throwable { |
| | | String spel = redisLock.key(); |
| | | String lockName = redisLock.lockName(); |
| | | |
| | | RLock rLock = redissonClient.getLock(getRedisKey(joinPoint,lockName,spel)); |
| | | |
| | | Object result = null; |
| | | |
| | | try { |
| | | rLock.lock(redisLock.expire(),redisLock.timeUnit()); |
| | | //执行方法 |
| | | result = joinPoint.proceed(); |
| | | |
| | | } finally { |
| | | if (rLock.isLocked()) { |
| | | rLock.unlock(); |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 将spel表达式转换为字符串 |
| | | * @param joinPoint 切点 |
| | | * @return redisKey |
| | | */ |
| | | private String getRedisKey(ProceedingJoinPoint joinPoint,String lockName,String spel) { |
| | | Signature signature = joinPoint.getSignature(); |
| | | MethodSignature methodSignature = (MethodSignature) signature; |
| | | Method targetMethod = methodSignature.getMethod(); |
| | | Object target = joinPoint.getTarget(); |
| | | Object[] arguments = joinPoint.getArgs(); |
| | | return REDISSON_LOCK_PREFIX + lockName + StrUtil.COLON + SpelUtil.parse(target,spel, targetMethod, arguments); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 阿里配置信息 |
| | | * @author LGH |
| | | */ |
| | | @Data |
| | | public class ALiDaYu { |
| | | |
| | | private String accessKeyId; |
| | | |
| | | private String accessKeySecret; |
| | | |
| | | private String signName; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean; |
| | | |
| | | |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | /** |
| | | * OSS配置信息 |
| | | * @author LGH |
| | | */ |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @Data |
| | | public class AliOss extends SwitchBaseModel { |
| | | |
| | | private String bucketName; |
| | | |
| | | private String accessKeyId; |
| | | |
| | | private String accessKeySecret; |
| | | |
| | | private String endpoint; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 支付宝配置 |
| | | * @author lgh |
| | | */ |
| | | @Data |
| | | public class Alipay { |
| | | |
| | | private String appId; |
| | | |
| | | /** |
| | | * 应用公钥证书 |
| | | */ |
| | | private String appCertPath; |
| | | |
| | | /** |
| | | * 支付宝公钥证书 |
| | | */ |
| | | private String alipayCertPath; |
| | | |
| | | /** |
| | | * 支付宝根证书 |
| | | */ |
| | | private String alipayRootCertPath; |
| | | |
| | | /** |
| | | * 应用私钥 |
| | | */ |
| | | private String appPrivateKey; |
| | | } |
New file |
| | |
| | | package com.yami.shop.common.bean; |
| | | |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | public class CDNConfigBean { |
| | | |
| | | @Schema(name = "账号appid") |
| | | private String appId; |
| | | |
| | | @Schema(name = "手机号码") |
| | | private String telephone; |
| | | |
| | | @Schema(name = "登录密码") |
| | | private String password; |
| | | |
| | | @Schema(name = "登录url") |
| | | private String url; |
| | | |
| | | @Schema(name = "设备url") |
| | | private String deviceUrl; |
| | | |
| | | @Schema(name = "设备流水url") |
| | | private String deviceEarnUrl; |
| | | |
| | | @Schema(name = "设备分组url") |
| | | private String deviceGroupUrl; |
| | | |
| | | @Schema(name = "设备释放url") |
| | | private String deviceReleaseUrl; |
| | | } |
New file |
| | |
| | | package com.yami.shop.common.bean; |
| | | |
| | | import lombok.Data; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | |
| | | /** |
| | | * @auth lxw |
| | | * @date 2024/4/25 |
| | | * @desc |
| | | */ |
| | | @Data |
| | | public class CDNDevice { |
| | | private String appId; |
| | | |
| | | private String password; |
| | | |
| | | private String telephone; |
| | | |
| | | private String url; |
| | | |
| | | private String deviceUrl; |
| | | |
| | | private String deviceEarnUrl; |
| | | |
| | | private String deviceGroupUrl; |
| | | |
| | | private String deviceReleaseUrl; |
| | | } |
New file |
| | |
| | | package com.yami.shop.common.bean; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | @Data |
| | | public class CdnIncomeRadioConfig { |
| | | private Double supplier; |
| | | private Double platform; |
| | | private Double user; |
| | | } |
New file |
| | |
| | | package com.yami.shop.common.bean; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | @Data |
| | | public class ContranctInfo implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * 姓名 |
| | | */ |
| | | private String name; |
| | | |
| | | /** |
| | | * 地址 |
| | | */ |
| | | private String address; |
| | | |
| | | /** |
| | | * 身份证号 |
| | | */ |
| | | private String certNo; |
| | | |
| | | /** |
| | | * 手机号 |
| | | */ |
| | | private String tel; |
| | | |
| | | /** |
| | | * 单价 |
| | | */ |
| | | private String price; |
| | | |
| | | /** |
| | | * 数量 |
| | | */ |
| | | private String count; |
| | | |
| | | /** |
| | | * 总价(小写) |
| | | */ |
| | | private String lettTotal; |
| | | |
| | | /** |
| | | * 总价(大写) |
| | | */ |
| | | private String capTotal; |
| | | |
| | | /** |
| | | * 时间(年) |
| | | */ |
| | | private String year; |
| | | /** |
| | | * 时间(月) |
| | | */ |
| | | private String month; |
| | | /** |
| | | * 时间(日) |
| | | */ |
| | | private String day; |
| | | |
| | | /** |
| | | * 账号 |
| | | */ |
| | | private String accNo; |
| | | /** |
| | | * 银行账号 |
| | | */ |
| | | private String bankNo; |
| | | /** |
| | | * 开户银行 |
| | | */ |
| | | private String bankName; |
| | | |
| | | } |
New file |
| | |
| | | package com.yami.shop.common.bean; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.Data; |
| | | |
| | | import javax.validation.constraints.NotBlank; |
| | | |
| | | /** |
| | | * 大淘客接入的各个平台配置 |
| | | * @author zsq |
| | | */ |
| | | @Data |
| | | @TableName("tz_cps_config") |
| | | public class CpsConfig { |
| | | |
| | | @TableId |
| | | private Long id; |
| | | |
| | | @NotBlank(message="参数名不能为空") |
| | | private String paramKey; |
| | | |
| | | @NotBlank(message="参数值不能为空") |
| | | private String paramValue; |
| | | |
| | | @NotBlank(message="备注") |
| | | private String remark; |
| | | } |
New file |
| | |
| | | package com.yami.shop.common.bean; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * @auth lxw |
| | | * @date 2024/4/23 |
| | | * @desc 统一时间VO |
| | | */ |
| | | @Data |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class DateVO { |
| | | |
| | | // 开始时间 |
| | | private Date start; |
| | | |
| | | // 结束时间 |
| | | private Date end; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 域名配置信息 |
| | | * @author lgh |
| | | */ |
| | | @Data |
| | | public class Domain { |
| | | |
| | | private String apiDomainName; |
| | | |
| | | private String multishopDomainName; |
| | | |
| | | private String platformDomainName; |
| | | |
| | | private String resourcesDomainName; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 汇率: 本系统货币 和其他币种的兑换比例 |
| | | * @author yami |
| | | */ |
| | | @Data |
| | | public class ExchangeRate { |
| | | |
| | | /** 本系统 1 */ |
| | | private BigDecimal currencyLocal; |
| | | |
| | | /** 美元 */ |
| | | private BigDecimal currencyUsd; |
| | | |
| | | private BigDecimal zero = new BigDecimal("0.0"); |
| | | |
| | | /** 获取美元的汇率 */ |
| | | public BigDecimal getUsdExchangeRate() { |
| | | return div(this.currencyUsd,this.currencyLocal,4); |
| | | } |
| | | |
| | | public BigDecimal getCurExchangeRate() { |
| | | return div(this.currencyLocal, this.currencyUsd, 4); |
| | | } |
| | | |
| | | private BigDecimal div(BigDecimal v1, BigDecimal v2,int scale) { |
| | | if (Objects.isNull(v1) || Objects.isNull(v2)) { |
| | | return this.zero; |
| | | } |
| | | if (v1.compareTo(this.zero) <=0 || v2.compareTo(this.zero) <= 0) { |
| | | return this.zero; |
| | | } |
| | | return v1.divide(v2,scale, RoundingMode.HALF_EVEN); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean; |
| | | |
| | | |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | /** |
| | | * OBS配置信息 |
| | | * @author LGH |
| | | */ |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @Data |
| | | public class HuaWeiOss extends SwitchBaseModel { |
| | | |
| | | private String bucketName; |
| | | |
| | | private String accessKeyId; |
| | | |
| | | private String secretAccessKey; |
| | | |
| | | private String endpoint; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean; |
| | | |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | /** |
| | | * minio配置信息 |
| | | * @Author lth |
| | | * @Date 2021/11/11 10:33 |
| | | */ |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @Data |
| | | public class Minio extends SwitchBaseModel { |
| | | private String bucketName; |
| | | |
| | | private String accessKey; |
| | | |
| | | private String secretKey; |
| | | |
| | | private String endpoint; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * Paypal支付配置 |
| | | * @author cl |
| | | */ |
| | | @Data |
| | | public class PayPal { |
| | | |
| | | /** |
| | | * PayPal 的 clientId |
| | | */ |
| | | private String clientId; |
| | | |
| | | /** |
| | | * PayPal 的 clientSecret |
| | | */ |
| | | private String clientSecret; |
| | | |
| | | /** |
| | | * sandbox 沙箱or live生产 |
| | | */ |
| | | private String mode; |
| | | /** |
| | | * 商家邮箱 |
| | | */ |
| | | private String receiverEmail; |
| | | /** |
| | | * 事件 id |
| | | */ |
| | | private String webHookId; |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean; |
| | | |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | /** |
| | | * 腾讯云cos存储配置信息 |
| | | * @author lgh |
| | | */ |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @Data |
| | | public class QCloud extends SwitchBaseModel { |
| | | |
| | | private String secretId; |
| | | |
| | | private String secretKey; |
| | | |
| | | private String region; |
| | | |
| | | private String bucketName; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean; |
| | | |
| | | import com.yami.shop.common.enums.QiniuZone; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | /** |
| | | * 七牛云存储配置信息 |
| | | * @author lgh |
| | | */ |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @Data |
| | | public class Qiniu extends SwitchBaseModel { |
| | | |
| | | private String accessKey; |
| | | |
| | | private String secretKey; |
| | | |
| | | private String bucket; |
| | | |
| | | private QiniuZone zone; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonIgnore; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | /** |
| | | * 快递鸟物流详情查询 |
| | | * @author SJL |
| | | */ |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @Data |
| | | public class Quick100 extends SwitchBaseModel { |
| | | |
| | | /** |
| | | * 快递100中顺丰编码 |
| | | */ |
| | | @JsonIgnore |
| | | public final static String SF_CODE = "shunfeng"; |
| | | /** |
| | | * 快递100中丰网速运编码 |
| | | */ |
| | | @JsonIgnore |
| | | public final static String FENGWANG_CODE = "fengwang"; |
| | | |
| | | private String customer; |
| | | private String key; |
| | | private String reqUrl; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean; |
| | | |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | /** |
| | | * 阿里物流详情查询 |
| | | * @Author lth |
| | | * @Date 2021/11/11 14:48 |
| | | */ |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @Data |
| | | public class QuickAli extends SwitchBaseModel { |
| | | |
| | | /** |
| | | * 阿里物流中的顺丰编号 |
| | | */ |
| | | public final static String SF_CODE = "SFEXPRESS"; |
| | | |
| | | private String aliCode; |
| | | private String reqUrl; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonIgnore; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | /** |
| | | * 快递鸟物流详情查询 |
| | | * @author yami |
| | | */ |
| | | @EqualsAndHashCode(callSuper = true) |
| | | public class QuickBird extends SwitchBaseModel { |
| | | |
| | | /** |
| | | * 快递鸟中顺丰编码 |
| | | */ |
| | | @JsonIgnore |
| | | public final static String SF_CODE = "SF"; |
| | | |
| | | private String eBusinessID; |
| | | private String appKey; |
| | | private String reqUrl; |
| | | |
| | | public String geteBusinessID() { |
| | | return eBusinessID; |
| | | } |
| | | |
| | | public void seteBusinessID(String eBusinessID) { |
| | | this.eBusinessID = eBusinessID; |
| | | } |
| | | |
| | | public String getAppKey() { |
| | | return appKey; |
| | | } |
| | | |
| | | public void setAppKey(String appKey) { |
| | | this.appKey = appKey; |
| | | } |
| | | |
| | | public String getReqUrl() { |
| | | return reqUrl; |
| | | } |
| | | |
| | | public void setReqUrl(String reqUrl) { |
| | | this.reqUrl = reqUrl; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | | return "QuickBird{" + |
| | | "eBusinessID='" + eBusinessID + '\'' + |
| | | ", appKey='" + appKey + '\'' + |
| | | ", reqUrl='" + reqUrl + '\'' + |
| | | '}'; |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean; |
| | | |
| | | /** |
| | | * @author Citrus |
| | | * @date 2021/8/6 10:25 |
| | | */ |
| | | public class SensitiveWord { |
| | | /** |
| | | * 敏感词 |
| | | */ |
| | | private String sensitiveWord; |
| | | |
| | | public String getSensitiveWord() { |
| | | return sensitiveWord; |
| | | } |
| | | |
| | | public void setSensitiveWord(String sensitiveWord) { |
| | | this.sensitiveWord = sensitiveWord; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | | return "SensitiveWord{" + |
| | | "sensitiveWord='" + sensitiveWord + '\'' + |
| | | '}'; |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.common.bean; |
| | | |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | public class ShopLuckyCoin { |
| | | /** |
| | | * 技师需交幸运币 |
| | | */ |
| | | private Long technician; |
| | | |
| | | /** |
| | | * 普通商家需交幸运币 |
| | | */ |
| | | private Long lifeShop; |
| | | |
| | | /** |
| | | * 生活服务商家需交幸运币 |
| | | */ |
| | | private Long shop; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 配置开关属性基本类 |
| | | * |
| | | * @Author lth |
| | | * @Date 2021/11/17 16:16 |
| | | */ |
| | | @Data |
| | | public class SwitchBaseModel { |
| | | |
| | | private Boolean isOpen; |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.Data; |
| | | |
| | | import javax.validation.constraints.NotBlank; |
| | | |
| | | /** |
| | | * 系统配置信息 |
| | | * @author yami |
| | | */ |
| | | @Data |
| | | @TableName("tz_sys_config") |
| | | public class SysConfig { |
| | | @TableId |
| | | private Long id; |
| | | |
| | | @NotBlank(message="参数名不能为空") |
| | | private String paramKey; |
| | | |
| | | @NotBlank(message="参数值不能为空") |
| | | private String paramValue; |
| | | |
| | | @NotBlank(message="备注") |
| | | private String remark; |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 系统支付开关配置 |
| | | * @author cl |
| | | */ |
| | | @Data |
| | | public class SysPayConfig { |
| | | |
| | | /** |
| | | * 是否开启支付宝支付 |
| | | */ |
| | | private Boolean aliPaySwitch; |
| | | |
| | | /** |
| | | * 是否开启微信支付 |
| | | */ |
| | | private Boolean wxPaySwitch; |
| | | |
| | | /** |
| | | * 是否开启余额支付 |
| | | */ |
| | | private Boolean balancePaySwitch; |
| | | |
| | | /** |
| | | * 是否开启支付宝支付 |
| | | */ |
| | | private Boolean payPalSwitch; |
| | | |
| | | /** |
| | | * 是否开启杉德支付收银台 |
| | | */ |
| | | private Boolean sdPayPalSwitch; |
| | | |
| | | /** |
| | | * 是否开启杉德支付二维码 |
| | | */ |
| | | private Boolean sdQrcodeSwitch; |
| | | |
| | | /** |
| | | * 是否开启瓜瓜豆支付 |
| | | */ |
| | | private Boolean sdBeanSwitch; |
| | | |
| | | /** |
| | | * 是否开启蓝积分支付 |
| | | */ |
| | | // private Boolean bluePointSwitch; |
| | | |
| | | /** |
| | | * 是否开启蓝积分+红积分支付 |
| | | */ |
| | | private Boolean blueRedPointSwitch; |
| | | |
| | | /** |
| | | * 是否开启蓝积分+余额支付 |
| | | */ |
| | | private Boolean blueBalancePointSwitch; |
| | | |
| | | /** |
| | | * 是否开启红积分 |
| | | */ |
| | | private Boolean redPointSwitch; |
| | | |
| | | |
| | | /** |
| | | * 杉德个人支付二维码 |
| | | */ |
| | | private Boolean sdGrQrcodeSwitch; |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 商品开关配置 |
| | | * @author Citrus |
| | | */ |
| | | @Data |
| | | public class SysProdConfig { |
| | | |
| | | /** |
| | | * 是否开启商品审核 |
| | | */ |
| | | private Boolean prodAudit; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 系统服务条例开关配置 |
| | | * @author Citrus |
| | | */ |
| | | @Data |
| | | public class SysServiceConfig { |
| | | |
| | | @Schema(description = "是否开启服务条款" ) |
| | | private Boolean serviceTermsSwitch; |
| | | |
| | | @Schema(description = "是否开启隐私策略" ) |
| | | private Boolean privacyPolicySwitch; |
| | | |
| | | @Schema(description = "是否开启商家注册协议" ) |
| | | private Boolean merchantRegisterProtocolSwitch; |
| | | |
| | | @Schema(description = "是否开启开店协议" ) |
| | | private Boolean shopProtocolSwitch; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean; |
| | | |
| | | |
| | | 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; |
| | | |
| | | /** |
| | | * 系统用户 |
| | | * @author yami |
| | | */ |
| | | @Data |
| | | @TableName("sys_upgrade_info") |
| | | public class SysUpgradeInfo implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | /** |
| | | * 主键 |
| | | * |
| | | */ |
| | | @TableId |
| | | @Schema(description = "ID" ) |
| | | private Long id; |
| | | |
| | | @Schema(description = "版本更新内容" ) |
| | | private String decribe; |
| | | |
| | | @Schema(description = "apk、wgt包下载地址或者应用市场地址安卓应用市场" ) |
| | | private String editionUrl; |
| | | |
| | | @Schema(description = "是否强制更新 0代表否 1代表是" ) |
| | | private String editionForce; |
| | | |
| | | @Schema(description = "0是整包升级(apk或者appstore或者安卓应用市场)1是wgt升级" ) |
| | | private String packageType; |
| | | @Schema(description = "是否发行 @否 1是 为了控制上架应用市场审核时不能弹出热更新框" ) |
| | | private String editionIssue; |
| | | @Schema(description = "版本号 最重要的manifest里的版本号" ) |
| | | private String editionNumber; |
| | | @Schema(description = "版本名称 manifest里的版本名称" ) |
| | | private String editionName; |
| | | @Schema(description = "是否静默更新 0代表否 1代表是" ) |
| | | private String editionSilence; |
| | | @Schema(description = "创建时间" ) |
| | | private String createTime; |
| | | @Schema(description = "修改时间" ) |
| | | private String updateTime; |
| | | @Schema(description = "发布时间" ) |
| | | private String releaseTime; |
| | | } |
New file |
| | |
| | | package com.yami.shop.common.bean; |
| | | |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | public class TaskPageUrl { |
| | | |
| | | private String prodDetailPage; |
| | | |
| | | private String registerPage; |
| | | |
| | | private String promotionPage; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean; |
| | | |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 微信app参数 |
| | | * @author yami |
| | | */ |
| | | @Data |
| | | public class WxApp { |
| | | /** |
| | | * 设置微信原生的appid |
| | | */ |
| | | private String appId; |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean; |
| | | |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 微信小程序参数 |
| | | * @author yami |
| | | */ |
| | | @Data |
| | | public class WxMiniApp { |
| | | /** |
| | | * 设置微信小程序的appid |
| | | */ |
| | | private String appId; |
| | | |
| | | /** |
| | | * 设置微信小程序的Secret |
| | | */ |
| | | private String secret; |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean; |
| | | |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 微信公众号参数 |
| | | * @author yami |
| | | */ |
| | | @Data |
| | | public class WxMp { |
| | | /** |
| | | * 设置微信公众号的appid |
| | | */ |
| | | private String appId; |
| | | |
| | | /** |
| | | * 设置微信公众号的Secret |
| | | */ |
| | | private String secret; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean; |
| | | |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 微信支付参数 |
| | | * @author yami |
| | | */ |
| | | @Data |
| | | public class WxPay { |
| | | |
| | | public static final Integer VERSION_3 = 3; |
| | | |
| | | /** |
| | | * 微信支付mchId |
| | | */ |
| | | private String mchId; |
| | | |
| | | /** |
| | | * 微信支付mchKey |
| | | */ |
| | | private String mchKey; |
| | | |
| | | /** |
| | | * 签名类型 |
| | | */ |
| | | private String signType; |
| | | |
| | | /** |
| | | * 支付证书路径 |
| | | */ |
| | | private String keyPath; |
| | | |
| | | // ======== v3 需要======= |
| | | /** |
| | | * 微信支付版本 2代表用旧的v2支付 3代表用v3支付 |
| | | */ |
| | | private Integer version; |
| | | |
| | | /** |
| | | * 证书序列号 |
| | | */ |
| | | private String certSerialNo; |
| | | |
| | | /** |
| | | * apiV3秘钥 |
| | | */ |
| | | private String apiv3Key; |
| | | |
| | | /** |
| | | * apiv3 商户apiclient_key.pem |
| | | */ |
| | | private String privateKeyPath; |
| | | |
| | | /** |
| | | * apiv3 商户apiclient_cert.pem |
| | | */ |
| | | private String privateCertPath; |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.bean.event; |
| | | |
| | | import com.yami.shop.common.bean.SensitiveWord; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 获取敏感词配置的事件 |
| | | * @author Citrus |
| | | * @date 2021/8/17 11:24 |
| | | */ |
| | | @Data |
| | | @AllArgsConstructor |
| | | public class GetSensitiveWordEvent { |
| | | |
| | | /** |
| | | * 配置key |
| | | */ |
| | | private String key; |
| | | |
| | | /** |
| | | * 敏感词 |
| | | */ |
| | | private SensitiveWord sensitiveWord; |
| | | } |
New file |
| | |
| | | package com.yami.shop.common.config; |
| | | |
| | | public class BigSellerConfig { |
| | | |
| | | /** 大淘客(淘宝联盟)相关配置 */ |
| | | public static final String CPS_TAOBAO_CONFIG = "CPS_TAOBAO_CONFIG"; |
| | | |
| | | /** 大淘客(京东联盟)相关配置 */ |
| | | public static final String CPS_JINGDONG_CONFIG = "CPS_JINGDONG_CONFIG"; |
| | | |
| | | /** 美团联盟相关配置 */ |
| | | public static final String CPS_MTLM_CONFIG = "CPS_MTLM_CONFIG"; |
| | | |
| | | /** 美团分销联盟相关配置 */ |
| | | public static final String CPS_MTFXLM_CONFIG = "CPS_MTFXLM_CONFIG"; |
| | | |
| | | /** 多多进宝相关配置 */ |
| | | public static final String CPS_PDD_CONFIG = "CPS_PDD_CONFIG"; |
| | | |
| | | /** 聚推客联盟配置 */ |
| | | public static final String CPS_JTK_CONFIG = "CPS_JTK_CONFIG"; |
| | | |
| | | /** 美团联盟自助取链接口 */ |
| | | public static final String CPS_MTLM_GENERATELINK = "https://openapi.meituan.com/api/generateLink"; |
| | | |
| | | /** 美团联盟订单查询接口 */ |
| | | public static final String CPS_MTLM_ORDERLIST ="https://openapi.meituan.com/api/orderList"; |
| | | |
| | | /** 美团分销联盟取链接口 */ |
| | | public static final String CPS_MTFX_GENERATELINK = "https://union.dianping.com/api/promotion/link"; |
| | | |
| | | /** 美团分销联盟订单获取接口 */ |
| | | public static final String CPS_MTFX_ORDERLIST = "https://union.dianping.com/data/promote/verify/item/new"; |
| | | |
| | | /** 美团分销联盟省份查询接⼝ */ |
| | | public static final String CPS_MTFX_PROVINCEALL = "https://union.dianping.com/api/province/all"; |
| | | |
| | | /** 美团分销联盟省份查询接⼝ */ |
| | | public static final String CPS_JTK_PROVINCEALL = "http://api.act.jutuike.com/mtfx/province_all "; |
| | | |
| | | /** 聚推客联盟城市查询接口 */ |
| | | public static final String CPS_MTFX_CITYALL = "https://union.dianping.com/api/province/"; |
| | | |
| | | /** 聚推客联盟城市查询接口 */ |
| | | public static final String CPS_JTK_CITYALL = "http://api.act.jutuike.com/mtfx/province_cities"; |
| | | |
| | | /** 美团分销联盟城市类目查询接口 */ |
| | | public static final String CPS_MTFX_CITYCATEGORY = "https://union.dianping.com/api/city/"; |
| | | |
| | | /** 聚推客联盟城市类目查询接口 */ |
| | | public static final String CPS_JTK_CITYCATEGORY = "http://api.act.jutuike.com/mtfx/city_categories"; |
| | | |
| | | /** 团购API-获取某个城市的商圈信息(美团) */ |
| | | public static final String CPS_MTFX_MTREGIONS = "https://union.dianping.com/api/mt/city/"; |
| | | |
| | | /** 聚推客团购API-获取某个城市的商圈信息(美团) */ |
| | | public static final String CPS_JTK_MTREGIONS = "http://api.act.jutuike.com/mtfx/mt_regions"; |
| | | |
| | | /** 美团分销联盟商品搜索接口 */ |
| | | // public static final String CPS_MTFX_SEARCHDEALS = "https://union.dianping.com/api/search/deals"; |
| | | |
| | | /** 美团分销联盟门店关键信息接口 */ |
| | | // public static final String CPS_MTFX_SHOPDETAIL = "https://union.dianping.com/api/shop/detail"; |
| | | |
| | | |
| | | /** 美团分销联盟门店关键信息接口 */ |
| | | public static final String CPS_JTK_UNIONACT = "http://api.jutuike.com/union/act"; |
| | | |
| | | /** 美团分销联盟门店关键信息接口 */ |
| | | public static final String CPS_JTK_UNIONORDER = "http://api.jutuike.com/union/orders"; |
| | | |
| | | /** 聚推客 团购订单查询 */ |
| | | public static final String CPS_JTK_SEARCHDEALS = "http://api.act.jutuike.com/mtfx/search_deals "; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.config; |
| | | |
| | | import com.yami.shop.common.i18n.LanguageEnum; |
| | | |
| | | /** |
| | | * 常量 |
| | | * @author yami |
| | | */ |
| | | public class Constant { |
| | | |
| | | /** 超级管理员ID */ |
| | | public static final int SUPER_ADMIN_ID = 1; |
| | | |
| | | /** |
| | | * 自营店id |
| | | */ |
| | | public static final long MAIN_SHOP = 1L; |
| | | |
| | | /** |
| | | * 如果把平台的数据也保存在店铺里面,如分类,热搜之类的,保存的店铺id |
| | | */ |
| | | public static final long PLATFORM_SHOP_ID = 0L; |
| | | /** |
| | | * 平台条件标签上限 |
| | | */ |
| | | public static final long TAG_LIMIT_NUM = 20; |
| | | /** |
| | | * 平台店名称 |
| | | */ |
| | | public static final String PLATFORM_SHOP_NAME = "官方店"; |
| | | |
| | | /** |
| | | * 积分名称 |
| | | */ |
| | | public static final String SCORE_CONFIG = "SCORE_CONFIG"; |
| | | public static final String SCORE_EXPLAIN = "SCORE_EXPLAIN"; |
| | | public static final String LEVEL_SHOW = "LEVEL_SHOW"; |
| | | public static final String SCORE_EXPIRE = "SCORE_EXPIRE"; |
| | | public static final String SCORE_QUESTION = "SCORE_QUESTION"; |
| | | /** |
| | | * 商城缺失sku属性时的字符描述 |
| | | */ |
| | | public static final String SKU_PREFIX = "规格:"; |
| | | |
| | | public static final String DEFAULT_SKU = "规格"; |
| | | /** |
| | | * 成长值名称 |
| | | */ |
| | | public static final String GROWTH_CONFIG = "GROWTH_CONFIG"; |
| | | |
| | | /** 会员初始等级id*/ |
| | | public static final int USER_LEVEL_INIT = 1; |
| | | |
| | | /** 商家线下核销*/ |
| | | public static final int SERVICE_TYPE = 1; |
| | | |
| | | /** 系统菜单最大id */ |
| | | public static final int SYS_MENU_MAX_ID = 30; |
| | | |
| | | /** 订单超时时间 */ |
| | | public static final int ORDER_MAX_TIME = 30; |
| | | |
| | | /** 订单类型:积分订单 */ |
| | | public static final int ORDER_TYPE_SCORE = 3; |
| | | |
| | | /** |
| | | * 最大确认收货退款时间7天 |
| | | */ |
| | | public static final int MAX_FINALLY_REFUND_TIME = 7; |
| | | |
| | | /** |
| | | * 退款最长申请时间,当申请时间过了这个时间段之后,会取消退款申请 |
| | | */ |
| | | public static final int MAX_REFUND_APPLY_TIME = 7; |
| | | /** |
| | | * 离即将退款超时x小时时提醒 |
| | | */ |
| | | public static final int MAX_REFUND_HOUR = 12; |
| | | /** |
| | | * 直播间置顶上限个数 |
| | | */ |
| | | public static final int MAX_TOP_NUM = 10; |
| | | |
| | | /** |
| | | * 分销佣金结算在确认收货后的时间,维权期过后(7+7+1) |
| | | */ |
| | | public static final int DISTRIBUTION_SETTLEMENT_TIME = MAX_FINALLY_REFUND_TIME + MAX_REFUND_APPLY_TIME + 1; |
| | | |
| | | /** |
| | | * 查询订单成功状态 |
| | | */ |
| | | public static final String SUCCESS = "SUCCESS"; |
| | | |
| | | /** |
| | | * 一级分类id |
| | | */ |
| | | public static final Long CATEGORY_ID = 0L; |
| | | |
| | | /** |
| | | * 配置名称 |
| | | */ |
| | | public static final String ALIPAY_CONFIG = "ALIPAY_CONFIG"; |
| | | public static final String WXPAY_CONFIG = "WXPAY_CONFIG"; |
| | | public static final String QINIU_CONFIG = "QINIU_CONFIG"; |
| | | public static final String ALI_OSS_CONFIG = "ALI_OSS_CONFIG"; |
| | | public static final String Q_CLOUD_CONFIG = "Q_CLOUD_CONFIG"; |
| | | public static final String MINIO_OSS_CONFIG = "MINIO_OSS_CONFIG"; |
| | | public static final String HUAWEI_OBS_CONFIG = "HUAWEI_OBS_CONFIG"; |
| | | public static final String QUICKBIRD_CONFIG = "QUICKBIRD_CONFIG"; |
| | | public static final String QUICK100_CONFIG = "QUICK100_CONFIG"; |
| | | public static final String ALI_QUICK_CONFIG = "ALI_QUICK_CONFIG"; |
| | | public static final String MA_CONFIG = "MA_CONFIG"; |
| | | public static final String MP_CONFIG = "MP_CONFIG"; |
| | | public static final String ALIDAYU_CONFIG = "ALIDAYU_CONFIG"; |
| | | public static final String DOMAIN_CONFIG = "DOMAIN_CONFIG"; |
| | | public static final String MX_APP_CONFIG = "MX_APP_CONFIG"; |
| | | public static final String PAYPAL_CONFIG = "PAYPAL_CONFIG"; |
| | | public static final String MERCHANT_REGISTER_PROTOCOL_CN = "MERCHANT_REGISTER_PROTOCOL_CN"; |
| | | public static final String MERCHANT_REGISTER_PROTOCOL_EN = "MERCHANT_REGISTER_PROTOCOL_EN"; |
| | | public static final String SHOP_PROTOCOL_CN = "SHOP_PROTOCOL_CN"; |
| | | public static final String SHOP_PROTOCOL_EN = "SHOP_PROTOCOL_EN"; |
| | | public static final String SENSITIVE_WORDS = "SENSITIVE_WORDS"; |
| | | public static final String CDN_DEVICE_CONFIG = "CDN_DEVICE_CONFIG"; |
| | | public static final String TASK_PAGE_URL_CONFIG = "TASK_PAGE_URL_CONFIG"; |
| | | public static final String CDN_CONFIG = "CDN_CONFIG"; |
| | | public static final String LUCKY_COIN_CONFIG = "LUCKY_COIN_CONFIG"; |
| | | |
| | | /** 汇率配置 */ |
| | | public static final String EXCHANGE_RATE_CONFIG = "EXCHANGE_RATE_CONFIG"; |
| | | |
| | | /** |
| | | * 记录缓存名称 |
| | | */ |
| | | public static final String FLOW_ANALYSIS_LOG = "flowAnalysisLog"; |
| | | |
| | | /** |
| | | * 心跳字符串 |
| | | */ |
| | | public static final String HEART_BEAT = "HEART_BEAT"; |
| | | |
| | | |
| | | /** |
| | | * 最大会员等级折扣 |
| | | */ |
| | | public static final double MAX_LEVEL_DISCOUNT = 10D; |
| | | |
| | | /** |
| | | * 最小会员等级积分倍率 |
| | | */ |
| | | public static final double MIN_LEVEL_RATE_SCORE = 1D; |
| | | /** |
| | | * 短信套餐包最大数量 |
| | | */ |
| | | public static final int MAX_SMS_PACKAGE = 10; |
| | | /** |
| | | * 商品最低金额(非积分商品) |
| | | */ |
| | | public static final Double MIN_PRODUCT_AMOUNT = 0.01D; |
| | | |
| | | /** |
| | | * 店铺最多可以签约的分类数量 |
| | | */ |
| | | public static final int SIGNING_CATEGORY_LIMIT_NUM = 200; |
| | | |
| | | /** |
| | | * 店铺签约的品牌数量上限 |
| | | */ |
| | | public static final int SIGNING_BRAND_LIMIT_NUM = 50; |
| | | |
| | | /** |
| | | * 店铺可以绑定的银行卡上限 |
| | | */ |
| | | public static final int SHOP_BANK_CARD_LIMIT_NUM = 5; |
| | | /** |
| | | * 句号(英文符号) |
| | | */ |
| | | public static final String PERIOD = "."; |
| | | /** |
| | | * 逗号 |
| | | */ |
| | | public static final String COMMA = ","; |
| | | /** |
| | | * 中文逗号 |
| | | */ |
| | | public static final String CN_COMMA = ","; |
| | | /** |
| | | * 冒号 |
| | | */ |
| | | public static final String COLON = ":"; |
| | | /** |
| | | * 零 |
| | | */ |
| | | public static final Long ZERO_LONG = 0L; |
| | | /** |
| | | * 零 |
| | | */ |
| | | public static final Double ZERO_DOUBLE = 0D; |
| | | /** |
| | | * |
| | | * 参考CacheKeyPrefix |
| | | * cacheNames 与 key 之间的默认连接字符 |
| | | */ |
| | | public static final String UNION = "::"; |
| | | /** |
| | | * 默认语言 |
| | | */ |
| | | public static final Integer DEFAULT_LANG = LanguageEnum.LANGUAGE_ZH_CN.getLang(); |
| | | public static final Integer MAX_PAGE_SIZE = 100; |
| | | |
| | | /** |
| | | * 数据量大时,系统单次处理数据的数量 |
| | | */ |
| | | public static final Long MAX_DATA_HANDLE_NUM = 10000L; |
| | | |
| | | /** |
| | | * 分销相关配置 |
| | | */ |
| | | public static final String DISTRIBUTION_CONFIG = "DISTRIBUTION_CONFIG"; |
| | | public static final String DISTRIBUTION_RECRUIT_CONFIG = "DISTRIBUTION_RECRUIT_CONFIG"; |
| | | public static final Double MAX_USER_BALANCE = 999999999.99D; |
| | | public static String DISTRIBUTION_REMARKS = "分销配置"; |
| | | public static String DISTRIBUTION_RECRUIT_REMARKS = "分销招募推广配置"; |
| | | public static final String PURCHASES_ORDER = "PO"; |
| | | |
| | | /** |
| | | * 签名相关 |
| | | */ |
| | | public static final String PUBLIC_KEY = "publicKey"; |
| | | public static final String PRIVATE_KEY = "privateKey"; |
| | | /** |
| | | * 系统配置相关 |
| | | */ |
| | | public static final String PAY_SWITCH_CONFIG = "PAY_SWITCH_CONFIG"; |
| | | |
| | | public static final String SERVICE_SWITCH_CONFIG = "SERVICE_SWITCH_CONFIG"; |
| | | |
| | | public static final String PROD_SWITCH_CONFIG = "PROD_SWITCH_CONFIG"; |
| | | |
| | | /** |
| | | * 店铺最大银行卡数量 |
| | | */ |
| | | public static final int MAX_SHOP_BANK_CARD = 5; |
| | | |
| | | /** |
| | | * 使用商品浏览记录进行推荐时,使用的数据数量 |
| | | */ |
| | | public static final int MAX_PROD_BROWSE_NUM = 50; |
| | | |
| | | /** |
| | | * 成功状态码 |
| | | */ |
| | | public static final int SUCCESS_CODE = 200; |
| | | |
| | | /** |
| | | * xls文件 |
| | | */ |
| | | public static final String XLS_FILE = "xls"; |
| | | |
| | | /** |
| | | * xlsx文件 |
| | | */ |
| | | public static final String XLSX_FILE = "xlsx"; |
| | | |
| | | public static final int LAST_FOUR_BY_MOBILE = 4; |
| | | |
| | | /** |
| | | * 微信最大支付金额 |
| | | */ |
| | | public static final Double WECHAT_MAX_PAY_AMOUNT = 10000000.00D; |
| | | |
| | | public static final int MAX_NICK_NAME_LENGTH = 15; |
| | | |
| | | public static final int EXCEL_BEGIN_ROW = 2; |
| | | |
| | | /** |
| | | * 统计的最大步骤数 |
| | | */ |
| | | public static final int MAX_ROUTE_STEP = 10; |
| | | |
| | | |
| | | public static final int MAX_MYSQL_STRING_LENGTH = 255; |
| | | |
| | | /** |
| | | * 秒杀sku缓存key |
| | | */ |
| | | public static final String SECKILL_SKU_STOCKS_PREFIX = "SECKILL_SKU_STOCKS_"; |
| | | |
| | | /** |
| | | * 最大轮播图数量 |
| | | */ |
| | | public static final int MAX_INDEX_IMG_NUM = 10; |
| | | |
| | | public static final Integer ERROR1 = 475; |
| | | |
| | | public static final Integer ERROR2 = 476; |
| | | |
| | | public static final Integer ERROR3 = 477; |
| | | |
| | | public static final Integer stockWarningMax = 9999999; |
| | | |
| | | /** 用户收益明细*/ |
| | | public static final String USER_DEVICE_INCOME = "USER_DEVICE_INCOME:"; |
| | | |
| | | /** 短剧金币转积分*/ |
| | | public static final String RATE_G_SCORE = "RATE_G_SCORE"; |
| | | |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.config; |
| | | |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.response.ResponseEnum; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.http.HttpStatus; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.stereotype.Controller; |
| | | import org.springframework.validation.BindException; |
| | | import org.springframework.validation.FieldError; |
| | | import org.springframework.web.bind.MethodArgumentNotValidException; |
| | | import org.springframework.web.bind.annotation.ExceptionHandler; |
| | | import org.springframework.web.bind.annotation.RestControllerAdvice; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 自定义错误处理器 |
| | | * @author LGH |
| | | */ |
| | | @Slf4j |
| | | @Controller |
| | | @RestControllerAdvice |
| | | public class DefaultExceptionHandlerConfig { |
| | | |
| | | |
| | | private static final Logger logger = LoggerFactory.getLogger(DefaultExceptionHandlerConfig.class); |
| | | |
| | | @ExceptionHandler({ MethodArgumentNotValidException.class, BindException.class }) |
| | | public ResponseEntity<ServerResponseEntity<List<String>>> methodArgumentNotValidExceptionHandler(Exception e) { |
| | | logger.error("methodArgumentNotValidExceptionHandler", e); |
| | | List<FieldError> fieldErrors = null; |
| | | if (e instanceof MethodArgumentNotValidException) { |
| | | fieldErrors = ((MethodArgumentNotValidException) e).getBindingResult().getFieldErrors(); |
| | | } |
| | | if (e instanceof BindException) { |
| | | fieldErrors = ((BindException) e).getBindingResult().getFieldErrors(); |
| | | } |
| | | if (fieldErrors == null) { |
| | | return ResponseEntity.status(HttpStatus.OK) |
| | | .body(ServerResponseEntity.fail(ResponseEnum.METHOD_ARGUMENT_NOT_VALID)); |
| | | } |
| | | |
| | | List<String> defaultMessages = new ArrayList<>(fieldErrors.size()); |
| | | for (FieldError fieldError : fieldErrors) { |
| | | defaultMessages.add(fieldError.getField() + ":" + fieldError.getDefaultMessage()); |
| | | } |
| | | return ResponseEntity.status(HttpStatus.OK) |
| | | .body(ServerResponseEntity.fail(ResponseEnum.METHOD_ARGUMENT_NOT_VALID, defaultMessages)); |
| | | } |
| | | |
| | | @ExceptionHandler(YamiShopBindException.class) |
| | | public ResponseEntity<ServerResponseEntity<?>> unauthorizedExceptionHandler(YamiShopBindException e){ |
| | | logger.error("mall4jExceptionHandler", e); |
| | | |
| | | ServerResponseEntity<?> serverResponseEntity = e.getServerResponseEntity(); |
| | | if (serverResponseEntity!=null) { |
| | | return ResponseEntity.status(HttpStatus.OK).body(serverResponseEntity); |
| | | } |
| | | // 失败返回消息 状态码固定为直接显示消息的状态码 |
| | | return ResponseEntity.status(HttpStatus.OK).body(ServerResponseEntity.fail(e.getCode(),e.getMessage())); |
| | | } |
| | | |
| | | @ExceptionHandler(Exception.class) |
| | | public ResponseEntity<ServerResponseEntity<Object>> exceptionHandler(Exception e){ |
| | | logger.error("exceptionHandler", e); |
| | | return ResponseEntity.status(HttpStatus.OK).body(ServerResponseEntity.fail(ResponseEnum.EXCEPTION)); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.config; |
| | | |
| | | import cn.hutool.core.io.IoUtil; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.lionsoul.ip2region.xdb.Searcher; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.core.io.ClassPathResource; |
| | | |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | |
| | | /** |
| | | * 获取IP |
| | | * @author yami |
| | | */ |
| | | @Slf4j |
| | | @Configuration |
| | | public class Ip2RegionConfig { |
| | | |
| | | @Bean(destroyMethod = "close") |
| | | public Searcher searcher() throws IOException { |
| | | // 获取ip库路径 |
| | | ClassPathResource classPathResource = new ClassPathResource("ip2region.xdb"); |
| | | if (classPathResource.getClassLoader() == null){ |
| | | log.error("ip2region.xdb 存储路径发生错误,没有被发现"); |
| | | return null; |
| | | } |
| | | InputStream inputStream = classPathResource.getInputStream(); |
| | | // 1、从 dbPath 加载整个 xdb 到内存。 |
| | | byte[] cBuff = IoUtil.readBytes(inputStream); |
| | | |
| | | // 2、使用上述的 cBuff 创建一个完全基于内存的查询对象。 |
| | | Searcher searcher = null; |
| | | try { |
| | | searcher = Searcher.newWithBuffer(cBuff); |
| | | } catch (Exception e) { |
| | | System.out.printf("failed to create content cached searcher: %s\n", e); |
| | | } |
| | | return searcher; |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.config; |
| | | |
| | | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.time.format.DateTimeFormatter; |
| | | |
| | | /** |
| | | * 时间配置 |
| | | * @author yami |
| | | */ |
| | | @Configuration |
| | | public class LocalDateTimeSerializerConfig { |
| | | |
| | | @Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}") |
| | | private String pattern; |
| | | |
| | | @Bean |
| | | public LocalDateTimeSerializer localDateTimeDeserializer() { |
| | | return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern)); |
| | | } |
| | | |
| | | @Bean |
| | | public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() { |
| | | return builder -> builder.serializerByType(LocalDateTime.class, localDateTimeDeserializer()); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.yami.shop.common.config; |
| | | |
| | | import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.ibatis.reflection.MetaObject; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * @program: feel-generator |
| | | * @description: 自动填充时间 |
| | | * @author: Jianfeng LIAN |
| | | * @nickname: 我自然 |
| | | * @email : 2580040689@qq.com |
| | | * @github :https://github.com/woizran |
| | | * @date: 2021-06-05 00:28 |
| | | **/ |
| | | @Component |
| | | @Slf4j |
| | | public class MyDetaObjectHandler implements MetaObjectHandler { |
| | | public void insertFill(MetaObject metaObject) { |
| | | log.info("come to insert fill ........."); |
| | | //setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject) |
| | | this.setFieldValByName("createTime",new Date(),metaObject); |
| | | this.setFieldValByName("updateTime",new Date(),metaObject); |
| | | } |
| | | |
| | | @Override |
| | | public void updateFill(MetaObject metaObject) { |
| | | log.info("come to update fill ......."); |
| | | |
| | | this.setFieldValByName("updateTime",new Date(),metaObject); |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.config; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.DbType; |
| | | import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer; |
| | | import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector; |
| | | import com.baomidou.mybatisplus.core.injector.ISqlInjector; |
| | | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; |
| | | import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor; |
| | | import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; |
| | | import org.apache.ibatis.type.EnumTypeHandler; |
| | | import org.mybatis.spring.annotation.MapperScan; |
| | | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * @author LGH |
| | | */ |
| | | @Configuration |
| | | @MapperScan({"com.yami.shop.**.dao"}) |
| | | public class MybatisPlusConfig { |
| | | |
| | | /** |
| | | * 逻辑删除插件 |
| | | * @return LogicSqlInjector |
| | | */ |
| | | @Bean |
| | | @ConditionalOnMissingBean |
| | | public ISqlInjector sqlInjector() { |
| | | return new DefaultSqlInjector(); |
| | | } |
| | | |
| | | /** |
| | | * mybatis-plus插件 |
| | | */ |
| | | @Bean |
| | | public MybatisPlusInterceptor optimisticLockerInterceptor() { |
| | | MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor(); |
| | | mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); |
| | | mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); |
| | | return mybatisPlusInterceptor; |
| | | } |
| | | |
| | | /** |
| | | * 自定义mapper 实体类之间类型处理handler |
| | | * @return |
| | | */ |
| | | @Bean |
| | | public ConfigurationCustomizer mybatisConfigurationCustomizer() { |
| | | return configuration -> { |
| | | // 注册自定义 TypeHandler |
| | | configuration.getTypeHandlerRegistry().register(Set.class, EnumTypeHandler.class); |
| | | }; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.config; |
| | | |
| | | import ma.glasnost.orika.MapperFacade; |
| | | import ma.glasnost.orika.MapperFactory; |
| | | import ma.glasnost.orika.impl.DefaultMapperFactory; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | /** |
| | | * MapperFacade 用于dto ->entity的转换 |
| | | * @author lgh |
| | | */ |
| | | @Configuration |
| | | public class OrikaConfig { |
| | | |
| | | @Bean |
| | | public MapperFactory mapperFactory() { |
| | | return new DefaultMapperFactory.Builder().build(); |
| | | } |
| | | |
| | | @Bean |
| | | public MapperFacade mapperFacade() { |
| | | return mapperFactory().getMapperFacade(); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.config; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonTypeInfo; |
| | | import com.fasterxml.jackson.databind.DeserializationFeature; |
| | | import com.fasterxml.jackson.databind.MapperFeature; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import com.fasterxml.jackson.databind.SerializationFeature; |
| | | import com.fasterxml.jackson.databind.json.JsonMapper; |
| | | import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; |
| | | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; |
| | | import com.yami.shop.common.util.SpringContextUtils; |
| | | import org.redisson.codec.JsonJacksonCodec; |
| | | import org.springframework.cache.CacheManager; |
| | | import org.springframework.cache.annotation.EnableCaching; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.data.redis.cache.RedisCacheConfiguration; |
| | | import org.springframework.data.redis.cache.RedisCacheManager; |
| | | import org.springframework.data.redis.cache.RedisCacheWriter; |
| | | import org.springframework.data.redis.connection.RedisConnectionFactory; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.data.redis.core.StringRedisTemplate; |
| | | import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; |
| | | import org.springframework.data.redis.serializer.RedisSerializationContext; |
| | | import org.springframework.data.redis.serializer.RedisSerializer; |
| | | import org.springframework.data.redis.serializer.StringRedisSerializer; |
| | | |
| | | import java.time.Duration; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * @author lgh |
| | | */ |
| | | @EnableCaching |
| | | @Configuration |
| | | public class RedisCacheConfig { |
| | | |
| | | @Bean |
| | | public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory,RedisSerializer<Object> redisSerializer) { |
| | | |
| | | RedisCacheManager redisCacheManager = new RedisCacheManager( |
| | | RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory), |
| | | // 默认策略,未配置的 key 会使用这个 |
| | | this.getRedisCacheConfigurationWithTtl(3600,redisSerializer), |
| | | // 指定 key 策略 |
| | | this.getRedisCacheConfigurationMap(redisSerializer) |
| | | ); |
| | | redisCacheManager.setTransactionAware(true); |
| | | return redisCacheManager; |
| | | } |
| | | |
| | | private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap(RedisSerializer<Object> redisSerializer) { |
| | | Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>(16); |
| | | redisCacheConfigurationMap.put("product", this.getRedisCacheConfigurationWithTtl(1800,redisSerializer)); |
| | | redisCacheConfigurationMap.put("SeckillById", this.getRedisCacheConfigurationWithTtl(10,redisSerializer)); |
| | | redisCacheConfigurationMap.put("SeckillByProdId", this.getRedisCacheConfigurationWithTtl(10,redisSerializer)); |
| | | redisCacheConfigurationMap.put("SeckillSkuBySeckillId", this.getRedisCacheConfigurationWithTtl(10,redisSerializer)); |
| | | redisCacheConfigurationMap.put("SeckillSkuById", this.getRedisCacheConfigurationWithTtl(10,redisSerializer)); |
| | | redisCacheConfigurationMap.put("SeckillGetByProdId", this.getRedisCacheConfigurationWithTtl(10,redisSerializer)); |
| | | return redisCacheConfigurationMap; |
| | | } |
| | | |
| | | private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds,RedisSerializer<Object> redisSerializer) { |
| | | |
| | | |
| | | RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig(); |
| | | redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith( |
| | | RedisSerializationContext |
| | | .SerializationPair |
| | | .fromSerializer(redisSerializer) |
| | | ).entryTtl(Duration.ofSeconds(seconds)); |
| | | |
| | | return redisCacheConfiguration; |
| | | } |
| | | |
| | | @Bean |
| | | public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory,RedisSerializer<Object> redisSerializer) { |
| | | |
| | | RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); |
| | | redisTemplate.setConnectionFactory(redisConnectionFactory); |
| | | redisTemplate.setKeySerializer(new StringRedisSerializer()); |
| | | redisTemplate.setHashKeySerializer(new StringRedisSerializer()); |
| | | redisTemplate.setValueSerializer(redisSerializer); |
| | | redisTemplate.setHashValueSerializer(redisSerializer); |
| | | redisTemplate.setEnableTransactionSupport(false); |
| | | |
| | | redisTemplate.afterPropertiesSet(); |
| | | return redisTemplate; |
| | | } |
| | | |
| | | /** |
| | | * 自定义redis序列化的机制,重新定义一个ObjectMapper.防止和MVC的冲突 |
| | | * https://juejin.im/post/5e869d426fb9a03c6148c97e |
| | | */ |
| | | @Bean |
| | | public RedisSerializer<Object> redisSerializer() { |
| | | ObjectMapper objectMapper = JsonMapper.builder().disable(MapperFeature.USE_ANNOTATIONS).build(); |
| | | // 反序列化时候遇到不匹配的属性并不抛出异常 |
| | | objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); |
| | | // 序列化时候遇到空对象不抛出异常 |
| | | objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); |
| | | // 反序列化的时候如果是无效子类型,不抛出异常 |
| | | objectMapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false); |
| | | // 不使用默认的dateTime进行序列化, |
| | | objectMapper.configure(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS, false); |
| | | // 使用JSR310提供的序列化类,里面包含了大量的JDK8时间序列化类 |
| | | objectMapper.registerModule(new JavaTimeModule()); |
| | | // 启用反序列化所需的类型信息,在属性中添加@class |
| | | objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, |
| | | JsonTypeInfo.As.PROPERTY); |
| | | // 配置null值的序列化器 |
| | | GenericJackson2JsonRedisSerializer.registerNullValueSerializer(objectMapper, null); |
| | | return new GenericJackson2JsonRedisSerializer(objectMapper); |
| | | } |
| | | |
| | | |
| | | @Bean |
| | | public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory){ |
| | | StringRedisTemplate redisTemplate = new StringRedisTemplate(redisConnectionFactory); |
| | | redisTemplate.setEnableTransactionSupport(false); |
| | | return redisTemplate; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.config; |
| | | |
| | | import java.util.HashSet; |
| | | |
| | | /** |
| | | * @author Citrus |
| | | * @date 2021/8/6 14:32 |
| | | */ |
| | | public class SensitiveWordConfig { |
| | | |
| | | private static final String SENSITIVE_WORD_SEARCH_URL = "/sys/pconfig/info/SENSITIVE_WORDS"; |
| | | private static final String WEBJARS_URL = "/webjars/**"; |
| | | private static final String API_DOCS_URL = "/v3/api-docs/**"; |
| | | private static final String DOC_URL = "/doc.html"; |
| | | private static final String CAPTCHA_URL = "/captcha.jpg"; |
| | | private static final String SAVE_CONFIG = "/sys/pconfig/save"; |
| | | /** |
| | | * excel |
| | | */ |
| | | private static final String SOLD_EXCEL = "/order/order/soldExcel"; |
| | | private static final String PL_SOLD_EXCEL = "/platform/order/soldExcel"; |
| | | private static final String SCORE_SOLD_EXCEL = "/score/order/soldExcel"; |
| | | private static final String IMPORT_USER_MODEL = "/admin/user/importUserModel"; |
| | | private static final String ADMIN_FORM_EXCEL = "/admin/form/formExcel"; |
| | | private static final String PLATFORM_FORM_EXCEL = "/platform/form/formExcel"; |
| | | private static final String EXPORT_USER = "/admin/user/exportUser"; |
| | | private static final String UN_DELIVERY_ORDER_EXCEL = "/order/order/unDeliveryOrderExcel"; |
| | | private static final String DOWNLOAD_MODEL = "/prod/prod/downloadModel"; |
| | | private static final String PLATFORM_EXPORT_PROD = "/platform/search/prod/prodExport"; |
| | | private static final String MULTISHOP_EXPORT_PROD = "/admin/search/prod/prodExport"; |
| | | private static final String GET_FIN_DETAIL_FORM = "/platform/financialManagement/getFinanDetailForm"; |
| | | private static final String GET_PAY_INFO_FORM = "/platform/account_detail/get_pay_info_form"; |
| | | private static final String GET_REFUND_INFO_FORM = "/platform/account_detail/get_refund_info_form"; |
| | | private static final String EXPORT_SHOP = "/platform/shopDetail/exportShop"; |
| | | private static final String EXPORT_SUPPLIER = "/supplier/supplier/exportSupplier"; |
| | | private static final String IMPORT_SUPPLIER = "/supplier/supplier/importExcel"; |
| | | private static final String MODEL_SUPPLIER = "/supplier/supplier/downLoadModel"; |
| | | private static final String MODEL_SUPPLIER_PROD = "/supplier/supplierProd/downLoadModel"; |
| | | private static final String IMPORT_SUPPLIER_PROD = "/supplier/supplierProd/importExcel"; |
| | | private static final String EXPORT_SUPPLIER_PROD = "/supplier/supplierProd/exportSupplierProd"; |
| | | private static final String EXPORT_STOCK_BILL_LOG = "/shop/stockBillLog/exportStockBillLog"; |
| | | private static final String EXPORT_STOCK_BILL_LOG_ITEM = "/shop/stockBillLogItem/downloadModel"; |
| | | private static final String IMPORT_STOCK_BILL_LOG_ITEM = "/shop/stockBillLogItem/importExcel"; |
| | | private static final String STOCK_FLOW_EXPORT_EXCEL = "/shop/stockBillLogItem/exportFlow"; |
| | | private static final String EXPORT_SKU = "/sku/exportSkuList"; |
| | | private static final String MODEL_TAKE_PROD = "/stock/takeStockProd/downLoadModel"; |
| | | private static final String IMPORT_TAKE_PROD = "/stock/takeStockProd/importExcel"; |
| | | private static final String EXPORT_TAKE_PROD = "/stock/takeStockProd/exportTakeStockProd"; |
| | | private static final String EXPORT_TAKE_STOCK = "/stock/takeStock/exportTakeStock"; |
| | | private static final String PURCHASES_ORDER_DOWNLOAD_MODEL = "/purchase/order/downloadModel"; |
| | | private static final String PURCHASES_ORDER_EXPORT_EXCEL = "/purchase/order/exportExcel"; |
| | | private static final String PURCHASES_ORDER_INBOUND_EXPORT = "/purchase/order/inbound/export"; |
| | | private static final String PURCHASES_ORDER_INBOUND_DOWNLOAD_MODEL = "/purchase/order/inbound/downloadModel"; |
| | | private static final String PURCHASES_ORDER_INBOUND_EXPORT_EXCEL = "/purchase/order/inbound/exportExcel"; |
| | | private static final String DISTRIBUTION_QR_CODE_INVITATION = "/p/distribution/qrCode/invitation"; |
| | | private static final String MINI_QR_CODE = "/qrcodeTicket/miniQrCode"; |
| | | private static final String CATEGORY_EXPORT = "/prod/category/export"; |
| | | private static final String MEMBER_TREND_EXPORT = "/platform/flowCustomerAnalysis/memberTrendExport"; |
| | | private static final String FLOW_ANALYSIS_EXPORT = "/platform/flowAnalysis/analysisDataExport"; |
| | | private static final String FLOW_TREND_EXPORT = "/platform/flowAnalysis/flowTrendExport"; |
| | | private static final String FLOW_SOUR_EXPORT = "/platform/flowAnalysis/flowSourExport"; |
| | | private static final String FLOW_USER_ANALYSIS_EXPORT = "/platform/flowUserAnalysis/userAnalysisDataExport"; |
| | | private static final String ACCOUNT_DETAIL_EXPORT = "/platform/accountDetail/getPayAndRefundInfoForm"; |
| | | private static final String SHOP_WALLET_PLATFORM_EXPORT = "/shop/shopWallet/getShopWalletLogForm"; |
| | | private static final String FINANCE_DETAIL_FORM_EXPORT = "/platform/financialManagement/getFinanceDetailForm"; |
| | | private static final String MULTISHOP_PROD_EFFECT_EXPORT = "/multishop/prodAnalysis/prodEffectExport"; |
| | | private static final String PLATFORM_PROD_EFFECT_EXPORT = "/platform/prodAnalysis/prodEffectExport"; |
| | | private static final String PLATFORM_PAY_AMOUNT_TOP_EXPORT = "/platform/prodAnalysis/payAmountTopExport"; |
| | | private static final String MULTISHOP_PAY_AMOUNT_TOP_EXPORT = "/multishop/prodAnalysis/payAmountTopExport"; |
| | | private static final String PROD_SURVEY_EXPORT = "/platform/prodAnalysis/prodSurveyExport"; |
| | | private static final String CUSTOMER_EXPORT = "/user/user/exportCustomer"; |
| | | private static final String CUSTOMER_IMPORT = "/user/user/importCustomerExcel"; |
| | | private static final String MEMBER_CUSTOMER_TEMPLATE_DOWNLOAD = "/user/user/downloadTemplate"; |
| | | private static final String WEB_CONFIG_INFO= "/webConfig/info/*"; |
| | | private static final String SYS_WEB_CONFIG_INFO = "/sys/webConfig/info/*"; |
| | | private static final String SEARCH_PAGE = "/search/page"; |
| | | private static final String API_SHOP_LIST = "/cps/getShopList"; |
| | | private static final String SOLD_WITHDRAWAL_EXCEL = "/cdn/Withdrawal/exportWithdrawal"; |
| | | private static final String SOLD_WITHDRAWALS_EXCEL = "/cdn/Withdrawal/exportWithdrawals"; |
| | | private static final String SOLD_RECHARGE_EXCEL = "/cdn/recharge/exportRecharge"; |
| | | /** |
| | | * 商家提现信息 |
| | | */ |
| | | private static final String EXPORT_SHOPWITHDRAWCASH = "/shop/shopWithdrawCash/exportShopWithdrawCash"; |
| | | /** |
| | | * 权限 |
| | | */ |
| | | private static final String GET_SHOP_MENU = "/sys/shopMenu/nav"; |
| | | /** |
| | | * jsapi签名 |
| | | */ |
| | | private static final String CREATE_JSAPI_SIGNATURE = "/p/wx/jsapi/createJsapiSignature"; |
| | | /** |
| | | * 导出待发货的积分订单 |
| | | */ |
| | | private static final String EXPORT_SCORE_ORDER = "/score/order/unDeliveryOrderExcel"; |
| | | /** |
| | | * 导入待发货的积分订单 |
| | | */ |
| | | private static final String IMPORT_SCORE_ORDER = "/score/order/exportOrderExcel"; |
| | | static final HashSet<String> SENSITIVE_WHITE_SET; |
| | | static { |
| | | SENSITIVE_WHITE_SET = new HashSet<>(); |
| | | SENSITIVE_WHITE_SET.add(SENSITIVE_WORD_SEARCH_URL); |
| | | SENSITIVE_WHITE_SET.add(WEBJARS_URL); |
| | | SENSITIVE_WHITE_SET.add(API_DOCS_URL); |
| | | SENSITIVE_WHITE_SET.add(DOC_URL); |
| | | SENSITIVE_WHITE_SET.add(CAPTCHA_URL); |
| | | SENSITIVE_WHITE_SET.add(SAVE_CONFIG); |
| | | SENSITIVE_WHITE_SET.add(SOLD_EXCEL); |
| | | SENSITIVE_WHITE_SET.add(PL_SOLD_EXCEL); |
| | | SENSITIVE_WHITE_SET.add(SCORE_SOLD_EXCEL); |
| | | SENSITIVE_WHITE_SET.add(IMPORT_USER_MODEL); |
| | | SENSITIVE_WHITE_SET.add(ADMIN_FORM_EXCEL); |
| | | SENSITIVE_WHITE_SET.add(PLATFORM_FORM_EXCEL); |
| | | SENSITIVE_WHITE_SET.add(EXPORT_USER); |
| | | SENSITIVE_WHITE_SET.add(UN_DELIVERY_ORDER_EXCEL); |
| | | SENSITIVE_WHITE_SET.add(DOWNLOAD_MODEL); |
| | | SENSITIVE_WHITE_SET.add(PLATFORM_EXPORT_PROD); |
| | | SENSITIVE_WHITE_SET.add(MULTISHOP_EXPORT_PROD); |
| | | SENSITIVE_WHITE_SET.add(GET_FIN_DETAIL_FORM); |
| | | SENSITIVE_WHITE_SET.add(GET_PAY_INFO_FORM); |
| | | SENSITIVE_WHITE_SET.add(GET_REFUND_INFO_FORM); |
| | | SENSITIVE_WHITE_SET.add(GET_SHOP_MENU); |
| | | SENSITIVE_WHITE_SET.add(EXPORT_SHOP); |
| | | SENSITIVE_WHITE_SET.add(IMPORT_SUPPLIER); |
| | | SENSITIVE_WHITE_SET.add(EXPORT_SUPPLIER); |
| | | SENSITIVE_WHITE_SET.add(MODEL_SUPPLIER); |
| | | SENSITIVE_WHITE_SET.add(MODEL_SUPPLIER_PROD); |
| | | SENSITIVE_WHITE_SET.add(IMPORT_SUPPLIER_PROD); |
| | | SENSITIVE_WHITE_SET.add(EXPORT_SUPPLIER_PROD); |
| | | SENSITIVE_WHITE_SET.add(EXPORT_STOCK_BILL_LOG); |
| | | SENSITIVE_WHITE_SET.add(EXPORT_STOCK_BILL_LOG_ITEM); |
| | | SENSITIVE_WHITE_SET.add(IMPORT_STOCK_BILL_LOG_ITEM); |
| | | SENSITIVE_WHITE_SET.add(CREATE_JSAPI_SIGNATURE); |
| | | SENSITIVE_WHITE_SET.add(STOCK_FLOW_EXPORT_EXCEL); |
| | | SENSITIVE_WHITE_SET.add(EXPORT_SKU); |
| | | SENSITIVE_WHITE_SET.add(MODEL_TAKE_PROD); |
| | | SENSITIVE_WHITE_SET.add(IMPORT_TAKE_PROD); |
| | | SENSITIVE_WHITE_SET.add(EXPORT_TAKE_PROD); |
| | | SENSITIVE_WHITE_SET.add(EXPORT_TAKE_STOCK); |
| | | SENSITIVE_WHITE_SET.add(PURCHASES_ORDER_DOWNLOAD_MODEL); |
| | | SENSITIVE_WHITE_SET.add(PURCHASES_ORDER_EXPORT_EXCEL); |
| | | SENSITIVE_WHITE_SET.add(PURCHASES_ORDER_INBOUND_EXPORT); |
| | | SENSITIVE_WHITE_SET.add(PURCHASES_ORDER_INBOUND_DOWNLOAD_MODEL); |
| | | SENSITIVE_WHITE_SET.add(PURCHASES_ORDER_INBOUND_EXPORT_EXCEL); |
| | | SENSITIVE_WHITE_SET.add(DISTRIBUTION_QR_CODE_INVITATION); |
| | | SENSITIVE_WHITE_SET.add(MINI_QR_CODE); |
| | | SENSITIVE_WHITE_SET.add(EXPORT_SHOPWITHDRAWCASH); |
| | | SENSITIVE_WHITE_SET.add(EXPORT_SCORE_ORDER); |
| | | SENSITIVE_WHITE_SET.add(IMPORT_SCORE_ORDER); |
| | | SENSITIVE_WHITE_SET.add(CATEGORY_EXPORT); |
| | | SENSITIVE_WHITE_SET.add(MEMBER_TREND_EXPORT); |
| | | SENSITIVE_WHITE_SET.add(FLOW_ANALYSIS_EXPORT); |
| | | SENSITIVE_WHITE_SET.add(FLOW_TREND_EXPORT); |
| | | SENSITIVE_WHITE_SET.add(FLOW_SOUR_EXPORT); |
| | | SENSITIVE_WHITE_SET.add(FLOW_USER_ANALYSIS_EXPORT); |
| | | SENSITIVE_WHITE_SET.add(ACCOUNT_DETAIL_EXPORT); |
| | | SENSITIVE_WHITE_SET.add(SHOP_WALLET_PLATFORM_EXPORT); |
| | | SENSITIVE_WHITE_SET.add(FINANCE_DETAIL_FORM_EXPORT); |
| | | SENSITIVE_WHITE_SET.add(MULTISHOP_PROD_EFFECT_EXPORT); |
| | | SENSITIVE_WHITE_SET.add(PLATFORM_PROD_EFFECT_EXPORT); |
| | | SENSITIVE_WHITE_SET.add(PLATFORM_PAY_AMOUNT_TOP_EXPORT); |
| | | SENSITIVE_WHITE_SET.add(MULTISHOP_PAY_AMOUNT_TOP_EXPORT); |
| | | SENSITIVE_WHITE_SET.add(PROD_SURVEY_EXPORT); |
| | | SENSITIVE_WHITE_SET.add(CUSTOMER_EXPORT); |
| | | SENSITIVE_WHITE_SET.add(CUSTOMER_IMPORT); |
| | | SENSITIVE_WHITE_SET.add(MEMBER_CUSTOMER_TEMPLATE_DOWNLOAD); |
| | | SENSITIVE_WHITE_SET.add(WEB_CONFIG_INFO); |
| | | SENSITIVE_WHITE_SET.add(SYS_WEB_CONFIG_INFO); |
| | | SENSITIVE_WHITE_SET.add(SEARCH_PAGE); |
| | | SENSITIVE_WHITE_SET.add(API_SHOP_LIST); |
| | | SENSITIVE_WHITE_SET.add(SOLD_WITHDRAWAL_EXCEL); |
| | | SENSITIVE_WHITE_SET.add(SOLD_WITHDRAWALS_EXCEL); |
| | | SENSITIVE_WHITE_SET.add(SOLD_RECHARGE_EXCEL); |
| | | } |
| | | |
| | | private SensitiveWordConfig() { |
| | | |
| | | } |
| | | |
| | | public static HashSet<String> getSensitiveWhiteSet() { |
| | | return SENSITIVE_WHITE_SET; |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.config; |
| | | |
| | | import com.google.gson.Gson; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | /** |
| | | * 配置 |
| | | * @author yami |
| | | */ |
| | | @Configuration |
| | | @AllArgsConstructor |
| | | public class ShopBeanConfig { |
| | | |
| | | @Bean |
| | | public Gson gson(){ |
| | | return new Gson(); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.config; |
| | | |
| | | import cn.hutool.core.lang.Snowflake; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | /** |
| | | * 雪花算法订单号生成 |
| | | * @author yami |
| | | */ |
| | | @Configuration |
| | | public class SnowflakeConfig { |
| | | |
| | | @Value("${application.datacenterId}") |
| | | private Long datacenterId; |
| | | |
| | | @Value("${application.workerId}") |
| | | private Long workerId; |
| | | |
| | | @Bean |
| | | public Snowflake snowflake() { |
| | | return new Snowflake(workerId, datacenterId); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.yami.shop.common.config; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.fasterxml.jackson.annotation.JsonIgnore; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import io.swagger.v3.oas.annotations.Hidden; |
| | | import org.apache.commons.lang3.reflect.FieldUtils; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | import org.springdoc.core.DelegatingMethodParameter; |
| | | import org.springdoc.core.GenericParameterService; |
| | | import org.springdoc.core.PropertyResolverUtils; |
| | | import org.springdoc.core.SpringDocUtils; |
| | | import org.springdoc.core.customizers.DelegatingMethodParameterCustomizer; |
| | | import org.springdoc.core.providers.ObjectMapperProvider; |
| | | import org.springdoc.core.providers.WebConversionServiceProvider; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.core.MethodParameter; |
| | | |
| | | import java.lang.annotation.Annotation; |
| | | import java.lang.reflect.Field; |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | import java.util.Optional; |
| | | import java.util.stream.Collectors; |
| | | import java.util.stream.Stream; |
| | | |
| | | @Configuration |
| | | public class SwaggerConfig { |
| | | |
| | | static { |
| | | SpringDocUtils.getConfig().addAnnotationsToIgnore(JsonIgnore.class); |
| | | } |
| | | |
| | | @Bean |
| | | public GenericParameterService parameterBuilder(PropertyResolverUtils propertyResolverUtils, Optional<WebConversionServiceProvider> optionalWebConversionServiceProvider, ObjectMapperProvider objectMapperProvider) { |
| | | return new GenericParameterService(propertyResolverUtils, delegatingMethodParameterCustomizer(), |
| | | optionalWebConversionServiceProvider,objectMapperProvider); |
| | | } |
| | | |
| | | // 解决@ParameterObject和@Hidden, JsonIgnore同时使用不生效的问题 |
| | | private Optional<DelegatingMethodParameterCustomizer> delegatingMethodParameterCustomizer() { // NOSONAR |
| | | return Optional.of((originalMethodParam, methodParam) -> { |
| | | // 这个方法类拥有的注解 |
| | | Annotation[] annotations = originalMethodParam.getParameterType().getAnnotations(); |
| | | boolean typeContainParameterObject = false; |
| | | if (annotations.length > 0) { |
| | | List<? extends Class<? extends Annotation>> annotationTypes = Arrays.stream(annotations).map(Annotation::annotationType).collect(Collectors.toList()); |
| | | typeContainParameterObject = annotationTypes.contains(ParameterObject.class); |
| | | } |
| | | |
| | | |
| | | if (typeContainParameterObject |
| | | || (originalMethodParam.hasParameterAnnotations() && originalMethodParam.hasParameterAnnotation(ParameterObject.class))) { |
| | | try { |
| | | if (isParameterIgnore(originalMethodParam, methodParam)) { |
| | | Field field = FieldUtils.getDeclaredField(DelegatingMethodParameter.class, "additionalParameterAnnotations", true); |
| | | try { |
| | | field.set(methodParam, new Annotation[] {new Hidden() { // NOSONAR |
| | | @Override |
| | | public Class<? extends Annotation> annotationType() { |
| | | return Hidden.class; |
| | | }} |
| | | }); |
| | | } catch (IllegalArgumentException|IllegalAccessException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } catch (NoSuchFieldException | SecurityException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | |
| | | private boolean isParameterIgnore(MethodParameter originalMethodParam, MethodParameter methodParam) throws NoSuchFieldException, SecurityException { |
| | | String parameterName = StrUtil.isBlank(methodParam.getParameterName())? "":methodParam.getParameterName(); |
| | | String fieldName = parameterName.indexOf('.') == -1 ? parameterName : parameterName.substring(0, parameterName.indexOf('.')); |
| | | // 解决mybatis-plus返回的查询参数污染的问题 |
| | | if (originalMethodParam.getParameterType().isAssignableFrom(PageParam.class)) { |
| | | if ("searchCount".equals(fieldName)) { |
| | | return true; |
| | | } |
| | | } |
| | | Field declaredField; |
| | | try { |
| | | declaredField = originalMethodParam.getParameterType().getDeclaredField(fieldName); |
| | | } catch (NoSuchFieldException e) { |
| | | e.printStackTrace(); |
| | | declaredField = originalMethodParam.getParameterType().getSuperclass().getDeclaredField(fieldName); |
| | | } |
| | | return Stream.of(declaredField.getAnnotations()) |
| | | .filter(annot -> Arrays.asList(Hidden.class, JsonIgnore.class).contains(annot.annotationType())).count() > 0; |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.config; |
| | | |
| | | import com.yami.shop.common.i18n.YamiLocaleChangeInterceptor; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; |
| | | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
| | | import org.springframework.web.servlet.i18n.SessionLocaleResolver; |
| | | |
| | | /** |
| | | * @author LGH |
| | | */ |
| | | @Configuration |
| | | public class WebMvcConfig { |
| | | |
| | | @Autowired |
| | | private YamiLocaleChangeInterceptor localeChangeInterceptor; |
| | | |
| | | @Bean |
| | | public WebMvcConfigurer webMvcConfigurer() { |
| | | return new WebMvcConfigurer() { |
| | | //拦截器 |
| | | @Override |
| | | public void addInterceptors(InterceptorRegistry registry) { |
| | | registry.addInterceptor(localeChangeInterceptor).addPathPatterns("/**"); |
| | | } |
| | | }; |
| | | } |
| | | |
| | | @Bean |
| | | public SessionLocaleResolver localeResolver() { |
| | | return new SessionLocaleResolver(); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.config; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * payPal支付 网络钩子常量 |
| | | * @author yami |
| | | */ |
| | | @Data |
| | | public class WebhookConstant { |
| | | |
| | | public static final String ALL_EVENTS = "ALL.EVENTS"; |
| | | public static final String BILLING_PLAN_ACTIVATED = "BILLING.PLAN.ACTIVATED"; |
| | | public static final String BILLING_PLAN_CREATED = "BILLING.PLAN.CREATED"; |
| | | public static final String BILLING_PLAN_DEACTIVATED = "BILLING.PLAN.DEACTIVATED"; |
| | | public static final String BILLING_PLAN_PRICING_CHANGE_ACTIVATED = "BILLING.PLAN.PRICING-CHANGE.ACTIVATED"; |
| | | public static final String BILLING_PLAN_PRICING_CHANGE_INPROGRESS = "BILLING.PLAN.PRICING-CHANGE.INPROGRESS"; |
| | | public static final String BILLING_PLAN_UPDATED = "BILLING.PLAN.UPDATED"; |
| | | public static final String BILLING_SUBSCRIPTION_ACTIVATED = "BILLING.SUBSCRIPTION.ACTIVATED"; |
| | | public static final String BILLING_SUBSCRIPTION_CANCELLED = "BILLING.SUBSCRIPTION.CANCELLED"; |
| | | public static final String BILLING_SUBSCRIPTION_CREATED = "BILLING.SUBSCRIPTION.CREATED"; |
| | | public static final String BILLING_SUBSCRIPTION_EXPIRED = "BILLING.SUBSCRIPTION.EXPIRED"; |
| | | public static final String BILLING_SUBSCRIPTION_PAYMENT_FAILED = "BILLING.SUBSCRIPTION.PAYMENT.FAILED"; |
| | | public static final String BILLING_SUBSCRIPTION_RE_ACTIVATED = "BILLING.SUBSCRIPTION.RE-ACTIVATED"; |
| | | public static final String BILLING_SUBSCRIPTION_RENEWED = "BILLING.SUBSCRIPTION.RENEWED"; |
| | | public static final String BILLING_SUBSCRIPTION_SUSPENDED = "BILLING.SUBSCRIPTION.SUSPENDED"; |
| | | public static final String BILLING_SUBSCRIPTION_UPDATED = "BILLING.SUBSCRIPTION.UPDATED"; |
| | | public static final String CATALOG_PRODUCT_CREATED = "CATALOG.PRODUCT.CREATED"; |
| | | public static final String CATALOG_PRODUCT_UPDATED = "CATALOG.PRODUCT.UPDATED"; |
| | | public static final String CHECKOUT_CHECKOUT_BUYER_APPROVED = "CHECKOUT.CHECKOUT.BUYER-APPROVED"; |
| | | public static final String CHECKOUT_ORDER_APPROVED = "CHECKOUT.ORDER.APPROVED"; |
| | | public static final String CHECKOUT_ORDER_COMPLETED = "CHECKOUT.ORDER.COMPLETED"; |
| | | public static final String CHECKOUT_ORDER_SAVED = "CHECKOUT.ORDER.SAVED"; |
| | | public static final String CHECKOUT_ORDER_VOIDED = "CHECKOUT.ORDER.VOIDED"; |
| | | public static final String COMPLIANCE_PROCESS_AGENT_ACTION_INITIATED = "COMPLIANCE.PROCESS.AGENT-ACTION-INITIATED"; |
| | | public static final String COMPLIANCE_PROCESS_COMPLETED = "COMPLIANCE.PROCESS.COMPLETED"; |
| | | public static final String COMPLIANCE_PROCESS_END_USER_ACTION_REQUIRED = "COMPLIANCE.PROCESS.END-USER-ACTION-REQUIRED"; |
| | | public static final String COMPLIANCE_PROCESS_EXEMPTED = "COMPLIANCE.PROCESS.EXEMPTED"; |
| | | public static final String COMPLIANCE_PROCESS_FAILED = "COMPLIANCE.PROCESS.FAILED"; |
| | | public static final String COMPLIANCE_PROCESS_NOT_APPLIED = "COMPLIANCE.PROCESS.NOT-APPLIED"; |
| | | public static final String COMPLIANCE_PROCESS_SYSTEM_ACTION_INITIATED = "COMPLIANCE.PROCESS.SYSTEM-ACTION-INITIATED"; |
| | | public static final String DISPUTES_CREATED = "DISPUTES.CREATED"; |
| | | public static final String DISPUTES_RESOLVED = "DISPUTES.RESOLVED"; |
| | | public static final String DISPUTES_UPDATED = "DISPUTES.UPDATED"; |
| | | public static final String CUSTOMER_MANAGED_ACCOUNT_CREATED = "CUSTOMER.MANAGED-ACCOUNT.CREATED"; |
| | | public static final String CUSTOMER_MANAGED_ACCOUNT_RISK_ASSESSED = "CUSTOMER.MANAGED-ACCOUNT.RISK-ASSESSED"; |
| | | public static final String CUSTOMER_MANAGED_ACCOUNT_UPDATED = "CUSTOMER.MANAGED-ACCOUNT.UPDATED"; |
| | | public static final String CUSTOMER_MERCHANT_INTEGRATION_CAPABILITY_UPDATED = "CUSTOMER.MERCHANT-INTEGRATION.CAPABILITY-UPDATED"; |
| | | public static final String CUSTOMER_MERCHANT_INTEGRATION_PRODUCT_SUBSCRIPTION_UPDATED = "CUSTOMER.MERCHANT-INTEGRATION.PRODUCT-SUBSCRIPTION-UPDATED"; |
| | | public static final String CUSTOMER_MERCHANT_INTEGRATION_SELLER_ALREADY_INTEGRATED = "CUSTOMER.MERCHANT-INTEGRATION.SELLER-ALREADY-INTEGRATED"; |
| | | public static final String CUSTOMER_MERCHANT_INTEGRATION_SELLER_CONSENT_GRANTED = "CUSTOMER.MERCHANT-INTEGRATION.SELLER-CONSENT-GRANTED"; |
| | | public static final String CUSTOMER_MERCHANT_INTEGRATION_SELLER_EMAIL_CONFIRMED = "CUSTOMER.MERCHANT-INTEGRATION.SELLER-EMAIL-CONFIRMED"; |
| | | public static final String CUSTOMER_MERCHANT_INTEGRATION_SELLER_ERROR_BAD_REQUEST = "CUSTOMER.MERCHANT-INTEGRATION.SELLER-ERROR-BAD-REQUEST"; |
| | | public static final String CUSTOMER_MERCHANT_INTEGRATION_SELLER_ERROR_INTERNAL_SERVER_ERROR = "CUSTOMER.MERCHANT-INTEGRATION.SELLER-ERROR-INTERNAL-SERVER-ERROR"; |
| | | public static final String CUSTOMER_MERCHANT_INTEGRATION_SELLER_ONBOARDING_INITIATED = "CUSTOMER.MERCHANT-INTEGRATION.SELLER-ONBOARDING-INITIATED"; |
| | | public static final String CUSTOMER_MERCHANT_INTEGRATION_SELLER_ONBOARDING_STARTED = "CUSTOMER.MERCHANT-INTEGRATION.SELLER-ONBOARDING-STARTED"; |
| | | public static final String CUSTOMER_PAYOUT_COMPLETED = "CUSTOMER.PAYOUT.COMPLETED"; |
| | | public static final String CUSTOMER_PAYOUT_FAILED = "CUSTOMER.PAYOUT.FAILED"; |
| | | public static final String CUSTOMER_USER_PROFILE_PASSWORD_CHANGED = "CUSTOMER.USER-PROFILE.PASSWORD-CHANGED"; |
| | | public static final String IDENTITY_AUTHORIZATION_CONSENT_GRANTED = "IDENTITY.AUTHORIZATION-CONSENT.GRANTED"; |
| | | public static final String IDENTITY_AUTHORIZATION_CONSENT_REVOKED = "IDENTITY.AUTHORIZATION-CONSENT.REVOKED"; |
| | | public static final String INVOICING_INVOICE_CANCELLED = "INVOICING.INVOICE.CANCELLED"; |
| | | public static final String INVOICING_INVOICE_CREATED = "INVOICING.INVOICE.CREATED"; |
| | | public static final String INVOICING_INVOICE_PAID = "INVOICING.INVOICE.PAID"; |
| | | public static final String INVOICING_INVOICE_REFUNDED = "INVOICING.INVOICE.REFUNDED"; |
| | | public static final String INVOICING_INVOICE_SCHEDULED = "INVOICING.INVOICE.SCHEDULED"; |
| | | public static final String INVOICING_INVOICE_UPDATED = "INVOICING.INVOICE.UPDATED"; |
| | | public static final String MERCHANT_ONBOARDING_COMPLETED = "MERCHANT.ONBOARDING.COMPLETED"; |
| | | public static final String MERCHANT_PARTNER_CONSENT_REVOKED = "MERCHANT.PARTNER-CONSENT.REVOKED"; |
| | | public static final String PAYMENT_NETWORKS_ALTERNATIVE_PAYMENT_COMPLETED = "PAYMENT-NETWORKS.ALTERNATIVE-PAYMENT.COMPLETED"; |
| | | public static final String PAYMENT_AUTHORIZATION_CREATED = "PAYMENT.AUTHORIZATION.CREATED"; |
| | | public static final String PAYMENT_AUTHORIZATION_VOIDED = "PAYMENT.AUTHORIZATION.VOIDED"; |
| | | public static final String PAYMENT_CAPTURE_COMPLETED = "PAYMENT.CAPTURE.COMPLETED"; |
| | | public static final String PAYMENT_CAPTURE_DENIED = "PAYMENT.CAPTURE.DENIED"; |
| | | public static final String PAYMENT_CAPTURE_PENDING = "PAYMENT.CAPTURE.PENDING"; |
| | | public static final String PAYMENT_CAPTURE_REFUNDED = "PAYMENT.CAPTURE.REFUNDED"; |
| | | public static final String PAYMENT_CAPTURE_REVERSED = "PAYMENT.CAPTURE.REVERSED"; |
| | | public static final String PAYMENT_ORDER_CANCELLED = "PAYMENT.ORDER.CANCELLED"; |
| | | public static final String PAYMENT_ORDER_CREATED = "PAYMENT.ORDER.CREATED"; |
| | | public static final String PAYMENT_PAYOUTS_ITEM_BLOCKED = "PAYMENT.PAYOUTS-ITEM.BLOCKED"; |
| | | public static final String PAYMENT_PAYOUTS_ITEM_CANCELED = "PAYMENT.PAYOUTS-ITEM.CANCELED"; |
| | | public static final String PAYMENT_PAYOUTS_ITEM_DENIED = "PAYMENT.PAYOUTS-ITEM.DENIED"; |
| | | public static final String PAYMENT_PAYOUTS_ITEM_FAILED = "PAYMENT.PAYOUTS-ITEM.FAILED"; |
| | | public static final String PAYMENT_PAYOUTS_ITEM_HELD = "PAYMENT.PAYOUTS-ITEM.HELD"; |
| | | public static final String PAYMENT_PAYOUTS_ITEM_REFUNDED = "PAYMENT.PAYOUTS-ITEM.REFUNDED"; |
| | | public static final String PAYMENT_PAYOUTS_ITEM_RETURNED = "PAYMENT.PAYOUTS-ITEM.RETURNED"; |
| | | public static final String PAYMENT_PAYOUTS_ITEM_SUCCEEDED = "PAYMENT.PAYOUTS-ITEM.SUCCEEDED"; |
| | | public static final String PAYMENT_PAYOUTS_ITEM_UNCLAIMED = "PAYMENT.PAYOUTS-ITEM.UNCLAIMED"; |
| | | public static final String PAYMENT_PAYOUTSBATCH_DENIED = "PAYMENT.PAYOUTSBATCH.DENIED"; |
| | | public static final String PAYMENT_PAYOUTSBATCH_PROCESSING = "PAYMENT.PAYOUTSBATCH.PROCESSING"; |
| | | public static final String PAYMENT_PAYOUTSBATCH_SUCCESS = "PAYMENT.PAYOUTSBATCH.SUCCESS"; |
| | | public static final String PAYMENT_REFUND_COMPLETED = "PAYMENT.REFUND.COMPLETED"; |
| | | public static final String PAYMENT_SALE_COMPLETED = "PAYMENT.SALE.COMPLETED"; |
| | | public static final String PAYMENT_SALE_DENIED = "PAYMENT.SALE.DENIED"; |
| | | public static final String PAYMENT_SALE_PENDING = "PAYMENT.SALE.PENDING"; |
| | | public static final String PAYMENT_SALE_REFUNDED = "PAYMENT.SALE.REFUNDED"; |
| | | public static final String PAYMENT_SALE_REVERSED = "PAYMENT.SALE.REVERSED"; |
| | | public static final String PAYMENTS_PAYMENT_CREATED = "PAYMENTS.PAYMENT.CREATED"; |
| | | public static final String PAYMENT_NETWORKS_INSTRUMENT_LINKED_ACCOUNT_UPDATED = "PAYMENT.NETWORKS.INSTRUMENT.LINKED-ACCOUNT-UPDATED"; |
| | | public static final String RISK_DISPUTE_CREATED = "RISK.DISPUTE.CREATED"; |
| | | public static final String VAULT_CREDIT_CARD_CREATED = "VAULT.CREDIT-CARD.CREATED"; |
| | | public static final String VAULT_CREDIT_CARD_DELETED = "VAULT.CREDIT-CARD.DELETED"; |
| | | public static final String VAULT_CREDIT_CARD_UPDATED = "VAULT.CREDIT-CARD.UPDATED"; |
| | | public static final String VAULT_PAYMENT_TOKEN_CREATED = "VAULT.PAYMENT-TOKEN.CREATED"; |
| | | public static final String VAULT_PAYMENT_TOKEN_DELETED = "VAULT.PAYMENT-TOKEN.DELETED"; |
| | | public static final String VAULT_PAYMENT_TOKEN_DELETION_INITIATED = "VAULT.PAYMENT-TOKEN.DELETION-INITIATED"; |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.constants; |
| | | |
| | | /** |
| | | * @Author lth |
| | | * @Date 2021/8/17 13:09 |
| | | */ |
| | | public interface CacheNames extends ProductCacheNames, ShopCacheNames { |
| | | /** |
| | | * |
| | | * 参考CacheKeyPrefix |
| | | * cacheNames 与 key 之间的默认连接字符 |
| | | */ |
| | | String UNION = "::"; |
| | | /** |
| | | * key内部的连接字符(自定义) |
| | | */ |
| | | String UNION_KEY = ":"; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.constants; |
| | | |
| | | |
| | | /** |
| | | * pcdn常量 |
| | | * |
| | | * @author yami |
| | | */ |
| | | public class DictConstant { |
| | | |
| | | //售卖状态(1:发起售卖,2:处理中 3:交易完成 4:锁定 5取消) |
| | | public static final String PRODUCT_STATUS_1 = "1"; |
| | | public static final String PRODUCT_STATUS_2 = "2"; |
| | | public static final String PRODUCT_STATUS_3 = "3"; |
| | | public static final String PRODUCT_STATUS_4 = "4"; |
| | | public static final String PRODUCT_STATUS_5 = "5"; |
| | | |
| | | //求购状态(1:发起求购,2:处理中 3:交易完成 4:锁定 5.取消) |
| | | public static final String WANT_STATUS_1 = "1"; |
| | | public static final String WANT_STATUS_2 = "2"; |
| | | public static final String WANT_STATUS_3 = "3"; |
| | | public static final String WANT_STATUS_4 = "4"; |
| | | public static final String WANT_STATUS_5 = "5"; |
| | | |
| | | //订单状态(1:处理中 2:交易成功 3:交易失败 4:订单锁定 5订单取消 6.订单超时) |
| | | public static final String ORDER_STATUS_1 = "1"; |
| | | public static final String ORDER_STATUS_2 = "2"; |
| | | public static final String ORDER_STATUS_3 = "3"; |
| | | public static final String ORDER_STATUS_4 = "4"; |
| | | public static final String ORDER_STATUS_5 = "5"; |
| | | public static final String ORDER_STATUS_6 = "6"; |
| | | |
| | | //寄售等级 |
| | | public static final String TRAN_LEVEL_1 = "1"; |
| | | public static final String TRAN_LEVEL_2 = "2"; |
| | | public static final String TRAN_LEVEL_3 = "3"; |
| | | public static final String TRAN_LEVEL_4 = "4"; |
| | | public static final String TRAN_LEVEL_5 = "5"; |
| | | public static final String OTRAN_LEVEL_6 = "6"; |
| | | public static final String OTRAN_LEVEL_7 = "7"; |
| | | |
| | | //币种(8:流量,9金牛豆 10:幸运池 11:积分) |
| | | public static final Integer WALLET_ID_8 = 8; |
| | | public static final Integer WALLET_ID_9 = 9; |
| | | public static final Integer WALLET_ID_10 = 10; |
| | | public static final Integer WALLET_ID_11 = 11; |
| | | |
| | | //方式(1:支付宝,2:微信 3:银行卡 ) |
| | | public static final String PAY_TYPE_1 = "1"; |
| | | public static final String PAY_TYPE_2 = "2"; |
| | | public static final String PAY_TYPE_3 = "3"; |
| | | |
| | | //流水类型 25:转换(红--绿)26:刮刮卡绑定兑换绿积分 27:寄售交易 28 金牛豆转换幸运池) |
| | | public static final Integer FLOWNAME_ID_25 = 25; |
| | | public static final Integer FLOWNAME_ID_26 = 26; |
| | | public static final Integer FLOWNAME_ID_27 = 27; |
| | | public static final Integer FLOWNAME_ID_28 = 28; |
| | | public static final Integer FLOWNAME_ID_30 = 30; |
| | | public static final Integer FLOWNAME_ID_50 = 50; |
| | | |
| | | //激活状态(0:未激活,1:已激活) |
| | | public static final String ACTIVE_STATUS_0 = "0"; |
| | | public static final String ACTIVE_STATUS_1 = "1"; |
| | | |
| | | //是否(0:否,1:1) |
| | | public static final String ISNO_0 = "0"; |
| | | public static final String ISNO_1 = "1"; |
| | | |
| | | //类型(1,单人,2. 多人) |
| | | public static final String TYPE_1 = "1"; |
| | | public static final String TYPE_2 = "2"; |
| | | |
| | | //常量1 |
| | | public static final String CONSTANT_1 = "1"; |
| | | //常量1 |
| | | public static final String CONSTANT_5 = "5"; |
| | | public static final String CONSTANT_1000 = "1000"; |
| | | public static final String CONSTANT_5000 = "5000"; |
| | | public static final String CONSTANT_100 = "100"; |
| | | //流量提现手续费 |
| | | public static final String RED_WITHDRAWAL_FEE = "red_withdrawal_fee"; |
| | | //流量转金牛豆兑换比例(100:110) |
| | | public static final String RED_CHANGE_GREEN_FEE = "red_change_green_fee"; |
| | | //提现平台扣除手续费 |
| | | public static final String PLAN_HAND_FEE = "plan_hand_fee"; |
| | | //平台提现时间(1=1号) |
| | | public static final String PLAT_WITH_TIME = "plat_with_time"; |
| | | //寄售模式交易费用 |
| | | public static final String TRAN_FEE = "tran_fee"; |
| | | //刮刮卡序列号 |
| | | public static final String HAND_CARD_SEQ = "hand_card_seq"; |
| | | //寄售模式(最大交易额度) |
| | | public static final String MAX_TRAN_NUM = "max_tran_num"; |
| | | //寄售模式(最小交易额度) |
| | | public static final String MIN_TRAN_NUM = "min_tran_num"; |
| | | //合同模板存放地址 |
| | | public static final String CONTRACT_MODEL_URL = "contract_model_url"; |
| | | //合同存放地址 |
| | | public static final String CONTRACT_URL = "contract_url"; |
| | | //金牛豆兑换幸运池比例 |
| | | public static final String POINT_SJ_BS = "point_sj_bs"; |
| | | |
| | | //域名 |
| | | public static final String DONAME_URL = "https://www.huoxingsuanli.cn"; |
| | | //pdf访问路径 |
| | | public static final String PDF_URL = "/pdf/concat/"; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.constants; |
| | | |
| | | |
| | | /** |
| | | * 配置缓存名字 |
| | | * |
| | | * @author lhd |
| | | * @date 2020/12/30 |
| | | */ |
| | | public interface EsCacheNames { |
| | | /** |
| | | * 装修商品ids缓存名称和缓存失效时间 |
| | | */ |
| | | String RENOVATION_PRODUCT_IDS_CACHE = "renovationProductIdsCache"; |
| | | Integer RENOVATION_PRODUCT_IDS_CACHE_TIME = 300; |
| | | Integer RENOVATION_PRODUCT_IDS_LIMIT = 1000; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.constants; |
| | | |
| | | /** |
| | | * @author FrozenWatermelon |
| | | * @date 2020/11/23 |
| | | */ |
| | | public interface OauthCacheNames { |
| | | |
| | | /** |
| | | * oauth 授权相关key |
| | | */ |
| | | String OAUTH_PREFIX = "mall4j_oauth:"; |
| | | |
| | | /** |
| | | * token 授权相关key |
| | | */ |
| | | String OAUTH_TOKEN_PREFIX = OAUTH_PREFIX + "token:"; |
| | | |
| | | /** |
| | | * 保存token 缓存使用key |
| | | */ |
| | | String ACCESS = OAUTH_TOKEN_PREFIX + "access:"; |
| | | |
| | | /** |
| | | * 刷新token 缓存使用key |
| | | */ |
| | | String REFRESH_TO_ACCESS = OAUTH_TOKEN_PREFIX + "refresh_to_access:"; |
| | | |
| | | /** |
| | | * 根据uid获取保存的token key缓存使用的key |
| | | */ |
| | | String UID_TO_ACCESS = OAUTH_TOKEN_PREFIX + "uid_to_access:"; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.constants; |
| | | |
| | | /** |
| | | * @author FrozenWatermelon |
| | | * @date 2020/11/23 |
| | | */ |
| | | public interface OrderCacheNames { |
| | | /** |
| | | * |
| | | * 参考CacheKeyPrefix |
| | | * cacheNames 与 key 之间的默认连接字符 |
| | | */ |
| | | String UNION = "::"; |
| | | |
| | | |
| | | /** |
| | | * 普通确认订单信息缓存 |
| | | */ |
| | | String ORDER_CONFIRM_KEY = "order:confirm:"; |
| | | |
| | | /** |
| | | * 普通订单uuid |
| | | */ |
| | | String ORDER_CONFIRM_UUID_KEY = "order:uuid_confirm:"; |
| | | |
| | | /** |
| | | * 拼团确认订单信息缓存 |
| | | */ |
| | | String GROUP_ORDER_CONFIRM_KEY = "group_order:confirm:"; |
| | | |
| | | /** |
| | | * 拼团订单uuid |
| | | */ |
| | | String GROUP_ORDER_CONFIRM_UUID_KEY = "group_order:uuid_confirm:"; |
| | | /** |
| | | * 秒杀确认订单信息缓存 |
| | | */ |
| | | String SECKILL_ORDER_CONFIRM_KEY = "seckill_order:confirm:"; |
| | | |
| | | /** |
| | | * 秒杀订单uuid |
| | | */ |
| | | String SECKILL_ORDER_CONFIRM_UUID_KEY = "seckill_order:uuid_confirm:"; |
| | | |
| | | /** |
| | | * 积分确认订单信息缓存 |
| | | */ |
| | | String SCORE_ORDER_CONFIRM_KEY = "score_order:confirm:"; |
| | | |
| | | /** |
| | | * 积分订单uuid |
| | | */ |
| | | String SCORE_ORDER_CONFIRM_UUID_KEY = "score_order:uuid_confirm:"; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.constants; |
| | | |
| | | |
| | | /** |
| | | * pcdn常量 |
| | | * |
| | | * @author yami |
| | | */ |
| | | public class PCDNConstant { |
| | | |
| | | // pcdn token key |
| | | public static final String PCDN_TOKEN_CONSTANT = "pcdn-key:"; |
| | | |
| | | // pcdn api接口返回成功状态 |
| | | public static final Integer PCDN_API_RESPONSE_CODE = 1000; |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.constants; |
| | | |
| | | |
| | | /** |
| | | * paypal支付常量 |
| | | * @author yami |
| | | */ |
| | | public class PaypalConstant { |
| | | /** |
| | | * PayPal 取消支付回调地址 |
| | | */ |
| | | public static final String PAYPAL_CANCEL_URL = "/notice/pay/paypal/cancel"; |
| | | /** |
| | | * PayPal 取消支付回调地址 |
| | | */ |
| | | public static final String PAYPAL_SUCCESS_URL = "/notice/pay/paypal/success"; |
| | | |
| | | /** |
| | | * 当前货币币种简称, 默认为人名币的币种 EUR CNY USD |
| | | * 默认为美元币种 |
| | | */ |
| | | public static final String CURRENTCY = "USD"; |
| | | /** |
| | | * approval_url 验证url |
| | | */ |
| | | public static final String APPROVAL_URL = "approval_url"; |
| | | |
| | | /** |
| | | * approved 获准 |
| | | */ |
| | | public static final String APPROVED = "approved"; |
| | | /** |
| | | * sandbox 沙箱or live生产 |
| | | */ |
| | | public static final String PAYPAL_MODE = "live"; |
| | | |
| | | public static final String CAPTURE = "CAPTURE"; |
| | | /** |
| | | * 该标签将覆盖PayPal网站上PayPal帐户中的公司名称 |
| | | */ |
| | | public static final String BRANDNAME = "Supernote"; |
| | | /** |
| | | * LOGIN。当客户单击PayPal Checkout时,客户将被重定向到页面以登录PayPal并批准付款。 |
| | | * BILLING。当客户单击PayPal Checkout时,客户将被重定向到一个页面,以输入信用卡或借记卡以及完成购买所需的其他相关账单信息 |
| | | * NO_PREFERENCE。当客户单击“ PayPal Checkout”时,将根据其先前的交互方式将其重定向到页面以登录PayPal并批准付款,或重定向至页面以输入信用卡或借记卡以及完成购买所需的其他相关账单信息使用PayPal。 |
| | | * 默认值:NO_PREFERENCE |
| | | */ |
| | | public static final String LANDINGPAGE = "NO_PREFERENCE"; |
| | | /** |
| | | * CONTINUE。将客户重定向到PayPal付款页面后,将出现“ 继续”按钮。当结帐流程启动时最终金额未知时,请使用此选项,并且您想将客户重定向到商家页面而不处理付款。 |
| | | * PAY_NOW。将客户重定向到PayPal付款页面后,出现“ 立即付款”按钮。当启动结帐时知道最终金额并且您要在客户单击“ 立即付款”时立即处理付款时,请使用此选项。 |
| | | */ |
| | | public static final String USERACTION = "PAY_NOW"; |
| | | /** |
| | | * GET_FROM_FILE。使用贝宝网站上客户提供的送货地址。 |
| | | * NO_SHIPPING。从PayPal网站编辑送货地址。推荐用于数字商品 |
| | | * SET_PROVIDED_ADDRESS。使用商家提供的地址。客户无法在PayPal网站上更改此地址 |
| | | */ |
| | | public static final String SHIPPINGPREFERENCE = "SET_PROVIDED_ADDRESS"; |
| | | |
| | | public static final String COMPLETED = "COMPLETED"; |
| | | |
| | | /** |
| | | * 交易异常 |
| | | */ |
| | | public static final String FAILURE = "failure"; |
| | | /** |
| | | * 交易成功 |
| | | */ |
| | | public static final String SUCCESS = "success"; |
| | | |
| | | /** |
| | | * ipn回调。支付成功 |
| | | */ |
| | | public static final String PAYMENT_STATUS_COMPLETED = "Completed"; |
| | | /** |
| | | * ipn回调。退款成功 |
| | | */ |
| | | public static final String PAYMENT_STATUS_REFUNDED = "Refunded"; |
| | | /** |
| | | * ipn回调。待定 |
| | | */ |
| | | public static final String PAYMENT_STATUS_PENDING = "Pending"; |
| | | |
| | | /** |
| | | * ipn回调,付款因退款或其他类型的冲销而被冲销。资金已从您的帐户余额中删除,并退还给买方 |
| | | */ |
| | | public static final String PAYMENT_STATUS_REVERSED = "Reversed"; |
| | | |
| | | /** |
| | | * ipn回调, 撤销已被取消。例如,您赢得了与客户的纠纷,并且撤回的交易资金已退还给您 |
| | | */ |
| | | public static final String PAYMENT_STATUS_CANCELED_REVERSAL = "Canceled_Reversal"; |
| | | |
| | | /** |
| | | * ipn回调,付款被拒绝 |
| | | */ |
| | | public static final String PAYMENT_STATUS_DENIED = "Denied"; |
| | | |
| | | /** |
| | | * ipn回调, 此授权已过期,无法捕获 |
| | | */ |
| | | public static final String PAYMENT_STATUS_EXPIRED = "Expired"; |
| | | |
| | | /** |
| | | * ipn回调, 德国的ELV付款是通过Express Checkout进行的 |
| | | */ |
| | | public static final String PAYMENT_STATUS_CREATED = "Created"; |
| | | |
| | | /** |
| | | * ipn回调, 付款失败。仅当付款是通过您客户的银行帐户进行的。 |
| | | */ |
| | | public static final String PAYMENT_STATUS_FAILED = "Failed"; |
| | | |
| | | /** |
| | | * ipn回调,付款已被接受 |
| | | */ |
| | | public static final String PAYMENT_STATUS_PROCESSED = "Processed"; |
| | | |
| | | /** |
| | | * ipn回调,此授权已失效 |
| | | */ |
| | | public static final String PAYMENT_STATUS_VOIDED = "Voided"; |
| | | |
| | | //订单状态 |
| | | /** |
| | | * 1、支付完成;捕获的付款的资金已记入收款人的PayPal帐户 |
| | | * 2、退款完成;该交易的资金已记入客户的帐户 |
| | | */ |
| | | public static final String STATE_COMPLETED = "COMPLETED"; |
| | | /** |
| | | * 部分退款;少于所捕获付款金额的金额已部分退还给付款人。 |
| | | */ |
| | | public static final String STATE_PARTIALLY_REFUNDED = "PARTIALLY_REFUNDED"; |
| | | |
| | | |
| | | /** |
| | | * 1、支付待定;捕获的付款资金尚未记入收款人的PayPal帐户。有关更多信息请参见status.details。 |
| | | * 2、退款待定;有关更多信息,请参见status_details.reason。 |
| | | */ |
| | | /** |
| | | * 支付待定: |
| | | * capture_status_details |
| | | * reason 枚举 |
| | | * 捕获的付款状态为PENDING或DENIED的原因。可能的值为: |
| | | * BUYER_COMPLAINT。付款人与贝宝(PayPal)对此捕获的付款提出了争议。 |
| | | * CHARGEBACK。响应于付款人与用于支付此已捕获付款的金融工具的发行人对此已捕获的付款提出异议,已收回的资金被撤回。 |
| | | * ECHECK。由尚未结清的电子支票支付的付款人。 |
| | | * INTERNATIONAL_WITHDRAWAL。访问您的在线帐户。在您的“帐户概览”中,接受并拒绝此笔付款。 |
| | | * OTHER。无法提供其他特定原因。有关此笔付款的更多信息,请在线访问您的帐户或联系PayPal。 |
| | | * PENDING_REVIEW。捕获的付款正在等待人工审核。 |
| | | *(手动收取)RECEIVING_PREFERENCE_MANDATES_MANUAL_ACTION。收款人尚未为其帐户设置适当的接收首选项。有关如何接受或拒绝此付款的更多信息,请在线访问您的帐户。通常在某些情况下提供此原因,例如,当所捕获付款的货币与收款人的主要持有货币不同时。 |
| | | * REFUNDED。收回的资金已退还。 |
| | | * TRANSACTION_APPROVED_AWAITING_FUNDING。付款人必须将这笔付款的资金汇出。通常,此代码适用于手动EFT。 |
| | | * UNILATERAL。收款人没有PayPal帐户。 |
| | | * VERIFICATION_REQUIRED。收款人的PayPal帐户未通过验证。 |
| | | */ |
| | | /** |
| | | * 退款待定 |
| | | * 退款具有“PENDING”或“FAILED”状态的原因。 可能的值为: |
| | | * ECHECK。客户的帐户通过尚未结清的eCheck进行注资。 |
| | | */ |
| | | public static final String STATE_PENDING = "PENDING"; |
| | | /** |
| | | * 退款;大于或等于此捕获的付款金额的金额已退还给付款人 |
| | | */ |
| | | public static final String STATE_REFUNDED = "REFUNDED"; |
| | | /** |
| | | * 支付拒绝 |
| | | */ |
| | | public static final String STATE_DENIED = "DENIED"; |
| | | /** |
| | | * 退款失败 |
| | | */ |
| | | public static final String STATE_FAILED = "FAILED"; |
| | | |
| | | /** |
| | | * 争议状态 |
| | | */ |
| | | public static final String BUYER_COMPLAINT = "BUYER_COMPLAINT"; |
| | | |
| | | /** |
| | | * 沙箱环境请求网关地址 |
| | | */ |
| | | public static final String SANDBOX = "https://api-m.sandbox.paypal.com"; |
| | | /** |
| | | * 生产环境请求网关地址 |
| | | */ |
| | | public static final String LIVE = "https://api.paypal.com"; |
| | | /** |
| | | * 添加物流信息请求路径 |
| | | */ |
| | | public static final String ADD_TRACK_URL = "/v1/shipping/trackers-batch"; |
| | | |
| | | /** |
| | | * 修改物流信息请求路径 |
| | | */ |
| | | public static final String UPDATE_TRACK_URL = "/v1/shipping/trackers/"; |
| | | |
| | | public static final String REFUNDED = "Refunded"; |
| | | public static final String PENDING = "Pending"; |
| | | |
| | | public static final String VERIFIED = "VERIFIED"; |
| | | /** |
| | | * 验签地址 |
| | | * 沙箱: https://www.sandbox.paypal.com/cgi-bin/webscr |
| | | * 正式: https://www.paypal.com/cgi-bin/webscr |
| | | */ |
| | | public final static String PAY_URL = "https://www.sandbox.paypal.com/cgi-bin/webscr"; |
| | | |
| | | public final static String CMD_XCLICK = "_xclick"; |
| | | |
| | | public final static String CMD_NOTIFY_VALIDATE = "_notify-validate"; |
| | | |
| | | /** 生成发票二维码地址 */ |
| | | public final static String INVOICES_QR_CODE_URL = "/v2/invoicing/invoices/{invoice_id}/generate-qr-code"; |
| | | /** 生成发票二维码 的高度*/ |
| | | public final static Integer INVOICES_QR_CODE_HEIGHT = 400; |
| | | /** 生成发票二维码 的宽度*/ |
| | | public final static Integer INVOICES_QR_CODE_WIDTH = 400; |
| | | |
| | | /** payPal网络钩子超出限制 */ |
| | | public final static String WEBHOOK_NUMBER_LIMIT_EXCEEDED = "WEBHOOK_NUMBER_LIMIT_EXCEEDED"; |
| | | |
| | | //币种 |
| | | public final static String WALLET_ID_1 = "1"; |
| | | public final static String WALLET_ID_2 = "2"; |
| | | public final static String WALLET_ID_3 = "3"; |
| | | public final static String WALLET_ID_4 = "4"; |
| | | public final static String WALLET_ID_5 = "5"; |
| | | public final static String WALLET_ID_6 = "6"; |
| | | public final static String WALLET_ID_7 = "7"; |
| | | public final static String WALLET_ID_8 = "8"; |
| | | |
| | | //支付方式 |
| | | public final static String PAY_TYPE_1 = "1"; |
| | | public final static String PAY_TYPE_2 = "2"; |
| | | public final static String PAY_TYPE_3 = "3"; |
| | | public final static String PAY_TYPE_4 = "4"; |
| | | public final static String PAY_TYPE_5 = "5"; |
| | | public final static String PAY_TYPE_6 = "6"; |
| | | public final static String PAY_TYPE_7 = "7"; |
| | | public final static String PAY_TYPE_8 = "8"; |
| | | public final static String PAY_TYPE_9 = "9"; |
| | | public final static String PAY_TYPE_10 = "10"; |
| | | public final static String PAY_TYPE_11 = "11"; |
| | | public final static String PAY_TYPE_12 = "12"; |
| | | public final static String PAY_TYPE_13 = "13"; |
| | | public final static String PAY_TYPE_14 = "14"; |
| | | public final static String PAY_TYPE_15 = "15"; |
| | | public final static String PAY_TYPE_16 = "16"; |
| | | public final static String PAY_TYPE_17 = "17"; |
| | | public final static String PAY_TYPE_18 = "18"; |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.constants; |
| | | |
| | | /** |
| | | * @author FrozenWatermelon |
| | | * @date 2020/11/23 |
| | | */ |
| | | public interface ProductCacheNames { |
| | | |
| | | /** |
| | | * 前缀 |
| | | */ |
| | | String PRODUCT_PREFIX = "mall4cloud_product:"; |
| | | |
| | | /** |
| | | * 用户端分类列表缓存key |
| | | */ |
| | | String CATEGORY_INFO = PRODUCT_PREFIX + "category:info:"; |
| | | /** |
| | | * 根据店铺id和上级id,获取分类列表缓存key |
| | | */ |
| | | String CATEGORY_RATE = PRODUCT_PREFIX + "category:category_rate:"; |
| | | /** |
| | | * 购物车商品数量 |
| | | */ |
| | | String SHOP_CART_ITEM_COUNT = "shop_cart:count:"; |
| | | |
| | | /** |
| | | * 获取商品的缓存key |
| | | */ |
| | | String PRODUCT_KEY = "product"; |
| | | |
| | | /** |
| | | * 获取商品扩展信息的缓存key |
| | | */ |
| | | String PROD_EXTENSION_INFO_KEY = "prodExtensionInfo"; |
| | | |
| | | |
| | | /** |
| | | * 根据skuId获取sku的缓存key |
| | | */ |
| | | String SKU_KEY = "sku"; |
| | | |
| | | /** |
| | | * 获取sku列表的缓存key |
| | | */ |
| | | String SKU_LIST_KEY = "skuList"; |
| | | |
| | | /** |
| | | * 获取sku库存列表的缓存key |
| | | */ |
| | | String LIST_SKU_STOCK_KEY = "listSkuStock"; |
| | | |
| | | /** |
| | | * 店铺获取签约的所有分类列表 |
| | | */ |
| | | String LIST_SIGNING_CATEGORY_BY_SHOP_ID = "category_shop:list_signing:"; |
| | | /** |
| | | * 店铺签约的可用分类列表(发布商品时使用) |
| | | */ |
| | | String LIST_AVAILABLE_SIGNING_CATEGORY_BY_SHOP_ID = "category_shop:list_available:"; |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.constants; |
| | | |
| | | |
| | | /** |
| | | * pcdn常量 |
| | | * |
| | | * @author yami |
| | | */ |
| | | public class ResultMsg { |
| | | |
| | | //流量不足 |
| | | public static final String REDRUDY_INSU = "流量不足!"; |
| | | //金牛豆不足 |
| | | public static final String GREEN_INSU = "金牛豆不足!"; |
| | | //单日取消订单已经达到三次,请明天开始交易 |
| | | public static final String DAY_CACEL_INSU = "单日取消订单已经达到三次,请明天开始交易!"; |
| | | //流量转换金牛豆 |
| | | public static final String RED_TRAN_GREEN = "流量转换金牛豆"; |
| | | //流量转换金牛豆 |
| | | public static final String C2C_TRAN = "c2c交易"; |
| | | //绑定刮刮卡兑换金牛豆 |
| | | public static final String BAND_TRAN_GREEN = "绑定刮刮卡兑换金牛豆"; |
| | | //流量转换金牛豆 |
| | | public static final String ACTIVE_TRAN_ADVERT = "金牛豆激活广告"; |
| | | //流量转换金牛豆 |
| | | public static final String GREEM_TRAN_LUCK = "金牛豆转换幸运池"; |
| | | //流量已抢空,无法发起订单! |
| | | public static final String RED_TRAN_EMPTY = "流量已抢空,无法发起订单!"; |
| | | //有业务正在处理,无法取消! |
| | | public static final String BUSSINESS_BEING = "有业务正在处理,无法取消!"; |
| | | //用户锁定状态,无法操作! |
| | | public static final String USER_LOCK_CANOT_OPER = "用户锁定状态,无法操作!"; |
| | | //当前用户等级无法操作! |
| | | public static final String USER_LEVE_CANOT_OPER = "当前用户等级无法操作!"; |
| | | //请先进行实名认证! |
| | | public static final String USER_AUTHCATION= "请先进行实名认证!"; |
| | | public static final String EXCHANGE_MONEYIS_EMPTY= "兑换金额为空!"; |
| | | public static final String ERROR_HUNDRED= "请输入整百的倍数!"; |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.constants; |
| | | |
| | | /** |
| | | * @Author lth |
| | | * @Date 2021/8/17 13:09 |
| | | */ |
| | | public interface ShopCacheNames { |
| | | String SHOP_DETAIL_ID_KEY = "shop_detail"; |
| | | } |
New file |
| | |
| | | package com.yami.shop.common.enums; |
| | | |
| | | /** |
| | | * 统一的enum接口 |
| | | * 实现该接口 统一处理枚举类和实体类映射 |
| | | */ |
| | | public interface CodeBaseEnum { |
| | | |
| | | Integer getValue(); |
| | | String getDesc(); |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.enums; |
| | | |
| | | |
| | | /** |
| | | * 装修商品排序 |
| | | * @author lhd |
| | | * @date 2023/01/30 |
| | | */ |
| | | public enum EsRenovationProductSortEnum { |
| | | |
| | | /** |
| | | * 上架时间升序 |
| | | */ |
| | | CREATE_TIME_ASC(0, "createTime"), |
| | | |
| | | /** |
| | | * 上架时间降序 |
| | | */ |
| | | CREATE_TIME_DESC(1, "createTime"), |
| | | |
| | | /** |
| | | * 销量倒序 |
| | | */ |
| | | SALE_NUM_DESC(2, "saleNum"), |
| | | |
| | | /** |
| | | * 销量正序 |
| | | */ |
| | | SALE_NUM_ASC(3, "saleNum"), |
| | | |
| | | /** |
| | | * 评论数量倒序 |
| | | */ |
| | | COMMENT_NUM_DESC(4, "commentNum"), |
| | | |
| | | /** |
| | | * 评论数量正序 |
| | | */ |
| | | COMMENT_NUM_ASC(5, "commentNum"), |
| | | ; |
| | | |
| | | private final Integer value; |
| | | |
| | | private final String param; |
| | | |
| | | |
| | | public Integer value() { |
| | | return value; |
| | | } |
| | | |
| | | EsRenovationProductSortEnum(Integer value, String param) { |
| | | this.value = value; |
| | | this.param = param; |
| | | } |
| | | |
| | | public String param() { |
| | | return param; |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.common.enums; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 幸运币 |
| | | */ |
| | | public enum LuckyCoinEnum { |
| | | /** |
| | | * 应交最低幸运币数额 |
| | | */ |
| | | TechnicianAmount(3000L),ShopAmount(4000L),LifeShopAmount(5000L); |
| | | |
| | | |
| | | private final Long value; |
| | | |
| | | // 构造方法 |
| | | LuckyCoinEnum(Long value) { |
| | | this.value = value; |
| | | } |
| | | |
| | | // Getter方法 |
| | | public Long getValue() { |
| | | return value; |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.enums; |
| | | |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 支付类型 |
| | | * @author yami |
| | | */ |
| | | public enum PayType { |
| | | |
| | | /** 积分支付*/ |
| | | SCOREPAY(0,"积分支付"), |
| | | |
| | | /** 微信支付*/ |
| | | WECHATPAY(1,"小程序支付"), |
| | | |
| | | /** 支付宝*/ |
| | | ALIPAY(2,"支付宝"), |
| | | |
| | | /** 微信扫码支付*/ |
| | | WECHATPAY_SWEEP_CODE(3,"微信扫码支付"), |
| | | |
| | | /** 微信H5支付*/ |
| | | WECHATPAY_H5(4,"微信H5支付"), |
| | | |
| | | /** 微信公众号*/ |
| | | WECHATPAY_MP(5,"微信公众号支付"), |
| | | |
| | | /** 支付宝H5支付*/ |
| | | ALIPAY_H5(6,"支付宝H5支付"), |
| | | |
| | | /** 支付宝APP支付*/ |
| | | ALIPAY_APP(7,"支付宝APP支付"), |
| | | |
| | | /** 微信APP支付*/ |
| | | WECHATPAY_APP(8,"微信APP支付"), |
| | | |
| | | /** 余额支付*/ |
| | | BALANCE(9,"余额支付"), |
| | | |
| | | /** paypal支付 */ |
| | | PAYPAL(10,"paypal支付"), |
| | | |
| | | /** 杉德付款码支付(主扫) */ |
| | | SDPAY(11,"杉德付款码支付"), |
| | | |
| | | /** 杉德收银台统一下单 */ |
| | | SDSYTPAY(12,"杉德收银台统一下单"), |
| | | |
| | | /** 瓜瓜豆支付 **/ |
| | | BEAN(13,"瓜瓜豆支付"), |
| | | BLUEPOINT(14,"蓝积分支付"), |
| | | BLUEREDPOINT(15,"蓝积分+红积分支付"), |
| | | BLUEBALANCEPOINT(16,"蓝积分+余额支付"), |
| | | REDPOINT(17,"红积分支付"), |
| | | SDPEOPLEPAY(18,"杉德宝支付"); |
| | | |
| | | private final Integer num; |
| | | |
| | | private final String payTypeName; |
| | | |
| | | public Integer value() { |
| | | return num; |
| | | } |
| | | |
| | | public String payTypeName() {return payTypeName;} |
| | | |
| | | PayType(Integer num,String payTypeName){ |
| | | this.num = num; |
| | | this.payTypeName = payTypeName; |
| | | } |
| | | |
| | | public static PayType instance(Integer value) { |
| | | PayType[] enums = values(); |
| | | for (PayType statusEnum : enums) { |
| | | if (statusEnum.value().equals(value)) { |
| | | return statusEnum; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public static boolean isWxPay(PayType payType) { |
| | | return (Objects.equals(payType, PayType.WECHATPAY) |
| | | || Objects.equals(payType, PayType.WECHATPAY_SWEEP_CODE) |
| | | || Objects.equals(payType, PayType.WECHATPAY_H5) |
| | | || Objects.equals(payType, PayType.WECHATPAY_MP) |
| | | || Objects.equals(payType, PayType.WECHATPAY_APP)); |
| | | } |
| | | |
| | | public static boolean isAliPay(PayType payType) { |
| | | return (Objects.equals(payType, PayType.ALIPAY_H5) |
| | | || Objects.equals(payType, PayType.ALIPAY) |
| | | || Objects.equals(payType, PayType.ALIPAY_APP)); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.enums; |
| | | |
| | | /** |
| | | * 七牛云zone的选择 |
| | | * @author LGH |
| | | */ |
| | | public enum QiniuZone { |
| | | |
| | | /** |
| | | * 华东机房相关 |
| | | */ |
| | | HUA_DONG(), |
| | | |
| | | /** |
| | | * 华北机房相关 |
| | | */ |
| | | HUA_BEI(), |
| | | |
| | | /** |
| | | * 华南机房相关 |
| | | */ |
| | | HUA_NAN(), |
| | | |
| | | /** |
| | | * 北美机房相关 |
| | | */ |
| | | BEI_MEI(), |
| | | |
| | | /** |
| | | * 新加坡机房相关 |
| | | */ |
| | | XIN_JIA_PO(), |
| | | |
| | | ; |
| | | |
| | | QiniuZone(){ |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.enums; |
| | | |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 状态 |
| | | * @author yxf |
| | | * @date 2020/11/20 |
| | | */ |
| | | public enum StatusEnum { |
| | | |
| | | /** |
| | | * 删除 (逻辑删除) |
| | | */ |
| | | DELETE(-1), |
| | | |
| | | /** |
| | | * 禁用/过期/下架 |
| | | */ |
| | | DISABLE(0), |
| | | |
| | | /** |
| | | * 启用/未过期/上架 |
| | | */ |
| | | ENABLE(1), |
| | | |
| | | /** |
| | | * 违规下架/未启用 |
| | | */ |
| | | OFFLINE(2), |
| | | |
| | | /** |
| | | * 等待审核 |
| | | */ |
| | | WAIT_AUDIT(3), |
| | | |
| | | /** |
| | | * 关闭 |
| | | */ |
| | | FINISHED(4) |
| | | ; |
| | | |
| | | private final Integer value; |
| | | |
| | | public Integer value() { |
| | | return value; |
| | | } |
| | | |
| | | StatusEnum(Integer value) { |
| | | this.value = value; |
| | | } |
| | | |
| | | public static StatusEnum instance(Integer value) { |
| | | StatusEnum[] enums = values(); |
| | | for (StatusEnum statusEnum : enums) { |
| | | if (statusEnum.value().equals(value)) { |
| | | return statusEnum; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public static Boolean offlineStatus (Integer value) { |
| | | StatusEnum[] enums = values(); |
| | | for (StatusEnum statusEnum : enums) { |
| | | if (statusEnum.value().equals(value)) { |
| | | return Boolean.TRUE; |
| | | } |
| | | } |
| | | return Boolean.FALSE; |
| | | } |
| | | |
| | | public static Boolean offlineOrDelete (Integer status) { |
| | | if (Objects.equals(status, OFFLINE.value) || Objects.equals(status, DELETE.value) || Objects.equals(status, DISABLE.value)) { |
| | | return Boolean.TRUE; |
| | | } |
| | | return Boolean.FALSE; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.enums; |
| | | |
| | | /** |
| | | * 会员等级类型 |
| | | * |
| | | * @author yami |
| | | */ |
| | | public enum UserLevelType { |
| | | /** 普通会员 */ |
| | | ORDINARY(0), |
| | | |
| | | /** vip会员 */ |
| | | VIP(1), |
| | | ; |
| | | |
| | | private Integer num; |
| | | |
| | | public Integer value() { |
| | | return num; |
| | | } |
| | | |
| | | UserLevelType(Integer num){ |
| | | this.num = num; |
| | | } |
| | | |
| | | public static UserLevelType instance(Integer value) { |
| | | UserLevelType[] enums = values(); |
| | | for (UserLevelType 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.common.enums; |
| | | |
| | | /** |
| | | * 币种 |
| | | */ |
| | | public enum WalletEnum { |
| | | /** |
| | | * 余额 |
| | | */ |
| | | BALANCE(3), |
| | | /** |
| | | * 瓜瓜豆 |
| | | */ |
| | | BEAN(4), |
| | | |
| | | /** |
| | | * 绿积分 |
| | | */ |
| | | GREENPOINT(5), |
| | | |
| | | /** |
| | | * 红积分 |
| | | */ |
| | | REDPOINT(6), |
| | | /** |
| | | * 蓝积分 |
| | | */ |
| | | BLUEPOINT(7), |
| | | |
| | | /** |
| | | *流量 |
| | | */ |
| | | FLOW(8), |
| | | |
| | | /* |
| | | * 金牛豆 |
| | | */ |
| | | GOLDCOWBEAN(9), |
| | | |
| | | /* |
| | | * 幸运池 |
| | | */ |
| | | LUCKPOOL(10), |
| | | |
| | | /** |
| | | * 积分 |
| | | */ |
| | | INTEGRAL(11), |
| | | |
| | | /* |
| | | * 贡献值 |
| | | */ |
| | | CREDIT(12), |
| | | |
| | | /** |
| | | * 合金豆 |
| | | */ |
| | | ALLOY(13), |
| | | ; |
| | | |
| | | private final Integer value; |
| | | |
| | | public Integer value() { |
| | | return value; |
| | | } |
| | | |
| | | WalletEnum(Integer value) { |
| | | this.value = value; |
| | | } |
| | | |
| | | public static WalletEnum instance(Integer value) { |
| | | WalletEnum[] enums = values(); |
| | | for (WalletEnum 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.common.exception; |
| | | |
| | | import com.yami.shop.common.i18n.I18nMessage; |
| | | import com.yami.shop.common.response.ResponseEnum; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import lombok.Data; |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * 自定义异常 |
| | | * @author yami |
| | | */ |
| | | @Getter |
| | | public class YamiShopBindException extends RuntimeException{ |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | private static final long serialVersionUID = -4137688758944857209L; |
| | | |
| | | /** |
| | | * http状态码 |
| | | */ |
| | | private String code; |
| | | |
| | | private Object object; |
| | | |
| | | private ServerResponseEntity<?> serverResponseEntity; |
| | | |
| | | /** |
| | | * @param responseEnum http状态码 |
| | | */ |
| | | public YamiShopBindException(ResponseEnum responseEnum) { |
| | | super(responseEnum.getMsg()); |
| | | this.code = responseEnum.value(); |
| | | } |
| | | |
| | | /** |
| | | * @param responseEnum http状态码 |
| | | */ |
| | | public YamiShopBindException(ResponseEnum responseEnum, String msg) { |
| | | super(I18nMessage.getMessage(msg)); |
| | | this.code = responseEnum.value(); |
| | | } |
| | | |
| | | public YamiShopBindException(ServerResponseEntity<?> serverResponseEntity) { |
| | | this.serverResponseEntity = serverResponseEntity; |
| | | } |
| | | |
| | | public YamiShopBindException(String msg) { |
| | | // super(msg); |
| | | super(I18nMessage.getMessage(msg)); |
| | | this.code = ResponseEnum.SHOW_FAIL.value(); |
| | | } |
| | | |
| | | public YamiShopBindException(String msg, Object object) { |
| | | super(I18nMessage.getMessage(msg)); |
| | | this.code = ResponseEnum.SHOW_FAIL.value(); |
| | | this.object = object; |
| | | } |
| | | |
| | | public YamiShopBindException(String code, String msg) { |
| | | super(I18nMessage.getMessage(msg)); |
| | | this.code = code; |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.filter; |
| | | |
| | | import cn.hutool.core.collection.CollectionUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.hutool.http.ContentType; |
| | | import com.yami.shop.common.config.SensitiveWordConfig; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.handler.SensitiveHandler; |
| | | import com.yami.shop.common.wrapper.RequestWrapper; |
| | | import com.yami.shop.common.wrapper.ResponseWrapper; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.util.AntPathMatcher; |
| | | import org.springframework.web.context.request.RequestContextHolder; |
| | | import org.springframework.web.context.request.ServletRequestAttributes; |
| | | |
| | | import javax.servlet.*; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * @author Citrus |
| | | * @date 2021/8/17 11:05 |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | public class SensitiveFilter implements Filter { |
| | | |
| | | Logger logger = LoggerFactory.getLogger(getClass().getName()); |
| | | |
| | | |
| | | @Autowired |
| | | private SensitiveHandler sensitiveHandler; |
| | | |
| | | @Override |
| | | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { |
| | | HttpServletRequest req = (HttpServletRequest) request; |
| | | HttpServletResponse resp = (HttpServletResponse) response; |
| | | ServletRequestAttributes attributes = new ServletRequestAttributes(req, resp); |
| | | RequestContextHolder.setRequestAttributes(attributes); |
| | | logger.info("uri:{}", req.getRequestURI()); |
| | | Set<String> sensitiveWhiteSet = SensitiveWordConfig.getSensitiveWhiteSet(); |
| | | AntPathMatcher antPathMatcher = new AntPathMatcher(); |
| | | if (CollectionUtil.isNotEmpty(sensitiveWhiteSet)){ |
| | | for (String sensitiveUrl : sensitiveWhiteSet) { |
| | | if (antPathMatcher.match(sensitiveUrl,req.getRequestURI())){ |
| | | chain.doFilter(req, resp); |
| | | return; |
| | | } |
| | | } |
| | | } |
| | | ResponseWrapper responseWrapper = new ResponseWrapper(resp); |
| | | // 敏感词输入过滤 |
| | | if (StrUtil.isNotBlank(req.getContentType()) && req.getContentType().contains(ContentType.JSON.getValue())) { |
| | | RequestWrapper requestWrapper; |
| | | requestWrapper = new RequestWrapper(req); |
| | | String body = requestWrapper.getBody(); |
| | | if (StrUtil.isNotBlank(body) && sensitiveHandler.isSensitive(body)) { |
| | | throw new YamiShopBindException("yami.sensitive.words.reenter"); |
| | | } |
| | | chain.doFilter(requestWrapper, responseWrapper); |
| | | } else { |
| | | Map<String, String[]> parameterMap = req.getParameterMap(); |
| | | StringBuilder stringBuilder = new StringBuilder(); |
| | | for (String s : parameterMap.keySet()) { |
| | | stringBuilder.append(parameterMap.get(s)[0]); |
| | | } |
| | | // 传入参数是否包含敏感词,最小匹配 |
| | | if (StrUtil.isNotBlank(stringBuilder.toString()) && sensitiveHandler.isSensitive(stringBuilder.toString())) { |
| | | throw new YamiShopBindException("yami.sensitive.words.reenter"); |
| | | } |
| | | //xss |
| | | chain.doFilter(req, responseWrapper); |
| | | } |
| | | boolean isType = Objects.nonNull(responseWrapper.getContentType()) && |
| | | (responseWrapper.getContentType().contains(ContentType.JSON.getValue()) || responseWrapper.getContentType().contains(ContentType.TEXT_PLAIN.getValue())); |
| | | if (isType) { |
| | | byte[] content = responseWrapper.getContent(); |
| | | //敏感词输出过滤 |
| | | if (content.length > 0) { |
| | | String s = new String(content, StandardCharsets.UTF_8); |
| | | //属于json格式再处理 |
| | | String sensitiveText = null; |
| | | try { |
| | | sensitiveText = sensitiveHandler.replaceSensitiveWord(s, "*"); |
| | | } catch (Exception e) { |
| | | log.error("替换敏感词失败:", e); |
| | | } |
| | | ServletOutputStream outputStream = resp.getOutputStream(); |
| | | outputStream.write(sensitiveText != null ? sensitiveText.getBytes(StandardCharsets.UTF_8) : new byte[0]); |
| | | outputStream.flush(); |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.common.handler; |
| | | |
| | | import com.yami.shop.common.enums.CodeBaseEnum; |
| | | import lombok.NoArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.ibatis.type.BaseTypeHandler; |
| | | import org.apache.ibatis.type.JdbcType; |
| | | |
| | | import java.sql.CallableStatement; |
| | | import java.sql.PreparedStatement; |
| | | import java.sql.ResultSet; |
| | | import java.sql.SQLException; |
| | | |
| | | /** |
| | | * @auth lxw |
| | | * @date 2024/4/25 |
| | | * @desc mapper里字段到枚举类的映射 |
| | | */ |
| | | @NoArgsConstructor |
| | | @Slf4j |
| | | public class EnumTypeHandler<E extends Enum<?> & CodeBaseEnum> extends BaseTypeHandler<CodeBaseEnum> { |
| | | private Class<E> clazz; |
| | | |
| | | public EnumTypeHandler(Class<E> enumType) { |
| | | if (enumType == null) |
| | | throw new IllegalArgumentException("Type argument cannot be null"); |
| | | |
| | | this.clazz = enumType; |
| | | } |
| | | |
| | | @Override |
| | | public void setNonNullParameter(PreparedStatement ps, int i, CodeBaseEnum parameter, JdbcType jdbcType) |
| | | throws SQLException { |
| | | ps.setInt(i, parameter.getValue()); |
| | | } |
| | | |
| | | @Override |
| | | public E getNullableResult(ResultSet rs, String columnName) throws SQLException { |
| | | return this.codeOf(clazz, rs.getInt(columnName)); |
| | | } |
| | | |
| | | @Override |
| | | public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException { |
| | | return this.codeOf(clazz, rs.getInt(columnIndex)); |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { |
| | | return this.codeOf(clazz, cs.getInt(columnIndex)); |
| | | } |
| | | |
| | | /** |
| | | * @param enumClass |
| | | * @param code |
| | | * @param <E> |
| | | * @return |
| | | */ |
| | | public static <E extends Enum<?> & CodeBaseEnum> E codeOf(Class<E> enumClass, int code) { |
| | | E[] enumConstants = enumClass.getEnumConstants(); // [OTHER, VALID, INVALID] |
| | | for (E e : enumConstants) { |
| | | if (e.getValue() == code) |
| | | return e; |
| | | } |
| | | return null; |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.handler; |
| | | |
| | | import cn.hutool.core.util.CharsetUtil; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.web.context.request.RequestContextHolder; |
| | | import org.springframework.web.context.request.ServletRequestAttributes; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | import java.io.PrintWriter; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * @author FrozenWatermelon |
| | | * @date 2020/7/16 |
| | | */ |
| | | @Component |
| | | public class HttpHandler { |
| | | |
| | | private static final Logger logger = LoggerFactory.getLogger(HttpHandler.class); |
| | | |
| | | @Autowired |
| | | private ObjectMapper objectMapper; |
| | | |
| | | public <T> void printServerResponseToWeb(ServerResponseEntity<T> serverResponseEntity) { |
| | | if (serverResponseEntity == null) { |
| | | logger.info("print obj is null"); |
| | | return; |
| | | } |
| | | |
| | | ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder |
| | | .getRequestAttributes(); |
| | | if (requestAttributes == null) { |
| | | logger.error("requestAttributes is null, can not print to web"); |
| | | return; |
| | | } |
| | | HttpServletResponse response = requestAttributes.getResponse(); |
| | | if (response == null) { |
| | | logger.error("httpServletResponse is null, can not print to web"); |
| | | return; |
| | | } |
| | | logger.error("response error: " + serverResponseEntity.getMsg()); |
| | | response.setCharacterEncoding(CharsetUtil.UTF_8); |
| | | response.setContentType(MediaType.APPLICATION_JSON_VALUE); |
| | | PrintWriter printWriter = null; |
| | | try { |
| | | printWriter = response.getWriter(); |
| | | printWriter.write(objectMapper.writeValueAsString(serverResponseEntity)); |
| | | } |
| | | catch (IOException e) { |
| | | throw new YamiShopBindException("io 异常", e); |
| | | } |
| | | } |
| | | |
| | | public <T> void printServerResponseToWeb(YamiShopBindException yamiShopBindException) { |
| | | if (yamiShopBindException == null) { |
| | | logger.info("print obj is null"); |
| | | return; |
| | | } |
| | | |
| | | if (Objects.nonNull(yamiShopBindException.getServerResponseEntity())) { |
| | | printServerResponseToWeb(yamiShopBindException.getServerResponseEntity()); |
| | | return; |
| | | } |
| | | |
| | | ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>(); |
| | | serverResponseEntity.setCode(yamiShopBindException.getCode()); |
| | | serverResponseEntity.setMsg(yamiShopBindException.getMessage()); |
| | | printServerResponseToWeb(serverResponseEntity); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.handler; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.alibaba.fastjson.JSONValidator; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import com.github.benmanes.caffeine.cache.Cache; |
| | | import com.github.benmanes.caffeine.cache.Caffeine; |
| | | import com.yami.shop.common.bean.SensitiveWord; |
| | | import com.yami.shop.common.bean.event.GetSensitiveWordEvent; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.context.ApplicationContext; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.*; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | | * @author FrozenWatermelon |
| | | * @date 2021/12/29 |
| | | */ |
| | | @Component |
| | | public class SensitiveHandler { |
| | | |
| | | @Autowired |
| | | private ApplicationContext applicationContext; |
| | | @Autowired |
| | | private ObjectMapper objectMapper; |
| | | |
| | | /** |
| | | * 缓存 |
| | | */ |
| | | private static final Cache<Object, Object> CONFIG_MAP = Caffeine.newBuilder() |
| | | // 数量上限 |
| | | .maximumSize(1) |
| | | // 过期机制 |
| | | .expireAfterWrite(5, TimeUnit.MINUTES).build(); |
| | | /** |
| | | * 最小匹配 |
| | | */ |
| | | public static int minMatchType = 1; |
| | | /** |
| | | * 最大匹配 |
| | | */ |
| | | public static int maxMatchType = 2; |
| | | |
| | | private static final String IS_END = "isEnd"; |
| | | private static final String IS_ONE = "1"; |
| | | |
| | | /** |
| | | * 是否有敏感词 |
| | | * @param txt |
| | | * @return |
| | | */ |
| | | public boolean isSensitive(String txt) { |
| | | return isSensitive(txt, minMatchType); |
| | | } |
| | | |
| | | public boolean isSensitive(String txt, int matchType) { |
| | | boolean flag = false; |
| | | for (int i = 0; i < txt.length(); i++) { |
| | | int matchFlag = this.checkSensitiveWord(txt, i, matchType); |
| | | if (matchFlag > 0) { |
| | | flag = true; |
| | | } |
| | | } |
| | | return flag; |
| | | } |
| | | |
| | | /** |
| | | * 替换敏感词 |
| | | * @param txt |
| | | * @param replaceChar |
| | | * @return |
| | | */ |
| | | public String replaceSensitiveWord(String txt, String replaceChar) { |
| | | JSON json; |
| | | if (JSONValidator.Type.Object.equals(JSONValidator.from(txt).getType())) { |
| | | json = JSON.parseObject(txt); |
| | | } else if (JSONValidator.Type.Array.equals(JSONValidator.from(txt).getType())) { |
| | | json = JSON.parseArray(txt); |
| | | }else { |
| | | return replaceSensitiveWord(txt,maxMatchType, replaceChar); |
| | | } |
| | | jsonIterator(json, replaceChar); |
| | | String jsonStr; |
| | | try { |
| | | jsonStr = objectMapper.writeValueAsString(json); |
| | | } catch (IOException e) { |
| | | throw new YamiShopBindException("io 异常"); |
| | | } |
| | | return jsonStr; |
| | | } |
| | | |
| | | public String replaceSensitiveWord(String txt, int matchType, String replaceChar) { |
| | | String resultTxt = txt; |
| | | Set<String> sensitiveWordSet = this.getSensitiveWord(txt, matchType); |
| | | Iterator<String> iterator = sensitiveWordSet.iterator(); |
| | | String word; |
| | | String replaceString; |
| | | while (iterator.hasNext()) { |
| | | word = iterator.next(); |
| | | replaceString = getReplaceChars(replaceChar, word.length()); |
| | | resultTxt = resultTxt.replaceAll(word, replaceString); |
| | | } |
| | | return resultTxt; |
| | | } |
| | | |
| | | private void jsonIterator(JSON json, String replaceChar) { |
| | | if (json instanceof JSONObject) { |
| | | JSONObject jsonObject = (JSONObject)json; |
| | | for (String key : jsonObject.keySet()) { |
| | | Object object = jsonObject.get(key); |
| | | if (Objects.nonNull(object)) { |
| | | String value = object.toString(); |
| | | if (object instanceof JSON) { |
| | | jsonIterator((JSON)object, replaceChar); |
| | | } else if (object instanceof String){ |
| | | jsonObject.put(key, replaceSensitiveWord(value, maxMatchType, replaceChar)); |
| | | } |
| | | } |
| | | } |
| | | } else if (json instanceof JSONArray){ |
| | | JSONArray jsonArray = (JSONArray)json; |
| | | for (int key = 0; key < jsonArray.size(); key++) { |
| | | Object object = jsonArray.get(key); |
| | | if (object instanceof JSON) { |
| | | jsonIterator((JSON)object, replaceChar); |
| | | } else if (object instanceof String){ |
| | | jsonArray.set(key, replaceSensitiveWord(object.toString(), maxMatchType, replaceChar)); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | public Set<String> getSensitiveWord(String txt, int matchType) { |
| | | Set<String> sensitiveWordList = new HashSet<>(); |
| | | for (int i = 0; i < txt.length(); i++) { |
| | | int length = checkSensitiveWord(txt, i, matchType); |
| | | if (length > 0) { |
| | | sensitiveWordList.add(txt.substring(i, i + length)); |
| | | i = i + length - 1; |
| | | } |
| | | } |
| | | return sensitiveWordList; |
| | | } |
| | | |
| | | private String getReplaceChars(String replaceChar, int length) { |
| | | StringBuilder resultReplace = new StringBuilder(); |
| | | resultReplace.append(replaceChar); |
| | | for (int i = 1; i < length; i++) { |
| | | resultReplace.append(replaceChar); |
| | | } |
| | | return resultReplace.toString(); |
| | | } |
| | | |
| | | private int checkSensitiveWord(String txt, int beginIndex, int matchType) { |
| | | Map nowMap = getSensitiveWordMap(); |
| | | boolean flag = false; |
| | | char word = 0; |
| | | int matchFlag = 0; |
| | | for (int i = beginIndex; i < txt.length(); i++) { |
| | | word = txt.charAt(i); |
| | | nowMap = (Map) nowMap.get(word); |
| | | if (Objects.isNull(nowMap)) { |
| | | break; |
| | | } |
| | | matchFlag++; |
| | | if (isEnd(nowMap)) { |
| | | flag = true; |
| | | if (Objects.equals(minMatchType, matchType)) { |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | if (matchFlag <= 1 || !flag) { |
| | | matchFlag = 0; |
| | | } |
| | | return matchFlag; |
| | | } |
| | | |
| | | |
| | | private boolean isEnd(Map nowMap) { |
| | | boolean flag = false; |
| | | if (Objects.equals(nowMap.get(IS_END), IS_ONE)) { |
| | | flag = true; |
| | | } |
| | | return flag; |
| | | } |
| | | |
| | | |
| | | private Map getSensitiveWordMap() { |
| | | Map finalMap = (Map) CONFIG_MAP.get(Constant.SENSITIVE_WORDS, cacheKey -> { |
| | | SensitiveWord sensitiveWord = new SensitiveWord(); |
| | | try { |
| | | applicationContext.publishEvent(new GetSensitiveWordEvent(Constant.SENSITIVE_WORDS,sensitiveWord)); |
| | | } catch (Exception e) { |
| | | return Collections.emptyMap(); |
| | | } |
| | | if (StrUtil.isBlank(sensitiveWord.getSensitiveWord())) { |
| | | return Collections.emptyMap(); |
| | | } |
| | | //根据中文逗号分隔 |
| | | List<String> sensitiveWordsList = Arrays.asList(sensitiveWord.getSensitiveWord().split(Constant.CN_COMMA)); |
| | | HashSet<String> sensitiveWordSet = new HashSet<>(sensitiveWordsList); |
| | | Iterator<String> iterator = sensitiveWordSet.iterator(); |
| | | String key; |
| | | Map nowMap; |
| | | Map<String, String> newWordMap; |
| | | Map<Object, Object> sensitiveWordMap = new HashMap<>(sensitiveWordSet.size()); |
| | | while (iterator.hasNext()) { |
| | | //敏感词 |
| | | key = iterator.next(); |
| | | nowMap = sensitiveWordMap; |
| | | for (int i = 0; i < key.length(); i++) { |
| | | //敏 |
| | | char charAt = key.charAt(i); |
| | | Object wordMap = nowMap.get(charAt); |
| | | if (wordMap != null) { |
| | | //逐字加入map |
| | | nowMap = (Map) wordMap; |
| | | } else { |
| | | newWordMap = new HashMap<>(sensitiveWordSet.size()); |
| | | //最后一个字,加标记 |
| | | newWordMap.put("isEnd", "0"); |
| | | nowMap.put(charAt, newWordMap); |
| | | nowMap = newWordMap; |
| | | } |
| | | if (i == key.length() - 1) { |
| | | //结束 |
| | | nowMap.put("isEnd", "1"); |
| | | } |
| | | } |
| | | } |
| | | return sensitiveWordMap; |
| | | }); |
| | | |
| | | if (finalMap == null) { |
| | | CONFIG_MAP.invalidate(Constant.SENSITIVE_WORDS); |
| | | } |
| | | |
| | | return finalMap; |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.i18n; |
| | | |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.context.i18n.LocaleContextHolder; |
| | | import org.springframework.context.support.MessageSourceAccessor; |
| | | import org.springframework.context.support.ReloadableResourceBundleMessageSource; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.Locale; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 多语言国际化消息工具类 |
| | | * @author yami |
| | | */ |
| | | @Slf4j |
| | | public class I18nMessage { |
| | | private static MessageSourceAccessor accessor; |
| | | |
| | | // private static final String BASE_FOLDE = "i18n"; |
| | | |
| | | private static final String BASE_NAME = "i18n/messages"; |
| | | |
| | | static{ |
| | | ReloadableResourceBundleMessageSource reloadableResourceBundleMessageSource = new ReloadableResourceBundleMessageSource(); |
| | | reloadableResourceBundleMessageSource.setBasenames(BASE_NAME); |
| | | reloadableResourceBundleMessageSource.setCacheSeconds(5); |
| | | reloadableResourceBundleMessageSource.setDefaultEncoding("UTF-8"); |
| | | accessor = new MessageSourceAccessor(reloadableResourceBundleMessageSource); |
| | | } |
| | | |
| | | |
| | | // /** |
| | | // * 获取一条语言配置信息 |
| | | // * |
| | | // * @param message 配置信息属性名,eg: api.response.code.user.signUp |
| | | // * @return |
| | | // */ |
| | | // public static String getMessage(String message) { |
| | | // Locale locale = LocaleContextHolder.getLocale(); |
| | | // return I18nMessage.accessor.getMessage(message,locale); |
| | | // } |
| | | |
| | | /** |
| | | * 获取一条语言配置信息 |
| | | * |
| | | * @param message 配置信息属性名,eg: api.response.code.user.signUp |
| | | * @return |
| | | */ |
| | | public static String getMessage(String message) { |
| | | Locale locale = LocaleContextHolder.getLocale(); |
| | | try { |
| | | return accessor.getMessage(message,locale); |
| | | }catch (Exception e){ |
| | | return message; |
| | | } |
| | | |
| | | } |
| | | /** |
| | | * 获取一条语言配置信息(后台管理) |
| | | * |
| | | * @return |
| | | * @throws IOException |
| | | */ |
| | | public static Integer getLang() { |
| | | Locale locale = LocaleContextHolder.getLocale(); |
| | | return LanguageEnum.valueOf(locale).getLang(); |
| | | } |
| | | |
| | | /** |
| | | * 获取一条语言配置信息(小程序、pc) |
| | | * |
| | | * @return |
| | | * @throws IOException |
| | | */ |
| | | public static Integer getDbLang() { |
| | | Integer lang = getLang(); |
| | | if (Objects.equals(lang, 0)) { |
| | | return LanguageEnum.LANGUAGE_ZH_CN.getLang(); |
| | | } |
| | | return lang; |
| | | } |
| | | |
| | | // /** |
| | | // * 获取文件夹下所有的国际化文件名 |
| | | // * |
| | | // * @param folderName 文件名 |
| | | // * @return |
| | | // * @throws IOException |
| | | // */ |
| | | // private static String[] getAllBaseNames(final String folderName) throws IOException { |
| | | // URL url = Thread.currentThread().getContextClassLoader() |
| | | // .getResource(folderName); |
| | | // if (null == url) { |
| | | // throw new RuntimeException("无法获取资源文件路径"); |
| | | // } |
| | | // |
| | | // List<String> baseNames = new ArrayList<>(); |
| | | // if (url.getProtocol().equalsIgnoreCase("file")) { |
| | | // // 文件夹形式,用File获取资源路径 |
| | | // File file = new File(url.getFile()); |
| | | // if (file.exists() && file.isDirectory()) { |
| | | // baseNames = Files.walk(file.toPath()) |
| | | // .filter(path -> path.toFile().isFile()) |
| | | // .map(Path::toString) |
| | | // .map(path -> path.substring(path.indexOf(folderName))) |
| | | // .map(I18nMessage::getI18FileName) |
| | | // .distinct() |
| | | // .collect(Collectors.toList()); |
| | | // } else { |
| | | // log.error("指定的baseFile不存在或者不是文件夹"); |
| | | // } |
| | | // } |
| | | // return baseNames.toArray(new String[0]); |
| | | // } |
| | | // |
| | | // /** |
| | | // * 把普通文件名转换成国际化文件名 |
| | | // * |
| | | // * @param filename |
| | | // * @return |
| | | // */ |
| | | // private static String getI18FileName(String filename) { |
| | | // filename = filename.replace(".properties", ""); |
| | | //// for (int i = 0; i < 2; i++) { |
| | | //// int index = filename.lastIndexOf("_"); |
| | | //// if (index != -1) { |
| | | //// filename = filename.substring(0, index); |
| | | //// } |
| | | //// } |
| | | // return filename.replace("\\", "/"); |
| | | // } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.i18n; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Data; |
| | | import lombok.Getter; |
| | | import lombok.Setter; |
| | | |
| | | import java.util.Locale; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 国际化 语言枚举类 |
| | | * @author LGH |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum LanguageEnum { |
| | | |
| | | /** |
| | | * 简体中文 |
| | | */ |
| | | LANGUAGE_ZH_CN("zh", 0), |
| | | /** |
| | | * 英文 |
| | | */ |
| | | LANGUAGE_EN("en", 1) |
| | | |
| | | ; |
| | | |
| | | private String language; |
| | | |
| | | private Integer lang; |
| | | |
| | | |
| | | /** |
| | | * 获取指定语言类型(如果没有对应的语言类型,则返回中文) |
| | | * |
| | | * @param language 语言类型 |
| | | * @return |
| | | */ |
| | | public static String getLanguageType(String language){ |
| | | if (StrUtil.isEmpty(language)) { |
| | | return LANGUAGE_ZH_CN.language; |
| | | } |
| | | for (LanguageEnum languageEnum : LanguageEnum.values()) { |
| | | if (languageEnum.language.equalsIgnoreCase(language)) { |
| | | return languageEnum.language; |
| | | } |
| | | } |
| | | return LANGUAGE_ZH_CN.language; |
| | | } |
| | | |
| | | |
| | | public static LanguageEnum valueOf(int lang) { |
| | | for (LanguageEnum languageEnum : values()) { |
| | | if (languageEnum.lang == lang) { |
| | | return languageEnum; |
| | | } |
| | | } |
| | | return LanguageEnum.LANGUAGE_ZH_CN; |
| | | } |
| | | |
| | | public static LanguageEnum valueOf(Locale locale) { |
| | | for (LanguageEnum languageEnum : values()) { |
| | | if (Objects.equals(languageEnum.language, locale.toString())) { |
| | | return languageEnum; |
| | | } |
| | | } |
| | | return LanguageEnum.LANGUAGE_ZH_CN; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.i18n; |
| | | |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.context.i18n.LocaleContextHolder; |
| | | import org.springframework.core.annotation.Order; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.servlet.*; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | import java.util.Locale; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * RequestContextFilter 会传入默认的Locale,优先级(-105) 要比RequestContextFilter优先级高 |
| | | * @author LGH |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | @Order(-104) |
| | | public class YamiLocaleChangeFilter implements Filter { |
| | | |
| | | public static String ZH_CN = "zh_CN"; |
| | | public static String ZH_CN_L = "zh_cn"; |
| | | |
| | | @Override |
| | | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { |
| | | HttpServletRequest request = (HttpServletRequest) servletRequest; |
| | | HttpServletResponse response = (HttpServletResponse) servletResponse; |
| | | |
| | | String newLocale = request.getHeader("locale"); |
| | | if(Objects.equals(newLocale,"zh_CN")||Objects.equals(newLocale,"zh_cn")){ |
| | | newLocale = "zh"; |
| | | } |
| | | if (newLocale != null) { |
| | | String lowerLocale = newLocale.toLowerCase(); |
| | | LocaleContextHolder.setLocale(new Locale(lowerLocale)); |
| | | } |
| | | filterChain.doFilter(request, response); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.i18n; |
| | | |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.web.servlet.LocaleResolver; |
| | | import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; |
| | | import org.springframework.web.servlet.support.RequestContextUtils; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | |
| | | /** |
| | | * @author LGH |
| | | */ |
| | | @Component("localeChangeInterceptor") |
| | | @Slf4j |
| | | public class YamiLocaleChangeInterceptor extends LocaleChangeInterceptor { |
| | | |
| | | @Override |
| | | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { |
| | | |
| | | String newLocale = request.getHeader(getParamName()); |
| | | if (newLocale != null) { |
| | | LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request); |
| | | if (localeResolver == null) { |
| | | throw new IllegalStateException( |
| | | "No LocaleResolver found: not in a DispatcherServlet request?"); |
| | | } |
| | | try { |
| | | localeResolver.setLocale(request, response, parseLocaleValue(newLocale)); |
| | | } |
| | | catch (IllegalArgumentException ex) { |
| | | if (isIgnoreInvalidLocale()) { |
| | | if (logger.isDebugEnabled()) { |
| | | logger.debug("Ignoring invalid locale value [" + newLocale + "]: " + ex.getMessage()); |
| | | } |
| | | } |
| | | else { |
| | | throw ex; |
| | | } |
| | | } |
| | | } |
| | | // Proceed in any case. |
| | | return true; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.response; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 响应实体 |
| | | * @author yami |
| | | */ |
| | | public class R<T> implements Serializable { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(R.class); |
| | | |
| | | /** |
| | | * 状态码 |
| | | */ |
| | | @Schema(description = "状态码" ) |
| | | private String code; |
| | | |
| | | /** |
| | | * 信息 |
| | | */ |
| | | @Schema(description = "信息" ) |
| | | private String msg; |
| | | |
| | | /** |
| | | * 数据 |
| | | */ |
| | | @Schema(description = "数据" ) |
| | | private T data; |
| | | |
| | | /** |
| | | * 版本 |
| | | */ |
| | | private String version; |
| | | |
| | | /** |
| | | * 时间 |
| | | */ |
| | | private Long timestamp; |
| | | |
| | | private String sign; |
| | | |
| | | public String getSign() { |
| | | return sign; |
| | | } |
| | | |
| | | public void setSign(String sign) { |
| | | this.sign = sign; |
| | | } |
| | | |
| | | public String getCode() { |
| | | return code; |
| | | } |
| | | |
| | | public void setCode(String code) { |
| | | this.code = code; |
| | | } |
| | | |
| | | public String getMsg() { |
| | | return msg; |
| | | } |
| | | |
| | | public void setMsg(String msg) { |
| | | this.msg = msg; |
| | | } |
| | | |
| | | public T getData() { |
| | | return data; |
| | | } |
| | | |
| | | public R setData(T data) { |
| | | this.data = data; |
| | | return this; |
| | | } |
| | | |
| | | public Long getTimestamp() { |
| | | return timestamp; |
| | | } |
| | | |
| | | public void setTimestamp(Long timestamp) { |
| | | this.timestamp = timestamp; |
| | | } |
| | | |
| | | public String getVersion() { |
| | | return version; |
| | | } |
| | | |
| | | public void setVersion(String version) { |
| | | this.version = version; |
| | | } |
| | | |
| | | public boolean isSuccess() { |
| | | return Objects.equals(ResponseEnum.OK.value(), this.code); |
| | | } |
| | | public boolean isFail() { |
| | | return !Objects.equals(ResponseEnum.OK.value(), this.code); |
| | | } |
| | | |
| | | public R() { |
| | | // 版本号 |
| | | this.version = "mall4j.v230213"; |
| | | } |
| | | |
| | | public static <T> R<T> success(T data) { |
| | | R<T> serverResponseEntity = new R<>(); |
| | | serverResponseEntity.setData(data); |
| | | serverResponseEntity.setCode(ResponseEnum.OK.value()); |
| | | return serverResponseEntity; |
| | | } |
| | | |
| | | public static <T> R<T> success() { |
| | | R<T> serverResponseEntity = new R<>(); |
| | | serverResponseEntity.setCode(ResponseEnum.OK.value()); |
| | | serverResponseEntity.setMsg(ResponseEnum.OK.getMsg()); |
| | | return serverResponseEntity; |
| | | } |
| | | |
| | | public static <T> R<T> success(Integer code, T data) { |
| | | return success(String.valueOf(code), data); |
| | | } |
| | | |
| | | public static <T> R<T> success(String code, T data) { |
| | | R<T> serverResponseEntity = new R<>(); |
| | | serverResponseEntity.setCode(code); |
| | | serverResponseEntity.setData(data); |
| | | return serverResponseEntity; |
| | | } |
| | | |
| | | /** |
| | | * 前端显示失败消息 |
| | | * @param msg 失败消息 |
| | | * @return |
| | | */ |
| | | public static <T> R<T> showFailMsg(String msg) { |
| | | log.error(msg); |
| | | R<T> serverResponseEntity = new R<>(); |
| | | serverResponseEntity.setMsg(msg); |
| | | serverResponseEntity.setCode(ResponseEnum.SHOW_FAIL.value()); |
| | | return serverResponseEntity; |
| | | } |
| | | |
| | | public static <T> R<T> fail(ResponseEnum responseEnum) { |
| | | log.error(responseEnum.toString()); |
| | | R<T> serverResponseEntity = new R<>(); |
| | | serverResponseEntity.setMsg(responseEnum.getMsg()); |
| | | serverResponseEntity.setCode(responseEnum.value()); |
| | | return serverResponseEntity; |
| | | } |
| | | |
| | | public static <T> R<T> fail(ResponseEnum responseEnum, T data) { |
| | | log.error(responseEnum.toString()); |
| | | R<T> serverResponseEntity = new R<>(); |
| | | serverResponseEntity.setMsg(responseEnum.getMsg()); |
| | | serverResponseEntity.setCode(responseEnum.value()); |
| | | serverResponseEntity.setData(data); |
| | | return serverResponseEntity; |
| | | } |
| | | |
| | | public static <T> R<T> fail(String code, String msg, T data) { |
| | | log.error(msg); |
| | | R<T> serverResponseEntity = new R<>(); |
| | | serverResponseEntity.setMsg(msg); |
| | | serverResponseEntity.setCode(code); |
| | | serverResponseEntity.setData(data); |
| | | return serverResponseEntity; |
| | | } |
| | | |
| | | public static <T> R<T> fail(String code, String msg) { |
| | | return fail(code, msg, null); |
| | | } |
| | | |
| | | public static <T> R<T> fail(Integer code, T data) { |
| | | R<T> serverResponseEntity = new R<>(); |
| | | serverResponseEntity.setCode(String.valueOf(code)); |
| | | serverResponseEntity.setData(data); |
| | | return serverResponseEntity; |
| | | } |
| | | |
| | | @SuppressWarnings("unchecked") |
| | | public static <T> R<T> transform(R<?> oldServerResponseEntity) { |
| | | R<T> serverResponseEntity = new R<>(); |
| | | serverResponseEntity.setMsg(oldServerResponseEntity.getMsg()); |
| | | serverResponseEntity.setCode(oldServerResponseEntity.getCode()); |
| | | serverResponseEntity.setData((T) oldServerResponseEntity.getData()); |
| | | log.error(serverResponseEntity.toString()); |
| | | return serverResponseEntity; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | | return "ServerResponseEntity{" + |
| | | "code='" + code + '\'' + |
| | | ", msg='" + msg + '\'' + |
| | | ", data=" + data + |
| | | ", version='" + version + '\'' + |
| | | ", timestamp=" + timestamp + |
| | | ", sign='" + sign + '\'' + |
| | | '}'; |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.response; |
| | | |
| | | /** |
| | | * 响应码 |
| | | * @author yami |
| | | */ |
| | | public interface ResponseCode { |
| | | |
| | | int SUCCESS = 1; |
| | | int WX_SUCCESS = 0; |
| | | |
| | | int FAIL = -1; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.response; |
| | | |
| | | /** |
| | | * @author FrozenWatermelon |
| | | * @date 2020/7/9 |
| | | */ |
| | | public enum ResponseEnum { |
| | | |
| | | /** |
| | | * ok |
| | | */ |
| | | OK("00000", "ok"), |
| | | /** |
| | | * ok |
| | | */ |
| | | ERROR("99999", "失败"), |
| | | |
| | | /** |
| | | * 用于直接显示提示用户的错误,内容由输入内容决定 |
| | | */ |
| | | SHOW_FAIL("A00001", ""), |
| | | |
| | | /** |
| | | * 用于直接显示提示系统的成功,内容由输入内容决定 |
| | | */ |
| | | SHOW_SUCCESS("A00002", ""), |
| | | |
| | | /** |
| | | * 未授权 |
| | | */ |
| | | UNAUTHORIZED("A00004", "Unauthorized"), |
| | | |
| | | /** |
| | | * 服务器出了点小差 |
| | | */ |
| | | EXCEPTION("A00005", "服务器出了点小差"), |
| | | // |
| | | // /** |
| | | // * 验证码有误 |
| | | // */ |
| | | // VERIFICATION_CODE_ERROR("A00006", "验证码有误或已过期"), |
| | | // |
| | | // /** |
| | | // * 数据异常 |
| | | // */ |
| | | // DATA_ERROR("A00007", "数据异常,请刷新后重新操作"), |
| | | // |
| | | // /** |
| | | // * 一些需要登录的接口,而实际上因为前端无法知道token是否已过期,导致token已失效时, |
| | | // * 应该返回一个状态码,告诉前端token已经失效了,及时清理 |
| | | // */ |
| | | // CLEAN_TOKEN("A00008", "clean token"), |
| | | // |
| | | // /** |
| | | // * 刷新token已过期 |
| | | // */ |
| | | // REFRESH_TOKEN_EXIST("A00009", "refresh token exist"), |
| | | // |
| | | // /** |
| | | // * 数据不完整 |
| | | // */ |
| | | // DATA_INCOMPLETE("A00010", "数据不完整"), |
| | | // |
| | | // /** |
| | | // * 有敏感词 |
| | | // */ |
| | | // SENSITIVE_WORD("A00011","存在敏感词,请重新输入"), |
| | | |
| | | /** |
| | | * TempUid异常 |
| | | * 一般不会出现这个异常,出现这个异常会有两种已知可能 |
| | | * 1. 一种是旧的tempUid |
| | | * 2. 一种是同域名的localstorage 有个也叫tempUid的存储覆盖了(有的人测试环境和正式环境放在同一个域名不同子目录下) |
| | | * 如果前端看到返回了这个异常,为了让用户能够顺利登录,需要重新获取一遍code,重新获取tempUid |
| | | */ |
| | | TEMP_UID_ERROR("A00012", "TempUid Error"), |
| | | |
| | | /** |
| | | * 接口不存在 |
| | | */ |
| | | NOT_FOUND("A00013", "接口不存在"), |
| | | |
| | | /** |
| | | * 方法参数没有校验,内容由输入内容决定 |
| | | */ |
| | | METHOD_ARGUMENT_NOT_VALID("A00014", "方法参数没有校验"), |
| | | |
| | | /** |
| | | * 01开头代表商品 |
| | | * 商品已下架,返回特殊的状态码,用于渲染商品下架的页面 |
| | | */ |
| | | // SPU_NOT_EXIST("A01000", "商品不存在"), |
| | | |
| | | /** |
| | | * 02开头代表购物车 |
| | | */ |
| | | // SHOP_CART_NOT_EXIST("A02000", "商品已下架"), |
| | | |
| | | /** |
| | | * 03开头代表订单 |
| | | */ |
| | | // ORDER_NOT_EXIST("A03000", "订单不存在"), |
| | | |
| | | /** |
| | | * 订单不支持该配送方式 |
| | | */ |
| | | ORDER_DELIVERY_NOT_SUPPORTED("A03001", "The delivery method is not supported"), |
| | | |
| | | /** |
| | | * 请勿重复提交订单, |
| | | * 1.当前端遇到该异常时,说明前端防多次点击没做好 |
| | | * 2.提示用户 订单已发生改变,请勿重复下单 |
| | | */ |
| | | REPEAT_ORDER("A03002", "订单已过期,请重新下单"), |
| | | |
| | | /** |
| | | * 优惠券不能共用 |
| | | */ |
| | | COUPON_CANNOT_USE_TOGETHER("A03003", "优惠券不能共用"), |
| | | |
| | | /** |
| | | * 库存不足,body会具体返回那个skuid的库存不足,后台通过skuId知道哪个商品库存不足,前端不需要判断 |
| | | */ |
| | | NOT_STOCK("A03010", "not stock"), |
| | | |
| | | /** |
| | | * 该社交账号被其他用户绑定了,如果返回这个状态码,前端应该提示用户解绑已经绑定的账号重新绑定 |
| | | */ |
| | | SOCIAL_ACCOUNT_BIND_BY_OTHER("A04002", "social account bind by other"), |
| | | |
| | | |
| | | /** |
| | | * 该社交账号被其他用户绑定了,如果返回这个状态码,前端应该提示用户解绑已经绑定的账号重新绑定 |
| | | */ |
| | | TAOBAO_OAUTH_FAIL("A05001", "oauth fail"), |
| | | |
| | | /** |
| | | * 用户收货地址超过配送范围 |
| | | */ |
| | | DELIVERY_OVER("A07001", "") |
| | | ; |
| | | |
| | | private final String code; |
| | | |
| | | private final String msg; |
| | | |
| | | public String value() { |
| | | return code; |
| | | } |
| | | |
| | | public String getMsg() { |
| | | return msg; |
| | | } |
| | | |
| | | ResponseEnum(String code, String msg) { |
| | | this.code = code; |
| | | this.msg = msg; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | | return "ResponseEnum{" + "code='" + code + '\'' + ", msg='" + msg + '\'' + "} " + super.toString(); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.response; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 响应实体 |
| | | * @author yami |
| | | */ |
| | | public class ServerResponseEntity<T> implements Serializable { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(ServerResponseEntity.class); |
| | | |
| | | /** |
| | | * 状态码 |
| | | */ |
| | | @Schema(description = "状态码" ) |
| | | private String code; |
| | | |
| | | /** |
| | | * 信息 |
| | | */ |
| | | @Schema(description = "信息" ) |
| | | private String msg; |
| | | |
| | | /** |
| | | * 数据 |
| | | */ |
| | | @Schema(description = "数据" ) |
| | | private T data; |
| | | |
| | | /** |
| | | * 版本 |
| | | */ |
| | | private String version; |
| | | |
| | | /** |
| | | * 时间 |
| | | */ |
| | | private Long timestamp; |
| | | |
| | | private String sign; |
| | | |
| | | public String getSign() { |
| | | return sign; |
| | | } |
| | | |
| | | public void setSign(String sign) { |
| | | this.sign = sign; |
| | | } |
| | | |
| | | public String getCode() { |
| | | return code; |
| | | } |
| | | |
| | | public void setCode(String code) { |
| | | this.code = code; |
| | | } |
| | | |
| | | public String getMsg() { |
| | | return msg; |
| | | } |
| | | |
| | | public void setMsg(String msg) { |
| | | this.msg = msg; |
| | | } |
| | | |
| | | public T getData() { |
| | | return data; |
| | | } |
| | | |
| | | public ServerResponseEntity setData(T data) { |
| | | this.data = data; |
| | | return this; |
| | | } |
| | | |
| | | public Long getTimestamp() { |
| | | return timestamp; |
| | | } |
| | | |
| | | public void setTimestamp(Long timestamp) { |
| | | this.timestamp = timestamp; |
| | | } |
| | | |
| | | public String getVersion() { |
| | | return version; |
| | | } |
| | | |
| | | public void setVersion(String version) { |
| | | this.version = version; |
| | | } |
| | | |
| | | public boolean isSuccess() { |
| | | return Objects.equals(ResponseEnum.OK.value(), this.code); |
| | | } |
| | | public boolean isFail() { |
| | | return !Objects.equals(ResponseEnum.OK.value(), this.code); |
| | | } |
| | | |
| | | public ServerResponseEntity() { |
| | | // 版本号 |
| | | this.version = "mall4j.v230213"; |
| | | } |
| | | |
| | | public static <T> ServerResponseEntity<T> success(T data) { |
| | | ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>(); |
| | | serverResponseEntity.setData(data); |
| | | serverResponseEntity.setCode(ResponseEnum.OK.value()); |
| | | return serverResponseEntity; |
| | | } |
| | | |
| | | public static <T> ServerResponseEntity<T> success() { |
| | | ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>(); |
| | | serverResponseEntity.setCode(ResponseEnum.OK.value()); |
| | | serverResponseEntity.setMsg(ResponseEnum.OK.getMsg()); |
| | | return serverResponseEntity; |
| | | } |
| | | |
| | | public static <T> ServerResponseEntity<T> success(Integer code, T data) { |
| | | return success(String.valueOf(code), data); |
| | | } |
| | | |
| | | public static <T> ServerResponseEntity<T> success(String code, T data) { |
| | | ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>(); |
| | | serverResponseEntity.setCode(code); |
| | | serverResponseEntity.setData(data); |
| | | return serverResponseEntity; |
| | | } |
| | | |
| | | /** |
| | | * 前端显示失败消息 |
| | | * @param msg 失败消息 |
| | | * @return |
| | | */ |
| | | public static <T> ServerResponseEntity<T> showFailMsg(String msg) { |
| | | log.error(msg); |
| | | ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>(); |
| | | serverResponseEntity.setMsg(msg); |
| | | serverResponseEntity.setCode(ResponseEnum.SHOW_FAIL.value()); |
| | | return serverResponseEntity; |
| | | } |
| | | |
| | | public static <T> ServerResponseEntity<T> fail(ResponseEnum responseEnum) { |
| | | log.error(responseEnum.toString()); |
| | | ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>(); |
| | | serverResponseEntity.setMsg(responseEnum.getMsg()); |
| | | serverResponseEntity.setCode(responseEnum.value()); |
| | | return serverResponseEntity; |
| | | } |
| | | |
| | | public static <T> ServerResponseEntity<T> fail(ResponseEnum responseEnum, T data) { |
| | | log.error(responseEnum.toString()); |
| | | ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>(); |
| | | serverResponseEntity.setMsg(responseEnum.getMsg()); |
| | | serverResponseEntity.setCode(responseEnum.value()); |
| | | serverResponseEntity.setData(data); |
| | | return serverResponseEntity; |
| | | } |
| | | |
| | | public static <T> ServerResponseEntity<T> fail(String code, String msg, T data) { |
| | | log.error(msg); |
| | | ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>(); |
| | | serverResponseEntity.setMsg(msg); |
| | | serverResponseEntity.setCode(code); |
| | | serverResponseEntity.setData(data); |
| | | return serverResponseEntity; |
| | | } |
| | | |
| | | public static <T> ServerResponseEntity<T> fail(String code, String msg) { |
| | | return fail(code, msg, null); |
| | | } |
| | | |
| | | public static <T> ServerResponseEntity<T> fail(Integer code, T data) { |
| | | ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>(); |
| | | serverResponseEntity.setCode(String.valueOf(code)); |
| | | serverResponseEntity.setData(data); |
| | | return serverResponseEntity; |
| | | } |
| | | |
| | | @SuppressWarnings("unchecked") |
| | | public static <T> ServerResponseEntity<T> transform(ServerResponseEntity<?> oldServerResponseEntity) { |
| | | ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>(); |
| | | serverResponseEntity.setMsg(oldServerResponseEntity.getMsg()); |
| | | serverResponseEntity.setCode(oldServerResponseEntity.getCode()); |
| | | serverResponseEntity.setData((T) oldServerResponseEntity.getData()); |
| | | log.error(serverResponseEntity.toString()); |
| | | return serverResponseEntity; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | | return "ServerResponseEntity{" + |
| | | "code='" + code + '\'' + |
| | | ", msg='" + msg + '\'' + |
| | | ", data=" + data + |
| | | ", version='" + version + '\'' + |
| | | ", timestamp=" + timestamp + |
| | | ", sign='" + sign + '\'' + |
| | | '}'; |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.response; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 微信直播商品响应参数 |
| | | * @author yami |
| | | */ |
| | | @Data |
| | | public class WxLiveProdResponse<T> implements Serializable { |
| | | |
| | | |
| | | private int errcode; |
| | | |
| | | private Integer total; |
| | | |
| | | private String msg; |
| | | |
| | | private T goods; |
| | | |
| | | private Long roomId; |
| | | |
| | | public boolean isSuccess(){ |
| | | return Objects.equals(ResponseCode.WX_SUCCESS, this.errcode); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.response; |
| | | |
| | | import cn.binarywang.wx.miniapp.json.WxMaGsonBuilder; |
| | | import com.google.gson.annotations.SerializedName; |
| | | import com.yami.shop.common.wx.bean.resp.LiveUserRespInfo; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 微信响应参数 |
| | | * @author yami |
| | | */ |
| | | @Data |
| | | public class WxServerResponse<T> implements Serializable { |
| | | |
| | | |
| | | private int errcode; |
| | | |
| | | private Integer total; |
| | | |
| | | private String msg; |
| | | |
| | | @SerializedName("list") |
| | | private List<LiveUserRespInfo> list; |
| | | |
| | | private T roomInfo; |
| | | |
| | | private Long roomId; |
| | | |
| | | public boolean isSuccess(){ |
| | | return Objects.equals(ResponseCode.WX_SUCCESS, this.errcode); |
| | | } |
| | | |
| | | public static WxServerResponse fromJson(String json) { |
| | | return WxMaGsonBuilder.create().fromJson(json, WxServerResponse.class); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.serializer.json; |
| | | |
| | | import cn.hutool.core.util.ArrayUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.fasterxml.jackson.core.JsonGenerator; |
| | | import com.fasterxml.jackson.databind.JsonSerializer; |
| | | import com.fasterxml.jackson.databind.SerializerProvider; |
| | | import com.yami.shop.common.bean.Domain; |
| | | import com.yami.shop.common.bean.SysConfig; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.common.util.CacheManagerUtil; |
| | | import com.yami.shop.common.util.Json; |
| | | import com.yami.shop.common.util.SpringContextUtils; |
| | | import org.apache.ibatis.session.SqlSession; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.regex.Matcher; |
| | | import java.util.regex.Pattern; |
| | | |
| | | /** |
| | | * 图片加上前缀 |
| | | * @author yami |
| | | */ |
| | | @Component |
| | | public class ImgJsonSerializer extends JsonSerializer<String> { |
| | | |
| | | @Override |
| | | public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException { |
| | | CacheManagerUtil cacheManagerUtil = SpringContextUtils.getBean(CacheManagerUtil.class); |
| | | if (StrUtil.isBlank(value)) { |
| | | gen.writeString(StrUtil.EMPTY); |
| | | return; |
| | | } |
| | | String[] imgs = value.split(StrUtil.COMMA); |
| | | StringBuilder sb = new StringBuilder(); |
| | | if (ArrayUtil.isEmpty(imgs)) { |
| | | gen.writeString(sb.toString()); |
| | | return; |
| | | } |
| | | |
| | | String rule="^((http[s]{0,1})://)"; |
| | | Pattern pattern= Pattern.compile(rule); |
| | | |
| | | Domain domain = cacheManagerUtil.getCache("SysConfigObject", Constant.DOMAIN_CONFIG); |
| | | if (domain == null) { |
| | | SysConfig config = SpringContextUtils.getBean(SqlSession.class).selectOne("com.yami.shop.dao.SysConfigMapper.queryByKey", Constant.DOMAIN_CONFIG); |
| | | domain = Json.parseObject(config.getParamValue(),Domain.class); |
| | | cacheManagerUtil.putCache("SysConfigObject", Constant.DOMAIN_CONFIG, domain); |
| | | } |
| | | |
| | | for (String img : imgs) { |
| | | Matcher matcher=pattern.matcher(img); |
| | | //若图片以http或https开头,直接返回 |
| | | if (matcher.find()){ |
| | | sb.append(img).append(StrUtil.COMMA); |
| | | }else { |
| | | sb.append(domain.getResourcesDomainName()).append("/").append(img).append(StrUtil.COMMA); |
| | | } |
| | | } |
| | | sb.deleteCharAt(sb.length()-1); |
| | | gen.writeString(sb.toString()); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.util; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 算术工具类 |
| | | * @author yami |
| | | */ |
| | | public class Arith { |
| | | /** |
| | | * 默认除法运算精度 |
| | | */ |
| | | private static final int DEF_DIV_SCALE = 10; |
| | | |
| | | /** |
| | | * 这个类不能实例化 |
| | | */ |
| | | private Arith() { |
| | | } |
| | | |
| | | /** |
| | | * 提供精确的加法运算。. |
| | | * |
| | | * @param v1 被加数 |
| | | * @param v2 加数 |
| | | * @return 两个参数的和 |
| | | */ |
| | | public static double add(double v1, double v2) { |
| | | String s1 = Double.toString(v1); |
| | | String s2 = Double.toString(v2); |
| | | // 必须转换成String |
| | | BigDecimal b1 = new BigDecimal(s1); |
| | | BigDecimal b2 = new BigDecimal(s2); |
| | | return b1.add(b2).doubleValue(); |
| | | } |
| | | |
| | | /** |
| | | * 提供精确的加法运算。. |
| | | * |
| | | * @param v1 被加数 |
| | | * @param v2 加数 |
| | | * @return 两个参数的和 |
| | | */ |
| | | public static double addMayBeEmpty(Double v1, Double v2) { |
| | | if(Objects.isNull(v1)){ |
| | | v1 = 0.0; |
| | | } |
| | | if(Objects.isNull(v2)){ |
| | | v2 = 0.0; |
| | | } |
| | | String s1 = Double.toString(v1); |
| | | String s2 = Double.toString(v2); |
| | | // 必须转换成String |
| | | BigDecimal b1 = new BigDecimal(s1); |
| | | BigDecimal b2 = new BigDecimal(s2); |
| | | return b1.add(b2).doubleValue(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 提供精确的减法运算。. |
| | | * |
| | | * @param v1 被减数 |
| | | * @param v2 减数 |
| | | * @return 两个参数的差 |
| | | */ |
| | | public static double sub(double v1, double v2) { |
| | | String s1 = Double.toString(v1); |
| | | String s2 = Double.toString(v2); |
| | | // 必须转换成String |
| | | BigDecimal b1 = new BigDecimal(s1); |
| | | BigDecimal b2 = new BigDecimal(s2); |
| | | return b1.subtract(b2).doubleValue(); |
| | | } |
| | | |
| | | /** |
| | | * 提供精确的乘法运算。. |
| | | * |
| | | * @param v1 被乘数 |
| | | * @param v2 乘数 |
| | | * @return 两个参数的积 |
| | | */ |
| | | public static double mul(double v1, double v2) { |
| | | String s1 = Double.toString(v1); |
| | | String s2 = Double.toString(v2); |
| | | // 必须转换成String |
| | | BigDecimal b1 = new BigDecimal(s1); |
| | | BigDecimal b2 = new BigDecimal(s2); |
| | | return b1.multiply(b2).doubleValue(); |
| | | } |
| | | |
| | | /** |
| | | * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入。. |
| | | * |
| | | * @param v1 被除数 |
| | | * @param v2 除数 |
| | | * @return 两个参数的商 |
| | | */ |
| | | public static double div(double v1, double v2) { |
| | | if (v2 == 0){ |
| | | return 0.0; |
| | | } |
| | | return div(v1, v2, DEF_DIV_SCALE); |
| | | } |
| | | |
| | | /** |
| | | * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指定精度,以后的数字采用银行家舍入 |
| | | * |
| | | * @param v1 被除数 |
| | | * @param v2 除数 |
| | | * @param scale 表示表示需要精确到小数点以后几位。 |
| | | * @return 两个参数的商 |
| | | */ |
| | | public static double div(double v1, double v2, int scale) { |
| | | if (scale < 0) { |
| | | throw new IllegalArgumentException("The scale must be a positive integer or zero"); |
| | | } |
| | | if (v2 == 0){ |
| | | return 0.0; |
| | | } |
| | | String s1 = Double.toString(v1); |
| | | String s2 = Double.toString(v2); |
| | | // 必须转换成String |
| | | BigDecimal b1 = new BigDecimal(s1); |
| | | BigDecimal b2 = new BigDecimal(s2); |
| | | return b1.divide(b2, scale, RoundingMode.HALF_EVEN).doubleValue(); |
| | | } |
| | | |
| | | /** |
| | | * 提供精确的小数位银行家舍入法 |
| | | * |
| | | * @param v 需要处理的数字 |
| | | * @param scale 小数点后保留几位 |
| | | * @return 结果 |
| | | */ |
| | | public static double roundByBanker(double v, int scale) { |
| | | if (scale < 0) { |
| | | throw new IllegalArgumentException("The scale must be a positive integer or zero"); |
| | | } |
| | | String s = Double.toString(v); |
| | | BigDecimal b = new BigDecimal(s); |
| | | BigDecimal one = new BigDecimal("1"); |
| | | return b.divide(one, scale, RoundingMode.HALF_EVEN).doubleValue(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * @param bigDecimal |
| | | * @param bigDecimal2 |
| | | * @param bigDecimal3 |
| | | * @return |
| | | */ |
| | | public static double add(BigDecimal bigDecimal, BigDecimal bigDecimal2, BigDecimal bigDecimal3) { |
| | | return bigDecimal.add(bigDecimal2).add(bigDecimal3).doubleValue(); |
| | | } |
| | | |
| | | /** |
| | | * @param preDepositPrice |
| | | * @param finalPrice |
| | | * @return |
| | | */ |
| | | public static double add(BigDecimal preDepositPrice, BigDecimal finalPrice) { |
| | | return preDepositPrice.add(finalPrice).doubleValue(); |
| | | } |
| | | |
| | | /** |
| | | * 两个浮点数比较是否相等 |
| | | * @param v1 |
| | | * @param v2 |
| | | * @return |
| | | */ |
| | | public static boolean isEquals(double v1, double v2) { |
| | | String s1 = Double.toString(v1); |
| | | String s2 = Double.toString(v2); |
| | | // 必须转换成String |
| | | BigDecimal b1 = new BigDecimal(s1); |
| | | BigDecimal b2 = new BigDecimal(s2); |
| | | return Objects.equals(b1,b2); |
| | | } |
| | | |
| | | /** |
| | | * 计算百分比 |
| | | * @param a 被除数 |
| | | * @param b 除数 |
| | | * @param scale 保留小数位 |
| | | * @param percentage 放大倍数 |
| | | * @return 放大倍数后的数值 |
| | | */ |
| | | public static BigDecimal calculatePercentage(Integer a, Integer b, int scale, Integer percentage) { |
| | | boolean isCalculate = Objects.isNull(a) || Objects.isNull(b) || Objects.isNull(percentage) || |
| | | a.compareTo(0)==0 || b<0 || percentage.compareTo(0)==0 ; |
| | | if (isCalculate) { |
| | | return new BigDecimal("0"); |
| | | } |
| | | BigDecimal bigDecimal = new BigDecimal(a.toString()); |
| | | BigDecimal divisor = new BigDecimal(b.toString()); |
| | | BigDecimal multiplicand = new BigDecimal(percentage.toString()); |
| | | return bigDecimal.multiply(multiplicand).divide(divisor,scale, RoundingMode.HALF_EVEN); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.util; |
| | | |
| | | /** |
| | | * 用于构造百度地图中的经纬度点 |
| | | * |
| | | * @author zhengtian |
| | | * @date 2013-8-5 下午02:54:41 |
| | | */ |
| | | public class BmapPoint { |
| | | /** 经度 */ |
| | | private double lng; |
| | | /** 纬度 */ |
| | | private double lat; |
| | | |
| | | public BmapPoint() { |
| | | |
| | | } |
| | | |
| | | public BmapPoint(double lng, double lat) { |
| | | this.lng = lng; |
| | | this.lat = lat; |
| | | } |
| | | |
| | | @Override |
| | | public boolean equals(Object obj) { |
| | | if (obj instanceof BmapPoint) { |
| | | BmapPoint bmapPoint = (BmapPoint) obj; |
| | | return (bmapPoint.getLng() == lng && bmapPoint.getLat() == lat) ? true : false; |
| | | } else { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | public double getLng() { |
| | | return lng; |
| | | } |
| | | |
| | | public void setLng(double lng) { |
| | | this.lng = lng; |
| | | } |
| | | |
| | | public double getLat() { |
| | | return lat; |
| | | } |
| | | |
| | | public void setLat(double lat) { |
| | | this.lat = lat; |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.util; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.cache.Cache; |
| | | import org.springframework.cache.CacheManager; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * 缓存工具类 |
| | | * @author yami |
| | | */ |
| | | @Component |
| | | @AllArgsConstructor |
| | | public class CacheManagerUtil { |
| | | |
| | | private CacheManager cacheManager; |
| | | |
| | | @SuppressWarnings({"unchecked"}) |
| | | public <T> T getCache(String cacheName,String key) { |
| | | Cache cache = cacheManager.getCache(cacheName); |
| | | if (cache == null) { |
| | | return null; |
| | | } |
| | | Cache.ValueWrapper valueWrapper = cache.get(key); |
| | | if (valueWrapper == null) { |
| | | return null; |
| | | } |
| | | return (T)valueWrapper.get(); |
| | | } |
| | | |
| | | public void putCache(String cacheName,String key, Object value) { |
| | | Cache cache = cacheManager.getCache(cacheName); |
| | | if (cache != null) { |
| | | cache.put(key, value); |
| | | } |
| | | } |
| | | |
| | | public void evictCache(String cacheName,String key) { |
| | | Cache cache = cacheManager.getCache(cacheName); |
| | | if (cache != null) { |
| | | cache.evict(key); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.util; |
| | | |
| | | /** |
| | | * 获取带有中文字符的长度 |
| | | * @author yami |
| | | */ |
| | | public class CharUtil { |
| | | /** |
| | | * 得到一个字符串的长度,显示的长度,一个汉字或日韩文长度为2,英文字符长度为1 |
| | | * @param s 需要得到长度的字符串 |
| | | * @return int 得到的字符串长度 |
| | | */ |
| | | public static int length(String s) { |
| | | if (s == null) { |
| | | return 0; |
| | | } |
| | | int len = 0; |
| | | for (char item : s.toCharArray()) { |
| | | len++; |
| | | if (item / 0x80 == 0) { |
| | | continue; |
| | | } |
| | | len++; |
| | | } |
| | | return len; |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.util; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * 时间参数 |
| | | * @author yami |
| | | */ |
| | | @Data |
| | | public class DateParam { |
| | | |
| | | private Date startTime; |
| | | |
| | | private Date endTime; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.util; |
| | | |
| | | import cn.hutool.core.date.DateTime; |
| | | import cn.hutool.core.date.DateUnit; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import com.yami.shop.common.bean.DateVO; |
| | | |
| | | import java.text.ParseException; |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.time.LocalTime; |
| | | import java.time.ZoneId; |
| | | import java.time.temporal.ChronoUnit; |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * 时间工具类 |
| | | * @author yami |
| | | */ |
| | | public class DateUtils { |
| | | |
| | | public static final String yyyy = "yyyy"; |
| | | public static final String MM = "MM"; |
| | | public static final String dd = "dd"; |
| | | public static final String yyyyMMdd = "yyyyMMdd"; |
| | | public static final String yyyy_MM_dd = "yyyy-MM-dd"; |
| | | public static final String yyyy_MM_ddHHmmSS = "yyyy-MM-dd HH:mm:ss"; |
| | | |
| | | public static String formatDate(String format){ |
| | | SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format); |
| | | return simpleDateFormat.format(new Date()); |
| | | } |
| | | |
| | | public static Long dateToNumber(Date date) { |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); |
| | | String format = sdf.format(date); |
| | | Long value = 0L; |
| | | try { |
| | | value = Long.valueOf(format); |
| | | } catch (Exception e) { |
| | | return value; |
| | | } |
| | | return value; |
| | | } |
| | | public static String dateToStrYmd(Date date) { |
| | | String format = "yyyy-MM-dd"; |
| | | return DateUtil.format(date,format); |
| | | } |
| | | |
| | | public static Date strToDateYmd(String date) { |
| | | String format = "yyyy-MM-dd"; |
| | | return DateUtil.parse(date,format); |
| | | } |
| | | |
| | | public static Date strToDate(String date) { |
| | | String format = "yyyy-MM-dd HH:mm:ss"; |
| | | return DateUtil.parse(date,format); |
| | | } |
| | | |
| | | public static List<Date> findDates(Date dBegin, Date dEnd) { |
| | | List lDate = new ArrayList(); |
| | | lDate.add(dBegin); |
| | | Calendar cBegin = Calendar.getInstance(); |
| | | Calendar cEnd = Calendar.getInstance(); |
| | | // 使用给定的 Date 设置此 Calendar 的时间 |
| | | cBegin.setTime(dBegin); |
| | | cEnd.setTime(dEnd); |
| | | |
| | | cEnd.add(Calendar.DAY_OF_MONTH,-2); |
| | | // 测试此日期是否在指定日期之后 |
| | | while (cEnd.getTime().after(cBegin.getTime())) { |
| | | // 根据日历的规则,为给定的日历字段添加或减去指定的时间量 |
| | | cBegin.add(Calendar.DAY_OF_MONTH, 1); |
| | | lDate.add(dateToLast(cBegin.getTime())); |
| | | } |
| | | return lDate; |
| | | } |
| | | |
| | | public static List<DateParam> findEveryDays(Date dBegin, Date dEnd) { |
| | | List<DateParam> params = new ArrayList(); |
| | | Calendar calBegin = Calendar.getInstance(); |
| | | // 使用给定的 Date 设置此 Calendar 的时间 |
| | | calBegin.setTime(dBegin); |
| | | Calendar calEnd = Calendar.getInstance(); |
| | | // 使用给定的 Date 设置此 Calendar 的时间 |
| | | calEnd.setTime(dEnd); |
| | | calEnd.add(Calendar.DAY_OF_MONTH,-2); |
| | | // 判断两个时间是否为同一天 |
| | | if (!DateUtil.isSameDay(dBegin, dEnd)) { |
| | | DateParam first = new DateParam(); |
| | | first.setStartTime(dBegin); |
| | | first.setEndTime(dateToLast(dBegin)); |
| | | params.add(first); |
| | | } |
| | | // 测试此日期是否在指定日期之后 |
| | | while (calEnd.getTime().after(calBegin.getTime())) { |
| | | DateParam res = new DateParam(); |
| | | // 根据日历的规则,为给定的日历字段添加或减去指定的时间量 |
| | | calBegin.add(Calendar.DAY_OF_MONTH, 1); |
| | | res.setEndTime(dateToLast(calBegin.getTime())); |
| | | res.setStartTime(dateToFast(calBegin.getTime())); |
| | | params.add(res); |
| | | } |
| | | DateParam last = new DateParam(); |
| | | last.setStartTime(dateToFast(dEnd)); |
| | | last.setEndTime(dEnd); |
| | | params.add(last); |
| | | return params; |
| | | } |
| | | public static Date dateToFast(Date date) { |
| | | return dateToFastOrLast(date,1); |
| | | } |
| | | public static Date dateToLast(Date date) { |
| | | return dateToFastOrLast(date,2); |
| | | } |
| | | |
| | | /** |
| | | * 获取传入时间的前一天的初始和结束时间 |
| | | */ |
| | | public static Date getBeforeDate(Date date){ |
| | | Calendar instance = Calendar.getInstance(); |
| | | instance.setTime(date); |
| | | instance.add(Calendar.DATE, -1); |
| | | return instance.getTime(); |
| | | } |
| | | |
| | | /** |
| | | * 根据传入日期获取t天前的开始和结束日期 |
| | | * @param t 具体天数 >0 则为当前日期后几天,反之为前几天 |
| | | * @return |
| | | */ |
| | | public static DateVO getDay(int t) { |
| | | LocalDate localDate = LocalDate.now(); |
| | | if (t > 0) { |
| | | localDate = localDate.plusDays(Math.abs(t)); |
| | | } else { |
| | | localDate = localDate.minusDays(Math.abs(t)); |
| | | } |
| | | LocalDateTime min = LocalDateTime.of(localDate, LocalTime.MIN); |
| | | Date minDate = Date.from(min.atZone(ZoneId.systemDefault()).toInstant()); |
| | | LocalDateTime max = LocalDateTime.of(localDate, LocalTime.MAX); |
| | | Date maxDate = Date.from(max.atZone(ZoneId.systemDefault()).toInstant()); |
| | | DateVO dateVO = new DateVO(minDate, maxDate); |
| | | return dateVO; |
| | | } |
| | | /** |
| | | * 获取传入时间的前n年时间点 |
| | | * @param n 例如: n = -1 表示当前时间的前一年, n = 1 表示获取后一年 |
| | | */ |
| | | public static Date getBeforeYear(Date date, int n) { |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(date); |
| | | calendar.add(Calendar.YEAR, n); |
| | | return calendar.getTime(); |
| | | } |
| | | /** |
| | | * 获取传入时间的前n月时间点 |
| | | * @param n 例如: n = -1 表示当前时间的前一月, n = 1 表示获取后一月 |
| | | */ |
| | | public static Date getBeforeOrNextNumMonth(Date date, int n) { |
| | | Calendar instance = Calendar.getInstance(); |
| | | instance.setTime(date); |
| | | instance.add(Calendar.MONTH, n); |
| | | return instance.getTime(); |
| | | } |
| | | /** |
| | | * 获取传入时间的前n天时间点 |
| | | * @param n 例如: n = -1 表示当前时间的前一天, n = 1 表示获取后一天 |
| | | */ |
| | | public static Date getBeforeDay(Date date, int n) { |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(date); |
| | | calendar.add(Calendar.DATE, n); |
| | | return calendar.getTime(); |
| | | } |
| | | |
| | | public static String dateToString(Date date) { |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | return sdf.format(date); |
| | | } |
| | | /** |
| | | * |
| | | * @param date 2020-06-12 15:00:00 |
| | | * @param type 1 date 的开始时间例如: 2020-06-12 00:00:00 |
| | | * 2 date 的结束时间例如: 2020-06-12 23:59:59 |
| | | * @return |
| | | */ |
| | | public static Date dateToFastOrLast(Date date, Integer type) { |
| | | Calendar c = Calendar.getInstance(); |
| | | c.setTime(date); |
| | | int y = c.get(Calendar.YEAR); |
| | | int m = c.get(Calendar.MONTH ) + 1; |
| | | int d = c.get(Calendar.DAY_OF_MONTH); |
| | | String dateStr = ""; |
| | | if (Objects.equals(1,type)){ |
| | | dateStr = y + "-" + m + "-" + d +" " + 00 + ":"+ 00 + ":" + 00; |
| | | } else { |
| | | dateStr = y + "-" + m + "-" + d +" " + 23 + ":"+ 59 + ":" + 59; |
| | | } |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | try { |
| | | Date parse = sdf.parse(dateStr); |
| | | c.setTime(parse); |
| | | }catch (ParseException e) { |
| | | System.out.println("解析异常"); |
| | | } |
| | | return c.getTime(); |
| | | } |
| | | |
| | | public static List<DateParam> getMonthBetweenStartTimeAndEndTime(Date startTime, Date endTime) { |
| | | List<DateParam> monthBetween = getMonthBetween(startTime, endTime); |
| | | if (monthBetween.size() == 0) { |
| | | DateParam param = new DateParam(); |
| | | param.setStartTime(startTime); |
| | | param.setEndTime(endTime); |
| | | monthBetween.add(param); |
| | | return monthBetween; |
| | | } |
| | | if (monthBetween.size() == 1) { |
| | | DateParam param = monthBetween.get(0); |
| | | param.setEndTime(endTime); |
| | | monthBetween.set(0,param); |
| | | return monthBetween; |
| | | } |
| | | DateParam param = monthBetween.get(0); |
| | | param.setStartTime(startTime); |
| | | DateParam last = monthBetween.get(monthBetween.size() - 1); |
| | | last.setEndTime(endTime); |
| | | monthBetween.set(0,param); |
| | | monthBetween.set(monthBetween.size()-1,last); |
| | | return monthBetween; |
| | | } |
| | | |
| | | public static List<DateParam> getMonthBetween(Date minDate, Date maxDate){ |
| | | List<DateParam> res = new ArrayList<>(); |
| | | Calendar min = Calendar.getInstance(); |
| | | Calendar max = Calendar.getInstance(); |
| | | |
| | | min.setTime(minDate); |
| | | min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1); |
| | | |
| | | max.setTime(maxDate); |
| | | max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2); |
| | | |
| | | Calendar curr = min; |
| | | while (curr.before(max)) { |
| | | DateParam param = new DateParam(); |
| | | Date time = curr.getTime(); |
| | | param.setStartTime(getMonthFirstOrLastDay(time,0)); |
| | | param.setEndTime(getMonthFirstOrLastDay(time,1)); |
| | | res.add(param); |
| | | curr.add(Calendar.MONTH, 1); |
| | | } |
| | | return res; |
| | | } |
| | | |
| | | public static int countMonthNumBetweenDate(Date startTime, Date endTime) { |
| | | Calendar min = Calendar.getInstance(); |
| | | min.setTime(startTime); |
| | | Calendar max = Calendar.getInstance(); |
| | | max.setTime(endTime); |
| | | int year =max.get(Calendar.YEAR) - min.get(Calendar.YEAR); |
| | | //开始日期若小月结束日期 |
| | | if(year < 0){ |
| | | year = -year; |
| | | return year*12 + min.get(Calendar.MONTH) - max.get(Calendar.MONTH); |
| | | } |
| | | return year*12 + max.get(Calendar.MONTH) - min.get(Calendar.MONTH); |
| | | } |
| | | |
| | | // public static int countDayBetweenDate(Date startTime, Date endTime) { |
| | | // long day = DateUtil.betweenDay(startTime, endTime, true); |
| | | // return Integer.valueOf(String.valueOf(day)); |
| | | // } |
| | | |
| | | /** |
| | | * @param date 传入的时间点 2020-03-12 15:30:00 |
| | | * @param type 0 获取传入时间的月份开始时间 2020-03-01 00:00:00 |
| | | * 1 获取传入时间的月份最后一天的时刻 2020-03-31 23:59:59 |
| | | * @return date |
| | | */ |
| | | public static Date getMonthFirstOrLastDay(Date date,Integer type) { |
| | | Calendar c = Calendar.getInstance(); |
| | | c.setTime(date); |
| | | if (Objects.equals(0,type)){ |
| | | // 获取传入时间的月份的第一天 yyyy-MM-dd 00:00:00 |
| | | c.add(Calendar.MONTH,0); |
| | | c.set(Calendar.DAY_OF_MONTH,1); |
| | | c.set(Calendar.HOUR_OF_DAY,00); |
| | | c.set(Calendar.MINUTE,00); |
| | | c.set(Calendar.SECOND,00); |
| | | } else { |
| | | // 获取传入时间的月份的最后一天 yyyy-MM-dd 23:59:59 |
| | | c.add(Calendar.MONTH,1); |
| | | c.set(Calendar.DAY_OF_MONTH,0); |
| | | c.set(Calendar.HOUR_OF_DAY,23); |
| | | c.set(Calendar.MINUTE,59); |
| | | c.set(Calendar.SECOND,59); |
| | | } |
| | | return c.getTime(); |
| | | } |
| | | |
| | | /** |
| | | * 开始时间和结束时间的时间差n天 |
| | | * 结束时间是开始时间,开始时间的前n天作为开始时间 |
| | | * @param startTime 开始时间 |
| | | * @param endTime 结束时间 |
| | | * @return 参数 |
| | | */ |
| | | public static DateParam getPreDateByRangeTime(Date startTime, Date endTime) { |
| | | DateParam param = new DateParam(); |
| | | long days = DateUtil.between(startTime, endTime, DateUnit.DAY); |
| | | DateTime dateTime = DateUtil.offsetDay(startTime, -(int) days); |
| | | param.setStartTime(DateUtil.beginOfDay(dateTime)); |
| | | param.setEndTime(DateUtil.endOfDay(startTime)); |
| | | return param; |
| | | } |
| | | |
| | | public static boolean flagIn30DayDate(String str) { |
| | | String YYYY_MM_DD = "yyyy-MM-dd"; |
| | | int day = -30; |
| | | boolean convertSuccess = false; |
| | | //时间格式定义 |
| | | SimpleDateFormat format = new SimpleDateFormat(YYYY_MM_DD); |
| | | //获取当前时间日期--nowDate |
| | | String nowDate = format.format(new Date()); |
| | | //获取30天前的时间日期--minDate |
| | | Calendar calc = Calendar.getInstance(); |
| | | calc.add(Calendar.DAY_OF_MONTH, day); |
| | | String minDate = format.format(calc.getTime()); |
| | | try { |
| | | //设置lenient为false. 否则SimpleDateFormat会比较宽松地验证日期,比如2007/02/29会被接受,并转换成2007/03/01 |
| | | format.setLenient(false); |
| | | //获取字符串转换后的时间--strDate |
| | | String strDates = format.format(format.parse(str)); |
| | | if (nowDate.compareTo(strDates) >= 0 && strDates.compareTo(minDate) >= 0){ |
| | | convertSuccess = true; |
| | | } |
| | | } catch (ParseException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return convertSuccess; |
| | | } |
| | | |
| | | /** |
| | | * localDateTime转Date |
| | | * @param localDateTime |
| | | * @return |
| | | */ |
| | | public static Date toDate(LocalDateTime localDateTime) { |
| | | return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()); |
| | | } |
| | | |
| | | /** |
| | | * 获取本周开始时间 |
| | | */ |
| | | public static Date getCurrentWeekStartTimes(Date date) { |
| | | Calendar cal = Calendar.getInstance(); |
| | | cal.setTime(date); |
| | | cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0); |
| | | cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); |
| | | return cal.getTime(); |
| | | } |
| | | |
| | | /** |
| | | * 获取本周结束时间 |
| | | */ |
| | | public static Date getCurrentWeekEndTimes(Date date) { |
| | | Calendar cal = Calendar.getInstance(); |
| | | cal.setTime(getCurrentWeekStartTimes(date)); |
| | | cal.add(Calendar.DAY_OF_WEEK, 6); |
| | | cal.set(Calendar.HOUR_OF_DAY, 23); |
| | | cal.set(Calendar.MINUTE, 59); |
| | | cal.set(Calendar.SECOND, 59); |
| | | cal.set(Calendar.MILLISECOND, 999); |
| | | return cal.getTime(); |
| | | } |
| | | |
| | | /** |
| | | * 获取当年的开始时间戳 |
| | | * |
| | | * @return |
| | | */ |
| | | public static Date getCurrentYearStartTime(Date date) { |
| | | Calendar calendar = Calendar.getInstance();// 获取当前日期 |
| | | calendar.setTimeInMillis(date.getTime()); |
| | | calendar.add(Calendar.YEAR, 0); |
| | | calendar.add(Calendar.MONTH, 0); |
| | | calendar.set(Calendar.DAY_OF_YEAR, 1); |
| | | calendar.set(Calendar.HOUR_OF_DAY, 0); |
| | | calendar.set(Calendar.MINUTE, 0); |
| | | calendar.set(Calendar.SECOND, 0); |
| | | calendar.set(Calendar.MILLISECOND, 0); |
| | | return calendar.getTime(); |
| | | } |
| | | |
| | | /** |
| | | * 获取当年的最后时间戳 |
| | | * |
| | | * @return |
| | | */ |
| | | public static Date getCurrentYearEndTime(Date date) { |
| | | Calendar calendar = Calendar.getInstance();// 获取当前日期 |
| | | calendar.setTimeInMillis(date.getTime()); |
| | | int year = calendar.get(Calendar.YEAR); |
| | | calendar.clear(); |
| | | calendar.set(Calendar.YEAR, year); |
| | | calendar.set(Calendar.HOUR_OF_DAY, 23); |
| | | calendar.set(Calendar.MINUTE, 59); |
| | | calendar.set(Calendar.SECOND, 59); |
| | | calendar.set(Calendar.MILLISECOND, 999); |
| | | calendar.roll(Calendar.DAY_OF_YEAR, -1); |
| | | return calendar.getTime(); |
| | | } |
| | | |
| | | /** |
| | | * 获取当天剩余时间(秒) |
| | | * @return |
| | | */ |
| | | public static long getCurrentDayEndSec() { |
| | | // 获取当前时间 |
| | | LocalDateTime now = LocalDateTime.now(); |
| | | // 设置当天结束的时间为23:59:59 |
| | | LocalDateTime endOfDay = now.withHour(23).withMinute(59).withSecond(59); |
| | | // 如果当前时间已经超过23:59:59,则应该计算到明天的结束时间 |
| | | if (now.toLocalTime().isAfter(LocalTime.of(23, 59, 59))) { |
| | | endOfDay = endOfDay.plusDays(1); |
| | | } |
| | | // 计算时间差 |
| | | long duration = ChronoUnit.SECONDS.between(now, endOfDay); |
| | | return duration; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.util; |
| | | |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | |
| | | /** |
| | | * 用于点与多边形位置关系的判断 |
| | | * |
| | | * @author lhd |
| | | * @date 2020-5-22 上午09:59:35 |
| | | */ |
| | | public class GraphUtils { |
| | | |
| | | public static int TWO = 2; |
| | | /** |
| | | * 判断点是否在多边形内(基本思路是用交点法) |
| | | * |
| | | * @param point |
| | | * @param boundaryPoints |
| | | * @return |
| | | */ |
| | | public static boolean isPointInPolygon(BmapPoint point, List<BmapPoint> boundaryPoints) { |
| | | if(CollectionUtils.isEmpty(boundaryPoints) || Objects.isNull(point)){ |
| | | return false; |
| | | } |
| | | int pointCount = boundaryPoints.size(); |
| | | |
| | | // 首先判断点是否在多边形的外包矩形内,如果在,则进一步判断,否则返回false |
| | | if (!isPointInRectangle(point, boundaryPoints)) { |
| | | return false; |
| | | } |
| | | // 如果点与多边形的其中一个顶点重合,那么直接返回true |
| | | for (BmapPoint boundaryPoint : boundaryPoints) { |
| | | if (point.equals(boundaryPoint)) { |
| | | return true; |
| | | } |
| | | } |
| | | /* |
| | | 基本思想是利用X轴射线法,计算射线与多边形各边的交点,如果是偶数,则点在多边形外,否则在多边形内。还会考虑一些特殊情况,如点在多边形顶点上 |
| | | , 点在多边形边上等特殊情况。 |
| | | */ |
| | | // X轴射线与多边形的交点数 |
| | | int intersectPointCount = 0; |
| | | // X轴射线与多边形的交点权值 |
| | | float intersectPointWeights = 0; |
| | | // 浮点类型计算时候与0比较时候的容差 |
| | | double precision = 2e-10; |
| | | // 边P1P2的两个端点 |
| | | BmapPoint point1 = boundaryPoints.get(0), point2; |
| | | // 循环判断所有的边 |
| | | for (int i = 1; i <= pointCount; i++) { |
| | | point2 = boundaryPoints.get(i % pointCount); |
| | | |
| | | /* |
| | | 如果点的y坐标在边P1P2的y坐标开区间范围之外,那么不相交。 |
| | | */ |
| | | if (point.getLat() < Math.min(point1.getLat(), point2.getLat()) |
| | | || point.getLat() > Math.max(point1.getLat(), point2.getLat())) { |
| | | point1 = point2; |
| | | continue; |
| | | } |
| | | |
| | | /* |
| | | 此处判断射线与边相交 |
| | | */ |
| | | // 如果点的y坐标在边P1P2的y坐标开区间内 |
| | | if (point.getLat() > Math.min(point1.getLat(), point2.getLat()) |
| | | && point.getLat() < Math.max(point1.getLat(), point2.getLat())) { |
| | | // 若边P1P2是垂直的 |
| | | if (point1.getLng() == point2.getLng()) { |
| | | if (point.getLng() == point1.getLng()) { |
| | | // 若点在垂直的边P1P2上,则点在多边形内 |
| | | return true; |
| | | } else if (point.getLng() < point1.getLng()) { |
| | | // 若点在在垂直的边P1P2左边,则点与该边必然有交点 |
| | | ++intersectPointCount; |
| | | } |
| | | } else { |
| | | // 若边P1P2是斜线 |
| | | // 点point的x坐标在点P1和P2的左侧 |
| | | if (point.getLng() <= Math.min(point1.getLng(), point2.getLng())) { |
| | | ++intersectPointCount; |
| | | // 点point的x坐标在点P1和P2的x坐标中间 |
| | | } else if (point.getLng() > Math.min(point1.getLng(), point2.getLng()) |
| | | && point.getLng() < Math.max(point1.getLng(), point2.getLng())) { |
| | | double slopeDiff = 0.0d; |
| | | if (point1.getLat() > point2.getLat()) { |
| | | slopeDiff = (point.getLat() - point2.getLat()) / (point.getLng() - point2.getLng()) |
| | | - (point1.getLat() - point2.getLat()) / (point1.getLng() - point2.getLng()); |
| | | } else { |
| | | slopeDiff = (point.getLat() - point1.getLat()) / (point.getLng() - point1.getLng()) |
| | | - (point2.getLat() - point1.getLat()) / (point2.getLng() - point1.getLng()); |
| | | } |
| | | if (slopeDiff > 0) { |
| | | // 由于double精度在计算时会有损失,故匹配一定的容差。经试验,坐标经度可以达到0.0001 |
| | | if (slopeDiff < precision) { |
| | | // 点在斜线P1P2上 |
| | | return true; |
| | | } else { |
| | | // 点与斜线P1P2有交点 |
| | | intersectPointCount++; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } else { |
| | | // 边P1P2水平 |
| | | if (point1.getLat() == point2.getLat()) { |
| | | if (point.getLng() <= Math.max(point1.getLng(), point2.getLng()) |
| | | && point.getLng() >= Math.min(point1.getLng(), point2.getLng())) { |
| | | // 若点在水平的边P1P2上,则点在多边形内 |
| | | return true; |
| | | } |
| | | } |
| | | // 判断点通过多边形顶点 |
| | | boolean res = ((point.getLat() == point1.getLat() && point.getLng() < point1.getLng())) |
| | | || (point.getLat() == point2.getLat() && point.getLng() < point2.getLng()); |
| | | if (res) { |
| | | if (point2.getLat() < point1.getLat()) { |
| | | intersectPointWeights += -0.5; |
| | | } else if (point2.getLat() > point1.getLat()) { |
| | | intersectPointWeights += 0.5; |
| | | } |
| | | } |
| | | } |
| | | point1 = point2; |
| | | } |
| | | // 偶数在多边形外 |
| | | // 奇数在多边形内 |
| | | return (intersectPointCount + Math.abs(intersectPointWeights)) % TWO != 0; |
| | | } |
| | | |
| | | /** |
| | | * 判断点是否在矩形内在矩形边界上,也算在矩形内(根据这些点,构造一个外包矩形) |
| | | * |
| | | * @param point |
| | | * 点对象 |
| | | * @param boundaryPoints |
| | | * 矩形边界点 |
| | | * @return |
| | | */ |
| | | public static boolean isPointInRectangle(BmapPoint point, List<BmapPoint> boundaryPoints) { |
| | | // 西南角点 |
| | | BmapPoint southWestPoint = getSouthWestPoint(boundaryPoints); |
| | | // 东北角点 |
| | | BmapPoint northEastPoint = getNorthEastPoint(boundaryPoints); |
| | | return (point.getLng() >= southWestPoint.getLng() && point.getLng() <= northEastPoint.getLng() |
| | | && point.getLat() >= southWestPoint.getLat() && point.getLat() <= northEastPoint.getLat()); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 根据这组坐标,画一个矩形,然后得到这个矩形西南角的顶点坐标 |
| | | * |
| | | * @param vertexs |
| | | * @return |
| | | */ |
| | | private static BmapPoint getSouthWestPoint(List<BmapPoint> vertexs) { |
| | | double minLng = vertexs.get(0).getLng(), minLat = vertexs.get(0).getLat(); |
| | | for (BmapPoint bmapPoint : vertexs) { |
| | | double lng = bmapPoint.getLng(); |
| | | double lat = bmapPoint.getLat(); |
| | | if (lng < minLng) { |
| | | minLng = lng; |
| | | } |
| | | if (lat < minLat) { |
| | | minLat = lat; |
| | | } |
| | | } |
| | | return new BmapPoint(minLng, minLat); |
| | | } |
| | | |
| | | /** |
| | | * 根据这组坐标,画一个矩形,然后得到这个矩形东北角的顶点坐标 |
| | | * |
| | | * @param vertexs |
| | | * @return |
| | | */ |
| | | private static BmapPoint getNorthEastPoint(List<BmapPoint> vertexs) { |
| | | double maxLng = 0.0d, maxLat = 0.0d; |
| | | for (BmapPoint bmapPoint : vertexs) { |
| | | double lng = bmapPoint.getLng(); |
| | | double lat = bmapPoint.getLat(); |
| | | if (lng > maxLng) { |
| | | maxLng = lng; |
| | | } |
| | | if (lat > maxLat) { |
| | | maxLat = lat; |
| | | } |
| | | } |
| | | return new BmapPoint(maxLng, maxLat); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.util; |
| | | |
| | | import cn.hutool.core.lang.Snowflake; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | import java.util.UUID; |
| | | |
| | | /** |
| | | * 进制转换工具,最大支持十进制和DICT.length()进制的转换 |
| | | * 1、将十进制的数字转换为指定进制的字符串; |
| | | * 2、将其它进制的数字(字符串形式)转换为十进制的数字 |
| | | * @author xuliugen |
| | | * @date 2018/04/23 |
| | | */ |
| | | @Component |
| | | public class HandCardUtil { |
| | | |
| | | |
| | | /** |
| | | * 获取随机串码 |
| | | * @param |
| | | * @return |
| | | */ |
| | | public static String getHandCard() { |
| | | UUID uuid = UUID.randomUUID(); |
| | | String str = uuid.toString().replace("-", "").substring(0, 20); |
| | | return str; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.util; |
| | | |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import lombok.experimental.UtilityClass; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.web.context.request.RequestContextHolder; |
| | | import org.springframework.web.context.request.ServletRequestAttributes; |
| | | |
| | | import javax.servlet.ServletInputStream; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.io.IOException; |
| | | import java.nio.charset.StandardCharsets; |
| | | |
| | | /** |
| | | * @author LGH |
| | | */ |
| | | @Slf4j |
| | | @UtilityClass |
| | | public class HttpContextUtils{ |
| | | |
| | | /** |
| | | * 请求字符串的最大长度 1m |
| | | */ |
| | | public static final int MAX_STRING_SIZE = 1024 * 1024; |
| | | |
| | | public HttpServletRequest getHttpServletRequest() { |
| | | return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); |
| | | } |
| | | |
| | | public String getDomain(){ |
| | | HttpServletRequest request = getHttpServletRequest(); |
| | | StringBuffer url = request.getRequestURL(); |
| | | return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString(); |
| | | } |
| | | |
| | | public String getOrigin(){ |
| | | HttpServletRequest request = getHttpServletRequest(); |
| | | return request.getHeader("Origin"); |
| | | } |
| | | |
| | | |
| | | public String getStringFromStream(HttpServletRequest req) { |
| | | if (req.getContentLength() > MAX_STRING_SIZE) { |
| | | // 请求数据过长 |
| | | throw new YamiShopBindException("yami.request.data.too.long"); |
| | | } |
| | | ServletInputStream is; |
| | | try { |
| | | is = req.getInputStream(); |
| | | int nRead = 1; |
| | | int nTotalRead = 0; |
| | | byte[] bytes = new byte[1024]; |
| | | while (nRead > 0) { |
| | | nRead = is.read(bytes, nTotalRead, bytes.length - nTotalRead); |
| | | if (nRead > 0) { |
| | | nTotalRead = nTotalRead + nRead; |
| | | } |
| | | } |
| | | if (nTotalRead > MAX_STRING_SIZE) { |
| | | // 请求数据过长 |
| | | throw new YamiShopBindException("yami.request.data.too.long"); |
| | | } |
| | | return new String(bytes, 0, nTotalRead, StandardCharsets.UTF_8); |
| | | } catch (IOException e) { |
| | | log.error("IOException:", e); |
| | | return ""; |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.util; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | |
| | | /** |
| | | * IP帮助工具 |
| | | * @author yami |
| | | */ |
| | | public class IPHelper { |
| | | private static final String UNKNOWN = "unknown"; |
| | | |
| | | /** |
| | | * 得到用户的真实地址,如果有多个就取第一个 |
| | | * |
| | | * @return |
| | | */ |
| | | public static String getIpAddr() { |
| | | HttpServletRequest request = HttpContextUtils.getHttpServletRequest(); |
| | | if (request == null) { |
| | | return null; |
| | | } |
| | | String ip = request.getHeader("x-forwarded-for"); |
| | | if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { |
| | | ip = request.getHeader("Proxy-Client-IP"); |
| | | } |
| | | if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { |
| | | ip = request.getHeader("WL-Proxy-Client-IP"); |
| | | } |
| | | if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { |
| | | ip = request.getRemoteAddr(); |
| | | } |
| | | String[] ips = ip.split(","); |
| | | return ips[0].trim(); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.yami.shop.common.util; |
| | | |
| | | import java.text.ParseException; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Calendar; |
| | | import java.util.Date; |
| | | import java.util.Scanner; |
| | | |
| | | public class IdCardCheck { |
| | | |
| | | /* |
| | | 在lesson02中设计一个名字为IdCardCheck.java类,实现从键盘 输入一个身份证号码字符串, |
| | | 判断输入的字符串是否符合身份证号码的规则,如果符合,计算输出年龄 输出它的年龄,输出你 |
| | | 出生在那一年的第几周以及出生到现在已经经过了几周了。如果不符合,提示,并让其重新输入。 |
| | | 直到输入正确省份证号码为止 |
| | | */ |
| | | |
| | | //441225200002312559 //检验码正确,但2月份没有31天 |
| | | //441225201012092558 //生成的正确格式的身份证号码 |
| | | public void test() throws ParseException { |
| | | Scanner sc = new Scanner(System.in); |
| | | String idNum; |
| | | do { |
| | | System.out.println("请输入身份证号码:"); |
| | | idNum = sc.nextLine(); |
| | | } while (!checkIdCardNum(idNum)); |
| | | |
| | | System.out.println("身份证号码\"" + idNum + "\"正确!"); |
| | | System.out.println("持卡人的年龄:" + getYear(idNum)); |
| | | System.out.println("出生的所在那一周是出生那年的第 " + getBirthWeek(idNum) + " 周"); |
| | | System.out.println("从出生到现在过去了 " + getWeeks(idNum) + " 周"); |
| | | |
| | | } |
| | | |
| | | //身份证号码的严格校验 |
| | | public boolean checkIdCardNum(String idNum) throws ParseException { |
| | | idNum = idNum.toUpperCase(); //将末尾可能存在的x转成X |
| | | |
| | | String regex = ""; |
| | | regex += "^[1-6]\\d{5}"; //前6位地址码。后面仍需打表校验 |
| | | |
| | | regex += "(18|19|20)\\d{2}"; //年份。后面仍需校验 |
| | | regex += "((0[1-9])|(1[0-2]))"; //月份。后面仍需校验 |
| | | regex += "(([0-2][1-9])|10|20|30|31)"; //日期。后面仍需校验 |
| | | |
| | | regex += "\\d{3}"; //3位顺序码 |
| | | |
| | | regex += "[0-9X]"; //检验码。后面仍需验证 |
| | | |
| | | if (!idNum.matches(regex)) |
| | | return false; |
| | | |
| | | //第1,2位(省)打表进一步校验 |
| | | int[] d = {11, 12, 13, 14, 15, |
| | | 21, 22, 23, 31, 32, 33, 34, 35, 36, 37, |
| | | 41, 42, 43, |
| | | 44, 45, 46, |
| | | 50, 51, 52, 53, 53, |
| | | 61, 62, 63, 64, 65, |
| | | 83, 81, 82}; |
| | | boolean flag = false; |
| | | int prov = Integer.parseInt(idNum.substring(0, 2)); |
| | | for (int i = 0; i < d.length; i++) |
| | | if (d[i] == prov) { |
| | | flag = true; |
| | | break; |
| | | } |
| | | if (!flag) |
| | | return false; |
| | | |
| | | //生日校验:生日的时间不能比当前时间(指程序检测用户输入的身份证号码的时候)晚 |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); |
| | | Date birthDate = sdf.parse(idNum.substring(6, 14)); |
| | | Date curDate = new Date(); |
| | | if (birthDate.getTime() > curDate.getTime()) |
| | | return false; |
| | | |
| | | //生日校验:每个月的天数不一样(有的月份没有31),还要注意闰年的二月 |
| | | int year = Integer.parseInt(idNum.substring(6, 10)); |
| | | int leap = ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) ? 1 : 0; |
| | | final int[] month = {0, 31, 28 + leap, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; |
| | | int mon = Integer.parseInt(idNum.substring(10, 12)); |
| | | int day = Integer.parseInt(idNum.substring(12, 14)); |
| | | if (day > month[mon]) { |
| | | //System.out.println(day+" "+month[mon]+"\n"); |
| | | //System.out.println("---"); |
| | | return false; |
| | | } |
| | | |
| | | |
| | | //检验码 |
| | | if (idNum.charAt(17) != getLastChar(idNum)) |
| | | return false; |
| | | |
| | | return true; |
| | | } |
| | | |
| | | //根据身份证号码的前17位计算校验码 |
| | | public char getLastChar(String idNum) //由于这个功能比较独立,就分离出来 |
| | | { |
| | | final int[] w = {0, 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; |
| | | final char[] ch = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'}; //这就是为什么一开始将末尾可能存在的x转成X的原因 |
| | | int res = 0; |
| | | for (int i = 0; i < 17; i++) { |
| | | int t = idNum.charAt(i) - '0'; |
| | | res += (t * w[i + 1]); |
| | | } |
| | | return ch[res % 11]; |
| | | } |
| | | |
| | | //根据身份证号码的出生日期计算年龄 |
| | | public int getYear(String idNum) { |
| | | int yearBirth = Integer.parseInt(idNum.substring(6, 10)); |
| | | int monBirth = Integer.parseInt(idNum.substring(10, 12)); |
| | | int dayBirth = Integer.parseInt(idNum.substring(12, 14)); |
| | | |
| | | Calendar cur = Calendar.getInstance(); |
| | | int yearCur = cur.get(Calendar.YEAR); |
| | | int monCur = cur.get(Calendar.MONTH) + 1; //不要忘了+1 |
| | | int dayCur = cur.get(Calendar.DATE); |
| | | |
| | | |
| | | //System.out.println(yearCur+" "+monCur+" "+dayCur); |
| | | int age = yearCur - yearBirth; |
| | | if (monCur < monBirth || (monCur == monBirth && dayCur < dayBirth)) |
| | | age--; |
| | | |
| | | return age; |
| | | } |
| | | |
| | | //出生的所在那一周是出生那年的第几周 |
| | | public int getBirthWeek(String idNum) throws ParseException, ParseException { |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); |
| | | Date birthDate = sdf.parse(idNum.substring(6, 14)); //默认0时0分0秒 |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(birthDate); |
| | | return calendar.get(Calendar.WEEK_OF_YEAR); |
| | | } |
| | | |
| | | //从出生到现在过去了多少周 |
| | | public int getWeeks(String idNum) throws ParseException { |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); |
| | | Date birthDate = sdf.parse(idNum.substring(6, 14)); //默认0时0分0秒 |
| | | Date curDate = new Date(); |
| | | return (int) ((curDate.getTime() - birthDate.getTime()) / (long) (7 * 24 * 60 * 60 * 1000)); //不建议把分子转成int,可能会溢出 |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.util; |
| | | |
| | | import cn.hutool.core.lang.Snowflake; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 进制转换工具,最大支持十进制和DICT.length()进制的转换 |
| | | * 1、将十进制的数字转换为指定进制的字符串; |
| | | * 2、将其它进制的数字(字符串形式)转换为十进制的数字 |
| | | * @author xuliugen |
| | | * @date 2018/04/23 |
| | | */ |
| | | @Component |
| | | public class IdUtil { |
| | | |
| | | @Autowired(required = false) |
| | | private Snowflake snowflake; |
| | | |
| | | private static final String DICT = "0123456789abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"; |
| | | |
| | | private static final int SEED = DICT.length(); |
| | | |
| | | private static final int ID_MIN_LENGTH = 6; |
| | | /** |
| | | * 数字->字符映射 |
| | | */ |
| | | private static final char[] CHARS = DICT.toCharArray(); |
| | | /** |
| | | * 字符->数字映射 |
| | | */ |
| | | private static final Map<Character, Integer> NUMBERS = new HashMap<>(); |
| | | |
| | | static { |
| | | int len = CHARS.length; |
| | | for (int i = 0; i<len; i++) { |
| | | NUMBERS.put(CHARS[i], i); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 根据从数据库中返回的记录ID生成对应的短网址编码 |
| | | * @param id (1-56.8billion) |
| | | * @return |
| | | */ |
| | | public static String encode(long id) { |
| | | StringBuilder shortUrl = new StringBuilder(); |
| | | while (id > 0) { |
| | | int r = (int) (id % SEED); |
| | | shortUrl.insert(0, CHARS[r]); |
| | | id = id / SEED; |
| | | } |
| | | int len = shortUrl.length(); |
| | | while (len < ID_MIN_LENGTH) { |
| | | shortUrl.insert(0, CHARS[0]); |
| | | len++; |
| | | } |
| | | return shortUrl.toString(); |
| | | } |
| | | |
| | | /** |
| | | * 根据获得的短网址编码解析出数据库中对应的记录ID |
| | | * @param key 短网址 eg. RwTji8, GijT7Y等等 |
| | | * @return |
| | | */ |
| | | public static long decode(String key) { |
| | | char[] shorts = key.toCharArray(); |
| | | int len = shorts.length; |
| | | long id = 0L; |
| | | for (int i = 0; i < len; i++) { |
| | | id = id + (long) (NUMBERS.get(shorts[i]) * Math.pow(SEED, len-i-1)); |
| | | } |
| | | return id; |
| | | } |
| | | |
| | | |
| | | public String nextShortId() { |
| | | return encode(snowflake.nextId()); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.util; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | |
| | | import javax.imageio.ImageIO; |
| | | import java.awt.*; |
| | | import java.awt.image.BufferedImage; |
| | | import java.io.ByteArrayOutputStream; |
| | | import java.io.IOException; |
| | | import java.net.URL; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 图片处理工具类 |
| | | * @author yami |
| | | */ |
| | | public class ImageUtil { |
| | | |
| | | /** |
| | | * 将图片转为二进制数组 |
| | | * @param imgUrl |
| | | * @return |
| | | */ |
| | | public static byte[] imgToBinary(String imgUrl) { |
| | | try { |
| | | BufferedImage bufferedImage = ImageIO.read(new URL(imgUrl)); |
| | | ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| | | String suffix = imgUrlFileType(imgUrl); |
| | | //ImageIO无法写入jpeg文件 报Invalid argument to native writeImage,需重画 |
| | | if(StrUtil.equals(suffix, "jpg") || StrUtil.equals(suffix, "jpeg")){ |
| | | BufferedImage tag; |
| | | tag = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(), BufferedImage.TYPE_INT_BGR); |
| | | Graphics g = tag.getGraphics(); |
| | | g.drawImage(bufferedImage, 0, 0, null); |
| | | g.dispose(); |
| | | bufferedImage = tag; |
| | | } |
| | | ImageIO.write(bufferedImage, suffix, baos); |
| | | byte[] bytes = baos.toByteArray(); |
| | | return bytes; |
| | | } catch (IOException e) { |
| | | // 图片丢失,请重新上传图片 |
| | | throw new YamiShopBindException("yami.img.lose"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @param imgUrl |
| | | * @return 文件得后缀,文件类型 jpg , png , ... |
| | | */ |
| | | public static String imgUrlFileType(String imgUrl) { |
| | | if (StrUtil.isBlank(imgUrl)) { |
| | | return imgUrl; |
| | | } |
| | | imgUrl.trim(); |
| | | String[] split = imgUrl.split("\\."); |
| | | String s = split[split.length - 1]; |
| | | return s; |
| | | } |
| | | |
| | | /** |
| | | * @param imgUrl |
| | | * @return 获取文件名称 |
| | | */ |
| | | public static String imgUrlFileName(String imgUrl) { |
| | | if (StrUtil.isBlank(imgUrl)) { |
| | | return imgUrl; |
| | | } |
| | | imgUrl.trim(); |
| | | String[] split = imgUrl.split("/"); |
| | | String s = split[split.length - 1]; |
| | | return s; |
| | | } |
| | | /** |
| | | * @param imgUrl |
| | | * @return 获取文件名称 45d3631e97d8438d80f9db1369595b8c |
| | | */ |
| | | public static String imgUrlFileNameNoSuffix(String imgUrl) { |
| | | if (StrUtil.isBlank(imgUrl)) { |
| | | return imgUrl; |
| | | } |
| | | imgUrl.trim(); |
| | | String[] split = imgUrl.split("/"); |
| | | String s = split[split.length - 1]; |
| | | String[] split1 = s.split("\\."); |
| | | return split1[0]; |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.util; |
| | | |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonInclude; |
| | | import com.fasterxml.jackson.core.JsonProcessingException; |
| | | import com.fasterxml.jackson.core.json.JsonWriteFeature; |
| | | import com.fasterxml.jackson.databind.DeserializationFeature; |
| | | import com.fasterxml.jackson.databind.JsonNode; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import com.fasterxml.jackson.databind.SerializationFeature; |
| | | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * json 工具类 |
| | | * @author yami |
| | | */ |
| | | @Slf4j |
| | | public class Json { |
| | | |
| | | private static ObjectMapper objectMapper = new ObjectMapper(); |
| | | static { |
| | | // 是否缩放排列输出,默认false,有些场合为了便于排版阅读则需要对输出做缩放排列 |
| | | // objectMapper.enable(SerializationFeature.INDENT_OUTPUT); |
| | | // 序列化日期时以timestamps输出,默认true |
| | | // objectMapper.enable(SerializationFeature.INDENT_OUTPUT); |
| | | // 序列化枚举是以toString()来输出,默认false,即默认以name()来输出 如:ENUM01("enum_01") 默认为 ENUM01,true则为enum_01 |
| | | // objectMapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING); |
| | | // 序列化枚举是以ordinal()来输出,默认false 如:ENUM01("enum_01") 默认为 ENUM01,true则为 0 非常危险 |
| | | // objectMapper.enable(SerializationFeature.WRITE_ENUMS_USING_INDEX); |
| | | // 序列化Map时对key进行排序操作,默认false |
| | | // objectMapper.enable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS); |
| | | // 序列化char[]时以json数组输出,默认false |
| | | //objectMapper.enable(SerializationFeature.WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS); |
| | | //序列化BigDecimal时之间输出原始数字还是科学计数,默认false,即是否以toPlainString()科学计数方式来输出 |
| | | // 1E+20 -> 100000000000000000000 |
| | | // objectMapper.enable(Feature.WRITE_BIGDECIMAL_AS_PLAIN); |
| | | |
| | | // 如果为空则不输出 |
| | | objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); |
| | | // 对于空的对象转json的时候不抛出错误 |
| | | objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); |
| | | // 禁用序列化日期为timestamps |
| | | objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); |
| | | // 禁用遇到未知属性抛出异常 |
| | | objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); |
| | | // 视空字符传为null |
| | | // objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT); |
| | | |
| | | // 低层级配置 |
| | | // objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true); |
| | | // 允许属性名称没有引号 |
| | | // objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); |
| | | // 允许单引号 |
| | | // objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); |
| | | |
| | | // 取消对非ASCII字符的转码 |
| | | objectMapper.configure(JsonWriteFeature.ESCAPE_NON_ASCII.mappedFeature(), false); |
| | | // 取消过时objectMapper.configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, false) |
| | | objectMapper.registerModule(new JavaTimeModule()); |
| | | } |
| | | |
| | | /** |
| | | * 对象转json |
| | | * @param object |
| | | * @return |
| | | */ |
| | | public static String toJsonString(Object object) { |
| | | try { |
| | | return objectMapper.writeValueAsString(object); |
| | | } catch (JsonProcessingException e) { |
| | | log.error("对象转json错误:", e); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * json转对象 |
| | | * @param json |
| | | * @param clazz |
| | | * @return |
| | | */ |
| | | public static <T> T parseObject(String json, Class<T> clazz) { |
| | | if (json == null) { |
| | | return null; |
| | | } |
| | | T result = null; |
| | | try { |
| | | result = objectMapper.readValue(json, clazz); |
| | | } catch (Exception e) { |
| | | log.error("json转对象错误:", e); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * json转换换成对象 |
| | | * @param src src |
| | | * @param clazz clazz |
| | | * @return Class |
| | | */ |
| | | public static <T> T parseObject(byte[] src, Class<T> clazz) { |
| | | T result = null; |
| | | try { |
| | | result = objectMapper.readValue(src, clazz); |
| | | } |
| | | catch (Exception e) { |
| | | e.printStackTrace(); |
| | | log.error("parseObject() error: {}", e.getMessage()); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | public static ObjectMapper getObjectMapper() { |
| | | return objectMapper; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * * https://stackoverflow.com/questions/6349421/how-to-use-jackson-to-deserialise-an-array-of-objects |
| | | * * List<MyClass> myObjects = Arrays.asList(mapper.readValue(json, MyClass[].class)) |
| | | * * works up to 10 time faster than TypeRefence. |
| | | * @return |
| | | */ |
| | | public static <T> List<T> parseArray(String json, Class<T[]> clazz){ |
| | | if (json == null) { |
| | | return null; |
| | | } |
| | | T[] result = null; |
| | | try { |
| | | result = objectMapper.readValue(json, clazz); |
| | | } catch (Exception e) { |
| | | log.error("Exception:", e); |
| | | } |
| | | if (result == null) { |
| | | return Collections.emptyList(); |
| | | } |
| | | return Arrays.asList(result); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 转换成json节点,即map |
| | | * @param jsonStr |
| | | * @return |
| | | */ |
| | | public static JsonNode parseJson(String jsonStr) { |
| | | if (jsonStr == null) { |
| | | return null; |
| | | } |
| | | JsonNode jsonNode = null; |
| | | try { |
| | | jsonNode = objectMapper.readTree(jsonStr); |
| | | } catch (Exception e) { |
| | | log.error("Exception:", e); |
| | | } |
| | | return jsonNode; |
| | | } |
| | | |
| | | // public static void main(String[] args){ |
| | | // String arr = "[1.01,1.03,1.23]"; |
| | | // |
| | | // List<Double> doubles = parseArray(arr, Double[].class); |
| | | // for (Double aDouble : doubles) { |
| | | // System.out.println(aDouble); |
| | | // } |
| | | // |
| | | // } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.util; |
| | | |
| | | import cn.hutool.core.util.PageUtil; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 分页适配 |
| | | * @author LGH |
| | | */ |
| | | @Data |
| | | public class PageAdapter{ |
| | | |
| | | private int begin; |
| | | |
| | | private int size; |
| | | |
| | | public PageAdapter(Page page) { |
| | | int[] startEnd = PageUtil.transToStartEnd((int) page.getCurrent() - 1, (int) page.getSize()); |
| | | this.begin = startEnd[0]; |
| | | this.size = (int)page.getSize(); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.util; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.OrderItem; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import io.swagger.v3.oas.annotations.Hidden; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import org.springdoc.api.annotations.ParameterObject; |
| | | |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | /** |
| | | * 分页参数 |
| | | * @author yami |
| | | */ |
| | | @Schema |
| | | @ParameterObject |
| | | public class PageParam<T> extends Page<T> { |
| | | |
| | | |
| | | /** |
| | | * 每页显示条数,默认 10 |
| | | */ |
| | | @Schema(description = "每页大小,默认10") |
| | | private long size = 10; |
| | | |
| | | /** |
| | | * 当前页 |
| | | */ |
| | | @Schema(description = "当前页,默认1") |
| | | private long current = 1; |
| | | |
| | | /** |
| | | * 查询数据列表 |
| | | */ |
| | | @Hidden |
| | | private List<T> records; |
| | | /** |
| | | * 总数 |
| | | */ |
| | | @Hidden |
| | | private long total = 0; |
| | | |
| | | |
| | | /** |
| | | * 是否进行 count 查询 |
| | | */ |
| | | @Hidden |
| | | private boolean isSearchCount = true; |
| | | |
| | | @Hidden |
| | | private String countId; |
| | | @Hidden |
| | | private Long maxLimit; |
| | | @Hidden |
| | | private boolean optimizeCountSql; |
| | | @Hidden |
| | | private List<OrderItem> orders; |
| | | |
| | | @Override |
| | | public List<T> getRecords() { |
| | | return this.records; |
| | | } |
| | | |
| | | @Override |
| | | public Page<T> setRecords(List<T> records) { |
| | | this.records = records; |
| | | return this; |
| | | } |
| | | |
| | | @Override |
| | | public long getTotal() { |
| | | return this.total; |
| | | } |
| | | |
| | | @Override |
| | | public Page<T> setTotal(long total) { |
| | | this.total = total; |
| | | return this; |
| | | } |
| | | |
| | | @Hidden |
| | | public boolean getSearchCount() { |
| | | if (total < 0) { |
| | | return false; |
| | | } |
| | | return isSearchCount; |
| | | } |
| | | |
| | | @Override |
| | | public boolean isSearchCount() { |
| | | if (total < 0) { |
| | | return false; |
| | | } |
| | | return isSearchCount; |
| | | } |
| | | |
| | | @Override |
| | | public Page<T> setSearchCount(boolean isSearchCount) { |
| | | this.isSearchCount = isSearchCount; |
| | | return this; |
| | | } |
| | | |
| | | @Override |
| | | public long getSize() { |
| | | return this.size; |
| | | } |
| | | |
| | | @Override |
| | | public Page<T> setSize(long size) { |
| | | if (size > 100) { |
| | | this.size = 100; |
| | | } else { |
| | | this.size = size; |
| | | } |
| | | return this; |
| | | } |
| | | |
| | | @Override |
| | | public long getCurrent() { |
| | | return this.current; |
| | | } |
| | | |
| | | @Override |
| | | public Page<T> setCurrent(long current) { |
| | | this.current = current; |
| | | return this; |
| | | } |
| | | |
| | | @Override |
| | | public void setOrders(List<OrderItem> orders) { |
| | | super.setOrders(Collections.emptyList()); |
| | | } |
| | | |
| | | /** @deprecated */ |
| | | @Deprecated |
| | | public String getCountId() { |
| | | return this.countId; |
| | | } |
| | | |
| | | /** @deprecated */ |
| | | @Deprecated |
| | | public Long getMaxLimit() { |
| | | return this.maxLimit; |
| | | } |
| | | |
| | | /** @deprecated */ |
| | | @Deprecated |
| | | public List<OrderItem> getOrders() { |
| | | return this.orders; |
| | | } |
| | | |
| | | /** @deprecated */ |
| | | @Deprecated |
| | | public boolean isOptimizeCountSql() { |
| | | return this.optimizeCountSql; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.yami.shop.common.util; |
| | | |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.math.BigInteger; |
| | | import java.security.MessageDigest; |
| | | import java.security.NoSuchAlgorithmException; |
| | | |
| | | @Component |
| | | public class PayUtil { |
| | | 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 |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.util; |
| | | |
| | | import cn.hutool.core.date.DatePattern; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import cn.hutool.core.io.IORuntimeException; |
| | | import cn.hutool.core.io.IoUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.hutool.poi.excel.ExcelWriter; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.apache.poi.ss.usermodel.*; |
| | | import org.apache.poi.ss.util.CellRangeAddress; |
| | | import org.apache.poi.ss.util.CellRangeAddressList; |
| | | import org.apache.poi.xssf.usermodel.XSSFDataValidation; |
| | | import org.apache.poi.xssf.usermodel.XSSFDataValidationConstraint; |
| | | |
| | | import javax.servlet.ServletOutputStream; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | import java.io.OutputStream; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.text.NumberFormat; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 功能: poi导出excel工具类 |
| | | * |
| | | * @author lhd |
| | | */ |
| | | @Slf4j |
| | | public class PoiExcelUtil { |
| | | |
| | | /** |
| | | * 合并单元格处理,获取合并行 |
| | | * |
| | | * @param sheet |
| | | * @return List<CellRangeAddress> |
| | | */ |
| | | public static List<CellRangeAddress> getCombineCell(Sheet sheet) { |
| | | List<CellRangeAddress> list = new ArrayList<CellRangeAddress>(); |
| | | // 获得一个 sheet 中合并单元格的数量 |
| | | int sheetmergerCount = sheet.getNumMergedRegions(); |
| | | // 遍历所有的合并单元格 |
| | | for (int i = 0; i < sheetmergerCount; i++) { |
| | | // 获得合并单元格保存进list中 |
| | | CellRangeAddress ca = sheet.getMergedRegion(i); |
| | | list.add(ca); |
| | | } |
| | | return list; |
| | | } |
| | | |
| | | public static int getRowNum(List<CellRangeAddress> listCombineCell, Cell cell, Sheet sheet) { |
| | | int xr = 0; |
| | | int firstC = 0; |
| | | int lastC = 0; |
| | | int firstR = 0; |
| | | int lastR = 0; |
| | | for (CellRangeAddress ca : listCombineCell) { |
| | | // 获得合并单元格的起始行, 结束行, 起始列, 结束列 |
| | | firstC = ca.getFirstColumn(); |
| | | lastC = ca.getLastColumn(); |
| | | firstR = ca.getFirstRow(); |
| | | lastR = ca.getLastRow(); |
| | | if (cell.getRowIndex() >= firstR && cell.getRowIndex() <= lastR) { |
| | | if (cell.getColumnIndex() >= firstC && cell.getColumnIndex() <= lastC) { |
| | | xr = lastR; |
| | | } |
| | | } |
| | | } |
| | | return xr; |
| | | } |
| | | |
| | | /** |
| | | * 简单格式化校验,返回字符串类型,如果是int类型还需进行处理,Double.valueOf(value).intValue() |
| | | * |
| | | * @param row 行数据 |
| | | * @param cellNum 单元格 |
| | | * @param isNum 是否为数值类型 |
| | | * @return |
| | | */ |
| | | public static String getRowValue(Row row, Integer cellNum, Boolean isNum) { |
| | | // 单品名称 |
| | | String value = null; |
| | | CellType cellType = null; |
| | | try { |
| | | cellType = row.getCell(cellNum).getCellType(); |
| | | } catch (NullPointerException e) { |
| | | return isNum ? "0" : null; |
| | | } |
| | | if (Objects.equals(CellType.NUMERIC, cellType)) { |
| | | |
| | | if (org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(row.getCell(cellNum))) { |
| | | Date time = row.getCell(cellNum).getDateCellValue(); |
| | | SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | value = format.format(time); |
| | | } else { |
| | | NumberFormat numberFormat = NumberFormat.getInstance(); |
| | | // 不显示千位分割符,否则显示结果会变成类似1,234,567,890 |
| | | numberFormat.setGroupingUsed(false); |
| | | double d = row.getCell(cellNum).getNumericCellValue(); |
| | | value = numberFormat.format(d); |
| | | |
| | | } |
| | | } else { |
| | | value = Objects.isNull(row.getCell(cellNum)) ? "" : row.getCell(cellNum).getStringCellValue(); |
| | | } |
| | | if (isNum) { |
| | | return StrUtil.isBlank(value) ? "0" : value; |
| | | } |
| | | return value; |
| | | } |
| | | |
| | | /** |
| | | * 判断指定的单元格是否是合并单元格 |
| | | * |
| | | * @param sheet |
| | | * @param row 行下标 |
| | | * @param column 列下标 |
| | | * @return |
| | | */ |
| | | public static boolean isMergedRegion(Sheet sheet, int row, int column) { |
| | | int sheetMergeCount = sheet.getNumMergedRegions(); |
| | | for (int i = 0; i < sheetMergeCount; i++) { |
| | | CellRangeAddress range = sheet.getMergedRegion(i); |
| | | int firstColumn = range.getFirstColumn(); |
| | | int lastColumn = range.getLastColumn(); |
| | | int firstRow = range.getFirstRow(); |
| | | int lastRow = range.getLastRow(); |
| | | if (row >= firstRow && row <= lastRow) { |
| | | if (column >= firstColumn && column <= lastColumn) { |
| | | return true; |
| | | } |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 如果需要合并的话,就合并 |
| | | */ |
| | | public static void mergeIfNeed(ExcelWriter writer, int firstRow, int lastRow, int firstColumn, int lastColumn, Object content) { |
| | | if (content instanceof Date) { |
| | | content = DateUtil.format((Date) content, DatePattern.NORM_DATETIME_PATTERN); |
| | | } |
| | | if (lastRow - firstRow > 0 || lastColumn - firstColumn > 0) { |
| | | writer.merge(firstRow, lastRow, firstColumn, lastColumn, content, false); |
| | | } else { |
| | | writer.writeCellValue(firstColumn, firstRow, content); |
| | | } |
| | | |
| | | } |
| | | |
| | | public static void writeExcel(HttpServletResponse response, ExcelWriter writer) { |
| | | //response为HttpServletResponse对象 |
| | | response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); |
| | | //test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码 |
| | | response.setHeader("Content-Disposition", "attachment;filename=1.xlsx"); |
| | | |
| | | ServletOutputStream servletOutputStream = null; |
| | | try { |
| | | servletOutputStream = response.getOutputStream(); |
| | | writer.flush(servletOutputStream); |
| | | servletOutputStream.flush(); |
| | | } catch (IORuntimeException | IOException e) { |
| | | log.error("写出Excel发生错误:", e); |
| | | } finally { |
| | | IoUtil.close(writer); |
| | | } |
| | | } |
| | | |
| | | public static void writeExcel(String filename, ExcelWriter writer, HttpServletResponse response) { |
| | | OutputStream ouputStream = null; |
| | | try { |
| | | filename = new String(filename.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1); |
| | | response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); |
| | | response.setHeader("Content-disposition", "attachment;filename=" + filename); |
| | | ouputStream = response.getOutputStream(); |
| | | writer.flush(ouputStream); |
| | | ouputStream.flush(); |
| | | } catch (Exception e) { |
| | | log.error("写出Excel发生错误:", e); |
| | | } finally { |
| | | IoUtil.close(writer); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 创建下拉列表选项 |
| | | * |
| | | * @param workbook 当前写入器 |
| | | * @param sheet 所在Sheet页面 |
| | | * @param list 下拉框的选项值 |
| | | * @param firstRow 起始行(从0开始) |
| | | * @param lastRow 终止行(从0开始) |
| | | * @param firstCol 起始列(从0开始) |
| | | * @param lastCol 终止列(从0开始) |
| | | */ |
| | | public static void createDropDownList(Workbook workbook, Sheet sheet, List<String> list, int firstRow, int lastRow, int firstCol, int lastCol) { |
| | | if (CollectionUtils.isEmpty(list)) { |
| | | return; |
| | | } |
| | | int sheetTotal = workbook.getNumberOfSheets(); |
| | | // 设置下拉框数据 |
| | | // 新建一个sheet,把数据隐藏,从单元格引用就没有255的报错 |
| | | String sheetName = "hidden" + sheetTotal; |
| | | Sheet hidden = workbook.getSheet(sheetName); |
| | | if (Objects.isNull(hidden)) { |
| | | hidden = workbook.createSheet(sheetName); |
| | | for (int i = 0; i < list.size(); i++) { |
| | | Row row = hidden.createRow(i); |
| | | Cell cell = row.createCell(0); |
| | | cell.setCellValue(list.get(i)); |
| | | } |
| | | workbook.setSheetHidden(sheetTotal, true); |
| | | } |
| | | String strFormula = sheetName + "!$A$1:$A$65535"; |
| | | DataValidationConstraint constraint = new XSSFDataValidationConstraint(DataValidationConstraint.ValidationType.LIST, strFormula); |
| | | CellRangeAddressList regions = new CellRangeAddressList(firstRow, lastRow, firstCol, lastCol); |
| | | DataValidationHelper help = hidden.getDataValidationHelper(); |
| | | DataValidation dataValidation = help.createValidation(constraint, regions); |
| | | sheet.addValidationData(dataValidation); |
| | | // Excel兼容性问题 |
| | | if (dataValidation instanceof XSSFDataValidation) { |
| | | dataValidation.setSuppressDropDownArrow(true); |
| | | dataValidation.setShowErrorBox(true); |
| | | } else { |
| | | dataValidation.setSuppressDropDownArrow(false); |
| | | } |
| | | sheet.addValidationData(dataValidation); |
| | | } |
| | | |
| | | /** |
| | | * 创建下拉列表选项【适用长度不会超过255的】 |
| | | * |
| | | * @param sheet 所在Sheet页面 |
| | | * @param values 下拉框的选项值 |
| | | * @param firstRow 起始行(从0开始) |
| | | * @param lastRow 终止行(从0开始) |
| | | * @param firstCol 起始列(从0开始) |
| | | * @param lastCol 终止列(从0开始) |
| | | */ |
| | | public static void createDropDownList(Sheet sheet, String[] values, int firstRow, int lastRow, int firstCol, int lastCol) { |
| | | DataValidationHelper helper = sheet.getDataValidationHelper(); |
| | | CellRangeAddressList addressList = new CellRangeAddressList(firstRow, lastRow, firstCol, lastCol); |
| | | // 设置下拉框数据 |
| | | DataValidationConstraint constraint = helper.createExplicitListConstraint(values); |
| | | DataValidation dataValidation = helper.createValidation(constraint, addressList); |
| | | // Excel兼容性问题 |
| | | if (dataValidation instanceof XSSFDataValidation) { |
| | | dataValidation.setSuppressDropDownArrow(true); |
| | | dataValidation.setShowErrorBox(true); |
| | | } else { |
| | | dataValidation.setSuppressDropDownArrow(false); |
| | | } |
| | | sheet.addValidationData(dataValidation); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.util; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | |
| | | import java.util.regex.Pattern; |
| | | |
| | | /** |
| | | * 正则表达式工具 |
| | | * @author LGH |
| | | */ |
| | | public class PrincipalUtil { |
| | | |
| | | /** |
| | | * 以1开头,后面跟10位数 |
| | | */ |
| | | public static final String MOBILE_REGEXP = "1[0-9]{10}"; |
| | | /** |
| | | * 电话号码 |
| | | */ |
| | | public static final String TEL_REGEXP = "([0-9]{3,4}-)?[0-9]{7,8}"; |
| | | /** |
| | | * 微信号 |
| | | */ |
| | | public static final String WX_NUMBER_REGEXP = "[a-zA-Z][a-zA-Z\\d_-]{5,19}$"; |
| | | /** |
| | | * QQ号 |
| | | */ |
| | | public static final String QQ_NUMBER_REGEXP = "[1-9][0-9]{4,14}"; |
| | | /** |
| | | * 1. 用户名不能为纯数字 2. 由数字字母下划线 4-16位组成 |
| | | */ |
| | | public static final String USER_NAME_REGEXP = "(?!\\d+$)([a-zA-Z0-9_]{4,16})"; |
| | | |
| | | /** |
| | | * 字段名,数字字母下划线 |
| | | */ |
| | | public static final String FIELD_REGEXP = "([a-zA-Z0-9_]+)"; |
| | | |
| | | /** |
| | | * 只能输入数字字母 |
| | | */ |
| | | public static final String WITHOUT_CHINESE = "^[A-Za-z0-9]+$"; |
| | | |
| | | /** |
| | | * 由简单的字母数字拼接而成的字符串 不含有下划线,大写字母 |
| | | */ |
| | | public static final String SIMPLE_CHAR_REGEXP = "([a-z0-9]+)"; |
| | | |
| | | /** |
| | | * 邮箱正则 |
| | | */ |
| | | public static final String MAIL_REGEXP = "([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})"; |
| | | |
| | | public static boolean isMobile(String value) { |
| | | if(StrUtil.isBlank(value)) { |
| | | return false; |
| | | } |
| | | return Pattern.matches(MOBILE_REGEXP, value); |
| | | } |
| | | |
| | | public static boolean isTel(String value) { |
| | | if(StrUtil.isBlank(value)) { |
| | | return false; |
| | | } |
| | | return Pattern.matches(TEL_REGEXP, value); |
| | | } |
| | | |
| | | public static boolean isWxNumber(String value) { |
| | | if(StrUtil.isBlank(value)) { |
| | | return false; |
| | | } |
| | | return Pattern.matches(WX_NUMBER_REGEXP, value); |
| | | } |
| | | |
| | | public static boolean isQQNumber(String value) { |
| | | if(StrUtil.isBlank(value)) { |
| | | return false; |
| | | } |
| | | return Pattern.matches(QQ_NUMBER_REGEXP, value); |
| | | } |
| | | |
| | | public static boolean isUserName(String value) { |
| | | if(StrUtil.isBlank(value)) { |
| | | return false; |
| | | } |
| | | return Pattern.matches(USER_NAME_REGEXP, value); |
| | | } |
| | | |
| | | public static boolean isMail(String value) { |
| | | if(StrUtil.isBlank(value)) { |
| | | return false; |
| | | } |
| | | return Pattern.matches(MAIL_REGEXP, value); |
| | | } |
| | | |
| | | /** |
| | | * 是否符合字段规则 |
| | | * @param value 输入值 |
| | | * @return 匹配结果 |
| | | */ |
| | | public static boolean isField(String value) { |
| | | return isMatching(FIELD_REGEXP, value); |
| | | } |
| | | |
| | | public static boolean isMatching(String regexp, String value) { |
| | | if (StrUtil.isBlank(value)) { |
| | | return false; |
| | | } |
| | | return Pattern.matches(regexp, value); |
| | | } |
| | | |
| | | /** |
| | | * 是否是由简单的字母数字拼接而成的字符串 |
| | | * @param value 输入值 |
| | | * @return 匹配结果 |
| | | */ |
| | | public static boolean isSimpleChar(String value) { |
| | | return isMatching(SIMPLE_CHAR_REGEXP, value); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.util; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.response.ResponseEnum; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.data.redis.core.StringRedisTemplate; |
| | | import org.springframework.data.redis.core.script.DefaultRedisScript; |
| | | |
| | | import java.util.*; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | | * 缓存工具类 |
| | | * @author yami |
| | | */ |
| | | @Slf4j |
| | | public class RedisUtil { |
| | | |
| | | @SuppressWarnings("unchecked") |
| | | private static RedisTemplate<String,Object> redisTemplate = SpringContextUtils.getBean("redisTemplate",RedisTemplate.class); |
| | | |
| | | public static final StringRedisTemplate STRING_REDIS_TEMPLATE = SpringContextUtils.getBean("stringRedisTemplate",StringRedisTemplate.class); |
| | | private static final Logger logger = LoggerFactory.getLogger(RedisUtil.class); |
| | | //=============================common============================ |
| | | /** |
| | | * 指定缓存失效时间 |
| | | * @param key 键 |
| | | * @param time 时间(秒) |
| | | * @return |
| | | */ |
| | | public static Boolean expire(String key,long time){ |
| | | try { |
| | | if(time>0){ |
| | | redisTemplate.expire(key, time, TimeUnit.SECONDS); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | log.error("指定Redis缓存失效时间错误:", e); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 根据key 获取过期时间 |
| | | * @param key 键 不能为null |
| | | * @return 时间(秒) 返回-1代表为永久有效 失效时间为0,说明该主键未设置失效时间(失效时间默认为-1) |
| | | */ |
| | | public static Long getExpire(String key){ |
| | | return redisTemplate.getExpire(key,TimeUnit.SECONDS); |
| | | } |
| | | |
| | | /** |
| | | * 判断key是否存在 |
| | | * @param key 键 |
| | | * @return true 存在 false 不存在 |
| | | */ |
| | | public static Boolean hasKey(String key){ |
| | | try { |
| | | return redisTemplate.hasKey(key); |
| | | } catch (Exception e) { |
| | | log.error("判断Redis中指定的key是否存在错误:", e); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 删除缓存 |
| | | * @param key 可以传一个值 或多个 |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public static void del(String ... key){ |
| | | if(key!=null&&key.length>0){ |
| | | if(key.length==1){ |
| | | redisTemplate.delete(key[0]); |
| | | }else{ |
| | | redisTemplate.delete(Arrays.asList(key)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 删除缓存 |
| | | * @param keys key列表 |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public static void del(List<String> keys){ |
| | | if(CollUtil.isEmpty(keys)){ |
| | | return; |
| | | } |
| | | redisTemplate.delete(keys); |
| | | } |
| | | |
| | | //============================String============================= |
| | | /** |
| | | * 普通缓存获取 |
| | | * @param key 键 |
| | | * @return 值 |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public static <T> T get(String key){ |
| | | return key==null?null:(T)redisTemplate.opsForValue().get(key); |
| | | } |
| | | |
| | | /** |
| | | * 普通缓存放入并设置时间 |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 |
| | | * @return true成功 false 失败 |
| | | */ |
| | | public static boolean set(String key,Object value,long time){ |
| | | try { |
| | | if(time>0){ |
| | | redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); |
| | | }else{ |
| | | redisTemplate.opsForValue().set(key, value); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | log.error("设置Redis缓存错误:", e); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 递增 此时value值必须为int类型 否则报错 |
| | | * @param key 键 |
| | | * @param delta 要增加几(大于0) |
| | | * @return |
| | | */ |
| | | public static Long incr(String key, long delta){ |
| | | if(delta<0){ |
| | | throw new RuntimeException("递增因子必须大于0"); |
| | | } |
| | | return STRING_REDIS_TEMPLATE.opsForValue().increment(key, delta); |
| | | } |
| | | |
| | | /** |
| | | * 递减 |
| | | * @param key 键 |
| | | * @param delta 要减少几(小于0) |
| | | * @return |
| | | */ |
| | | public static Long decr(String key, long delta){ |
| | | if(delta<0){ |
| | | throw new RuntimeException("递减因子必须小于0"); |
| | | } |
| | | return STRING_REDIS_TEMPLATE.opsForValue().increment(key, -delta); |
| | | } |
| | | |
| | | public static boolean setLongValue(String key,Long value,long time) { |
| | | try { |
| | | if(time>0){ |
| | | STRING_REDIS_TEMPLATE.opsForValue().set(key, String.valueOf(value), time, TimeUnit.SECONDS); |
| | | }else{ |
| | | STRING_REDIS_TEMPLATE.opsForValue().set(key, String.valueOf(value)); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | log.error("设置Redis缓存错误:", e); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 普通缓存获取 |
| | | * @param key 键 |
| | | * @return 值 |
| | | */ |
| | | public static Long getLongValue(String key){ |
| | | if (key == null) { |
| | | return null; |
| | | } |
| | | String result = STRING_REDIS_TEMPLATE.opsForValue().get(key); |
| | | if (result == null) { |
| | | return null; |
| | | } |
| | | return Long.valueOf(result); |
| | | } |
| | | |
| | | /** |
| | | * 比较和删除标记,原子性 |
| | | * @return 是否成功 |
| | | */ |
| | | public static boolean cad(String key, String value) { |
| | | |
| | | if (key.contains(StrUtil.SPACE) || value.contains(StrUtil.SPACE)) { |
| | | throw new YamiShopBindException("yami.network.busy"); |
| | | } |
| | | |
| | | String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; |
| | | |
| | | //通过lure脚本原子验证令牌和删除令牌 |
| | | Long result = STRING_REDIS_TEMPLATE.execute(new DefaultRedisScript<Long>(script, Long.class), |
| | | Collections.singletonList(key), |
| | | value); |
| | | |
| | | return !Objects.equals(result, 0L); |
| | | } |
| | | |
| | | /** |
| | | * 批量删除缓存 |
| | | * @param keys |
| | | */ |
| | | public static void deleteBatch(List<String> keys) { |
| | | if (CollUtil.isEmpty(keys)) { |
| | | return; |
| | | } |
| | | for (String key : keys) { |
| | | if (key.contains(StrUtil.SPACE)) { |
| | | throw new YamiShopBindException("yami.network.busy"); |
| | | } |
| | | } |
| | | redisTemplate.delete(keys); |
| | | } |
| | | |
| | | public static Set<String> keys(String pattern) { |
| | | return redisTemplate.keys(pattern); |
| | | } |
| | | |
| | | /** |
| | | * list缓存放入并设置时间 |
| | | * @param key 键 |
| | | * @param list 值 |
| | | * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 |
| | | * @return true成功 false 失败 |
| | | */ |
| | | public static boolean setRightPushAll(String key, List list, long time) { |
| | | if (key.contains(StrUtil.SPACE)) { |
| | | throw new YamiShopBindException(ResponseEnum.EXCEPTION); |
| | | } |
| | | try { |
| | | if (time > 0) { |
| | | redisTemplate.opsForList().rightPushAll(key,list); |
| | | expire(key,time); |
| | | } |
| | | else { |
| | | redisTemplate.opsForList().rightPushAll(key,list); |
| | | } |
| | | return true; |
| | | } |
| | | catch (Exception e) { |
| | | logger.error("Redis opsForList error: {}", e.getMessage()); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取list缓存的size |
| | | * @param key 键 |
| | | * @return true成功 false 失败 |
| | | */ |
| | | public static Long getListSize(String key) { |
| | | if (key.contains(StrUtil.SPACE)) { |
| | | throw new YamiShopBindException(ResponseEnum.EXCEPTION); |
| | | } |
| | | try { |
| | | return redisTemplate.opsForList().size(key); |
| | | } |
| | | catch (Exception e) { |
| | | logger.error("Redis opsForList error: {}", e.getMessage()); |
| | | return 0L; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 根据key 获取list指定范围的内容 |
| | | * @param key 键 不能为null |
| | | * @param start |
| | | * @param end |
| | | * @return 时间(秒) 返回-1代表为永久有效 失效时间为0,说明该主键未设置失效时间(失效时间默认为-1) |
| | | */ |
| | | public static List getListRange(String key, Long start, Long end) { |
| | | if (key.contains(StrUtil.SPACE)) { |
| | | throw new YamiShopBindException(ResponseEnum.EXCEPTION); |
| | | } |
| | | return redisTemplate.opsForList().range(key, start, end); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.util; |
| | | |
| | | import cn.hutool.captcha.LineCaptcha; |
| | | import cn.hutool.core.img.ImgUtil; |
| | | import cn.hutool.core.util.RandomUtil; |
| | | |
| | | import java.awt.*; |
| | | import java.awt.image.BufferedImage; |
| | | import java.util.concurrent.ThreadLocalRandom; |
| | | |
| | | /** |
| | | * 二维码 |
| | | * @author yami |
| | | */ |
| | | public class SimpleCaptcha extends LineCaptcha{ |
| | | |
| | | private static final long serialVersionUID = -9042552338521307038L; |
| | | |
| | | private static final String CAPTCHA_CODE = "abcdefhjkmnpqrstuvwxyz2345678"; |
| | | |
| | | private int codeCount; |
| | | |
| | | public SimpleCaptcha(int width, int height, int codeCount, int interfereCount) { |
| | | |
| | | super(width, height, codeCount, interfereCount); |
| | | this.codeCount = codeCount; |
| | | } |
| | | |
| | | @Override |
| | | protected void generateCode() { |
| | | this.code = RandomUtil.randomString(CAPTCHA_CODE,codeCount); |
| | | } |
| | | |
| | | @Override |
| | | public Image createImage(String code) { |
| | | // 图像buffer |
| | | final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); |
| | | final ThreadLocalRandom random = RandomUtil.getRandom(); |
| | | final Graphics2D g = ImgUtil.createGraphics(image, new Color(255,255,255)); |
| | | |
| | | // 干扰线 |
| | | drawInterfere(g, random); |
| | | |
| | | // 创建字体 |
| | | g.setFont(this.font); |
| | | final FontMetrics metrics = g.getFontMetrics(); |
| | | int minY = metrics.getAscent() - metrics.getLeading() - metrics.getDescent(); |
| | | // 文字 |
| | | final int len = codeCount; |
| | | int charWidth = width / len; |
| | | for (int i = 0; i < len; i++) { |
| | | // 产生随机的颜色值,让输出的每个字符的颜色值都将不同。 |
| | | g.setColor(ImgUtil.randomColor(random)); |
| | | g.drawString(String.valueOf(code.charAt(i)), i * charWidth, RandomUtil.randomInt(minY, this.height)); |
| | | } |
| | | |
| | | return image; |
| | | } |
| | | |
| | | /** |
| | | * 绘制干扰线 |
| | | * |
| | | * @param g {@link Graphics2D}画笔 |
| | | * @param random 随机对象 |
| | | */ |
| | | private void drawInterfere(Graphics2D g, ThreadLocalRandom random) { |
| | | // 干扰线 |
| | | for (int i = 0; i < this.interfereCount; i++) { |
| | | int xs = random.nextInt(width); |
| | | int ys = random.nextInt(height); |
| | | int xe = xs + random.nextInt(width / 8); |
| | | int ye = ys + random.nextInt(height / 8); |
| | | g.setColor(ImgUtil.randomColor(random)); |
| | | g.drawLine(xs, ys, xe, ye); |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.util; |
| | | |
| | | import cn.hutool.core.util.ArrayUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import org.springframework.context.expression.MethodBasedEvaluationContext; |
| | | import org.springframework.core.LocalVariableTableParameterNameDiscoverer; |
| | | import org.springframework.expression.ExpressionParser; |
| | | import org.springframework.expression.spel.standard.SpelExpressionParser; |
| | | import org.springframework.expression.spel.support.StandardEvaluationContext; |
| | | |
| | | import java.lang.reflect.Method; |
| | | |
| | | /** |
| | | * 解析SPEL 表达式 |
| | | * @author huxingnan |
| | | * @date 2018/5/21 10:51 |
| | | */ |
| | | public class SpelUtil { |
| | | |
| | | /** |
| | | * 支持 #p0 参数索引的表达式解析 |
| | | * @param rootObject 根对象,method 所在的对象 |
| | | * @param spel 表达式 |
| | | * @param method ,目标方法 |
| | | * @param args 方法入参 |
| | | * @return 解析后的字符串 |
| | | */ |
| | | public static String parse(Object rootObject,String spel, Method method, Object[] args) { |
| | | if (StrUtil.isBlank(spel)) { |
| | | return StrUtil.EMPTY; |
| | | } |
| | | //获取被拦截方法参数名列表(使用Spring支持类库) |
| | | LocalVariableTableParameterNameDiscoverer u = |
| | | new LocalVariableTableParameterNameDiscoverer(); |
| | | String[] paraNameArr = u.getParameterNames(method); |
| | | if (ArrayUtil.isEmpty(paraNameArr)) { |
| | | return spel; |
| | | } |
| | | //使用SPEL进行key的解析 |
| | | ExpressionParser parser = new SpelExpressionParser(); |
| | | //SPEL上下文 |
| | | StandardEvaluationContext context = new MethodBasedEvaluationContext(rootObject,method,args,u); |
| | | //把方法参数放入SPEL上下文中 |
| | | for (int i = 0; i < paraNameArr.length; i++) { |
| | | context.setVariable(paraNameArr[i], args[i]); |
| | | } |
| | | return parser.parseExpression(spel).getValue(context, String.class); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.util; |
| | | |
| | | import org.springframework.beans.BeansException; |
| | | import org.springframework.context.ApplicationContext; |
| | | import org.springframework.context.ApplicationContextAware; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * Spring Context 工具类 |
| | | * @author lgh |
| | | */ |
| | | @Component |
| | | public class SpringContextUtils implements ApplicationContextAware { |
| | | public static ApplicationContext applicationContext; |
| | | |
| | | @Override |
| | | public void setApplicationContext(ApplicationContext applicationContext) |
| | | throws BeansException { |
| | | SpringContextUtils.applicationContext = applicationContext; |
| | | } |
| | | |
| | | public static Object getBean(String name) { |
| | | return applicationContext.getBean(name); |
| | | } |
| | | |
| | | public static <T> T getBean(Class<T> requiredType) { |
| | | return applicationContext.getBean(requiredType); |
| | | } |
| | | |
| | | public static <T> T getBean(String name, Class<T> requiredType) { |
| | | return applicationContext.getBean(name, requiredType); |
| | | } |
| | | public static boolean containsBean(String name) { |
| | | return applicationContext.containsBean(name); |
| | | } |
| | | |
| | | public static boolean isSingleton(String name) { |
| | | return applicationContext.isSingleton(name); |
| | | } |
| | | |
| | | public static Class<? extends Object> getType(String name) { |
| | | return applicationContext.getType(name); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.util; |
| | | |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.aspose.words.Document; |
| | | import com.aspose.words.SaveFormat; |
| | | import org.apache.poi.xwpf.usermodel.XWPFDocument; |
| | | import org.apache.poi.xwpf.usermodel.XWPFParagraph; |
| | | import org.apache.poi.xwpf.usermodel.XWPFRun; |
| | | import org.apache.poi.xwpf.usermodel.XWPFTable; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.io.FileInputStream; |
| | | import java.io.FileOutputStream; |
| | | import java.util.ArrayList; |
| | | import java.util.Iterator; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | /** |
| | | * 进制转换工具,最大支持十进制和DICT.length()进制的转换 |
| | | * 1、将十进制的数字转换为指定进制的字符串; |
| | | * 2、将其它进制的数字(字符串形式)转换为十进制的数字 |
| | | * @author xuliugen |
| | | * @date 2018/04/23 |
| | | */ |
| | | @Component |
| | | public class WordUtil { |
| | | |
| | | // 标识忽略 |
| | | static final int ignoreTg = 0; |
| | | // 标识已读取到'$'字符 |
| | | static final int startTg = 1; |
| | | // 标识已读取到'{'字符 |
| | | static final int readTg = 2; |
| | | |
| | | /** |
| | | * 占位符 |
| | | * @param |
| | | * @return |
| | | */ |
| | | public static void replacePlaceholders(XWPFDocument doc, Map<String, String> params) { |
| | | // 遍历文档中的所有段落 |
| | | for (XWPFParagraph para : doc.getParagraphs()) { |
| | | List<XWPFRun> runs = para.getRuns(); |
| | | for (int i = 0; i < runs.size(); i++) { |
| | | XWPFRun run = runs.get(i); |
| | | String text = run.getText(run.getTextPosition()); |
| | | for (Map.Entry<String, String> entry : params.entrySet()) { |
| | | if (text != null && text.contains(entry.getKey())) { |
| | | run.setText(text.replace(entry.getKey(), entry.getValue()), 0); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取表格中占位符信息 |
| | | * |
| | | * @param doc 当前文档 |
| | | * @param list 存储占位符信息 |
| | | * @param placeholderValues 需要替换的值 |
| | | * @return void |
| | | * @author liuchao |
| | | * @date 2020/7/6 |
| | | */ |
| | | public static void getTableParagraphs(XWPFDocument doc, List<XWPFParagraph> list, Map<String, String> placeholderValues) { |
| | | List<XWPFTable> tables = doc.getTables(); |
| | | if (ObjectUtil.isEmpty(tables)) { |
| | | return; |
| | | } |
| | | tables.forEach(table -> table.getRows().forEach(row -> row.getTableCells().forEach(cell -> { |
| | | String text = cell.getText(); |
| | | if (ObjectUtil.isEmpty(text)) { |
| | | return; |
| | | } |
| | | Iterator<String> it = placeholderValues.keySet().iterator(); |
| | | while (it.hasNext()) { |
| | | String key = it.next(); |
| | | if (text.indexOf(key) != -1) { |
| | | list.addAll(cell.getParagraphs()); |
| | | } |
| | | } |
| | | }))); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 清除占位符信息 |
| | | * |
| | | * @param placeholderList 占位符位置信息 |
| | | * @param paragraphList 行数据 |
| | | * @return void |
| | | * @author liuchao |
| | | * @date 2020/6/10 |
| | | */ |
| | | public static void clearPlaceholder(List<int[]> placeholderList, List<XWPFParagraph> paragraphList) { |
| | | if (ObjectUtil.isEmpty(placeholderList)) { |
| | | return; |
| | | } |
| | | int[] currentPlaceholder = placeholderList.get(0); |
| | | StringBuilder tempSb = new StringBuilder(); |
| | | for (int i = 0; i < paragraphList.size(); i++) { |
| | | XWPFParagraph p = paragraphList.get(i); |
| | | List<XWPFRun> runs = p.getRuns(); |
| | | for (int j = 0; j < runs.size(); j++) { |
| | | XWPFRun run = runs.get(j); |
| | | String text = run.getText(run.getTextPosition()); |
| | | StringBuilder nval = new StringBuilder(); |
| | | char[] textChars = text.toCharArray(); |
| | | for (int m = 0; m < textChars.length; m++) { |
| | | char c = textChars[m]; |
| | | if (null == currentPlaceholder) { |
| | | nval.append(c); |
| | | continue; |
| | | } |
| | | // 排除'$'和'}'两个字符之间的字符 |
| | | int start = currentPlaceholder[0] * 1000000 + currentPlaceholder[1] * 500 + currentPlaceholder[2]; |
| | | int end = currentPlaceholder[3] * 1000000 + currentPlaceholder[4] * 500 + currentPlaceholder[5]; |
| | | int cur = i * 1000000 + j * 500 + m; |
| | | if (!(cur >= start && cur <= end)) { |
| | | nval.append(c); |
| | | } else { |
| | | tempSb.append(c); |
| | | } |
| | | //判断是否是占位符结尾,如果是那获取新的占位符 |
| | | if (tempSb.toString().endsWith("}")) { |
| | | placeholderList.remove(0); |
| | | if (ObjectUtil.isEmpty(placeholderList)) { |
| | | currentPlaceholder = null; |
| | | continue; |
| | | } |
| | | currentPlaceholder = placeholderList.get(0); |
| | | tempSb = new StringBuilder(); |
| | | } |
| | | } |
| | | run.setText(nval.toString(), run.getTextPosition()); |
| | | |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取占位符信息,并且在占位符后面填充值 |
| | | * |
| | | * @param paragraphList 行数据 |
| | | * @param map 要替换的占位符key\value |
| | | * @return java.util.List<int [ ]> |
| | | * @author liuchao |
| | | * @date 2020/6/10 |
| | | */ |
| | | public static List<int[]> getPlaceholderList(List<XWPFParagraph> paragraphList, Map<String, String> map) { |
| | | // 存储占位符 位置信息集合 |
| | | List<int[]> placeholderList = new ArrayList<>(); |
| | | // 当前占位符 0:'$'字符在XWPFParagraph集合中下标 |
| | | // 1:'$'字符在XWPFRun集合中下标 |
| | | // 2:'$'字符在text.toCharArray()数组下标 |
| | | // 3: '}'字符在XWPFParagraph集合中下标 |
| | | // 4: '}'字符在XWPFRun集合中下标 |
| | | // 5:'}'字符在text.toCharArray()数组下标 |
| | | int[] currentPlaceholder = new int[6]; |
| | | |
| | | // 当前标识 |
| | | int modeTg = ignoreTg; |
| | | StringBuilder sb = new StringBuilder(); |
| | | for (int i = 0; i < paragraphList.size(); i++) { |
| | | XWPFParagraph p = paragraphList.get(i); |
| | | List<XWPFRun> runs = p.getRuns(); |
| | | for (int j = 0; j < runs.size(); j++) { |
| | | XWPFRun run = runs.get(j); |
| | | String text = run.getText(run.getTextPosition()); |
| | | if(null == text){ |
| | | text = ""; |
| | | } |
| | | char[] textChars = text.toCharArray(); |
| | | String newVal = ""; |
| | | StringBuilder textSofar = new StringBuilder(); |
| | | for (int m = 0; m < textChars.length; m++) { |
| | | char c = textChars[m]; |
| | | textSofar.append(c); |
| | | switch (c) { |
| | | case '$': { |
| | | modeTg = startTg; |
| | | sb.append(c); |
| | | } |
| | | break; |
| | | case '{': { |
| | | if (modeTg == startTg) { |
| | | sb.append(c); |
| | | modeTg = readTg; |
| | | currentPlaceholder[0] = i; |
| | | currentPlaceholder[1] = j; |
| | | currentPlaceholder[2] = m - 1; |
| | | } else { |
| | | if (modeTg == readTg) { |
| | | sb = new StringBuilder(); |
| | | modeTg = ignoreTg; |
| | | } |
| | | } |
| | | } |
| | | break; |
| | | case '}': { |
| | | if (modeTg == readTg) { |
| | | modeTg = ignoreTg; |
| | | sb.append(c); |
| | | String val = map.get(sb.toString()); |
| | | if (ObjectUtil.isNotEmpty(val)) { |
| | | newVal += textSofar.toString() + val; |
| | | placeholderList.add(currentPlaceholder); |
| | | textSofar = new StringBuilder(); |
| | | } |
| | | currentPlaceholder[3] = i; |
| | | currentPlaceholder[4] = j; |
| | | currentPlaceholder[5] = m; |
| | | currentPlaceholder = new int[6]; |
| | | sb = new StringBuilder(); |
| | | } else if (modeTg == startTg) { |
| | | modeTg = ignoreTg; |
| | | sb = new StringBuilder(); |
| | | } |
| | | } |
| | | default: { |
| | | if (modeTg == readTg) { |
| | | sb.append(c); |
| | | } else if (modeTg == startTg) { |
| | | modeTg = ignoreTg; |
| | | sb = new StringBuilder(); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | newVal += textSofar.toString(); |
| | | run.setTextPosition(0); |
| | | run.setText(newVal, run.getTextPosition()); |
| | | } |
| | | } |
| | | return placeholderList; |
| | | } |
| | | |
| | | /** |
| | | * word文档转PDF |
| | | * @param wordPath word文档路径 |
| | | * @param outPdfPath PDF输出路径 |
| | | */ |
| | | public static void wordConvertPdf(String wordPath, String outPdfPath) { |
| | | try( |
| | | FileInputStream fileInputStream = new FileInputStream(wordPath); |
| | | FileOutputStream pdfOutStremp = new FileOutputStream(outPdfPath); |
| | | ) { |
| | | Document document = new Document(fileInputStream); |
| | | document.save(pdfOutStremp, SaveFormat.PDF); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.util; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Calendar; |
| | | |
| | | /** |
| | | * 获取核销码的工具方法 |
| | | * @author lhd |
| | | * @date 2021/10/26 |
| | | */ |
| | | @Component |
| | | public class WriteOffCodeUtil { |
| | | |
| | | private static final Integer LENGTH = 8; |
| | | private static final Integer ROUND_LENGTH = (LENGTH-2)/2; |
| | | private static final Long INIT_ROUND = 10000000000L; |
| | | |
| | | /** |
| | | * 随机码: 三位随机数 + (月+日+45) + 三位随机数 |
| | | * 若随机码不够用,可更改长度:LENGTH 和 初始值:INIT_ROUND,增加随机码 |
| | | * @param oldCode |
| | | * @return |
| | | */ |
| | | public static String getCode(String oldCode){ |
| | | Calendar cal = Calendar.getInstance(); |
| | | int dayAddMonth = (cal.get(Calendar.DATE)) + cal.get(Calendar.MONTH) + 46; |
| | | String code; |
| | | Long roundNum; |
| | | if (StrUtil.isNotBlank(oldCode)){ |
| | | //随机数增加的最大值 |
| | | long changeNum = 5L; |
| | | // 获取随机数 |
| | | long num = Long.parseLong(oldCode.substring(0,ROUND_LENGTH) + oldCode.substring(LENGTH - ROUND_LENGTH)); |
| | | roundNum = num + Math.round(Math.random() * changeNum) + 1; |
| | | }else { |
| | | // 随机数 = 5*1000000000011以内的随机数 + 2*1000000000011 |
| | | roundNum = Math.round(Math.random() * 5 * INIT_ROUND) + 2 * INIT_ROUND; |
| | | } |
| | | // 随机数大于等于最大值,初始化 |
| | | long maxRoundNum= 10L * INIT_ROUND; |
| | | if (roundNum >= maxRoundNum){ |
| | | roundNum = roundNum - maxRoundNum + INIT_ROUND; |
| | | } |
| | | code = roundNum.toString(); |
| | | return code.substring(0,ROUND_LENGTH)+ dayAddMonth + code.substring(ROUND_LENGTH); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.wrapper; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import javax.servlet.ReadListener; |
| | | import javax.servlet.ServletInputStream; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletRequestWrapper; |
| | | import java.io.*; |
| | | import java.nio.charset.StandardCharsets; |
| | | |
| | | /** |
| | | * @author Citrus |
| | | * @date 2021/8/13 13:31 |
| | | */ |
| | | @Slf4j |
| | | public class RequestWrapper extends HttpServletRequestWrapper { |
| | | |
| | | private String body; |
| | | |
| | | /** |
| | | * Constructs a request object wrapping the given request. |
| | | * |
| | | * @param request The request to wrap |
| | | * @throws IllegalArgumentException if the request is null |
| | | */ |
| | | public RequestWrapper(HttpServletRequest request) throws IOException { |
| | | super(request); |
| | | StringBuilder stringBuilder = new StringBuilder(); |
| | | BufferedReader bufferedReader = null; |
| | | try { |
| | | InputStream inputStream = request.getInputStream(); |
| | | if (inputStream != null) { |
| | | bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); |
| | | char[] charBuffer = new char[1024]; |
| | | int bytesRead = -1; |
| | | while ((bytesRead = bufferedReader.read(charBuffer)) > 0) { |
| | | stringBuilder.append(charBuffer, 0, bytesRead); |
| | | } |
| | | } else { |
| | | stringBuilder.append(""); |
| | | } |
| | | } catch (IOException e) { |
| | | log.error("IOException:", e); |
| | | } finally { |
| | | if (bufferedReader != null) { |
| | | bufferedReader.close(); |
| | | } |
| | | } |
| | | body = stringBuilder.toString(); |
| | | } |
| | | |
| | | public String getBody() { |
| | | return body; |
| | | } |
| | | |
| | | public void setBody(String body) { |
| | | this.body = body; |
| | | } |
| | | |
| | | @Override |
| | | public BufferedReader getReader() throws IOException { |
| | | return new BufferedReader(new InputStreamReader(this.getInputStream())); |
| | | } |
| | | |
| | | @Override |
| | | public ServletInputStream getInputStream() throws IOException { |
| | | final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8)); |
| | | return new ServletInputStream() { |
| | | @Override |
| | | public boolean isFinished() { |
| | | return false; |
| | | } |
| | | |
| | | @Override |
| | | public boolean isReady() { |
| | | return false; |
| | | } |
| | | |
| | | @Override |
| | | public void setReadListener(ReadListener readListener) { |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public int read() throws IOException { |
| | | return byteArrayInputStream.read(); |
| | | } |
| | | }; |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.wrapper; |
| | | |
| | | import javax.servlet.ServletOutputStream; |
| | | import javax.servlet.WriteListener; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import javax.servlet.http.HttpServletResponseWrapper; |
| | | import java.io.ByteArrayOutputStream; |
| | | import java.io.IOException; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 返回值输出代理类 |
| | | * @author Citrus |
| | | * @date 2021/8/11 14:09 |
| | | */ |
| | | public class ResponseWrapper extends HttpServletResponseWrapper { |
| | | |
| | | private final ByteArrayOutputStream buffer; |
| | | |
| | | private final ServletOutputStream outputStream; |
| | | |
| | | public ResponseWrapper(HttpServletResponse response) { |
| | | super(response); |
| | | buffer = new ByteArrayOutputStream(); |
| | | outputStream = new WrapperOutPutStream(buffer); |
| | | } |
| | | |
| | | @Override |
| | | public ServletOutputStream getOutputStream() throws IOException { |
| | | return outputStream; |
| | | } |
| | | |
| | | @Override |
| | | public void flushBuffer() throws IOException { |
| | | if (Objects.nonNull(outputStream)) { |
| | | outputStream.flush(); |
| | | } |
| | | } |
| | | |
| | | public byte[] getContent() throws IOException{ |
| | | flushBuffer(); |
| | | return buffer.toByteArray(); |
| | | } |
| | | |
| | | static class WrapperOutPutStream extends ServletOutputStream { |
| | | |
| | | private final ByteArrayOutputStream bos; |
| | | |
| | | public WrapperOutPutStream(ByteArrayOutputStream bos) { |
| | | this.bos = bos; |
| | | } |
| | | |
| | | @Override |
| | | public boolean isReady() { |
| | | return false; |
| | | } |
| | | |
| | | @Override |
| | | public void setWriteListener(WriteListener writeListener) { |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void write(int b) throws IOException { |
| | | bos.write(b); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.wx; |
| | | |
| | | import cn.hutool.http.HttpUtil; |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.TypeReference; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.i18n.I18nMessage; |
| | | import com.yami.shop.common.response.WxLiveProdResponse; |
| | | import com.yami.shop.common.response.WxServerResponse; |
| | | import com.yami.shop.common.util.Json; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.common.wx.bean.*; |
| | | import com.yami.shop.common.wx.bean.resp.GoodsInfoRespParam; |
| | | import com.yami.shop.common.wx.bean.resp.GoodsListRespParam; |
| | | import com.yami.shop.common.wx.bean.resp.RoomDetailResponse; |
| | | import com.yami.shop.common.wx.bean.resp.RoomResponse; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * 微信相关工具类 |
| | | * @author LHD |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | public class WxInterfaceUtil { |
| | | |
| | | |
| | | |
| | | private String url; |
| | | private String wxImgUrl = "https://api.weixin.qq.com/cgi-bin/media"; |
| | | private String liveUrl = "https://api.weixin.qq.com"; |
| | | private String goodsUrl = "https://api.weixin.qq.com/wxaapi/broadcast/goods"; |
| | | private String goodsStatusUrl = "https://api.weixin.qq.com/wxa/business"; |
| | | private String goodsListUrl = "https://api.weixin.qq.com/wxaapi/broadcast/goods/getapproved?access_token=[ACCESS_TOKEN]"; |
| | | |
| | | public static String GET_GOODS_WARE_HOUSE = "getgoodswarehouse"; |
| | | public static String GET_APPROVED = "getapproved"; |
| | | public static String ERR_MSG = "errmsg"; |
| | | |
| | | |
| | | // /** |
| | | // * 上传临时素材接口 |
| | | // * @return |
| | | // */ |
| | | // public ServerResponse<ImageResponse> uploadMedia(WxInterfaceInfo creditInfo){ |
| | | // Map<String, Object> requestParam = new HashMap<>(16); |
| | | //// requestParam.put("type", creditInfo.getType()); |
| | | // // 微信token |
| | | //// requestParam.put("access_token", creditInfo.getAccessToken()); |
| | | // requestParam.put("media", creditInfo.getByteArray()); |
| | | // |
| | | // return signAndSend(creditInfo, requestParam,new TypeReference<ServerResponse<ImageResponse>>() {}); |
| | | // |
| | | // } |
| | | |
| | | /** |
| | | * 增加直播间接口 |
| | | * @return |
| | | */ |
| | | public WxServerResponse<Void> addLiveRoom(WxLiveRoomInfo wxLiveRoomInfo){ |
| | | Map<String, Object> requestParam = new HashMap<>(16); |
| | | requestParam.put("name",wxLiveRoomInfo.getName()); |
| | | requestParam.put("coverImg",wxLiveRoomInfo.getCoverImgId()); |
| | | requestParam.put("startTime",wxLiveRoomInfo.getWxStartTime()); |
| | | requestParam.put("endTime",wxLiveRoomInfo.getWxEndTime()); |
| | | requestParam.put("anchorName",wxLiveRoomInfo.getAnchorName()); |
| | | requestParam.put("anchorWechat",wxLiveRoomInfo.getAnchorWechat()); |
| | | requestParam.put("shareImg",wxLiveRoomInfo.getShareImgId()); |
| | | requestParam.put("feedsImg",wxLiveRoomInfo.getFeedsImgId()); |
| | | requestParam.put("isFeedPublic",wxLiveRoomInfo.getIsFeedsPublic()); |
| | | requestParam.put("type",wxLiveRoomInfo.getType()); |
| | | requestParam.put("screenType",wxLiveRoomInfo.getScreenType()); |
| | | requestParam.put("closeLike",wxLiveRoomInfo.getCloseLike()); |
| | | requestParam.put("closeGoods",wxLiveRoomInfo.getCloseGoods()); |
| | | requestParam.put("closeComment",wxLiveRoomInfo.getCloseComment()); |
| | | requestParam.put("closeReplay",wxLiveRoomInfo.getCloseReplay()); |
| | | requestParam.put("closeShare",wxLiveRoomInfo.getCloseShare()); |
| | | requestParam.put("closeKf",wxLiveRoomInfo.getCloseKf()); |
| | | return signAndSend(wxLiveRoomInfo, requestParam,new TypeReference<WxServerResponse<Void>>() {}); |
| | | |
| | | } |
| | | /** |
| | | * 获取直播间列表接口 |
| | | * @return |
| | | */ |
| | | public WxServerResponse<List<RoomDetailResponse>> pageLiveRoom(PageLiveRoomInfo wxLiveRoomInfo){ |
| | | Map<String, Object> requestParam = new HashMap<>(16); |
| | | requestParam.put("start",wxLiveRoomInfo.getStart()); |
| | | requestParam.put("limit", wxLiveRoomInfo.getLimit()); |
| | | |
| | | return signAndSend(wxLiveRoomInfo, requestParam,new TypeReference<WxServerResponse<List<RoomDetailResponse>>>() {}); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 4.直播间导入商品 |
| | | * 调用接口往指定直播间导入已入库的商品 |
| | | * @return |
| | | */ |
| | | public WxServerResponse<Void> addLiveRoomProds(WxRoomProdInfo wxRoomProdInfo){ |
| | | Map<String, Object> requestParam = new HashMap<>(16); |
| | | requestParam.put("ids",wxRoomProdInfo.getIds()); |
| | | requestParam.put("roomId",wxRoomProdInfo.getRoomId()); |
| | | return signAndSend(wxRoomProdInfo, requestParam,new TypeReference<WxServerResponse<Void>>() {}); |
| | | } |
| | | |
| | | /** |
| | | * 查询直播间回放 |
| | | * @return |
| | | */ |
| | | public WxServerResponse<PageParam<RoomResponse>> pagePlayBackByRoomId(PageLiveRoomInfo wxRoomPlayBackInfo){ |
| | | Map<String, Object> requestParam = new HashMap<>(16); |
| | | requestParam.put("action","get_replay"); |
| | | requestParam.put("room_id",wxRoomPlayBackInfo.getRoomId()); |
| | | requestParam.put("start",wxRoomPlayBackInfo.getStart()); |
| | | requestParam.put("limit",wxRoomPlayBackInfo.getLimit()); |
| | | return signAndSend(wxRoomPlayBackInfo, requestParam,new TypeReference<WxServerResponse<PageParam<RoomResponse>>>() {}); |
| | | } |
| | | |
| | | // /** |
| | | // * 发送请求,获取响应结果 |
| | | // * @param requestParam |
| | | // * @return |
| | | // */ |
| | | // private <T> ServerResponse<T> signAndSend(WxInterfaceInfo creditInfo, Map<String, Object> requestParam, TypeReference<ServerResponse<T>> typeReference) { |
| | | //// log.info(Json.toJsonString(requestParam)); |
| | | // String uploadMediaUrl = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE"; |
| | | // uploadMediaUrl = uploadMediaUrl.replace("ACCESS_TOKEN", creditInfo.getAccessToken()).replace("TYPE", creditInfo.getType()); |
| | | // System.out.println(uploadMediaUrl); |
| | | // String body = HttpUtil.createPost(uploadMediaUrl) |
| | | // .contentType("multipart/form-data;boundary=----WebKitFormBoundaryLFoM36YJSszHqhMR") |
| | | // .form(Json.toJsonString(requestParam)) |
| | | // .execute().body(); |
| | | //// String body = HttpUtil.createPost(wxImgUrl + creditInfo.getRequestUrl()).form(requestParam).contentType("application/x-www-form-urlencoded").execute().body(); |
| | | // log.info(body); |
| | | // return JSON.parseObject(body, typeReference); |
| | | // } |
| | | |
| | | |
| | | /** |
| | | * 商品添加并提审 |
| | | * 商品添加到微信并且提交审核的接口 |
| | | */ |
| | | public GoodsInfoRespParam prodAddVerify(GoodsInfoReqParam goodsInfo){ |
| | | Map<String, Object> requestParam = new HashMap<>(16); |
| | | requestParam.put("goodsInfo",goodsInfo); |
| | | GoodsInfoRespParam goodsInfoRespParam = prodSignAndSend(goodsInfo, requestParam, new TypeReference<GoodsInfoRespParam>() {}); |
| | | System.out.println("goodsInfo: " + goodsInfoRespParam); |
| | | if (!Objects.equals(goodsInfoRespParam.getErrcode(),0) ) { |
| | | // 提交审核失败 |
| | | throw new YamiShopBindException("yami.examine.fail"); |
| | | } |
| | | return goodsInfoRespParam; |
| | | } |
| | | |
| | | // /** |
| | | // * 撤回审核 |
| | | // * 可撤回直播商品的提审申请,消耗的提审次数不返还 |
| | | // */ |
| | | // public GoodsInfoRespParam prodCancelVerify(GoodsReqInfo goodsInfo){ |
| | | // Map<String, Object> requestParam = new HashMap<>(16); |
| | | // requestParam.put("auditId",goodsInfo.getAuditId()); |
| | | // requestParam.put("goodsId",goodsInfo.getGoodsId()); |
| | | // goodsInfo.setRequestUrl("/resetaudit?access_token="); |
| | | // GoodsInfoRespParam goodsRespInfo = prodSignAndSend(goodsInfo, requestParam, new TypeReference<GoodsInfoRespParam>() {}); |
| | | // if (!Objects.equals(goodsRespInfo.getErrcode(),0) ) { |
| | | // throw new YamiShopBindExcetion("撤回审核失败"); |
| | | // } |
| | | // return goodsRespInfo; |
| | | // } |
| | | |
| | | // /** |
| | | // * 重新提交审核 |
| | | // * 调用此接口可以对已撤回提审的商品再次发起提审申请 |
| | | // * 需要更新 "auditId": 525022184 |
| | | // */ |
| | | // public GoodsInfoRespParam prodAgainVerify(GoodsReqInfo goodsInfo){ |
| | | // Map<String, Object> requestParam = new HashMap<>(16); |
| | | // requestParam.put("goodsId",goodsInfo.getGoodsId()); |
| | | // goodsInfo.setRequestUrl("/audit?access_token="); |
| | | // GoodsInfoRespParam goodsRespInfo = prodSignAndSend(goodsInfo, requestParam, new TypeReference<GoodsInfoRespParam>() {}); |
| | | // if (!Objects.equals(goodsRespInfo.getErrcode(),0) ) { |
| | | // throw new YamiShopBindExcetion("重新提交审核失败"); |
| | | // } |
| | | // return goodsRespInfo; |
| | | // } |
| | | |
| | | /** |
| | | * 调用此接口,可删除【小程序直播】商品库中的商品,删除后直播间上架的该商品也将被同步删除,不可恢复 |
| | | * 删除商品 |
| | | * { |
| | | * "errcode": 0, |
| | | * } |
| | | */ |
| | | public WxLiveProdResponse<Void> prodDelete(GoodsReqInfo goodsInfo){ |
| | | Map<String, Object> requestParam = new HashMap<>(16); |
| | | requestParam.put("goodsId",goodsInfo.getGoodsId()); |
| | | goodsInfo.setRequestUrl("/wxaapi/broadcast/goods/delete?access_token="); |
| | | return liveProdSignAndSend(goodsInfo, requestParam, new TypeReference<WxLiveProdResponse<Void>>() {}); |
| | | } |
| | | |
| | | /** |
| | | * 调用此接口可以更新商品信息,审核通过的商品仅允许更新价格类型与价格,审核中的商品不允许更新, |
| | | * 未审核的商品允许更新所有字段, 只传入需要更新的字段 |
| | | * 更新商品 |
| | | * { |
| | | * "errcode": 0, |
| | | * } |
| | | */ |
| | | public WxLiveProdResponse<Void> prodUpdate(UpdateGoodsInfoReqParam goodsInfo){ |
| | | Map<String, Object> requestParam = new HashMap<>(16); |
| | | requestParam.put("goodsInfo",goodsInfo); |
| | | return liveProdSignAndSend(goodsInfo, requestParam, new TypeReference<WxLiveProdResponse<Void>>() {}); |
| | | } |
| | | |
| | | /** |
| | | * 获取商品状态 调用此接口可获取商品的信息与审核状态 |
| | | * { |
| | | * "errcode": 0, |
| | | * } |
| | | */ |
| | | public WxLiveProdResponse<List<GoodsInfoRespParam>> prodGetStatus(GoodsReqInfo goodsInfo){ |
| | | Map<String, Object> requestParam = new HashMap<>(16); |
| | | if (CollectionUtils.isEmpty(goodsInfo.getGoodsIds())) { |
| | | List<Long> list = new ArrayList<>(); |
| | | list.add(goodsInfo.getGoodsId()); |
| | | requestParam.put("goods_ids", list.toArray()); |
| | | } else { |
| | | requestParam.put("goods_ids", goodsInfo.getGoodsIds().toArray()); |
| | | } |
| | | goodsInfo.setRequestUrl("/wxa/business/getgoodswarehouse?access_token="); |
| | | return liveProdSignAndSend(goodsInfo, requestParam, new TypeReference<WxLiveProdResponse<List<GoodsInfoRespParam>>>() {}); |
| | | } |
| | | |
| | | /** |
| | | * 获取商品列表 调用此接口可获取商品的信息与审核状态 |
| | | * 调用此接口可获取商品列表 |
| | | * { |
| | | * "errcode": 0, |
| | | * } |
| | | */ |
| | | public GoodsListRespParam prodList(GoodsListReqParam goodsInfo){ |
| | | Map<String, Object> requestParam = new HashMap<>(16); |
| | | requestParam.put("offset", goodsInfo.getOffset()); |
| | | requestParam.put("limit", goodsInfo.getLimit()); |
| | | requestParam.put("status", goodsInfo.getStatus()); |
| | | GoodsListRespParam goodsRespInfo = prodSignAndSend(goodsInfo, requestParam, new TypeReference<GoodsListRespParam>() {}); |
| | | if (!Objects.equals(goodsRespInfo.getErrcode(),0) ) { |
| | | // 获取商品列表失败 |
| | | throw new YamiShopBindException("yami.get.goods"); |
| | | } |
| | | return goodsRespInfo; |
| | | } |
| | | |
| | | /** |
| | | * 微信请求-商品管理请求 |
| | | * |
| | | */ |
| | | private <T> T prodSignAndSend(WxInterfaceInfo wxInterfaceInfo, Map<String, Object> requestParam, TypeReference<T> typeReference) { |
| | | log.info(Json.toJsonString(requestParam)); |
| | | String reqUrl = goodsUrl + wxInterfaceInfo.getRequestUrl() + wxInterfaceInfo.getAccessToken(); |
| | | if (wxInterfaceInfo.getRequestUrl().contains(GET_GOODS_WARE_HOUSE)) { |
| | | reqUrl = goodsStatusUrl + wxInterfaceInfo.getRequestUrl() + wxInterfaceInfo.getAccessToken(); |
| | | } |
| | | if (wxInterfaceInfo.getRequestUrl().contains(GET_APPROVED)) { |
| | | reqUrl = goodsListUrl.replace("ACCESS_TOKEN",wxInterfaceInfo.getAccessToken()); |
| | | } |
| | | log.info("url: " + reqUrl); |
| | | String body = HttpUtil.createPost(reqUrl) |
| | | .body(Json.toJsonString(requestParam)) |
| | | .contentType("application/json") |
| | | .execute().body(); |
| | | log.info(body); |
| | | if (StringUtils.contains(body,ERR_MSG)) { |
| | | if(StringUtils.contains(body, "300018")){ |
| | | throw new YamiShopBindException("商品图片尺寸过大"); |
| | | } |
| | | String message = I18nMessage.getMessage("yami.request.error"); |
| | | throw new YamiShopBindException(message+body); |
| | | } |
| | | return JSON.parseObject(body,typeReference); |
| | | } |
| | | |
| | | /** |
| | | * 微信请求-统一直播间接口处理 |
| | | */ |
| | | private <T> WxServerResponse<T> signAndSend(WxInterfaceInfo wxInterfaceInfo, Map<String, Object> requestParam, TypeReference<WxServerResponse<T>> typeReference) { |
| | | log.info(Json.toJsonString(requestParam)); |
| | | String str = liveUrl + wxInterfaceInfo.getRequestUrl() + wxInterfaceInfo.getAccessToken(); |
| | | System.out.println("str: " + str); |
| | | String body = HttpUtil.createPost(str) |
| | | .body(Json.toJsonString(requestParam)) |
| | | .contentType("application/json") |
| | | .execute().body(); |
| | | log.info(body); |
| | | return JSON.parseObject(body, typeReference); |
| | | } |
| | | |
| | | /** |
| | | * 微信请求-统一直播商品处理 |
| | | */ |
| | | private <T> WxLiveProdResponse<T> liveProdSignAndSend(WxInterfaceInfo wxInterfaceInfo, Map<String, Object> requestParam, TypeReference<WxLiveProdResponse<T>> typeReference) { |
| | | log.info(Json.toJsonString(requestParam)); |
| | | String str = liveUrl + wxInterfaceInfo.getRequestUrl() + wxInterfaceInfo.getAccessToken(); |
| | | System.out.println("str: " + str); |
| | | String body; |
| | | try { |
| | | body = HttpUtil.createPost(str) |
| | | .contentType("application/json") |
| | | .body(Json.toJsonString(requestParam)) |
| | | .execute().body(); |
| | | }catch (Exception e){ |
| | | // 远程微信连接异常! |
| | | throw new YamiShopBindException("yami.network.exception"); |
| | | } |
| | | log.info(body); |
| | | return JSON.parseObject(body, typeReference); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.wx.bean; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 微信小程序直播请求参数 |
| | | * @author yami |
| | | */ |
| | | @Data |
| | | public class GoodsInfoReqParam extends WxInterfaceInfo{ |
| | | |
| | | private String coverImgUrl; |
| | | |
| | | private String name; |
| | | |
| | | private Integer priceType; |
| | | |
| | | private Double price; |
| | | |
| | | private Double price2; |
| | | |
| | | private String url; |
| | | |
| | | private String requestUrl; |
| | | |
| | | /** |
| | | * 微信商品id |
| | | */ |
| | | private Long goodsId; |
| | | @Override |
| | | public String getRequestUrl() { |
| | | return "/add?access_token="; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.wx.bean; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 微信小程序直播参数 |
| | | * @author yami |
| | | */ |
| | | @Data |
| | | public class GoodsListReqParam extends WxInterfaceInfo{ |
| | | |
| | | private Long offset; |
| | | |
| | | private Long limit; |
| | | |
| | | private Integer status; |
| | | |
| | | @Override |
| | | public String getRequestUrl() { |
| | | return "/getapproved?access_token="; |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.wx.bean; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 微信小程序直播参数 |
| | | * @author yami |
| | | */ |
| | | @Data |
| | | public class GoodsReqInfo extends WxInterfaceInfo{ |
| | | |
| | | /** |
| | | * 商品ID |
| | | */ |
| | | private Long goodsId; |
| | | |
| | | private List<Long> goodsIds; |
| | | /** |
| | | * 审核单ID |
| | | */ |
| | | private Long auditId; |
| | | |
| | | private String requestUrl; |
| | | |
| | | @Override |
| | | public String getRequestUrl() { |
| | | return requestUrl; |
| | | } |
| | | |
| | | public void setRequestUrl(String requestUrl) { |
| | | this.requestUrl = requestUrl; |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.wx.bean; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 图片请求参数 |
| | | * @author yami |
| | | */ |
| | | @Data |
| | | public class ImageUploadReqParam { |
| | | |
| | | private String name; |
| | | |
| | | private String type = "image/jpeg"; |
| | | |
| | | private Integer size; |
| | | |
| | | private byte[] file; |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.wx.bean; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 直播用户请求参数 |
| | | * @author yami |
| | | */ |
| | | @Data |
| | | public class LiveUserReqInfo extends WxInterfaceInfo{ |
| | | |
| | | /** |
| | | * 主播微信号 |
| | | */ |
| | | private String username; |
| | | /** |
| | | * 角色列表 |
| | | */ |
| | | private Integer role; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.wx.bean; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 微信直播间接口所需参数 |
| | | * @author LHD |
| | | */ |
| | | @Data |
| | | public class PageLiveRoomInfo extends WxInterfaceInfo{ |
| | | |
| | | private Long roomId; |
| | | |
| | | @Override |
| | | public String getRequestUrl() { |
| | | return "/wxa/business/getliveinfo?access_token="; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.wx.bean; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 修改直播间商品请求参数 |
| | | * @author yami |
| | | */ |
| | | @Data |
| | | public class UpdateGoodsInfoReqParam extends WxInterfaceInfo{ |
| | | |
| | | private String coverImgUrl; |
| | | |
| | | private String name; |
| | | |
| | | private Integer priceType; |
| | | |
| | | private Double price; |
| | | |
| | | private Double price2; |
| | | |
| | | private String url; |
| | | |
| | | private String requestUrl; |
| | | |
| | | /** |
| | | * 微信商品id |
| | | */ |
| | | private Long goodsId; |
| | | |
| | | @Override |
| | | public String getRequestUrl() { |
| | | return "/wxaapi/broadcast/goods/update?access_token="; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.wx.bean; |
| | | |
| | | import lombok.Data; |
| | | import org.apache.http.entity.mime.content.ByteArrayBody; |
| | | |
| | | /** |
| | | * 微信接口所需参数 |
| | | * @author LHD |
| | | */ |
| | | @Data |
| | | public class WxInterfaceInfo { |
| | | |
| | | /** |
| | | * 媒体文件类型,分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb) |
| | | */ |
| | | private String imgType = "image"; |
| | | |
| | | /** |
| | | * 微信的accessToken |
| | | */ |
| | | private String accessToken; |
| | | |
| | | /** |
| | | * 图片字节数组 |
| | | */ |
| | | private byte[] bytes; |
| | | private Long limit; |
| | | |
| | | private Long start; |
| | | |
| | | private ByteArrayBody byteArray; |
| | | |
| | | public String getRequestUrl() { |
| | | return "/upload"; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.wx.bean; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 微信直播间接口所需参数 |
| | | * @author LHD |
| | | */ |
| | | @Data |
| | | public class WxLiveRoomInfo extends WxInterfaceInfo{ |
| | | |
| | | /** |
| | | * 直播间名称 |
| | | */ |
| | | private String name; |
| | | /** |
| | | * 主播昵称 |
| | | */ |
| | | private String anchorName; |
| | | /** |
| | | * 主播微信号 |
| | | */ |
| | | private String anchorWechat; |
| | | /** |
| | | * 背景图 |
| | | */ |
| | | private String coverImg; |
| | | /** |
| | | * 主播分享图 |
| | | */ |
| | | private String shareImg; |
| | | /** |
| | | * 购物直播频道封面图 |
| | | */ |
| | | private String feedsImg; |
| | | /** |
| | | * 是否开启官方收录 |
| | | */ |
| | | private Integer isFeedsPublic; |
| | | |
| | | /** |
| | | * 直播间类型 1.推流 2.手机直播 |
| | | */ |
| | | private Integer type; |
| | | |
| | | /** |
| | | * 0.竖屏 1.横屏 |
| | | */ |
| | | private Integer screenType; |
| | | /** |
| | | * 直播间功能 |
| | | */ |
| | | private String roomTools; |
| | | /** |
| | | * 购物直播频道封面图微信mediaId |
| | | */ |
| | | private String feedsImgId; |
| | | /** |
| | | * 购物直播频道封面图微信mediaId |
| | | */ |
| | | private String coverImgId; |
| | | /** |
| | | * 购物直播频道封面图微信mediaId |
| | | */ |
| | | private String shareImgId; |
| | | /** |
| | | * 直播开始时间 |
| | | */ |
| | | private Long wxStartTime; |
| | | /** |
| | | * 直播结束时间 |
| | | */ |
| | | private Long wxEndTime; |
| | | /** |
| | | * 是否关闭客服 0 开启,1 关闭 |
| | | */ |
| | | private Integer closeKf; |
| | | /** |
| | | * 是否关闭点赞 0 开启,1 关闭 |
| | | */ |
| | | private Integer closeLike; |
| | | /** |
| | | * 是否关闭货架 0 开启,1 关闭 |
| | | */ |
| | | private Integer closeGoods; |
| | | /** |
| | | * 是否关闭评论 0 开启,1 关闭 |
| | | */ |
| | | private Integer closeComment; |
| | | /** |
| | | * 是否关闭回放 0 开启,1 关闭 |
| | | */ |
| | | private Integer closeReplay; |
| | | /** |
| | | * 是否关闭分享 0 开启,1 关闭 |
| | | */ |
| | | private Integer closeShare; |
| | | |
| | | |
| | | @Override |
| | | public String getRequestUrl() { |
| | | return "/wxaapi/broadcast/room/create?access_token="; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.wx.bean; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 微信直播间商品详情参数 |
| | | * @author yami |
| | | */ |
| | | @Data |
| | | public class WxRoomProdInfo extends WxInterfaceInfo{ |
| | | |
| | | private List<Long> ids; |
| | | |
| | | private Long roomId; |
| | | |
| | | @Override |
| | | public String getRequestUrl() { |
| | | return "/wxaapi/broadcast/room/addgoods?access_token="; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.wx.bean.resp; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 微信小程序直播响应参数 |
| | | * @author yami |
| | | */ |
| | | @Data |
| | | public class GoodsInfoRespParam { |
| | | /** |
| | | * 商品ID |
| | | * "goodsId":"5","auditId":430376413,"errcode":0 |
| | | * {"goodsId":"8","auditId":430376427,"errcode":0} |
| | | */ |
| | | private Integer goodsId; |
| | | /** |
| | | * 审核单ID |
| | | */ |
| | | private Integer auditId; |
| | | |
| | | /** |
| | | * 商品图片链接 |
| | | */ |
| | | private String coverImgUrl; |
| | | |
| | | /** |
| | | * 商品名称 |
| | | */ |
| | | private String name; |
| | | |
| | | /** |
| | | * 1:一口价,此时读price字段; 2:价格区间,此时price字段为左边界,price2字段为右边界; 3:折扣价,此时price字段为原价,price2字段为现价; |
| | | */ |
| | | private Integer priceType; |
| | | |
| | | /** |
| | | * 价格左区间,单位“元” |
| | | */ |
| | | private Double price; |
| | | |
| | | /** |
| | | * 价格右区间,单位“元” |
| | | */ |
| | | private Double price2; |
| | | |
| | | /** |
| | | * 商品小程序路径 |
| | | */ |
| | | private String url; |
| | | /** |
| | | * 1、2:表示是为 API 添加商品,否则是直播控制台添加的商品 |
| | | */ |
| | | private Integer thirdPartyTag; |
| | | |
| | | private Integer errcode; |
| | | |
| | | /** |
| | | * 0:未审核,1:审核中,2:审核通过,3审核失败 |
| | | */ |
| | | private Integer auditStatus; |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.wx.bean.resp; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 微信小程序直播参数 |
| | | * @author yami |
| | | */ |
| | | @Data |
| | | public class GoodsListInfosRespParam { |
| | | /** |
| | | * 商品ID |
| | | */ |
| | | private Long goodsId; |
| | | /** |
| | | * 商品图片url |
| | | */ |
| | | private String coverImgUrl; |
| | | /** |
| | | * 商品名称 |
| | | */ |
| | | private String name; |
| | | /** |
| | | * 商品详情页的小程序路径 |
| | | */ |
| | | private String url; |
| | | /** |
| | | * 1:一口价,此时读price字段; 2:价格区间,此时price字段为左边界,price2字段为右边界; 3:折扣价,此时price字段为原价,price2字段为现价; |
| | | */ |
| | | private Integer priceType; |
| | | /** |
| | | * 价格左区间,单位“元” |
| | | */ |
| | | private Double price; |
| | | /** |
| | | * 价格右区间,单位“元” |
| | | */ |
| | | private Double price2; |
| | | /** |
| | | * 1、2:表示是为 API 添加商品,否则是直播控制台添加的商品 |
| | | */ |
| | | private Integer thirdPartyTag; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.wx.bean.resp; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 微信小程序直播参数 |
| | | * @author yami |
| | | */ |
| | | @Data |
| | | public class GoodsListRespParam { |
| | | |
| | | private Long errcode; |
| | | |
| | | private String errmsg; |
| | | |
| | | private GoodsListInfosRespParam goods; |
| | | /** |
| | | * 商品个数 |
| | | */ |
| | | private Integer total; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.wx.bean.resp; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 注册返回值 |
| | | * @author LGH |
| | | */ |
| | | @Data |
| | | public class ImageResponse { |
| | | |
| | | private String type; |
| | | |
| | | private String media_id; |
| | | |
| | | private String created_at; |
| | | |
| | | // private String[] item; |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.wx.bean.resp; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 直播用户响应参数 |
| | | * @author yami |
| | | */ |
| | | @Data |
| | | public class LiveUserRespInfo{ |
| | | |
| | | /** |
| | | * 主播微信号 |
| | | */ |
| | | private String username; |
| | | /** |
| | | * 昵称 |
| | | */ |
| | | private String nickname; |
| | | /** |
| | | * 头像 |
| | | */ |
| | | private String headingimg; |
| | | /** |
| | | * 角色列表 |
| | | */ |
| | | private Integer[] roleList; |
| | | /** |
| | | * openId |
| | | */ |
| | | private String openid; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.wx.bean.resp; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 注册返回值 |
| | | * @author LGH |
| | | */ |
| | | @Data |
| | | public class RoomDetailResponse { |
| | | /** |
| | | * 直播间id |
| | | */ |
| | | private Long roomId; |
| | | /** |
| | | * 直播间名称 |
| | | */ |
| | | private String name; |
| | | /** |
| | | * 主播昵称 |
| | | */ |
| | | private String anchorName; |
| | | /** |
| | | * 背景图 |
| | | */ |
| | | private String coverImg; |
| | | /** |
| | | * 主播分享图 |
| | | */ |
| | | private String shareImg; |
| | | /** |
| | | * 购物直播频道封面图 |
| | | */ |
| | | private String feedsImg; |
| | | /** |
| | | * 是否开启官方收录 |
| | | */ |
| | | private Integer isFeedsPublic; |
| | | |
| | | /** |
| | | * 直播间类型 1.推流 2.手机直播 |
| | | */ |
| | | private Integer type; |
| | | |
| | | /** |
| | | * 1.竖屏 2.横屏 |
| | | */ |
| | | private Integer screenType; |
| | | /** |
| | | * 直播间功能 |
| | | */ |
| | | private String roomTools; |
| | | /** |
| | | * 购物直播频道封面图微信mediaId |
| | | */ |
| | | private String feedsImgId; |
| | | /** |
| | | * 购物直播频道封面图微信mediaId |
| | | */ |
| | | private String coverImgId; |
| | | /** |
| | | * 购物直播频道封面图微信mediaId |
| | | */ |
| | | private String shareImgId; |
| | | /** |
| | | * 直播开始时间 |
| | | */ |
| | | private Long wxStartTime; |
| | | /** |
| | | * 直播结束时间 |
| | | */ |
| | | private Long wxEndTime; |
| | | /** |
| | | * 直播间状态 |
| | | */ |
| | | private Integer liveStatus; |
| | | /** |
| | | * 直播间商品 |
| | | */ |
| | | private List<GoodsInfoRespParam> goods; |
| | | /** |
| | | * 直播间商品 |
| | | */ |
| | | private Integer total; |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.common.wx.bean.resp; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 注册返回值 |
| | | * @author LGH |
| | | */ |
| | | @Data |
| | | public class RoomResponse { |
| | | |
| | | private Long roomId; |
| | | |
| | | private String qrcodeUrl; |
| | | |
| | | private String createdAt; |
| | | |
| | | } |
New file |
| | |
| | | yami.activity.cannot.delete=Cannot delete in the active state |
| | | yami.activity.prod.cannot.delete=The activity is in progress. You can not delete the product. You can wait for the activity to finish or after the group activity is invalid |
| | | yami.activity.cannot.find=This activity was not found. Please try again later |
| | | yami.activity.cannot.find.check=The activity does not exist, has not started or has ended |
| | | yami.activity.prod.no.exist=The active product does not exist. Please try again later |
| | | yami.activity.prod.status=The activity includes offline products |
| | | yami.activity.prod.update.error=Failed to update active product |
| | | yami.activity.prod.no.auth=You are not authorized to operate this activity product |
| | | yami.activity.no.auth=You are not authorized to operate this activity |
| | | yami.activity.add.prod.empty=The product to be added cannot be empty |
| | | yami.activity.enable.prod.empty=Failed to enable. Please select at least one active product |
| | | yami.activity.disable=Failure to fail, activity not in progress or preheat state cannot fail operation |
| | | yami.activity.info.check=Please fill in the full information |
| | | yami.activity.item.check=Activity item cannot be empty, there must be at least one active item |
| | | yami.activity.status.check=The activity has been offline by the platform. The status cannot be changed |
| | | yami.activity.now.over.end.time=The current time has exceeded the end time of the activity. The activity cannot be enabled |
| | | yami.distribution.has.distributionUser=The user is already in use, please do not modify it again |
| | | yami.discount.MaxReduceAmount.limit=Please enter a number less than 10 trillion |
| | | yami.activity.add.success=Added successfully |
| | | yami.activity.update.success=Modification succeeded |
| | | yami.submitted.successfully=Submitted successfully |
| | | yami.submitted.examine=Submitted for review |
| | | yami.no.auth=No permission to operate |
| | | yami.delete.successfully=Deletion succeeded |
| | | yami.undo.successfully=Revocation successful |
| | | yami.address.added.successfully=Address added successfully |
| | | yami.address.modified.successfully=Address modified successfully |
| | | yami.deleted.address.successfully=Address deleted successfully |
| | | yami.address.exists=The address already exists |
| | | yami.address.add.limit=Shipping address has reached the upper limit, no more new address can be added |
| | | yami.address.cannot.delete=The default address cannot be deleted |
| | | yami.user.address.delete=The address has been deleted |
| | | yami.user.receive.score=Get points successfully |
| | | yami.user.receive.score.check=Today has been signed in, please try again tomorrow! |
| | | yami.shopCart.enter.num=Enter change quantity |
| | | yami.constant.code.expire=QR code expired |
| | | yami.network.exception=Network anomaly |
| | | yami.network.busy=The server is busy. Please try again later |
| | | yami.examine.fail=Failed to submit for review |
| | | yami.examine.already=The application has been reviewed |
| | | yami.examine.status.error=Audit status error |
| | | yami.get.goods=Failed to get product list |
| | | yami.request.error=Third party request failed\uFF1A |
| | | yami.request.data.too.long=The request data is too long |
| | | yami.address.receiver.length.limit=The length of receiver's name is too long |
| | | yami.group.team.no.exist=Team information not found |
| | | yami.group.order.update.fail=Failed to update the order to be shipped. Please try again later |
| | | yami.group.team.no.join=The team is not in the group, can not participate in the group |
| | | yami.group.no.progress=The group activity is not in progress. Please try again later |
| | | yami.group.prod.status.error=The active product is not in normal state |
| | | yami.group.prod.sold.out=The product specifications have been sold out or off the shelf |
| | | yami.group.prod.shop.limit=The limited quantity of goods purchased is |
| | | yami.group.user.shop.num=, you have purchased |
| | | yami.group.user.now.shop=Buy now |
| | | yami.group.prod.overstep.shop.limit=,Exceeding the maximum purchase quantity |
| | | yami.group.prod.insufficient.stock=Insufficient stock, please reselect purchase quantity |
| | | yami.group.prod.has.group.order=You have an order in group purchase, please be patient and wait for the group to be successful. |
| | | yami.group.user.join.group=You are participating in this activity, please try again after the success of the group |
| | | yami.group.user.join.check=The current order is waiting for the group status, and the next operation can be carried out after waiting for the group |
| | | yami.group.user.join.group.error=You have participated in this group. You can't join it again |
| | | yami.group.order.no.exist=The order does not exist |
| | | yami.request.too.much=The request is too frequent. Please try again later |
| | | yami.day=day |
| | | yami.constant.num=second |
| | | yami.seckill.order.expire=The order has expired. Please reselect the product for seckill |
| | | yami.seckill.complete=This round of goods have been killed in seconds, there are still users who have not paid, there are still opportunities |
| | | yami.seckill.finish=This product has been killed by seconds. Please come earlier next time |
| | | yami.seckill.limit.shop=The second sale of goods is limited |
| | | yami.seckill.num=piece |
| | | yami.seckill.exception=Seckill activity not started or ended |
| | | yami.seckill.not.start=Seckill activity has not started |
| | | yami.seckill.has.ended=Seckill activity has ended |
| | | yami.seckill.prod=Products cannot participate in the second kill |
| | | yami.seckill.input.maxNum=Please enter the purchase limit quantity |
| | | yami.seckill.cannot.delete=Seckill activity is not closed, unable to delete |
| | | yami.seckill.cannot.invalid=Spike activity has violated the shelf, can not be closed |
| | | yami.shop.cart.prod.unrecognized=The shopping cart contains unrecognized items |
| | | yami.delivery.address=Please fill in the delivery address |
| | | yami.product.remove=Item removed from cart |
| | | yami.station.address.check=Please fill in the self provided information |
| | | yami.station.detail.check=Please select the pick-up point and fill in the complete self collection information |
| | | yami.station.no.find=The bootstrap information was not found |
| | | yami.product.not.exist=The product information cannot be found |
| | | yami.product.off.not.enable.disProduct=The product are not online, and the distribution product cannot be put on the shelf |
| | | yami.product.already.deleted=This product has been removed |
| | | yami.stock.no.number=Inventory must be a purely numeric integer, and enter up to 9 digits |
| | | yami.product.service.delete=The product status is incorrect, please contact the platform |
| | | yami.renovation.not.exist=The decoration information could not be found |
| | | yami.unable.get.page=Unable to get page information |
| | | yami.product.off.shelves=Product offline |
| | | yami.product.disable = The product has been withdrawn or sold out |
| | | yami.product.on.normal=The product is not in normal state, modification failed |
| | | yami.insufficient.inventory= Insufficient stock, please place a new order |
| | | yami.insufficient.inventory.place.new.order= insufficient stock |
| | | yami.product=product |
| | | yami.selelct.items=Please select the goods you need to add to the shopping cart |
| | | yami.product.download=Start downloading templates |
| | | yami.product.dvy.type=Please select delivery method |
| | | yami.product.dvy.fee=Freight cannot be less than zero |
| | | yami.product.group.check=A combined item must be associated with a single item |
| | | yami.product.category.not.under=The current platform category is no longer available, please refresh the category list and select again |
| | | yami.product.category.not.exit=You have cancelled your contract with this product type, please re-contract this product type to be listed |
| | | yami.product.category.is.offline=The platform category has been taken offline and the product cannot be listed |
| | | yami.product.shop.category.not.under=The current store category is no longer available, please refresh the category list and select again |
| | | yami.product.brand.not.under=The currently selected brand is no longer available, please select again |
| | | yami.product.brand.not.delete=Some products are using the brand and cannot be deleted |
| | | yami.product.join.group=The product is participating in the group activity. The specification cannot be modified |
| | | yami.product.join.seckill=The product is participating in the seckill activity. The specification cannot be modified |
| | | yami.product.no.exist=Product information does not exist |
| | | yami.product.no.auth=You have no permission to obtain the product specification information |
| | | yami.product.no.auth.update=No permission to modify this product |
| | | yami.product.category.offline=The platform classification is offline, the product cannot be put on the shelf, please contact the administrator before operation |
| | | yami.product.signing.category.invalid=The contract classification of this product has expired, and the status of the product cannot be modified |
| | | yami.product.shop.category.offline=This shop category is offline, the product cannot be put on the shelf |
| | | yami.product.shop.offline=The store is offline in violation of the rules. This operation cannot be performed. Please contact the administrator and try again |
| | | yami.product.shop.AUDIT=The store is reviewing. This operation cannot be performed. Please contact the administrator and try again |
| | | yami.product.enable.sku=At least one product specification must be enabled |
| | | yami.same.specifications=The same name specification already exists |
| | | yami.shop.name.have.already=Already have the same store name |
| | | yami.shop.auditing=The store is under review, please do not submit it repeatedly |
| | | yami.product.sold.out=Goods sold empty or off the shelf |
| | | yami.order.expired=The order has expired. Please order again |
| | | yami.add.live.prod.num=Failed to add wechat live room products |
| | | yami.live.room.wechat.not.exist = The room does not exist in the wechat live console |
| | | yami.live.prod.wechat.not.exist = The product does not exist on wechat live console |
| | | yami.category.one.check=The first level classification cannot be changed to the second level classification |
| | | yami.category.two.check=Secondary classification cannot be changed to primary classification |
| | | yami.category.superior.check=The superior of classification cannot be oneself |
| | | yami.category.name.exist=Category name already exists\uFF01 |
| | | yami.category.status.check=Failed to modify. The superior classification does not exist or is not in normal status |
| | | yami.category.delete.check=There are goods under this category, please delete the goods under this category first |
| | | yami.category.delete.child=Please delete the subcategory and then delete the category |
| | | yami.score.select.num=Please select product |
| | | yami.score.select.num.shop=Please select the goods you need to purchase |
| | | yami.user.score.enough=Insufficient user points |
| | | yami.user.score.input.check=Please enter the correct number of points |
| | | yami.user.score.no.enough=Unable to submit order due to insufficient points |
| | | yami.user.score.prod=It's not a point product or an abnormal point price |
| | | yami.user.no.get.phone=Unable to get user's mobile phone number information |
| | | yami.user.account.error=Incorrect username or password |
| | | yami.user.account.exist=The user name already exists |
| | | yami.user.account.no.exist=user does not exist |
| | | yami.user.disabled = user is disabled, please contact customer service |
| | | yami.user.err.phone=Please enter a valid phone number |
| | | yami.user.account.lock=The account has been locked. Please contact the administrator |
| | | yami.user.account.lock.pre=The account has been locked due to: |
| | | yami.user.account.lock.after=, Please contact the administrator |
| | | yami.user.phone.exist=The mobile phone number has been registered, unable to re register |
| | | yami.user.name.check=The user name should consist of a 4-16 digit alphanumeric underline |
| | | yami.user.password.no.exist=New password cannot be empty |
| | | yami.user.password.check=The new password cannot be the same as the original password |
| | | yami.user.code.error=The verification code is wrong or expired |
| | | yami.user.code.empty=The verification code cannot be empty |
| | | yami.user.code.check.too.much=The verification code is checked too frequently. Please try again later |
| | | yami.verification.limit=The number of SMS verification codes sent today has reached the upper limit |
| | | yami.verification.time.check=The captcha can only be sent once a minute |
| | | yami.verification.expire=The verification code has expired. Please resend the verification code for verification |
| | | yami.sending.message.failed=Failed to send SMS. Please try again later |
| | | yami.user.login.error=Abnormal login information |
| | | yami.user.login.type=Unable to get login method |
| | | yami.user.unable.login.type=The login method is not implemented |
| | | yami.user.no.exist=Unable to get user information |
| | | yami.select.source=Please select material type |
| | | yami.user.level.no.exist=The membership level does not exist or the current level is not a paying member level |
| | | yami.user.pay.level.check=Users cannot purchase lower level members during the membership period |
| | | yami.user.growh.no.enough=Insufficient growth value of users, unable to purchase |
| | | yami.user.request.error=User related requests should start with / P!!! |
| | | yami.user.addr.update.error=Unable to modify user default address. Please try again later |
| | | yami.user.level.delete.error=This level cannot be deleted. At least one level must be kept |
| | | yami.shop.user.account.lock=Account has been locked, please contact the store administrator |
| | | yami.shop.sys.super.user.no.modify=Store Super Administrator, cannot be changed here |
| | | yami.shop.account.have.only.one=One store needs only one super administrator, please handle the store account data |
| | | yami.shop.data.is.removed=This data has been deleted |
| | | yami.shop.card.is.exist=This bank card number already exists |
| | | yami.distribution.close=Promotion plan closed |
| | | yami.distribution.set.exception=Distribution exception settings |
| | | yami.distribution.userWallet.banlance=You still have balance in your distribution account |
| | | yami.distribution.info.cardno=Application information is not complete, need ID card number |
| | | yami.distribution.info.pic=Application information is not complete, need ID card photo |
| | | yami.distribution.info.name=Application information is incomplete, real name is required |
| | | yami.distribution.submit.examine=You have submitted it for review. Please wait patiently |
| | | yami.distribution.ban.examine=The account has been permanently blocked |
| | | yami.distribution.clear.examine=It has been temporarily blocked and cannot be applied. Please contact the administrator |
| | | yami.distribution.success.examine=Your audit has passed, no need to review again |
| | | yami.distribution.get.examine=Unable to get the information of the invitee |
| | | yami.distribution.shop.error=The information of the inviting store is wrong |
| | | yami.distribution.user.error=You can't invite yourself |
| | | yami.distribution.user.Unqualified=If you do not meet the application conditions, please contact customer service to apply |
| | | yami.distribution.fee.error=The consumption amount does not meet the requirements |
| | | yami.distribution.fee.num=The number of consumption does not meet the requirements |
| | | yami.distribution.user.no.shop=You are not a distributor of the current store |
| | | yami.distribution.user.no.distributor=You are not a distributor yet |
| | | yami.distribution.user.no.distributor1=Your distribution identity is abnormal, please contact the administrator |
| | | yami.distribution.no.distributor=You are not a distributor yet. You cannot upgrade |
| | | yami.distribution.level.limit=The level limit has been reached |
| | | yami.distribution.level.condition=You are not eligible for upgrade |
| | | yami.distribution.cash.param1=The withdrawal amount cannot be empty |
| | | yami.distribution.cash.param2=The minimum withdrawal amount is $1 |
| | | yami.distribution.cash.num=The number of withdrawals is |
| | | yami.distribution.cash.month=monthly |
| | | yami.distribution.set.error=The basic distribution setting information of the store was not found |
| | | yami.distribution.prod.exist.error=The distribution item information was not found |
| | | yami.distribution.prod.award=Fixed reward proportion cannot exceed 100% |
| | | yami.distribution.prod.level=The level reward proportion cannot exceed 100% |
| | | yami.distribution.prod.award.check=Fixed bonus settings cannot exceed the maximum price of an item |
| | | yami.distribution.prod.level.check=The level reward setting cannot exceed the maximum price of the product |
| | | yami.distribution.prod.parent.award=The fixed reward proportion of invitees cannot exceed 100% |
| | | yami.distribution.prod.parent.level=The level reward proportion of invitees cannot exceed 100% |
| | | yami.distribution.prod.parentAward.check=The invitee fixed reward cannot be greater than or equal to the highest price of the item |
| | | yami.distribution.prod.parentLevel.check=Inviter level reward cannot be greater than or equal to the highest price of the item |
| | | yami.distribution.prod.price.check=Reward setting cannot be greater than or equal to the highest price of the product or 100% |
| | | yami.distribution.prod.exist=Distribution item already exists |
| | | yami.distribution.exist.error=Distributor information not found |
| | | yami.distribution.enable.error=The merchant did not open the binding user mode |
| | | yami.distribution.extension.error=You have become the promoter of the shop, and cannot be promoted |
| | | yami.distribution.extension.time=You are still in the promotion period and cannot be promoted by new promoters |
| | | yami.distribution.user.protection.period=The user failed to bind during the protection period |
| | | yami.distribution.status.error=Promoter status abnormal |
| | | yami.distribution.get.fail=Failed to obtain promoter information |
| | | yami.distribution.batch.update.income=Failed to batch update distribution revenue status |
| | | yami.distribution.fee.than.error=The withdrawal amount is greater than the maximum withdrawal amount |
| | | yami.distribution.fee.less.error=The withdrawal amount is less than the minimum withdrawal amount |
| | | yami.distribution.balance.not.enough=Withdrawal failed, insufficient balance |
| | | yami.distribution.user.withdrawals=If you are not bound to WeChat, please log in with the WeChat Mini Program authorization before withdrawing cash |
| | | yami.sys.menu.exist=Menu URL cannot be empty |
| | | yami.sys.file.no.exist=The domain name of the file is not configured. The successful image cannot be uploaded |
| | | yami.sys.sms.no.exist=Unable to get SMS configuration, unable to send SMS |
| | | yami.sys.wxMa.no.exist=Please set the wechat applet information on the background page before operation |
| | | yami.sys.wxMp.no.exist=Please set up WeChat official account information on the background page before proceeding. |
| | | yami.sys.wxApp.no.exist=Please set the wechat application information on the background page before operation |
| | | yami.sys.wxPay.no.exist=Please set the wechat application information on the background page before operation |
| | | yami.sys.wxDomain.no.exist=Please set the callback domain name on the background page before operation |
| | | yami.sys.menu.child.delete=Please delete the submenu or button first |
| | | yami.sys.menu.delete.error=System menu, cannot be deleted |
| | | yami.sys.menu.user.error=You can't be your superior |
| | | yami.sys.menu.superior.list=The superior menu can only be directory type |
| | | yami.sys.menu.superior.menu=The superior menu can only be a menu type |
| | | yami.sys.role.identical.name=The same role name already exists in the system |
| | | yami.document.no.content=The document has no content |
| | | yami.file.error=File format error |
| | | yami.modified.settlement.information=Settlement information changed |
| | | yami.platform.num.check=Platform today |
| | | yami.num.limit=The number of times available has reached the maximum! |
| | | yami.sys.delete.error=Current user cannot delete |
| | | yami.sys.admin.error=System administrator cannot delete |
| | | yami.sys.select.user=Please select the user to be deleted |
| | | yami.sys.user.already=The user already exists |
| | | yami.sys.sms.package=The purchased SMS package does not exist. Please refresh and try again |
| | | yami.sys.sms.package.limit=The number of packages has reached the upper limit of 10, please delete and add again! |
| | | yami.sys.illegalArgument=Illegal request parameter, please check! |
| | | yami.cannot.get.app.info=Unable to get app information |
| | | yami.same.key=A key with the same configuration already exists in the system |
| | | yami.sys.paypal.no.exist=Please set up paypal related information in the backend page before proceeding |
| | | yami.address.deleted=Order item does not exist |
| | | yami.item.has.commented=Changed order item has been commented, please do not repeat common |
| | | yami.item.com.repeated=Order comment has been submitted |
| | | yami.confirm.receipt=Please confirm receipt before common |
| | | yami.comment.is.delete=Evaluation does not exist or has been deleted, please return and refresh to try again |
| | | yami.cannot.reapply=You have applied to open the store. You cannot apply again |
| | | yami.shop.num.check=Shop today |
| | | yami.store.name.exist=Shop name already exists |
| | | yami.store.not.exist=Store information not found |
| | | yami.shop.not.category=The current store does not have a signed platform classification, please sign the classification first |
| | | yami.station.account.exist=This account already exists. Please enter a new account |
| | | yami.store.account.exist=The account already exists, please re-enter |
| | | yami.store.apply.no.exist=Application information not found |
| | | yami.store.offline.check=The store is not open or closed, and cannot be offline |
| | | yami.shop.company.repeat.application=You cannot submit multiple change applications at the same time,please revoke the application submitted last time and apply again |
| | | yami.cannot.update.wallet=Failed to update store wallet information |
| | | yami.cannot.distribution.update.wallet=Failed to update promoter wallet information |
| | | yami.store.brand.name.error=The brand name already exists |
| | | yami.my.store.no.cash=Self operated stores cannot withdraw cash |
| | | yami.shop.cash.too.less=The amount of withdrawal shall not be less than 1.00 RMB |
| | | yami.shop.cannot.delete.card=Default card cannot be deleted |
| | | yami.shop.max.card.num=The maximum number of bank cards has been reached and cannot be added |
| | | yami.shop.least.one.card=Keep at least one bank card |
| | | yami.shop.cannot.delete.check=The bank card used to apply for withdrawal cannot be deleted |
| | | yami.shop.station.close=The pickup point has been closed. Please contact the administrator |
| | | yami.shop.station.not.open=The pick-up point is not in operation |
| | | yami.shop.phone.no.exist=Mobile phone number cannot be empty |
| | | yami.shop.update.balance=Failed to update balance record. Please try again later |
| | | yami.shop.cash.no.enough=Insufficient withdrawal amount |
| | | yami.shop.cash.grant=Cash withdrawal and distribution |
| | | yami.shop.company.credit.code.repeat=Duplicate unified credit code |
| | | yami.shop.business.date.error=The business start date cannot be greater than or equal to the business end time |
| | | yami.shop.company.date.not.empty=Business date cannot be empty |
| | | yami.shop.bank.card.not.empty=At least one bank card must be added |
| | | yami.shop.bank.card.no.repeat=Duplicate account |
| | | yami.shop.bank.card.max.limit=The number of bank cards cannot exceed |
| | | yami.cash.grant=Cash withdrawal |
| | | yami.open.store=Please apply for shop opening first |
| | | yami.password.error=The original password is incorrect |
| | | yami.stop.cannot.modified=Store account has been set and cannot be modified |
| | | yami.stop.examine.success=The business has been approved successfully, no need to audit again |
| | | yami.stop.cannot.open=The account has been opened and cannot be opened again |
| | | yami.sign.check=Signature verification failed |
| | | yami.bar.code.exist=Single item barcode already exists |
| | | yami.select.only.shop.type=Please select a store type |
| | | yami.select.a.shop=Please select a store |
| | | yami.transaction.not.exists=Transaction number does not exist |
| | | yami.query.error=Query error |
| | | yami.order.no.exist=Order does not exist |
| | | yami.order.is.delivery=The order has already been partially shipped and cannot be shipped in bulk |
| | | yami.order.amount.error=The order amount is wrong and cannot be paid |
| | | yami.order.amount.too.large.error=The order amount is too large and cannot be paid |
| | | yami.order.code.no.exist=The checkout code, there is no corresponding order |
| | | yami.order.code.no.error=Checkout code error |
| | | yami.h5.index.ad.images.limit=Rotation ads limit 10 |
| | | yami.order.payed=Order has been paid and cannot be cancelled |
| | | yami.order.not.paid=The current order has not been paid, unable to apply |
| | | yami.order.has.failed=The current order has failed. No refund is allowed |
| | | yami.order.receipt.no.delivery=Order not shipped, cannot confirm receipt |
| | | yami.order.pay.user.disable=You have been disabled and cannot purchase. Please contact the customer service of the platform |
| | | yami.order.status.no.right=The order is not in the status to be put into storage, so it cannot be put into storage |
| | | yami.order.delivery.no.right=The order is not in the status of waiting for shipment and cannot be delivered |
| | | yami.order.pay.fail=Payment failed. The order is not in unpaid status |
| | | yami.order.no.delivery=The order is not in the waiting state and cannot be confirmed |
| | | yami.order.delivery.refund.error=The order has refund information in process, please process it before shipment! |
| | | yami.order.receipt.refund=Order refund, cannot confirm receipt |
| | | yami.order.no.success=In order refund, the order is not completed or closed, so the order cannot be deleted |
| | | yami.order.no.dvyName=The name of the courier company can not be empty |
| | | yami.order.delivery.number=Wrong format of courier bill number |
| | | yami.order.delivery.error=When multiple stores submit orders, the delivery method can only be express delivery |
| | | yami.order.same.city.error=The current shop does not open the same city distribution! |
| | | yami.order.same.city.error2=The delivery distance is exceeded or the starting fee is not enough! |
| | | yami.order.same.city.error3=Current orders do not support same-city delivery!! |
| | | yami.order.same.city.error4=Exceeds the currently set delivery distance! |
| | | yami.order.unrecognized.prod=The order status is abnormal, the order address cannot be changed |
| | | yami.order.unrecognized.update=Order status is abnormal, order amount cannot be changed |
| | | yami.order.amount.check=The order amount must be greater than 0, or the data has changed (please refresh and try again) |
| | | yami.order.status.error=The order contains unrecognized items |
| | | yami.order.status.change=Order status has changed, please do not repeat operation |
| | | yami.order.status.check.change=The order status has changed, please place the order again |
| | | yami.order.submit.change=Please do not submit orders repeatedly |
| | | yami.order.refund.status.exist=Return status cannot be empty |
| | | yami.order.refund.exist=Refund note does not exist |
| | | yami.order.refund.define=Please confirm the refund before starting the refund operation |
| | | yami.order.refund.success=The refund has been successful. You cannot apply for refund again |
| | | yami.order.refund.cancel=The buyer has cancelled the application |
| | | yami.set.refund.information=Please select return address |
| | | yami.order.refund.day.check=The current order has received more than |
| | | yami.order.refund.day.check2=Days, no refund |
| | | yami.no.found.order=The order information was not found |
| | | yami.order.refund.score=Credit products, no refund |
| | | yami.availabl.cash.refund=Your cash withdrawal amount is insufficient and cannot be refunded |
| | | yami.not.sufficient.refund=Your amount to be settled is insufficient and cannot be refunded |
| | | yami.refund.processed=The refund has been processed and no repeat processing is required |
| | | yami.order.all.refund.go.on=The order already has goods in the process of refund, so the whole order cannot be refunded |
| | | yami.order.all.refund.check=The whole order is being refunded. No new refund operation can be performed |
| | | yami.order.need.station=Please select at least one order to be picked up by yourself |
| | | yami.order.refund.go.on=This product is in the process of being refunded. New refund operation cannot be performed |
| | | yami.refund.exceeded.amount=The refund amount has exceeded the order amount, unable to apply |
| | | yami.not.refunds.requested=No payment record found, unable to apply for refund |
| | | yami.refund.progress=The order is in the process of refund settlement, please do not repeat the operation |
| | | yami.unable.refund.information=Unable to get refund order information |
| | | yami.refund.amount.check=The payment amount and points of some order items of this order are 0, partial refund cannot be used! |
| | | yami.refund.platform.amount.check=There is a refund for this order. You can't use this platform! |
| | | yami.refund.num.check=The quantity of refund items has exceeded the quantity in the order. Application is not allowed |
| | | yami.order.processed=Refund order item has been processed, please do not apply again |
| | | yami.order.unfinished.cannot.destroy.account=you still have unfinished orders. Please wait until all orders have been finish |
| | | yami.cannot.find=No found refund information |
| | | yami.not.permission=Application failed. You do not have the permission |
| | | yami.not.submission=The current application type is not allowed to submit logistics information |
| | | yami.not.submission.delivery=Current status does not allow to submit logistics information operation |
| | | yami.not.update.delivery=Update of logistics information is not allowed in current status |
| | | yami.revocation.failed=Cancellation failed. The refund order does not exist |
| | | yami.shop.processing.check=The seller is processing a refund and cannot cancel the refund request |
| | | yami.user.delivery.check=The buyer has delivered the goods and cannot cancel the refund application |
| | | yami.user.receipt.check=The seller has received the goods and cannot cancel the refund application |
| | | yami.refund.success.check=Refund successful. Refund application cannot be cancelled |
| | | yami.refund.finish.check=All items in the order are refunded and cannot be cancelled |
| | | yami.refund.status.check=Undo failed. This operation is not allowed in the current state |
| | | yami.failed.not.exist=Failed to view. The refund order does not exist |
| | | yami.failed.not.permiso=Failed to view. You do not have this permission |
| | | yami.item.not.exist=The item does not exist in the order |
| | | yami.shopCart.take.off=Off the shelf |
| | | yami.contains.unrecognized.items=The shopping cart contains unrecognized items |
| | | yami.no.auth.update.form=You do not have permission to change the data of this report |
| | | yami.auth.fail=Authorization failed. Please re authorize |
| | | yami.img.name.exist=Picture name cannot be empty |
| | | yami.area.delete=Please delete sub region first |
| | | yami.delivery.using=In use, cannot delete |
| | | yami.selCity=Please select the designated city for package delivery |
| | | yami.model=Template |
| | | yami.img.lose=The picture is missing. Please upload the picture again |
| | | yami.unable.get.classification=Unable to get classification information |
| | | yami.select.notify.check=Please select at least one notification method |
| | | yami.select.notify.type.check=Other configuration of the current message type already exists. Please go to modify it. |
| | | yami.flush.category.tips=Please go to [member management] > [point growth value configuration] - > [point acquisition configuration] to configure and save |
| | | yami.form.time.check=Please select the start and end time |
| | | yami.form.data.error=The report data is incorrect, please refresh and re-enter |
| | | yami.coupon.no.auth=You have no permission to modify the coupon information |
| | | yami.coupon.receive.finish=The voucher cannot be collected or the voucher is finished! |
| | | yami.coupon.stock.enough=Insufficient coupon stock |
| | | yami.coupon.user.limit=The coupon has reached the upper limit of individual claim and cannot continue to receive it\uFF01 |
| | | yami.coupon.limit.check=The limited quantity of coupons should be greater than 0 |
| | | yami.coupon.time.check=Start time should be greater than end time |
| | | yami.coupon.launch.time.check = Coupon placement time cannot be empty |
| | | yami.coupon.launch.time.check1 = The casting time needs to be greater than the current time |
| | | yami.coupon.launch.time.lt.endtime = The Lanuch time needs to be less than the end time |
| | | yami.coupon.no.exist=Coupon does not exist |
| | | yami.coupon.delete.check1=The coupon has been claimed. Deletion failed |
| | | yami.coupon.delete.check2=The coupon has been put in, failed to delete |
| | | yami.coupon.receive.success=Coupon received successfully |
| | | yami.live.time.check=The start time cannot be greater than the end time |
| | | yami.live.time.one.check=The start time should be 10 minutes after the current time, and not after 6 months! |
| | | yami.live.time.two.check=The interval between the start time and the end time should not be less than 30 minutes or more than 24 hours! |
| | | yami.live.name.check=Name length does not conform to the rule! |
| | | yami.live.user.name.check=The host micro signal does not have real name authentication by \u3010\u5C0F\u7A0B\u5E8F\u76F4\u64AD\u3011\uFF01 |
| | | yami.live.room.check1=not configured in the applet management background customer service |
| | | yami.live.config.check=Failed to create. Please check the configuration of the live room carefully\uFF01 |
| | | yami.live.platform.numLimit=The number of times that the platform can get the live broadcast room information today has reached the limit\uFF01 |
| | | yami.live.prod.name.check=Illegal name length, at least 3 Chinese characters or 6 characters, maximum 14 Chinese characters! |
| | | yami.live.room.name.check=The length of the name of the studio is illegal, the shortest is 3 Chinese characters, and the longest is 17 Chinese characters! |
| | | yami.live.room.name.check2=The length of the host's nickname is illegal, the shortest is 2 Chinese characters, and the longest is 15 Chinese characters |
| | | yami.live.room.top.check=The ceiling has reached the upper limit of 10, which cannot be set. Please cancel the topping of other live broadcasting rooms first |
| | | yami.live.prod.delete.fail=Failed to delete live product |
| | | yami.live.room.delete.fail = Failed to delete live room |
| | | yami.live.prod.update.fail=Failed to update live product library |
| | | yami.live.prod.not.exist=The product associated with the current live broadcast product does not exist or has been deleted |
| | | yami.live.prod.examine=The product is under review and cannot be modified |
| | | yami.live.img.isWebp=Pictures cannot use webp format, jpg or png is recommended |
| | | yami.prod.pre.sell=Pre sale items cannot be added to the shopping cart! |
| | | yami.order=order |
| | | yami.order.station.check=Refund, unable to collect |
| | | yami.order.station.finish=Picked up |
| | | yami.prod.no.join.activity=The current product did not participate in the activity |
| | | yami.activity.no.start=At present, the activity of group organization has not started |
| | | yami.activity.already.end=The current group activity has ended |
| | | yami.activity.already.invalid=The current group activity is invalid |
| | | yami.job.get.error=Exception in getting crontrigger for timed task |
| | | yami.prod.category.error=Please select the three-level classification of the platform |
| | | yami.notify.tag.msg=Please select at least one label! |
| | | yami.user.payType.error=Please use WeChat or Alipay for payment. |
| | | yami.information.is.wrong=Your information is wrong, please try to refresh before operation |
| | | yami.balance.is.insufficient=Your balance is insufficient, please recharge the balance first |
| | | yami.id.number.already.exists=The ID number already exists. |
| | | yami.phone.number.already.exists=The phone number already exists in the system. |
| | | yami.phone.number.not.exists=The account does not exist |
| | | yami.get.user.cash.info=Unable to obtain withdrawal information |
| | | yami.get.user.withdraw.info=Unable to get user wallet information |
| | | yami.withdrawCash.update.no.auth=No permission to modify withdrawal information |
| | | yami.user.tag.not.exists=User tag does not exist |
| | | yami.user.tag.type.not.right=User tag type not right |
| | | yami.user.tag.refresh.limit=The refresh interval cannot be less than one minute |
| | | yami.user.tag.time=The start time cannot be later than the end time |
| | | yami.user.tag.number=The minimum number cannot be greater than the maximum number |
| | | yami.user.tag.amount=The minimum amount cannot be greater than the maximum amount |
| | | yami.finance.transactionTime=Transaction Time |
| | | yami.finance.orderNumber=Order Number |
| | | yami.finance.incOrPay=Pay Or Income |
| | | yami.finance.payType=Payment Method |
| | | yami.finance.transactionAmount=Transaction Amount |
| | | yami.finance.reportTitle=Financial Statement |
| | | yami.finance.income=Income |
| | | yami.finance.pay=Pay |
| | | yami.payType.pay0=Point Payment |
| | | yami.payType.pay1=WeChat Payment |
| | | yami.payType.pay2=Alipay Payment |
| | | yami.payType.pay3=WeChat Scan Code Payment |
| | | yami.payType.pay4=WeChat H5 Payment |
| | | yami.payType.pay5=WeChat Official Account Payment |
| | | yami.payType.pay6=Alipay H5 Payment |
| | | yami.payType.pay7=Alipay APP Payment |
| | | yami.payType.pay8=WeChat APP Payment |
| | | yami.payType.pay9=User balance Payment |
| | | yami.store.name.no.exist=Store name cannot be empty |
| | | yami.store.name.check1=Product name length should be less than {max} |
| | | yami.tag.num.check=The number of condition tags exceeds the upper limit |
| | | yami.tag.shop.check=You are not authorized to operate this product label |
| | | yami.tag.prod.check=Please select the products to be grouped |
| | | yami.tag.prod.delete.check=Please select the product in the group to be deleted |
| | | yami.tag.prod.update.check=Please select the goods in the group to be modified |
| | | yami.live.user.check=Wechat account non compliance |
| | | yami.live.user.check1=Wechat account signal needs real name authentication, which may appear only when the host role is set |
| | | yami.live.user.check2=Add role repeatedly |
| | | yami.live.user.check3=Added role reaches the upper limit |
| | | yami.live.user.check4=Failed to delete the anchor role. There is a live room that has not been started |
| | | yami.live.user.super.admin=Super administrator\uFF0C |
| | | yami.live.user.admin=administrators\uFF0C |
| | | yami.live.user.anchor=anchor\uFF0C |
| | | yami.live.user.operators=Operators\uFF0C |
| | | yami.live.user.check5=The user already has a manager role |
| | | yami.live.user.check6=Host role deletion failed, the host does not exist or there is a live room that is not open |
| | | yami.tag.name.exist=Label name already exists |
| | | yami.customer.no.online=The customer service or user selected to forward is no longer online and cannot be forwarded! |
| | | yami.user.balance.check=The current balance of the user is insufficient and cannot be reduced |
| | | yami.excel.user.info=User Information Form |
| | | yami.excel.user.number=Serial number |
| | | yami.excel.user.userNickname=User nickname |
| | | yami.excel.user.userName=User Name |
| | | yami.excel.user.contactNumber=Contact number |
| | | yami.excel.user.memberLevel=Membership Level |
| | | yami.excel.user.memberType=Membership Type |
| | | yami.excel.user.accScore=User score |
| | | yami.excel.user.status=Status |
| | | yami.excel.user.amountConsum=Spending amount |
| | | yami.excel.user.amountActPaid=Actual amount paid |
| | | yami.excel.user.numberConsum=Number of consumption |
| | | yami.excel.user.aveDiscount=Average Discount |
| | | yami.excel.user.rechargeAmount=Recharge amount |
| | | yami.excel.user.topUpTimes=Recharge times |
| | | yami.excel.user.refundAmount=Refund amount |
| | | yami.excel.user.numberOfRefund=Number of refunds |
| | | yami.excel.user.accPoints=Accumulated score |
| | | yami.excel.user.currBalance=Current Balance |
| | | yami.excel.user.accBalance=Accumulated Balance |
| | | yami.excel.user.regTime=Registration Time |
| | | yami.excel.user.receConsumDate=Latest consumption time |
| | | yami.web.config.check=Please turn on at least one configuration and then turn off the current configuration |
| | | yami.average.retention.rate=Average retention rate |
| | | yami.prod.set.top.check=You can only top items that are already on the shelves |
| | | yami.login.password.check=The login has been restricted for 30 minutes after entering the password incorrectly ten times within half an hour. |
| | | yami.product.sku.invalid=Stock is invalid |
| | | yami.group.name.duplicate=Group name already exists |
| | | yami.invoice.shopId.notNull=Shop id cannot be empty |
| | | yami.invoice.invoiceId.duplicate=This order has already requested an invoice, please do not repeat it! |
| | | yami.invoice.not.user=Unable to view invoice information for non-current users |
| | | yami.file.isNot.exist=Please upload the file |
| | | yami.file.isNot.shop=Unable to view files that are not in our store |
| | | yami.prod.common.invalid=Data has expired, please refresh the page |
| | | yami.station.no.exist=Pickup point information does not exist, please select a new pickup point |
| | | yami.prod.name.not.blank=Product Chinese name cannot be empty |
| | | yami.prod.name.en.not.blank=Product English name cannot be empty |
| | | yami.prod.brief.not.blank=Product Chinese brief cannot be empty |
| | | yami.prod.category.not.blank=Product category cannot be empty |
| | | yami.platform.category.not.blank=Platform category cannot be empty |
| | | yami.prod.shop.type.not.blank=Product type cannot be empty |
| | | yami.prod.shop.category.not.blank=Product shop category cannot be empty |
| | | yami.prod.dvy.type.not.blank=Product delivery method cannot be empty |
| | | yami.prod.transport.not.exist=Product shipping templates do not exist |
| | | yami.prod.pic.limit = The number of uploaded pictures exceeds the limit |
| | | yami.prod.pic.format.error = Uploaded picture format error |
| | | yami.prod.video.format.error = Upload video format error |
| | | yami.prod.video.too.large.error = Uploaded video is too large |
| | | yami.product.not.shelf=This product is not on the shelf, please select another product |
| | | yami.supplier.name.not.blank=Supplier name cannot be empty |
| | | yami.supplier.not.null=Supplier cannot be empty |
| | | yami.supplier.supplierName.exist=Supplier name already exists |
| | | yami.supplier.supplierName.than=The number of words in the name of the supplier cannot exceed 50 |
| | | yami.supplier.contactName.than=Contact name cannot exceed 50 |
| | | yami.supplier.tel.error=Wrong format of unit phone number |
| | | yami.supplier.contactTel.error=Wrong format of contact number |
| | | yami.supplier.mail.error=Mailbox format error |
| | | yami.supplier.qqNumber.error=The qq number is malformed |
| | | yami.supplier.wxNumber.error=WeChat format error |
| | | yami.supplier.prod.not.shop=Cannot view items that are not in our shop |
| | | yami.sku.party.code.exist=Product code already exists |
| | | yami.sku.party.code.not.exist=The product code does not exist or the product has been deleted |
| | | yami.sku.party.code.is.repeated=There are multiple product specifications under this product code, please update the corresponding product specification code and re-import it. |
| | | yami.supplier.category.not.exit=Supplier classification does not exist or has been disabled |
| | | yami.supplier.category.already.exit=Supplier categories already exist |
| | | yami.order.not.null=The required fields for the order cannot be empty\uFF01 |
| | | yami.order.coupon.not.start=Card vouchers are not up for use or have expired |
| | | yami.order.coupon.expired=Card voucher has expired |
| | | yami.order.coupon.exist=Card vouchers do not exist or have been cancelled! |
| | | yami.order.virtual.check=Refund in progress, can't write off! |
| | | yami.order.virtual.check2=Current virtual goods orders do not require write-off |
| | | yami.virtual.prod.check=Virtual products cannot be added to the shopping cart |
| | | yami.order.virtual.refund.check1=Current order can not be refunded, please contact customer service |
| | | yami.order.virtual.refund.check2=virtual goods orders cannot be returned for refund |
| | | yami.order.virtual.refund.check3=The current order has expired and cannot be refunded, please contact customer service |
| | | yami.order.virtual.refund.check4=The current order has been fully checked out and cannot be refunded, please contact customer service |
| | | yami.order.virtual.refund.check5=The number of refunds available for the current order is exceeded |
| | | yami.order.prod.type.check=Product type cannot be modified after product creation |
| | | yami.prod.type.check=Product type changed, please refresh the page and try again |
| | | yami.take.stock.time.not.null=Inventory start time cannot be empty |
| | | yami.take.stock.prod.null=Inventory items cannot be empty |
| | | yami.take.stock.id.not.null=Inventory Id cannot be empty |
| | | yami.take.stock.message.error=Current inventory information does not belong to your store |
| | | yami.take.stock.status.error=The current inventory task has been completed or invalidated, please return to the list page and refresh |
| | | yami.take.stock.import.error=The inventory list already has products imported, so you cannot use the bulk import function. |
| | | yami.take.stock.count.not.null=Inventory quantity cannot be empty |
| | | yami.shop.sku.is.null=Product specifications do not exist |
| | | yami.shop.stock.update.error=Inventory update failure |
| | | yami.shop.total.stock.not.null=The actual inventory of the product cannot be empty |
| | | yami.purchases.order.voided=This order has been voided |
| | | yami.purchases.order.complete=This order has been complete |
| | | yami.purchases.order.party.code=Product code cannot be empty |
| | | yami.purchases.order.stock.num=Purchase number cannot be empty |
| | | yami.purchases.order.error.code=Wrong product code |
| | | yami.supplier.status.error=This provider is disabled, please enable it before operation |
| | | yami.sku.party.code=Product Code |
| | | yami.sku.stockWarning.limit = StockWarning is greater than maxvalue |
| | | yami.is.exist=Already exists |
| | | yami.properties=Sales Property Combination String |
| | | yami.properties.error=Format error |
| | | yami.sku.name=Specification name |
| | | yami.is.duplicate=is repeat |
| | | yami.supplier.not.exist.or.disabled=Supplier does not exist or is disabled |
| | | yami.purchased.order.not.exist=Purchased order do not exist, please refresh and try again! |
| | | yami.purchased.prod.not.exist.or.disabled=Purchased items do not exist or have been deleted, please refresh and try again! |
| | | yami.data.deleted.or.not.exist=Data has been deleted or does not exist |
| | | yami.platform.prod.offline.check=The current product/activity has been removed from the shelves or is under review, and cannot be removed from the shelves |
| | | yami.order.coupon.expire.check=The currently selected coupon has expired, please return to resubmit the order |
| | | yami.order.discount.expire.check=The currently selected full discount activity has expired, please return to resubmit the order |
| | | yami.order.combo.expire.check=The currently selected package activity has expired, please return to resubmit your order |
| | | yami.order.giveaway.expire.check=The currently selected giveaway event has expired, please return to resubmit your order |
| | | yami.order.pay.type.check=The platform does not support the current payment method, please refresh and select after |
| | | yami.platform.delivery.name.repeat=Logistics name cannot be repeated |
| | | yami.prod.parameter.format.error=Wrong format of product parameters |
| | | yami.balance.than.max.balance=Your balance plus recharge balance will be greater than the maximum balance. Recharge operation is not allowed |
| | | yami.user.blance.not.exist = The current recharge option no longer exists, please refresh and try again |
| | | yami.prod.status.change=Product status has changed, please refresh the page |
| | | yami.refund.amount.change.check=Current refund order status cannot change refund amount, please try again later |
| | | yami.refund.amount.change.check2=Refunds for whole orders do not support changing the refund amount at this time |
| | | yami.refund.amount.change.check3=The refund amount cannot be modified for orders using the platform offer |
| | | yami.order.delivery.num.check=Insufficient number of orders shipped, please refresh and try again |
| | | yami.active.is.delete=The activity has been deleted, please refresh the page and try again |
| | | yami.station.no.exists=Current store does not exist or is not in business status, please try again |
| | | yami.exprot.prod.sku.error=If there are products with more than 100 groups of specifications detected, please modify them and re-import them. |
| | | |
| | | yami.combo.end.time.error=Event end time cannot be less than current time |
| | | yami.combo.main.prod.not.empty=Package main product cannot be empty |
| | | yami.combo.matching.prod.count.error=Wrong number of matching products |
| | | yami.combo.prod.delete.after.tips=Has been deleted, please select again |
| | | yami.combo.prod.matching.price.after.tips=The matching price cannot exceed the original price of the product |
| | | yami.combo.not.shop=The current package does not belong to your shop |
| | | yami.combo.already.delete=The current package has been deleted |
| | | yami.combo.update.fail=Package information update failed, please refresh and try again |
| | | yami.combo.matching.required.not.empty=Please set at least one required matching product |
| | | yami.combo.open.error.tips=The end time of the current package is less than the current time, the opening fails, please set the activity time of the package first |
| | | yami.combo.least.num.not.empty=The starting quantity cannot be empty |
| | | yami.combo.not.find.prod=Can't find product information |
| | | yami.combo.info.error=info error |
| | | yami.combo.already.invalid=The current package activity has expired |
| | | yami.combo.product.already.delete.rear.tips=Has been deleted, please select again |
| | | yami.combo.product.already.disable.rear.tips=Has been disabled, please select again |
| | | yami.combo.spec.already=specifications |
| | | yami.combo.delete.fail=Delete failed, please refresh and try again |
| | | yami.giveaway.not.on.shop=The gift information does not belong to your shop |
| | | yami.giveaway.prod.error=There are wrong products, please refresh and select again |
| | | yami.giveaway.virtual.prod.error=It is a virtual product and cannot be set as a gift product |
| | | yami.giveaway.activity.time.error.tips1=Activity time and gifts\u3010 |
| | | yami.giveaway.activity.time.error.tips2=\u3011The time conflicts, one main product cannot set up multiple gift activities at the same time,\u3010 |
| | | yami.giveaway.activity.time.error.tips3=\u3011Activity time for |
| | | yami.giveaway.activity.time.error.tips4=The end time of the current gift is less than the current time, the opening fails, please set the event time of the gift first |
| | | yami.giveaway.activity.time.error.tips5=No multiple giveaways can be set up for one main product |
| | | yami.giveaway.time.to=to |
| | | yami.giveaway.already.invalid=The current gift event has expired |
| | | yami.giveaway.already.delete=The current giveaway has been deleted |
| | | yami.giveaway.update.fail=Failed to update gift information, please refresh and try again |
| | | yami.giveaway.refund.price.error=The total return price of the gift cannot exceed the price of the main product |
| | | yami.prod.combo.expired=Product combo does not exist, or has expired |
| | | yami.main.prod.wrong=The main product information is wrong, please refresh and try again |
| | | yami.select.matching.prod=Please select matching products |
| | | yami.select.required.matching.items=Please select the required matching items |
| | | yami.prod.package.cannot.empty=Product package with product list cannot be empty |
| | | yami.active.prod.cannot.add.cart=Active items cannot be added to the shopping cart |
| | | yami.active.prod.cannot.add.collection=Active items cannot be added to collection |
| | | yami.active.prod.cannot.buy=Active items cannot be purchased separately |
| | | yami.combo.prod.already.exists=There is already a package of this size in your shopping cart, please do not add to it. |
| | | yami.specification.already.exists.shopping.cart=The specification already exists in the shopping cart |
| | | yami.cn.reason.duplicate=Chinese reason is repeated, please re-enter |
| | | yami.en.reason.duplicate=English reason is repeated, please re-enter |
| | | yami.system.reason.not.delete=System built-in in/out reasons cannot be deleted |
| | | yami.sku.price.not.change=participated in the package or giveaway activities, can not change the price, please refresh the page and try again |
| | | yami.combo.prod.not.delete=Products participating in the following activities cannot be removed: Discount packages |
| | | yami.giveaway.prod.not.delete=Items participating in the following events cannot be removed: Giveaways |
| | | yami.sys.web.config.delete=Active configuration cannot be deleted |
| | | yami.imgs.length.then.max=IMGs data error: length greater than 255 |
| | | yami.seckill.invalid=The second kill activity has expired |
| | | yami.not.ordinary.prod= is not an ordinary Product |
| | | yami.lack.permission.pre=You lack the permission of |
| | | yami.lack.permission.suf= module |
| | | yami.refund.amount.check1=Refund amount is wrong, please re-enter |
| | | yami.role.use.cannot.deleted=Role in use cannot be deleted |
| | | yami.prod.platform.category.deleted=This platform category has been deleted, please select a new category |
| | | yami.index.img.reached.limit=The maximum number of rotation pictures on this client has been reached, so you can't add any more |
| | | yami.shopCart.prod.error=Pre-sale, virtual, and event items cannot be added to the cart! |
| | | yami.sku.cannot.empty=SKU list cannot be empty |
| | | yami.signingAuditing.auditInformation.notfound=Could not find this audit information, please refresh the page |
| | | yami.Auditing.applicationInfo.notFound=Application information could not be found, please refresh the page |
| | | yami.signingAuditing.categorySigningInformation.notFound=The category signing information does not exist or is incorrect. Please refresh the page |
| | | yami.invoice.categoryId.notNull=The category ID cannot be empty |
| | | yami.invoice.brandId.notNull=The brand ID cannot be empty |
| | | yami.not.permission.modify.administrator.info=You do not have permission to modify administrator information |
| | | yami.order.devType.notMatch=The imported shipping method is inconsistent with the shipping method for the order |
| | | yami.out.orderNumber=external order number |
| | | yami.pay.status=payment status |
| | | yami.pay.score=payment points |
| | | yami.pay.amount=payment amount |
| | | yami.pay.time=payment time |
| | | yami.order.pay=payed |
| | | yami.order.no.paid=not paid |
| | | yami.pay.info.reportTitle=revenue reconciliation detail report |
| | | yami.refund.info.reportTitle=Refund Reconciliation Detail Report |
| | | yami.account.info.reportTitle=Reconciliation Detail Report |
| | | yami.pay.no=payment number |
| | | yami.refund.no=Refund order number |
| | | yami.refund.status=Refund status |
| | | yami.refund.time=Refund time |
| | | yami.refund.finish=Refunded |
| | | yami.message.leng.exceed.limit=Message content length exceeds limit |
| | | |
| | | yami.order.is.closed=Orders are closed |
| | | yami.deliverySum.exceed.stocks=Outgoing quantity exceeds stock quantity |
| | | yami.shop.pay.info.update.error=Payment information update failed |
| | | yami.prod.import.virtualRemark.notValid=The message format for virtual goods is incorrect |
| | | yami.sensitive.words.reenter=There are sensitive words, please re-enter |
| | | yami.prod.status.error.Please.exit.and.try.again=The status of the product is incorrect Please exit and try again |
| | | yami.finance.form.excel=Please select the transaction time for exporting reports |
| | | yami.shop.wallet.log.excel=Store billing schedule |
| | | yami.Shipping.amount.error=Shipping amount cannot be less than 0 |
| | | yami.balance.out.error=balance must not exceed 9999999999.99 |
| | | yami.score.out.error=score must not exceed 100000000 |
| | | yami.trans.amount.not.null=The shipping cost cannot be empty when the flat rate is applied |
| | | yami.delivery.name.is.same=Duplicate with the system built-in template name, please re-enter |
| | | yami.delivery.error=Please select a shipping region |
| | | yami.delivery.over=Shipping is not supported in the current region |
| | | yami.cannot.used.score.payment=Orders with payment amount greater than 0 cannot be paid with points |
| | | yami.combo.price.excessive=The total amount of the combo is too large, please set it properly |
| | | yami.order.prod.count.limit=The number of products ordered cannot be less than 1 |
| | | yami.product.has.created.seckill=This product has created a seckill activity, please do not submit again |
| | | yami.pcdn.error=The system is busy, please try again later |
| | | yami.pcdn.assets.freeze=The frozen quantity must be between 100 and 9999 |
| | | yami.user.assets.lucky.coin.balance=Insufficient balance of lucky coins |
| | | yami.user.assets.lucky.coin.freeze=Freeze coin is null as param |
| | | yami.user.device.not.exist=The user device does not exist |
| | | yami.pcdn.device.bound=The device has been bound |
| | | yami.pcdn.device.delete=The device has been deleted |
| | | yami.pcdn.device.token=Please set the configuration file for obtaining tokens |
| | | yami.pcdn.device.id.null=The device id is empty |
| | | yami.pcdn.device.userId.null=The user id is empty |
| | | yami.pcdn.device.binding.error=The device is already bound to your account |
| | | |
New file |
| | |
| | | yami.activity.cannot.delete=\u8BE5\u6D3B\u52A8\u72B6\u6001\u4E0B\u4E0D\u80FD\u8FDB\u884C\u5220\u9664 |
| | | yami.activity.prod.cannot.delete=\u6D3B\u52A8\u8FDB\u884C\u4E2D\uFF0C\u4E0D\u80FD\u5220\u9664\u6D3B\u52A8\u5546\u54C1\uFF0C\u60A8\u53EF\u4EE5\u7B49\u5F85\u6D3B\u52A8\u7ED3\u675F\u540E\u6216\u5931\u6548\u8BE5\u62FC\u56E2\u6D3B\u52A8\u540E\u8FDB\u884C\u64CD\u4F5C |
| | | yami.activity.cannot.find=\u672A\u627E\u5230\u6B64\u6D3B\u52A8\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5 |
| | | yami.activity.cannot.find.check=\u8BE5\u6D3B\u52A8\u4E0D\u5B58\u5728\u3001\u672A\u5F00\u59CB\u6216\u8005\u5DF2\u7ED3\u675F |
| | | yami.activity.prod.no.exist=\u6D3B\u52A8\u5546\u54C1\u4E0D\u5B58\u5728\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5 |
| | | yami.activity.prod.status=\u6D3B\u52A8\u4E2D\u5305\u542B\u5DF2\u4E0B\u7EBF\u5546\u54C1 |
| | | yami.activity.prod.update.error=\u66F4\u65B0\u6D3B\u52A8\u5546\u54C1\u5931\u8D25 |
| | | yami.activity.prod.no.auth=\u60A8\u65E0\u6743\u5BF9\u6B64\u6D3B\u52A8\u5546\u54C1\u8FDB\u884C\u64CD\u4F5C |
| | | yami.activity.no.auth=\u60A8\u65E0\u6743\u64CD\u4F5C\u6B64\u6D3B\u52A8 |
| | | yami.activity.add.prod.empty=\u6DFB\u52A0\u62FC\u56E2\u5546\u54C1\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.activity.enable.prod.empty=\u542F\u7528\u5931\u8D25\uFF0C\u8BF7\u81F3\u5C11\u9009\u62E9\u4E00\u4E2A\u6D3B\u52A8\u5546\u54C1 |
| | | yami.activity.disable=\u5931\u6548\u5931\u8D25\uFF0C\u6D3B\u52A8\u4E0D\u5728\u8FDB\u884C\u4E2D\u6216\u9884\u70ED\u72B6\u6001\u65E0\u6CD5\u8FDB\u884C\u5931\u6548\u64CD\u4F5C |
| | | yami.activity.info.check=\u8BF7\u586B\u5199\u5B8C\u6574\u6EE1\u51CF\u4FE1\u606F |
| | | yami.activity.item.check=\u6D3B\u52A8\u9879\u4E0D\u80FD\u4E3A\u7A7A\uFF0C\u6700\u5C11\u8981\u6709\u4E00\u4E2A\u6D3B\u52A8\u9879 |
| | | yami.activity.status.check=\u8BE5\u6D3B\u52A8\u5DF2\u88AB\u5E73\u53F0\u4E0B\u7EBF\uFF0C\u4E0D\u80FD\u518D\u66F4\u6539\u72B6\u6001 |
| | | yami.activity.now.over.end.time=\u5F53\u524D\u65F6\u95F4\u5DF2\u8D85\u8FC7\u6D3B\u52A8\u7ED3\u675F\u65F6\u95F4\uFF0C\u4E0D\u80FD\u542F\u7528\u6D3B\u52A8 |
| | | yami.activity.add.success=\u6DFB\u52A0\u6210\u529F |
| | | yami.activity.update.success=\u4FEE\u6539\u6210\u529F |
| | | yami.submitted.successfully=\u63D0\u4EA4\u6210\u529F |
| | | yami.submitted.examine=\u5DF2\u63D0\u4EA4\u5BA1\u6838 |
| | | yami.no.auth=\u6CA1\u6709\u6743\u9650\u8FDB\u884C\u64CD\u4F5C |
| | | yami.delete.successfully=\u5220\u9664\u6210\u529F |
| | | yami.undo.successfully=\u64A4\u9500\u6210\u529F |
| | | yami.address.added.successfully=\u6DFB\u52A0\u5730\u5740\u6210\u529F |
| | | yami.address.modified.successfully=\u4FEE\u6539\u5730\u5740\u6210\u529F |
| | | yami.deleted.address.successfully=\u5220\u9664\u5730\u5740\u6210\u529F |
| | | yami.address.exists=\u8BE5\u5730\u5740\u5DF2\u5B58\u5728 |
| | | yami.address.add.limit=\u6536\u8D27\u5730\u5740\u5DF2\u8FBE\u5230\u4E0A\u9650\uFF0C\u65E0\u6CD5\u518D\u65B0\u589E\u5730\u5740 |
| | | yami.address.cannot.delete=\u9ED8\u8BA4\u5730\u5740\u65E0\u6CD5\u5220\u9664 |
| | | yami.user.address.delete=\u8BE5\u5730\u5740\u5DF2\u88AB\u5220\u9664 |
| | | yami.user.receive.score=\u9886\u53D6\u79EF\u5206\u6210\u529F |
| | | yami.user.receive.score.check=\u4ECA\u5929\u5DF2\u7ECF\u7B7E\u5230\u8FC7\u4E86\uFF0C\u8BF7\u660E\u5929\u518D\u8BD5\uFF01 |
| | | yami.shopCart.enter.num=\u8F93\u5165\u66F4\u6539\u6570\u91CF |
| | | yami.constant.code.expire=\u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F |
| | | yami.network.exception=\u7F51\u7EDC\u5F02\u5E38 |
| | | yami.network.busy=\u670D\u52A1\u5668\u7E41\u5FD9\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5 |
| | | yami.examine.fail=\u63D0\u4EA4\u5BA1\u6838\u5931\u8D25 |
| | | yami.examine.already=\u8BE5\u7533\u8BF7\u5DF2\u88AB\u5BA1\u6838 |
| | | yami.examine.status.error=\u5BA1\u6838\u72B6\u6001\u6709\u8BEF |
| | | yami.get.goods=\u83B7\u53D6\u5546\u54C1\u5217\u8868\u5931\u8D25 |
| | | yami.request.error=\u7B2C\u4E09\u65B9\u8BF7\u6C42\u5931\u8D25\uFF1A |
| | | yami.request.data.too.long=\u8BF7\u6C42\u6570\u636E\u8FC7\u957F |
| | | yami.address.receiver.length.limit=\u6536\u8D27\u4EBA\u540D\u79F0\u592A\u957F\u4E86 |
| | | yami.group.team.no.exist=\u672A\u627E\u5230\u62FC\u56E2\u56E2\u961F\u4FE1\u606F |
| | | yami.group.order.update.fail=\u66F4\u65B0\u62FC\u56E2\u8BA2\u5355\u4E3A\u5F85\u53D1\u8D27\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5 |
| | | yami.group.team.no.join=\u62FC\u56E2\u56E2\u961F\u4E0D\u5728\u62FC\u56E2\u4E2D\uFF0C\u4E0D\u80FD\u53C2\u4E0E\u62FC\u56E2 |
| | | yami.group.no.progress=\u62FC\u56E2\u6D3B\u52A8\u4E0D\u5728\u8FDB\u884C\u4E2D\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5 |
| | | yami.group.prod.status.error=\u6D3B\u52A8\u5546\u54C1\u4E0D\u5728\u6B63\u5E38\u72B6\u6001 |
| | | yami.group.prod.sold.out=\u6D3B\u52A8\u5546\u54C1\u89C4\u683C\u5DF2\u552E\u7A7A\u6216\u5DF2\u4E0B\u67B6 |
| | | yami.group.prod.shop.limit=\u6D3B\u52A8\u5546\u54C1\u9650\u8D2D\u6570\u91CF\u4E3A |
| | | yami.group.user.shop.num=,\u60A8\u5DF2\u8D2D\u4E70 |
| | | yami.group.user.now.shop=\u73B0\u8D2D |
| | | yami.group.prod.overstep.shop.limit=,\u8D85\u51FA\u6700\u5927\u7684\u8D2D\u4E70\u6570\u91CF |
| | | yami.group.prod.insufficient.stock=\u5E93\u5B58\u91CF\u4E0D\u8DB3\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u8D2D\u4E70\u6570\u91CF |
| | | yami.group.prod.has.group.order=\u60A8\u5DF2\u6709\u62FC\u56E2\u4E2D\u7684\u8BA2\u5355\uFF0C\u8BF7\u8010\u5FC3\u7B49\u5F85\u62FC\u56E2\u6210\u529F |
| | | yami.group.user.join.group=\u60A8\u6B63\u5728\u53C2\u52A0\u6B64\u6D3B\u52A8\uFF0C\u8BF7\u5728\u62FC\u56E2\u6210\u529F\u540E\u91CD\u8BD5 |
| | | yami.group.user.join.check=\u5F53\u524D\u8BA2\u5355\u6B63\u5728\u7B49\u5F85\u6210\u56E2\u72B6\u6001\uFF0C\u9700\u7B49\u5F85\u6210\u56E2\u624D\u80FD\u8FDB\u884C\u4E0B\u4E00\u6B65\u64CD\u4F5C |
| | | yami.group.user.join.group.error=\u60A8\u5DF2\u53C2\u52A0\u8FC7\u6B64\u56E2\uFF0C\u4E0D\u80FD\u91CD\u590D\u53C2\u56E2 |
| | | yami.group.order.no.exist=\u8BE5\u62FC\u56E2\u5355\u4E0D\u5B58\u5728 |
| | | yami.request.too.much=\u8BF7\u6C42\u8FC7\u9891\u7E41\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5 |
| | | yami.day=\u5929 |
| | | yami.constant.num=\u6B21 |
| | | yami.seckill.order.expire=\u8BA2\u5355\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u5546\u54C1\u8FDB\u884C\u79D2\u6740 |
| | | yami.seckill.complete=\u672C\u8F6E\u5546\u54C1\u5DF2\u88AB\u79D2\u6740\u5B8C\u6BD5\uFF0C\u8FD8\u6709\u7528\u6237\u672A\u652F\u4ED8\uFF0C\u8FD8\u6709\u673A\u4F1A\u54DF |
| | | yami.seckill.finish=\u672C\u5546\u54C1\u5DF2\u88AB\u79D2\u6740\u5B8C\u6BD5\uFF0C\u4E0B\u6B21\u8BB0\u5F97\u65E9\u70B9\u6765\u54DF |
| | | yami.seckill.limit.shop=\u672C\u6B21\u79D2\u6740\u5546\u54C1\u9650\u8D2D |
| | | yami.seckill.num=\u4EF6 |
| | | yami.seckill.exception=\u79D2\u6740\u6D3B\u52A8\u672A\u5F00\u59CB\u6216\u5DF2\u7ED3\u675F |
| | | yami.seckill.not.start=\u79D2\u6740\u6D3B\u52A8\u672A\u5F00\u59CB |
| | | yami.seckill.has.ended=\u79D2\u6740\u6D3B\u52A8\u5DF2\u7ED3\u675F |
| | | yami.seckill.prod=\u5546\u54C1\u65E0\u6CD5\u53C2\u4E0E\u79D2\u6740\u6D3B\u52A8 |
| | | yami.seckill.input.maxNum=\u8BF7\u8F93\u5165\u9650\u8D2D\u6570\u91CF |
| | | |
| | | yami.seckill.cannot.delete=\u79D2\u6740\u6D3B\u52A8\u672A\u5173\u95ED\uFF0C\u65E0\u6CD5\u5220\u9664 |
| | | yami.seckill.cannot.invalid=\u79D2\u6740\u6D3B\u52A8\u5DF2\u8FDD\u89C4\u4E0B\u67B6\uFF0C\u65E0\u6CD5\u5173\u95ED |
| | | yami.shop.cart.prod.unrecognized=\u8D2D\u7269\u8F66\u5305\u542B\u65E0\u6CD5\u8BC6\u522B\u7684\u5546\u54C1 |
| | | yami.delivery.address=\u8BF7\u586B\u5199\u6536\u8D27\u5730\u5740 |
| | | yami.product.remove=\u5546\u54C1\u5DF2\u4ECE\u8D2D\u7269\u8F66\u79FB\u9664 |
| | | yami.station.address.check=\u8BF7\u586B\u5199\u81EA\u63D0\u4FE1\u606F |
| | | yami.station.detail.check=\u8BF7\u9009\u62E9\u81EA\u63D0\u70B9\u5E76\u586B\u5199\u5B8C\u6574\u7684\u81EA\u63D0\u4FE1\u606F |
| | | yami.station.no.find=\u672A\u627E\u5230\u8BE5\u81EA\u63D0\u70B9\u4FE1\u606F |
| | | yami.product.not.exist=\u67E5\u627E\u4E0D\u5230\u8BE5\u5546\u54C1\u4FE1\u606F |
| | | yami.product.off.not.enable.disProduct=\u5546\u54C1\u4E0D\u5904\u4E8E\u4E0A\u67B6\u72B6\u6001\uFF0C\u5206\u9500\u5546\u54C1\u4E0D\u80FD\u8FDB\u884C\u4E0A\u67B6\u64CD\u4F5C |
| | | yami.product.already.deleted=\u8BE5\u5546\u54C1\u5DF2\u7ECF\u88AB\u5220\u9664 |
| | | yami.stock.no.number=\u5E93\u5B58\u5FC5\u987B\u4E3A\u7EAF\u6570\u5B57\u6574\u6570,\u4E14\u6700\u591A\u8F93\u51659\u4F4D\u6570\u5B57 |
| | | yami.product.service.delete=\u5546\u54C1\u72B6\u6001\u4E0D\u6B63\u786E\uFF0C\u8BF7\u8054\u7CFB\u5E73\u53F0 |
| | | yami.renovation.not.exist=\u67E5\u627E\u4E0D\u5230\u8BE5\u88C5\u4FEE\u4FE1\u606F |
| | | yami.unable.get.page=\u65E0\u6CD5\u83B7\u53D6\u9875\u9762\u4FE1\u606F |
| | | yami.product.off.shelves=\u5546\u54C1\u5DF2\u4E0B\u7EBF |
| | | yami.product.disable=\u5546\u54C1\u5DF2\u552E\u7A7A\u6216\u5DF2\u4E0B\u67B6 |
| | | yami.product.on.normal=\u5546\u54C1\u4E0D\u5728\u6B63\u5E38\u72B6\u6001\uFF0C\u4FEE\u6539\u5931\u8D25 |
| | | yami.insufficient.inventory=\u5E93\u5B58\u4E0D\u8DB3 |
| | | yami.insufficient.inventory.place.new.order= \u5E93\u5B58\u4E0D\u8DB3, \u8BF7\u91CD\u65B0\u4E0B\u5355 |
| | | yami.product=\u5546\u54C1 |
| | | yami.selelct.items=\u8BF7\u9009\u62E9\u60A8\u9700\u8981\u7684\u5546\u54C1\u52A0\u5165\u8D2D\u7269\u8F66 |
| | | yami.product.download=\u5F00\u59CB\u4E0B\u8F7D\u6A21\u677F |
| | | yami.product.dvy.type=\u8BF7\u9009\u62E9\u914D\u9001\u65B9\u5F0F |
| | | yami.product.dvy.fee=\u8FD0\u8D39\u4E0D\u80FD\u5C0F\u4E8E\u96F6 |
| | | yami.product.group.check=\u7EC4\u5408\u5355\u54C1\u5FC5\u987B\u5173\u8054\u4E00\u4E2A\u5355\u54C1 |
| | | yami.product.join.group=\u5546\u54C1\u6B63\u5728\u53C2\u4E0E\u62FC\u56E2\u6D3B\u52A8\uFF0C\u65E0\u6CD5\u4FEE\u6539\u89C4\u683C |
| | | yami.product.join.seckill=\u5546\u54C1\u6B63\u5728\u53C2\u4E0E\u79D2\u6740\u6D3B\u52A8\uFF0C\u65E0\u6CD5\u4FEE\u6539\u89C4\u683C |
| | | yami.product.signing.category.invalid=\u8BE5\u5546\u54C1\u7684\u7B7E\u7EA6\u5206\u7C7B\u5DF2\u5931\u6548\uFF0C\u65E0\u6CD5\u4FEE\u6539\u5546\u54C1\u72B6\u6001 |
| | | yami.product.category.not.under=\u5F53\u524D\u5E73\u53F0\u5206\u7C7B\u5DF2\u4E0D\u53EF\u7528\uFF0C\u8BF7\u5237\u65B0\u5206\u7C7B\u5217\u8868\u91CD\u65B0\u9009\u62E9 |
| | | yami.product.category.not.exit=\u60A8\u5DF2\u53D6\u6D88\u4E0E\u8BE5\u5546\u54C1\u7C7B\u578B\u7684\u7B7E\u7EA6\uFF0C\u8BF7\u91CD\u65B0\u7B7E\u7EA6\u8BE5\u5546\u54C1\u7C7B\u578B\u65B9\u53EF\u4E0A\u67B6 |
| | | yami.product.category.is.offline=\u8BE5\u5E73\u53F0\u5206\u7C7B\u5DF2\u88AB\u4E0B\u7EBF\uFF0C\u65E0\u6CD5\u4E0A\u67B6\u8BE5\u5546\u54C1 |
| | | yami.product.shop.category.not.under=\u5F53\u524D\u5E97\u94FA\u5206\u7C7B\u5DF2\u4E0D\u53EF\u7528\uFF0C\u8BF7\u5237\u65B0\u5206\u7C7B\u5217\u8868\u91CD\u65B0\u9009\u62E9 |
| | | yami.product.brand.not.under=\u5F53\u524D\u9009\u62E9\u7684\u54C1\u724C\u5DF2\u7ECF\u4E0D\u80FD\u4F7F\u7528\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9 |
| | | yami.product.brand.not.delete=\u6709\u90E8\u5206\u5546\u54C1\u5728\u4F7F\u7528\u8BE5\u54C1\u724C\uFF0C\u4E0D\u80FD\u8FDB\u884C\u5220\u9664\u64CD\u4F5C |
| | | yami.product.no.exist=\u5546\u54C1\u4FE1\u606F\u4E0D\u5B58\u5728 |
| | | yami.product.no.auth=\u6CA1\u6709\u6743\u9650\u83B7\u53D6\u8BE5\u5546\u54C1\u89C4\u683C\u4FE1\u606F |
| | | yami.product.no.auth.update=\u6CA1\u6709\u6743\u9650\u4FEE\u6539\u6B64\u5546\u54C1 |
| | | yami.product.category.offline=\u5E73\u53F0\u5206\u7C7B\u5904\u4E8E\u4E0B\u7EBF\u4E2D\uFF0C\u5546\u54C1\u4E0D\u80FD\u4E0A\u67B6\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u540E\u518D\u8FDB\u884C\u64CD\u4F5C |
| | | yami.product.shop.category.offline=\u672C\u5E97\u5206\u7C7B\u5904\u4E8E\u4E0B\u7EBF\u4E2D\uFF0C\u5546\u54C1\u4E0D\u80FD\u4E0A\u67B6 |
| | | yami.product.shop.offline=\u5E97\u94FA\u5904\u4E8E\u8FDD\u89C4\u4E0B\u7EBF\u4E2D\uFF0C\u4E0D\u80FD\u8FDB\u884C\u6B64\u64CD\u4F5C\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u540E\u91CD\u8BD5 |
| | | yami.product.shop.AUDIT=\u5E97\u94FA\u5BA1\u6838\u4E2D\uFF0C\u4E0D\u80FD\u8FDB\u884C\u6B64\u64CD\u4F5C\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u540E\u91CD\u8BD5 |
| | | yami.product.enable.sku=\u81F3\u5C11\u8981\u542F\u7528\u4E00\u79CD\u5546\u54C1\u89C4\u683C |
| | | yami.same.specifications=\u5DF2\u6709\u76F8\u540C\u540D\u79F0\u89C4\u683C |
| | | yami.shop.name.have.already=\u5DF2\u6709\u76F8\u540C\u5E97\u94FA\u540D\u79F0 |
| | | yami.shop.auditing=\u5E97\u94FA\u5BA1\u6838\u4E2D\uFF0C\u8BF7\u4E0D\u8981\u91CD\u590D\u63D0\u4EA4 |
| | | yami.product.sold.out=\u5546\u54C1\u5DF2\u552E\u7A7A\u6216\u5DF2\u4E0B\u67B6 |
| | | yami.order.expired=\u8BA2\u5355\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u4E0B\u5355 |
| | | yami.add.live.prod.num=\u6DFB\u52A0\u5FAE\u4FE1\u76F4\u64AD\u95F4\u5546\u54C1\u5931\u8D25 |
| | | yami.live.room.wechat.not.exist = \u5FAE\u4FE1\u76F4\u64AD\u63A7\u5236\u53F0\u4E0D\u5B58\u5728\u8BE5\u623F\u95F4 |
| | | yami.live.prod.wechat.not.exist = \u5FAE\u4FE1\u76F4\u64AD\u63A7\u5236\u53F0\u4E0D\u5B58\u5728\u8BE5\u5546\u54C1 |
| | | yami.category.one.check=\u4E00\u7EA7\u5206\u7C7B\u4E0D\u80FD\u6539\u4E3A\u4E8C\u7EA7\u5206\u7C7B |
| | | yami.category.two.check=\u4E8C\u7EA7\u5206\u7C7B\u4E0D\u80FD\u6539\u4E3A\u4E00\u7EA7\u5206\u7C7B |
| | | yami.category.superior.check=\u5206\u7C7B\u7684\u4E0A\u7EA7\u4E0D\u80FD\u662F\u81EA\u5DF1\u672C\u8EAB |
| | | yami.category.name.exist=\u7C7B\u76EE\u540D\u79F0\u5DF2\u5B58\u5728\uFF01 |
| | | yami.category.status.check=\u4FEE\u6539\u5931\u8D25\uFF0C\u4E0A\u7EA7\u5206\u7C7B\u4E0D\u5B58\u5728\u6216\u8005\u4E0D\u4E3A\u6B63\u5E38\u72B6\u6001 |
| | | yami.category.delete.check=\u8BE5\u5206\u7C7B\u4E0B\u8FD8\u6709\u5546\u54C1\uFF0C\u8BF7\u5148\u5220\u9664\u8BE5\u5206\u7C7B\u4E0B\u7684\u5546\u54C1 |
| | | yami.category.delete.child=\u8BF7\u5220\u9664\u5B50\u5206\u7C7B\uFF0C\u518D\u5220\u9664\u8BE5\u5206\u7C7B |
| | | yami.distribution.has.distributionUser=\u8BE5\u7528\u6237\u5DF2\u5904\u4E8E\u4F7F\u7528\u4E2D\uFF0C\u8BF7\u52FF\u91CD\u590D\u4FEE\u6539 |
| | | yami.score.select.num=\u8BF7\u9009\u62E9\u5546\u54C1 |
| | | yami.score.select.num.shop=\u8BF7\u9009\u62E9\u60A8\u9700\u8981\u7684\u5546\u54C1\u8FDB\u884C\u8D2D\u4E70 |
| | | yami.user.score.enough=\u7528\u6237\u79EF\u5206\u4E0D\u8DB3 |
| | | yami.user.score.input.check=\u8BF7\u8F93\u5165\u6B63\u786E\u7684\u79EF\u5206\u6570\u91CF |
| | | yami.user.score.no.enough=\u79EF\u5206\u4E0D\u8DB3\u65E0\u6CD5\u63D0\u4EA4\u8BA2\u5355 |
| | | yami.user.score.prod=\u4E0D\u662F\u79EF\u5206\u5546\u54C1\u6216\u8005\u79EF\u5206\u4EF7\u683C\u5F02\u5E38 |
| | | yami.user.no.get.phone=\u65E0\u6CD5\u83B7\u53D6\u7528\u6237\u624B\u673A\u53F7\u4FE1\u606F |
| | | yami.user.account.error=\u7528\u6237\u540D\u6216\u5BC6\u7801\u4E0D\u6B63\u786E |
| | | yami.user.account.exist=\u7528\u6237\u540D\u5DF2\u5B58\u5728 |
| | | yami.user.account.no.exist=\u7528\u6237\u4E0D\u5B58\u5728 |
| | | yami.user.disabled = \u7528\u6237\u5DF2\u7981\u7528\uFF0C\u8BF7\u8054\u7CFB\u5BA2\u670D |
| | | yami.user.err.phone=\u8BF7\u8F93\u5165\u6B63\u786E\u7684\u624B\u673A\u53F7 |
| | | yami.user.account.lock=\u8D26\u53F7\u5DF2\u88AB\u9501\u5B9A,\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458 |
| | | yami.user.account.lock.pre=\u8D26\u53F7\u5DF2\u88AB\u9501\u5B9A\uFF0C\u539F\u56E0\u662F\uFF1A |
| | | yami.user.account.lock.after=\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458 |
| | | yami.user.phone.exist=\u8BE5\u624B\u673A\u53F7\u5DF2\u6CE8\u518C\uFF0C\u65E0\u6CD5\u91CD\u65B0\u6CE8\u518C |
| | | yami.user.name.check=\u7528\u6237\u540D\u5E94\u75314-16\u4F4D\u6570\u5B57\u5B57\u6BCD\u4E0B\u5212\u7EBF\u7EC4\u6210 |
| | | yami.user.password.no.exist=\u65B0\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.user.password.check=\u65B0\u5BC6\u7801\u4E0D\u80FD\u4E0E\u539F\u5BC6\u7801\u76F8\u540C! |
| | | yami.user.code.error=\u9A8C\u8BC1\u7801\u6709\u8BEF\u6216\u5DF2\u8FC7\u671F |
| | | yami.user.code.empty=\u9A8C\u8BC1\u7801\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.user.code.check.too.much=\u9A8C\u8BC1\u7801\u6821\u9A8C\u8FC7\u9891\u7E41\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5 |
| | | yami.verification.limit=\u4ECA\u65E5\u53D1\u9001\u77ED\u4FE1\u9A8C\u8BC1\u7801\u6B21\u6570\u5DF2\u8FBE\u5230\u4E0A\u9650 |
| | | yami.verification.time.check=\u4E00\u5206\u949F\u5185\u53EA\u80FD\u53D1\u9001\u4E00\u6B21\u9A8C\u8BC1\u7801 |
| | | yami.verification.expire=\u9A8C\u8BC1\u7801\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u53D1\u9001\u9A8C\u8BC1\u7801\u6821\u9A8C |
| | | yami.sending.message.failed=\u53D1\u9001\u77ED\u4FE1\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5 |
| | | yami.user.login.error=\u767B\u9646\u4FE1\u606F\u5F02\u5E38 |
| | | yami.user.login.type=\u65E0\u6CD5\u83B7\u53D6\u767B\u9646\u65B9\u5F0F |
| | | yami.user.unable.login.type=\u672A\u5B9E\u73B0\u8BE5\u767B\u9646\u65B9\u6CD5 |
| | | yami.user.no.exist=\u65E0\u6CD5\u83B7\u53D6\u7528\u6237\u4FE1\u606F |
| | | yami.select.source=\u8BF7\u9009\u62E9\u7D20\u6750\u7C7B\u578B |
| | | yami.user.level.no.exist=\u4F1A\u5458\u7B49\u7EA7\u4E0D\u5B58\u5728\u6216\u5F53\u524D\u7B49\u7EA7\u4E0D\u4E3A\u4ED8\u8D39\u4F1A\u5458\u7B49\u7EA7 |
| | | yami.user.pay.level.check=\u7528\u6237\u65E0\u6CD5\u5728\u4F1A\u5458\u671F\u95F4\u8D2D\u4E70\u4F4E\u7B49\u7EA7\u4F1A\u5458 |
| | | yami.user.growh.no.enough=\u7528\u6237\u6210\u957F\u503C\u4E0D\u8DB3\uFF0C\u65E0\u6CD5\u8D2D\u4E70 |
| | | yami.user.request.error=\u7528\u6237\u76F8\u5173\u7684\u8BF7\u6C42\uFF0C\u5E94\u8BE5\u4EE5/p\u5F00\u5934\uFF01\uFF01\uFF01 |
| | | yami.user.addr.update.error=\u65E0\u6CD5\u4FEE\u6539\u7528\u6237\u9ED8\u8BA4\u5730\u5740\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5 |
| | | yami.user.level.delete.error=\u6B64\u7B49\u7EA7\u4E0D\u80FD\u5220\u9664\uFF0C\u5FC5\u987B\u8981\u4FDD\u7559\u6700\u5C11\u4E00\u4E2A\u7B49\u7EA7 |
| | | yami.user.level.update.repeatLevelName.error=\u76F8\u540C\u4F1A\u5458\u7C7B\u578B\u7684\u7B49\u7EA7\u540D\u79F0\u4E0D\u80FD\u91CD\u590D |
| | | yami.shop.user.account.lock=\u8D26\u53F7\u5DF2\u88AB\u9501\u5B9A,\u8BF7\u8054\u7CFB\u5E97\u94FA\u7BA1\u7406\u5458 |
| | | yami.shop.sys.super.user.no.modify=\u5E97\u94FA\u8D85\u7EA7\u7BA1\u7406\u5458\uFF0C\u4E0D\u80FD\u5728\u6B64\u5904\u66F4\u6539 |
| | | yami.shop.account.have.only.one=\u4E00\u4E2A\u5E97\u94FA\u9700\u8981\u4EC5\u4E00\u4E2A\u8D85\u7EA7\u7BA1\u7406\u5458\uFF0C\u8BF7\u5904\u7406\u5E97\u94FA\u8D26\u53F7\u6570\u636E |
| | | yami.shop.data.is.removed=\u6B64\u6570\u636E\u5DF2\u88AB\u5220\u9664 |
| | | yami.shop.card.is.exist=\u8BE5\u94F6\u884C\u5361\u53F7\u5DF2\u5B58\u5728 |
| | | yami.discount.MaxReduceAmount.limit=\u8BF7\u8F93\u5165\u4E00\u4E2A\u5C0F\u4E8E10\u768413\u6B21\u65B9\u7684\u6570\u5B57 |
| | | yami.distribution.close=\u63A8\u5E7F\u8BA1\u5212\u5DF2\u5173\u95ED |
| | | yami.distribution.set.exception=\u5206\u9500\u8BBE\u7F6E\u5F02\u5E38\ |
| | | yami.distribution.userWallet.banlance=\u60A8\u7684\u5206\u9500\u8D26\u6237\u4F59\u989D\u5927\u4E8E0 |
| | | yami.distribution.info.cardno=\u7533\u8BF7\u586B\u5199\u4FE1\u606F\u4E0D\u5168,\u9700\u8981\u8EAB\u4EFD\u8BC1\u53F7 |
| | | yami.distribution.info.pic=\u7533\u8BF7\u586B\u5199\u4FE1\u606F\u4E0D\u5168,\u9700\u8981\u8EAB\u4EFD\u8BC1\u7167\u7247 |
| | | yami.distribution.info.name=\u7533\u8BF7\u586B\u5199\u4FE1\u606F\u4E0D\u5168,\u9700\u8981\u771F\u5B9E\u59D3\u540D |
| | | yami.distribution.submit.examine=\u4F60\u5DF2\u7ECF\u63D0\u4EA4\u8FC7\u5BA1\u6838\u4E86,\u8BF7\u8010\u5FC3\u7B49\u5F85 |
| | | yami.distribution.ban.examine=\u8BE5\u8D26\u6237\u5DF2\u88AB\u6C38\u4E45\u5C01\u7981 |
| | | yami.distribution.clear.examine=\u5DF2\u6682\u65F6\u5C01\u7981\u4E0D\u53EF\u7533\u8BF7,\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458 |
| | | yami.distribution.success.examine=\u4F60\u7684\u5BA1\u6838\u5DF2\u7ECF\u901A\u8FC7,\u65E0\u9700\u518D\u6B21\u5BA1\u6838 |
| | | yami.distribution.get.examine=\u65E0\u6CD5\u83B7\u53D6\u9080\u8BF7\u4EBA\u4FE1\u606F |
| | | yami.distribution.shop.error=\u9080\u8BF7\u4EBA\u5E97\u94FA\u4FE1\u606F\u6709\u8BEF |
| | | yami.distribution.user.error=\u81EA\u5DF1\u65E0\u6CD5\u9080\u8BF7\u81EA\u5DF1 |
| | | yami.distribution.user.Unqualified=\u4E0D\u7B26\u5408\u7533\u8BF7\u6761\u4EF6\uFF0C\u8BF7\u8054\u7CFB\u5BA2\u670D\u8FDB\u884C\u7533\u8BF7 |
| | | yami.distribution.fee.error=\u6D88\u8D39\u91D1\u989D\u4E0D\u7B26\u5408\u8981\u6C42 |
| | | yami.distribution.fee.num=\u6D88\u8D39\u7B14\u6570\u4E0D\u7B26\u5408\u8981\u6C42 |
| | | yami.distribution.user.no.shop=\u60A8\u8FD8\u4E0D\u662F\u672C\u5E97\u7684\u5206\u9500\u5458 |
| | | yami.distribution.user.no.distributor=\u60A8\u8FD8\u4E0D\u662F\u5206\u9500\u5458 |
| | | yami.distribution.user.no.distributor1=\u60A8\u7684\u5206\u9500\u8EAB\u4EFD\u5F02\u5E38\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458 |
| | | yami.distribution.no.distributor=\u4F60\u8FD8\u4E0D\u662F\u5206\u9500\u5458\uFF0C\u65E0\u6CD5\u8FDB\u884C\u5347\u7EA7\u64CD\u4F5C |
| | | yami.distribution.level.limit=\u5DF2\u8FBE\u5230\u7B49\u7EA7\u4E0A\u9650 |
| | | yami.distribution.level.condition=\u60A8\u4E0D\u7B26\u5408\u5347\u7EA7\u6761\u4EF6 |
| | | yami.distribution.cash.param1=\u63D0\u73B0\u91D1\u989D\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.distribution.cash.param2=\u6700\u5C0F\u63D0\u73B0\u91D1\u989D\u4E3A1\u5143 |
| | | yami.distribution.cash.num=\u63D0\u73B0\u6B21\u6570\u4E3A |
| | | yami.distribution.cash.month=\u6BCF\u6708 |
| | | yami.distribution.set.error=\u672A\u627E\u5230\u8BE5\u5E97\u94FA\u5206\u9500\u57FA\u7840\u8BBE\u7F6E\u4FE1\u606F |
| | | yami.distribution.prod.exist.error=\u672A\u627E\u5230\u8BE5\u5206\u9500\u5546\u54C1\u4FE1\u606F |
| | | yami.distribution.prod.award=\u56FA\u5B9A\u5956\u52B1\u6BD4\u4F8B\u8BBE\u7F6E\u4E0D\u80FD\u8D85\u8FC7100% |
| | | yami.distribution.prod.level=\u7B49\u7EA7\u5956\u52B1\u6BD4\u4F8B\u8BBE\u7F6E\u4E0D\u80FD\u8D85\u8FC7100% |
| | | yami.distribution.prod.award.check=\u56FA\u5B9A\u5956\u52B1\u8BBE\u7F6E\u4E0D\u80FD\u8D85\u8FC7\u5546\u54C1\u7684\u6700\u9AD8\u4EF7 |
| | | yami.distribution.prod.level.check=\u7B49\u7EA7\u5956\u52B1\u8BBE\u7F6E\u4E0D\u80FD\u8D85\u8FC7\u5546\u54C1\u7684\u6700\u9AD8\u4EF7 |
| | | yami.distribution.prod.parent.award=\u9080\u8BF7\u4EBA\u56FA\u5B9A\u5956\u52B1\u6BD4\u4F8B\u8BBE\u7F6E\u4E0D\u80FD\u8D85\u8FC7100% |
| | | yami.distribution.prod.parent.level=\u9080\u8BF7\u4EBA\u7B49\u7EA7\u5956\u52B1\u6BD4\u4F8B\u8BBE\u7F6E\u4E0D\u80FD\u8D85\u8FC7100% |
| | | yami.distribution.prod.parentAward.check=\u9080\u8BF7\u4EBA\u56FA\u5B9A\u5956\u52B1\u4E0D\u80FD\u5927\u4E8E\u6216\u7B49\u4E8E\u5546\u54C1\u7684\u6700\u9AD8\u4EF7 |
| | | yami.distribution.prod.parentLevel.check=\u9080\u8BF7\u4EBA\u7B49\u7EA7\u5956\u52B1\u4E0D\u80FD\u5927\u4E8E\u6216\u7B49\u4E8E\u5546\u54C1\u7684\u6700\u9AD8\u4EF7 |
| | | yami.distribution.prod.price.check=\u5956\u52B1\u8BBE\u7F6E\u4E0D\u80FD\u5927\u4E8E\u7B49\u4E8E\u5546\u54C1\u6700\u9AD8\u4EF7\u6216\u8005\u6BD4\u4F8B100% |
| | | yami.distribution.prod.exist=\u5206\u9500\u5546\u54C1\u5DF2\u7ECF\u5B58\u5728 |
| | | yami.distribution.exist.error=\u672A\u627E\u5230\u5206\u9500\u5458\u4FE1\u606F |
| | | yami.distribution.enable.error=\u5546\u6237\u672A\u5F00\u542F\u8BE5\u7ED1\u5B9A\u7528\u6237\u65B9\u5F0F |
| | | yami.distribution.extension.error=\u60A8\u5DF2\u6210\u4E3A\u8BE5\u5E97\u94FA\u7684\u63A8\u5E7F\u5458\uFF0C\u65E0\u6CD5\u88AB\u63A8\u5E7F |
| | | yami.distribution.extension.time=\u60A8\u8FD8\u5728\u63A8\u5E7F\u671F\u5185\uFF0C\u65E0\u6CD5\u88AB\u65B0\u63A8\u5E7F\u5458\u63A8\u5E7F |
| | | yami.distribution.user.protection.period=\u7528\u6237\u5728\u4FDD\u62A4\u671F\u5185\uFF0C\u7ED1\u5B9A\u5931\u8D25 |
| | | yami.distribution.status.error=\u63A8\u5E7F\u5458\u72B6\u6001\u5F02\u5E38 |
| | | yami.distribution.get.fail=\u83B7\u53D6\u63A8\u5E7F\u5458\u4FE1\u606F\u5931\u8D25 |
| | | yami.distribution.batch.update.income=\u6279\u91CF\u66F4\u65B0\u5206\u9500\u6536\u5165\u72B6\u6001\u5931\u8D25 |
| | | yami.distribution.fee.than.error=\u63D0\u73B0\u91D1\u989D\u5927\u4E8E\u6700\u5927\u63D0\u73B0\u91D1\u989D |
| | | yami.distribution.fee.less.error=\u63D0\u73B0\u91D1\u989D\u5C0F\u4E8E\u6700\u5C0F\u63D0\u73B0\u91D1\u989D |
| | | yami.distribution.user.withdrawals=\u60A8\u672A\u7ED1\u5B9A\u5FAE\u4FE1\uFF0C\u8BF7\u5148\u5728\u5FAE\u4FE1\u5C0F\u7A0B\u5E8F\u6388\u6743\u767B\u5F55\u540E\u518D\u63D0\u73B0 |
| | | yami.distribution.balance.not.enough=\u63D0\u73B0\u5931\u8D25,\u4F59\u989D\u4E0D\u8DB3 |
| | | yami.sys.menu.exist=\u83DC\u5355URL\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.sys.file.no.exist=\u672A\u914D\u7F6E\u6587\u4EF6\u57DF\u540D\uFF0C\u65E0\u6CD5\u4E0A\u4F20\u6210\u529F\u56FE\u7247 |
| | | yami.sys.sms.no.exist=\u65E0\u6CD5\u83B7\u53D6\u77ED\u4FE1\u914D\u7F6E\uFF0C\u65E0\u6CD5\u53D1\u9001\u77ED\u4FE1 |
| | | yami.sys.wxMa.no.exist=\u8BF7\u5728\u540E\u53F0\u9875\u9762\u8BBE\u7F6E\u5FAE\u4FE1\u5C0F\u7A0B\u5E8F\u4FE1\u606F\u540E\uFF0C\u518D\u8FDB\u884C\u64CD\u4F5C |
| | | yami.sys.wxMp.no.exist=\u8BF7\u5728\u540E\u53F0\u9875\u9762\u8BBE\u7F6E\u5FAE\u4FE1\u516C\u4F17\u53F7\u4FE1\u606F\u540E\uFF0C\u518D\u8FDB\u884C\u64CD\u4F5C |
| | | yami.sys.wxApp.no.exist=\u8BF7\u5728\u540E\u53F0\u9875\u9762\u8BBE\u7F6E\u5FAE\u4FE1\u5F00\u653E\u5E73\u7533\u8BF7\u5E94\u7528\u76F8\u5173\u4FE1\u606F\u540E\uFF0C\u518D\u8FDB\u884C\u64CD\u4F5C |
| | | yami.sys.wxPay.no.exist=\u8BF7\u5728\u540E\u53F0\u9875\u9762\u8BBE\u7F6E\u5FAE\u4FE1\u652F\u4ED8\u4FE1\u606F\u540E\uFF0C\u518D\u8FDB\u884C\u64CD\u4F5C |
| | | yami.sys.wxDomain.no.exist=\u8BF7\u5728\u540E\u53F0\u9875\u9762\u8BBE\u7F6E\u56DE\u8C03\u57DF\u540D\u540E\uFF0C\u518D\u8FDB\u884C\u64CD\u4F5C |
| | | yami.sys.menu.child.delete=\u8BF7\u5148\u5220\u9664\u5B50\u83DC\u5355\u6216\u6309\u94AE |
| | | yami.sys.menu.delete.error=\u7CFB\u7EDF\u83DC\u5355\uFF0C\u4E0D\u80FD\u5220\u9664 |
| | | yami.sys.menu.user.error=\u81EA\u5DF1\u4E0D\u80FD\u662F\u81EA\u5DF1\u7684\u4E0A\u7EA7 |
| | | yami.sys.menu.superior.list=\u4E0A\u7EA7\u83DC\u5355\u53EA\u80FD\u4E3A\u76EE\u5F55\u7C7B\u578B |
| | | yami.sys.menu.superior.menu=\u4E0A\u7EA7\u83DC\u5355\u53EA\u80FD\u4E3A\u83DC\u5355\u7C7B\u578B |
| | | yami.sys.role.identical.name=\u7CFB\u7EDF\u5DF2\u5B58\u5728\u76F8\u540C\u89D2\u8272\u540D\u79F0 |
| | | yami.document.no.content=\u6587\u4EF6\u65E0\u5185\u5BB9 |
| | | yami.file.error=\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF |
| | | yami.modified.settlement.information=\u7ED3\u7B97\u4FE1\u606F\u5DF2\u66F4\u6539 |
| | | yami.platform.num.check=\u5E73\u53F0\u4ECA\u65E5 |
| | | yami.num.limit=\u53EF\u7528\u6B21\u6570\u5DF2\u8FBE\u4E0A\u9650! |
| | | yami.sys.delete.error=\u5F53\u524D\u7528\u6237\u4E0D\u80FD\u5220\u9664 |
| | | yami.sys.admin.error=\u7CFB\u7EDF\u7BA1\u7406\u5458\u4E0D\u80FD\u5220\u9664 |
| | | yami.sys.select.user=\u8BF7\u9009\u62E9\u9700\u8981\u5220\u9664\u7684\u7528\u6237 |
| | | yami.sys.user.already=\u8BE5\u7528\u6237\u540D\u5DF2\u5B58\u5728 |
| | | yami.sys.sms.package=\u8D2D\u4E70\u7684\u77ED\u4FE1\u5957\u9910\u4E0D\u5B58\u5728\uFF0C\u8BF7\u5237\u65B0\u540E\u91CD\u8BD5 |
| | | yami.sys.sms.package.limit=\u5957\u9910\u5305\u6570\u91CF\u5DF2\u8FBE\u4E0A\u9650\u5341\u4E2A\uFF0C\u8BF7\u8FDB\u884C\u5220\u9664\u540E\u518D\u6DFB\u52A0\uFF01 |
| | | yami.sys.illegalArgument=\u8BF7\u6C42\u53C2\u6570\u975E\u6CD5\uFF0C\u8BF7\u6838\u5B9E! |
| | | yami.cannot.get.app.info=\u65E0\u6CD5\u83B7\u53D6app\u4FE1\u606F |
| | | yami.same.key=\u7CFB\u7EDF\u5DF2\u5B58\u5728\u76F8\u540C\u914D\u7F6E\u7684key |
| | | yami.sys.paypal.no.exist=\u8BF7\u5728\u540E\u53F0\u9875\u9762\u8BBE\u7F6Epaypal\u76F8\u5173\u4FE1\u606F\u540E\uFF0C\u518D\u8FDB\u884C\u64CD\u4F5C |
| | | yami.address.deleted=\u8BA2\u5355\u9879\u4E0D\u5B58\u5728 |
| | | yami.item.has.commented=\u8BE5\u8BA2\u5355\u9879\u5DF2\u8BC4\u8BBA\uFF0C\u8BF7\u52FF\u91CD\u590D\u8BC4\u8BBA |
| | | yami.item.com.repeated==\u8BA2\u5355\u8BC4\u8BBA\u5DF2\u63D0\u4EA4 |
| | | yami.confirm.receipt=\u8BF7\u786E\u8BA4\u6536\u8D27\u540E\u518D\u8FDB\u884C\u8BC4\u8BBA |
| | | yami.comment.is.delete=\u8BC4\u4EF7\u4E0D\u5B58\u5728\u6216\u5DF2\u88AB\u5220\u9664\uFF0C\u8BF7\u8FD4\u56DE\u540E\u5237\u65B0\u91CD\u8BD5 |
| | | yami.cannot.reapply=\u60A8\u5DF2\u7ECF\u7533\u8BF7\u5F00\u542F\u5E97\u94FA,\u4E0D\u80FD\u91CD\u65B0\u7533\u8BF7 |
| | | yami.shop.num.check=\u5E97\u94FA\u4ECA\u65E5 |
| | | yami.store.name.exist=\u5E97\u94FA\u540D\u79F0\u5DF2\u5B58\u5728 |
| | | yami.store.not.exist=\u672A\u627E\u5230\u5E97\u94FA\u4FE1\u606F |
| | | yami.shop.not.category=\u5F53\u524D\u5E97\u94FA\u6CA1\u6709\u7B7E\u7EA6\u7684\u5E73\u53F0\u5206\u7C7B\uFF0C\u8BF7\u5148\u7B7E\u7EA6\u5206\u7C7B |
| | | yami.station.account.exist=\u6B64\u8D26\u53F7\u5DF2\u5B58\u5728\uFF0C\u8BF7\u8F93\u5165\u65B0\u7684\u8D26\u53F7 |
| | | yami.store.account.exist=\u8BE5\u8D26\u53F7\u5DF2\u5B58\u5728\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165 |
| | | yami.store.apply.no.exist=\u672A\u627E\u5230\u7533\u8BF7\u4FE1\u606F |
| | | yami.store.offline.check=\u5E97\u94FA\u4E0D\u5904\u4E8E\u8425\u4E1A\u6216\u505C\u4E1A\u72B6\u6001,\u4E0D\u80FD\u8FDB\u884C\u4E0B\u7EBF |
| | | yami.shop.company.repeat.application=\u4E0D\u80FD\u540C\u65F6\u63D0\u4EA4\u591A\u6B21\u53D8\u66F4\u7533\u8BF7\uFF0C\u8BF7\u8010\u5FC3\u7B49\u5019\u5E73\u53F0\u5BA1\u6838\uFF0C\u6216\u8005\u628A\u5DF2\u6709\u7533\u8BF7\u64A4\u9500\u540E\u91CD\u65B0\u7533\u8BF7 |
| | | yami.cannot.update.wallet=\u66F4\u65B0\u5E97\u94FA\u94B1\u5305\u4FE1\u606F\u5931\u8D25 |
| | | yami.cannot.distribution.update.wallet=\u66F4\u65B0\u63A8\u5E7F\u5458\u94B1\u5305\u4FE1\u606F\u5931\u8D25 |
| | | yami.store.brand.name.error=\u8BE5\u54C1\u724C\u540D\u79F0\u5DF2\u5B58\u5728 |
| | | yami.my.store.no.cash=\u81EA\u8425\u5E97\u65E0\u6CD5\u63D0\u73B0 |
| | | yami.shop.cash.too.less=\u63D0\u73B0\u91D1\u989D\u4E0D\u80FD\u5C11\u4E8E1.00\u5143 |
| | | yami.shop.cannot.delete.card=\u4E0D\u80FD\u5220\u9664\u9ED8\u8BA4\u94F6\u884C\u5361 |
| | | yami.shop.max.card.num=\u94F6\u884C\u5361\u5DF2\u8FBE\u5230\u6700\u5927\u6570\u91CF\uFF0C\u4E0D\u80FD\u518D\u65B0\u589E |
| | | yami.shop.least.one.card=\u81F3\u5C11\u4FDD\u7559\u4E00\u5F20\u94F6\u884C\u5361 |
| | | yami.shop.cannot.delete.check=\u6B63\u5728\u7528\u4E8E\u7533\u8BF7\u63D0\u73B0\u7684\u94F6\u884C\u5361\u4E0D\u80FD\u5220\u9664 |
| | | yami.shop.station.close=\u8BE5\u81EA\u63D0\u70B9\u5DF2\u5173\u95ED\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458 |
| | | yami.shop.station.not.open=\u8BE5\u81EA\u63D0\u70B9\u672A\u5728\u8425\u4E1A\u72B6\u6001 |
| | | yami.shop.phone.no.exist=\u624B\u673A\u53F7\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.shop.update.balance=\u66F4\u65B0\u4F59\u989D\u8BB0\u5F55\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5 |
| | | yami.shop.cash.no.enough=\u53EF\u63D0\u73B0\u91D1\u989D\u4E0D\u8DB3 |
| | | yami.shop.cash.grant=\u5546\u5BB6\u63D0\u73B0\u53D1\u653E |
| | | yami.shop.company.credit.code.repeat=\u7EDF\u4E00\u4FE1\u7528\u7801\u91CD\u590D |
| | | yami.shop.business.date.error=\u8425\u4E1A\u8D77\u59CB\u65E5\u671F\u4E0D\u80FD\u5927\u4E8E\u7B49\u4E8E\u8425\u4E1A\u7EC8\u6B62\u65F6\u95F4 |
| | | yami.shop.company.date.not.empty=\u8425\u4E1A\u65E5\u671F\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.shop.bank.card.not.empty=\u81F3\u5C11\u8981\u6DFB\u52A0\u4E00\u4E2A\u94F6\u884C\u5361 |
| | | yami.shop.bank.card.no.repeat=\u8D26\u53F7\u91CD\u590D |
| | | yami.cash.grant=\u63D0\u73B0\u53D1\u653E |
| | | yami.open.store=\u8BF7\u5148\u8FDB\u884C\u5F00\u5E97\u7533\u8BF7 |
| | | yami.password.error=\u539F\u5BC6\u7801\u4E0D\u6B63\u786E |
| | | yami.stop.cannot.modified=\u5E97\u94FA\u8D26\u53F7\u5DF2\u8BBE\u7F6E\u4E0D\u80FD\u4FEE\u6539 |
| | | yami.stop.examine.success=\u5546\u5BB6\u5DF2\u7ECF\u5BA1\u6838\u6210\u529F\uFF0C\u65E0\u9700\u518D\u6B21\u5BA1\u6838 |
| | | yami.stop.cannot.open=\u8BE5\u8D26\u53F7\u5DF2\u7ECF\u5F00\u901A\u8FC7\u5E97\u94FA\uFF0C\u65E0\u6CD5\u91CD\u590D\u5F00\u901A |
| | | yami.sign.check=\u9A8C\u7B7E\u5931\u8D25 |
| | | yami.bar.code.exist=\u5355\u54C1\u6761\u7801\u5DF2\u7ECF\u5B58\u5728 |
| | | yami.select.only.shop.type=\u8BF7\u9009\u62E9\u4E00\u4E2A\u5E97\u94FA\u7C7B\u578B |
| | | yami.select.a.shop=\u8BF7\u9009\u62E9\u4E00\u4E2A\u5E97\u94FA |
| | | yami.transaction.not.exists=\u4EA4\u6613\u5355\u53F7\u4E0D\u5B58\u5728 |
| | | yami.query.error=\u67E5\u8BE2\u51FA\u9519 |
| | | yami.order.no.exist=\u8BA2\u5355\u4E0D\u5B58\u5728 |
| | | yami.order.is.delivery=\u8BE5\u8BA2\u5355\u5DF2\u6709\u90E8\u5206\u5546\u54C1\u53D1\u8D27\uFF0C\u65E0\u6CD5\u8FDB\u884C\u6279\u91CF\u53D1\u8D27\u64CD\u4F5C |
| | | yami.order.amount.error=\u8BA2\u5355\u91D1\u989D\u6709\u8BEF\uFF0C\u65E0\u6CD5\u8FDB\u884C\u652F\u4ED8 |
| | | yami.order.amount.too.large.error=\u8BA2\u5355\u91D1\u989D\u8FC7\u5927\uFF0C\u65E0\u6CD5\u8FDB\u884C\u652F\u4ED8 |
| | | yami.order.code.no.exist=\u8BE5\u6838\u9500\u7801\uFF0C\u6CA1\u6709\u5BF9\u5E94\u7684\u8BA2\u5355 |
| | | yami.order.code.no.error=\u6838\u9500\u7801\u9519\u8BEF |
| | | yami.h5.index.ad.images.limit=\u8F6E\u64AD\u56FE\u4E0D\u80FD\u8D85\u8FC710\u4E2A |
| | | yami.order.payed=\u8BA2\u5355\u5DF2\u652F\u4ED8\uFF0C\u65E0\u6CD5\u53D6\u6D88\u8BA2\u5355 |
| | | yami.order.not.paid=\u5F53\u524D\u8BA2\u5355\u8FD8\u672A\u4ED8\u6B3E\uFF0C\u65E0\u6CD5\u7533\u8BF7 |
| | | yami.order.has.failed=\u5F53\u524D\u8BA2\u5355\u5DF2\u5931\u8D25\uFF0C\u4E0D\u5141\u8BB8\u9000\u6B3E |
| | | yami.order.receipt.no.delivery=\u8BA2\u5355\u672A\u53D1\u8D27\uFF0C\u65E0\u6CD5\u786E\u8BA4\u6536\u8D27 |
| | | yami.order.pay.user.disable=\u60A8\u5DF2\u88AB\u7981\u7528\uFF0C\u4E0D\u80FD\u8D2D\u4E70\uFF0C\u8BF7\u8054\u7CFB\u5E73\u53F0\u5BA2\u670D |
| | | yami.order.status.no.right=\u8BA2\u5355\u4E0D\u5904\u4E8E\u5F85\u5165\u5E93\u72B6\u6001\uFF0C\u65E0\u6CD5\u8FDB\u884C\u5165\u5E93 |
| | | yami.order.delivery.no.right=\u8BA2\u5355\u4E0D\u5904\u4E8E\u5F85\u53D1\u8D27\u72B6\u6001\uFF0C\u65E0\u6CD5\u8FDB\u884C\u53D1\u8D27 |
| | | yami.order.no.delivery=\u8BA2\u5355\u4E0D\u5904\u4E8E\u5F85\u6536\u8D27\u72B6\u6001\uFF0C\u65E0\u6CD5\u786E\u8BA4\u6536\u8D27 |
| | | yami.order.pay.fail=\u652F\u4ED8\u5931\u8D25\uFF0C\u8BA2\u5355\u4E0D\u5728\u672A\u652F\u4ED8\u72B6\u6001 |
| | | yami.order.delivery.refund.error=\u8BE5\u8BA2\u5355\u6709\u9000\u6B3E\u4FE1\u606F\u6B63\u5728\u5904\u7406\u5F53\u4E2D\uFF0C\u8BF7\u5904\u7406\u5B8C\u6BD5\u4E4B\u540E\u518D\u8FDB\u884C\u53D1\u8D27\u7684\u64CD\u4F5C\uFF01 |
| | | yami.order.receipt.refund=\u8BA2\u5355\u9000\u6B3E\u4E2D\uFF0C\u65E0\u6CD5\u786E\u8BA4\u6536\u8D27 |
| | | yami.order.no.success=\u8BA2\u5355\u9000\u6B3E\u4E2D\uFF0C\u8BA2\u5355\u672A\u5B8C\u6210\u6216\u672A\u5173\u95ED\uFF0C\u65E0\u6CD5\u5220\u9664\u8BA2\u5355 |
| | | yami.order.no.dvyName=\u5FEB\u9012\u516C\u53F8\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.order.delivery.number=\u5FEB\u9012\u5355\u53F7\u683C\u5F0F\u9519\u8BEF |
| | | yami.order.delivery.error=\u591A\u5BB6\u5E97\u94FA\u63D0\u4EA4\u8BA2\u5355\u65F6\uFF0C\u914D\u9001\u65B9\u5F0F\u53EA\u80FD\u662F\u5FEB\u9012 |
| | | yami.order.same.city.error=\u5F53\u524D\u5E97\u94FA\u672A\u5F00\u542F\u540C\u57CE\u914D\u9001! |
| | | yami.order.same.city.error2=\u8D85\u51FA\u5546\u5BB6\u914D\u9001\u8DDD\u79BB\u6216\u8D77\u9001\u8D39\u4E0D\u591F! |
| | | yami.order.same.city.error3=\u5F53\u524D\u8BA2\u5355\u4E0D\u652F\u6301\u540C\u57CE\u914D\u9001! |
| | | yami.order.same.city.error4=\u8D85\u51FA\u5F53\u524D\u8BBE\u7F6E\u7684\u914D\u9001\u8DDD\u79BB! |
| | | yami.order.unrecognized.prod=\u8BA2\u5355\u72B6\u6001\u5F02\u5E38\uFF0C\u65E0\u6CD5\u66F4\u6539\u8BA2\u5355\u5730\u5740 |
| | | yami.order.unrecognized.update=\u8BA2\u5355\u72B6\u6001\u5F02\u5E38\uFF0C\u65E0\u6CD5\u66F4\u6539\u8BA2\u5355\u91D1\u989D |
| | | yami.order.amount.check=\u8BA2\u5355\u91D1\u989D\u5FC5\u987B\u5927\u4E8E0\uFF0C\u6216\u8005\u6570\u636E\u53D1\u751F\u53D8\u5316(\u8BF7\u5237\u65B0\u540E\u91CD\u8BD5) |
| | | yami.order.status.error=\u8BA2\u5355\u5305\u542B\u65E0\u6CD5\u8BC6\u522B\u7684\u5546\u54C1 |
| | | yami.order.status.change=\u8BA2\u5355\u72B6\u6001\u5DF2\u7ECF\u53D1\u751F\u6539\u53D8\uFF0C\u8BF7\u52FF\u91CD\u590D\u64CD\u4F5C |
| | | yami.order.status.check.change=\u8BA2\u5355\u72B6\u6001\u5DF2\u7ECF\u53D1\u751F\u6539\u53D8\uFF0C\u8BF7\u91CD\u65B0\u4E0B\u5355 |
| | | yami.order.submit.change=\u8BF7\u52FF\u91CD\u590D\u63D0\u4EA4\u8BA2\u5355 |
| | | yami.order.refund.status.exist=\u9000\u8D27\u72B6\u6001\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.order.refund.exist=\u9000\u6B3E\u5355\u4E0D\u5B58\u5728 |
| | | yami.order.refund.define=\u8BF7\u5148\u786E\u5B9A\u9000\u6B3E\uFF0C\u624D\u80FD\u53D1\u8D77\u9000\u6B3E\u64CD\u4F5C |
| | | yami.order.refund.success=\u5DF2\u9000\u6B3E\u6210\u529F\uFF0C\u65E0\u6CD5\u518D\u7533\u8BF7\u9000\u6B3E\u64CD\u4F5C |
| | | yami.order.refund.cancel=\u4E70\u5BB6\u5DF2\u53D6\u6D88\u7533\u8BF7 |
| | | yami.set.refund.information=\u8BF7\u9009\u62E9\u9000\u8D27\u5730\u5740 |
| | | yami.order.refund.day.check=\u5F53\u524D\u8BA2\u5355\u5DF2\u786E\u8BA4\u6536\u8D27\u8D85\u8FC7 |
| | | yami.order.refund.day.check2=\u5929\uFF0C\u65E0\u6CD5\u9000\u6B3E |
| | | yami.no.found.order=\u672A\u627E\u5230\u8BE5\u8BA2\u5355\u4FE1\u606F |
| | | yami.order.refund.score=\u79EF\u5206\u5546\u54C1\uFF0C\u65E0\u6CD5\u9000\u6B3E |
| | | yami.availabl.cash.refund=\u60A8\u7684\u53EF\u63D0\u73B0\u91D1\u989D\u4E0D\u8DB3\uFF0C\u65E0\u6CD5\u8FDB\u884C\u9000\u6B3E |
| | | yami.not.sufficient.refund=\u60A8\u7684\u5F85\u7ED3\u7B97\u91D1\u989D\u4E0D\u8DB3\uFF0C\u65E0\u6CD5\u8FDB\u884C\u9000\u6B3E |
| | | yami.refund.processed=\u9000\u6B3E\u5DF2\u5904\u7406\uFF0C\u65E0\u9700\u91CD\u590D\u5904\u7406 |
| | | yami.order.all.refund.go.on=\u8BE5\u8BA2\u5355\u5DF2\u6709\u5546\u54C1\u6B63\u5728\u9000\u6B3E\u4E2D\uFF0C\u4E0D\u80FD\u518D\u8FDB\u884C\u6574\u5355\u9000\u6B3E |
| | | yami.order.all.refund.check=\u8BE5\u8BA2\u5355\u6B63\u5728\u8FDB\u884C\u6574\u5355\u9000\u6B3E\uFF0C\u65E0\u6CD5\u8FDB\u884C\u65B0\u7684\u9000\u6B3E\u64CD\u4F5C |
| | | yami.order.need.station=\u8BF7\u9009\u62E9\u6700\u5C11\u4E00\u4E2A\u9700\u8981\u81EA\u63D0\u7684\u8BA2\u5355 |
| | | yami.order.refund.go.on=\u8BE5\u5546\u54C1\u6B63\u5728\u8FDB\u884C\u9000\u6B3E\u4E2D\uFF0C\u65E0\u6CD5\u8FDB\u884C\u65B0\u7684\u9000\u6B3E\u64CD\u4F5C |
| | | yami.refund.exceeded.amount=\u9000\u6B3E\u91D1\u989D\u5DF2\u8D85\u51FA\u8BA2\u5355\u91D1\u989D\uFF0C\u65E0\u6CD5\u7533\u8BF7 |
| | | yami.not.refunds.requested=\u6CA1\u6709\u67E5\u8BE2\u5230\u652F\u4ED8\u8BB0\u5F55\uFF0C\u65E0\u6CD5\u7533\u8BF7\u9000\u6B3E |
| | | yami.refund.progress=\u8BA2\u5355\u6B63\u5728\u8FDB\u884C\u9000\u6B3E\u7ED3\u7B97\uFF0C\u8BF7\u52FF\u91CD\u590D\u64CD\u4F5C |
| | | yami.unable.refund.information=\u65E0\u6CD5\u83B7\u53D6\u9000\u6B3E\u8BA2\u5355\u4FE1\u606F |
| | | yami.refund.amount.check=\u8BE5\u8BA2\u5355\u90E8\u5206\u8BA2\u5355\u9879\u652F\u4ED8\u91D1\u989D\u548C\u79EF\u5206\u4E3A0\uFF0C\u65E0\u6CD5\u4F7F\u7528\u90E8\u5206\u9000\u6B3E\uFF01 |
| | | yami.refund.platform.amount.check=\u8BE5\u8BA2\u5355\u6709\u4F7F\u7528\u5E73\u53F0\u4F18\u60E0\uFF0C\u65E0\u6CD5\u4F7F\u7528\u90E8\u5206\u9000\u6B3E\uFF01 |
| | | yami.refund.num.check=\u9000\u6B3E\u7269\u54C1\u6570\u91CF\u5DF2\u8D85\u51FA\u8BA2\u5355\u4E2D\u7684\u6570\u91CF\uFF0C\u4E0D\u5141\u8BB8\u7533\u8BF7 |
| | | yami.order.processed=\u9000\u6B3E\u8BA2\u5355\u9879\u5DF2\u5904\u7406\uFF0C\u8BF7\u52FF\u91CD\u590D\u7533\u8BF7 |
| | | yami.order.unfinished.cannot.destroy.account=\u60A8\u7684\u8D26\u6237\u5F53\u524D\u5B58\u5728\u672A\u5B8C\u6210\u7684\u8BA2\u5355\uFF0C\u8BF7\u5F85\u6240\u6709\u8BA2\u5355\u5B8C\u6210\u540E\u518D\u6CE8\u9500\u8D26\u6237 |
| | | yami.cannot.find=\u67E5\u8BE2\u4E0D\u5230\u9000\u6B3E\u4FE1\u606F |
| | | yami.not.permission=\u7533\u8BF7\u5931\u8D25\uFF0C\u60A8\u6CA1\u6709\u8BE5\u6743\u9650 |
| | | yami.not.submission=\u5F53\u524D\u7533\u8BF7\u7C7B\u578B\u4E0D\u5141\u8BB8\u63D0\u4EA4\u7269\u6D41\u4FE1\u606F\u64CD\u4F5C |
| | | yami.not.submission.delivery=\u5F53\u524D\u72B6\u6001\u4E0D\u5141\u8BB8\u63D0\u4EA4\u7269\u6D41\u4FE1\u606F\u64CD\u4F5C |
| | | yami.not.update.delivery=\u5F53\u524D\u72B6\u6001\u4E0D\u5141\u8BB8\u66F4\u65B0\u7269\u6D41\u4FE1\u606F\u64CD\u4F5C |
| | | yami.revocation.failed=\u64A4\u9500\u5931\u8D25\uFF0C\u9000\u6B3E\u8BA2\u5355\u4E0D\u5B58\u5728 |
| | | yami.shop.processing.check=\u5356\u5BB6\u6B63\u5728\u5904\u7406\u9000\u6B3E\uFF0C\u4E0D\u80FD\u64A4\u9500\u9000\u6B3E\u7533\u8BF7 |
| | | yami.user.delivery.check=\u4E70\u5BB6\u5DF2\u53D1\u8D27\uFF0C\u4E0D\u80FD\u64A4\u9500\u9000\u6B3E\u7533\u8BF7 |
| | | yami.user.receipt.check=\u5356\u5BB6\u5DF2\u6536\u8D27\uFF0C\u4E0D\u80FD\u64A4\u9500\u9000\u6B3E\u7533\u8BF7 |
| | | yami.refund.success.check=\u9000\u6B3E\u6210\u529F\uFF0C\u4E0D\u80FD\u64A4\u9500\u9000\u6B3E\u7533\u8BF7 |
| | | yami.refund.finish.check=\u8BE5\u8BA2\u5355\u6240\u6709\u5546\u54C1\u90FD\u8FDB\u884C\u9000\u6B3E\uFF0C\u5DF2\u65E0\u6CD5\u53D6\u6D88\u9000\u6B3E |
| | | yami.refund.status.check=\u64A4\u9500\u5931\u8D25\uFF0C\u5F53\u524D\u72B6\u6001\u4E0D\u5141\u8BB8\u6B64\u64CD\u4F5C |
| | | yami.failed.not.exist=\u67E5\u770B\u5931\u8D25\uFF0C\u8BE5\u9000\u6B3E\u8BA2\u5355\u4E0D\u5B58\u5728 |
| | | yami.failed.not.permiso=\u67E5\u770B\u5931\u8D25\uFF0C\u60A8\u6CA1\u6709\u6B64\u6743\u9650 |
| | | yami.item.not.exist=\u8BE5\u7269\u54C1\u5728\u8BA2\u5355\u4E2D\u4E0D\u5B58\u5728 |
| | | yami.shopCart.take.off=\u5DF2\u4E0B\u67B6 |
| | | yami.contains.unrecognized.items=\u8D2D\u7269\u8F66\u5305\u542B\u65E0\u6CD5\u8BC6\u522B\u7684\u5546\u54C1 |
| | | yami.no.auth.update.form=\u60A8\u6CA1\u6709\u6743\u9650\u66F4\u6539\u8BE5\u62A5\u8868\u7684\u6570\u636E |
| | | yami.auth.fail=\u6388\u6743\u5931\u8D25\uFF0C\u8BF7\u91CD\u65B0\u6388\u6743 |
| | | yami.img.name.exist=\u56FE\u7247\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.area.delete=\u8BF7\u5148\u5220\u9664\u5B50\u5730\u533A |
| | | yami.delivery.using=\u6B63\u5728\u4F7F\u7528\u4E2D\uFF0C\u65E0\u6CD5\u8FDB\u884C\u5220\u9664\u64CD\u4F5C |
| | | yami.selCity=\u8BF7\u9009\u62E9\u6307\u5B9A\u5305\u90AE\u57CE\u5E02 |
| | | yami.model=\u6A21\u677F |
| | | yami.img.lose=\u56FE\u7247\u4E22\u5931\uFF0C\u8BF7\u91CD\u65B0\u4E0A\u4F20\u56FE\u7247 |
| | | yami.unable.get.classification=\u65E0\u6CD5\u83B7\u53D6\u5206\u7C7B\u4FE1\u606F |
| | | yami.select.notify.check=\u8BF7\u81F3\u5C11\u9009\u62E9\u4E00\u79CD\u901A\u77E5\u65B9\u5F0F |
| | | yami.select.notify.type.check=\u5DF2\u7ECF\u5B58\u5728\u5F53\u524D\u6D88\u606F\u7C7B\u578B\u7684\u5176\u4ED6\u914D\u7F6E\uFF0C\u8BF7\u53BB\u8FDB\u884C\u4FEE\u6539\u64CD\u4F5C\u3002 |
| | | yami.flush.category.tips=\u8BF7\u5148\u524D\u5F80 \u3010\u4F1A\u5458\u7BA1\u7406\u3011-> \u3010\u79EF\u5206\u6210\u957F\u503C\u914D\u7F6E\u3011-> \u3010\u79EF\u5206\u83B7\u53D6\u914D\u7F6E\u3011 \u8FDB\u884C\u914D\u7F6E\u5E76\u4FDD\u5B58 |
| | | yami.form.time.check=\u8BF7\u9009\u62E9\u8D77\u6B62\u65F6\u95F4 |
| | | yami.form.data.error=\u8BE5\u62A5\u8868\u6570\u636E\u6709\u8BEF\uFF0C\u8BF7\u5237\u65B0\u540E\u91CD\u65B0\u8F93\u5165 |
| | | yami.coupon.no.auth=\u6CA1\u6709\u6743\u9650\u4FEE\u6539\u8BE5\u4F18\u60E0\u5238\u4FE1\u606F |
| | | yami.coupon.receive.finish=\u8BE5\u5238\u65E0\u6CD5\u88AB\u9886\u53D6\u6216\u8005\u8BE5\u5238\u9886\u5B8C\u4E86! |
| | | yami.coupon.stock.enough=\u4F18\u60E0\u5238\u5E93\u5B58\u4E0D\u8DB3 |
| | | yami.coupon.user.limit=\u4F18\u60E0\u5238\u6570\u91CF\u8D85\u51FA\u9886\u53D6\u4E0A\u9650 |
| | | yami.coupon.limit.check=\u4F18\u60E0\u5238\u9650\u9886\u6570\u91CF\u9700\u5927\u4E8E0 |
| | | yami.coupon.time.check=\u5F00\u59CB\u65F6\u95F4\u9700\u5927\u4E8E\u7ED3\u675F\u65F6\u95F4 |
| | | yami.coupon.launch.time.check = \u4F18\u60E0\u5238\u6295\u653E\u65F6\u95F4\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.coupon.launch.time.check1 = \u6295\u653E\u65F6\u95F4\u9700\u5927\u4E8E\u5F53\u524D\u65F6\u95F4 |
| | | yami.coupon.launch.time.lt.endtime = \u6295\u653E\u65F6\u95F4\u8981\u5C0F\u4E8E\u5931\u6548\u65F6\u95F4 |
| | | yami.coupon.no.exist=\u4F18\u60E0\u5238\u4E0D\u5B58\u5728 |
| | | yami.coupon.delete.check1=\u8BE5\u4F18\u60E0\u5238\u5DF2\u88AB\u9886\u53D6\uFF0C\u5220\u9664\u5931\u8D25 |
| | | yami.coupon.delete.check2=\u8BE5\u4F18\u60E0\u5238\u5DF2\u6295\u653E\uFF0C\u5220\u9664\u5931\u8D25 |
| | | yami.coupon.receive.success=\u9886\u53D6\u4F18\u60E0\u5238\u6210\u529F |
| | | yami.live.time.check=\u5F00\u59CB\u65F6\u95F4\u4E0D\u80FD\u5927\u4E8E\u7ED3\u675F\u65F6\u95F4 |
| | | yami.live.time.one.check=\u5F00\u59CB\u65F6\u95F4\u9700\u8981\u5728\u5F53\u524D\u65F6\u95F4\u768415\u5206\u949F\u540E,\u5E76\u4E14\u4E0D\u80FD\u57286\u4E2A\u6708\u540E! |
| | | yami.live.time.two.check=\u5F00\u59CB\u65F6\u95F4\u548C\u7ED3\u675F\u65F6\u95F4\u95F4\u9694\u4E0D\u5F97\u77ED\u4E8E30\u5206\u949F\uFF0C\u4E0D\u5F97\u8D85\u8FC724\u5C0F\u65F6\uFF01 |
| | | yami.live.name.check=\u540D\u79F0\u957F\u5EA6\u4E0D\u7B26\u5408\u89C4\u5219\uFF01 |
| | | yami.live.user.name.check=\u4E3B\u64AD\u5FAE\u4FE1\u53F7\u672A\u7ECF\u8FC7\u3010\u5C0F\u7A0B\u5E8F\u76F4\u64AD\u3011\u5C0F\u7A0B\u5E8F\u5B9E\u540D\u8BA4\u8BC1\uFF01 |
| | | yami.live.room.check1=\u672A\u5728\u5C0F\u7A0B\u5E8F\u7BA1\u7406\u540E\u53F0\u914D\u7F6E\u5BA2\u670D |
| | | yami.live.config.check=\u521B\u5EFA\u5931\u8D25\uFF0C\u8BF7\u4ED4\u7EC6\u68C0\u67E5\u76F4\u64AD\u95F4\u7684\u914D\u7F6E\uFF01 |
| | | yami.live.room.delete.fail = \u5220\u9664\u76F4\u64AD\u95F4\u5931\u8D25 |
| | | yami.live.platform.numLimit=\u5E73\u53F0\u4ECA\u65E5\u53EF\u7528\u83B7\u53D6\u76F4\u64AD\u95F4\u4FE1\u606F\u7684\u6B21\u6570\u5DF2\u8FBE\u4E0A\u9650\uFF01 |
| | | yami.live.prod.name.check=\u540D\u79F0\u957F\u5EA6\u975E\u6CD5,\u6700\u5C113\u4E2A\u6C49\u5B57\u6216\u80056\u4E2A\u5B57\u7B26\u3001\u6700\u592714\u4E2A\u6C49\u5B57\uFF01 |
| | | yami.live.room.name.check=\u76F4\u64AD\u95F4\u540D\u79F0\u957F\u5EA6\u975E\u6CD5,\u6700\u77ED3\u4E2A\u6C49\u5B57\uFF0C\u6700\u957F17\u4E2A\u6C49\u5B57\uFF01 |
| | | yami.live.room.name.check2=\u4E3B\u64AD\u6635\u79F0\u957F\u5EA6\u975E\u6CD5\uFF0C\u6700\u77ED2\u4E2A\u6C49\u5B57\uFF0C\u6700\u957F15\u4E2A\u6C49\u5B57 |
| | | yami.live.room.top.check=\u7F6E\u9876\u5DF2\u8FBE\u4E0A\u965010\u4E2A\u65E0\u6CD5\u8FDB\u884C\u7F6E\u9876\uFF0C\u8BF7\u5148\u53D6\u6D88\u5176\u4F59\u76F4\u64AD\u95F4\u7684\u7F6E\u9876 |
| | | yami.live.prod.delete.fail=\u5220\u9664\u76F4\u64AD\u5546\u54C1\u5931\u8D25 |
| | | yami.live.prod.update.fail=\u66F4\u65B0\u76F4\u64AD\u5546\u54C1\u5E93\u5931\u8D25 |
| | | yami.live.prod.not.exist=\u5F53\u524D\u76F4\u64AD\u5546\u54C1\u5173\u8054\u7684\u5546\u54C1\u4E0D\u5B58\u5728\u6216\u5DF2\u88AB\u5220\u9664 |
| | | yami.live.prod.examine=\u5546\u54C1\u6B63\u5728\u5BA1\u6838\u4E2D\uFF0C\u65E0\u6CD5\u8FDB\u884C\u4FEE\u6539 |
| | | yami.prod.pre.sell=\u9884\u552E\u5546\u54C1\u4E0D\u80FD\u52A0\u5165\u8D2D\u7269\u8F66\uFF01 |
| | | yami.live.img.isWebp=\u56FE\u7247\u4E0D\u80FD\u4F7F\u7528webp\u683C\u5F0F,\u63A8\u8350\u4F7F\u7528jpg\u6216png |
| | | yami.order=\u8BA2\u5355 |
| | | yami.order.station.check=\u9000\u6B3E\u4E2D\uFF0C\u65E0\u6CD5\u81EA\u63D0 |
| | | yami.order.station.finish=\u5DF2\u63D0\u8D27 |
| | | yami.prod.no.join.activity=\u5F53\u524D\u5546\u54C1\u6CA1\u6709\u53C2\u52A0\u8BE5\u62FC\u56E2\u6D3B\u52A8 |
| | | yami.activity.no.start=\u5F53\u524D\u62FC\u56E2\u6D3B\u52A8\u672A\u5F00\u59CB |
| | | yami.activity.already.end=\u5F53\u524D\u62FC\u56E2\u6D3B\u52A8\u5DF2\u7ED3\u675F |
| | | yami.activity.already.invalid=\u5F53\u524D\u62FC\u56E2\u6D3B\u52A8\u5DF2\u5931\u6548 |
| | | yami.job.get.error=\u83B7\u53D6\u5B9A\u65F6\u4EFB\u52A1CronTrigger\u51FA\u73B0\u5F02\u5E38 |
| | | yami.prod.category.error=\u8BF7\u9009\u62E9\u5E73\u53F0\u7684\u4E09\u7EA7\u5206\u7C7B |
| | | yami.user.payType.error=\u8BF7\u4F7F\u7528\u5FAE\u4FE1\u6216\u652F\u4ED8\u5B9D\u8FDB\u884C\u652F\u4ED8 |
| | | yami.notify.tag.msg=\u8BF7\u81F3\u5C11\u9009\u62E9\u4E00\u4E2A\u6807\u7B7E\uFF01 |
| | | yami.information.is.wrong=\u60A8\u7684\u4FE1\u606F\u6709\u8BEF\uFF0C\u8BF7\u5C1D\u8BD5\u5237\u65B0\u540E\u518D\u8FDB\u884C\u64CD\u4F5C |
| | | yami.balance.is.insufficient=\u60A8\u7684\u4F59\u989D\u4E0D\u8DB3\uFF0C\u8BF7\u5148\u5145\u503C\u4F59\u989D |
| | | yami.id.number.already.exists=\u8BE5\u8EAB\u4EFD\u8BC1\u53F7\u7801\u5DF2\u5B58\u5728 |
| | | yami.phone.number.already.exists=\u8BE5\u624B\u673A\u53F7\u7801\u5DF2\u5728\u7CFB\u7EDF\u5B58\u5728 |
| | | yami.phone.number.not.exists=\u8BE5\u8D26\u53F7\u4E0D\u5B58\u5728 |
| | | yami.get.user.cash.info=\u65E0\u6CD5\u83B7\u53D6\u63D0\u73B0\u4FE1\u606F |
| | | yami.get.user.withdraw.info=\u65E0\u6CD5\u83B7\u53D6\u7528\u6237\u94B1\u5305\u4FE1\u606F |
| | | yami.withdrawCash.update.no.auth=\u6CA1\u6709\u6743\u9650\u4FEE\u6539\u63D0\u73B0\u4FE1\u606F |
| | | yami.user.tag.not.exists=\u7528\u6237\u6807\u7B7E\u4E0D\u5B58\u5728 |
| | | yami.user.tag.type.not.right=\u6807\u7B7E\u7C7B\u578B\u4E0D\u5BF9\u52B2 |
| | | yami.user.tag.refresh.limit=\u5237\u65B0\u95F4\u9694\u4E0D\u80FD\u5C0F\u4E8E\u4E00\u5206\u949F |
| | | yami.user.tag.time=\u5F00\u59CB\u65F6\u95F4\u4E0D\u80FD\u6BD4\u7ED3\u675F\u65F6\u95F4\u665A |
| | | yami.user.tag.number=\u6700\u5C0F\u6B21\u6570\u4E0D\u80FD\u6BD4\u6700\u5927\u6B21\u6570\u5927 |
| | | yami.user.tag.amount=\u6700\u5C0F\u91D1\u989D\u4E0D\u80FD\u6BD4\u6700\u5927\u91D1\u989D\u5927 |
| | | yami.finance.transactionTime=\u4EA4\u6613\u65F6\u95F4 |
| | | yami.finance.orderNumber=\u8BA2\u5355\u7F16\u53F7 |
| | | yami.finance.incOrPay=\u6536\u652F\u7C7B\u578B |
| | | yami.finance.payType=\u652F\u4ED8\u65B9\u5F0F |
| | | yami.finance.transactionAmount=\u4EA4\u6613\u91D1\u989D |
| | | yami.finance.reportTitle=\u8D22\u52A1\u660E\u7EC6\u62A5\u8868 |
| | | yami.finance.income=\u6536\u5165 |
| | | yami.finance.pay=\u652F\u51FA |
| | | yami.payType.pay0=\u79EF\u5206\u652F\u4ED8 |
| | | yami.payType.pay1=\u5FAE\u4FE1\u652F\u4ED8 |
| | | yami.payType.pay2=\u652F\u4ED8\u5B9D\u652F\u4ED8 |
| | | yami.payType.pay3=\u5FAE\u4FE1\u626B\u7801\u652F\u4ED8 |
| | | yami.payType.pay4=\u5FAE\u4FE1H5\u652F\u4ED8 |
| | | yami.payType.pay5=\u5FAE\u4FE1\u516C\u4F17\u53F7 |
| | | yami.payType.pay6=\u652F\u4ED8\u5B9DH5\u652F\u4ED8 |
| | | yami.payType.pay7=\u652F\u4ED8\u5B9DAPP\u652F\u4ED8 |
| | | yami.payType.pay8=\u5FAE\u4FE1APP\u652F\u4ED8 |
| | | yami.payType.pay9=\u7528\u6237\u4F59\u989D\u652F\u4ED8 |
| | | yami.store.name.no.exist=\u5E97\u94FA\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.store.brief.check=\u5E97\u94FA\u7B80\u4ECB\u957F\u5EA6\u5E94\u8BE5\u5C0F\u4E8E{max} |
| | | yami.store.name.check1=\u5546\u54C1\u540D\u79F0\u957F\u5EA6\u5E94\u8BE5\u5C0F\u4E8E{max} |
| | | yami.store.phone.no.exist=\u5E97\u94FA\u8054\u7CFB\u7535\u8BDD\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.tag.num.check=\u6761\u4EF6\u6807\u7B7E\u6570\u91CF\u8D85\u8FC7\u4E0A\u9650 |
| | | yami.tag.shop.check=\u60A8\u65E0\u6743\u5BF9\u6B64\u5546\u54C1\u6807\u7B7E\u8FDB\u884C\u64CD\u4F5C |
| | | yami.tag.prod.check=\u8BF7\u9009\u62E9\u9700\u8981\u52A0\u5165\u5206\u7EC4\u7684\u5546\u54C1 |
| | | yami.tag.prod.delete.check=\u8BF7\u9009\u62E9\u9700\u8981\u5220\u9664\u7684\u5206\u7EC4\u4E2D\u5546\u54C1 |
| | | yami.tag.prod.update.check=\u8BF7\u9009\u62E9\u9700\u8981\u4FEE\u6539\u7684\u5206\u7EC4\u4E2D\u5546\u54C1 |
| | | yami.live.user.check=\u5FAE\u4FE1\u53F7\u4E0D\u5408\u89C4 |
| | | yami.live.user.check1=\u5FAE\u4FE1\u53F7\u9700\u8981\u5B9E\u540D\u8BA4\u8BC1\uFF0C\u4EC5\u8BBE\u7F6E\u4E3B\u64AD\u89D2\u8272\u65F6\u53EF\u80FD\u51FA\u73B0 |
| | | yami.live.user.check2=\u91CD\u590D\u6DFB\u52A0\u89D2\u8272 |
| | | yami.live.user.check3=\u6DFB\u52A0\u89D2\u8272\u8FBE\u5230\u4E0A\u9650 |
| | | yami.live.user.check4=\u4E3B\u64AD\u89D2\u8272\u5220\u9664\u5931\u8D25\uFF0C\u8BE5\u4E3B\u64AD\u5B58\u5728\u672A\u5F00\u64AD\u7684\u76F4\u64AD\u95F4 |
| | | yami.live.user.super.admin=\u8D85\u7EA7\u7BA1\u7406\u5458\uFF0C |
| | | yami.live.user.admin=\u7BA1\u7406\u5458\uFF0C |
| | | yami.live.user.anchor=\u4E3B\u64AD\uFF0C |
| | | yami.live.user.operators=\u8FD0\u8425\u8005\uFF0C |
| | | yami.live.user.check5=\u7528\u6237\u5DF2\u5177\u6709\u7BA1\u7406\u5458\u89D2\u8272 |
| | | yami.live.user.check6=\u4E3B\u64AD\u89D2\u8272\u5220\u9664\u5931\u8D25\uFF0C\u8BE5\u4E3B\u64AD\u4E0D\u5B58\u5728\u6216\u8005\u5B58\u5728\u672A\u5F00\u64AD\u7684\u76F4\u64AD\u95F4 |
| | | yami.tag.name.exist=\u6807\u7B7E\u540D\u79F0\u5DF2\u5B58\u5728 |
| | | yami.customer.no.online=\u9009\u62E9\u8F6C\u53D1\u7684\u5BA2\u670D\u6216\u7528\u6237\u5DF2\u4E0D\u5728\u7EBF\u4E0A\uFF0C\u65E0\u6CD5\u8FDB\u884C\u8F6C\u53D1! |
| | | yami.user.balance.check=\u7528\u6237\u5F53\u524D\u4F59\u989D\u4E0D\u8DB3\uFF0C\u65E0\u6CD5\u51CF\u5C11 |
| | | yami.excel.user.info=\u7528\u6237\u4FE1\u606F\u8868 |
| | | yami.excel.user.number=\u5E8F\u53F7 |
| | | yami.excel.user.userNickname=\u7528\u6237\u6635\u79F0 |
| | | yami.excel.user.userName=\u7528\u6237\u540D\u79F0 |
| | | yami.excel.user.contactNumber=\u8054\u7CFB\u7535\u8BDD |
| | | yami.excel.user.memberLevel=\u4F1A\u5458\u7B49\u7EA7 |
| | | yami.excel.user.memberType=\u4F1A\u5458\u7C7B\u578B |
| | | yami.excel.user.accScore=\u7528\u6237\u79EF\u5206 |
| | | yami.excel.user.status=\u72B6\u6001 |
| | | yami.excel.user.amountConsum=\u6D88\u8D39\u91D1\u989D |
| | | yami.excel.user.amountActPaid=\u5B9E\u4ED8\u91D1\u989D |
| | | yami.excel.user.numberConsum=\u6D88\u8D39\u6B21\u6570 |
| | | yami.excel.user.aveDiscount=\u5E73\u5747\u6298\u6263 |
| | | yami.excel.user.rechargeAmount=\u5145\u503C\u91D1\u989D |
| | | yami.excel.user.topUpTimes=\u5145\u503C\u6B21\u6570 |
| | | yami.excel.user.refundAmount=\u9000\u6B3E\u91D1\u989D |
| | | yami.excel.user.numberOfRefund=\u9000\u6B3E\u6B21\u6570 |
| | | yami.excel.user.accPoints=\u7D2F\u8BA1\u79EF\u5206 |
| | | yami.excel.user.currBalance=\u5F53\u524D\u4F59\u989D |
| | | yami.excel.user.accBalance=\u7D2F\u8BA1\u4F59\u989D |
| | | yami.excel.user.regTime=\u6CE8\u518C\u65F6\u95F4 |
| | | yami.excel.user.receConsumDate=\u6700\u8FD1\u6D88\u8D39\u65F6\u95F4 |
| | | yami.web.config.check=\u8BF7\u81F3\u5C11\u5F00\u542F\u4E00\u4E2A\u914D\u7F6E\u540E\u518D\u5173\u95ED\u5F53\u524D\u914D\u7F6E |
| | | yami.average.retention.rate=\u5E73\u5747\u7559\u5B58\u7387 |
| | | yami.prod.set.top.check=\u53EA\u80FD\u7F6E\u9876\u5DF2\u4E0A\u67B6\u7684\u5546\u54C1 |
| | | yami.login.password.check=\u534A\u5C0F\u65F6\u5185\u8F93\u5165\u5BC6\u7801\u9519\u8BEF\u5341\u6B21\uFF0C\u5DF2\u9650\u5236\u767B\u5F5530\u5206\u949F |
| | | yami.product.sku.invalid=\u5E93\u5B58\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u5237\u65B0\u9875\u9762 |
| | | yami.group.name.duplicate=\u5206\u7EC4\u540D\u5DF2\u5B58\u5728 |
| | | yami.invoice.shopId.notNull=\u5E97\u94FAid\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.invoice.invoiceId.duplicate=\u8BE5\u8BA2\u5355\u5DF2\u7ECF\u7533\u8BF7\u53D1\u7968\uFF0C\u8BF7\u52FF\u91CD\u590D\u7533\u8BF7\uFF01 |
| | | yami.invoice.not.user=\u65E0\u6CD5\u67E5\u770B\u975E\u5F53\u524D\u7528\u6237\u7684\u53D1\u7968\u4FE1\u606F |
| | | yami.file.isNot.exist=\u8BF7\u4E0A\u4F20\u6587\u4EF6 |
| | | yami.file.isNot.shop=\u65E0\u6CD5\u67E5\u770B\u975E\u672C\u5E97\u94FA\u7684\u6587\u4EF6 |
| | | yami.prod.common.invalid=\u6570\u636E\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u5237\u65B0\u9875\u9762 |
| | | yami.prod.name.not.blank=\u4EA7\u54C1\u4E2D\u6587\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.prod.brief.not.blank=\u4EA7\u54C1\u4E2D\u6587\u5356\u70B9\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.prod.category.not.blank=\u4EA7\u54C1\u5206\u7C7B\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.platform.category.not.blank=\u5E73\u53F0\u5206\u7C7B\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.prod.shop.type.not.blank=\u4EA7\u54C1\u7C7B\u578B\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.prod.shop.category.not.blank=\u4EA7\u54C1\u5E97\u94FA\u5206\u7C7B\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.prod.dvy.type.not.blank=\u4EA7\u54C1\u914D\u9001\u65B9\u5F0F\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.prod.transport.not.exist=\u4EA7\u54C1\u8FD0\u8D39\u6A21\u677F\u4E0D\u5B58\u5728 |
| | | yami.prod.pic.limit = \u4E0A\u4F20\u56FE\u7247\u6570\u91CF\u8D85\u8FC7\u9650\u5236 |
| | | yami.prod.pic.format.error = \u4E0A\u4F20\u56FE\u7247\u683C\u5F0F\u9519\u8BEF |
| | | yami.prod.video.format.error = \u4E0A\u4F20\u89C6\u9891\u683C\u5F0F\u9519\u8BEF |
| | | yami.prod.video.too.large.error = \u4E0A\u4F20\u89C6\u9891\u8FC7\u5927 |
| | | yami.product.not.shelf=\u8BE5\u5546\u54C1\u672A\u4E0A\u67B6\uFF0C\u8BF7\u9009\u62E9\u522B\u7684\u5546\u54C1 |
| | | yami.supplier.name.not.blank=\u4F9B\u5E94\u5546\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.supplier.not.null=\u4F9B\u5E94\u5546\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.supplier.category.not.exit=\u4F9B\u5E94\u5546\u5206\u7C7B\u4E0D\u5B58\u5728\u6216\u5DF2\u88AB\u7981\u7528 |
| | | yami.supplier.category.already.exit=\u4F9B\u5E94\u5546\u5206\u7C7B\u5DF2\u5B58\u5728 |
| | | yami.supplier.supplierName.exist=\u4F9B\u5E94\u5546\u540D\u79F0\u5DF2\u5B58\u5728 |
| | | yami.supplier.supplierName.than=\u4F9B\u5E94\u5546\u540D\u79F0\u5B57\u6570\u4E0D\u80FD\u8D85\u8FC750 |
| | | yami.supplier.contactName.than=\u8054\u7CFB\u4EBA\u540D\u79F0\u4E0D\u80FD\u8D85\u8FC750 |
| | | yami.supplier.tel.error=\u5355\u4F4D\u7535\u8BDD\u683C\u5F0F\u9519\u8BEF |
| | | yami.supplier.contactTel.error=\u8054\u7CFB\u7535\u8BDD\u683C\u5F0F\u9519\u8BEF |
| | | yami.supplier.mail.error=\u90AE\u7BB1\u683C\u5F0F\u9519\u8BEF |
| | | yami.supplier.qqNumber.error=qq\u53F7\u683C\u5F0F\u9519\u8BEF |
| | | yami.supplier.wxNumber.error=\u5FAE\u4FE1\u53F7\u683C\u5F0F\u9519\u8BEF |
| | | yami.supplier.prod.not.shop=\u65E0\u6CD5\u67E5\u770B\u975E\u672C\u5E97\u94FA\u7684\u5546\u54C1 |
| | | yami.sku.party.code.exist=\u5546\u54C1\u7F16\u7801\u5DF2\u5B58\u5728 |
| | | yami.sku.party.code.not.exist=\u5546\u54C1\u7F16\u7801\u4E0D\u5B58\u5728\u6216\u8BE5\u5546\u54C1\u5DF2\u88AB\u5220\u9664 |
| | | yami.sku.party.code.is.repeated=\u8BE5\u5546\u54C1\u7F16\u7801\u4E0B\u5B58\u5728\u591A\u4E2A\u5546\u54C1\u89C4\u683C\uFF0C\u8BF7\u66F4\u65B0\u5BF9\u5E94\u7684\u5546\u54C1\u89C4\u683C\u7F16\u7801\u540E\u91CD\u65B0\u5BFC\u5165 |
| | | yami.station.no.exist=\u81EA\u63D0\u70B9\u4FE1\u606F\u4E0D\u5B58\u5728\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u81EA\u63D0\u70B9 |
| | | yami.order.not.null=\u8BA2\u5355\u6240\u9700\u5FC5\u586B\u9879\u4E0D\u80FD\u4E3A\u7A7A\uFF01 |
| | | yami.order.coupon.not.start=\u5361\u5238\u672A\u5230\u4F7F\u7528\u65F6\u95F4\u6216\u5DF2\u8FC7\u671F\uFF01 |
| | | yami.order.coupon.expired=\u5361\u5238\u5DF2\u8FC7\u671F\uFF01 |
| | | yami.order.coupon.exist=\u5361\u5238\u4E0D\u5B58\u5728\u6216\u8005\u5DF2\u6838\u9500\uFF01 |
| | | yami.order.virtual.check=\u9000\u6B3E\u4E2D\uFF0C\u65E0\u6CD5\u6838\u9500\uFF01 |
| | | yami.order.virtual.check2=\u5F53\u524D\u865A\u62DF\u5546\u54C1\u8BA2\u5355\u65E0\u9700\u6838\u9500 |
| | | yami.virtual.prod.check=\u865A\u62DF\u5546\u54C1\u4E0D\u80FD\u52A0\u5165\u8D2D\u7269\u8F66 |
| | | yami.order.virtual.refund.check1=\u5F53\u524D\u8BA2\u5355\u4E0D\u80FD\u9000\u6B3E\uFF0C\u8BF7\u8054\u7CFB\u5BA2\u670D |
| | | yami.order.virtual.refund.check2=\u865A\u62DF\u5546\u54C1\u8BA2\u5355\u4E0D\u80FD\u9000\u8D27\u9000\u6B3E |
| | | yami.order.virtual.refund.check3=\u5F53\u524D\u8BA2\u5355\u6838\u9500\u65F6\u95F4\u5DF2\u8FC7\u671F\u4E0D\u80FD\u7533\u8BF7\u9000\u6B3E\uFF0C\u8BF7\u8054\u7CFB\u5BA2\u670D |
| | | yami.order.virtual.refund.check4=\u5F53\u524D\u8BA2\u5355\u5DF2\u7ECF\u5168\u90E8\u6838\u9500\u5B8C\u6210\u4E0D\u80FD\u7533\u8BF7\u9000\u6B3E\uFF0C\u8BF7\u8054\u7CFB\u5BA2\u670D |
| | | yami.order.virtual.refund.check5=\u5F53\u524D\u8BA2\u5355\u53EF\u4EE5\u9000\u6B3E\u7684\u6570\u91CF\u8D85\u51FA |
| | | yami.order.prod.type.check=\u5546\u54C1\u521B\u5EFA\u540E\u4E0D\u80FD\u4FEE\u6539\u5546\u54C1\u7C7B\u578B |
| | | yami.prod.type.check=\u5546\u54C1\u7C7B\u578B\u6539\u53D8\uFF0C\u8BF7\u5237\u65B0\u9875\u9762\u540E\u91CD\u8BD5 |
| | | yami.take.stock.time.not.null=\u76D8\u70B9\u5F00\u59CB\u65F6\u95F4\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.take.stock.prod.null=\u76D8\u70B9\u5546\u54C1\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.take.stock.id.not.null=\u76D8\u70B9Id\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.take.stock.message.error=\u5F53\u524D\u76D8\u70B9\u4FE1\u606F\u4E0D\u5C5E\u4E8E\u4F60\u7684\u5E97\u94FA |
| | | yami.take.stock.status.error=\u5F53\u524D\u76D8\u70B9\u4EFB\u52A1\u5DF2\u5B8C\u6210\u6216\u5DF2\u4F5C\u5E9F\uFF0C\u8BF7\u8FD4\u56DE\u5217\u8868\u9875\u9762\u540E\u5237\u65B0 |
| | | yami.take.stock.import.error=\u8BE5\u76D8\u70B9\u5355\u5DF2\u6709\u5546\u54C1\u5BFC\u5165\uFF0C\u65E0\u6CD5\u4F7F\u7528\u6279\u91CF\u5BFC\u5165\u529F\u80FD |
| | | yami.take.stock.count.not.null=\u76D8\u70B9\u6570\u91CF\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.shop.sku.is.null=\u5546\u54C1\u89C4\u683C\u4E0D\u5B58\u5728 |
| | | yami.shop.stock.update.error=\u5E93\u5B58\u66F4\u65B0\u5931\u8D25 |
| | | yami.shop.total.stock.not.null=\u5546\u54C1\u5B9E\u76D8\u5E93\u5B58\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.purchases.order.voided=\u6B64\u8BA2\u5355\u5DF2\u4F5C\u5E9F |
| | | yami.purchases.order.complete=\u6B64\u8BA2\u5355\u5DF2\u5B8C\u6210 |
| | | yami.purchases.order.party.code=\u5546\u54C1\u7F16\u7801\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.purchases.order.stock.num=\u91C7\u8D2D\u6570\u91CF\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.purchases.order.error.code=\u9519\u8BEF\u7684\u5546\u54C1\u7F16\u53F7 |
| | | yami.supplier.status.error=\u8BE5\u4F9B\u5E94\u5546\u5DF2\u88AB\u7981\u7528\uFF0C\u8BF7\u542F\u7528\u540E\u518D\u64CD\u4F5C |
| | | yami.sku.party.code=\u5546\u54C1\u7F16\u7801 |
| | | yami.is.exist=\u5DF2\u5B58\u5728 |
| | | yami.properties=\u9500\u552E\u5C5E\u6027\u7EC4\u5408\u5B57\u7B26\u4E32 |
| | | yami.properties.error=\u683C\u5F0F\u9519\u8BEF |
| | | yami.sku.name=\u89C4\u683C\u540D |
| | | yami.is.duplicate=\u91CD\u590D |
| | | yami.sys.access.key.id.not.null=sysAccessKeyId \u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.supplier.not.exist.or.disabled=\u4F9B\u5E94\u5546\u4E0D\u5B58\u5728\u6216\u5DF2\u7981\u7528 |
| | | yami.purchased.order.not.exist=\u91C7\u8D2D\u8BA2\u5355\u4E0D\u5B58\u5728\uFF0C\u8BF7\u5237\u65B0\u540E\u91CD\u8BD5\uFF01 |
| | | yami.purchased.prod.not.exist.or.disabled=\u91C7\u8D2D\u5546\u54C1\u4E0D\u5B58\u5728\u6216\u5DF2\u5220\u9664\uFF0C\u8BF7\u5237\u65B0\u540E\u91CD\u8BD5\uFF01 |
| | | yami.data.deleted.or.not.exist=\u6570\u636E\u5DF2\u5220\u9664\u6216\u4E0D\u5B58\u5728 |
| | | yami.platform.prod.offline.check=\u5F53\u524D\u5546\u54C1/\u6D3B\u52A8\u5DF2\u8FDD\u89C4\u4E0B\u67B6\u6216\u8005\u6B63\u5728\u5BA1\u6838\u4E2D\uFF0C\u4E0D\u80FD\u8FDB\u884C\u4E0B\u67B6\u64CD\u4F5C |
| | | yami.order.coupon.expire.check=\u5F53\u524D\u9009\u62E9\u7684\u4F18\u60E0\u5238\u5DF2\u7ECF\u8FC7\u671F\uFF0C\u8BF7\u8FD4\u56DE\u91CD\u65B0\u63D0\u4EA4\u8BA2\u5355 |
| | | yami.order.discount.expire.check=\u5F53\u524D\u9009\u62E9\u7684\u6EE1\u51CF\u6D3B\u52A8\u5DF2\u7ECF\u8FC7\u671F\uFF0C\u8BF7\u8FD4\u56DE\u91CD\u65B0\u63D0\u4EA4\u8BA2\u5355 |
| | | yami.order.combo.expire.check=\u5F53\u524D\u9009\u62E9\u7684\u5957\u9910\u6D3B\u52A8\u5DF2\u7ECF\u8FC7\u671F\uFF0C\u8BF7\u8FD4\u56DE\u91CD\u65B0\u63D0\u4EA4\u8BA2\u5355 |
| | | yami.order.giveaway.expire.check=\u5F53\u524D\u9009\u62E9\u7684\u8D60\u54C1\u6D3B\u52A8\u5DF2\u7ECF\u8FC7\u671F\uFF0C\u8BF7\u8FD4\u56DE\u91CD\u65B0\u63D0\u4EA4\u8BA2\u5355 |
| | | yami.order.pay.type.check=\u5E73\u53F0\u6682\u4E0D\u652F\u6301\u5F53\u524D\u652F\u4ED8\u65B9\u5F0F\uFF0C\u8BF7\u5237\u65B0\u540E\u5728\u9009\u62E9 |
| | | yami.platform.delivery.name.repeat=\u7269\u6D41\u540D\u79F0\u4E0D\u80FD\u91CD\u590D |
| | | yami.prod.parameter.format.error=\u5546\u54C1\u53C2\u6570\u683C\u5F0F\u6709\u8BEF |
| | | yami.balance.than.max.balance=\u60A8\u7684\u4F59\u989D\u52A0\u5145\u503C\u7684\u4F59\u989D\u5C06\u5927\u4E8E\u6700\u5927\u4F59\u989D\uFF0C\u4E0D\u80FD\u8FDB\u884C\u5145\u503C\u64CD\u4F5C |
| | | yami.user.blance.not.exist = \u5F53\u524D\u5145\u503C\u9009\u9879\u5DF2\u4E0D\u5B58\u5728\uFF0C\u8BF7\u5237\u65B0\u91CD\u8BD5 |
| | | yami.prod.status.change=\u5546\u54C1\u72B6\u6001\u5DF2\u6539\u53D8\uFF0C\u8BF7\u5237\u65B0\u9875\u9762 |
| | | yami.refund.amount.change.check=\u5F53\u524D\u9000\u6B3E\u5355\u72B6\u6001\u4E0D\u80FD\u4FEE\u6539\u9000\u6B3E\u91D1\u989D\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5 |
| | | yami.refund.amount.change.check2=\u6574\u5355\u9000\u6B3E\u6682\u4E0D\u652F\u6301\u4FEE\u6539\u9000\u6B3E\u91D1\u989D |
| | | yami.refund.amount.change.check3=\u4F7F\u7528\u5E73\u53F0\u4F18\u60E0\u7684\u8BA2\u5355\u4E0D\u80FD\u4FEE\u6539\u9000\u6B3E\u91D1\u989D |
| | | yami.order.delivery.num.check=\u8BA2\u5355\u53D1\u8D27\u6570\u91CF\u4E0D\u8DB3\uFF0C\u8BF7\u5237\u65B0\u540E\u518D\u8BD5 |
| | | yami.active.is.delete=\u6D3B\u52A8\u5DF2\u88AB\u5220\u9664\uFF0C\u8BF7\u5237\u65B0\u9875\u9762\u91CD\u8BD5 |
| | | yami.station.no.exists=\u5F53\u524D\u95E8\u5E97\u4E0D\u5B58\u5728\u6216\u8005\u4E0D\u5728\u8425\u4E1A\u72B6\u6001\uFF0C\u8BF7\u91CD\u8BD5 |
| | | yami.exprot.prod.sku.error=\u68C0\u6D4B\u5230\u5B58\u5728\u8D85\u8FC7100\u7EC4\u89C4\u683C\u7684\u5546\u54C1\uFF0C\u8BF7\u4FEE\u6539\u540E\u91CD\u65B0\u5BFC\u5165 |
| | | |
| | | |
| | | yami.combo.end.time.error=\u6D3B\u52A8\u7ED3\u675F\u65F6\u95F4\u4E0D\u80FD\u5C0F\u4E8E\u5F53\u524D\u65F6\u95F4 |
| | | yami.combo.main.prod.not.empty=\u5957\u9910\u4E3B\u5546\u54C1\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.combo.matching.prod.count.error=\u642D\u914D\u5546\u54C1\u6570\u91CF\u9519\u8BEF |
| | | yami.combo.prod.delete.after.tips=\u5DF2\u88AB\u5220\u9664\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9 |
| | | yami.combo.prod.matching.price.after.tips=\u7684\u642D\u914D\u4EF7\u683C\u4E0D\u80FD\u8D85\u8FC7\u5546\u54C1\u539F\u4EF7 |
| | | yami.combo.not.shop=\u5F53\u524D\u5957\u9910\u4E0D\u5C5E\u4E8E\u60A8\u7684\u5E97\u94FA |
| | | yami.combo.already.delete=\u5F53\u524D\u5957\u9910\u5DF2\u88AB\u5220\u9664 |
| | | yami.combo.update.fail=\u5957\u9910\u4FE1\u606F\u66F4\u65B0\u5931\u8D25\uFF0C\u8BF7\u5237\u65B0\u540E\u91CD\u8BD5 |
| | | yami.combo.matching.required.not.empty=\u8BF7\u81F3\u5C11\u8BBE\u7F6E\u4E00\u4E2A\u5FC5\u9009\u7684\u642D\u914D\u5546\u54C1 |
| | | yami.combo.open.error.tips=\u5F53\u524D\u5957\u9910\u7684\u7ED3\u675F\u65F6\u95F4\u5C0F\u4E8E\u5F53\u524D\u65F6\u95F4\uFF0C\u5F00\u542F\u5931\u8D25\uFF0C\u8BF7\u5148\u8BBE\u7F6E\u8BE5\u5957\u9910\u7684\u6D3B\u52A8\u65F6\u95F4 |
| | | yami.combo.least.num.not.empty=\u8D77\u642D\u6570\u91CF\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.combo.not.find.prod=\u627E\u4E0D\u5230\u5546\u54C1\u4FE1\u606F |
| | | yami.combo.info.error=\u4FE1\u606F\u9519\u8BEF |
| | | yami.combo.delete.fail=\u5220\u9664\u5931\u8D25,\u8BF7\u5237\u65B0\u540E\u91CD\u8BD5 |
| | | yami.combo.already.invalid=\u5F53\u524D\u5957\u9910\u6D3B\u52A8\u5DF2\u5931\u6548 |
| | | yami.combo.product.already.delete.rear.tips=\u5DF2\u88AB\u5220\u9664\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9 |
| | | yami.combo.product.already.disable.rear.tips=\u5DF2\u88AB\u7981\u7528\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9 |
| | | yami.combo.spec.already=\u7684\u89C4\u683C |
| | | yami.giveaway.not.on.shop=\u8BE5\u8D60\u54C1\u4FE1\u606F\u4E0D\u5C5E\u4E8E\u4F60\u7684\u5E97\u94FA |
| | | yami.giveaway.prod.error=\u5B58\u5728\u9519\u8BEF\u7684\u5546\u54C1\uFF0C\u8BF7\u5237\u65B0\u540E\u91CD\u65B0\u9009\u62E9 |
| | | yami.giveaway.virtual.prod.error=\u5C5E\u4E8E\u865A\u62DF\u5546\u54C1\uFF0C\u4E0D\u80FD\u8BBE\u7F6E\u4E3A\u8D60\u9001\u5546\u54C1 |
| | | yami.giveaway.activity.time.error.tips1=\u6D3B\u52A8\u65F6\u95F4\u4E0E\u8D60\u54C1\u3010 |
| | | yami.giveaway.activity.time.error.tips2=\u3011\u7684\u65F6\u95F4\u53D1\u751F\u51B2\u7A81\uFF0C\u4E00\u4E2A\u4E3B\u5546\u54C1\u540C\u4E00\u65F6\u95F4\u4E0D\u80FD\u8BBE\u7F6E\u591A\u4E2A\u8D60\u54C1\u6D3B\u52A8\uFF0C\u3010 |
| | | yami.giveaway.activity.time.error.tips3=\u3011\u7684\u6D3B\u52A8\u65F6\u95F4\u4E3A |
| | | yami.giveaway.activity.time.error.tips4=\u5F53\u524D\u8D60\u54C1\u7684\u7ED3\u675F\u65F6\u95F4\u5C0F\u4E8E\u5F53\u524D\u65F6\u95F4\uFF0C\u5F00\u542F\u5931\u8D25\uFF0C\u8BF7\u5148\u8BBE\u7F6E\u8BE5\u8D60\u54C1\u7684\u6D3B\u52A8\u65F6\u95F4 |
| | | yami.giveaway.activity.time.error.tips5=\u4E00\u4E2A\u4E3B\u5546\u54C1\u4E0D\u80FD\u8BBE\u7F6E\u591A\u4E2A\u8D60\u54C1\u6D3B\u52A8 |
| | | yami.giveaway.time.to=\u81F3 |
| | | yami.giveaway.already.invalid=\u5F53\u524D\u8D60\u54C1\u6D3B\u52A8\u5DF2\u5931\u6548 |
| | | yami.giveaway.already.delete=\u5F53\u524D\u8D60\u54C1\u5DF2\u88AB\u5220\u9664 |
| | | yami.giveaway.update.fail=\u8D60\u54C1\u4FE1\u606F\u66F4\u65B0\u5931\u8D25\uFF0C\u8BF7\u5237\u65B0\u540E\u91CD\u8BD5 |
| | | yami.giveaway.refund.price.error=\u8D60\u54C1\u7684\u603B\u552E\u540E\u4EF7\u4E0D\u80FD\u8D85\u8FC7\u4E3B\u5546\u54C1\u4EF7\u683C |
| | | yami.prod.combo.expired=\u5957\u9910\u4E0D\u5B58\u5728\uFF0C\u6216\u5DF2\u5931\u6548 |
| | | yami.main.prod.wrong=\u4E3B\u5546\u54C1\u4FE1\u606F\u9519\u8BEF\uFF0C\u8BF7\u5237\u65B0\u540E\u91CD\u8BD5 |
| | | yami.select.matching.prod=\u8BF7\u9009\u62E9\u642D\u914D\u5546\u54C1 |
| | | yami.select.required.matching.items=\u8BF7\u9009\u62E9\u5FC5\u9009\u642D\u914D\u5546\u54C1 |
| | | yami.prod.package.cannot.empty=\u5957\u9910\u642D\u914D\u5546\u54C1\u5217\u8868\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.active.prod.cannot.add.cart=\u6D3B\u52A8\u5546\u54C1\u4E0D\u80FD\u52A0\u5165\u8D2D\u7269\u8F66 |
| | | yami.active.prod.cannot.add.collection=\u6D3B\u52A8\u5546\u54C1\u4E0D\u80FD\u6DFB\u52A0\u6536\u85CF |
| | | yami.active.prod.cannot.buy=\u6D3B\u52A8\u5546\u54C1\u4E0D\u80FD\u5355\u72EC\u8D2D\u4E70 |
| | | yami.combo.prod.already.exists=\u8D2D\u7269\u8F66\u4E2D\u5DF2\u5B58\u5728\u8BE5\u89C4\u683C\u4E0D\u540C\u642D\u914D\u7684\u5957\u9910\uFF0C \u8BF7\u52FF\u91CD\u590D\u52A0\u8D2D |
| | | yami.specification.already.exists.shopping.cart=\u8D2D\u7269\u8F66\u5DF2\u5B58\u5728\u8BE5\u89C4\u683C |
| | | yami.cn.reason.duplicate=\u4E2D\u6587\u539F\u56E0\u91CD\u590D\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165 |
| | | yami.en.reason.duplicate=\u82F1\u6587\u539F\u56E0\u91CD\u590D\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165 |
| | | yami.system.reason.not.delete=\u7CFB\u7EDF\u5185\u7F6E\u51FA\u5165\u5E93\u539F\u56E0\u4E0D\u80FD\u5220\u9664 |
| | | yami.sku.price.not.change=\u53C2\u52A0\u4E86\u5957\u9910\u6216\u8D60\u54C1\u6D3B\u52A8\uFF0C\u65E0\u6CD5\u66F4\u6539\u4EF7\u683C\uFF0C\u8BF7\u5237\u65B0\u9875\u9762\u91CD\u8BD5 |
| | | yami.sku.stockWarning.limit = \u5E93\u5B58\u9884\u8B66\u8D85\u8FC7\u6700\u5927\u503C |
| | | yami.combo.prod.not.delete=\u53C2\u52A0\u4EE5\u4E0B\u6D3B\u52A8\u7684\u5546\u54C1\u4E0D\u80FD\u88AB\u5220\u9664\uFF1A\u4F18\u60E0\u5957\u9910 |
| | | yami.giveaway.prod.not.delete=\u53C2\u52A0\u4EE5\u4E0B\u6D3B\u52A8\u7684\u5546\u54C1\u4E0D\u80FD\u88AB\u5220\u9664\uFF1A\u8D60\u54C1 |
| | | yami.sys.web.config.delete=\u4E0D\u80FD\u5220\u9664\u6FC0\u6D3B\u72B6\u6001\u7684\u914D\u7F6E |
| | | yami.imgs.length.then.max=imgs\u6570\u636E\u9519\u8BEF\uFF1A\u957F\u5EA6\u5927\u4E8E255 |
| | | yami.seckill.invalid=\u8BE5\u79D2\u6740\u6D3B\u52A8\u5DF2\u5931\u6548 |
| | | yami.not.ordinary.prod=\u4E0D\u662F\u666E\u901A\u5546\u54C1 |
| | | yami.lack.permission.pre=\u60A8\u7F3A\u5C11 |
| | | yami.lack.permission.suf=\u6A21\u5757\u7684\u6743\u9650 |
| | | yami.refund.amount.check1=\u9000\u6B3E\u91D1\u989D\u6709\u8BEF\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165 |
| | | yami.role.use.cannot.deleted=\u89D2\u8272\u4F7F\u7528\u4E2D\u4E0D\u80FD\u5220\u9664 |
| | | yami.prod.platform.category.deleted=\u8BE5\u5E73\u53F0\u5206\u7C7B\u5DF2\u5220\u9664\uFF0C\u8BF7\u9009\u62E9\u65B0\u7684\u5206\u7C7B |
| | | yami.not.permission.modify.administrator.info=\u60A8\u6CA1\u6709\u6743\u9650\u4FEE\u6539\u7BA1\u7406\u5458\u4FE1\u606F |
| | | yami.index.img.reached.limit=\u8BE5\u7528\u6237\u7AEF\u7684\u8F6E\u64AD\u56FE\u5DF2\u8FBE\u5230\u6700\u5927\u6570\u91CF\uFF0C\u4E0D\u80FD\u518D\u8FDB\u884C\u65B0\u589E\u64CD\u4F5C |
| | | yami.shopCart.prod.error=\u9884\u552E/\u865A\u62DF/\u6D3B\u52A8\u5546\u54C1\u4E0D\u80FD\u52A0\u5165\u8D2D\u7269\u8F66\uFF01 |
| | | yami.sku.cannot.empty=sku\u5217\u8868\u4E0D\u80FD\u4E3A\u7A7A |
| | | |
| | | |
| | | yami.signingAuditing.auditInformation.notFound=\u627E\u4E0D\u5230\u8BE5\u5BA1\u6838\u4FE1\u606F\uFF0C\u8BF7\u5237\u65B0\u9875\u9762 |
| | | yami.Auditing.applicationInfo.notFound=\u627E\u4E0D\u5230\u6B64\u7533\u8BF7\u4FE1\u606F\uFF0C\u8BF7\u5237\u65B0\u9875\u9762 |
| | | yami.signingAuditing.categorySigningInformation.notFound=\u8BE5\u5206\u7C7B\u7B7E\u7EA6\u4FE1\u606F\u4E0D\u5B58\u5728\u6216\u9519\u8BEF\uFF0C\u8BF7\u5237\u65B0\u9875\u9762 |
| | | yami.invoice.categoryId.notNull=\u5206\u7C7Bid\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.invoice.brandId.notNull=\u54C1\u724Cid\u4E0D\u80FD\u4E3A\u7A7A |
| | | |
| | | yami.order.devType.notMatch=\u5BFC\u5165\u7684\u914D\u9001\u65B9\u5F0F\u4E0E\u8BA2\u5355\u7684\u914D\u9001\u65B9\u5F0F\u4E0D\u4E00\u81F4 |
| | | yami.out.orderNumber=\u5916\u90E8\u8BA2\u5355\u6D41\u6C34\u53F7 |
| | | yami.pay.status=\u652F\u4ED8\u72B6\u6001 |
| | | yami.pay.score=\u652F\u4ED8\u79EF\u5206 |
| | | yami.pay.amount=\u652F\u4ED8\u91D1\u989D |
| | | yami.pay.time=\u652F\u4ED8\u65F6\u95F4 |
| | | yami.order.pay=\u5DF2\u652F\u4ED8 |
| | | yami.order.no.paid=\u672A\u652F\u4ED8 |
| | | yami.pay.info.reportTitle=\u6536\u5165\u5BF9\u8D26\u660E\u7EC6\u62A5\u8868 |
| | | yami.refund.info.reportTitle=\u9000\u6B3E\u5BF9\u8D26\u660E\u7EC6\u62A5\u8868 |
| | | yami.account.info.reportTitle=\u5BF9\u8D26\u660E\u7EC6\u62A5\u8868 |
| | | yami.pay.no=\u652F\u4ED8\u5355\u53F7 |
| | | yami.refund.no=\u9000\u6B3E\u5355\u53F7 |
| | | yami.refund.status=\u9000\u6B3E\u72B6\u6001 |
| | | yami.refund.time=\u9000\u6B3E\u65F6\u95F4 |
| | | yami.refund.finish=\u5DF2\u9000\u6B3E |
| | | yami.message.leng.exceed.limit=\u6D88\u606F\u5185\u5BB9\u957F\u5EA6\u8D85\u51FA\u9650\u5236 |
| | | |
| | | yami.order.is.closed=\u8BA2\u5355\u5DF2\u5173\u95ED |
| | | yami.deliverySum.exceed.stocks=\u51FA\u5E93\u6570\u8D85\u51FA\u5E93\u5B58\u6570 |
| | | yami.shop.pay.info.update.error=\u652F\u4ED8\u4FE1\u606F\u66F4\u65B0\u5931\u8D25 |
| | | |
| | | yami.prod.import.virtualRemark.notValid=\u865A\u62DF\u5546\u54C1\u7559\u8A00\u683C\u5F0F\u4E0D\u6B63\u786E |
| | | yami.sensitive.words.reenter=\u5B58\u5728\u654F\u611F\u8BCD\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165 |
| | | |
| | | yami.prod.status.error.Please.exit.and.try.again=\u5546\u54C1\u72B6\u6001\u4E0D\u6B63\u786E\uFF0C\u8BF7\u9000\u51FA\u91CD\u8BD5 |
| | | yami.finance.form.excel=\u8BF7\u9009\u62E9\u5BFC\u51FA\u62A5\u8868\u7684\u4EA4\u6613\u65F6\u95F4 |
| | | yami.shop.wallet.log.excel=\u5E97\u94FA\u7ED3\u7B97\u660E\u7EC6\u8868 |
| | | yami.Shipping.amount.error=\u8FD0\u8D39\u91D1\u989D\u4E0D\u80FD\u5C0F\u4E8E0 |
| | | yami.balance.out.error=\u4F59\u989D\u4E0D\u5F97\u8D85\u8FC7999999999.99 |
| | | yami.score.out.error=\u79EF\u5206\u4E0D\u5F97\u8D85\u8FC7100000000 |
| | | yami.trans.amount.not.null=\u7EDF\u4E00\u8FD0\u8D39\u65F6\u8FD0\u8D39\u4E0D\u80FD\u4E3A\u7A7A |
| | | yami.delivery.name.is.same=\u4E0E\u7CFB\u7EDF\u5185\u7F6E\u6A21\u677F\u540D\u79F0\u91CD\u590D\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165 |
| | | yami.delivery.error=\u8BF7\u9009\u62E9\u53EF\u914D\u9001\u533A\u57DF |
| | | yami.delivery.over=\u5F53\u524D\u533A\u57DF\u4E0D\u652F\u6301\u914D\u9001 |
| | | yami.cannot.used.score.payment=\u652F\u4ED8\u91D1\u989D\u5927\u4E8E0\u7684\u8BA2\u5355\uFF0C\u4E0D\u80FD\u4F7F\u7528\u79EF\u5206\u652F\u4ED8 |
| | | yami.combo.price.excessive=\u5957\u9910\u603B\u91D1\u989D\u8FC7\u5927\uFF0C\u8BF7\u5408\u7406\u8BBE\u7F6E |
| | | yami.order.prod.count.limit=\u4E0B\u5355\u5546\u54C1\u6570\u91CF\u4E0D\u80FD\u5C0F\u4E8E1 |
| | | yami.product.has.created.seckill=\u8BE5\u5546\u54C1\u5DF2\u521B\u5EFA\u79D2\u6740\u6D3B\u52A8\uFF0C\u8BF7\u52FF\u91CD\u590D\u63D0\u4EA4 |
| | | yami.pcdn.error=\u7cfb\u7edf\u7e41\u5fd9\uff0c\u8bf7\u7a0d\u540e\u518d\u8bd5 |
| | | yami.pcdn.assets.freeze=\u51bb\u7ed3\u6570\u91cf\u5fc5\u987b\u5728100\u52309999\u4e4b\u95f4 |
| | | yami.user.assets.lucky.coin.balance=\u5e78\u8fd0\u5e01\u4f59\u989d\u4e0d\u8db3 |
| | | yami.user.assets.lucky.coin.freeze=\u51bb\u7ed3\u5e01\u4f5c\u4e3a\u53c2\u6570\u4e3a\u7a7a |
| | | yami.user.device.not.exist=\u7528\u6237\u8bbe\u5907\u4e0d\u5b58\u5728 |
| | | yami.pcdn.device.bound=\u8be5\u8bbe\u5907\u5df2\u88ab\u7ed1\u5b9a |
| | | yami.pcdn.device.delete=\u8be5\u8bbe\u5907\u5df2\u88ab\u5220\u9664 |
| | | yami.pcdn.device.token=\u8bf7\u8bbe\u7f6e\u83b7\u53d6token\u7684\u914d\u7f6e\u6587\u4ef6 |
| | | yami.pcdn.device.id.null=\u8bbe\u5907id\u4e3a\u7a7a |
| | | yami.pcdn.device.userId.null=\u7528\u6237id\u4e3a\u7a7a |
| | | yami.pcdn.device.binding.error=\u8be5\u8bbe\u5907\u5df2\u7ecf\u7ed1\u5b9a\u5728\u4f60\u7684\u8d26\u53f7 |
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-coupon</artifactId> |
| | | |
| | | <description>商城优惠券模块</description> |
| | | <packaging>pom</packaging> |
| | | |
| | | <modules> |
| | | <module>yami-shop-coupon-api</module> |
| | | <module>yami-shop-coupon-platform</module> |
| | | <module>yami-shop-coupon-multishop</module> |
| | | <module>yami-shop-coupon-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-coupon</artifactId> |
| | | <groupId>com.yami.shop</groupId> |
| | | <version>0.0.1-SNAPSHOT</version> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>yami-shop-coupon-api</artifactId> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.yami.shop</groupId> |
| | | <artifactId>yami-shop-coupon-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> |
| | | </dependencies> |
| | | </project> |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.api.config; |
| | | |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import org.springdoc.core.GroupedOpenApi; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | |
| | | /** |
| | | * 优惠券 |
| | | * @author lanhai |
| | | */ |
| | | @Configuration("couponSwaggerConfiguration") |
| | | @AllArgsConstructor |
| | | public class SwaggerConfiguration { |
| | | |
| | | |
| | | @Bean |
| | | public GroupedOpenApi couponRestApi() { |
| | | return GroupedOpenApi.builder() |
| | | .group("优惠券接口") |
| | | .packagesToScan("com.yami.shop.coupon.api.controller") |
| | | .pathsToMatch("/**") |
| | | .build(); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.api.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.app.dto.CouponDto; |
| | | import com.yami.shop.bean.app.dto.ProductDto; |
| | | import com.yami.shop.bean.enums.CouponProdType; |
| | | 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.model.Coupon; |
| | | import com.yami.shop.coupon.common.model.CouponProd; |
| | | import com.yami.shop.coupon.common.service.CouponService; |
| | | 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.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.Collections; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * 优惠券接口 |
| | | * |
| | | * @author lanhai |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/coupon") |
| | | @Tag(name = "优惠券接口") |
| | | public class CouponController { |
| | | |
| | | @Autowired |
| | | private CouponService couponService; |
| | | |
| | | @Autowired |
| | | private MapperFacade mapperFacade; |
| | | |
| | | @GetMapping("/listShopCoupon") |
| | | @Operation(summary = "查看一店铺的所有优惠券" , description = "通过店铺id(shopId)获取该店优惠券") |
| | | @Parameters({ |
| | | @Parameter(name = "shopId", description = "店铺ID" , required = true) |
| | | }) |
| | | public ServerResponseEntity<List<CouponDto>> listShopCoupon(@RequestParam(value = "shopId") Long shopId) { |
| | | List<Coupon> couponList = couponService.listPutonByShopId(shopId); |
| | | List<CouponDto> couponDtos = mapperFacade.mapAsList(couponList, CouponDto.class); |
| | | return ServerResponseEntity.success(couponDtos); |
| | | } |
| | | |
| | | @GetMapping("/listByProdId") |
| | | @Operation(summary = "获取商品可用的优惠券列表" , description = "获取该商品可用的优惠券列表") |
| | | @Parameters({ |
| | | @Parameter(name = "shopId", description = "店铺id" , required = true), |
| | | @Parameter(name = "prodId", description = "商品id" , required = true) |
| | | }) |
| | | public ServerResponseEntity<List<CouponDto>> listByProdId(Long shopId, Long prodId) { |
| | | // 获取已投放优惠券 |
| | | List<Coupon> couponList = couponService.listPutonByShopId(shopId); |
| | | // 过滤商品 |
| | | couponList = couponList.stream().filter(a -> { |
| | | boolean flag = true; |
| | | |
| | | if (a.getGetWay() == null) { |
| | | // 如果getWay为空,默认当成0处理 |
| | | a.setGetWay(0); |
| | | } else if (a.getGetWay() == 1) { |
| | | // 不是用户直接领取的优惠券,直接不显示该优惠券 |
| | | return false; |
| | | } |
| | | //过滤指定商品不参与 |
| | | if (Objects.equals(a.getSuitableProdType(), CouponProdType.PROD_NO_IN.value())) { |
| | | for (CouponProd couponProd : a.getCouponProds()) { |
| | | if (Objects.equals(couponProd.getProdId(), prodId)) { |
| | | flag = false; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | //过滤指定商品参与 |
| | | else if (Objects.equals(a.getSuitableProdType(), CouponProdType.PROD_IN.value())) { |
| | | flag = false; |
| | | for (CouponProd couponProd : a.getCouponProds()) { |
| | | if (Objects.equals(couponProd.getProdId(), prodId)) { |
| | | flag = true; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | return flag; |
| | | }).collect(Collectors.toList()); |
| | | List<CouponDto> couponDtos = mapperFacade.mapAsList(couponList, CouponDto.class); |
| | | return ServerResponseEntity.success(couponDtos); |
| | | } |
| | | |
| | | @GetMapping("/prodListByCouponId") |
| | | @Operation(summary = "获取优惠券可用的商品列表" , description = "获取优惠券可用的商品列表") |
| | | @Parameter(name = "couponId", description = "优惠券id" , required = true) |
| | | public ServerResponseEntity<IPage<ProductDto>> prodListByCouponId(PageParam<ProductDto> page, @RequestParam("couponId") Long couponId) { |
| | | if (couponId <= 0) { |
| | | page.setRecords(Collections.emptyList()); |
| | | return ServerResponseEntity.success(page); |
| | | } |
| | | Coupon coupon = couponService.getById(couponId); |
| | | if (Objects.isNull(coupon) || coupon.getOverdueStatus() != 1) { |
| | | page.setRecords(Collections.emptyList()); |
| | | return ServerResponseEntity.success(page); |
| | | } |
| | | IPage<ProductDto> productPage = couponService.prodListByCoupon(page, coupon, I18nMessage.getDbLang()); |
| | | return ServerResponseEntity.success(productPage); |
| | | } |
| | | |
| | | @GetMapping("/couponScorePage") |
| | | @Operation(summary = "积分优惠券列表" , description = "获取积分商城可换的优惠券列表") |
| | | public ServerResponseEntity<IPage<Coupon>> couponScorePage(PageParam<Coupon> page) { |
| | | IPage<Coupon> couponDtos = couponService.page(page, new LambdaQueryWrapper<Coupon>() |
| | | .eq(Coupon::getOverdueStatus, 1) |
| | | .eq(Coupon::getPutonStatus, 1) |
| | | .eq(Coupon::getIsScoreType, 1)); |
| | | return ServerResponseEntity.success(couponDtos); |
| | | } |
| | | |
| | | @GetMapping("/couponById") |
| | | @Operation(summary = "获取一条优惠券信息" , description = "通过id获取对应优惠券") |
| | | @Parameter(name = "couponId", description = "优惠券id" , required = true) |
| | | public ServerResponseEntity<Coupon> getCouponById(Long couponId) { |
| | | Coupon coupon = couponService.getById(couponId); |
| | | return ServerResponseEntity.success(coupon); |
| | | } |
| | | |
| | | @GetMapping("/getCouponPage") |
| | | @Operation(summary = "商品券列表(商家优惠券),游客访问" , description = "获取商品券列表(指定商品可用优惠券),游客访问") |
| | | public ServerResponseEntity<IPage<CouponDto>> getCouponList(PageParam<CouponDto> page) { |
| | | IPage<CouponDto> couponDto = couponService.getCouponList(page); |
| | | return ServerResponseEntity.success(couponDto); |
| | | } |
| | | |
| | | @GetMapping("/generalCouponList") |
| | | @Operation(summary = "通用券列表(平台优惠券)" , description = "获取通用券列表") |
| | | public ServerResponseEntity<List<CouponDto>> generalCouponList() { |
| | | List<CouponDto> couponList = couponService.generalCouponList(); |
| | | return ServerResponseEntity.success(couponList); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.api.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.app.dto.CouponDto; |
| | | 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.model.Coupon; |
| | | import com.yami.shop.coupon.common.model.CouponUser; |
| | | import com.yami.shop.coupon.common.service.CouponService; |
| | | import com.yami.shop.coupon.common.service.CouponUserService; |
| | | import com.yami.shop.security.api.util.SecurityUtils; |
| | | 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 java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 我的优惠券接口 |
| | | * |
| | | * @author lanhai |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/p/myCoupon") |
| | | @Tag(name = "我的优惠券接口") |
| | | @AllArgsConstructor |
| | | public class MyCouponController { |
| | | |
| | | private CouponService couponService; |
| | | private CouponUserService couponUserService; |
| | | |
| | | @GetMapping("/listCouponIds") |
| | | @Operation(summary = "查看用户拥有的所有优惠券id" , description = "查看用户拥有的所有优惠券id") |
| | | public ServerResponseEntity<List<CouponDto>> list() { |
| | | String userId = SecurityUtils.getUser().getUserId(); |
| | | List<CouponDto> coupons = couponService.listCouponIdsByUserId(userId); |
| | | return ServerResponseEntity.success(coupons); |
| | | } |
| | | |
| | | @PostMapping("/receive") |
| | | @Operation(summary = "领取优惠券接口" , description = "领取优惠券接口") |
| | | @Parameter(name = "couponId", description = "优惠券ID" , required = true) |
| | | public ServerResponseEntity<String> receive(@RequestBody Long couponId) { |
| | | String userId = SecurityUtils.getUser().getUserId(); |
| | | Coupon coupon = couponService.getById(couponId); |
| | | couponService.receive(coupon, userId); |
| | | // 领取优惠券成功 |
| | | return ServerResponseEntity.success(I18nMessage.getMessage("yami.coupon.receive.success")); |
| | | } |
| | | |
| | | @GetMapping("/getMyCouponsStatusCount") |
| | | @Operation(summary = "获取优惠券个数" , description = "获取各个状态下的优惠券个数") |
| | | public ServerResponseEntity<Map<String, Long>> getCouponCountByStatus() { |
| | | String userId = SecurityUtils.getUser().getUserId(); |
| | | Map<String, Long> couponCount = couponService.getCouponCountByStatus(userId); |
| | | return ServerResponseEntity.success(couponCount); |
| | | } |
| | | |
| | | @GetMapping("/getCouponList") |
| | | @Operation(summary = "通过状态查看用户的优惠券列表信息" , description = "通过状态查看用户的优惠券列表信息,优惠券状态 0:已过期 1:未使用 2:使用过") |
| | | @Parameter(name = "status", description = "优惠券状态 0:失效 1:有效 2:使用过" , required = true) |
| | | public ServerResponseEntity<IPage<CouponDto>> getCouponList(PageParam<CouponDto> page, @RequestParam("status") Integer status) { |
| | | String userId = SecurityUtils.getUser().getUserId(); |
| | | IPage<CouponDto> couponDtoList = couponService.getCouponListByStatus(page, userId, status); |
| | | return ServerResponseEntity.success(couponDtoList); |
| | | } |
| | | |
| | | @Deprecated |
| | | @DeleteMapping("/deleteCoupon/{couponId}") |
| | | @Operation(summary = "删除用户优惠券" , description = "通过优惠券id删除用户优惠券") |
| | | @Parameter(name = "couponId", description = "优惠券Id" , required = true) |
| | | public ServerResponseEntity<String> deleteCoupon(@PathVariable("couponId") Long couponId) { |
| | | String userId = SecurityUtils.getUser().getUserId(); |
| | | couponService.deleteUserCouponByCouponId(userId, couponId); |
| | | // 删除成功 |
| | | return ServerResponseEntity.success(I18nMessage.getMessage("yami.delete.successfully")); |
| | | } |
| | | |
| | | @DeleteMapping("/delCoupon/{couponUserId}") |
| | | @Operation(summary = "删除用户优惠券" , description = "通过优惠券关联id删除用户优惠券") |
| | | @Parameter(name = "couponUserId", description = "优惠券关联id" , required = true) |
| | | public ServerResponseEntity<String> deleteCouponById(@PathVariable("couponUserId") Long couponUserId) { |
| | | String userId = SecurityUtils.getUser().getUserId(); |
| | | CouponUser couponUser = new CouponUser(); |
| | | couponUser.setCouponUserId(couponUserId); |
| | | couponUser.setIsDelete(1); |
| | | couponUserService.update(couponUser, new LambdaUpdateWrapper<CouponUser>() |
| | | .eq(CouponUser::getCouponUserId, couponUserId).eq(CouponUser::getUserId, userId)); |
| | | // 删除成功 |
| | | return ServerResponseEntity.success(I18nMessage.getMessage("yami.delete.successfully")); |
| | | } |
| | | |
| | | @GetMapping("/generalCouponList") |
| | | @Operation(summary = "通用券列表(平台优惠券)" , description = "获取通用券列表") |
| | | public ServerResponseEntity<List<CouponDto>> generalCouponList() { |
| | | String userId = SecurityUtils.getUser().getUserId(); |
| | | List<CouponDto> couponList = couponService.generalCouponList(userId); |
| | | return ServerResponseEntity.success(couponList); |
| | | } |
| | | |
| | | // @GetMapping("/prodCouponList") |
| | | // @Operation(summary = "商品券列表" , description = "获取商品券列表(指定商品可用优惠券)") |
| | | // public ServerResponseEntity<IPage<CouponDto>> prodCouponList(PageParam<CouponDto> page) { |
| | | // String userId = SecurityUtils.getUser().getUserId(); |
| | | // return ServerResponseEntity.success(couponService.pageProdCoupon(page, userId)); |
| | | // } |
| | | |
| | | @GetMapping("/getCouponPage") |
| | | @Operation(summary = "商品券列表(商家优惠券)" , description = "获取商品券列表(指定商品可用优惠券)") |
| | | public ServerResponseEntity<IPage<CouponDto>> getCouponList(PageParam<CouponDto> page) { |
| | | String userId = SecurityUtils.getUser().getUserId(); |
| | | IPage<CouponDto> couponDto = couponService.getCouponList(page, userId); |
| | | return ServerResponseEntity.success(couponDto); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.api.listener; |
| | | |
| | | import cn.hutool.core.collection.CollectionUtil; |
| | | import com.yami.shop.bean.app.dto.CouponOrderDto; |
| | | import com.yami.shop.bean.app.dto.ShopCartOrderDto; |
| | | import com.yami.shop.bean.app.dto.ShopCartOrderMergerDto; |
| | | import com.yami.shop.bean.event.SubmitOrderActivityEvent; |
| | | import com.yami.shop.bean.order.SubmitOrderActivityOrder; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.coupon.common.dao.CouponUserMapper; |
| | | import com.yami.shop.security.api.util.SecurityUtils; |
| | | 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.stream.Collectors; |
| | | |
| | | /** |
| | | * 确认订单信息时的优惠券的相关操作,计算优惠券 优惠金额 |
| | | * |
| | | * @author LGH |
| | | */ |
| | | @Component("checkCouponStatusListener") |
| | | @AllArgsConstructor |
| | | public class SubmitOrderActivityListener { |
| | | |
| | | private final CouponUserMapper couponUserMapper; |
| | | |
| | | /** |
| | | * 将店铺下的所有商品归属到该店铺的购物车当中 |
| | | * |
| | | * @param event#ShopCartOrderMergerDto 组装完成的商品订单信息 |
| | | * @return 是否继续组装 |
| | | */ |
| | | @EventListener(SubmitOrderActivityEvent.class) |
| | | @Order(SubmitOrderActivityOrder.COUPON) |
| | | public void checkCouponStatusListener(SubmitOrderActivityEvent event) { |
| | | String userId = SecurityUtils.getUser().getUserId(); |
| | | ShopCartOrderMergerDto shopCartOrderMergerDto = event.getShopCartOrderMergerDto(); |
| | | //店铺优惠券 |
| | | List<List<CouponOrderDto>> shopCoupons = shopCartOrderMergerDto.getShopCartOrders().stream().filter((ShopCartOrderDto shopCartOrderDto) ->CollectionUtil.isNotEmpty(shopCartOrderDto.getCoupons())).map(ShopCartOrderDto::getCoupons).collect(Collectors.toList()); |
| | | List<Long> couponUserIds = new ArrayList<>(); |
| | | if(CollectionUtil.isEmpty(shopCartOrderMergerDto.getCoupons()) && CollectionUtil.isEmpty(shopCoupons)){ |
| | | return; |
| | | } |
| | | if(CollectionUtil.isNotEmpty(shopCartOrderMergerDto.getCoupons())){ |
| | | for (CouponOrderDto coupon : shopCartOrderMergerDto.getCoupons()) { |
| | | if(coupon.isChoose()){ |
| | | couponUserIds.add(coupon.getCouponUserId()); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | if(CollectionUtil.isNotEmpty(shopCoupons)){ |
| | | for (ShopCartOrderDto shopCartOrderDto : shopCartOrderMergerDto.getShopCartOrders()) { |
| | | for (CouponOrderDto coupon : shopCartOrderDto.getCoupons()) { |
| | | if(coupon.isChoose()){ |
| | | couponUserIds.add(coupon.getCouponUserId()); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | if(CollectionUtil.isEmpty(couponUserIds)){ |
| | | return; |
| | | } |
| | | int num = couponUserMapper.countNormalByCouponUserId(couponUserIds,userId); |
| | | if(num < couponUserIds.size()){ |
| | | throw new YamiShopBindException("yami.order.coupon.expire.check"); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.api.listener; |
| | | |
| | | import com.yami.shop.coupon.common.dao.CouponUserMapper; |
| | | import com.yami.shop.coupon.common.service.CouponUseRecordService; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * 优惠券提交订单监听 |
| | | * @author lanhai |
| | | */ |
| | | @Component("couponSubmitOrderListener") |
| | | @AllArgsConstructor |
| | | public class SubmitOrderListener { |
| | | |
| | | private final CouponUserMapper couponUserMapper; |
| | | private final CouponUseRecordService couponUseRecordService; |
| | | // |
| | | // /** |
| | | // * 修改优惠券为已使用状态 |
| | | // */ |
| | | // @EventListener(SubmitOrderEvent.class) |
| | | // @Order(SubmitOrderOrder.COUPON) |
| | | // public void couponSubmitOrderListener(SubmitOrderEvent event) { |
| | | // |
| | | // //待改状态的优惠列表 |
| | | // List<Long> userCouponIds = Lists.newArrayList(); |
| | | // |
| | | // List<CouponUseRecord> couponUseRecordList = Lists.newArrayList(); |
| | | // List<ShopCartOrderDto> shopCartOrders = event.getMergerOrder().getShopCartOrders(); |
| | | // |
| | | // |
| | | // if(CollectionUtils.isEmpty(shopCartOrders)){ |
| | | // return ; |
| | | // } |
| | | // // 订单号集合 |
| | | // StringBuilder orderNumbers = new StringBuilder(100); |
| | | // |
| | | // for (ShopCartOrderDto shopCartOrder : shopCartOrders) { |
| | | // orderNumbers.append(shopCartOrder.getOrderNumber()).append(StrUtil.COMMA); |
| | | // List<CouponOrderDto> shopCartOrderCoupons = shopCartOrder.getCoupons(); |
| | | // |
| | | // if (CollectionUtils.isEmpty(shopCartOrderCoupons)) { |
| | | // continue; |
| | | // } |
| | | // // 聚合店铺优惠券 |
| | | // addCouponUseRecordList(shopCartOrderCoupons, shopCartOrder.getOrderNumber(), couponUseRecordList, userCouponIds); |
| | | // } |
| | | // orderNumbers.deleteCharAt(orderNumbers.length() - 1); |
| | | // // 聚合平台优惠券 |
| | | // addCouponUseRecordList(event.getMergerOrder().getCoupons(),orderNumbers.toString(), couponUseRecordList, userCouponIds); |
| | | // |
| | | // |
| | | // if (CollectionUtils.isNotEmpty(userCouponIds)) { |
| | | // // 批量更新用户优惠券使用状态 |
| | | // couponUserMapper.batchUpdateUserCouponStatus(2, userCouponIds); |
| | | // } |
| | | // if (CollectionUtils.isNotEmpty(couponUseRecordList)) { |
| | | // // 批量插用户优惠券使用记录 |
| | | // couponUseRecordService.addCouponUseRecode(couponUseRecordList); |
| | | // } |
| | | // |
| | | // } |
| | | // |
| | | // private void addCouponUseRecordList(List<CouponOrderDto> shopCartOrderCoupons, String orderNumber,List<CouponUseRecord> couponUseRecordList, List<Long> userCouponIds){ |
| | | // if (CollectionUtils.isEmpty(shopCartOrderCoupons)) { |
| | | // return; |
| | | // } |
| | | // |
| | | // for (CouponOrderDto couponOrderDto : shopCartOrderCoupons) { |
| | | // if (couponOrderDto.isChoose() && couponOrderDto.isCanUse()) { |
| | | // CouponUseRecord couponUseRecord = new CouponUseRecord(); |
| | | // couponUseRecord.setAmount(couponOrderDto.getReduceAmount()); |
| | | // // 获取用户优惠券id |
| | | // couponUseRecord.setCouponUserId(couponOrderDto.getCouponUserId()); |
| | | // couponUseRecord.setUserId(SecurityUtils.getUser().getUserId()); |
| | | // couponUseRecord.setOrderNumber(orderNumber); |
| | | // couponUseRecord.setUseTime(new Date()); |
| | | // //优惠券记录为冻结状态 |
| | | // couponUseRecord.setStatus(1); |
| | | // couponUseRecordList.add(couponUseRecord); |
| | | // userCouponIds.add(couponOrderDto.getCouponUserId()); |
| | | // } |
| | | // } |
| | | // } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.gz-yami.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | |
| | | package com.yami.shop.coupon.api.manager.impl; |
| | | |
| | | import cn.hutool.core.collection.CollectionUtil; |
| | | import com.yami.shop.bean.app.dto.*; |
| | | import com.yami.shop.bean.param.ChooseCouponParam; |
| | | import com.yami.shop.bean.param.PlatformChooseCouponParam; |
| | | import com.yami.shop.common.util.Arith; |
| | | import com.yami.shop.coupon.api.util.ChooseCouponHelper; |
| | | import com.yami.shop.coupon.common.service.CouponService; |
| | | import com.yami.shop.manager.CouponConfirmOrderManager; |
| | | import com.yami.shop.security.api.util.SecurityUtils; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * 确认订单信息时的优惠券的相关操作,计算优惠券 优惠金额 |
| | | * |
| | | * @author LGH |
| | | */ |
| | | @Component |
| | | @AllArgsConstructor |
| | | public class CouponConfirmOrderManagerImpl implements CouponConfirmOrderManager { |
| | | |
| | | private final CouponService couponService; |
| | | |
| | | @Override |
| | | public List<ShopCartDto> chooseShopCoupon(ChooseCouponParam param) { |
| | | String userId = SecurityUtils.getUser().getUserId(); |
| | | |
| | | List<ShopCartDto> shopCarts = param.getShopCarts(); |
| | | |
| | | for (ShopCartDto shopCart : shopCarts) { |
| | | List<ShopCartItemDiscountDto> shopCartItemDiscounts = shopCart.getShopCartItemDiscounts(); |
| | | List<ShopCartItemDto> shopCartItems = new ArrayList<>(); |
| | | for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartItemDiscounts) { |
| | | shopCartItems.addAll(shopCartItemDiscount.getShopCartItems()); |
| | | } |
| | | // 因为经过满减,实际金额的顺序已经变了 |
| | | shopCartItems = shopCartItems.stream().sorted(Comparator.comparingDouble(ShopCartItemDto::getActualTotal)).collect(Collectors.toList()); |
| | | |
| | | // 获取用户有效的优惠券 |
| | | List<CouponOrderDto> shopCoupons = couponService.getCouponListByShopIds(userId, shopCart.getShopId()); |
| | | |
| | | // 用户选中的所有优惠券 |
| | | List<Long> couponUserIds = param.getCouponUserIds(); |
| | | |
| | | Integer userChangeCoupon = param.getUserChangeCoupon(); |
| | | |
| | | ChooseCouponHelper chooseCouponHelper = new ChooseCouponHelper(shopCartItems, shopCoupons, couponUserIds, userChangeCoupon).invoke(); |
| | | |
| | | if (chooseCouponHelper.getChooseCoupon() != null) { |
| | | |
| | | double couponReduce = chooseCouponHelper.getCouponReduce(); |
| | | // 最后组装订单信息 |
| | | shopCart.setCouponReduce(Math.min(couponReduce, shopCart.getActualTotal())); |
| | | shopCart.setActualTotal(Arith.sub(shopCart.getActualTotal(), shopCart.getCouponReduce())); |
| | | shopCart.setShopReduce(Arith.add(shopCart.getShopReduce(), shopCart.getCouponReduce())); |
| | | } |
| | | |
| | | shopCart.setCoupons(shopCoupons); |
| | | } |
| | | return shopCarts; |
| | | } |
| | | |
| | | @Override |
| | | public ShopCartOrderMergerDto choosePlatformCoupon(PlatformChooseCouponParam param) { |
| | | String userId = SecurityUtils.getUser().getUserId(); |
| | | ShopCartOrderMergerDto shopCartOrderMergerVO = param.getShopCartOrderMergerDto(); |
| | | |
| | | // 获取用户可用平台优惠券 |
| | | List<CouponOrderDto> couponList = couponService.getCouponListByShopIds(userId, 0L); |
| | | if (CollectionUtil.isEmpty(couponList)) { |
| | | return shopCartOrderMergerVO; |
| | | } |
| | | |
| | | // 完整的订单信息 |
| | | // 订单项目 |
| | | List<ShopCartItemDto> shopAllShopCartItems = new ArrayList<>(); |
| | | List<ShopCartOrderDto> shopCartOrders = shopCartOrderMergerVO.getShopCartOrders(); |
| | | for (ShopCartOrderDto shopCartOrder : shopCartOrders) { |
| | | List<ShopCartItemDiscountDto> shopCartItemDiscounts = shopCartOrder.getShopCartItemDiscounts(); |
| | | for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartItemDiscounts) { |
| | | shopAllShopCartItems.addAll(shopCartItemDiscount.getShopCartItems()); |
| | | } |
| | | } |
| | | // 因为经过满减,实际金额的顺序已经变了 |
| | | shopAllShopCartItems = shopAllShopCartItems.stream().sorted(Comparator.comparingDouble(ShopCartItemDto::getActualTotal)).collect(Collectors.toList()); |
| | | |
| | | ChooseCouponHelper chooseCouponHelper = new ChooseCouponHelper(shopAllShopCartItems, couponList, param.getCouponUserIds(), param.getUserChangeCoupon()).invoke(); |
| | | |
| | | |
| | | if (chooseCouponHelper.getChooseCoupon() != null) { |
| | | double couponReduce = chooseCouponHelper.getCouponReduce(); |
| | | Map<Long, Double> shopReduceMap = chooseCouponHelper.getShopReduceMap(); |
| | | for (ShopCartOrderDto shopCartOrder : shopCartOrders) { |
| | | Double couponAmount = shopReduceMap.get(shopCartOrder.getShopId()); |
| | | shopCartOrder.setPlatformCouponReduce(couponAmount); |
| | | couponAmount = Objects.isNull(shopCartOrder.getPlatformAmount()) ? couponAmount : Arith.add(shopCartOrder.getPlatformAmount(), couponAmount); |
| | | shopCartOrder.setPlatformAmount(couponAmount); |
| | | shopCartOrder.setActualTotal(Arith.sub(shopCartOrder.getActualTotal(), shopCartOrder.getPlatformCouponReduce())); |
| | | shopCartOrder.setShopReduce(Arith.add(shopCartOrder.getShopReduce(), shopCartOrder.getPlatformCouponReduce())); |
| | | } |
| | | shopCartOrderMergerVO.setOrderReduce(Arith.add(shopCartOrderMergerVO.getOrderReduce(), couponReduce)); |
| | | shopCartOrderMergerVO.setActualTotal(Arith.sub(shopCartOrderMergerVO.getActualTotal(), couponReduce)); |
| | | } |
| | | shopCartOrderMergerVO.setCoupons(couponList); |
| | | return shopCartOrderMergerVO; |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.api.util; |
| | | |
| | | import cn.hutool.core.collection.CollectionUtil; |
| | | import com.yami.shop.bean.app.dto.CouponOrderDto; |
| | | import com.yami.shop.bean.app.dto.ProductItemDto; |
| | | import com.yami.shop.bean.app.dto.ShopCartItemDto; |
| | | import com.yami.shop.bean.enums.CouponProdType; |
| | | import com.yami.shop.bean.enums.CouponType; |
| | | import com.yami.shop.common.util.Arith; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * 协助优惠券进行选择 |
| | | * |
| | | * @author LGH |
| | | */ |
| | | public class ChooseCouponHelper { |
| | | /** |
| | | * 购物项 |
| | | */ |
| | | private List<ShopCartItemDto> shopCartItems; |
| | | /** |
| | | * 含有的优惠券列表 |
| | | */ |
| | | private final List<CouponOrderDto> shopCoupons; |
| | | |
| | | /** |
| | | * 选中的优惠券id |
| | | */ |
| | | private List<Long> couponUserIds; |
| | | |
| | | /** |
| | | * 用户是否选中优惠券 |
| | | */ |
| | | private final Integer userChangeCoupon; |
| | | /** |
| | | * 选中的优惠券 |
| | | */ |
| | | private CouponOrderDto chooseCoupon; |
| | | |
| | | /** |
| | | * 可用优惠券的商品实际金额(商品实际金额 - 商品分摊金额) |
| | | */ |
| | | private double prodCanUseCouponActualTotal; |
| | | |
| | | /** |
| | | * 优惠金额 |
| | | */ |
| | | private double couponReduce; |
| | | |
| | | /** |
| | | * 优惠金额参与的商品数量 |
| | | */ |
| | | private Integer reduceNum; |
| | | |
| | | /** |
| | | * 优惠金额 |
| | | */ |
| | | private double chooseCouponProdAmount; |
| | | |
| | | /** |
| | | * 优惠券在订单中的优惠金额 |
| | | */ |
| | | private double couponInOrderAmount; |
| | | |
| | | /** |
| | | * 优惠金额关联店铺map |
| | | */ |
| | | private final Map<Long, Double> shopReduceMap = new HashMap<>(12); |
| | | |
| | | public ChooseCouponHelper(List<ShopCartItemDto> shopCartItems, List<CouponOrderDto> shopCoupons, List<Long> couponUserIds, Integer userChangeCoupon) { |
| | | this.shopCartItems = shopCartItems; |
| | | this.shopCoupons = shopCoupons; |
| | | this.couponUserIds = couponUserIds; |
| | | this.userChangeCoupon = userChangeCoupon; |
| | | } |
| | | |
| | | public CouponOrderDto getChooseCoupon() { |
| | | return chooseCoupon; |
| | | } |
| | | |
| | | public Map<Long, Double> getShopReduceMap() { |
| | | return shopReduceMap; |
| | | } |
| | | |
| | | public double getCouponReduce() { |
| | | return this.couponReduce; |
| | | } |
| | | |
| | | public ChooseCouponHelper invoke() { |
| | | // 没有平台优惠券直接返回 |
| | | if (CollectionUtils.isEmpty(shopCartItems)) { |
| | | return this; |
| | | } |
| | | |
| | | // 用户选中的关于该店铺的优惠券,一家店只能选择一张优惠券 |
| | | chooseCoupon = null; |
| | | reduceNum = 0; |
| | | |
| | | if (Objects.isNull(couponUserIds)) { |
| | | couponUserIds = new ArrayList<>(); |
| | | } |
| | | |
| | | // 可用优惠券的商品实际金额(商品实际金额 - 商品分摊金额) |
| | | prodCanUseCouponActualTotal = 0.0; |
| | | Date now = new Date(); |
| | | CouponOrderDto firstAvailableCoupon = null; |
| | | // CouponOrderDto maxReduceChooseCoupon= null; |
| | | // Double maxChooseCouponProdAmount = 0.00; |
| | | // Double maxReduce=Double.MAX_VALUE; |
| | | for (CouponOrderDto shopCoupon : shopCoupons) { |
| | | if (shopCoupon.getStartTime().getTime() > now.getTime() || shopCoupon.getEndTime().getTime() < now.getTime()) { |
| | | continue; |
| | | } |
| | | // 该优惠券关联的商品id |
| | | List<Long> prodIds = shopCoupon.getProdIds(); |
| | | // 可用优惠券的商品实际金额(商品实际金额 - 商品分摊金额) |
| | | prodCanUseCouponActualTotal = 0.0; |
| | | for (ShopCartItemDto shopCartItem : shopCartItems) { |
| | | // 套餐不参与优惠券活动 |
| | | if (Objects.nonNull(shopCartItem.getComboId()) && shopCartItem.getComboId() != 0) { |
| | | continue; |
| | | } |
| | | shopCartItem.setIsShareReduce(0); |
| | | // 该商品是否在该优惠券可用 |
| | | boolean isCouponsProd = isCouponsProd(shopCartItem.getProdId(), prodIds, shopCoupon.getSuitableProdType()); |
| | | if (isCouponsProd) { |
| | | shopCartItem.setIsShareReduce(1); |
| | | prodCanUseCouponActualTotal = Arith.add(prodCanUseCouponActualTotal, shopCartItem.getActualTotal()); |
| | | } |
| | | } |
| | | Date date = new Date(); |
| | | // 如果该商品实际总金额大于等于优惠券最低使用金额,并且开始时间大于优惠券的使用时间,则优惠券可用 |
| | | if (prodCanUseCouponActualTotal >= shopCoupon.getCashCondition() && shopCoupon.getStartTime().getTime() < date.getTime()) { |
| | | // 将优惠券标记为可用状态 |
| | | shopCoupon.setCanUse(true); |
| | | if (Objects.nonNull(chooseCoupon)) { |
| | | continue; |
| | | } |
| | | // 折扣券的优惠金额要根据订单金额实时计算 |
| | | if (CouponType.C2D.value().equals(shopCoupon.getCouponType())) { |
| | | double reduceMoney = Arith.roundByBanker(Arith.sub(prodCanUseCouponActualTotal, Arith.div(Arith.mul(prodCanUseCouponActualTotal, |
| | | shopCoupon.getCouponDiscount()), 10)), 2); |
| | | shopCoupon.setReduceAmount(reduceMoney); |
| | | } |
| | | // 聚合 用户选中的关于该店铺的优惠券 |
| | | if (couponUserIds.contains(shopCoupon.getCouponUserId())) { |
| | | chooseCoupon = shopCoupon; |
| | | chooseCouponProdAmount = prodCanUseCouponActualTotal; |
| | | } |
| | | // 记录第一张可用优惠券 |
| | | if (firstAvailableCoupon == null) { |
| | | firstAvailableCoupon = shopCoupon; |
| | | } |
| | | // // 如果用户没有选择优惠券,系统默认选择一张优惠最大的可用优惠券 |
| | | // else if (chooseCoupon == null && !Objects.equals(userChangeCoupon, 1) && shopCoupon.getReduceAmount() < maxReduce) { |
| | | // maxReduce = shopCoupon.getReduceAmount(); |
| | | // maxReduceChooseCoupon = shopCoupon; |
| | | // maxChooseCouponProdAmount = Arith.sub(prodCanUseCouponActualTotal,maxReduce); |
| | | // } |
| | | } |
| | | } |
| | | // 没选择优惠券,默认选择第一张可用的优惠券 |
| | | if (chooseCoupon == null |
| | | && firstAvailableCoupon != null |
| | | && !Objects.equals(userChangeCoupon, 1)) { |
| | | chooseCoupon = firstAvailableCoupon; |
| | | chooseCouponProdAmount = Arith.sub(prodCanUseCouponActualTotal, chooseCoupon.getReduceAmount()); |
| | | // chooseCoupon = maxReduceChooseCoupon; |
| | | // chooseCouponProdAmount = maxChooseCouponProdAmount; |
| | | } |
| | | for (CouponOrderDto shopCoupon : shopCoupons) { |
| | | // 该优惠券关联的商品id |
| | | List<Long> prodIds = shopCoupon.getProdIds(); |
| | | if (Objects.nonNull(chooseCoupon) && !Objects.equals(shopCoupon.getCouponUserId(), chooseCoupon.getCouponUserId())) { |
| | | continue; |
| | | } |
| | | for (ShopCartItemDto shopCartItem : shopCartItems) { |
| | | if (Objects.nonNull(shopCartItem.getComboId()) && shopCartItem.getComboId() != 0) { |
| | | continue; |
| | | } |
| | | shopCartItem.setIsShareReduce(0); |
| | | // 该商品是否在该优惠券可用 |
| | | boolean isCouponsProd = isCouponsProd(shopCartItem.getProdId(), prodIds, shopCoupon.getSuitableProdType()); |
| | | if (isCouponsProd) { |
| | | shopCartItem.setIsShareReduce(1); |
| | | reduceNum++; |
| | | } |
| | | } |
| | | } |
| | | prodCanUseCouponActualTotal = chooseCouponProdAmount; |
| | | if (chooseCoupon != null) { |
| | | chooseCoupon.setChoose(true); |
| | | // 计算优惠券优惠金额 |
| | | // calculateCouponReduce(); |
| | | couponReduce = chooseCoupon.getReduceAmount(); |
| | | couponInOrderAmount = chooseCoupon.getReduceAmount(); |
| | | // 设置分摊优惠金额 |
| | | setShareReduce(); |
| | | } |
| | | return this; |
| | | } |
| | | |
| | | /** |
| | | * 判断某个商品是否在此优惠券中 |
| | | * |
| | | * @param prodId 在该店铺中的商品商品id |
| | | * @param couponProdIds 优惠券关联的商品id |
| | | * @param couponProdType 优惠券适用商品类型 |
| | | * @return 商品是否在此优惠券中 |
| | | */ |
| | | private boolean isCouponsProd(Long prodId, List<Long> couponProdIds, Integer couponProdType) { |
| | | if (CouponProdType.ALL.value().equals(couponProdType)) { |
| | | return true; |
| | | } |
| | | |
| | | if (CouponProdType.PROD_IN.value().equals(couponProdType)) { |
| | | if (CollectionUtil.isEmpty(couponProdIds)) { |
| | | return false; |
| | | } |
| | | for (Long couponProdId : couponProdIds) { |
| | | if (Objects.equals(couponProdId, prodId)) { |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | if (CouponProdType.PROD_NO_IN.value().equals(couponProdType)) { |
| | | if (CollectionUtil.isEmpty(couponProdIds)) { |
| | | return true; |
| | | } |
| | | for (Long couponProdId : couponProdIds) { |
| | | if (Objects.equals(couponProdId, prodId)) { |
| | | return false; |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | |
| | | // /** |
| | | // * 计算优惠金额 |
| | | // */ |
| | | // private void calculateCouponReduce() { |
| | | // couponReduce = 0.0; |
| | | // couponInOrderAmount = 0.0; |
| | | // // 代金券 |
| | | // if (CouponType.C2M.value().equals(chooseCoupon.getCouponType())) { |
| | | // couponInOrderAmount = chooseCoupon.getReduceAmount(); |
| | | // } |
| | | // // 折扣券 |
| | | // if (CouponType.C2D.value().equals(chooseCoupon.getCouponType())) { |
| | | // couponInOrderAmount = Arith.roundByBanker(Arith.sub(prodCanUseCouponActualTotal, Arith.div(Arith.mul(prodCanUseCouponActualTotal, |
| | | // chooseCoupon.getCouponDiscount()), 10)), 2); |
| | | // chooseCoupon.setReduceAmount(couponInOrderAmount); |
| | | // } |
| | | // couponReduce = Arith.add(couponReduce, couponInOrderAmount); |
| | | // } |
| | | |
| | | /** |
| | | * 设置分摊优惠金额 |
| | | */ |
| | | |
| | | private void setShareReduce() { |
| | | double sumReduce = 0.0; |
| | | shopCartItems = shopCartItems.stream().sorted(Comparator.comparing(ProductItemDto::getActualTotal)).collect(Collectors.toList()); |
| | | int count = 0; |
| | | for (ShopCartItemDto shopCartItem : shopCartItems) { |
| | | if (Objects.nonNull(shopCartItem.getComboId()) && shopCartItem.getComboId() != 0) { |
| | | continue; |
| | | } |
| | | double shareReduce; |
| | | if (shopCartItem.getIsShareReduce() == 1) { |
| | | // shareReduce = Arith.roundByBanker(Arith.mul(couponInOrderAmount, Arith.div(shopCartItem.getActualTotal(), prodCanUseCouponActualTotal, 10)), 2); |
| | | shareReduce = Arith.div(Arith.mul(shopCartItem.getActualTotal(), couponInOrderAmount),prodCanUseCouponActualTotal, 2); |
| | | count++; |
| | | //如果是最后一项可以参与优惠的商品,直接将剩余的优惠金额赋值给他 |
| | | if (count >= reduceNum) { |
| | | shareReduce = Math.min(Arith.sub(chooseCoupon.getReduceAmount(), sumReduce), shopCartItem.getProductTotalAmount()); |
| | | } |
| | | if (Objects.equals(chooseCoupon.getShopId(), 0L)) { |
| | | // 平台分摊的每一个购物项优惠金额 |
| | | shopCartItem.setPlatformShareReduce(Arith.add(shopCartItem.getPlatformShareReduce(), shareReduce)); |
| | | shopCartItem.setPlatformCouponAmount(shareReduce); |
| | | } else { |
| | | // 商家分摊的每一个购物项优惠金额 |
| | | shopCartItem.setShareReduce(Arith.add(shopCartItem.getShareReduce(), shareReduce)); |
| | | shopCartItem.setShopCouponAmount(shareReduce); |
| | | } |
| | | } else { |
| | | shareReduce = 0.0; |
| | | } |
| | | // 分摊的优惠金额 不能大于商品金额 |
| | | double minShareReduce = Math.min(shareReduce, shopCartItem.getProductTotalAmount()); |
| | | shopCartItem.setActualTotal(Arith.sub(shopCartItem.getActualTotal(), minShareReduce)); |
| | | // 将对应店铺优惠券优惠的金额放入map中 |
| | | if (shopReduceMap.containsKey(shopCartItem.getShopId())) { |
| | | double shopReduce = shopReduceMap.get(shopCartItem.getShopId()); |
| | | shopReduceMap.put(shopCartItem.getShopId(), Arith.add(shopReduce, minShareReduce)); |
| | | } else { |
| | | shopReduceMap.put(shopCartItem.getShopId(), minShareReduce); |
| | | } |
| | | sumReduce = Arith.add(minShareReduce, sumReduce); |
| | | } |
| | | } |
| | | } |
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-coupon</artifactId> |
| | | <groupId>com.yami.shop</groupId> |
| | | <version>0.0.1-SNAPSHOT</version> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>yami-shop-coupon-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.coupon.common.constants; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * 优惠券状态 |
| | | * @author lanhai |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum CouponStatusEnum { |
| | | /** 取消投放 */ |
| | | CANCEL(-1,"取消投放"), |
| | | |
| | | /** 自动投放 */ |
| | | AUTO_LAUNCH(0, "自动投放"), |
| | | |
| | | /** 投放 */ |
| | | PUT_ON(1, "投放"), |
| | | |
| | | /** 违规下架 */ |
| | | OFFLINE(2, "违规下架"), |
| | | |
| | | /** 等待审核 */ |
| | | WAIT_AUDIT(3, "等待审核"), |
| | | |
| | | /** 暂不投放*/ |
| | | NOT_LAUNCH(4, "暂不投放"), |
| | | ; |
| | | private int value; |
| | | private String desc; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.common.constants; |
| | | |
| | | /** |
| | | * @author FrozenWatermelon |
| | | * @date 2020/12/28 |
| | | */ |
| | | public enum UserCouponRecordStatus { |
| | | |
| | | /** |
| | | * 1:冻结 |
| | | */ |
| | | FREEZE(1), |
| | | |
| | | /** |
| | | * 使用过 |
| | | */ |
| | | USED(2), |
| | | /** |
| | | * 3:退回 |
| | | */ |
| | | REFUND(3) |
| | | ; |
| | | |
| | | private Integer value; |
| | | |
| | | public Integer getValue() { |
| | | return value; |
| | | } |
| | | |
| | | public void setValue(Integer value) { |
| | | this.value = value; |
| | | } |
| | | |
| | | UserCouponRecordStatus(Integer value) { |
| | | this.value = value; |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.common.constants; |
| | | |
| | | /** |
| | | * @author FrozenWatermelon |
| | | * @date 2020/12/28 |
| | | */ |
| | | public enum UserCouponStatus { |
| | | /** |
| | | * 0:失效 |
| | | */ |
| | | INVALID(0), |
| | | |
| | | /** |
| | | * 1:有效 |
| | | */ |
| | | EFFECTIVE(1), |
| | | |
| | | /** |
| | | * 使用过 |
| | | */ |
| | | USED(2) |
| | | ; |
| | | |
| | | private Integer value; |
| | | |
| | | public Integer getValue() { |
| | | return value; |
| | | } |
| | | |
| | | public void setValue(Integer value) { |
| | | this.value = value; |
| | | } |
| | | |
| | | UserCouponStatus(Integer value) { |
| | | this.value = value; |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.common.constants; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * 优惠券状态 |
| | | * @author lhd |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum ValidTimeTypeEnum { |
| | | |
| | | /** 固定时间 */ |
| | | FIXED(1, "固定时间"), |
| | | |
| | | /** 领取后生效 */ |
| | | RECEIVE(2, "领取后生效") |
| | | ; |
| | | private int value; |
| | | private String desc; |
| | | |
| | | public Integer value() { |
| | | return value; |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.common.dao; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.app.dto.CouponDto; |
| | | import com.yami.shop.bean.app.dto.CouponOrderDto; |
| | | import com.yami.shop.common.util.PageAdapter; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.coupon.common.model.Coupon; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 优惠券 |
| | | * |
| | | * @author lanhai |
| | | */ |
| | | public interface CouponMapper extends BaseMapper<Coupon> { |
| | | |
| | | /** |
| | | * 根据优惠券id获取优惠券的信息及可用商品信息 |
| | | * |
| | | * @param id 优惠券id |
| | | * @return 优惠券的信息及可用商品信息 |
| | | */ |
| | | Coupon getCouponAndCouponProdsByCouponId(@Param("id") Long id); |
| | | |
| | | /** |
| | | * 修改优惠券库存 |
| | | * |
| | | * @param couponId 优惠券id |
| | | * @return 结果 |
| | | */ |
| | | int updateCouponStocksAndVersion(@Param("couponId") Long couponId); |
| | | |
| | | /** |
| | | * 设置店铺的过期优惠券为过期状态 |
| | | * |
| | | * @param now 时间 |
| | | */ |
| | | void updateOverdueStatusByTime(@Param("now") Date now); |
| | | |
| | | /** |
| | | * 投放优惠券 |
| | | * |
| | | * @param now 时间 |
| | | */ |
| | | void putonCoupon(@Param("now") Date now); |
| | | |
| | | /** |
| | | * 获取通用优惠券列表 |
| | | * |
| | | * @param userId 用户id |
| | | * @return 通用优惠券列表 |
| | | */ |
| | | List<CouponDto> generalCouponList(@Param("userId") String userId); |
| | | |
| | | |
| | | /** |
| | | * 通过优惠券状态获取优惠券列表 |
| | | * |
| | | * @param page 分页 |
| | | * @param userId 用户id |
| | | * @param status 状态 |
| | | * @return 优惠券分页列表 |
| | | */ |
| | | IPage<CouponDto> getCouponListByStatus(IPage<CouponDto> page, @Param("userId") String userId, @Param("status") Integer status); |
| | | |
| | | /** |
| | | * 通过店铺id及用户id获取用户未使用的优惠券 |
| | | * |
| | | * @param userId 用户id |
| | | * @param shopId 店铺id |
| | | * @return 用户未使用的优惠券列表 |
| | | */ |
| | | List<CouponOrderDto> getCouponListByShopIds(@Param("userId") String userId, @Param("shopId") Long shopId); |
| | | |
| | | |
| | | /** |
| | | * 查询需要更新的店铺id列表 |
| | | * |
| | | * @param now 当前时间 |
| | | * @return 店铺id列表 |
| | | */ |
| | | List<Long> listOverdueStatusShopIds(@Param("now") Date now); |
| | | |
| | | /** |
| | | * 获取某店铺所有的投放优惠券和优惠商品列表 |
| | | * |
| | | * @param shopId 店铺id |
| | | * @return 优惠券列表 |
| | | */ |
| | | List<Coupon> listPutonCouponAndCouponProdsByShopId(@Param("shopId") Long shopId); |
| | | |
| | | /** |
| | | * 获取用户的优惠券信息 |
| | | * |
| | | * @param userId 用户id |
| | | * @return 优惠券列表 |
| | | */ |
| | | List<CouponDto> listCouponIdsByUserId(@Param("userId") String userId); |
| | | |
| | | /** |
| | | * 获取用户各个状态下的优惠券个数 |
| | | * |
| | | * @param userId 用户id |
| | | * @return 用户各个状态下的优惠券个数 |
| | | */ |
| | | Map<String, Long> getCouponCountByStatus(@Param("userId") String userId); |
| | | |
| | | /** |
| | | * 平台 -- 分页获取优惠券数据 |
| | | * |
| | | * @param page 分页 |
| | | * @param coupon 优惠券 |
| | | * @return 分页优惠券数据 |
| | | */ |
| | | IPage<Coupon> getPlatformPage(@Param("page") PageParam<Coupon> page, @Param("coupon") Coupon coupon); |
| | | |
| | | /** |
| | | * 商家端--分页获取优惠券数据 |
| | | * |
| | | * @param page 分页参数 |
| | | * @param coupon 优惠券 |
| | | * @return 优惠券数据 |
| | | */ |
| | | IPage<Coupon> getMultiShopPage(@Param("page") PageParam<Coupon> page, @Param("coupon") Coupon coupon); |
| | | |
| | | /** |
| | | * 根据优惠券id获取其领取次数 |
| | | * |
| | | * @param couponId 优惠券id |
| | | * @param shopId 店铺id |
| | | * @return 领取次数 |
| | | */ |
| | | Integer countTakeNum(@Param("couponId") Long couponId, @Param("shopId") Long shopId); |
| | | |
| | | /** |
| | | * 根据优惠券id获取其使用次数 |
| | | * |
| | | * @param couponId 优惠券id |
| | | * @return 使用次数 |
| | | */ |
| | | Integer countUseNum(@Param("couponId") Long couponId); |
| | | |
| | | /** |
| | | * 更新投放状态 |
| | | * |
| | | * @param couponId 优惠券id |
| | | * @param status 更新的状态 |
| | | * @return 结果 |
| | | */ |
| | | int updatePutOnStatusByCouponId(@Param("couponId") Long couponId, @Param("status") int status); |
| | | |
| | | /** |
| | | * 更新投放状态 |
| | | * |
| | | * @param couponId 优惠券id |
| | | * @param overdueStatus 投放状态 |
| | | * @return 结果 |
| | | */ |
| | | int updateOverdueStatusByCouponId(@Param("couponId") Long couponId, @Param("overdueStatus") int overdueStatus); |
| | | |
| | | /** |
| | | * 根据优惠券适用类型,获取优惠券列表 |
| | | * |
| | | * @param couponIds 用户id |
| | | * @param lang 语言 |
| | | * @return 优惠券列表 |
| | | */ |
| | | List<CouponDto> getCouponList(@Param("couponIds") List<Long> couponIds, @Param("lang") Integer lang); |
| | | |
| | | /** |
| | | * 根据优惠券适用类型,获取优惠券列表 |
| | | * |
| | | * @param couponForAllProd 适用于所有商品列表 |
| | | * @param couponForProd 适用于部分商品列表 |
| | | * @param couponForElseProd 不适用于那些商品列表 |
| | | * @return 优惠券列表 |
| | | */ |
| | | List<CouponDto> getCouponListTourist(@Param("couponForAllProd") List<CouponDto> couponForAllProd, @Param("couponForProd") List<Long> couponForProd, |
| | | @Param("couponForElseProd") List<CouponDto> couponForElseProd); |
| | | |
| | | /** |
| | | * 获取店铺可领取优惠券id列表 |
| | | * |
| | | * @param pageAdapter 分页信息 |
| | | * @return 优惠券列表 |
| | | */ |
| | | List<Long> getShopAvailableCouponIds(@Param("adapter") PageAdapter pageAdapter); |
| | | |
| | | /** |
| | | * 获取优惠券数量 |
| | | * |
| | | * @return 优惠券数量 |
| | | */ |
| | | long countCouponPageByCouponDto(); |
| | | |
| | | /** |
| | | * 游客状态查询通用优惠券列表 |
| | | * |
| | | * @return 通用优惠券列表 |
| | | */ |
| | | List<CouponDto> generalCouponListTourist(); |
| | | |
| | | /** |
| | | * 更新优惠券 |
| | | * @param coupon |
| | | */ |
| | | void updateCoupon(@Param("coupon") Coupon coupon); |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.common.dao; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.yami.shop.coupon.common.model.CouponProd; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | | import java.util.List; |
| | | /** |
| | | * 优惠券商品信息 |
| | | * @author lanhai |
| | | */ |
| | | public interface CouponProdMapper extends BaseMapper<CouponProd> { |
| | | |
| | | /** |
| | | * 删除优惠券关联 |
| | | * @param couponId 优惠券id |
| | | */ |
| | | void deleteCouponProdsByCouponId(@Param("couponId") Long couponId); |
| | | |
| | | /** |
| | | * 新增优惠券关联 |
| | | * @param couponId 优惠券id |
| | | * @param prodIds 商品ids |
| | | */ |
| | | void insertCouponProdsBatch(@Param("couponId") Long couponId, @Param("prodIds") List<Long> prodIds); |
| | | |
| | | /** |
| | | * 根据优惠券ids删除优惠券关联 |
| | | * @param couponIds 优惠券ids |
| | | */ |
| | | void deleteCouponProdsByCouponIds(List<String> couponIds); |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.common.dao; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.yami.shop.coupon.common.model.CouponUseRecord; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 优惠券使用记录 |
| | | * |
| | | * @author yami code generator |
| | | * @date 2019-05-15 09:04:57 |
| | | */ |
| | | public interface CouponUseRecordMapper extends BaseMapper<CouponUseRecord> { |
| | | |
| | | /** |
| | | * 批量插入用户优惠券使用记录 |
| | | * |
| | | * @param couponUseRecordsList 用户优惠券使用记录集合 |
| | | */ |
| | | void addCouponUseRecode(@Param("couponUseRecordsList") List<CouponUseRecord> couponUseRecordsList); |
| | | |
| | | /** |
| | | * 批量更新商家券、平台券 |
| | | * |
| | | * @param status 状态 |
| | | * @param orderNumberList 订单编号list |
| | | */ |
| | | void batchUpdateRecordByStatusAndOrderNums(@Param("status") int status, @Param("orderNumberList") List<String> orderNumberList); |
| | | |
| | | /** |
| | | * 获取订单中使用的优惠券 |
| | | * |
| | | * @param orderNumber 订单编号 |
| | | * @return |
| | | */ |
| | | List<CouponUseRecord> listByOrderNumber(@Param("orderNumber") String orderNumber); |
| | | |
| | | /** |
| | | * 获取全部订单号字符串 |
| | | * @param orderNumber |
| | | * @return |
| | | */ |
| | | List<CouponUseRecord> getOrderNumberContact(@Param("orderNumber") String orderNumber); |
| | | |
| | | /** |
| | | * 根据id, 批量更新商家券、平台券 |
| | | * |
| | | * @param status |
| | | * @param ids |
| | | */ |
| | | void batchUpdateRecordStatusByStatusAndIds(@Param("status") int status, @Param("ids") List<Long> ids); |
| | | |
| | | /** |
| | | * 获取需要解锁的、用户所领取的优惠券 |
| | | * |
| | | * @param orderNumber 订单id |
| | | * @return 用户所领取的优惠券id |
| | | */ |
| | | List<Long> listCouponUserIdsByOrderNumber(@Param("orderNumber") String orderNumber); |
| | | |
| | | /** |
| | | * 将锁定状态标记为已解锁 |
| | | * |
| | | * @param couponUserIds 用户所领取的优惠券id |
| | | * @return |
| | | */ |
| | | int unLockByIds(@Param("couponUserIds") List<Long> couponUserIds); |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.common.dao; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.yami.shop.bean.param.*; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.coupon.common.model.CouponUser; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 优惠券商品信息 |
| | | * |
| | | * @author lanhai |
| | | */ |
| | | public interface CouponUserMapper extends BaseMapper<CouponUser> { |
| | | |
| | | /** |
| | | * 获取用户优惠券信息 |
| | | * |
| | | * @param userId 用户id |
| | | * @return 用户优惠券信息 |
| | | */ |
| | | List<CouponUser> getCouponAndCouponUserByUserId(@Param("userId") String userId); |
| | | |
| | | /** |
| | | * 通过关联ids获取用户优惠券信息 |
| | | * |
| | | * @param couponUserIds 用户优惠券ids |
| | | * @return 用户优惠券信息 |
| | | */ |
| | | List<CouponUser> getCouponAndCouponUserByCouponUserIds(@Param("couponUserIds") List<Long> couponUserIds); |
| | | |
| | | /** |
| | | * 删除用户失效半年以上的优惠券 |
| | | * |
| | | * @param date 时间 |
| | | */ |
| | | void deleteUnValidTimeCoupons(@Param("date") Date date); |
| | | |
| | | /** |
| | | * 设置用户的过期优惠券为失效状态 |
| | | * |
| | | * @param now 时间 |
| | | */ |
| | | void updateStatusByTime(@Param("now") Date now); |
| | | |
| | | /** |
| | | * 删除用户优惠关联信息 |
| | | * |
| | | * @param userId 用户id |
| | | * @param couponId 优惠券id |
| | | */ |
| | | void deleteUserCoupon(@Param("userId") String userId, @Param("couponId") Long couponId); |
| | | |
| | | /** |
| | | * 修改用户优惠券状态 |
| | | * |
| | | * @param status 状态 |
| | | * @param couponUserId 优惠券用户id |
| | | */ |
| | | void updateUseStatusByCouponUserId(@Param("status") Integer status, @Param("couponUserId") Long couponUserId); |
| | | |
| | | /** |
| | | * 批量修改用户优惠券状态 |
| | | * |
| | | * @param status 状态 |
| | | * @param couponUserIds 优惠券用户ids |
| | | */ |
| | | void batchUpdateUserCouponStatus(@Param("status") int status, @Param("couponUserIds") List<Long> couponUserIds); |
| | | |
| | | /** |
| | | * 批量修改用户优惠券状态通过订单编号 |
| | | * |
| | | * @param status 状态 |
| | | * @param orderNumber 订单编号 |
| | | */ |
| | | void updateStatusByOrderNumber(@Param("status") int status, @Param("orderNumber") String orderNumber); |
| | | |
| | | /** |
| | | * 根据日期判断用户优惠券详情 |
| | | * |
| | | * @param page |
| | | * @param param 日期 |
| | | * @return 优惠券详情 |
| | | */ |
| | | Page<CouponAnalysisParam> getCouponAnalysisParamByDate(Page page, @Param("param") ProdEffectParam param); |
| | | |
| | | /** |
| | | * 根据日期获取优惠券使用次数 |
| | | * |
| | | * @param couponId 优惠券id |
| | | * @param param |
| | | * @return 使用次数 |
| | | */ |
| | | Integer countUseNum(@Param("couponId") Long couponId, @Param("param") ProdEffectParam param); |
| | | |
| | | /** |
| | | * 获取用户优惠券领取次数 |
| | | * |
| | | * @param couponId 优惠券id |
| | | * @param status 状态 |
| | | * @param param 参数 |
| | | * @return 领取次数 |
| | | */ |
| | | Integer countTakeNum(@Param("couponId") Long couponId, @Param("status") Integer status, @Param("param") ProdEffectParam param); |
| | | |
| | | /** |
| | | * 领券会员数 |
| | | * |
| | | * @param param 相关条件参数 |
| | | * @return 领券会员数 |
| | | */ |
| | | Integer countMemberGetCoupon(@Param("param") CustomerReqParam param); |
| | | |
| | | /** |
| | | * 领券会员数 |
| | | * |
| | | * @param param 会员类型参数 |
| | | * @return 领券会员数 |
| | | */ |
| | | Integer countMemberCouponByParam(@Param("param") MemberReqParam param); |
| | | |
| | | /** |
| | | * 用户未使用的并且是未过期的优惠券数量 |
| | | * |
| | | * @param userId 用户id |
| | | * @param date 时间 |
| | | * @return 优惠券数量 |
| | | */ |
| | | Integer countCouponUsableNums(@Param("userId") String userId, @Param("date") Date date); |
| | | |
| | | /** |
| | | * 用户已使用的优惠券数量 |
| | | * |
| | | * @param userId 用户id |
| | | * @return 优惠券数量 |
| | | */ |
| | | Integer countCouponUsedNums(@Param("userId") String userId); |
| | | |
| | | /** |
| | | * 用户已失效的优惠券 |
| | | * |
| | | * @param userId 用户id |
| | | * @return 优惠券数量 |
| | | */ |
| | | Integer countCouponExpiredNums(@Param("userId") String userId); |
| | | |
| | | /** |
| | | * 获取某个用户的优惠券明细 |
| | | * |
| | | * @param page 分页信息 |
| | | * @param userId 用户id |
| | | * @param status 状态 |
| | | * @return 分页优惠券明细 |
| | | */ |
| | | IPage<CouponUser> getPageByUserId(PageParam<CouponUser> page, @Param("userId") String userId, @Param("status") Integer status); |
| | | |
| | | /** |
| | | * 根据id获取用户正常优惠券的数量 |
| | | * |
| | | * @param couponUserIds 选择的优惠券 |
| | | * @param userId 用户id |
| | | * @return 用户正常优惠券的数量 |
| | | */ |
| | | int countNormalByCouponUserId(@Param("couponUserIds") List<Long> couponUserIds, @Param("userId") String userId); |
| | | |
| | | /** |
| | | * 获取用户领取的优惠券及数量 |
| | | * @param couponIds |
| | | * @param userId |
| | | * @return |
| | | */ |
| | | List<CouponUser> listByCouponIdsAndUserId(@Param("couponIds") List<Long> couponIds, @Param("userId") String userId); |
| | | |
| | | /** |
| | | * 商家端获取优惠券各种状态和数量 |
| | | * @param userId |
| | | * @param shopId |
| | | * @return |
| | | */ |
| | | CouponUserParam getCouponCountInfo(@Param("userId") String userId, @Param("shopId") Long shopId); |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.common.dto; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author FrozenWatermelon |
| | | * @date 2020/12/23 |
| | | */ |
| | | @Data |
| | | public class CouponRecordDTO { |
| | | |
| | | /** |
| | | * 订单id |
| | | */ |
| | | private String orderNumbers; |
| | | |
| | | /** |
| | | * 优惠券id |
| | | */ |
| | | private Long couponId; |
| | | |
| | | /** |
| | | * 用户优惠券id |
| | | */ |
| | | private Long couponUserId; |
| | | |
| | | /** |
| | | * 优惠金额 |
| | | */ |
| | | private Double reduceAmount; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.common.listener; |
| | | |
| | | |
| | | import com.yami.shop.bean.event.CancelOrderEvent; |
| | | import com.yami.shop.bean.order.CancelOrderOrder; |
| | | import com.yami.shop.coupon.common.service.CouponUseRecordService; |
| | | import com.yami.shop.coupon.common.service.CouponUserService; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.context.event.EventListener; |
| | | import org.springframework.core.annotation.Order; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * 取消订单事件 |
| | | * @author lanhai |
| | | */ |
| | | @Component("couponCancelOrderListener") |
| | | @AllArgsConstructor |
| | | public class CancelOrderListener { |
| | | |
| | | // final private CouponUseRecordService couponUseRecordService; |
| | | final private CouponUserService couponUserService; |
| | | |
| | | @EventListener(CancelOrderEvent.class) |
| | | @Order(CancelOrderOrder.COUPON) |
| | | public void couponCancelOrderEvent(CancelOrderEvent event) { |
| | | // 将优惠券状态改为可用状态并删除优惠券记录 |
| | | String userId = event.getOrder().getUserId(); |
| | | String orderNumber = event.getOrder().getOrderNumber(); |
| | | couponUserService.cancelOrder(userId, orderNumber); |
| | | // couponUseRecordService.unlockCoupon(event.getOrder()); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.common.listener; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.yami.shop.bean.dto.OrderRefundDto; |
| | | import com.yami.shop.bean.enums.RefundStatusEnum; |
| | | import com.yami.shop.bean.event.OrderRefundSuccessEvent; |
| | | import com.yami.shop.bean.model.Order; |
| | | import com.yami.shop.coupon.common.dao.CouponUseRecordMapper; |
| | | import com.yami.shop.coupon.common.model.CouponUseRecord; |
| | | import com.yami.shop.coupon.common.model.CouponUser; |
| | | import com.yami.shop.coupon.common.service.CouponUserService; |
| | | import com.yami.shop.service.OrderService; |
| | | import lombok.AllArgsConstructor; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.springframework.context.event.EventListener; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * 退款订单监听 |
| | | * @author lhd |
| | | */ |
| | | @Component("couponOrderRefundListener") |
| | | @AllArgsConstructor |
| | | public class OrderRefundListener { |
| | | |
| | | private final OrderService orderService; |
| | | private final CouponUseRecordMapper couponUseRecordMapper; |
| | | private final CouponUserService couponUserService; |
| | | |
| | | |
| | | /** |
| | | * 退还用户此笔退款订单使用的优惠券 |
| | | */ |
| | | @EventListener(OrderRefundSuccessEvent.class) |
| | | public void conponOrderRefundSuccessEvent(OrderRefundSuccessEvent event) { |
| | | OrderRefundDto orderRefundDto = event.getOrderRefundDto(); |
| | | //获取退款的所有订单项 |
| | | if (CollectionUtils.isEmpty(orderRefundDto.getOrderItems())) { |
| | | return; |
| | | } |
| | | Order order = orderService.getOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderNumber, orderRefundDto.getOrderNumber())); |
| | | // 不是整单退款,不需要退优惠券 |
| | | if (!Objects.equals(order.getRefundStatus(), RefundStatusEnum.SUCCEED.value())) { |
| | | return; |
| | | } |
| | | String orderNumber = order.getOrderNumber(); |
| | | List<CouponUseRecord> records = couponUseRecordMapper.getOrderNumberContact(orderNumber); |
| | | List<CouponUseRecord> list = handlerCouponRecords(records, orderNumber); |
| | | // 订单没有使用优惠券,不需要处理 |
| | | if (CollUtil.isEmpty(list)) { |
| | | return; |
| | | } |
| | | long currentTime = System.currentTimeMillis(); |
| | | List<CouponUser> couponUsers = new ArrayList<>(); |
| | | List<Long> ids = new ArrayList<>(); |
| | | for (CouponUseRecord couponUseRecord : list) { |
| | | CouponUser couponUser = couponUseRecord.getCouponUser(); |
| | | // 已过有效时间、违规下架或已过期的优惠券, 不退还 |
| | | boolean notHandle = currentTime >= couponUser.getUserEndTime().getTime() || couponUser.getCoupon().getPutonStatus() > 1 || Objects.equals(couponUser.getCoupon().getOverdueStatus(), 0); |
| | | if (notHandle) { |
| | | continue; |
| | | } |
| | | couponUseRecord.setStatus(3); |
| | | ids.add(couponUseRecord.getCouponUseRecordId()); |
| | | couponUseRecord.getCouponUser().setStatus(1); |
| | | couponUsers.add(couponUseRecord.getCouponUser()); |
| | | } |
| | | couponUseRecordMapper.batchUpdateRecordStatusByStatusAndIds(3, ids); |
| | | couponUserService.updateBatchById(couponUsers); |
| | | } |
| | | |
| | | private List<CouponUseRecord> handlerCouponRecords(List<CouponUseRecord> records, String orderNumber) { |
| | | if (CollUtil.isEmpty(records)) { |
| | | return new ArrayList<>(); |
| | | } |
| | | Set<CouponUseRecord> resList = new HashSet<>(); |
| | | for (CouponUseRecord record : records) { |
| | | String dbOrderNumber = record.getOrderNumber(); |
| | | String[] orderNums = dbOrderNumber.split(","); |
| | | //查看除当前订单号之外的其他订单是否已经退款完成 |
| | | boolean flag = true; |
| | | if (orderNums.length > 1) { |
| | | for (String orderNum : orderNums) { |
| | | if (!orderNum.equals(orderNumber)) { |
| | | Order order = orderService.getOrderByOrderNumber(orderNum); |
| | | boolean isRefundSuccess = Objects.nonNull(order.getRefundStatus()) && Objects.equals(order.getRefundStatus(),2); |
| | | if (!isRefundSuccess) { |
| | | flag = false; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | List<CouponUseRecord> couponUseRecords; |
| | | if (flag) { |
| | | // 单个或多个订单均退款成功 |
| | | couponUseRecords = couponUseRecordMapper.listByOrderNumber(dbOrderNumber); |
| | | } else { |
| | | //有订单没有退款完成就只查当前订单自己的优惠券记录 |
| | | couponUseRecords = couponUseRecordMapper.listByOrderNumber(orderNumber); |
| | | } |
| | | resList.addAll(couponUseRecords); |
| | | } |
| | | return new ArrayList<>(resList); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.common.listener; |
| | | |
| | | import com.google.common.collect.Lists; |
| | | import com.yami.shop.bean.event.BatchBindCouponEvent; |
| | | import com.yami.shop.bean.event.PaySuccessOrderEvent; |
| | | import com.yami.shop.bean.order.PaySuccessOrderOrder; |
| | | import com.yami.shop.common.config.Constant; |
| | | import com.yami.shop.coupon.common.constants.UserCouponRecordStatus; |
| | | import com.yami.shop.coupon.common.service.CouponService; |
| | | import com.yami.shop.coupon.common.service.CouponUseRecordService; |
| | | import com.yami.shop.coupon.common.service.CouponUserService; |
| | | import lombok.AllArgsConstructor; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | 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 lanhai |
| | | */ |
| | | @Component("couponPaySuccessListener") |
| | | @AllArgsConstructor |
| | | public class PaySuccessOrderListener { |
| | | |
| | | private final CouponUseRecordService couponUseRecordService; |
| | | private final CouponService couponService; |
| | | private final CouponUserService couponUserService; |
| | | |
| | | /** |
| | | * 更新优惠券使用记录状态 |
| | | */ |
| | | @EventListener(PaySuccessOrderEvent.class) |
| | | @Order(PaySuccessOrderOrder.COUPON) |
| | | public void couponPaySuccessListener(PaySuccessOrderEvent event) { |
| | | if(Objects.equals(event.getOrders().get(0).getShopId(),Constant.PLATFORM_SHOP_ID)){ |
| | | return; |
| | | } |
| | | List<String> orderNumberList = Lists.newArrayList(); |
| | | List<com.yami.shop.bean.model.Order> orders = event.getOrders(); |
| | | |
| | | for (com.yami.shop.bean.model.Order order : orders) { |
| | | orderNumberList.add(order.getOrderNumber()); |
| | | } |
| | | if (CollectionUtils.isNotEmpty(orderNumberList)) { |
| | | couponUseRecordService.batchUpdateRecordByStatusAndOrderNums(UserCouponRecordStatus.USED.getValue(), orderNumberList); |
| | | } |
| | | |
| | | } |
| | | /** |
| | | * 批量绑定优惠券,如果已达上限等领取不了的情况直接退出。 |
| | | */ |
| | | @EventListener(BatchBindCouponEvent.class) |
| | | public void batchBindCouponEventListener(BatchBindCouponEvent event) { |
| | | couponService.batchBindCouponByIds(event.getCouponIds(),event.getUserId(),event.getShopId()); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.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 java.io.Serializable; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 优惠券 |
| | | * @author lanhai |
| | | */ |
| | | @Data |
| | | @TableName("tz_coupon") |
| | | @Schema(description = "优惠券") |
| | | public class Coupon implements Serializable { |
| | | private static final long serialVersionUID = 8018312153820119913L; |
| | | |
| | | @TableId |
| | | @Schema(description = "优惠券id" ) |
| | | private Long couponId; |
| | | |
| | | @Schema(description = "店铺ID" ) |
| | | private Long shopId; |
| | | |
| | | @Schema(description = "优惠券名称" ) |
| | | private String couponName; |
| | | |
| | | @Schema(description = "副标题" ) |
| | | private String subTitle; |
| | | |
| | | @Schema(description = "优惠类型 1:代金券 2:折扣券 3:兑换券" ) |
| | | private Integer couponType; |
| | | |
| | | @Schema(description = "使用条件" ) |
| | | private Double cashCondition; |
| | | |
| | | @Schema(description = "减免金额" ) |
| | | private Double reduceAmount; |
| | | |
| | | @Schema(description = "折扣额度" ) |
| | | private Double couponDiscount; |
| | | |
| | | @Schema(description = "生效类型 1:固定时间 2:领取后生效" ) |
| | | private Integer validTimeType; |
| | | |
| | | @Schema(description = "投放时间" ) |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private Date launchTime; |
| | | |
| | | @Schema(description = "开始时间" ) |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private Date startTime; |
| | | |
| | | @Schema(description = "结束时间" ) |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private Date endTime; |
| | | |
| | | @Schema(description = "领券后X天起生效" ) |
| | | private Integer afterReceiveDays; |
| | | |
| | | @Schema(description = "有效天数" ) |
| | | private Integer validDays; |
| | | |
| | | @Schema(description = "库存" ) |
| | | private Integer stocks; |
| | | |
| | | @Schema(description = "原始库存" ) |
| | | private Integer sourceStock; |
| | | |
| | | @Schema(description = "适用商品类型 0全部商品参与 1指定商品参与 2指定商品不参与" ) |
| | | private Integer suitableProdType; |
| | | |
| | | @Schema(description = "每个用户领券上限,如不填则默认为1" ) |
| | | private Integer limitNum; |
| | | |
| | | @Schema(description = "版本号" ) |
| | | private Integer version; |
| | | |
| | | @Schema(description = "是否积分优惠券 0不是 1是" ) |
| | | private Integer isScoreType; |
| | | |
| | | @Schema(description = "积分价格" ) |
| | | private Integer scorePrice; |
| | | |
| | | @Schema(description = "优惠券过期状态 0:过期 1:未过期" ) |
| | | private Integer overdueStatus; |
| | | |
| | | @Schema(description = "优惠券投放状态 0:未投放 1:投放 -1取消投放" ) |
| | | private Integer putonStatus; |
| | | |
| | | @Schema(description = "优惠商品" ) |
| | | @TableField(exist = false) |
| | | private List<CouponProd> couponProds; |
| | | |
| | | @Schema(description = "优惠券所在的店铺" ) |
| | | @TableField(exist = false) |
| | | private String shopName; |
| | | |
| | | @Schema(description = "获取方式 0=客户领取 1=平台发放" ) |
| | | private Integer getWay = 0; |
| | | |
| | | @Schema(description = "优惠券领取次数" ) |
| | | @TableField(exist = false) |
| | | private Integer takeNum = 0; |
| | | |
| | | @Schema(description = "优惠券微商城使用次数" ) |
| | | @TableField(exist = false) |
| | | private Integer useNum = 0; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.common.model; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | 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 java.io.Serializable; |
| | | |
| | | /** |
| | | * 优惠券商品信息 |
| | | * @author lanhai |
| | | */ |
| | | @Data |
| | | @TableName("tz_coupon_prod") |
| | | public class CouponProd implements Serializable { |
| | | |
| | | @TableId |
| | | @Schema(description = "优惠券商品ID" ) |
| | | private Long couponProdId; |
| | | |
| | | @Schema(description = "优惠券ID" ) |
| | | private Long couponId; |
| | | |
| | | @Schema(description = "商品ID" ) |
| | | private Long prodId; |
| | | |
| | | @Schema(description = "商品名称" ) |
| | | @TableField(exist=false) |
| | | private String prodName; |
| | | |
| | | @Schema(description = "商品主图" ) |
| | | @TableField(exist=false) |
| | | @JsonSerialize(using = ImgJsonSerializer.class) |
| | | private String pic; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.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 java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * 优惠券使用记录 |
| | | * |
| | | * @author yami code generator |
| | | * @date 2019-05-15 09:04:57 |
| | | */ |
| | | @Data |
| | | @TableName("tz_coupon_use_record") |
| | | public class CouponUseRecord implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * 优惠券使用id |
| | | */ |
| | | @TableId |
| | | private Long couponUseRecordId; |
| | | @Schema(description = "创建时间" ) |
| | | private Date createTime; |
| | | @Schema(description = "更新时间" ) |
| | | private Date updateTime; |
| | | /** |
| | | * 用户优惠券id |
| | | */ |
| | | private Long couponUserId; |
| | | |
| | | /** |
| | | * 用户id |
| | | */ |
| | | private String userId; |
| | | /** |
| | | * 订单编码 |
| | | */ |
| | | private String orderNumber; |
| | | /** |
| | | * 金额 |
| | | */ |
| | | private Double amount; |
| | | /** |
| | | * 使用时间 |
| | | */ |
| | | private Date useTime; |
| | | |
| | | /** |
| | | * 使用状态(1:冻结 2:已使用 3:已退还) |
| | | */ |
| | | private Integer status; |
| | | |
| | | /** |
| | | * 用户领取优惠券 |
| | | */ |
| | | @TableField(exist = false) |
| | | private CouponUser couponUser; |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.common.model; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.Data; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * 优惠券商品信息 |
| | | * @author lanhai |
| | | */ |
| | | @Data |
| | | @TableName("tz_coupon_user") |
| | | public class CouponUser implements Serializable { |
| | | private static final long serialVersionUID = 129965893236674626L; |
| | | /** |
| | | * 优惠券用户ID |
| | | */ |
| | | @TableId |
| | | private Long couponUserId; |
| | | |
| | | /** |
| | | * 优惠券ID |
| | | */ |
| | | private Long couponId; |
| | | |
| | | /** |
| | | * 用户ID |
| | | */ |
| | | private String userId; |
| | | |
| | | /** |
| | | * 领券时间 |
| | | */ |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private Date receiveTime; |
| | | |
| | | /** |
| | | * 优惠券状态 0:失效 1:有效 2:使用过 |
| | | */ |
| | | private Integer status; |
| | | |
| | | /** |
| | | * 开始时间 |
| | | */ |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private Date userStartTime; |
| | | |
| | | /** |
| | | * 结束时间 |
| | | */ |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private Date userEndTime; |
| | | |
| | | /** |
| | | * 是否删除 |
| | | */ |
| | | private Integer isDelete; |
| | | |
| | | /** |
| | | * 优惠券 |
| | | */ |
| | | @TableField(exist = false) |
| | | private Coupon coupon; |
| | | |
| | | /** |
| | | * 优惠券使用记录id |
| | | */ |
| | | @TableField(exist = false) |
| | | private Long couponUseRecordId; |
| | | |
| | | /** |
| | | * 用户领取的优惠券数量 |
| | | */ |
| | | @TableField(exist = false) |
| | | private Integer curUserReceiveCount; |
| | | } |
New file |
| | |
| | | package com.yami.shop.coupon.common.param; |
| | | |
| | | import com.yami.shop.bean.param.SendUserCouponsParam; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 批量发放优惠券给会员 |
| | | * @author TRACK |
| | | */ |
| | | @Data |
| | | public class UserCouponParam { |
| | | |
| | | @Schema(description = "用户id列表") |
| | | private List<String> userIds; |
| | | |
| | | @Schema(description = "发放优惠券列表") |
| | | private List<SendUserCouponsParam> coupons; |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.common.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.yami.shop.coupon.common.model.CouponProd; |
| | | |
| | | /** |
| | | * |
| | | * @author lgh on 2018/12/27. |
| | | */ |
| | | public interface CouponProdService extends IService<CouponProd> { |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.common.service; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.yami.shop.bean.app.dto.CouponDto; |
| | | import com.yami.shop.bean.app.dto.CouponOrderDto; |
| | | import com.yami.shop.bean.app.dto.ProductDto; |
| | | import com.yami.shop.bean.param.OfflineHandleEventAuditParam; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.coupon.common.model.Coupon; |
| | | import com.yami.shop.coupon.common.model.CouponUser; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * @author lgh on 2018/12/27. |
| | | */ |
| | | public interface CouponService extends IService<Coupon> { |
| | | |
| | | /** |
| | | * 修改优惠券关联商品信息 |
| | | * @param coupon 优惠券信息 |
| | | */ |
| | | void updateCouponAndCouponProds(@Valid Coupon coupon); |
| | | |
| | | /** |
| | | * 插入优惠券关联商品信息 |
| | | * @param coupon 优惠券信息 |
| | | */ |
| | | void insertCouponAndCouponProds(@Valid Coupon coupon); |
| | | |
| | | /** |
| | | * 获取优惠券关联商品信息 |
| | | * @param id 优惠券id |
| | | * @return |
| | | */ |
| | | Coupon getCouponAndCouponProdsByCouponId(Long id); |
| | | |
| | | /** |
| | | * 根据用户id发放优惠券 |
| | | * @param coupon 优惠券信息 |
| | | * @param userId 用户id |
| | | */ |
| | | void receive(Coupon coupon, String userId); |
| | | |
| | | /** |
| | | * 定时任务,改变店铺优惠券的状态 |
| | | * |
| | | * @param now 时间 |
| | | */ |
| | | void changeCoupon(Date now); |
| | | |
| | | /** |
| | | * 投放优惠券 |
| | | * @param now 时间 |
| | | */ |
| | | void putonCoupon(Date now); |
| | | |
| | | /** |
| | | * 删除优惠券 |
| | | * @param couponId 优惠券id |
| | | */ |
| | | void deleteByCouponId(Long couponId); |
| | | |
| | | /** |
| | | * 获取通用券列表 |
| | | * @param userId 用户id |
| | | * @return 通用券列表 |
| | | */ |
| | | List<CouponDto> generalCouponList(String userId); |
| | | |
| | | /** |
| | | * 游客状态查询所有通用优惠券列表 |
| | | * @return 通用优惠券列表 |
| | | */ |
| | | List<CouponDto> generalCouponList(); |
| | | |
| | | /** |
| | | * 通过状态查看用户的优惠券列表信息 |
| | | * @param page 分页信息 |
| | | * @param userId 用户id |
| | | * @param status 状态 |
| | | * @return 用户的优惠券列表信息 |
| | | */ |
| | | IPage<CouponDto> getCouponListByStatus(IPage<CouponDto> page, String userId, Integer status); |
| | | |
| | | /** |
| | | * 通过优惠券id删除用户优惠券 |
| | | * @param userId 用户id |
| | | * @param couponId 优惠券id |
| | | */ |
| | | void deleteUserCouponByCouponId(String userId, Long couponId); |
| | | |
| | | /** |
| | | * 获取用户有效的优惠券 |
| | | * @param userId 用户id |
| | | * @param shopId 店铺id |
| | | * @return 用户有效的优惠券列表 |
| | | */ |
| | | List<CouponOrderDto> getCouponListByShopIds(String userId, Long shopId); |
| | | |
| | | /** |
| | | * 获取已投放优惠券 |
| | | * |
| | | * @param shopId 店铺id |
| | | * @return 已投放优惠券 |
| | | */ |
| | | List<Coupon> listPutonByShopId(Long shopId); |
| | | |
| | | /** |
| | | * 查看用户拥有的所有优惠券 |
| | | * @param userId 用户id |
| | | * @return 用户拥有的所有优惠券 |
| | | */ |
| | | List<CouponDto> listCouponIdsByUserId(String userId); |
| | | |
| | | /** |
| | | * 通过优惠券id获取商品列表 |
| | | * @param page 分页信息 |
| | | * @param coupon 优惠券信息 |
| | | * @param dbLang 语言 |
| | | * @return 商品列表 |
| | | */ |
| | | IPage<ProductDto> prodListByCoupon(PageParam<ProductDto> page, Coupon coupon, Integer dbLang); |
| | | |
| | | /** |
| | | * 商家端分页获取优惠券数据 |
| | | * @param page 分页参数 |
| | | * @param coupon 优惠券 |
| | | * @return 优惠券数据 |
| | | */ |
| | | IPage<Coupon> getMultiShopPage(PageParam<Coupon> page, Coupon coupon); |
| | | /** |
| | | * 获取各个状态下优惠券个数 |
| | | * |
| | | * @param userId 用户id |
| | | * @return 各个状态下优惠券个数map |
| | | */ |
| | | Map<String, Long> getCouponCountByStatus(String userId); |
| | | |
| | | /** |
| | | * 平台 --获取分页优惠券数据 |
| | | * @param page 分页信息 |
| | | * @param coupon 优惠券信息 |
| | | * @return 分页优惠券数据 |
| | | */ |
| | | IPage<Coupon> getPlatformPage(PageParam<Coupon> page, Coupon coupon); |
| | | |
| | | /** |
| | | * 平台 --下线活动 |
| | | * @param coupon 优惠券信息 |
| | | * @param offlineReason 下线备注 |
| | | * @param sysUserId 系统用户id |
| | | */ |
| | | void offline(Coupon coupon, String offlineReason, Long sysUserId); |
| | | |
| | | /** |
| | | * 平台 --审核活动 |
| | | * @param offlineHandleEventAuditParam 审核信息 |
| | | * @param sysUserId 系统用户id |
| | | */ |
| | | void auditCoupon(OfflineHandleEventAuditParam offlineHandleEventAuditParam, Long sysUserId); |
| | | |
| | | /** |
| | | * 申请活动审核 |
| | | * @param eventId 事件id |
| | | * @param couponId 优惠券id |
| | | * @param reapplyReason 申请理由 |
| | | */ |
| | | void auditApply(Long eventId, Long couponId, String reapplyReason); |
| | | |
| | | /** |
| | | * 移除优惠券缓存 |
| | | * |
| | | * @param shopId 店铺id |
| | | */ |
| | | void removeCouponAndCouponProdsCache(Long shopId); |
| | | |
| | | /** |
| | | * 批量绑定优惠券,如果已达上限等领取不了的情况直接退出 |
| | | * @param couponIds 优惠券ids |
| | | * @param userId 用户id |
| | | * @param shopId 店铺id |
| | | */ |
| | | void batchBindCouponByIds(List<Long> couponIds, String userId,Long shopId); |
| | | |
| | | |
| | | /** |
| | | * 对用户发放优惠券,如果已达上限等领取不了的情况直接退出 |
| | | * @param couponId 优惠券id |
| | | * @param userId 用户id |
| | | * @param couponNums 优惠券数量 |
| | | * @param shopId 店铺id |
| | | */ |
| | | void bindCouponById(Long couponId, String userId, Integer couponNums, Long shopId); |
| | | |
| | | /** |
| | | * 获取 领优惠卷 接口的优惠券列表 |
| | | * @param page 分页信息 |
| | | * @param userId 用户id |
| | | * @return 优惠券列表 |
| | | */ |
| | | IPage<CouponDto> getCouponList(Page<CouponDto> page, String userId); |
| | | |
| | | /** |
| | | * 获取所有可领取的优惠券 |
| | | * @param page 分页信息 |
| | | * @return 可领取的优惠券 |
| | | */ |
| | | IPage<CouponDto> getCouponList(Page<CouponDto> page); |
| | | |
| | | /** |
| | | * 获取某个用户的优惠券明细 |
| | | * @param page 分页 |
| | | * @param userId 用户id |
| | | * @param status 状态 |
| | | * @return 优惠券明细 |
| | | */ |
| | | IPage<CouponUser> getPageByUserId(PageParam<CouponUser> page, String userId, Integer status); |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.common.service; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.yami.shop.bean.model.Order; |
| | | import com.yami.shop.coupon.common.dto.CouponRecordDTO; |
| | | import com.yami.shop.coupon.common.model.CouponUseRecord; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 优惠券使用记录 |
| | | * |
| | | * @author yami code generator |
| | | * @date 2019-05-15 09:04:57 |
| | | */ |
| | | public interface CouponUseRecordService extends IService<CouponUseRecord> { |
| | | |
| | | /** |
| | | * 添加优惠券使用记录 |
| | | * |
| | | * @param couponUseList |
| | | */ |
| | | void addCouponUseRecode(List<CouponUseRecord> couponUseList); |
| | | |
| | | /** |
| | | * 通过订单列表和批量修改记录状态 |
| | | * @param status 状态 |
| | | * @param orderNumberList 订单编号列表 |
| | | */ |
| | | void batchUpdateRecordByStatusAndOrderNums(int status, List<String> orderNumberList); |
| | | |
| | | /** |
| | | * 锁定订优惠券状态 |
| | | * @param lockCouponParams 订单id和优惠券id关联信息 |
| | | * @return void |
| | | */ |
| | | void lockCoupon(List<CouponRecordDTO> lockCouponParams, String userId); |
| | | |
| | | /** |
| | | * 根据订单号进行优惠券解锁 |
| | | * @param order 订单信息 |
| | | */ |
| | | void unlockCoupon(Order order); |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.common.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.yami.shop.bean.param.*; |
| | | import com.yami.shop.coupon.common.model.CouponUser; |
| | | |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author lgh on 2018/12/27. |
| | | */ |
| | | public interface CouponUserService extends IService<CouponUser> { |
| | | |
| | | // List<CouponUser> getCouponAndCouponUserByCouponUserIds(List<Long> couponUserIds); |
| | | |
| | | /** |
| | | * 删除用户失效半年以上的优惠券 |
| | | * @param date 时间 |
| | | */ |
| | | void deleteUnValidTimeCoupons(Date date); |
| | | |
| | | /** |
| | | * 设置用户的过期优惠券为失效状态 |
| | | * @param now 时间 |
| | | */ |
| | | void updateStatusByTime(Date now); |
| | | |
| | | /** |
| | | * 将优惠券状态改为可用状态并删除优惠券记录 |
| | | * @param userId 用户id |
| | | * @param orderNumber 订单编号 |
| | | */ |
| | | void cancelOrder(String userId, String orderNumber); |
| | | |
| | | /** |
| | | * 卡券分析,卡券昨日关键指标 |
| | | * @param param 参数信息 |
| | | * @return 卡券昨日关键指标 |
| | | */ |
| | | List<CouponAnalysisParam> getCouponAnalysis(ProdEffectParam param); |
| | | |
| | | /** |
| | | * 领券会员数 |
| | | * @param param 参数信息 |
| | | * @return 领券会员数 |
| | | */ |
| | | Integer countMemberGetCoupon(CustomerReqParam param); |
| | | |
| | | /** |
| | | * 领券会员数 |
| | | * @param param 参数信息 |
| | | * @return 领券会员数 |
| | | */ |
| | | Integer countMemberCouponByParam(MemberReqParam param); |
| | | |
| | | /** |
| | | * 获取优惠券各种状态的数量 |
| | | * @param userId 用户id |
| | | * @return 用户优惠券信息 |
| | | */ |
| | | CouponUserParam getCouponCountByUserId(String userId); |
| | | |
| | | /** |
| | | * 根据日期获得优惠券详情信息 |
| | | * @param page page参数 |
| | | * @param param 日期参数 |
| | | * @return 优惠券详情信息 |
| | | */ |
| | | Page<CouponAnalysisParam> getCouponAnalysisParamByDate(Page page,ProdEffectParam param); |
| | | |
| | | /** |
| | | * 商家端获取优惠券各种状态数量 |
| | | * @param userId |
| | | * @param shopId |
| | | * @return |
| | | */ |
| | | CouponUserParam getCouponCountInfo(String userId, Long shopId); |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.common.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.yami.shop.coupon.common.dao.CouponProdMapper; |
| | | import com.yami.shop.coupon.common.model.CouponProd; |
| | | import com.yami.shop.coupon.common.service.CouponProdService; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | | * |
| | | * @author lgh on 2018/12/27. |
| | | */ |
| | | @Service |
| | | public class CouponProdServiceImpl extends ServiceImpl<CouponProdMapper, CouponProd> implements CouponProdService { |
| | | |
| | | @Autowired |
| | | private CouponProdMapper couponProdMapper; |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.common.service.impl; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.yami.shop.bean.app.dto.CouponDto; |
| | | import com.yami.shop.bean.app.dto.CouponOrderDto; |
| | | import com.yami.shop.bean.app.dto.ProductDto; |
| | | import com.yami.shop.bean.enums.CouponProdType; |
| | | import com.yami.shop.bean.enums.CouponType; |
| | | import com.yami.shop.bean.enums.OfflineHandleEventStatus; |
| | | import com.yami.shop.bean.enums.OfflineHandleEventType; |
| | | import com.yami.shop.bean.event.BalanceCouponEvent; |
| | | import com.yami.shop.bean.event.ScoreOrderEvent; |
| | | import com.yami.shop.bean.model.OfflineHandleEvent; |
| | | import com.yami.shop.bean.param.OfflineHandleEventAuditParam; |
| | | 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.PageAdapter; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.coupon.common.constants.CouponStatusEnum; |
| | | import com.yami.shop.coupon.common.constants.ValidTimeTypeEnum; |
| | | import com.yami.shop.coupon.common.dao.CouponMapper; |
| | | import com.yami.shop.coupon.common.dao.CouponProdMapper; |
| | | import com.yami.shop.coupon.common.dao.CouponUserMapper; |
| | | import com.yami.shop.coupon.common.model.Coupon; |
| | | import com.yami.shop.coupon.common.model.CouponProd; |
| | | import com.yami.shop.coupon.common.model.CouponUser; |
| | | import com.yami.shop.coupon.common.service.CouponService; |
| | | import com.yami.shop.coupon.common.service.CouponUserService; |
| | | import com.yami.shop.dao.ProductMapper; |
| | | import com.yami.shop.service.OfflineHandleEventService; |
| | | import lombok.AllArgsConstructor; |
| | | import ma.glasnost.orika.MapperFacade; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.apache.commons.lang3.time.DateUtils; |
| | | import org.jetbrains.annotations.Nullable; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.cache.annotation.CacheEvict; |
| | | import org.springframework.cache.annotation.Cacheable; |
| | | import org.springframework.context.ApplicationContext; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * @author lgh on 2018/12/27. |
| | | */ |
| | | @Service |
| | | @AllArgsConstructor |
| | | public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> implements CouponService { |
| | | |
| | | private final CouponMapper couponMapper; |
| | | private final CouponProdMapper couponProdMapper; |
| | | private final CouponUserMapper couponUserMapper; |
| | | private final CouponUserService couponUserService; |
| | | private final ProductMapper productMapper; |
| | | private final OfflineHandleEventService offlineHandleEventService; |
| | | private final ApplicationContext applicationContext; |
| | | private final MapperFacade mapperFacade; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @CacheEvict(cacheNames = "couponAndCouponProds", key = "#coupon.shopId") |
| | | public void updateCouponAndCouponProds(@Valid Coupon coupon) { |
| | | Integer suitableProdType = coupon.getSuitableProdType(); |
| | | Coupon couponDb = couponMapper.selectById(coupon.getCouponId()); |
| | | checkInfo(coupon, false); |
| | | boolean isPutOn = Objects.equals(couponDb.getPutonStatus(), CouponStatusEnum.NOT_LAUNCH.getValue()) && Objects.equals(coupon.getPutonStatus(), CouponStatusEnum.PUT_ON.getValue()); |
| | | if (isPutOn) { |
| | | coupon.setLaunchTime(new Date()); |
| | | } |
| | | couponMapper.updateCoupon(coupon); |
| | | // 删除该优惠券下所有商品 |
| | | couponProdMapper.deleteCouponProdsByCouponId(coupon.getCouponId()); |
| | | if (suitableProdType != 0) { |
| | | List<Long> prodIds = coupon.getCouponProds().stream().map(CouponProd::getProdId).collect(Collectors.toList()); |
| | | // 插入所有商品 |
| | | couponProdMapper.insertCouponProdsBatch(coupon.getCouponId(), prodIds); |
| | | } |
| | | // 不是平台端的优惠券、修改后的领取类型为平台发放、没有发生领取类型变更的,直接返回 |
| | | if(!Objects.equals(coupon.getShopId(), Constant.PLATFORM_SHOP_ID) |
| | | || Objects.equals(coupon.getGetWay(), 1) |
| | | || Objects.equals(coupon.getGetWay(), couponDb.getGetWay())) { |
| | | return; |
| | | } |
| | | // 处理优惠券类型从系统发放变更为用户领取时,移除用户等级绑定的优惠券(目前用户等级绑定的优惠券只支持系统发放) |
| | | applicationContext.publishEvent(new BalanceCouponEvent(coupon.getCouponId())); |
| | | } |
| | | |
| | | @Override |
| | | @CacheEvict(cacheNames = "couponAndCouponProds", key = "#shopId") |
| | | public void removeCouponAndCouponProdsCache(Long shopId) { |
| | | } |
| | | |
| | | @Override |
| | | public IPage<CouponDto> getCouponList(Page<CouponDto> page, String userId) { |
| | | //获取优惠券列表 |
| | | List<Long> couponIds = couponMapper.getShopAvailableCouponIds(new PageAdapter(page)); |
| | | page.setTotal(couponMapper.countCouponPageByCouponDto()); |
| | | if (CollUtil.isEmpty(couponIds)) { |
| | | page.setRecords(new ArrayList<>()); |
| | | return page; |
| | | } |
| | | List<CouponDto> couponDtoList = couponMapper.getCouponList(couponIds, I18nMessage.getDbLang()); |
| | | List<CouponUser> couponUsers = couponUserMapper.listByCouponIdsAndUserId(couponIds, userId); |
| | | Map<Long, Integer> couponUserMap = couponUsers.stream().collect(Collectors.toMap(CouponUser::getCouponId, CouponUser::getCurUserReceiveCount)); |
| | | for (CouponDto couponDto : couponDtoList) { |
| | | if (couponUserMap.containsKey(couponDto.getCouponId())) { |
| | | couponDto.setCurUserReceiveCount(couponUserMap.get(couponDto.getCouponId())); |
| | | continue; |
| | | } |
| | | couponDto.setCurUserReceiveCount(0); |
| | | } |
| | | page.setRecords(couponDtoList); |
| | | return page; |
| | | } |
| | | |
| | | @Override |
| | | public IPage<CouponDto> getCouponList(Page<CouponDto> page) { |
| | | //获取优惠券列表 |
| | | page.setTotal(couponMapper.countCouponPageByCouponDto()); |
| | | List<Long> couponIds = couponMapper.getShopAvailableCouponIds(new PageAdapter(page)); |
| | | if (CollUtil.isEmpty(couponIds)) { |
| | | page.setRecords(new ArrayList<>()); |
| | | return page; |
| | | } |
| | | List<CouponDto> couponDtoList = couponMapper.getCouponList(couponIds, I18nMessage.getDbLang()); |
| | | page.setRecords(couponDtoList); |
| | | return page; |
| | | } |
| | | |
| | | @Override |
| | | public IPage<CouponUser> getPageByUserId(PageParam<CouponUser> page, String userId, Integer status) { |
| | | return couponUserMapper.getPageByUserId(page, userId, status); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | // @CacheEvict(cacheNames = "couponAndCouponProds", key = "#shopId") |
| | | public void batchBindCouponByIds(List<Long> couponIds, String userId, Long shopId) { |
| | | List<CouponUser> couponUsers = new ArrayList<>(); |
| | | Collection<Coupon> coupons = listByIds(couponIds); |
| | | if (CollectionUtils.isEmpty(coupons)) { |
| | | return; |
| | | } |
| | | for (Coupon coupon : coupons) { |
| | | CouponUser couponUser = getCouponUser(userId, coupon, 1); |
| | | if (couponUser == null) { |
| | | continue; |
| | | } |
| | | couponUsers.add(couponUser); |
| | | // 更新库存 |
| | | if (couponMapper.updateCouponStocksAndVersion(coupon.getCouponId()) < 1) { |
| | | // 优惠券库存不足 |
| | | throw new YamiShopBindException("yami.coupon.stock.enough"); |
| | | } |
| | | } |
| | | couponUserService.saveBatch(couponUsers); |
| | | } |
| | | |
| | | @Override |
| | | public void bindCouponById(Long couponId, String userId, Integer couponNums, Long shopId) { |
| | | Coupon coupon = getById(couponId); |
| | | if (Objects.isNull(coupon)) { |
| | | throw new YamiShopBindException("yami.coupon.no.exist"); |
| | | } |
| | | CouponUser couponUser = getCouponUser(userId, coupon, couponNums); |
| | | if (couponUser == null) { |
| | | return; |
| | | } |
| | | List<CouponUser> couponUsers = new ArrayList<>(couponNums); |
| | | for (Integer i = 0; i < couponNums; i++) { |
| | | CouponUser copyCouponUser = mapperFacade.map(couponUser, CouponUser.class); |
| | | couponUsers.add(copyCouponUser); |
| | | } |
| | | couponUserService.saveBatch(couponUsers, couponNums); |
| | | } |
| | | |
| | | /** |
| | | * 生成用户优惠券绑定对象 |
| | | * @param userId 用户id |
| | | * @param coupon 优惠券详情 |
| | | * @param couponNums 优惠券发放数量 |
| | | * @return |
| | | */ |
| | | private CouponUser getCouponUser(String userId, Coupon coupon, int couponNums) { |
| | | Date nowTime = new Date(); |
| | | // 当优惠券状态不为投放时 |
| | | if (coupon.getOverdueStatus() == 0 || coupon.getPutonStatus() != 1 || coupon.getStocks() == 0) { |
| | | // 该券无法被领取或者该券领完了! |
| | | log.warn("yami.coupon.receive.finish"); |
| | | return null; |
| | | } |
| | | int count = couponUserMapper.selectCount(new LambdaQueryWrapper<CouponUser>().eq(CouponUser::getUserId, userId).eq(CouponUser::getCouponId, coupon.getCouponId())); |
| | | if (count + couponNums > coupon.getLimitNum()) { |
| | | // 该券已达个人领取上限,无法继续领取! |
| | | log.warn("yami.coupon.user.limit"); |
| | | return null; |
| | | } |
| | | CouponUser couponUser = new CouponUser(); |
| | | couponUser.setUserId(userId); |
| | | couponUser.setStatus(1); |
| | | couponUser.setCouponId(coupon.getCouponId()); |
| | | couponUser.setReceiveTime(nowTime); |
| | | // 生效时间类型为固定时间 |
| | | if (coupon.getValidTimeType() == 1) { |
| | | couponUser.setUserStartTime(coupon.getStartTime()); |
| | | couponUser.setUserEndTime(coupon.getEndTime()); |
| | | } |
| | | // 生效时间类型为领取后生效 |
| | | if (coupon.getValidTimeType() == 2) { |
| | | if (coupon.getAfterReceiveDays() == null) { |
| | | coupon.setAfterReceiveDays(0); |
| | | } |
| | | if (coupon.getValidDays() == null) { |
| | | coupon.setValidDays(0); |
| | | } |
| | | couponUser.setUserStartTime(DateUtils.addDays(DateUtil.beginOfDay(nowTime), coupon.getAfterReceiveDays())); |
| | | couponUser.setUserEndTime(DateUtils.addDays(couponUser.getUserStartTime(), coupon.getValidDays() + 1)); |
| | | } |
| | | couponUser.setIsDelete(0); |
| | | return couponUser; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @CacheEvict(cacheNames = "couponAndCouponProds", key = "#coupon.shopId") |
| | | public void insertCouponAndCouponProds(@Valid Coupon coupon) { |
| | | Integer suitableProdType = coupon.getSuitableProdType(); |
| | | checkInfo(coupon, true); |
| | | if(Objects.equals(coupon.getPutonStatus(), CouponStatusEnum.PUT_ON.getValue())) { |
| | | coupon.setLaunchTime(new Date()); |
| | | } |
| | | couponMapper.insert(coupon); |
| | | if (suitableProdType != 0) { |
| | | List<Long> prodIds = coupon.getCouponProds().stream().map(CouponProd::getProdId).collect(Collectors.toList()); |
| | | // 插入所有商品 |
| | | couponProdMapper.insertCouponProdsBatch(coupon.getCouponId(), prodIds); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public Coupon getCouponAndCouponProdsByCouponId(Long id) { |
| | | return couponMapper.getCouponAndCouponProdsByCouponId(id); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @CacheEvict(cacheNames = "couponAndCouponProds", key = "#coupon.shopId") |
| | | public void receive(Coupon coupon, String userId) { |
| | | //如果是积分商品,就扣除用户相应的积分 |
| | | if (Objects.equals(coupon.getCouponType(), CouponType.C2P.value())) { |
| | | applicationContext.publishEvent(new ScoreOrderEvent(coupon.getCouponId(), null, coupon.getScorePrice())); |
| | | } |
| | | CouponUser couponUser = getCouponUser(coupon, userId); |
| | | couponUserMapper.insert(couponUser); |
| | | // 更新库存 |
| | | if (couponMapper.updateCouponStocksAndVersion(coupon.getCouponId()) < 1) { |
| | | // 优惠券库存不足 |
| | | throw new YamiShopBindException("yami.coupon.stock.enough"); |
| | | } |
| | | } |
| | | |
| | | private CouponUser getCouponUser(Coupon coupon, String userId) { |
| | | Date nowTime = new Date(); |
| | | // 当优惠券状态不为投放时 |
| | | if (coupon.getOverdueStatus() == 0 || coupon.getPutonStatus() != 1) { |
| | | // 该券无法被领取 |
| | | throw new YamiShopBindException("yami.coupon.receive.finish"); |
| | | } |
| | | // 当优惠券不在规定时间内(类型为固定时间) 优惠券使用时间,不是领取时间,一般优惠券都是可以领,还不能用的 |
| | | // if (coupon.getValidTimeType() == 1 && (coupon.getEndTime().getTime() < nowTime.getTime() || coupon.getStartTime().getTime() > nowTime.getTime())) { |
| | | // throw new YamiShopBindException("不在可领取的时间范围内"); |
| | | // } |
| | | // 当优惠券无库存时 |
| | | if (coupon.getStocks() == 0) { |
| | | // 该券领完了 |
| | | throw new YamiShopBindException("yami.coupon.receive.finish"); |
| | | } |
| | | int count = couponUserMapper.selectCount(new LambdaQueryWrapper<CouponUser>().eq(CouponUser::getUserId, userId).eq(CouponUser::getCouponId, coupon.getCouponId())); |
| | | if (count >= coupon.getLimitNum()) { |
| | | // 该券已达个人领取上限,无法继续领取 |
| | | throw new YamiShopBindException("yami.coupon.user.limit"); |
| | | } |
| | | CouponUser couponUser = new CouponUser(); |
| | | couponUser.setUserId(userId); |
| | | couponUser.setCouponId(coupon.getCouponId()); |
| | | couponUser.setStatus(1); |
| | | couponUser.setReceiveTime(nowTime); |
| | | // 生效时间类型为固定时间 |
| | | if (coupon.getValidTimeType() == 1) { |
| | | couponUser.setUserStartTime(coupon.getStartTime()); |
| | | couponUser.setUserEndTime(coupon.getEndTime()); |
| | | } |
| | | // 生效时间类型为领取后生效 |
| | | if (coupon.getValidTimeType() == ValidTimeTypeEnum.RECEIVE.getValue()) { |
| | | if (coupon.getAfterReceiveDays() == null) { |
| | | coupon.setAfterReceiveDays(0); |
| | | } |
| | | if (coupon.getValidDays() == null) { |
| | | coupon.setValidDays(0); |
| | | } |
| | | couponUser.setUserStartTime(DateUtils.addDays(DateUtil.beginOfDay(nowTime), coupon.getAfterReceiveDays())); |
| | | couponUser.setUserEndTime(DateUtils.addDays(couponUser.getUserStartTime(), coupon.getValidDays() + 1)); |
| | | } |
| | | couponUser.setIsDelete(0); |
| | | return couponUser; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void changeCoupon(Date now) { |
| | | // 设置店铺的过期优惠券为过期状态 |
| | | couponMapper.updateOverdueStatusByTime(now); |
| | | // 设置店铺库存为0优惠券的状态(设为未投放状态) 没库存就消失么? |
| | | // 像京东会有没库存的优惠券,一直展示大半天,也不消失,所以消失是用户手动下线的 |
| | | // couponMapper.updatePutonStatusByStocks(); |
| | | } |
| | | |
| | | @Override |
| | | public void putonCoupon(Date now) { |
| | | couponMapper.putonCoupon(now); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void deleteByCouponId(Long couponId) { |
| | | // 获取未被删除的优惠券数量 |
| | | Integer useCount = couponUserMapper.selectCount(new LambdaQueryWrapper<CouponUser>().eq(CouponUser::getCouponId, couponId).eq(CouponUser::getIsDelete, 0)); |
| | | if (useCount > 0) { |
| | | // 该优惠券已被领取,删除失败 |
| | | throw new YamiShopBindException("yami.coupon.delete.check1"); |
| | | } |
| | | |
| | | Coupon coupon = couponMapper.selectById(couponId); |
| | | if (Objects.isNull(coupon)) { |
| | | // 优惠券不存在 |
| | | throw new YamiShopBindException("yami.coupon.no.exist"); |
| | | } |
| | | if (Objects.equals(coupon.getPutonStatus(), 1)) { |
| | | // 该优惠券已投放,删除失败 |
| | | throw new YamiShopBindException("yami.coupon.delete.check2"); |
| | | } |
| | | //删除优惠券关联的商品 |
| | | couponProdMapper.delete(new LambdaQueryWrapper<CouponProd>().eq(CouponProd::getCouponId, couponId)); |
| | | //删除优惠券 |
| | | couponMapper.deleteById(couponId); |
| | | } |
| | | |
| | | @Override |
| | | public List<CouponDto> generalCouponList(String userId) { |
| | | return couponMapper.generalCouponList(userId); |
| | | } |
| | | |
| | | @Override |
| | | public List<CouponDto> generalCouponList() { |
| | | return couponMapper.generalCouponListTourist(); |
| | | } |
| | | |
| | | @Override |
| | | public IPage<CouponDto> getCouponListByStatus(IPage<CouponDto> page, String userId, Integer status) { |
| | | IPage<CouponDto> couponPage = couponMapper.getCouponListByStatus(page, userId, status); |
| | | List<CouponDto> couponDtoList = couponPage.getRecords(); |
| | | for (CouponDto couponDto : couponDtoList) { |
| | | if (Objects.equals(couponDto.getValidTimeType(), 2)) { |
| | | Integer afterReceiveDays = couponDto.getAfterReceiveDays(); |
| | | if (Objects.isNull(couponDto.getAfterReceiveDays())) { |
| | | afterReceiveDays = 0; |
| | | } |
| | | Integer validDays = couponDto.getValidDays(); |
| | | if (validDays == null) { |
| | | validDays = 0; |
| | | } |
| | | couponDto.setStartTime(DateUtil.offsetDay(couponDto.getReceiveTime(), afterReceiveDays)); |
| | | couponDto.setEndTime(DateUtil.offsetDay(couponDto.getStartTime(), validDays)); |
| | | } |
| | | } |
| | | return couponPage; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @CacheEvict(cacheNames = "CouponAndCouponUser", key = "#userId") |
| | | public void deleteUserCouponByCouponId(String userId, Long couponId) { |
| | | couponUserMapper.deleteUserCoupon(userId, couponId); |
| | | } |
| | | |
| | | @Override |
| | | public List<CouponOrderDto> getCouponListByShopIds(String userId, Long shopId) { |
| | | List<CouponOrderDto> couponOrderDtoList = couponMapper.getCouponListByShopIds(userId, shopId); |
| | | for (CouponOrderDto couponOrderDto : couponOrderDtoList) { |
| | | if (Objects.equals(couponOrderDto.getValidTimeType(), 2)) { |
| | | Integer validDays = couponOrderDto.getValidDays(); |
| | | if (validDays == null) { |
| | | validDays = 0; |
| | | } |
| | | Integer afterReceiveDays = couponOrderDto.getAfterReceiveDays(); |
| | | if (afterReceiveDays == null) { |
| | | afterReceiveDays = 0; |
| | | } |
| | | couponOrderDto.setStartTime(DateUtil.offsetDay(couponOrderDto.getReceiveTime(), afterReceiveDays)); |
| | | couponOrderDto.setEndTime(DateUtil.offsetDay(couponOrderDto.getStartTime(), validDays)); |
| | | } |
| | | } |
| | | return couponOrderDtoList; |
| | | } |
| | | |
| | | @Override |
| | | @Cacheable(cacheNames = "couponAndCouponProds", key = "#shopId") |
| | | public List<Coupon> listPutonByShopId(Long shopId) { |
| | | return couponMapper.listPutonCouponAndCouponProdsByShopId(shopId); |
| | | } |
| | | |
| | | @Override |
| | | public List<CouponDto> listCouponIdsByUserId(String userId) { |
| | | return couponMapper.listCouponIdsByUserId(userId); |
| | | } |
| | | |
| | | @Override |
| | | public IPage<ProductDto> prodListByCoupon(PageParam<ProductDto> page, Coupon coupon, Integer dbLang) { |
| | | // 优惠券所有商品可用、指定商品可用、指定商品不可用 (0全部商品参与 1指定商品参与 2指定商品不参与) |
| | | IPage<ProductDto> productPage; |
| | | if (coupon.getSuitableProdType() == 0) { |
| | | productPage = productMapper.listByShopId(page, coupon.getShopId(), dbLang); |
| | | } else { |
| | | productPage = productMapper.listBySuitableProdTypeAndCouponIdAndShopId(page, coupon.getShopId(), coupon.getSuitableProdType(), |
| | | coupon.getCouponId(), dbLang); |
| | | } |
| | | return productPage; |
| | | } |
| | | |
| | | @Override |
| | | public IPage<Coupon> getMultiShopPage(PageParam<Coupon> page, Coupon coupon) { |
| | | IPage<Coupon> multiShopPage = couponMapper.getMultiShopPage(page, coupon); |
| | | for (Coupon record : multiShopPage.getRecords()) { |
| | | record.setUseNum(couponMapper.countUseNum(record.getCouponId()) == null ? 0 : couponMapper.countUseNum(record.getCouponId())); |
| | | record.setTakeNum(couponMapper.countTakeNum(record.getCouponId(), record.getShopId()) == null ? 0 : couponMapper.countTakeNum(record.getCouponId(), record.getShopId())); |
| | | } |
| | | return multiShopPage; |
| | | } |
| | | |
| | | @Override |
| | | public Map<String, Long> getCouponCountByStatus(String userId) { |
| | | return couponMapper.getCouponCountByStatus(userId); |
| | | } |
| | | |
| | | @Override |
| | | public IPage<Coupon> getPlatformPage(PageParam<Coupon> page, Coupon coupon) { |
| | | IPage<Coupon> couponPage = couponMapper.getPlatformPage(page, coupon); |
| | | List<Coupon> couponList = couponPage.getRecords(); |
| | | for (Coupon temp : couponList) { |
| | | temp.setTakeNum(couponMapper.countTakeNum(temp.getCouponId(), temp.getShopId()) == null ? 0 : couponMapper.countTakeNum(temp.getCouponId(), temp.getShopId())); |
| | | temp.setUseNum(couponMapper.countUseNum(temp.getCouponId()) == null ? 0 : couponMapper.countUseNum(temp.getCouponId())); |
| | | } |
| | | return couponPage; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @CacheEvict(cacheNames = "couponAndCouponProds", key = "#coupon.shopId") |
| | | public void offline(Coupon coupon, String offlineReason, Long sysUserId) { |
| | | // 添加下线处理记录 |
| | | OfflineHandleEvent handleEvent = offlineHandleEventService.getBaseMapper().selectOne(new LambdaUpdateWrapper<OfflineHandleEvent>() |
| | | .eq(OfflineHandleEvent::getHandleId, coupon.getCouponId()) |
| | | .eq(OfflineHandleEvent::getHandleType, OfflineHandleEventType.COUPON.getValue()) |
| | | .ne(OfflineHandleEvent::getStatus, OfflineHandleEventStatus.AGREE_BY_PLATFORM.getValue()) |
| | | ); |
| | | if (Objects.isNull(handleEvent)) { |
| | | handleEvent = new OfflineHandleEvent(); |
| | | } |
| | | Date now = new Date(); |
| | | handleEvent.setHandleId(coupon.getCouponId()); |
| | | handleEvent.setHandleType(OfflineHandleEventType.COUPON.getValue()); |
| | | handleEvent.setCreateTime(now); |
| | | handleEvent.setOfflineReason(offlineReason); |
| | | handleEvent.setHandlerId(sysUserId); |
| | | handleEvent.setShopId(coupon.getShopId()); |
| | | handleEvent.setStatus(OfflineHandleEventStatus.OFFLINE_BY_PLATFORM.getValue()); |
| | | handleEvent.setUpdateTime(now); |
| | | if (Objects.nonNull(handleEvent.getEventId())) { |
| | | offlineHandleEventService.updateById(handleEvent); |
| | | } else { |
| | | offlineHandleEventService.save(handleEvent); |
| | | } |
| | | |
| | | // 更新活动状态为下线 |
| | | couponMapper.updatePutOnStatusByCouponId(coupon.getCouponId(), CouponStatusEnum.OFFLINE.getValue()); |
| | | //更新优惠券过期状态为过期 |
| | | couponMapper.updateOverdueStatusByCouponId(coupon.getCouponId(), 0); |
| | | |
| | | |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void auditCoupon(OfflineHandleEventAuditParam offlineHandleEventAuditParam, Long sysUserId) { |
| | | // 审核通过 |
| | | if (Objects.equals(offlineHandleEventAuditParam.getStatus(), OfflineHandleEventStatus.AGREE_BY_PLATFORM.getValue())) { |
| | | // 更新优惠券为暂不投放状态 |
| | | couponMapper.updatePutOnStatusByCouponId(offlineHandleEventAuditParam.getHandleId(), CouponStatusEnum.NOT_LAUNCH.getValue()); |
| | | //更新优惠券过期状态为未过期 |
| | | couponMapper.updateOverdueStatusByCouponId(offlineHandleEventAuditParam.getHandleId(), 1); |
| | | } |
| | | // 审核不通过 |
| | | else if (Objects.equals(offlineHandleEventAuditParam.getStatus(), OfflineHandleEventStatus.DISAGREE_BY_PLATFORM.getValue())) { |
| | | couponMapper.updatePutOnStatusByCouponId(offlineHandleEventAuditParam.getHandleId(), CouponStatusEnum.OFFLINE.getValue()); |
| | | } |
| | | offlineHandleEventService.auditOfflineEvent(offlineHandleEventAuditParam, sysUserId); |
| | | |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void auditApply(Long eventId, Long couponId, String reapplyReason) { |
| | | // 更新活动为待审核状态 |
| | | couponMapper.updatePutOnStatusByCouponId(couponId, CouponStatusEnum.WAIT_AUDIT.getValue()); |
| | | // 更新事件状态 |
| | | offlineHandleEventService.updateToApply(eventId, reapplyReason); |
| | | } |
| | | |
| | | private void checkInfo(Coupon coupon, Boolean isSave) { |
| | | boolean checkProd = (Objects.equals(CouponProdType.PROD_IN.value(), coupon.getSuitableProdType()) |
| | | || Objects.equals(CouponProdType.PROD_NO_IN.value(), coupon.getSuitableProdType())) |
| | | && CollectionUtils.isEmpty(coupon.getCouponProds()); |
| | | if (checkProd) { |
| | | // 商品不能为空 |
| | | throw new YamiShopBindException("yami.product.no.exist"); |
| | | } |
| | | // 判断投放时间 < 生效时间 |
| | | if(coupon.getLaunchTime() != null |
| | | && coupon.getEndTime() != null |
| | | && coupon.getLaunchTime().compareTo(coupon.getEndTime()) > 0) { |
| | | throw new YamiShopBindException("yami.coupon.launch.time.lt.endtime"); |
| | | } |
| | | if (Objects.equals(coupon.getPutonStatus(), CouponStatusEnum.AUTO_LAUNCH.getValue()) && Objects.isNull(coupon.getLaunchTime())) { |
| | | // 优惠券投放时间不能为空 |
| | | throw new YamiShopBindException("yami.coupon.launch.time.check"); |
| | | } |
| | | Date nowTime = new Date(); |
| | | if (Objects.nonNull(coupon.getLaunchTime()) && coupon.getLaunchTime().getTime() < nowTime.getTime()) { |
| | | // 投放时间需大于当前时间 |
| | | throw new YamiShopBindException("yami.coupon.launch.time.check1"); |
| | | } |
| | | if (isSave) { |
| | | if (coupon.getLimitNum() <= 0) { |
| | | // 优惠券限领数量需大于0 |
| | | throw new YamiShopBindException("yami.coupon.limit.check"); |
| | | } |
| | | if (coupon.getValidTimeType() == 1 && coupon.getStartTime().getTime() > coupon.getEndTime().getTime()) { |
| | | // 开始时间需大于结束时间 |
| | | throw new YamiShopBindException("yami.coupon.time.check"); |
| | | } |
| | | } |
| | | // 结束时间小于等于当前时间 |
| | | if (Objects.equals(coupon.getValidTimeType(), ValidTimeTypeEnum.FIXED.value())) { |
| | | if (coupon.getEndTime().getTime() < nowTime.getTime()) { |
| | | coupon.setOverdueStatus(0); |
| | | coupon.setPutonStatus(CouponStatusEnum.CANCEL.getValue()); |
| | | } else { |
| | | coupon.setOverdueStatus(1); |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.common.service.impl; |
| | | |
| | | |
| | | import cn.hutool.core.collection.CollectionUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.google.common.collect.Lists; |
| | | import com.yami.shop.bean.model.Order; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.common.response.ResponseEnum; |
| | | import com.yami.shop.coupon.common.constants.UserCouponRecordStatus; |
| | | import com.yami.shop.coupon.common.constants.UserCouponStatus; |
| | | import com.yami.shop.coupon.common.dao.CouponUseRecordMapper; |
| | | import com.yami.shop.coupon.common.dao.CouponUserMapper; |
| | | import com.yami.shop.coupon.common.dto.CouponRecordDTO; |
| | | import com.yami.shop.coupon.common.model.CouponUseRecord; |
| | | import com.yami.shop.coupon.common.service.CouponUseRecordService; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * 优惠券使用情况 |
| | | * |
| | | * @author yami code generator |
| | | * @date 2019-05-15 09:04:57 |
| | | */ |
| | | @Service |
| | | @AllArgsConstructor |
| | | public class CouponUseRecordServiceImpl extends ServiceImpl<CouponUseRecordMapper, CouponUseRecord> implements CouponUseRecordService { |
| | | |
| | | private final CouponUseRecordMapper couponUseRecordMapper; |
| | | private final CouponUserMapper couponUserMapper; |
| | | |
| | | @Override |
| | | public void addCouponUseRecode(List<CouponUseRecord> couponUseList) { |
| | | couponUseRecordMapper.addCouponUseRecode(couponUseList); |
| | | } |
| | | |
| | | @Override |
| | | public void batchUpdateRecordByStatusAndOrderNums(int status, List<String> orderNumberList) { |
| | | // 更新商家券、平台券 |
| | | couponUseRecordMapper.batchUpdateRecordByStatusAndOrderNums(status, orderNumberList); |
| | | } |
| | | |
| | | @Override |
| | | public void lockCoupon(List<CouponRecordDTO> lockCouponParams, String userId) { |
| | | List<CouponUseRecord> couponLocks = Lists.newArrayList(); |
| | | List<Long> userCouponIds = new ArrayList<>(); |
| | | Set<Long> orderIds = new HashSet<>(); |
| | | Date now = new Date(); |
| | | for (CouponRecordDTO lockCouponParam : lockCouponParams) { |
| | | CouponUseRecord couponLock = new CouponUseRecord(); |
| | | couponLock.setAmount(lockCouponParam.getReduceAmount()); |
| | | // 获取用户优惠券id |
| | | couponLock.setCouponUserId(lockCouponParam.getCouponUserId()); |
| | | userCouponIds.add(lockCouponParam.getCouponUserId()); |
| | | couponLock.setUserId(userId); |
| | | couponLock.setOrderNumber(lockCouponParam.getOrderNumbers()); |
| | | if (couponLock.getOrderNumber().contains(StrUtil.COMMA)) { |
| | | for (String orderId : couponLock.getOrderNumber().split(StrUtil.COMMA)) { |
| | | orderIds.add(Long.valueOf(orderId)); |
| | | } |
| | | } else { |
| | | orderIds.add(Long.valueOf(couponLock.getOrderNumber())); |
| | | } |
| | | //优惠券记录为冻结状态 |
| | | couponLock.setStatus(UserCouponRecordStatus.FREEZE.getValue()); |
| | | couponLock.setUseTime(now); |
| | | couponLocks.add(couponLock); |
| | | } |
| | | // 批量保存使用记录 |
| | | saveBatch(couponLocks); |
| | | // 批量将用户的优惠券变成已使用状态 |
| | | couponUserMapper.batchUpdateUserCouponStatus(UserCouponStatus.USED.getValue(), userCouponIds); |
| | | |
| | | // // 发送消息一个小时后解锁优惠券(包括哪些订单) |
| | | // SendStatus sendStatus = couponMqTemplate.syncSend(RocketMqConstant.COUPON_UNLOCK_TOPIC, new GenericMessage<>(orderIds), RocketMqConstant.TIMEOUT, RocketMqConstant.CANCEL_ORDER_DELAY_LEVEL + 1).getSendStatus(); |
| | | // if (!Objects.equals(sendStatus,SendStatus.SEND_OK)) { |
| | | // // 消息发不出去就抛异常,发的出去无所谓 |
| | | // throw new YamiShopBindException(ResponseEnum.EXCEPTION); |
| | | // } |
| | | } |
| | | |
| | | @Override |
| | | public void unlockCoupon(Order order) { |
| | | // 该订单没有下单成功,或订单已取消,赶紧解锁库存 |
| | | //查询订单所使用的优惠券列表 |
| | | List<CouponUseRecord> couponUseRecordList = couponUseRecordMapper.selectList(new LambdaQueryWrapper<CouponUseRecord>() |
| | | .eq(CouponUseRecord::getUserId, order.getUserId()) |
| | | .like(CouponUseRecord::getOrderNumber, order.getOrderNumber())); |
| | | List<Long> couponUserIds = Lists.newArrayList(); |
| | | for (CouponUseRecord couponUseRecord : couponUseRecordList) { |
| | | couponUserIds.add(couponUseRecord.getCouponUserId()); |
| | | } |
| | | if (CollectionUtil.isEmpty(couponUserIds)) { |
| | | return; |
| | | } |
| | | // 批量将用户的优惠券变成未使用状态 |
| | | couponUserMapper.batchUpdateUserCouponStatus(UserCouponStatus.EFFECTIVE.getValue(), couponUserIds); |
| | | |
| | | // 将锁定状态标记为已解锁 |
| | | int updateStatus = couponUseRecordMapper.unLockByIds(couponUserIds); |
| | | if (updateStatus == 0) { |
| | | throw new YamiShopBindException(ResponseEnum.EXCEPTION); |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.common.service.impl; |
| | | |
| | | import cn.hutool.core.collection.CollectionUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.yami.shop.bean.param.*; |
| | | import com.yami.shop.common.util.DateParam; |
| | | import com.yami.shop.common.util.DateUtils; |
| | | import com.yami.shop.coupon.common.dao.CouponUseRecordMapper; |
| | | import com.yami.shop.coupon.common.dao.CouponUserMapper; |
| | | import com.yami.shop.coupon.common.model.CouponUseRecord; |
| | | import com.yami.shop.coupon.common.model.CouponUser; |
| | | import com.yami.shop.coupon.common.service.CouponUserService; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.apache.commons.compress.utils.Lists; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | 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 on 2018/12/27. |
| | | */ |
| | | @Service |
| | | public class CouponUserServiceImpl extends ServiceImpl<CouponUserMapper, CouponUser> implements CouponUserService { |
| | | |
| | | @Autowired |
| | | private CouponUserMapper couponUserMapper; |
| | | |
| | | @Autowired |
| | | private CouponUseRecordMapper couponUseRecordMapper; |
| | | |
| | | // @Override |
| | | // public List<CouponUser> getCouponAndCouponUserByCouponUserIds(List<Long> couponUserIds) { |
| | | // if (CollectionUtil.isEmpty(couponUserIds)) { |
| | | // return Collections.emptyList(); |
| | | // } |
| | | // return couponUserMapper.getCouponAndCouponUserByCouponUserIds(couponUserIds); |
| | | // } |
| | | |
| | | @Override |
| | | public void deleteUnValidTimeCoupons(Date date) { |
| | | couponUserMapper.deleteUnValidTimeCoupons(date); |
| | | } |
| | | |
| | | @Override |
| | | public void updateStatusByTime(Date now) { |
| | | couponUserMapper.updateStatusByTime(now); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void cancelOrder(String userId, String orderNumber) { |
| | | |
| | | //查询订单所使用的优惠券列表 |
| | | List<CouponUseRecord> couponUseRecordList = couponUseRecordMapper.selectList(new LambdaQueryWrapper<CouponUseRecord>() |
| | | .eq(CouponUseRecord::getUserId, userId) |
| | | .like(CouponUseRecord::getOrderNumber, orderNumber)); |
| | | if (CollectionUtils.isEmpty(couponUseRecordList)) { |
| | | return; |
| | | } |
| | | List<Long> couponUseRecordIdList = Lists.newArrayList(); |
| | | List<Long> couponUserIds = Lists.newArrayList(); |
| | | for (CouponUseRecord couponUseRecord : couponUseRecordList) { |
| | | String[] split = couponUseRecord.getOrderNumber().split(StrUtil.COMMA); |
| | | // 订单号集合 |
| | | StringBuilder orderNumbers = new StringBuilder(100); |
| | | // 如果大于1则是平台优惠券,并且在多个店铺使用时 |
| | | if(split.length > 1){ |
| | | for (String orderNumStr : split) { |
| | | // 判断是不是当前的订单编号 |
| | | if(StrUtil.equals(orderNumStr,orderNumber)){ |
| | | continue; |
| | | } |
| | | orderNumbers.append(orderNumStr).append(StrUtil.COMMA); |
| | | } |
| | | orderNumbers.deleteCharAt(orderNumbers.length() - 1); |
| | | // 修改订单编号信息,在进行修改后结束本次循环 |
| | | couponUseRecord.setOrderNumber(orderNumbers.toString()); |
| | | couponUseRecordMapper.updateById(couponUseRecord); |
| | | continue; |
| | | } |
| | | couponUseRecordIdList.add(couponUseRecord.getCouponUseRecordId()); |
| | | couponUserIds.add(couponUseRecord.getCouponUserId()); |
| | | } |
| | | if(CollectionUtil.isNotEmpty(couponUseRecordIdList)) { |
| | | //删除优惠券使用记录 |
| | | couponUseRecordMapper.deleteBatchIds(couponUseRecordIdList); |
| | | } |
| | | if(CollectionUtil.isNotEmpty(couponUserIds)) { |
| | | //修改用户优惠券状态为可用状态 |
| | | couponUserMapper.batchUpdateUserCouponStatus(1, couponUserIds); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public List<CouponAnalysisParam> getCouponAnalysis(ProdEffectParam param) { |
| | | List<CouponAnalysisParam> resList = new ArrayList<>(); |
| | | List<DateParam> everyDays = DateUtils.findEveryDays(param.getStartTime(), param.getEndTime()); |
| | | for (DateParam everyDay : everyDays) { |
| | | CouponAnalysisParam res = new CouponAnalysisParam(); |
| | | param.setStartTime(everyDay.getStartTime()); |
| | | param.setEndTime(everyDay.getEndTime()); |
| | | res.setCurrentDay(DateUtils.dateToStrYmd(param.getStartTime())); |
| | | // 领取次数 |
| | | res.setTakeNum(couponUserMapper.countTakeNum(null,null, param)); |
| | | // TODO 验证次数 |
| | | // 微商城使用次数 |
| | | res.setUseNum(couponUserMapper.countTakeNum(null,2, param)); |
| | | // TODO 分享次数 |
| | | resList.add(res); |
| | | } |
| | | return resList; |
| | | } |
| | | |
| | | @Override |
| | | public Integer countMemberGetCoupon(CustomerReqParam param) { |
| | | return couponUserMapper.countMemberGetCoupon(param); |
| | | } |
| | | |
| | | @Override |
| | | public Integer countMemberCouponByParam(MemberReqParam param) { |
| | | return couponUserMapper.countMemberCouponByParam(param); |
| | | } |
| | | |
| | | @Override |
| | | public CouponUserParam getCouponCountByUserId(String userId) { |
| | | // 用户未使用的并且是未过期的优惠券 |
| | | Date now = new Date(); |
| | | Integer usables = couponUserMapper.countCouponUsableNums(userId,now); |
| | | // 已使用 |
| | | Integer usedNums = couponUserMapper.countCouponUsedNums(userId); |
| | | // 失效(已过期) |
| | | Integer couponExpiredNums = couponUserMapper.countCouponExpiredNums(userId); |
| | | CouponUserParam param = new CouponUserParam(); |
| | | param.setCouponUsableNums(getIntegerNum(usables)); |
| | | param.setCouponUsedNums(getIntegerNum(usedNums)); |
| | | param.setCouponExpiredNums(getIntegerNum(couponExpiredNums)); |
| | | return param; |
| | | } |
| | | |
| | | @Override |
| | | public Page<CouponAnalysisParam> getCouponAnalysisParamByDate(Page page, ProdEffectParam param) { |
| | | Page<CouponAnalysisParam> paramByDate = couponUserMapper.getCouponAnalysisParamByDate(page, param); |
| | | for (CouponAnalysisParam couponAnalysisParam : paramByDate.getRecords()) { |
| | | couponAnalysisParam.setUseNum(couponUserMapper.countUseNum(couponAnalysisParam.getCouponId(),param)); |
| | | } |
| | | return paramByDate; |
| | | } |
| | | |
| | | private Integer getIntegerNum(Integer value) { |
| | | if (Objects.isNull(value)){ |
| | | value = 0; |
| | | } |
| | | return value; |
| | | } |
| | | |
| | | @Override |
| | | public CouponUserParam getCouponCountInfo(String userId, Long shopId) { |
| | | return couponUserMapper.getCouponCountInfo(userId, shopId); |
| | | } |
| | | } |
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.coupon.common.dao.CouponMapper"> |
| | | <resultMap id="BaseResultMap" type="com.yami.shop.coupon.common.model.Coupon"> |
| | | <!-- |
| | | WARNING - @mbg.generated |
| | | --> |
| | | <id column="coupon_id" jdbcType="BIGINT" property="couponId"/> |
| | | <result column="shop_id" jdbcType="BIGINT" property="shopId"/> |
| | | <result column="coupon_name" jdbcType="VARCHAR" property="couponName"/> |
| | | <result column="sub_title" jdbcType="VARCHAR" property="subTitle"/> |
| | | <result column="coupon_type" jdbcType="TINYINT" property="couponType"/> |
| | | <result column="cash_condition" jdbcType="DECIMAL" property="cashCondition"/> |
| | | <result column="reduce_amount" jdbcType="DECIMAL" property="reduceAmount"/> |
| | | <result column="coupon_discount" jdbcType="DECIMAL" property="couponDiscount"/> |
| | | <result column="valid_time_type" jdbcType="TINYINT" property="validTimeType"/> |
| | | <result column="launch_time" jdbcType="TIMESTAMP" property="launchTime"/> |
| | | <result column="start_time" jdbcType="TIMESTAMP" property="startTime"/> |
| | | <result column="end_time" jdbcType="TIMESTAMP" property="endTime"/> |
| | | <result column="after_receive_days" jdbcType="INTEGER" property="afterReceiveDays"/> |
| | | <result column="valid_days" jdbcType="INTEGER" property="validDays"/> |
| | | <result column="stocks" jdbcType="INTEGER" property="stocks"/> |
| | | <result column="source_stock" jdbcType="INTEGER" property="sourceStock"/> |
| | | <result column="suitable_prod_type" jdbcType="TINYINT" property="suitableProdType"/> |
| | | <result column="limit_num" jdbcType="INTEGER" property="limitNum"/> |
| | | <result column="version" jdbcType="INTEGER" property="version"/> |
| | | <result column="is_score_type" jdbcType="INTEGER" property="isScoreType"/> |
| | | <result column="score_price" jdbcType="INTEGER" property="scorePrice"/> |
| | | <result column="overdue_status" jdbcType="TINYINT" property="overdueStatus"/> |
| | | <result column="puton_status" jdbcType="TINYINT" property="putonStatus"/> |
| | | </resultMap> |
| | | |
| | | <resultMap id="CouponAndCouponProdMap" type="com.yami.shop.coupon.common.model.Coupon"> |
| | | <id column="coupon_id" jdbcType="BIGINT" property="couponId"/> |
| | | <result column="shop_id" jdbcType="BIGINT" property="shopId"/> |
| | | <result column="coupon_name" jdbcType="VARCHAR" property="couponName"/> |
| | | <result column="sub_title" jdbcType="VARCHAR" property="subTitle"/> |
| | | <result column="get_way" jdbcType="TINYINT" property="getWay"/> |
| | | <result column="coupon_type" jdbcType="TINYINT" property="couponType"/> |
| | | <result column="cash_condition" jdbcType="DECIMAL" property="cashCondition"/> |
| | | <result column="reduce_amount" jdbcType="DECIMAL" property="reduceAmount"/> |
| | | <result column="coupon_discount" jdbcType="DECIMAL" property="couponDiscount"/> |
| | | <result column="valid_time_type" jdbcType="TINYINT" property="validTimeType"/> |
| | | <result column="launch_time" jdbcType="TIMESTAMP" property="launchTime"/> |
| | | <result column="start_time" jdbcType="TIMESTAMP" property="startTime"/> |
| | | <result column="end_time" jdbcType="TIMESTAMP" property="endTime"/> |
| | | <result column="after_receive_days" jdbcType="INTEGER" property="afterReceiveDays"/> |
| | | <result column="valid_days" jdbcType="INTEGER" property="validDays"/> |
| | | <result column="stocks" jdbcType="INTEGER" property="stocks"/> |
| | | <result column="source_stock" jdbcType="INTEGER" property="sourceStock"/> |
| | | <result column="suitable_prod_type" jdbcType="TINYINT" property="suitableProdType"/> |
| | | <result column="limit_num" jdbcType="INTEGER" property="limitNum"/> |
| | | <result column="version" jdbcType="INTEGER" property="version"/> |
| | | <result column="overdue_status" jdbcType="TINYINT" property="overdueStatus"/> |
| | | <result column="puton_status" jdbcType="TINYINT" property="putonStatus"/> |
| | | <collection property="couponProds" ofType="com.yami.shop.coupon.common.model.CouponProd"> |
| | | <id column="coupon_prod_id" jdbcType="BIGINT" property="couponProdId"/> |
| | | <!--下面注释不要打开,有bug--> |
| | | <!--<result column="coupon_id" jdbcType="BIGINT" property="couponId"/>--> |
| | | <result column="prod_id" jdbcType="BIGINT" property="prodId"/> |
| | | <result column="prod_name" jdbcType="VARCHAR" property="prodName"/> |
| | | <result column="pic" jdbcType="VARCHAR" property="pic"/> |
| | | </collection> |
| | | </resultMap> |
| | | |
| | | <resultMap id="couponOrderDtoMap" type="com.yami.shop.bean.app.dto.CouponOrderDto"> |
| | | <result column="coupon_user_id" jdbcType="BIGINT" property="couponUserId"/> |
| | | <result column="coupon_id" jdbcType="BIGINT" property="couponId"/> |
| | | <result column="shop_id" jdbcType="BIGINT" property="shopId"/> |
| | | <result column="coupon_name" jdbcType="VARCHAR" property="couponName"/> |
| | | <result column="sub_title" jdbcType="VARCHAR" property="subTitle"/> |
| | | <result column="coupon_type" jdbcType="TINYINT" property="couponType"/> |
| | | <result column="cash_condition" jdbcType="DECIMAL" property="cashCondition"/> |
| | | <result column="reduce_amount" jdbcType="DECIMAL" property="reduceAmount"/> |
| | | <result column="coupon_discount" jdbcType="DECIMAL" property="couponDiscount"/> |
| | | <result column="user_start_time" jdbcType="TIMESTAMP" property="startTime"/> |
| | | <result column="user_end_time" jdbcType="TIMESTAMP" property="endTime"/> |
| | | <result column="suitable_prod_type" jdbcType="TINYINT" property="suitableProdType"/> |
| | | <result column="coupon_user_id" jdbcType="BIGINT" property="couponUserId"/> |
| | | <result column="receive_time" jdbcType="TIMESTAMP" property="receiveTime"/> |
| | | <result column="valid_time_type" jdbcType="BIGINT" property="validTimeType"/> |
| | | <result column="after_receive_days" jdbcType="BIGINT" property="afterReceiveDays"/> |
| | | <result column="valid_days" jdbcType="BIGINT" property="validDays"/> |
| | | <collection property="prodIds" javaType="java.util.List" ofType="long"> |
| | | <result column="prodIds"/> |
| | | </collection> |
| | | </resultMap> |
| | | |
| | | |
| | | |
| | | <resultMap id="couponProdDtoMap" type="com.yami.shop.bean.app.dto.CouponDto"> |
| | | <id column="coupon_id" jdbcType="BIGINT" property="couponId"/> |
| | | <result column="shop_id" jdbcType="BIGINT" property="shopId"/> |
| | | <result column="shop_name" jdbcType="VARCHAR" property="shopName"/> |
| | | <result column="shop_logo" jdbcType="VARCHAR" property="shopLogo"/> |
| | | <result column="coupon_name" jdbcType="VARCHAR" property="couponName"/> |
| | | <result column="sub_title" jdbcType="VARCHAR" property="subTitle"/> |
| | | <result column="coupon_type" jdbcType="TINYINT" property="couponType"/> |
| | | <result column="cash_condition" jdbcType="DECIMAL" property="cashCondition"/> |
| | | <result column="reduce_amount" jdbcType="DECIMAL" property="reduceAmount"/> |
| | | <result column="coupon_discount" jdbcType="DECIMAL" property="couponDiscount"/> |
| | | <result column="source_stock" jdbcType="INTEGER" property="sourceStock"/> |
| | | <result column="stocks" jdbcType="INTEGER" property="stocks"/> |
| | | <result column="start_time" jdbcType="TIMESTAMP" property="startTime"/> |
| | | <result column="end_time" jdbcType="TIMESTAMP" property="endTime"/> |
| | | <result column="suitable_prod_type" jdbcType="TINYINT" property="suitableProdType"/> |
| | | <result column="coupon_user_id" jdbcType="BIGINT" property="couponUserId"/> |
| | | <result column="receive_time" jdbcType="TIMESTAMP" property="receiveTime"/> |
| | | <result column="valid_time_type" jdbcType="BIGINT" property="validTimeType"/> |
| | | <result column="after_receive_days" jdbcType="BIGINT" property="afterReceiveDays"/> |
| | | <result column="valid_days" jdbcType="BIGINT" property="validDays"/> |
| | | <result column="cur_user_receive_count" jdbcType="BIGINT" property="curUserReceiveCount"/> |
| | | <result column="user_use_count" jdbcType="INTEGER" property="userHasCount"/> |
| | | <result column="limit_num" jdbcType="INTEGER" property="limitNum"/> |
| | | <collection property="prods" javaType="java.util.List" ofType="com.yami.shop.bean.app.dto.ProductDto" column="coupon_id"> |
| | | <id column="prod_id" jdbcType="BIGINT" property="prodId"/> |
| | | <result column="prod_name" jdbcType="VARCHAR" property="prodName"/> |
| | | <result column="pic" jdbcType="VARCHAR" property="pic"/> |
| | | <result column="price" jdbcType="DECIMAL" property="price"/> |
| | | </collection> |
| | | </resultMap> |
| | | |
| | | |
| | | <select id="getCouponAndCouponProdsByCouponId" resultMap="CouponAndCouponProdMap"> |
| | | select c.*,cp.*,p.* from tz_coupon c |
| | | left join tz_coupon_prod cp on c.coupon_id = cp.coupon_id |
| | | left join tz_prod p on cp.prod_id = p.prod_id |
| | | where c.coupon_id = #{id} |
| | | </select> |
| | | |
| | | <update id="updateCouponStocksAndVersion"> |
| | | update tz_coupon set version = version + 1, stocks = stocks - 1 where coupon_id = #{couponId} and stocks > 0 |
| | | </update> |
| | | |
| | | <update id="updateOverdueStatusByTime"> |
| | | update tz_coupon set overdue_status = 0, puton_status = -1 where end_time < #{now} and valid_time_type = 1 |
| | | </update> |
| | | |
| | | <update id="putonCoupon"> |
| | | update tz_coupon set puton_status = 1 where launch_time <= #{now} and overdue_status = 1 and stocks > 0 and puton_status = 0 |
| | | </update> |
| | | |
| | | <select id="getCouponList" resultMap="couponProdDtoMap"> |
| | | SET @tmp=NULL; |
| | | SET @rank=NULL; |
| | | SELECT item.*,sd.shop_logo,sd.shop_name,pl.prod_name FROM |
| | | ( |
| | | SELECT IF(@tmp=coupon.coupon_id,@rank:=@rank + 1,@rank:=1) AS new_rank,@tmp:=coupon.coupon_id AS tmp, coupon.* FROM ( |
| | | <!--全部商品参与--> |
| | | SELECT c.*,p.pic,p.price,p.prod_id |
| | | FROM (SELECT * FROM tz_coupon WHERE suitable_prod_type = 0 AND coupon_id IN |
| | | <foreach collection="couponIds" item="couponId" separator="," open="(" close=")"> |
| | | #{couponId} |
| | | </foreach> |
| | | ) c |
| | | JOIN tz_prod p ON p.status = 1 AND c.shop_id = p.shop_id AND p.prod_type < 3 |
| | | UNION ALL |
| | | <!--指定商品参与--> |
| | | SELECT c.*,p.pic,p.price,p.prod_id |
| | | FROM (SELECT * FROM tz_coupon WHERE suitable_prod_type = 1 AND coupon_id IN |
| | | <foreach collection="couponIds" item="couponId" separator="," open="(" close=")"> |
| | | #{couponId} |
| | | </foreach> |
| | | ) c |
| | | LEFT JOIN tz_coupon_prod cp ON cp.`coupon_id` = c.`coupon_id` |
| | | JOIN tz_prod p ON p.status = 1 AND p.prod_id = cp.prod_id |
| | | UNION ALL |
| | | <!--指定商品不参与--> |
| | | SELECT c.*,p.pic,p.price,p.prod_id |
| | | FROM ( |
| | | SELECT * FROM tz_coupon WHERE suitable_prod_type = 2 AND coupon_id IN |
| | | <foreach collection="couponIds" item="couponId" separator="," open="(" close=")"> |
| | | #{couponId} |
| | | </foreach> |
| | | ) c |
| | | JOIN tz_prod p ON p.status = 1 AND p.prod_type < 3 AND p.prod_id NOT IN (SELECT prod_id FROM tz_coupon_prod WHERE coupon_id = c.coupon_id) AND p.shop_id = c.shop_id |
| | | ) AS coupon |
| | | order by coupon.coupon_id desc |
| | | ) AS item |
| | | JOIN tz_shop_detail sd ON sd.shop_id = item.shop_id AND sd.shop_status = 1 |
| | | LEFT JOIN tz_prod_lang pl ON pl.prod_id = item.prod_id AND pl.lang = #{lang} |
| | | WHERE item.new_rank IN (1,2,3) AND item.prod_id IS NOT NULL |
| | | </select> |
| | | |
| | | <select id="getCouponListTourist" resultMap="couponProdDtoMap"> |
| | | SET @tmp=NULL; |
| | | SET @rank=NULL; |
| | | set @id=NULL; |
| | | <!--指定商品参与--> |
| | | <if test="couponForProd != null and couponForProd.size() > 0"> |
| | | SELECT pc.* |
| | | FROM ( SELECT cp.prod_id,cp.pic,cp.price,cp.prod_name,c.* |
| | | FROM ( |
| | | SELECT IF(@tmp=cp.coupon_id,@rank:=@rank + 1,@rank:=1) AS new_rank,@tmp:=coupon_id AS tmp,cp.coupon_prod_id,cp.coupon_id,p.prod_id,p.pic,p.price,p.prod_name |
| | | FROM tz_coupon_prod cp |
| | | JOIN tz_prod p ON p.prod_id = cp.`prod_id` AND p.`status` = 1 |
| | | WHERE cp.coupon_id IN |
| | | <foreach collection="couponForProd" item="couponId" separator="," open="(" close=")"> |
| | | #{couponId} |
| | | </foreach> |
| | | ORDER BY cp.coupon_id |
| | | ) AS cp |
| | | JOIN tz_coupon c ON c.coupon_id = cp.coupon_id WHERE cp.new_rank <= 3 |
| | | ) AS pc |
| | | <if test="(couponForAllProd != null and couponForAllProd.size() > 0) or (couponForElseProd != null and couponForElseProd.size() > 0)"> |
| | | UNION |
| | | </if> |
| | | </if> |
| | | <if test="(couponForAllProd != null and couponForAllProd.size() > 0) or (couponForElseProd != null and couponForElseProd.size() > 0)"> |
| | | SELECT pc.* |
| | | FROM ( |
| | | SELECT temp.prod_id,temp.pic,temp.price,temp.prod_name,c.* |
| | | FROM ( |
| | | <!--全部商品参与--> |
| | | <foreach collection="couponForAllProd" item="coupon" separator="UNION"> |
| | | (SELECT @id:=#{coupon.couponId} AS temp_id,p.* FROM tz_prod p WHERE p.status = 1 AND p.shop_id = #{coupon.shopId} LIMIT 0,3) |
| | | </foreach> |
| | | <if test="couponForAllProd != null and couponForAllProd.size() > 0 and couponForElseProd != null and couponForElseProd.size() > 0"> |
| | | UNION |
| | | </if> |
| | | <!--指定商品不参与--> |
| | | <if test="couponForElseProd != null and couponForElseProd.size() > 0"> |
| | | <foreach collection="couponForElseProd" item="coupon" separator="UNION"> |
| | | (SELECT @id:=#{coupon.couponId} AS temp_id,p.* FROM tz_prod p WHERE p.status = 1 AND p.shop_id = #{coupon.shopId} |
| | | AND p.prod_id NOT IN (SELECT prod_id FROM tz_coupon_prod WHERE coupon_id = #{coupon.couponId}) LIMIT 0,3) |
| | | </foreach> |
| | | </if> |
| | | ) AS temp |
| | | JOIN tz_coupon c |
| | | ON c.coupon_id = temp.temp_id |
| | | ) AS pc |
| | | </if> |
| | | </select> |
| | | |
| | | <!--<select id="generalCouponList" resultType="com.yami.shop.bean.app.dto.CouponDto">--> |
| | | <!--SELECT tc.*,tsd.`shop_name`--> |
| | | <!--FROM tz_coupon tc--> |
| | | <!--JOIN tz_shop_detail tsd--> |
| | | <!--ON tsd.`shop_id` = tc.`shop_id`--> |
| | | <!--WHERE--> |
| | | <!--tc.suitable_prod_type =0 -- 获取全部商品券--> |
| | | <!--<!–AND tc.`stocks` >0–>--> |
| | | <!--AND tc.`overdue_status` =1 AND tc.`puton_status` = 1 and tsd.shop_status = 1--> |
| | | <!--AND tc.`is_score_type` <![CDATA[<>]]> 1--> |
| | | <!--ORDER BY tc.start_time DESC--> |
| | | <!--</select>--> |
| | | |
| | | <select id="generalCouponList" resultType="com.yami.shop.bean.app.dto.CouponDto"> |
| | | SELECT c.*,cu.* |
| | | FROM tz_coupon c |
| | | LEFT JOIN |
| | | ( |
| | | SELECT coupon_id, COUNT(*) cur_user_receive_count, SUM(IF(`status` = 1,1,0)) user_has_count FROM tz_coupon_user |
| | | WHERE user_id = #{userId} |
| | | GROUP BY coupon_id |
| | | ) AS cu ON cu.coupon_id = c.coupon_id |
| | | WHERE c.shop_id = 0 |
| | | AND c.`overdue_status` =1 AND c.`puton_status` = 1 |
| | | AND c.`is_score_type` <![CDATA[<>]]> 1 AND IFNULL(c.`get_way`,0) <![CDATA[<>]]> 1 |
| | | ORDER BY c.coupon_id DESC |
| | | </select> |
| | | |
| | | <select id="generalCouponListTourist" resultType="com.yami.shop.bean.app.dto.CouponDto"> |
| | | SELECT c.* |
| | | FROM tz_coupon c |
| | | WHERE c.shop_id = 0 |
| | | AND c.`overdue_status` =1 AND c.`puton_status` = 1 |
| | | AND c.`is_score_type` <![CDATA[<>]]> 1 AND IFNULL(c.`get_way`,0) <![CDATA[<>]]> 1 |
| | | ORDER BY c.coupon_id DESC |
| | | </select> |
| | | |
| | | <select id="getCouponListByStatus" resultType="com.yami.shop.bean.app.dto.CouponDto"> |
| | | SELECT tc.*,tcu.*,sd.shop_name |
| | | FROM tz_coupon_user tcu |
| | | INNER JOIN tz_coupon tc |
| | | ON tcu.`coupon_id` = tc.`coupon_id` |
| | | LEFT JOIN tz_shop_detail sd |
| | | ON tc.`shop_id` = sd.shop_id |
| | | WHERE tcu.`user_id` = #{userId} |
| | | AND tc.puton_status NOT IN (2,3) |
| | | AND tcu.`status` = #{status} |
| | | AND tcu.is_delete = 0 |
| | | </select> |
| | | <!--AND tc.puton_status = 1--> |
| | | |
| | | <select id="getCouponListByShopIds" resultMap="couponOrderDtoMap"> |
| | | select tc.*,tcp.prod_id as prodIds,tcu.* from tz_coupon tc |
| | | join tz_coupon_user tcu on tc.coupon_id = tcu.coupon_id |
| | | left join tz_coupon_prod tcp on tcp.coupon_id = tc.coupon_id |
| | | where tcu.user_id = #{userId} |
| | | -- 获取用户未使用的优惠券 |
| | | AND tc.puton_status NOT IN (2,3) |
| | | and tcu.status = 1 |
| | | and tcu.is_delete = 0 |
| | | and tc.shop_id = #{shopId} |
| | | </select> |
| | | <!--and tc.puton_status = 1--> |
| | | |
| | | <select id="listOverdueStatusShopIds" resultType="long"> |
| | | SELECT shop_id FROM tz_coupon |
| | | WHERE end_time < #{now} |
| | | and valid_time_type = 1 |
| | | GROUP BY shop_id |
| | | </select> |
| | | <select id="listPutonCouponAndCouponProdsByShopId" resultMap="CouponAndCouponProdMap"> |
| | | SELECT c.*,cp.*,p.* |
| | | FROM tz_coupon c |
| | | LEFT JOIN tz_coupon_prod cp ON c.coupon_id = cp.coupon_id |
| | | LEFT JOIN tz_prod p ON cp.prod_id = p.prod_id |
| | | WHERE c.`overdue_status` = 1 AND c.puton_status =1 AND c.shop_id =#{shopId} AND c.`is_score_type` <![CDATA[<>]]> 1 |
| | | ORDER BY c.`start_time` DESC |
| | | </select> |
| | | <select id="listCouponIdsByUserId" resultType="com.yami.shop.bean.app.dto.CouponDto"> |
| | | SELECT tcu.coupon_id,tcu.`status`,COUNT(tcu.coupon_id) AS cur_user_receive_count |
| | | FROM tz_coupon_user tcu |
| | | LEFT JOIN tz_coupon tc |
| | | ON tcu.`coupon_id` = tc.`coupon_id` |
| | | WHERE tcu.`user_id` = #{userId} |
| | | AND tcu.is_delete = 0 |
| | | GROUP BY tcu.coupon_id,tcu.`status` |
| | | </select> |
| | | <!--AND tc.puton_status = 1--> |
| | | |
| | | <select id="getCouponCountByStatus" resultType="map"> |
| | | SELECT |
| | | COUNT(CASE WHEN cu.`status` = 0 THEN 1 ELSE NULL END) AS 'expiredCount' ,-- 失效 |
| | | COUNT(CASE WHEN cu.`status` = 1 THEN 1 ELSE NULL END) AS 'unUseCount', -- 有效 |
| | | COUNT(CASE WHEN cu.`status` = 2 THEN 1 ELSE NULL END) AS 'useCount' -- 过期 |
| | | FROM tz_coupon_user cu |
| | | INNER JOIN tz_coupon c |
| | | ON c.`coupon_id` = cu.`coupon_id` AND c.puton_status NOT IN (2,3) |
| | | WHERE cu.`user_id` =#{userId} |
| | | AND cu.`is_delete` = 0 |
| | | </select> |
| | | <!--AND c.`puton_status` =1--> |
| | | |
| | | <select id="getPlatformPage" resultType="com.yami.shop.coupon.common.model.Coupon"> |
| | | SELECT c.*,sd.shop_name `shop_name` |
| | | FROM tz_coupon c |
| | | LEFT JOIN tz_shop_detail sd ON c.`shop_id` = sd.`shop_id` |
| | | <where> |
| | | <if test="coupon.shopId != null"> |
| | | AND c.shop_id = #{coupon.shopId} |
| | | </if> |
| | | <if test="coupon.shopId == null"> |
| | | AND c.shop_id != 0 |
| | | </if> |
| | | <if test="coupon.couponName !=null"> |
| | | and trim(replace(c.coupon_name,' ','')) like trim(replace(concat('%',#{coupon.couponName},'%'),' ','')) |
| | | </if> |
| | | <if test="coupon.putonStatus != null"> |
| | | AND c.puton_status = #{coupon.putonStatus} |
| | | </if> |
| | | <if test="coupon.overdueStatus != null"> |
| | | AND c.overdue_status = #{coupon.overdueStatus} |
| | | </if> |
| | | <if test="coupon.endTime != null"> |
| | | AND c.end_time <= #{coupon.endTime} |
| | | </if> |
| | | <if test="coupon.startTime != null"> |
| | | AND c.start_time >= #{coupon.startTime} |
| | | </if> |
| | | <if test="coupon.couponType != null"> |
| | | AND c.coupon_type = #{coupon.couponType} |
| | | </if> |
| | | <if test="coupon.isScoreType != null"> |
| | | AND c.is_score_type = #{coupon.isScoreType} |
| | | </if> |
| | | <if test="coupon.shopName != null"> |
| | | and trim(replace(sd.shop_name,' ','')) like trim(replace(concat('%',#{coupon.shopName},'%'),' ','')) |
| | | </if> |
| | | </where> |
| | | ORDER BY c.`coupon_id` DESC |
| | | </select> |
| | | <select id="getMultiShopPage" resultType="com.yami.shop.coupon.common.model.Coupon"> |
| | | SELECT c.* |
| | | FROM tz_coupon c |
| | | LEFT JOIN tz_shop_detail sd ON c.`shop_id` = sd.`shop_id` |
| | | <where> |
| | | <if test="coupon.shopId != null"> |
| | | AND c.shop_id = #{coupon.shopId} |
| | | </if> |
| | | <if test="coupon.couponName !=null"> |
| | | and trim(replace(c.coupon_name,' ','')) like trim(replace(concat('%',#{coupon.couponName},'%'),' ','')) |
| | | </if> |
| | | <if test="coupon.putonStatus != null"> |
| | | AND c.puton_status = #{coupon.putonStatus} |
| | | </if> |
| | | <if test="coupon.overdueStatus != null"> |
| | | AND c.overdue_status = #{coupon.overdueStatus} |
| | | </if> |
| | | <if test="coupon.endTime != null"> |
| | | AND c.end_time <= #{coupon.endTime} |
| | | </if> |
| | | <if test="coupon.startTime != null"> |
| | | AND c.start_time >= #{coupon.startTime} |
| | | </if> |
| | | <if test="coupon.couponType != null"> |
| | | AND c.coupon_type = #{coupon.couponType} |
| | | </if> |
| | | </where> |
| | | ORDER BY c.`coupon_id` DESC |
| | | </select> |
| | | <select id="countTakeNum" resultType="java.lang.Integer"> |
| | | select COUNT(cu.coupon_user_id) |
| | | from `tz_coupon_user` cu |
| | | left join `tz_coupon` c on cu.coupon_id = c.coupon_id |
| | | <where> cu.coupon_id = #{couponId} |
| | | <if test="shopId != null"> |
| | | AND c.shop_id = #{shopId} |
| | | </if> |
| | | </where> |
| | | GROUP BY cu.coupon_id |
| | | </select> |
| | | <select id="countUseNum" resultType="java.lang.Integer"> |
| | | select count(cur.coupon_use_record_id) |
| | | from `tz_coupon_user` cu |
| | | LEFT JOIN `tz_coupon_use_record` cur ON cur.coupon_user_id = cu.coupon_user_id |
| | | where cu.coupon_id = #{couponId} and cur.`status`!=3 |
| | | group by cu.coupon_id |
| | | </select> |
| | | <update id="updatePutOnStatusByCouponId"> |
| | | UPDATE tz_coupon c SET c.`puton_status` =#{status} WHERE c.`coupon_id` = #{couponId} |
| | | </update> |
| | | |
| | | <select id="getShopAvailableCouponIds" resultType="java.lang.Long"> |
| | | SELECT c.coupon_id FROM tz_coupon c |
| | | LEFT JOIN tz_coupon_prod cp ON cp.`coupon_id` = c.`coupon_id` |
| | | JOIN tz_prod p ON p.status = 1 AND p.prod_type < 3 AND |
| | | ((c.shop_id = p.shop_id AND c.suitable_prod_type=0) OR (p.prod_id = cp.prod_id AND c.suitable_prod_type=1) OR (p.prod_id != cp.prod_id AND c.suitable_prod_type=2 AND p.shop_id = c.shop_id)) |
| | | JOIN tz_shop_detail sd ON sd.shop_id = c.shop_id AND sd.shop_status = 1 |
| | | WHERE c.overdue_status = 1 AND c.puton_status = 1 AND c.is_score_type = 0 AND c.shop_id != 0 |
| | | GROUP BY c.coupon_id |
| | | ORDER BY c.coupon_id DESC |
| | | LIMIT #{adapter.begin}, #{adapter.size} |
| | | </select> |
| | | <update id="updateOverdueStatusByCouponId"> |
| | | UPDATE tz_coupon c SET c.`overdue_status` =#{overdueStatus} WHERE c.`coupon_id` = #{couponId} |
| | | </update> |
| | | <select id="countCouponPageByCouponDto" resultType="long"> |
| | | SELECT COUNT(DISTINCT c.coupon_id) FROM tz_coupon c |
| | | LEFT JOIN tz_coupon_prod cp ON cp.`coupon_id` = c.`coupon_id` |
| | | JOIN tz_prod p ON p.status = 1 AND p.prod_type < 3 AND ( |
| | | (c.shop_id = p.shop_id AND c.suitable_prod_type=0) OR |
| | | (p.prod_id = cp.prod_id AND c.suitable_prod_type=1) OR |
| | | (p.prod_id != cp.prod_id AND c.suitable_prod_type=2 AND p.shop_id = c.shop_id) |
| | | ) |
| | | JOIN tz_shop_detail sd ON sd.shop_id = c.shop_id AND sd.shop_status = 1 |
| | | WHERE c.overdue_status = 1 AND c.puton_status = 1 AND c.is_score_type = 0 AND c.shop_id != 0 |
| | | </select> |
| | | |
| | | <update id="updateCoupon"> |
| | | UPDATE tz_coupon |
| | | <set> |
| | | <if test="coupon.shopId != null"> |
| | | `shop_id` = #{coupon.shopId}, |
| | | </if> |
| | | <if test="coupon.couponName != null"> |
| | | `coupon_name` = #{coupon.couponName}, |
| | | </if> |
| | | <if test="coupon.couponName != null"> |
| | | `sub_title` = #{coupon.subTitle}, |
| | | </if> |
| | | <if test="coupon.couponType != null"> |
| | | `coupon_type` = #{coupon.couponType}, |
| | | </if> |
| | | <if test="coupon.cashCondition != null"> |
| | | `cash_condition` = #{coupon.cashCondition}, |
| | | </if> |
| | | <if test="coupon.reduceAmount != null"> |
| | | `reduce_amount` = #{coupon.reduceAmount}, |
| | | </if> |
| | | <if test="coupon.couponDiscount != null"> |
| | | `coupon_discount` = #{coupon.couponDiscount}, |
| | | </if> |
| | | <if test="coupon.validTimeType != null"> |
| | | `valid_time_type` = #{coupon.validTimeType}, |
| | | </if> |
| | | `launch_time` = #{coupon.launchTime}, |
| | | <if test="coupon.startTime != null"> |
| | | `start_time` = #{coupon.startTime}, |
| | | </if> |
| | | <if test="coupon.endTime != null"> |
| | | `end_time` = #{coupon.endTime}, |
| | | </if> |
| | | <if test="coupon.afterReceiveDays != null"> |
| | | `after_receive_days` = #{coupon.afterReceiveDays}, |
| | | </if> |
| | | <if test="coupon.validDays != null"> |
| | | `valid_days` = #{coupon.validDays}, |
| | | </if> |
| | | <if test="coupon.stocks != null"> |
| | | `stocks` = #{coupon.stocks}, |
| | | </if> |
| | | <if test="coupon.sourceStock != null"> |
| | | `source_stock` = #{coupon.sourceStock}, |
| | | </if> |
| | | <if test="coupon.suitableProdType != null"> |
| | | `suitable_prod_type` = #{coupon.suitableProdType}, |
| | | </if> |
| | | <if test="coupon.limitNum != null"> |
| | | `limit_num` = #{coupon.limitNum}, |
| | | </if> |
| | | <if test="coupon.version != null"> |
| | | `version` = #{coupon.version} + 1, |
| | | </if> |
| | | <if test="coupon.overdueStatus != null"> |
| | | `overdue_status` = #{coupon.overdueStatus}, |
| | | </if> |
| | | <if test="coupon.putonStatus != null"> |
| | | `puton_status` = #{coupon.putonStatus}, |
| | | </if> |
| | | <if test="coupon.getWay != null"> |
| | | `get_way` = #{coupon.getWay}, |
| | | </if> |
| | | </set> |
| | | WHERE coupon_id = #{coupon.couponId} |
| | | <if test="coupon.version != null"> |
| | | and `version` = #{coupon.version} |
| | | </if> |
| | | </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.coupon.common.dao.CouponProdMapper"> |
| | | |
| | | <resultMap id="BaseResultMap" type="com.yami.shop.coupon.common.model.CouponProd"> |
| | | <!-- |
| | | WARNING - @mbg.generated |
| | | --> |
| | | <id column="coupon_prod_id" jdbcType="BIGINT" property="couponProdId"/> |
| | | <result column="coupon_id" jdbcType="BIGINT" property="couponId"/> |
| | | <result column="prod_id" jdbcType="BIGINT" property="prodId"/> |
| | | </resultMap> |
| | | |
| | | |
| | | <delete id="deleteCouponProdsByCouponId"> |
| | | delete from tz_coupon_prod where coupon_id = #{couponId} |
| | | </delete> |
| | | |
| | | <insert id="insertCouponProdsBatch"> |
| | | insert into tz_coupon_prod (coupon_id, prod_id) values |
| | | <foreach collection="prodIds" item="prodId" separator=","> |
| | | (#{couponId}, #{prodId}) |
| | | </foreach> |
| | | </insert> |
| | | |
| | | <delete id="deleteCouponProdsByCouponIds"> |
| | | DELETE FROM tz_coupon_prod |
| | | WHERE coupon_id IN |
| | | <foreach collection="couponIds" item="couponId" separator="," open="(" close=")"> |
| | | #{couponId} |
| | | </foreach> |
| | | </delete> |
| | | </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.coupon.common.dao.CouponUseRecordMapper"> |
| | | |
| | | <resultMap id="couponUseMap" type="com.yami.shop.coupon.common.model.CouponUseRecord"> |
| | | <id property="couponUseRecordId" column="coupon_use_record_id"/> |
| | | <!--<result property="couponId" column="coupon_id"/>--> |
| | | <result property="couponUserId" column="coupon_user_id"/> |
| | | <result property="orderNumber" column="order_number"/> |
| | | <result property="userId" column="user_id"/> |
| | | <result property="amount" column="amount"/> |
| | | <result property="useTime" column="use_time"/> |
| | | </resultMap> |
| | | |
| | | <resultMap id="couponUseRecordOrderMap" type="com.yami.shop.coupon.common.model.CouponUseRecord"> |
| | | <result column="coupon_use_record_id" property="couponUseRecordId"/> |
| | | <result column="order_number" property="orderNumber"/> |
| | | <result column="status" property="status"/> |
| | | <collection property="couponUser" ofType="com.yami.shop.coupon.common.model.CouponUser"> |
| | | <id column="coupon_user_id" property="couponUserId"/> |
| | | <result column="user_end_time" property="userEndTime"/> |
| | | <collection property="coupon" ofType="com.yami.shop.coupon.common.model.Coupon"> |
| | | <id column="coupon_id" property="couponId"/> |
| | | <result column="overdue_status" property="overdueStatus"/> |
| | | <result column="puton_status" property="putonStatus"/> |
| | | </collection> |
| | | </collection> |
| | | </resultMap> |
| | | <insert id="addCouponUseRecode"> |
| | | INSERT INTO tz_coupon_use_record (coupon_user_id,user_id,order_number,amount,use_time,`status`) VALUES |
| | | <foreach collection="couponUseRecordsList" item="couponUseRecord" separator=","> |
| | | (#{couponUseRecord.couponUserId},#{couponUseRecord.userId},#{couponUseRecord.orderNumber},#{couponUseRecord.amount},#{couponUseRecord.useTime},#{couponUseRecord.status}) |
| | | </foreach> |
| | | </insert> |
| | | |
| | | <update id="batchUpdateRecordByStatusAndOrderNums"> |
| | | <foreach collection="orderNumberList" item="orderNum" separator=";"> |
| | | UPDATE tz_coupon_use_record SET `status` = #{status} |
| | | <where> |
| | | order_number like CONCAT('%',#{orderNum},'%') |
| | | </where> |
| | | </foreach> |
| | | </update> |
| | | |
| | | <select id="listByOrderNumber" resultMap="couponUseRecordOrderMap"> |
| | | SELECT cur.coupon_use_record_id,cu.coupon_user_id,cu.user_end_time,c.coupon_id,c.puton_status,c.overdue_status |
| | | FROM tz_coupon_use_record cur |
| | | JOIN tz_coupon_user cu ON cur.coupon_user_id = cu.coupon_user_id AND cu.status = 2 |
| | | JOIN tz_coupon c ON cu.coupon_id = c.coupon_id |
| | | WHERE cur.order_number = #{orderNumber} |
| | | </select> |
| | | <select id="getOrderNumberContact" resultType="com.yami.shop.coupon.common.model.CouponUseRecord"> |
| | | SELECT coupon_use_record_id,order_number |
| | | FROM tz_coupon_use_record cur |
| | | WHERE order_number LIKE CONCAT('%',#{orderNumber},'%') |
| | | </select> |
| | | |
| | | <update id="batchUpdateRecordStatusByStatusAndIds"> |
| | | <foreach collection="ids" item="id" separator=";"> |
| | | UPDATE tz_coupon_use_record SET `status` = #{status} WHERE coupon_use_record_id = #{id} |
| | | </foreach> |
| | | </update> |
| | | |
| | | <select id="listCouponUserIdsByOrderNumber" resultType="java.lang.Long"> |
| | | SELECT coupon_user_id |
| | | FROM tz_coupon_use_record |
| | | WHERE FIND_IN_SET(#{orderNumber}, order_number) |
| | | and status = 0 |
| | | </select> |
| | | |
| | | <update id="unLockByIds"> |
| | | update tz_coupon_use_record |
| | | set status = 3 where coupon_user_id in |
| | | <foreach collection="couponUserIds" item="couponUserId" separator="," open="(" close=")"> |
| | | #{couponUserId} |
| | | </foreach> |
| | | and status = 1 |
| | | </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.coupon.common.dao.CouponUserMapper"> |
| | | <resultMap id="BaseResultMap" type="com.yami.shop.coupon.common.model.CouponUser"> |
| | | <!-- |
| | | WARNING - @mbg.generated |
| | | --> |
| | | <result column="coupon_user_id" jdbcType="BIGINT" property="couponUserId"/> |
| | | <result column="coupon_id" jdbcType="BIGINT" property="couponId"/> |
| | | <result column="user_id" jdbcType="VARCHAR" property="userId"/> |
| | | <result column="receive_time" jdbcType="TIMESTAMP" property="receiveTime"/> |
| | | <result column="status" jdbcType="TINYINT" property="status"/> |
| | | <result column="user_start_time" jdbcType="TIMESTAMP" property="userStartTime"/> |
| | | <result column="user_end_time" jdbcType="TIMESTAMP" property="userEndTime"/> |
| | | <result column="is_delete" jdbcType="TINYINT" property="isDelete"/> |
| | | </resultMap> |
| | | |
| | | <resultMap id="CouponAndCouponUserMap" type="com.yami.shop.coupon.common.model.CouponUser"> |
| | | <result column="coupon_user_id" jdbcType="BIGINT" property="couponUserId"/> |
| | | <result column="coupon_id" jdbcType="BIGINT" property="couponId"/> |
| | | <result column="user_id" jdbcType="VARCHAR" property="userId"/> |
| | | <result column="receive_time" jdbcType="TIMESTAMP" property="receiveTime"/> |
| | | <result column="status" jdbcType="TINYINT" property="status"/> |
| | | <result column="user_start_time" jdbcType="TIMESTAMP" property="userStartTime"/> |
| | | <result column="user_end_time" jdbcType="TIMESTAMP" property="userEndTime"/> |
| | | <association property="coupon" javaType="com.yami.shop.coupon.common.model.Coupon"> |
| | | <result column="coupon_id" jdbcType="BIGINT" property="couponId"/> |
| | | <result column="shop_id" jdbcType="BIGINT" property="shopId"/> |
| | | <result column="coupon_name" jdbcType="VARCHAR" property="couponName"/> |
| | | <result column="sub_title" jdbcType="VARCHAR" property="subTitle"/> |
| | | <result column="coupon_type" jdbcType="TINYINT" property="couponType"/> |
| | | <result column="cash_condition" jdbcType="DECIMAL" property="cashCondition"/> |
| | | <result column="reduce_amount" jdbcType="DECIMAL" property="reduceAmount"/> |
| | | <result column="coupon_discount" jdbcType="DECIMAL" property="couponDiscount"/> |
| | | <result column="valid_time_type" jdbcType="TINYINT" property="validTimeType"/> |
| | | <result column="start_time" jdbcType="TIMESTAMP" property="startTime"/> |
| | | <result column="end_time" jdbcType="TIMESTAMP" property="endTime"/> |
| | | <result column="after_receive_days" jdbcType="INTEGER" property="afterReceiveDays"/> |
| | | <result column="valid_days" jdbcType="INTEGER" property="validDays"/> |
| | | <result column="stocks" jdbcType="INTEGER" property="stocks"/> |
| | | <result column="suitable_prod_type" jdbcType="TINYINT" property="suitableProdType"/> |
| | | <result column="limit_num" jdbcType="INTEGER" property="limitNum"/> |
| | | <result column="version" jdbcType="INTEGER" property="version"/> |
| | | <result column="overdue_status" jdbcType="TINYINT" property="overdueStatus"/> |
| | | <result column="puton_status" jdbcType="TINYINT" property="putonStatus"/> |
| | | <result column="shop_name" jdbcType="VARCHAR" property="shopName"/> |
| | | </association> |
| | | </resultMap> |
| | | |
| | | <select id="getCouponAndCouponUserByUserId" resultMap="CouponAndCouponUserMap"> |
| | | select cu.*,c.*,sd.shop_name from tz_coupon_user cu |
| | | left join tz_coupon c on cu.coupon_id = c.coupon_id |
| | | left join tz_shop_detail sd on c.shop_id = sd.shop_id |
| | | where cu.user_id = #{userId} and (cu.status = 0 or cu.status = 1) |
| | | </select> |
| | | |
| | | <select id="getCouponAndCouponUserByCouponUserIds" resultMap="CouponAndCouponUserMap"> |
| | | select cu.*,c.* from tz_coupon_user cu |
| | | left join tz_coupon c on cu.coupon_id = c.coupon_id |
| | | where cu.coupon_user_id in |
| | | <foreach collection="couponUserIds" item="couponUserId" separator="," open="(" close=")"> |
| | | #{couponUserId} |
| | | </foreach> |
| | | and cu.status = 1 and c.overdue_status = 1 and c.puton_status = 1 |
| | | </select> |
| | | <select id="getCouponAnalysisParamByDate" resultType="com.yami.shop.bean.param.CouponAnalysisParam"> |
| | | select c.coupon_name as couponName,c.coupon_type as couponType, |
| | | COUNT(cu.coupon_user_id) as takeNum, |
| | | cu.receive_time as currentDay,cu.coupon_id as couponId |
| | | from `tz_coupon_user` cu |
| | | left join `tz_coupon` c on cu.coupon_id = c.coupon_id |
| | | <where> |
| | | <if test="param.startTime != null and param.endTime != null"> |
| | | AND (cu.receive_time <![CDATA[ >= ]]> #{param.startTime} AND cu.receive_time <![CDATA[ <= ]]> #{param.endTime}) |
| | | </if> |
| | | <if test="param.shopId != null"> |
| | | AND c.shop_id = #{param.shopId} |
| | | </if> |
| | | </where> |
| | | GROUP BY cu.coupon_id |
| | | order by cu.receive_time DESC |
| | | </select> |
| | | <select id="countUseNum" resultType="java.lang.Integer"> |
| | | select count(cur.coupon_use_record_id) |
| | | from `tz_coupon_user` cu |
| | | LEFT JOIN `tz_coupon_use_record` cur ON cur.coupon_user_id = cu.coupon_user_id |
| | | <if test="param.startTime != null and param.endTime != null"> |
| | | AND (cur.use_time <![CDATA[ >= ]]> #{param.startTime} AND cur.use_time <![CDATA[ <= ]]> #{param.endTime}) |
| | | </if> |
| | | where cu.coupon_id = #{couponId} |
| | | group by cu.coupon_id |
| | | </select> |
| | | <select id="countTakeNum" resultType="java.lang.Integer"> |
| | | SELECT COUNT(coupon_user_id) |
| | | FROM `tz_coupon_user` cu LEFT JOIN `tz_coupon` tc ON cu.coupon_id = tc.coupon_id |
| | | <where> |
| | | <if test="param.shopId != null"> |
| | | AND tc.shop_id = #{param.shopId} |
| | | </if> |
| | | <if test="param.startTime != null and param.endTime != null"> |
| | | AND (cu.receive_time <![CDATA[ >= ]]> #{param.startTime} AND cu.receive_time <![CDATA[ <= ]]> #{param.endTime}) |
| | | </if> |
| | | <if test="couponId != null"> |
| | | AND cu.coupon_id = #{couponId} |
| | | </if> |
| | | <if test="status != null"> |
| | | AND cu.status = #{status} |
| | | </if> |
| | | </where> |
| | | </select> |
| | | <select id="countMemberGetCoupon" resultType="java.lang.Integer" |
| | | parameterType="com.yami.shop.bean.param.CustomerReqParam"> |
| | | SELECT COUNT(DISTINCT(cu.user_id)) |
| | | FROM `tz_coupon_user` cu LEFT JOIN `tz_coupon` tc ON cu.coupon_id = tc.coupon_id |
| | | LEFT JOIN `tz_user_extension` ue ON ue.user_id = cu.user_id |
| | | <where> |
| | | ue.level_type <![CDATA[ >= ]]> 0 |
| | | <if test="param.shopId != null"> |
| | | AND tc.shop_id = #{param.shopId} |
| | | </if> |
| | | <if test="param.startTime != null and param.endTime != null"> |
| | | AND (cu.receive_time <![CDATA[ >= ]]> #{param.startTime} AND cu.receive_time <![CDATA[ <= ]]> #{param.endTime}) |
| | | </if> |
| | | </where> |
| | | </select> |
| | | <select id="countMemberCouponByParam" resultType="java.lang.Integer" |
| | | parameterType="com.yami.shop.bean.param.MemberReqParam"> |
| | | SELECT COUNT(DISTINCT(cu.user_id)) |
| | | FROM `tz_coupon_user` cu LEFT JOIN `tz_coupon` tc ON cu.coupon_id = tc.coupon_id |
| | | LEFT JOIN `tz_user_extension` ue ON ue.user_id = cu.user_id |
| | | <where> |
| | | <choose> |
| | | <when test="param.memberType == 1"> |
| | | AND ue.level_type = 0 |
| | | </when> |
| | | <when test="param.memberType == 2"> |
| | | AND ue.level_type = 1 |
| | | </when> |
| | | </choose> |
| | | <if test="param.shopId != null"> |
| | | AND tc.shop_id = #{param.shopId} |
| | | </if> |
| | | <if test="param.startTime != null and param.endTime != null"> |
| | | AND (cu.receive_time <![CDATA[ >= ]]> #{param.startTime} AND cu.receive_time <![CDATA[ <= ]]> #{param.endTime}) |
| | | </if> |
| | | </where> |
| | | </select> |
| | | |
| | | <select id="countCouponUsedNums" resultType="java.lang.Integer" parameterType="java.lang.String"> |
| | | SELECT COUNT(1) FROM `tz_coupon_user` cu |
| | | WHERE cu.status = 2 AND cu.user_id = #{userId} AND cu.is_delete = 0 |
| | | </select> |
| | | <select id="countCouponExpiredNums" resultType="java.lang.Integer" parameterType="java.lang.String"> |
| | | SELECT COUNT(1) FROM `tz_coupon_user` cu |
| | | WHERE cu.status = 0 AND cu.user_id = #{userId} AND cu.is_delete = 0 |
| | | </select> |
| | | <select id="countCouponUsableNums" resultType="java.lang.Integer"> |
| | | SELECT COUNT(1) FROM `tz_coupon_user` cu |
| | | WHERE cu.user_id = #{userId} AND cu.is_delete = 0 |
| | | AND cu.status = 1 |
| | | </select> |
| | | <select id="getPageByUserId" resultMap="CouponAndCouponUserMap"> |
| | | SELECT |
| | | cu.coupon_user_id, |
| | | c.coupon_name, |
| | | c.coupon_type, |
| | | cu.user_start_time, |
| | | cu.user_end_time, |
| | | cu.status, |
| | | c.cash_condition, |
| | | c.reduce_amount, |
| | | c.coupon_discount, |
| | | cu.receive_time |
| | | FROM `tz_coupon_user` cu |
| | | LEFT JOIN `tz_coupon` c ON c.coupon_id = cu.coupon_id |
| | | <where> |
| | | cu.user_id = #{userId} AND cu.is_delete = 0 |
| | | <if test="status != null"> |
| | | AND cu.status = #{status} |
| | | </if> |
| | | </where> |
| | | ORDER BY cu.receive_time DESC |
| | | </select> |
| | | |
| | | <delete id="deleteUnValidTimeCoupons"> |
| | | delete from tz_coupon_user where user_end_time < #{date} and status = 0 |
| | | </delete> |
| | | |
| | | <update id="updateStatusByTime"> |
| | | update tz_coupon_user set status = 0 where user_end_time < #{now} |
| | | </update> |
| | | |
| | | <update id="deleteUserCoupon"> |
| | | UPDATE tz_coupon_user cu SET cu.is_delete =1 WHERE cu.user_id =#{userId} AND cu.coupon_id = #{couponId} |
| | | </update> |
| | | |
| | | <update id="updateUseStatusByCouponUserId"> |
| | | UPDATE tz_coupon_user SET `status` = #{status} WHERE coupon_user_id = #{couponUserId} |
| | | </update> |
| | | |
| | | <update id="batchUpdateUserCouponStatus"> |
| | | UPDATE tz_coupon_user SET `status` = #{status} |
| | | WHERE coupon_user_id IN |
| | | <foreach collection="couponUserIds" item="userCouponId" open="(" close=")" separator=","> |
| | | #{userCouponId} |
| | | </foreach> |
| | | </update> |
| | | |
| | | <update id="updateStatusByOrderNumber"> |
| | | UPDATE tz_coupon_user SET `status` = #{status} |
| | | WHERE order_number = #{orderNumber} |
| | | </update> |
| | | |
| | | <select id="countNormalByCouponUserId" resultType="int"> |
| | | select ifnull(count(*),0) from tz_coupon tc |
| | | join tz_coupon_user tcu on tc.coupon_id = tcu.coupon_id |
| | | left join tz_coupon_prod tcp on tcp.coupon_id = tc.coupon_id |
| | | where tcu.user_id = #{userId} |
| | | -- 获取用户未使用的优惠券 |
| | | and tc.puton_status NOT IN (2,3) |
| | | and tcu.status = 1 |
| | | and tcu.is_delete = 0 |
| | | and tcu.coupon_user_id in |
| | | <foreach collection="couponUserIds" item="couponUserId" separator="," open="(" close=")"> |
| | | #{couponUserId} |
| | | </foreach> |
| | | </select> |
| | | |
| | | <select id="listByCouponIdsAndUserId" resultType="com.yami.shop.coupon.common.model.CouponUser"> |
| | | SELECT coupon_id, COUNT(*) cur_user_receive_count FROM tz_coupon_user |
| | | WHERE `status` = 1 AND user_id = #{userId} |
| | | GROUP BY coupon_id |
| | | </select> |
| | | <select id="getCouponCountInfo" resultType="com.yami.shop.bean.param.CouponUserParam"> |
| | | SELECT |
| | | IFNULL(SUM(IF(cu.`status` = 0, 1, 0)), 0) couponExpiredNums, |
| | | IFNULL(SUM(IF(cu.`status` = 1, 1, 0)), 0) couponUsableNums, |
| | | IFNULL(SUM(IF(cu.`status` = 2, 1, 0)), 0) couponUsedNums |
| | | FROM `tz_coupon_user` cu |
| | | LEFT JOIN `tz_coupon` c ON cu.coupon_id = c.coupon_id |
| | | <if test="shopId != null"> |
| | | AND c.shop_id = #{shopId} |
| | | </if> |
| | | WHERE cu.user_id = #{userId} AND cu.is_delete = 0 |
| | | </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> |
| | | <artifactId>yami-shop-coupon</artifactId> |
| | | <groupId>com.yami.shop</groupId> |
| | | <version>0.0.1-SNAPSHOT</version> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>yami-shop-coupon-multishop</artifactId> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.yami.shop</groupId> |
| | | <artifactId>yami-shop-coupon-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.coupon.multishop.config; |
| | | |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import org.springdoc.core.GroupedOpenApi; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | |
| | | /** |
| | | * 优惠券 |
| | | * @author lanhai |
| | | */ |
| | | @Configuration("couponSwaggerConfiguration") |
| | | @AllArgsConstructor |
| | | public class SwaggerConfiguration { |
| | | |
| | | |
| | | @Bean |
| | | public GroupedOpenApi couponRestApi() { |
| | | return GroupedOpenApi.builder() |
| | | .group("优惠券接口") |
| | | .packagesToScan("com.yami.shop.coupon.multishop.controller") |
| | | .pathsToMatch("/**") |
| | | .build(); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.multishop.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.enums.OfflineHandleEventType; |
| | | import com.yami.shop.bean.model.OfflineHandleEvent; |
| | | import com.yami.shop.bean.param.OfflineHandleEventAuditParam; |
| | | import com.yami.shop.bean.param.SendUserCouponsParam; |
| | | 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.coupon.common.constants.CouponStatusEnum; |
| | | import com.yami.shop.coupon.common.constants.ValidTimeTypeEnum; |
| | | import com.yami.shop.coupon.common.model.Coupon; |
| | | import com.yami.shop.coupon.common.param.UserCouponParam; |
| | | import com.yami.shop.coupon.common.service.CouponService; |
| | | import com.yami.shop.security.common.enums.SysTypeEnum; |
| | | import com.yami.shop.security.multishop.util.SecurityUtils; |
| | | import com.yami.shop.service.OfflineHandleEventService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | 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.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * @author lgh on 2018/12/27. |
| | | */ |
| | | @RestController("adminCouponController") |
| | | @RequestMapping("/admin/coupon") |
| | | @Tag(name = "商家端优惠券接口") |
| | | public class CouponController { |
| | | |
| | | @Autowired |
| | | private CouponService couponService; |
| | | |
| | | @Autowired |
| | | private OfflineHandleEventService offlineHandleEventService; |
| | | |
| | | @GetMapping("/page") |
| | | @PreAuthorize("@pms.hasPermission('admin:coupon:page')") |
| | | @Operation(summary = "分页获取优惠券列表信息") |
| | | public ServerResponseEntity<IPage<Coupon>> page(@ParameterObject Coupon coupon, PageParam<Coupon> page) { |
| | | Long shopId = SecurityUtils.getShopUser().getShopId(); |
| | | coupon.setShopId(shopId); |
| | | IPage<Coupon> multiShopPage = couponService.getMultiShopPage(page, coupon); |
| | | return ServerResponseEntity.success(multiShopPage); |
| | | } |
| | | |
| | | @GetMapping("/info/{id}") |
| | | @Operation(summary = "根据优惠券id获取优惠券信息") |
| | | @Parameter(name = "id", description = "优惠券id" ) |
| | | public ServerResponseEntity<Coupon> info(@PathVariable("id") Long id) { |
| | | Coupon coupon = couponService.getCouponAndCouponProdsByCouponId(id); |
| | | if (!Objects.equals(SecurityUtils.getShopUser().getShopId(), coupon.getShopId())) { |
| | | throw new YamiShopBindException("yami.no.auth"); |
| | | } |
| | | return ServerResponseEntity.success(coupon); |
| | | } |
| | | |
| | | @PostMapping |
| | | @PreAuthorize("@pms.hasPermission('admin:coupon:save')") |
| | | @Operation(summary = "新增优惠券") |
| | | public ServerResponseEntity<Long> save(@RequestBody @Valid Coupon coupon) { |
| | | Long shopId = SecurityUtils.getShopUser().getShopId(); |
| | | coupon.setShopId(shopId); |
| | | coupon.setSourceStock(coupon.getStocks()); |
| | | //判断为领取后生效类型时,开始时间和结束时间为空 |
| | | if (Objects.equals(coupon.getValidTimeType(), ValidTimeTypeEnum.RECEIVE.getValue())) { |
| | | coupon.setEndTime(null); |
| | | coupon.setStartTime(null); |
| | | } |
| | | couponService.insertCouponAndCouponProds(coupon); |
| | | return ServerResponseEntity.success(coupon.getCouponId()); |
| | | } |
| | | |
| | | @PutMapping |
| | | @PreAuthorize("@pms.hasPermission('admin:coupon:update')") |
| | | @Operation(summary = "修改优惠券") |
| | | public ServerResponseEntity<Void> update(@RequestBody @Valid Coupon coupon) { |
| | | Long shopId = SecurityUtils.getShopUser().getShopId(); |
| | | Coupon dbCoupon = couponService.getById(coupon.getCouponId()); |
| | | if (!Objects.equals(dbCoupon.getShopId(), shopId)) { |
| | | // 没有权限修改该优惠券信息 |
| | | throw new YamiShopBindException("yami.coupon.no.auth"); |
| | | } |
| | | if (Objects.equals(dbCoupon.getPutonStatus(), CouponStatusEnum.OFFLINE.getValue()) || Objects.equals(dbCoupon.getPutonStatus(), CouponStatusEnum.WAIT_AUDIT.getValue())) { |
| | | // 优惠券处于违规下线或者待审核状态时,商家不能直接修改优惠券状态 |
| | | coupon.setPutonStatus(dbCoupon.getPutonStatus()); |
| | | } else if (Objects.equals(coupon.getPutonStatus(), CouponStatusEnum.OFFLINE.getValue()) || Objects.equals(coupon.getPutonStatus(), CouponStatusEnum.WAIT_AUDIT.getValue())) { |
| | | // 当数据库中的优惠券状态不是违规下线或者待审核状态时,如果接口传进来的优惠券状态为违规下线或者待审核状态,说明该优惠券应该已经被审核了 |
| | | // 使用数据库的优惠券状态 |
| | | coupon.setPutonStatus(dbCoupon.getPutonStatus()); |
| | | } |
| | | coupon.setShopId(shopId); |
| | | //被领取数量 |
| | | int receNum = dbCoupon.getSourceStock() - dbCoupon.getStocks(); |
| | | //新的原始库存 |
| | | int newSourceStock = coupon.getStocks() + receNum; |
| | | coupon.setSourceStock(newSourceStock); |
| | | couponService.updateCouponAndCouponProds(coupon); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @DeleteMapping |
| | | @PreAuthorize("@pms.hasPermission('admin:coupon:delete')") |
| | | @Operation(summary = "删除优惠券") |
| | | public ServerResponseEntity<Void> delete(@RequestBody Long couponId) { |
| | | Long shopId = SecurityUtils.getShopUser().getShopId(); |
| | | Coupon dbCoupon = couponService.getById(couponId); |
| | | if (!Objects.equals(dbCoupon.getShopId(), shopId)) { |
| | | // 没有权限修改该优惠券信息 |
| | | throw new YamiShopBindException("yami.coupon.no.auth"); |
| | | } |
| | | couponService.deleteByCouponId(couponId); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @GetMapping("/getOfflineHandleEventByCouponId/{couponId}") |
| | | @Operation(summary = "通过优惠券id获取下线信息") |
| | | @Parameter(name = "couponId", description = "优惠券id" ) |
| | | public ServerResponseEntity<OfflineHandleEvent> getOfflineHandleEventByDiscountId(@PathVariable("couponId") Long couponId) { |
| | | OfflineHandleEvent offlineHandleEvent = offlineHandleEventService.getProcessingEventByHandleTypeAndHandleId(OfflineHandleEventType.COUPON.getValue(), couponId); |
| | | return ServerResponseEntity.success(offlineHandleEvent); |
| | | } |
| | | |
| | | @PostMapping("/auditApply") |
| | | @PreAuthorize("@pms.hasPermission('admin:coupon:auditApply')") |
| | | @Operation(summary = "违规商品提交审核") |
| | | public ServerResponseEntity<Void> auditApply(@RequestBody OfflineHandleEventAuditParam offlineHandleEventAuditParam) { |
| | | Coupon coupon = couponService.getCouponAndCouponProdsByCouponId(offlineHandleEventAuditParam.getHandleId()); |
| | | if (coupon == null) { |
| | | // 未找到该活动信息 |
| | | throw new YamiShopBindException("yami.activity.cannot.find"); |
| | | } |
| | | couponService.auditApply(offlineHandleEventAuditParam.getEventId(), offlineHandleEventAuditParam.getHandleId(), offlineHandleEventAuditParam.getReapplyReason()); |
| | | // 移除缓存 |
| | | couponService.removeCouponAndCouponProdsCache(coupon.getShopId()); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @GetMapping("/listCanSendCoupon") |
| | | @Operation(summary = "获取品牌可以发放给会员的优惠券列表") |
| | | public ServerResponseEntity<IPage<Coupon>> listCanSendCoupon(PageParam<Coupon> page, @ParameterObject Coupon coupon) { |
| | | Long shopId = SecurityUtils.getShopUser().getShopId(); |
| | | PageParam<Coupon> couponList = couponService.page(page, new LambdaQueryWrapper<Coupon>() |
| | | .eq(Coupon::getShopId, shopId) |
| | | .eq(Coupon::getPutonStatus, 1) |
| | | .eq(Coupon::getGetWay, 1) |
| | | .like(StrUtil.isNotBlank(coupon.getCouponName()), Coupon::getCouponName, coupon.getCouponName()) |
| | | .orderByDesc(Coupon::getCouponId));; |
| | | return ServerResponseEntity.success(couponList); |
| | | } |
| | | |
| | | @PutMapping("/sendUserCoupon") |
| | | @Operation(summary = "品牌批量发放优惠券给会员") |
| | | @PreAuthorize("@pms.hasPermission('admin:coupon:send')") |
| | | public ServerResponseEntity<Boolean> sendUserCoupon(@RequestBody UserCouponParam param) { |
| | | // if (!Objects.equals(SecurityUtils.getShopUser().getSysType(), SysTypeEnum.BRAND.value())) { |
| | | // // 没有权限修改该优惠券信息 |
| | | // throw new YamiShopBindException("yami.coupon.no.auth"); |
| | | // } |
| | | Long shopId = SecurityUtils.getShopUser().getShopId(); |
| | | List<String> userIds = param.getUserIds(); |
| | | if (CollectionUtils.isEmpty(userIds)) { |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | List<SendUserCouponsParam> coupons = param.getCoupons(); |
| | | if (CollectionUtils.isEmpty(coupons)) { |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | for (String userId : userIds) { |
| | | for (SendUserCouponsParam coupon : coupons) { |
| | | Long couponId = coupon.getCouponId(); |
| | | Integer nums = coupon.getNums(); |
| | | if (Objects.equals(0, nums)) { |
| | | continue; |
| | | } |
| | | for (int i = 0; i < nums; i++) { |
| | | couponService.batchBindCouponByIds(Collections.singletonList(couponId), userId, shopId); |
| | | // couponService.deleteCache(shopId, null); |
| | | } |
| | | } |
| | | } |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.multishop.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.coupon.common.model.CouponProd; |
| | | import com.yami.shop.coupon.common.service.CouponProdService; |
| | | 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; |
| | | |
| | | |
| | | /** |
| | | * @author lgh on 2018/12/27. |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/admin/couponProd") |
| | | @Tag(name = "商家端优惠券商品接口") |
| | | public class CouponProdController { |
| | | |
| | | @Autowired |
| | | private CouponProdService couponProdService; |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "分页获取优惠券商品") |
| | | public ServerResponseEntity<IPage<CouponProd>> page(@ParameterObject CouponProd couponProd, PageParam<CouponProd> page) { |
| | | IPage<CouponProd> couponProds = couponProdService.page(page, new LambdaQueryWrapper<CouponProd>()); |
| | | return ServerResponseEntity.success(couponProds); |
| | | } |
| | | |
| | | @GetMapping("/info/{id}") |
| | | @Operation(summary = "根据优惠券商品id获取信息") |
| | | @Parameter(name = "id", description = "优惠券商品id" ) |
| | | public ServerResponseEntity<CouponProd> info(@PathVariable("id") Long id) { |
| | | CouponProd couponProd = couponProdService.getById(id); |
| | | return ServerResponseEntity.success(couponProd); |
| | | } |
| | | |
| | | @PostMapping |
| | | @Operation(summary = "保存优惠券商品信息") |
| | | public ServerResponseEntity<Void> save(@RequestBody @Valid CouponProd couponProd) { |
| | | couponProdService.save(couponProd); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping |
| | | @Operation(summary = "修改优惠券商品信息") |
| | | public ServerResponseEntity<Void> update(@RequestBody @Valid CouponProd couponProd) { |
| | | couponProdService.updateById(couponProd); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @DeleteMapping("/{id}") |
| | | @Operation(summary = "根据id删除优惠券商品") |
| | | @Parameter(name = "id", description = "优惠券商品id" ) |
| | | public ServerResponseEntity<Void> delete(@PathVariable Long id) { |
| | | couponProdService.removeById(id); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.multishop.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.common.util.PageParam; |
| | | import com.yami.shop.coupon.common.model.CouponUser; |
| | | import com.yami.shop.coupon.common.service.CouponUserService; |
| | | 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; |
| | | |
| | | |
| | | /** |
| | | * @author lgh on 2018/12/27. |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/admin/couponUser") |
| | | @Tag(name = "商家端优惠券用户接口") |
| | | public class CouponUserController { |
| | | |
| | | @Autowired |
| | | private CouponUserService couponUserService; |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "分页获取优惠券用户信息") |
| | | public ServerResponseEntity<IPage<CouponUser>> page(@ParameterObject CouponUser couponUser, PageParam<CouponUser> page) { |
| | | IPage<CouponUser> couponUsers = couponUserService.page(page, new LambdaQueryWrapper<CouponUser>()); |
| | | return ServerResponseEntity.success(couponUsers); |
| | | } |
| | | |
| | | @GetMapping("/info/{id}") |
| | | @Operation(summary = "根据优惠券用户id获取信息") |
| | | @Parameter(name = "id", description = "优惠券用户id" ) |
| | | public ServerResponseEntity<CouponUser> info(@PathVariable("id") Long id) { |
| | | CouponUser couponUser = couponUserService.getById(id); |
| | | return ServerResponseEntity.success(couponUser); |
| | | } |
| | | |
| | | @PostMapping |
| | | @Operation(summary = "新增优惠券用户") |
| | | public ServerResponseEntity<Void> save(@RequestBody @Valid CouponUser couponUser) { |
| | | couponUserService.save(couponUser); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping |
| | | @Operation(summary = "修改优惠券用户") |
| | | public ServerResponseEntity<Void> update(@RequestBody @Valid CouponUser couponUser) { |
| | | couponUserService.updateById(couponUser); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @DeleteMapping("/{id}") |
| | | @Operation(summary = "根据优惠券用户id删除信息") |
| | | @Parameter(name = "id", description = "优惠券用户id" ) |
| | | public ServerResponseEntity<Void> delete(@PathVariable Long id) { |
| | | couponUserService.removeById(id); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | } |
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-coupon</artifactId> |
| | | <groupId>com.yami.shop</groupId> |
| | | <version>0.0.1-SNAPSHOT</version> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>yami-shop-coupon-platform</artifactId> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.yami.shop</groupId> |
| | | <artifactId>yami-shop-coupon-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.coupon.platform.config; |
| | | |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import org.springdoc.core.GroupedOpenApi; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | /** |
| | | * 优惠券 |
| | | * @author lanhai |
| | | */ |
| | | @Configuration("couponSwaggerConfiguration") |
| | | @AllArgsConstructor |
| | | public class SwaggerConfiguration { |
| | | |
| | | @Bean |
| | | public GroupedOpenApi couponRestApi() { |
| | | return GroupedOpenApi.builder() |
| | | .group("优惠券接口") |
| | | .packagesToScan("com.yami.shop.coupon.platform.controller") |
| | | .pathsToMatch("/**") |
| | | .build(); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.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.enums.OfflineHandleEventType; |
| | | import com.yami.shop.bean.enums.SendType; |
| | | import com.yami.shop.bean.event.SendMessageEvent; |
| | | import com.yami.shop.bean.model.OfflineHandleEvent; |
| | | import com.yami.shop.bean.param.NotifyTemplateParam; |
| | | import com.yami.shop.bean.param.OfflineHandleEventAuditParam; |
| | | import com.yami.shop.bean.param.SendUserCouponsParam; |
| | | import com.yami.shop.bean.param.UserUpdateParam; |
| | | 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.coupon.common.model.Coupon; |
| | | import com.yami.shop.coupon.common.model.CouponUser; |
| | | import com.yami.shop.coupon.common.service.CouponService; |
| | | import com.yami.shop.coupon.common.service.CouponUserService; |
| | | import com.yami.shop.security.platform.util.SecurityUtils; |
| | | import com.yami.shop.service.OfflineHandleEventService; |
| | | 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.apache.commons.collections4.CollectionUtils; |
| | | 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.validation.Valid; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 优惠券后台接口 |
| | | * |
| | | * @author lanhai |
| | | */ |
| | | @RestController("adminCouponController") |
| | | @RequestMapping("/platform/coupon") |
| | | @Tag(name = "平台端优惠券接口") |
| | | public class CouponController { |
| | | |
| | | @Autowired |
| | | private CouponService couponService; |
| | | @Autowired |
| | | private CouponUserService couponUserService; |
| | | @Autowired |
| | | private OfflineHandleEventService offlineHandleEventService; |
| | | @Autowired |
| | | private ApplicationEventPublisher eventPublisher; |
| | | |
| | | @GetMapping("/page") |
| | | @PreAuthorize("@pms.hasPermission('platform:coupon:page')") |
| | | @Operation(summary = "分页获取优惠券列表信息") |
| | | public ServerResponseEntity<IPage<Coupon>> page(@ParameterObject Coupon coupon, PageParam<Coupon> page) { |
| | | IPage<Coupon> couponPage = couponService.getPlatformPage(page, coupon); |
| | | return ServerResponseEntity.success(couponPage); |
| | | } |
| | | |
| | | @GetMapping("/list") |
| | | @Operation(summary = "获取优惠券列表信息") |
| | | public ServerResponseEntity<IPage<Coupon>> couponList(PageParam<Coupon> page, @ParameterObject Coupon coupon) { |
| | | PageParam<Coupon> couponPage = couponService.page(page, new LambdaQueryWrapper<Coupon>() |
| | | .eq(Coupon::getShopId, Constant.PLATFORM_SHOP_ID) |
| | | .eq(Coupon::getPutonStatus, 1) |
| | | .eq(Objects.nonNull(coupon.getGetWay()), Coupon::getGetWay, coupon.getGetWay()) |
| | | .like(StrUtil.isNotBlank(coupon.getCouponName()), Coupon::getCouponName, coupon.getCouponName()) |
| | | .orderByDesc(Coupon::getCouponId) |
| | | ); |
| | | return ServerResponseEntity.success(couponPage); |
| | | } |
| | | |
| | | @GetMapping("/pageByPlatform") |
| | | @PreAuthorize("@pms.hasPermission('platform:coupon:page')") |
| | | @Operation(summary = "分页获取平台优惠券") |
| | | public ServerResponseEntity<IPage<Coupon>> pageByPlatform(@ParameterObject Coupon coupon, PageParam<Coupon> page) { |
| | | coupon.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | IPage<Coupon> couponPage = couponService.getPlatformPage(page, coupon); |
| | | return ServerResponseEntity.success(couponPage); |
| | | } |
| | | |
| | | @PutMapping("/removeScore") |
| | | @PreAuthorize("@pms.hasPermission('platform:coupon:delete')") |
| | | @Operation(summary = "修改优惠券不为积分商品") |
| | | @Parameter(name = "couponId", description = "优惠券id" , required = true) |
| | | public ServerResponseEntity<IPage<Coupon>> removeScore(@RequestBody Long couponId) { |
| | | Coupon coupon = couponService.getById(couponId); |
| | | coupon.setIsScoreType(0); |
| | | coupon.setScorePrice(0); |
| | | couponService.updateById(coupon); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping("/couponByScore") |
| | | @PreAuthorize("@pms.hasPermission('platform:coupon:update')") |
| | | @Operation(summary = "修改平台券可以积分兑换") |
| | | public ServerResponseEntity<IPage<Coupon>> couponByScore(@RequestBody @Valid Coupon coupon) { |
| | | if (coupon.getScorePrice() == null) { |
| | | // 请输入正确的积分数量 |
| | | throw new YamiShopBindException("yami.user.score.input.check"); |
| | | } |
| | | coupon.setIsScoreType(1); |
| | | couponService.updateById(coupon); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @GetMapping("/scorePage") |
| | | @PreAuthorize("@pms.hasPermission('platform:coupon:page')") |
| | | @Operation(summary = "分页获取积分可换优惠券") |
| | | public ServerResponseEntity<IPage<Coupon>> pageByScore(@ParameterObject Coupon coupon, PageParam<Coupon> page) { |
| | | coupon.setIsScoreType(1); |
| | | IPage<Coupon> couponPage = couponService.getPlatformPage(page, coupon); |
| | | return ServerResponseEntity.success(couponPage); |
| | | } |
| | | |
| | | @GetMapping("/info/{id}") |
| | | @PreAuthorize("@pms.hasPermission('platform:coupon:info')") |
| | | @Operation(summary = "根据优惠券id获取优惠券信息") |
| | | @Parameter(name = "id", description = "优惠券id" , required = true) |
| | | public ServerResponseEntity<Coupon> info(@PathVariable("id") Long id) { |
| | | Coupon coupon = couponService.getCouponAndCouponProdsByCouponId(id); |
| | | return ServerResponseEntity.success(coupon); |
| | | } |
| | | |
| | | @DeleteMapping |
| | | @PreAuthorize("@pms.hasPermission('platform:coupon:delete')") |
| | | @Operation(summary = "根据优惠券id删除优惠券") |
| | | @Parameter(name = "couponId", description = "优惠券id" , required = true) |
| | | public ServerResponseEntity<Void> delete(@RequestBody Long couponId) { |
| | | couponService.deleteByCouponId(couponId); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @GetMapping("/getOfflineHandleEventByCouponId/{couponId}") |
| | | @PreAuthorize("@pms.hasPermission('platform:coupon:info')") |
| | | @Operation(summary = "通过优惠券id获取下线信息") |
| | | @Parameter(name = "couponId", description = "优惠券id" , required = true) |
| | | public ServerResponseEntity<OfflineHandleEvent> getOfflineHandleEventByCouponId(@PathVariable("couponId") Long couponId) { |
| | | OfflineHandleEvent offlineHandleEvent = offlineHandleEventService.getProcessingEventByHandleTypeAndHandleId(OfflineHandleEventType.COUPON.getValue(), couponId); |
| | | return ServerResponseEntity.success(offlineHandleEvent); |
| | | } |
| | | |
| | | @PostMapping("/offline") |
| | | @PreAuthorize("@pms.hasPermission('platform:coupon:update')") |
| | | @Operation(summary = "下线活动") |
| | | public ServerResponseEntity<Void> offline(@RequestBody OfflineHandleEvent offlineHandleEvent) { |
| | | Long sysUserId = SecurityUtils.getSysUser().getUserId(); |
| | | Coupon coupon = couponService.getCouponAndCouponProdsByCouponId(offlineHandleEvent.getHandleId()); |
| | | if (coupon == null) { |
| | | // 未找到该活动信息 |
| | | throw new YamiShopBindException("yami.activity.cannot.find"); |
| | | } |
| | | couponService.offline(coupon, offlineHandleEvent.getOfflineReason(), sysUserId); |
| | | //发送活动下架提醒给商家 |
| | | NotifyTemplateParam shopParam = new NotifyTemplateParam(); |
| | | shopParam.setShopId(coupon.getShopId()); |
| | | shopParam.setActivityId(coupon.getCouponId()); |
| | | shopParam.setActivityName(coupon.getCouponName()); |
| | | shopParam.setSendType(SendType.ACTIVITY_OFFLINE.getValue()); |
| | | eventPublisher.publishEvent(new SendMessageEvent(shopParam)); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PostMapping("/auditCoupon") |
| | | @PreAuthorize("@pms.hasPermission('platform:coupon:update')") |
| | | @Operation(summary = "审核活动") |
| | | public ServerResponseEntity<Void> auditCoupon(@RequestBody OfflineHandleEventAuditParam offlineHandleEventAuditParam) { |
| | | Long sysUserId = SecurityUtils.getSysUser().getUserId(); |
| | | Coupon coupon = couponService.getCouponAndCouponProdsByCouponId(offlineHandleEventAuditParam.getHandleId()); |
| | | if (coupon == null) { |
| | | // 未找到该活动信息 |
| | | throw new YamiShopBindException("yami.activity.cannot.find"); |
| | | } |
| | | couponService.auditCoupon(offlineHandleEventAuditParam, sysUserId); |
| | | //发送活动审核提醒给商家 |
| | | NotifyTemplateParam shopParam = new NotifyTemplateParam(); |
| | | shopParam.setShopId(coupon.getShopId()); |
| | | shopParam.setActivityId(coupon.getCouponId()); |
| | | shopParam.setActivityName(coupon.getCouponName()); |
| | | shopParam.setSendType(SendType.ACTIVITY_AUDIT.getValue()); |
| | | eventPublisher.publishEvent(new SendMessageEvent(shopParam)); |
| | | // 移除缓存 |
| | | couponService.removeCouponAndCouponProdsCache(coupon.getShopId()); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PostMapping |
| | | @Operation(summary = "保存优惠券") |
| | | public ServerResponseEntity<Long> save(@RequestBody @Valid Coupon coupon) { |
| | | // 此处新增优惠券皆为平台通用 |
| | | coupon.setShopId(Constant.PLATFORM_SHOP_ID); |
| | | coupon.setSourceStock(coupon.getStocks()); |
| | | couponService.insertCouponAndCouponProds(coupon); |
| | | return ServerResponseEntity.success(coupon.getCouponId()); |
| | | } |
| | | |
| | | @PutMapping |
| | | @Operation(summary = "修改优惠券") |
| | | public ServerResponseEntity<Void> update(@RequestBody @Valid Coupon coupon) { |
| | | // 查询平台下优惠券 |
| | | Coupon dbCoupon = couponService.getById(coupon.getCouponId()); |
| | | if (null == dbCoupon) { |
| | | // 优惠券不存在 |
| | | throw new YamiShopBindException("yami.coupon.no.exist"); |
| | | } |
| | | coupon.setShopId(dbCoupon.getShopId()); |
| | | //被领取数量 |
| | | int receNum = dbCoupon.getSourceStock() - dbCoupon.getStocks(); |
| | | //新的原始库存 |
| | | int newSourceStock = coupon.getStocks() + receNum; |
| | | coupon.setSourceStock(newSourceStock); |
| | | couponService.updateCouponAndCouponProds(coupon); |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @PutMapping("/sendUserCoupon") |
| | | @PreAuthorize("@pms.hasPermission('platform:coupon:sendUserCoupon')") |
| | | @Operation(summary = "平台批量发放优惠券给会员") |
| | | public ServerResponseEntity<Boolean> sendUserCoupon(@RequestBody UserUpdateParam param) { |
| | | List<String> userIds = param.getUserIds(); |
| | | if (CollectionUtils.isEmpty(userIds)) { |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | List<SendUserCouponsParam> coupons = param.getCoupons(); |
| | | if (CollectionUtils.isEmpty(coupons)) { |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | for (String userId : userIds) { |
| | | for (SendUserCouponsParam coupon : coupons) { |
| | | Long couponId = coupon.getCouponId(); |
| | | Integer nums = coupon.getNums(); |
| | | if (Objects.equals(0, nums)) { |
| | | continue; |
| | | } |
| | | couponService.bindCouponById(couponId, userId, nums, Constant.PLATFORM_SHOP_ID); |
| | | } |
| | | } |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | @GetMapping("/pageByUserId") |
| | | @Operation(summary = "获取某个用户的优惠券明细") |
| | | @Parameters({ |
| | | @Parameter(name = "userId", description = "用户id" ), |
| | | @Parameter(name = "status", description = "优惠券状态 0:失效 1:有效 2:使用过" ) |
| | | }) |
| | | public ServerResponseEntity<IPage<CouponUser>> getPageByUserId(PageParam<CouponUser> page, String userId, Integer status) { |
| | | IPage<CouponUser> resPage = couponService.getPageByUserId(page, userId, status); |
| | | return ServerResponseEntity.success(resPage); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.coupon.platform.task; |
| | | |
| | | import cn.hutool.core.date.DateUtil; |
| | | import com.xxl.job.core.handler.annotation.XxlJob; |
| | | import com.yami.shop.common.util.CacheManagerUtil; |
| | | import com.yami.shop.coupon.common.dao.CouponMapper; |
| | | import com.yami.shop.coupon.common.service.CouponService; |
| | | import com.yami.shop.coupon.common.service.CouponUserService; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | |
| | | |
| | | /** |
| | | * 优惠券定时任务 |
| | | * //0 0 0/1 * * ? |
| | | * @author lanhai |
| | | */ |
| | | @Slf4j |
| | | @AllArgsConstructor |
| | | @Component |
| | | public class CouponTask { |
| | | |
| | | private final CouponUserService couponUserService; |
| | | private final CouponService couponService; |
| | | private final CouponMapper couponMapper; |
| | | private final CacheManagerUtil cacheManagerUtil; |
| | | |
| | | |
| | | /** |
| | | * 删除用户失效30天以上的优惠券 |
| | | */ |
| | | @XxlJob("deleteCouponUser") |
| | | public void deleteCouponUser() { |
| | | log.info("删除用户失效180天以上的优惠券"); |
| | | // 删除用户失效半年以上的优惠券 参考京东 |
| | | couponUserService.deleteUnValidTimeCoupons(DateUtil.offsetDay(new Date(), -180)); |
| | | } |
| | | |
| | | /** |
| | | * 改变用户优惠券的状态(设为失效状态) |
| | | */ |
| | | @XxlJob("changeCouponUser") |
| | | public void changeCouponUser() { |
| | | Date now = new Date(); |
| | | log.info("设置用户的过期优惠券为失效状态"); |
| | | // 设置用户的过期优惠券为失效状态 |
| | | couponUserService.updateStatusByTime(now); |
| | | } |
| | | |
| | | /** |
| | | * 改变店铺优惠券的状态(设为过期状态) |
| | | */ |
| | | @XxlJob("changeCoupon") |
| | | public void changeCoupon() { |
| | | Date now = new Date(); |
| | | log.info("设置店铺的过期优惠券为过期状态"); |
| | | // 查询需要更新的店铺id列表 |
| | | List<Long> shopIds = couponMapper.listOverdueStatusShopIds(now); |
| | | // 取消投放 |
| | | couponService.changeCoupon(now); |
| | | //清除缓存 |
| | | if (CollectionUtils.isNotEmpty(shopIds)) { |
| | | for (Long shopId : shopIds) { |
| | | cacheManagerUtil.evictCache("couponAndCouponProds", String.valueOf(shopId)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 投放优惠券 |
| | | */ |
| | | @XxlJob("putOnCoupon") |
| | | public void putOnCoupon() { |
| | | Date now = new Date(); |
| | | log.info("投放优惠券"); |
| | | // 投放优惠券 |
| | | couponService.putonCoupon(now); |
| | | } |
| | | } |
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-cps</artifactId> |
| | | |
| | | <description>CPS模块</description> |
| | | <packaging>pom</packaging> |
| | | |
| | | <modules> |
| | | <module>yami-shop-cps-api</module> |
| | | <module>yami-shop-cps-common</module> |
| | | <module>yami-shop-cps-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"> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | <parent> |
| | | <groupId>com.yami.shop</groupId> |
| | | <artifactId>yami-shop-cps</artifactId> |
| | | <version>0.0.1-SNAPSHOT</version> |
| | | </parent> |
| | | |
| | | <artifactId>yami-shop-cps-api</artifactId> |
| | | |
| | | <dependencies> |
| | | <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-cps-common</artifactId> |
| | | <version>${yami.shop.version}</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>pdd.sdk</groupId> |
| | | <artifactId>pop-sdk</artifactId> |
| | | <version>1.17.91</version> |
| | | <scope>system</scope> |
| | | <systemPath>${project.basedir}/src/main/resources/lib/pop-sdk-1.17.91-all.jar</systemPath> |
| | | </dependency> |
| | | </dependencies> |
| | | </project> |
New file |
| | |
| | | /* |
| | | * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved. |
| | | * |
| | | * https://www.mall4j.com/ |
| | | * |
| | | * 未经允许,不可做商业用途! |
| | | * |
| | | * 版权所有,侵权必究! |
| | | */ |
| | | package com.yami.shop.cps.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("cpsSwaggerConfiguration") |
| | | @AllArgsConstructor |
| | | public class SwaggerConfiguration { |
| | | |
| | | |
| | | @Bean |
| | | public GroupedOpenApi cpsRestApi() { |
| | | return GroupedOpenApi.builder() |
| | | .group("cps接口") |
| | | .packagesToScan("com.yami.shop.cps.api.controller") |
| | | .pathsToMatch("/**") |
| | | .build(); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.yami.shop.cps.api.controller; |
| | | |
| | | import com.yami.shop.bean.model.User; |
| | | import com.yami.shop.bean.param.PDDUnionExportParam; |
| | | import com.yami.shop.bean.vo.PDDUnionExportVo; |
| | | import com.yami.shop.common.config.BigSellerConfig; |
| | | import com.yami.shop.common.response.ServerResponseEntity; |
| | | import com.yami.shop.cps.commom.utils.PddUtils; |
| | | import com.yami.shop.cps.commom.vo.PddVo; |
| | | import com.yami.shop.service.CpsConfigService; |
| | | import com.yami.shop.service.UserService; |
| | | 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.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.RequestParam; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | @RestController |
| | | @RequestMapping("/p/pdd") |
| | | @Tag(name = "拼多多-cps接口") |
| | | public class PddCpsController { |
| | | |
| | | |
| | | @Autowired |
| | | private CpsConfigService cpsConfigService; |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @GetMapping("/getPddShopList") |
| | | @Operation(summary = "根据拼多多类目查询商品列表", description = "根据拼多多类目查询商品列表") |
| | | @Parameters({ |
| | | @Parameter(name = "catId", description = "类目Id"), |
| | | @Parameter(name = "keyword", description = "关键词"), |
| | | @Parameter(name = "page", description = "商品分页数 默认值1") |
| | | }) |
| | | public ServerResponseEntity<PDDUnionExportVo> getPddShopList(@ParameterObject PDDUnionExportParam pddUnionExportParam) throws Exception { |
| | | PddVo pddVo = cpsConfigService.getCpsConfigObject(BigSellerConfig.CPS_PDD_CONFIG, PddVo.class); |
| | | return ServerResponseEntity.success(PddUtils.getGoodsSearch(pddUnionExportParam, pddVo)); |
| | | } |
| | | |
| | | |
| | | @GetMapping("/getPddShopDetail") |
| | | @Operation(summary = "拼多多商品详情查询", description = "拼多多商品详情查询") |
| | | @Parameters({ |
| | | @Parameter(name = "goodsSign", description = "加密后的商品goodsId") |
| | | }) |
| | | public ServerResponseEntity<?> getPddShopDetail(@RequestParam(value = "goodsSign") String goodsSign) throws Exception { |
| | | PddVo pddVo = cpsConfigService.getCpsConfigObject(BigSellerConfig.CPS_PDD_CONFIG, PddVo.class); |
| | | return ServerResponseEntity.success(PddUtils.getGoodsDetail(goodsSign, pddVo)); |
| | | } |
| | | |
| | | @GetMapping("/getPddAuthorizationUrl") |
| | | @Operation(summary = "获取拼多多(多多进宝)授权链接" , description = "获取拼多多(多多进宝)授权链接") |
| | | @Parameters({ |
| | | @Parameter(name = "source", description = "来源" ), |
| | | @Parameter(name = "userId", description = "用户id" ) |
| | | }) |
| | | public ServerResponseEntity<String> getPddAuthorizationUrl(@RequestParam(value ="source") String source, @RequestParam(value ="userId") String userId) { |
| | | User user = userService.getUserByUserId(userId); |
| | | PddVo pddVo = cpsConfigService.getCpsConfigObject(BigSellerConfig.CPS_PDD_CONFIG, PddVo.class); |
| | | return ServerResponseEntity.success(PddUtils.pddAuthorizationUrl(user.getUserId().toString(),source,pddVo)); |
| | | } |
| | | |
| | | @GetMapping("/getAuthorization") |
| | | @Operation(summary = "拼多多获取APP授权链接", description = "拼多多获取APP授权链接") |
| | | @Parameters({ |
| | | @Parameter(name = "userId", description = "用户Id") |
| | | }) |
| | | public ServerResponseEntity<?> getAuthorization(@RequestParam(value = "userId") String userId) throws Exception { |
| | | PddVo pddVo = cpsConfigService.getCpsConfigObject(BigSellerConfig.CPS_PDD_CONFIG, PddVo.class); |
| | | return ServerResponseEntity.success(PddUtils.getAuthorization(userId,pddVo)); |
| | | } |
| | | |
| | | |
| | | @GetMapping("/getPrivilegeLink") |
| | | @Operation(summary = "拼多多推广链接生成" , description = "拼多多推广链接生成") |
| | | @Parameters({ |
| | | @Parameter(name = "goodsSign", description = "商品主键id" ), |
| | | @Parameter(name = "userId", description = "用户Id" ) |
| | | }) |
| | | public ServerResponseEntity<?> getPrivilegeLink(@RequestParam(value = "goodsSign") String goodsSign,@RequestParam(value = "userId") String userId){ |
| | | //根据用户Id 查询用户的渠道Id |
| | | PddVo pddVo = cpsConfigService.getCpsConfigObject(BigSellerConfig.CPS_PDD_CONFIG, PddVo.class); |
| | | String result = null; |
| | | try { |
| | | Integer bind = PddUtils.getIsBind(userId,pddVo); |
| | | if(bind == 1) { |
| | | result = PddUtils.pddUnionRequest2(userId,goodsSign,pddVo); |
| | | }else { |
| | | result =PddUtils.getAuthorization(userId,pddVo); |
| | | } |
| | | }catch (Exception e) { |
| | | return ServerResponseEntity.showFailMsg("推广链接生成失败"); |
| | | } |
| | | return ServerResponseEntity.success(result); |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.cps.api.controller; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.yami.shop.bean.model.CpsOrder; |
| | | import com.yami.shop.bean.model.CpsShop; |
| | | import com.yami.shop.bean.model.User; |
| | | import com.yami.shop.bean.vo.JtkLinkVO; |
| | | import com.yami.shop.bean.vo.LinkVO; |
| | | import com.yami.shop.bean.vo.MtResultVo; |
| | | import com.yami.shop.bean.vo.OrderResultVo; |
| | | import com.yami.shop.common.config.BigSellerConfig; |
| | | 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.cps.commom.service.CpsMtActitvityService; |
| | | import com.yami.shop.cps.commom.service.CpsOrderService; |
| | | import com.yami.shop.cps.commom.service.CpsShopService; |
| | | import com.yami.shop.cps.commom.utils.DTKUtils; |
| | | import com.yami.shop.cps.commom.utils.MTUtils; |
| | | import com.yami.shop.cps.commom.utils.TBUtils; |
| | | import com.yami.shop.cps.commom.vo.JingDongVo; |
| | | import com.yami.shop.cps.commom.vo.MtfxlmVo; |
| | | import com.yami.shop.cps.commom.vo.TaoBaoVo; |
| | | import com.yami.shop.service.CpsConfigService; |
| | | import com.yami.shop.service.UserService; |
| | | 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.apache.commons.lang3.StringUtils; |
| | | 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; |
| | | |
| | | /** |
| | | * cps接口 |
| | | * @author zsq |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/p/cps") |
| | | @Tag(name = "大淘客-cps接口") |
| | | public class TbCpsController { |
| | | |
| | | @Autowired |
| | | private CpsConfigService cpsConfigService; |
| | | |
| | | @Autowired |
| | | private CpsShopService cpsShopService; |
| | | |
| | | @Autowired |
| | | private CpsOrderService cpsOrderService; |
| | | |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @Autowired |
| | | private CpsMtActitvityService cpsMtActitvityService; |
| | | |
| | | |
| | | @GetMapping("/getPrivilegeLink") |
| | | @Operation(summary = "淘宝商品高效转链查询" , description = "通过大淘客的接口查询单个商品高效转链") |
| | | @Parameters({ |
| | | @Parameter(name = "id", description = "商品主键id" ), |
| | | @Parameter(name = "userId", description = "用户Id" ) |
| | | }) |
| | | public ServerResponseEntity<?> getPrivilegeLink(@RequestParam(value = "id") String id,@RequestParam(value = "userId") String userId) { |
| | | //根据用户Id 查询用户的渠道Id |
| | | User user = userService.getUserByUserId(userId); |
| | | if (StringUtils.isBlank(user.getSpecialId())) { |
| | | return ServerResponseEntity.fail(ResponseEnum.EXCEPTION); |
| | | } |
| | | CpsShop cpsShop = cpsShopService.getById(id); |
| | | TaoBaoVo taoBaoVo = cpsConfigService.getCpsConfigObject(BigSellerConfig.CPS_TAOBAO_CONFIG, TaoBaoVo.class); |
| | | return ServerResponseEntity.success(DTKUtils.getTBPrivilegeLink(user.getSpecialId(),cpsShop.getGoodsId(),taoBaoVo)); |
| | | } |
| | | |
| | | @GetMapping("/getTaoBaoAuthorizationUrl") |
| | | @Operation(summary = "获取淘宝授权链接" , description = "获取淘宝授权链接") |
| | | @Parameters({ |
| | | @Parameter(name = "source", description = "来源" ), |
| | | @Parameter(name = "id", description = "商品id" ), |
| | | @Parameter(name = "userId", description = "用户id" ) |
| | | }) |
| | | public ServerResponseEntity<String> getTaoBaoAuthorizationUrl(@RequestParam(value ="source") String source, @RequestParam(value ="id") String id, @RequestParam(value ="userId") String userId) { |
| | | User user = userService.getUserByUserId(userId); |
| | | if (StringUtils.isBlank(user.getSpecialId())) { |
| | | return ServerResponseEntity.success(TBUtils.taoBaoAuthorizationUrl(user.getUserId().toString(),source,id)); |
| | | } |
| | | return ServerResponseEntity.success(); |
| | | } |
| | | |
| | | |
| | | @GetMapping("/getOrderList") |
| | | @Operation(summary = "商品订单查询" , description = "通过大淘客的接口查询订单列表") |
| | | @Parameters({ |
| | | @Parameter(name = "userId", description = "用户id" ), |
| | | @Parameter(name = "status", description = "动态分类") |
| | | }) |
| | | public ServerResponseEntity<IPage<OrderResultVo>> getOrderList(PageParam<OrderResultVo> page, CpsOrder cpsOrder) { |
| | | if (StringUtils.isBlank(cpsOrder.getUserId())) { |
| | | return ServerResponseEntity.fail(ResponseEnum.EXCEPTION); |
| | | } |
| | | IPage<OrderResultVo> cpsOrderPage = cpsOrderService.cpsOrderList(cpsOrder,page); |
| | | return ServerResponseEntity.success(cpsOrderPage); |
| | | } |
| | | |
| | | |
| | | |
| | | @GetMapping("/getJdPrivilegeLink") |
| | | @Operation(summary = "京东商品高效转链查询" , description = "通过大淘客的接口查询京东商品转链") |
| | | @Parameters({ |
| | | @Parameter(name = "materialUrl", description = "商品Url" ), |
| | | @Parameter(name = "userId", description = "用户Id" ) |
| | | }) |
| | | public ServerResponseEntity<?> getJdPrivilegeLink(@RequestParam(value = "materialUrl") String materialUrl,@RequestParam(value = "userId") String userId) { |
| | | //根据用户Id 查询用户的渠道Id |
| | | User user = userService.getUserByUserId(userId); |
| | | JingDongVo jingDongVo = cpsConfigService.getCpsConfigObject(BigSellerConfig.CPS_JINGDONG_CONFIG, JingDongVo.class); |
| | | return ServerResponseEntity.success(DTKUtils.getJdPrivilegeLink(materialUrl,user,jingDongVo)); |
| | | } |
| | | |
| | | |
| | | @GetMapping("/getMtFinalLink") |
| | | @Operation(summary = "美团联盟生成最终链接" , description = "美团联盟生成最终链接") |
| | | @Parameters({ |
| | | @Parameter(name = "id", description = "活动id" ), |
| | | @Parameter(name = "userId", description = "用户Id" ), |
| | | @Parameter(name = "linkType", description = "链接类型(1 h5链接,2 deeplink(唤起)链接,3 中间页唤起链接,4 微信小程序唤起路径,5 团口令)" ) |
| | | }) |
| | | public ServerResponseEntity<MtResultVo> getMtFinalLink(@RequestParam(value = "id") Long id,@RequestParam(value = "userId") String userId,@RequestParam(value = "linkType") Integer linkType) { |
| | | if(StringUtils.isBlank(userId)) { |
| | | return ServerResponseEntity.showFailMsg("用户Id不能为空"); |
| | | } |
| | | if(id == null) { |
| | | return ServerResponseEntity.showFailMsg("活动Id不能为空"); |
| | | } |
| | | return ServerResponseEntity.success(cpsMtActitvityService.getMtFinalLink(id,userId,linkType)); |
| | | } |
| | | |
| | | |
| | | @GetMapping("/getJtkShopLink") |
| | | @Operation(summary = "聚推客联盟统一活动转链" , description = "聚推客联盟统一活动转链") |
| | | @Parameters({ |
| | | @Parameter(name = "actId", description = "活动id" ), |
| | | @Parameter(name = "userId", description = "用户Id" ) |
| | | }) |
| | | public ServerResponseEntity<JtkLinkVO> getJtkShopLink(@RequestParam(value = "actId") String actId, @RequestParam(value = "userId") String userId) { |
| | | return ServerResponseEntity.success(cpsMtActitvityService.getJtkShopLink(actId,userId)); |
| | | } |
| | | |
| | | |
| | | @GetMapping("/getMtfxPartLink") |
| | | @Operation(summary = "美团分销联盟取链" , description = "美团分销联盟取链") |
| | | @Parameters({ |
| | | @Parameter(name = "activity", description = "活动id" ), |
| | | @Parameter(name = "userId", description = "用户Id" ) |
| | | }) |
| | | public ServerResponseEntity<?> getMtfxPartLink(@RequestParam(value = "activity") String activity,@RequestParam(value = "userId") String userId) { |
| | | User user = userService.getUserByUserId(userId); |
| | | MtfxlmVo mtfxlmVo = cpsConfigService.getCpsConfigObject(BigSellerConfig.CPS_MTFXLM_CONFIG, MtfxlmVo.class); |
| | | String result =MTUtils.getMtfxPartLink(activity,user,mtfxlmVo); |
| | | JSONObject json = JSONObject.parseObject(result); |
| | | if(StringUtils.isNotBlank(json.getString("data"))){ |
| | | LinkVO linkVO = JSONObject.parseObject(json.getString("data"),LinkVO.class); |
| | | return ServerResponseEntity.success(linkVO); |
| | | }else{ |
| | | return ServerResponseEntity.showFailMsg("美团分销联盟取链失败!"); |
| | | } |
| | | } |
| | | |
| | | } |
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-cps</artifactId> |
| | | <version>0.0.1-SNAPSHOT</version> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <artifactId>yami-shop-cps-common</artifactId> |
| | | |
| | | <properties> |
| | | <java.version>1.8</java.version> |
| | | <httpclient.version>4.5.12</httpclient.version> |
| | | <commons-lang3.version>3.8.1</commons-lang3.version> |
| | | <jackson.version>2.11.1</jackson.version> |
| | | <knife4j.version>2.0.3</knife4j.version> |
| | | <skipTests>true</skipTests> |
| | | </properties> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.yami.shop</groupId> |
| | | <artifactId>yami-shop-security-common</artifactId> |
| | | <version>${yami.shop.version}</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.apache.httpcomponents</groupId> |
| | | <artifactId>httpclient</artifactId> |
| | | <version>${httpclient.version}</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>io.swagger</groupId> |
| | | <artifactId>swagger-annotations</artifactId> |
| | | <version>1.5.22</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>io.springfox</groupId> |
| | | <artifactId>springfox-swagger2</artifactId> |
| | | <version>2.9.2</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.apache.commons</groupId> |
| | | <artifactId>commons-lang3</artifactId> |
| | | <version>${commons-lang3.version}</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.projectlombok</groupId> |
| | | <artifactId>lombok</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- jackson --> |
| | | <dependency> |
| | | <groupId>com.fasterxml.jackson.core</groupId> |
| | | <artifactId>jackson-databind</artifactId> |
| | | <version>${jackson.version}</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.fasterxml.jackson.core</groupId> |
| | | <artifactId>jackson-core</artifactId> |
| | | <version>${jackson.version}</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.fasterxml.jackson.core</groupId> |
| | | <artifactId>jackson-annotations</artifactId> |
| | | <version>${jackson.version}</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>taobao.sdk.source</groupId> |
| | | <artifactId>taobao-sdk-java-source</artifactId> |
| | | <version>1.0.0</version> |
| | | <scope>system</scope> |
| | | <systemPath>${project.basedir}/src/main/resources/lib/taobao-sdk-java-auto_1705048877036-20240611-source.jar</systemPath> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>taobao.sdk</groupId> |
| | | <artifactId>taobao-sddk-java</artifactId> |
| | | <version>1.0.0</version> |
| | | <scope>system</scope> |
| | | <systemPath>${project.basedir}/src/main/resources/lib/taobao-sdk-java-auto.jar</systemPath> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>pdd.sdk</groupId> |
| | | <artifactId>pop-sdk</artifactId> |
| | | <version>1.17.91</version> |
| | | <scope>system</scope> |
| | | <systemPath>${project.basedir}/src/main/resources/lib/pop-sdk-1.17.91-all.jar</systemPath> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
New file |
| | |
| | | package com.yami.shop.cps.commom.client; |
| | | |
| | | import com.fasterxml.jackson.core.type.TypeReference; |
| | | import com.yami.shop.cps.commom.constant.DtkApiConstant; |
| | | import com.yami.shop.cps.commom.exception.DtkApiException; |
| | | import com.yami.shop.cps.commom.exception.DtkResultEnum; |
| | | import com.yami.shop.cps.commom.http.WebUtils; |
| | | import com.yami.shop.cps.commom.response.base.DtkApiResponse; |
| | | import com.yami.shop.cps.commom.utils.Assert; |
| | | import com.yami.shop.cps.commom.utils.JsonUtil; |
| | | import com.yami.shop.cps.commom.utils.RequiredCheck; |
| | | import com.yami.shop.cps.commom.utils.SignMd5Util; |
| | | import lombok.SneakyThrows; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.util.StringUtils; |
| | | |
| | | import java.lang.reflect.Field; |
| | | import java.util.Collections; |
| | | import java.util.Map; |
| | | import java.util.Optional; |
| | | import java.util.Random; |
| | | |
| | | /** |
| | | * dtk api: AbstractDtkApiClient |
| | | * |
| | | * @author 1 |
| | | * @date 2020/11/10 11:37 |
| | | */ |
| | | @Slf4j |
| | | public abstract class AbstractDtkApiClient implements DtkClient { |
| | | private final String appKey; |
| | | private final String appSecret; |
| | | |
| | | private static final String BASE_URL = "https://openapi.dataoke.com/api"; |
| | | |
| | | public AbstractDtkApiClient(String appKey, String appSecret) { |
| | | this.appKey = appKey; |
| | | this.appSecret = appSecret; |
| | | } |
| | | |
| | | @Override |
| | | @SuppressWarnings("unchecked") |
| | | public <T> T execute(DtkApiRequest<T> request) { |
| | | String requestUrl = request.requestUrl(); |
| | | T tRsp; |
| | | Map<String, String> requestHolderWithSign = null; |
| | | String resultJson = null; |
| | | try { |
| | | // 这是一个已经设置好所有参数的key-value集 |
| | | requestHolderWithSign = getRequestHolderWithSign(request); |
| | | Assert.notBank(requestUrl, DtkResultEnum.URL_NOT_EMPTY); |
| | | Assert.notBank(request.apiVersion(), DtkResultEnum.VERSION_NOT_EMPTY); |
| | | // http请求 |
| | | resultJson = WebUtils.doGet(BASE_URL + requestUrl, requestHolderWithSign); |
| | | Assert.notBank(resultJson, DtkResultEnum.UNKNOWN_ERROR); |
| | | |
| | | TypeReference<T> responseType = request.responseType(); |
| | | tRsp = JsonUtil.jsonToPojoByTypeReference(resultJson, responseType); |
| | | } catch (Exception ex) { |
| | | log.error("dtk_sdk处理异常:请求地址:{},请求参数:{}", requestUrl, |
| | | Optional.ofNullable(requestHolderWithSign).orElse(Collections.emptyMap()).toString()); |
| | | log.error("dtk_sdk处理异常:响应结果:{}", resultJson); |
| | | log.error("dtk_sdk处理异常:异常信息:", ex); |
| | | if (ex instanceof DtkApiException) { |
| | | DtkApiException exception = (DtkApiException) ex; |
| | | return (T) DtkApiResponse.buildFail(exception.getDtkResultEnum()); |
| | | } else { |
| | | return (T) DtkApiResponse.buildFail(DtkResultEnum.UNKNOWN_ERROR); |
| | | } |
| | | } |
| | | |
| | | return tRsp; |
| | | } |
| | | |
| | | /** |
| | | * 组装接口参数,处理加密、签名逻辑 |
| | | * |
| | | * @param request 请求参数对象 |
| | | * @return 组装完成的完整参数 |
| | | */ |
| | | @SneakyThrows |
| | | private Map<String, String> getRequestHolderWithSign(DtkApiRequest<?> request) |
| | | throws IllegalAccessException { |
| | | //校验必填参数 |
| | | Field[] fields = request.getClass().getDeclaredFields(); |
| | | for (Field field : fields) { |
| | | field.setAccessible(true); |
| | | if (field.isAnnotationPresent(RequiredCheck.class)) { |
| | | if (StringUtils.isEmpty(field.get(request))) { |
| | | throw new DtkApiException("请求参数必填项缺失!"); |
| | | } |
| | | } |
| | | } |
| | | Map<String, String> textParams = request.getTextParams(); |
| | | // 创建一个Random对象 |
| | | Random random = new Random(); |
| | | // 生成一个6位的随机数,范围在0到999999之间 |
| | | int randomNumber = random.nextInt(1000000); |
| | | String nonce = String.format("%06d", randomNumber); |
| | | // 获取当前时间戳 |
| | | String Timer = String.format("%d", System.currentTimeMillis()); |
| | | |
| | | textParams.put(DtkApiConstant.RequestCommonParam.APP_KEY, appKey); |
| | | textParams.put(DtkApiConstant.RequestCommonParam.Nonce, nonce); |
| | | textParams.put(DtkApiConstant.RequestCommonParam.Timer, Timer); |
| | | // 生成签名 |
| | | String urlParams = String.format("appKey=%s&timer=%s&nonce=%s", appKey, Timer, nonce); |
| | | String serverSign = SignMd5Util.sign(urlParams, appSecret); |
| | | textParams.put(DtkApiConstant.RequestCommonParam.SIGN, serverSign); |
| | | return textParams; |
| | | } |
| | | |
| | | /** |
| | | * 把一个字符串的第一个字母大写 |
| | | */ |
| | | private static String getMethodName(String fieldName) throws Exception { |
| | | byte[] items = fieldName.getBytes(); |
| | | items[0] = (byte) ((char) items[0] - 'a' + 'A'); |
| | | return new String(items); |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.cps.commom.client; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 把所有参数定义在这里,直接传对象初始化client |
| | | * |
| | | * @author 1 |
| | | * @date 2020/11/10 11:41 |
| | | */ |
| | | @Data |
| | | public class ApiRequest { |
| | | private String appKey; |
| | | private String appSecret; |
| | | } |
New file |
| | |
| | | package com.yami.shop.cps.commom.client; |
| | | |
| | | import com.yami.shop.cps.commom.exception.DtkResultEnum; |
| | | import com.yami.shop.cps.commom.utils.Assert; |
| | | |
| | | /** |
| | | * dtk api: dtkApiClient |
| | | * |
| | | * @author 1 |
| | | * @date 2020/11/9 16:20 |
| | | */ |
| | | public class DtkApiClient extends AbstractDtkApiClient { |
| | | private static volatile DtkApiClient dtkApiClient; |
| | | |
| | | private DtkApiClient() { |
| | | super(null, null); |
| | | } |
| | | |
| | | private DtkApiClient(String appKey, String appSecret) { |
| | | super(appKey, appSecret); |
| | | } |
| | | |
| | | public static DtkApiClient getInstance(ApiRequest apiRequest) { |
| | | return getInstance(apiRequest.getAppKey(), apiRequest.getAppSecret()); |
| | | } |
| | | |
| | | public static DtkApiClient getInstance(String appKey, String appSecret) { |
| | | Assert.notBank(appKey, DtkResultEnum.VERSION_NOT_EMPTY); |
| | | Assert.notBank(appSecret, DtkResultEnum.APP_SECRET_EMPTY); |
| | | if (dtkApiClient == null) { |
| | | synchronized (DtkApiClient.class) { |
| | | if (dtkApiClient == null) { |
| | | // 加锁 |
| | | dtkApiClient = new DtkApiClient(appKey, appSecret); |
| | | } |
| | | } |
| | | } |
| | | return dtkApiClient; |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.cps.commom.client; |
| | | |
| | | import com.fasterxml.jackson.core.type.TypeReference; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * dtk api: some basic request interface |
| | | * |
| | | * @author 1 |
| | | * @date 2020/11/10 10:36 |
| | | */ |
| | | public interface DtkApiRequest<T> { |
| | | /** |
| | | * 获取所有的Key-Value形式的文本请求参数集合。其中: |
| | | * <ul> |
| | | * <li>Key: 请求参数名</li> |
| | | * <li>Value: 请求参数值</li> |
| | | * </ul> |
| | | * 所有实现相同ObjectUtil.objToMap(this) |
| | | * |
| | | * @return 文本请求参数集合 |
| | | * @throws IllegalAccessException 反射对象异常 |
| | | */ |
| | | Map<String, String> getTextParams() throws IllegalAccessException; |
| | | |
| | | /** |
| | | * 得到当前API接口的版本 |
| | | * |
| | | * @return API版本 |
| | | */ |
| | | String apiVersion(); |
| | | |
| | | /** |
| | | * 得到当前API的响应结果类型 |
| | | * |
| | | * @return 响应类型 |
| | | */ |
| | | TypeReference<T> responseType(); |
| | | |
| | | /** |
| | | * 得到当前API的请求地址 |
| | | * |
| | | * @return 请求地址 |
| | | */ |
| | | String requestUrl(); |
| | | |
| | | void setVersion(String s); |
| | | } |
New file |
| | |
| | | package com.yami.shop.cps.commom.client; |
| | | |
| | | import com.yami.shop.cps.commom.exception.DtkApiException; |
| | | |
| | | /** |
| | | * dtk api: DtkClient,Provide an execution interface |
| | | * |
| | | * @author 1 |
| | | * @date 2020/11/10 11:24 |
| | | */ |
| | | public interface DtkClient { |
| | | /** |
| | | * 根据请求参数执行逻辑 |
| | | * |
| | | * @param request 请求参数 |
| | | * @param <T> 请求泛型 |
| | | * @return 返回结果与request对应 |
| | | * @throws DtkApiException dtk自定义异常 |
| | | */ |
| | | <T> T execute(DtkApiRequest<T> request); |
| | | } |
New file |
| | |
| | | package com.yami.shop.cps.commom.constant; |
| | | |
| | | /** |
| | | * dtk api: constant class |
| | | * |
| | | * @author 1 |
| | | * @date 2020/11/9 16:27 |
| | | */ |
| | | public class DtkApiConstant { |
| | | |
| | | private DtkApiConstant() { |
| | | } |
| | | |
| | | public static final String EMPTY_STR = ""; |
| | | |
| | | public static final String ENCRYPT_TYPE_MD5 = "MD5"; |
| | | |
| | | public static final String CLASS_TYPE = "class"; |
| | | |
| | | /** |
| | | * 默认时间格式 |
| | | **/ |
| | | public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; |
| | | |
| | | /** |
| | | * Date默认时区 |
| | | **/ |
| | | public static final String DATE_TIMEZONE = "GMT+8"; |
| | | |
| | | public static final String SDK_VERSION = "dtk-java-open-platform-sdk-1.0.0"; |
| | | |
| | | public static class Charset { |
| | | public static final String UTF_8 = "UTF-8"; |
| | | } |
| | | |
| | | public static class RequestCommonParam { |
| | | public static final String SIGN = "signRan"; |
| | | public static final String Nonce = "nonce"; |
| | | public static final String Timer = "timer"; |
| | | public static final String APP_KEY = "appKey"; |
| | | public static final String APP_SECRET = "appSecret"; |
| | | public static final String REQUEST_URL = "requestUrl"; |
| | | } |
| | | |
| | | public static class Domain { |
| | | public static final String PROD = "https://openapi.dataoke.com"; |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.cps.commom.controller.base; |
| | | |
| | | import com.yami.shop.cps.commom.client.DtkApiClient; |
| | | import com.yami.shop.cps.commom.client.DtkClient; |
| | | import com.yami.shop.cps.commom.constant.DtkApiConstant; |
| | | import com.yami.shop.cps.commom.exception.DtkResultEnum; |
| | | import com.yami.shop.cps.commom.request.putstorage.DtkGoodsListRequest; |
| | | 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.putstorage.DtkGoodsListItemResponse; |
| | | import com.yami.shop.cps.commom.utils.Assert; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.annotation.Resource; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | |
| | | /** |
| | | * dtk api: base controller |
| | | * |
| | | * @author baige |
| | | * @date 2020/11/13 14:21 |
| | | */ |
| | | @Component |
| | | public class BaseController { |
| | | @Resource |
| | | private HttpServletRequest request; |
| | | private DtkApiClient instance; |
| | | |
| | | protected DtkClient getDtkClient() { |
| | | String appKey = getClientHeader(DtkApiConstant.RequestCommonParam.APP_KEY); |
| | | Assert.notBank(appKey, DtkResultEnum.APP_KEY_EMPTY); |
| | | String appSecret = getClientHeader(DtkApiConstant.RequestCommonParam.APP_SECRET); |
| | | Assert.notBank(appSecret, DtkResultEnum.APP_SECRET_EMPTY); |
| | | if (instance == null) { |
| | | synchronized (BaseController.class) { |
| | | if (instance == null) { |
| | | this.instance = DtkApiClient.getInstance(appKey, appSecret); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return this.instance; |
| | | } |
| | | |
| | | /** |
| | | * 从header获取appKey和appSecret |
| | | */ |
| | | private String getClientHeader(String headerKey) { |
| | | return request.getHeader(headerKey); |
| | | } |
| | | |
| | | protected String getRequestUrl() { |
| | | String requestUrl = request.getRequestURI(); |
| | | return String.format("%s%s", DtkApiConstant.Domain.PROD, requestUrl); |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.cps.commom.controller.base; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.yami.shop.bean.model.User; |
| | | import com.yami.shop.common.config.BigSellerConfig; |
| | | import com.yami.shop.common.exception.YamiShopBindException; |
| | | import com.yami.shop.cps.commom.service.CpsMtActitvityService; |
| | | import com.yami.shop.cps.commom.utils.PddUtils; |
| | | import com.yami.shop.cps.commom.utils.TBUtils; |
| | | import com.yami.shop.cps.commom.vo.PddVo; |
| | | import com.yami.shop.service.CpsConfigService; |
| | | import com.yami.shop.service.UserService; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Controller; |
| | | import org.springframework.util.ObjectUtils; |
| | | 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.RequestMethod; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.util.Map; |
| | | import java.util.TreeMap; |
| | | |
| | | @Slf4j |
| | | @Controller |
| | | @RequestMapping("/tb/front/tbUnion") |
| | | @Api(tags = "cps回调接口") |
| | | public class TaoBaoUnionController { |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @Autowired |
| | | private CpsConfigService cpsConfigService; |
| | | |
| | | @Autowired |
| | | private CpsMtActitvityService cpsMtActitvityService; |
| | | |
| | | private String jumpH5Url ="http://127.0.0.1:8848/luckH5/index.html"; |
| | | |
| | | @Operation(summary = "淘宝回调" , description = "淘宝回调") |
| | | @RequestMapping(value = "/taobaoCallback", method = RequestMethod.GET) |
| | | public String taobaoCallback(HttpServletRequest request){ |
| | | String code = request.getParameter("code"); |
| | | String state = request.getParameter("state"); |
| | | String[] split = state.split("-"); |
| | | String userId= split[0]; |
| | | String source= split[1]; |
| | | if(userId!=null) { |
| | | try { |
| | | //获取用户授权的accessToken |
| | | String token = TBUtils.getToken(code); |
| | | JSONObject json = JSONObject.parseObject(token); |
| | | JSONObject authToken = JSONObject.parseObject(json.getString("top_auth_token_create_response")); |
| | | JSONObject tokenResult = JSON.parseObject(authToken.getString("token_result")); |
| | | String accessToken = tokenResult.getString("access_token"); |
| | | //System.out.println("accessToken--------------------"+accessToken); |
| | | //私域用户渠道备案 |
| | | String relationInfo = TBUtils.publisherInfoRelationSave(accessToken); |
| | | json = JSONObject.parseObject(relationInfo); |
| | | if (json.containsKey("tbk_sc_publisher_info_save_response")) { |
| | | JSONObject publisherInfo = JSONObject.parseObject(json.getString("tbk_sc_publisher_info_save_response")); |
| | | JSONObject relationData = JSON.parseObject(publisherInfo.getString("data")); |
| | | //渠道id |
| | | String relationId = relationData.getString("relation_id"); |
| | | //私域用户会员备案 |
| | | String memberInfo = TBUtils.publisherInfoMemberSave(accessToken); |
| | | json = JSONObject.parseObject(memberInfo); |
| | | JSONObject fansInfo = JSONObject.parseObject(json.getString("tbk_sc_publisher_info_save_response")); |
| | | JSONObject fansData = JSON.parseObject(fansInfo.getString("data")); |
| | | //会员id |
| | | String specialId = fansData.getString("special_id"); |
| | | //System.out.println("specialId--------------------"+specialId); |
| | | User user = userService.getRelationAndSpecialId(relationId,specialId); |
| | | if(!ObjectUtils.isEmpty(user)){ |
| | | return "redirect:"+jumpH5Url+"?source="+source+"&type=error&userId="+userId; |
| | | } |
| | | user = userService.getById(userId); |
| | | if (!ObjectUtils.isEmpty(user)) { |
| | | user.setRelationId(relationId); |
| | | user.setSpecialId(specialId); |
| | | userService.updateById(user); |
| | | } |
| | | } else { |
| | | throw new YamiShopBindException("不支持同人邀请!"); |
| | | } |
| | | } catch (Exception e) { |
| | | System.out.println("淘宝客回调异常:"); |
| | | } |
| | | } |
| | | |
| | | return "redirect:"+jumpH5Url+"?source="+source+"&&type=success&userId="+userId; |
| | | } |
| | | |
| | | |
| | | @Operation(summary = "美团联盟回调" , description = "美团联盟回调") |
| | | @PostMapping("/mtOrderCallback") |
| | | public Map<String, String> mtOrderCallback(@RequestBody TreeMap<String, String> params){ |
| | | return cpsMtActitvityService.mtOrderCallback(params); |
| | | } |
| | | |
| | | @Operation(summary = "拼多多回调" , description = "美团联盟回调") |
| | | @RequestMapping(value = "/pddCallback", method = RequestMethod.GET) |
| | | public String pddCallback(HttpServletRequest request){ |
| | | // 获取code参数 |
| | | String code = request.getParameter("code"); |
| | | String state = request.getParameter("state"); |
| | | String[] split = state.split("-"); |
| | | Integer userId = Integer.valueOf(split[0]); |
| | | String source = split[1]; |
| | | if (userId != null) { |
| | | try { |
| | | //获取用户授权的accessToken |
| | | PddVo pddVo = cpsConfigService.getCpsConfigObject(BigSellerConfig.CPS_PDD_CONFIG, PddVo.class); |
| | | String token = PddUtils.getToken(code,pddVo); |
| | | JSONObject json = JSONObject.parseObject(token); |
| | | JSONObject authToken = JSONObject.parseObject(json.getString("pop_auth_token_create_response")); |
| | | String accessToken = authToken.getString("access_token"); |
| | | String ownerId = authToken.getString("owner_id"); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | return "redirect:" + jumpH5Url + "?source=" + source + "&type=success"; |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.cps.commom.exception; |
| | | |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * dtk api: custom business exception |
| | | * |
| | | * @author 1 |
| | | * @date 2020/11/10 11:55 |
| | | */ |
| | | @Getter |
| | | public class DtkApiException extends RuntimeException { |
| | | private DtkResultEnum dtkResultEnum; |
| | | |
| | | public DtkApiException(String message) { |
| | | super(message); |
| | | } |
| | | |
| | | public DtkApiException(DtkResultEnum dtkResultEnum) { |
| | | super(dtkResultEnum.getMsg()); |
| | | this.dtkResultEnum = dtkResultEnum; |
| | | } |
| | | |
| | | @Override |
| | | public Throwable fillInStackTrace() { |
| | | return this; |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.cps.commom.exception; |
| | | |
| | | /** |
| | | * dtk api: result enum |
| | | * |
| | | * @author 1 |
| | | * @date 2020/11/10 17:49 |
| | | */ |
| | | public enum DtkResultEnum implements Result { |
| | | UNKNOWN_ERROR(-1, "服务器错误"), |
| | | SUCCESS(0, "成功"), |
| | | URL_NOT_EMPTY(1, "请求地址不能为空"), |
| | | RANK_TYPE_ERROR(10004, "榜单类型为空或不正确"), |
| | | APP_KEY_EMPTY(10016, "appKey不能为空"), |
| | | VERSION_NOT_EMPTY(10017, "版本号不能为空"), |
| | | APP_SECRET_EMPTY(10018, "appSecret不能为空"), |
| | | |
| | | |
| | | ; |
| | | |
| | | private final int code; |
| | | private final String msg; |
| | | |
| | | DtkResultEnum(int code, String msg) { |
| | | this.code = code; |
| | | this.msg = msg; |
| | | } |
| | | |
| | | @Override |
| | | public int getCode() { |
| | | return this.code; |
| | | } |
| | | |
| | | @Override |
| | | public String getMsg() { |
| | | return this.msg; |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.cps.commom.exception; |
| | | |
| | | /** |
| | | * dtk api: result abstract interface |
| | | * |
| | | * @author 1 |
| | | * @date 2020/11/10 17:49 |
| | | */ |
| | | public interface Result { |
| | | /** |
| | | * 获取结果code |
| | | * |
| | | * @return code |
| | | */ |
| | | int getCode(); |
| | | |
| | | /** |
| | | * 获取结果信息 |
| | | * |
| | | * @return message |
| | | */ |
| | | String getMsg(); |
| | | } |
New file |
| | |
| | | package com.yami.shop.cps.commom.http; |
| | | |
| | | import com.yami.shop.cps.commom.constant.DtkApiConstant; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import java.io.IOException; |
| | | import java.net.HttpURLConnection; |
| | | import java.net.InetAddress; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.text.DateFormat; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | import java.util.TimeZone; |
| | | |
| | | /** |
| | | * 日志打印 |
| | | * |
| | | * @author xx |
| | | * @date 2020/12/2 18:08 |
| | | */ |
| | | @Slf4j |
| | | public class Logger { |
| | | private static final String OS_NAME = System.getProperties().getProperty("os.name"); |
| | | private static boolean needEnableLogger = true; |
| | | private static String ip = null; |
| | | |
| | | public static void setNeedEnableLogger(boolean needEnableLogger) { |
| | | Logger.needEnableLogger = needEnableLogger; |
| | | } |
| | | |
| | | private Logger() { |
| | | } |
| | | |
| | | public static void logCommError(Exception e, String url, String appKey, String method, |
| | | Map<String, String> params) { |
| | | if (!needEnableLogger) { |
| | | return; |
| | | } |
| | | _logCommError(e, null, url, appKey, method, params); |
| | | } |
| | | |
| | | public static void logCommError(Exception e, HttpURLConnection conn, String appKey, |
| | | String method, Map<String, String> params) { |
| | | if (!needEnableLogger) { |
| | | return; |
| | | } |
| | | _logCommError(e, conn, null, appKey, method, params); |
| | | } |
| | | |
| | | public static void logCommError(Exception e, String url, String appKey, String method, |
| | | byte[] content) { |
| | | if (!needEnableLogger) { |
| | | return; |
| | | } |
| | | |
| | | String contentString = new String(content, StandardCharsets.UTF_8); |
| | | logCommError(e, url, appKey, method, contentString); |
| | | } |
| | | |
| | | private static void logCommError(Exception e, String url, String appKey, String method, |
| | | String content) { |
| | | Map<String, String> params = parseParam(content); |
| | | _logCommError(e, null, url, appKey, method, params); |
| | | } |
| | | |
| | | /** |
| | | * 通讯错误日志 |
| | | */ |
| | | private static void _logCommError(Exception e, HttpURLConnection conn, String url, |
| | | String appKey, String method, Map<String, String> params) { |
| | | DateFormat df = new SimpleDateFormat(DtkApiConstant.DATE_TIME_FORMAT); |
| | | df.setTimeZone(TimeZone.getTimeZone(DtkApiConstant.DATE_TIMEZONE)); |
| | | String sdkName = DtkApiConstant.SDK_VERSION; |
| | | String urlStr = null; |
| | | String rspCode = ""; |
| | | if (conn != null) { |
| | | try { |
| | | urlStr = conn.getURL().toString(); |
| | | rspCode = "HTTP_ERROR_" + conn.getResponseCode(); |
| | | } catch (IOException ioe) { |
| | | log.error(ioe.getMessage()); |
| | | } |
| | | } else { |
| | | urlStr = url; |
| | | rspCode = ""; |
| | | } |
| | | StringBuilder sb = new StringBuilder(); |
| | | // 时间 |
| | | sb.append(df.format(new Date())); |
| | | sb.append("^_^"); |
| | | // API |
| | | sb.append(method); |
| | | sb.append("^_^"); |
| | | // APP |
| | | sb.append(appKey); |
| | | sb.append("^_^"); |
| | | // IP地址 |
| | | sb.append(getIp()); |
| | | sb.append("^_^"); |
| | | // 操作系统 |
| | | sb.append(OS_NAME); |
| | | // SDK名字,这是例子,请换成其他名字 |
| | | sb.append("^_^"); |
| | | sb.append(sdkName); |
| | | sb.append("^_^"); |
| | | // 请求URL |
| | | sb.append(urlStr); |
| | | sb.append("^_^"); |
| | | sb.append(rspCode); |
| | | sb.append("^_^"); |
| | | sb.append((e.getMessage() + "").replaceAll("\r\n", " ")); |
| | | log.error(sb.toString()); |
| | | } |
| | | |
| | | public static void logCommError(Exception e, HttpURLConnection conn, String appKey, |
| | | String method, byte[] content) { |
| | | if (!needEnableLogger) { |
| | | return; |
| | | } |
| | | |
| | | String contentString; |
| | | try { |
| | | contentString = new String(content, StandardCharsets.UTF_8); |
| | | logCommError(e, conn, appKey, method, contentString); |
| | | } catch (Exception e1) { |
| | | log.error(e1.getMessage()); |
| | | } |
| | | } |
| | | |
| | | private static Map<String, String> parseParam(String contentString) { |
| | | Map<String, String> params = new HashMap<>(16); |
| | | if (contentString == null || "".equals(contentString.trim())) { |
| | | return params; |
| | | } |
| | | String[] paramsArray = contentString.split("&"); |
| | | for (String param : paramsArray) { |
| | | String[] keyValue = param.split("="); |
| | | if (keyValue.length == 2) { |
| | | params.put(keyValue[0], keyValue[1]); |
| | | } |
| | | } |
| | | |
| | | return params; |
| | | } |
| | | |
| | | /** |
| | | * 通讯错误日志 |
| | | */ |
| | | private static void logCommError(Exception e, HttpURLConnection conn, String appKey, |
| | | String method, String content) { |
| | | Map<String, String> params = parseParam(content); |
| | | logCommError(e, conn, null, appKey, method, params); |
| | | } |
| | | |
| | | /** |
| | | * 通讯错误日志 |
| | | */ |
| | | private static void logCommError(Exception e, HttpURLConnection conn, String url, |
| | | String appKey, String method, Map<String, String> params) { |
| | | DateFormat df = new SimpleDateFormat(DtkApiConstant.DATE_TIME_FORMAT); |
| | | df.setTimeZone(TimeZone.getTimeZone(DtkApiConstant.DATE_TIMEZONE)); |
| | | String sdkName = DtkApiConstant.SDK_VERSION; |
| | | String urlStr = null; |
| | | String rspCode = ""; |
| | | if (conn != null) { |
| | | try { |
| | | urlStr = conn.getURL().toString(); |
| | | rspCode = "HTTP_ERROR_" + conn.getResponseCode(); |
| | | } catch (IOException ioe) { |
| | | log.error(ioe.getMessage()); |
| | | } |
| | | } else { |
| | | urlStr = url; |
| | | rspCode = ""; |
| | | } |
| | | |
| | | StringBuilder sb = new StringBuilder(); |
| | | // 时间 |
| | | sb.append(df.format(new Date())); |
| | | sb.append("^_^"); |
| | | // API |
| | | sb.append(method); |
| | | sb.append("^_^"); |
| | | // APP |
| | | sb.append(appKey); |
| | | sb.append("^_^"); |
| | | // IP地址 |
| | | sb.append(getIp()); |
| | | sb.append("^_^"); |
| | | // 操作系统 |
| | | sb.append(OS_NAME); |
| | | sb.append("^_^"); |
| | | // SDK名字,这是例子,请换成其他名字 |
| | | sb.append(sdkName); |
| | | sb.append("^_^"); |
| | | // 请求URL |
| | | sb.append(urlStr); |
| | | sb.append("^_^"); |
| | | sb.append(rspCode); |
| | | sb.append("^_^"); |
| | | sb.append((e.getMessage() + "").replaceAll("\r\n", " ")); |
| | | log.error(sb.toString()); |
| | | } |
| | | |
| | | public static String getIp() { |
| | | if (ip == null) { |
| | | try { |
| | | ip = InetAddress.getLocalHost().getHostAddress(); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | return ip; |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.cps.commom.http; |
| | | |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * 字符传工具类 |
| | | * |
| | | * @author baige |
| | | * @date 2020/12/2 17:21 |
| | | */ |
| | | public class StringUtils { |
| | | private StringUtils() { |
| | | } |
| | | |
| | | /** |
| | | * 检查指定的字符串是否为空。 |
| | | * <ul> |
| | | * <li>SysUtils.isEmpty(null) = true</li> |
| | | * <li>SysUtils.isEmpty("") = true</li> |
| | | * <li>SysUtils.isEmpty(" ") = true</li> |
| | | * <li>SysUtils.isEmpty("abc") = false</li> |
| | | * </ul> |
| | | * |
| | | * @param value 待检查的字符串 |
| | | * @return true/false |
| | | */ |
| | | public static boolean isEmpty(String value) { |
| | | int strLen; |
| | | if (value == null || (strLen = value.length()) == 0) { |
| | | return true; |
| | | } |
| | | for (int i = 0; i < strLen; i++) { |
| | | if ((!Character.isWhitespace(value.charAt(i)))) { |
| | | return false; |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 检查对象是否为数字型字符串,包含负数开头的。 |
| | | */ |
| | | public static boolean isNumeric(Object obj) { |
| | | if (obj == null) { |
| | | return false; |
| | | } |
| | | char[] chars = obj.toString().toCharArray(); |
| | | int length = chars.length; |
| | | if (length < 1) { |
| | | return false; |
| | | } |
| | | |
| | | int i = 0; |
| | | if (length > 1 && chars[0] == '-') { |
| | | i = 1; |
| | | } |
| | | |
| | | for (; i < length; i++) { |
| | | if (!Character.isDigit(chars[i])) { |
| | | return false; |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 检查指定的字符串列表是否不为空。 |
| | | */ |
| | | public static boolean areNotEmpty(String... values) { |
| | | boolean result = true; |
| | | if (values == null || values.length == 0) { |
| | | result = false; |
| | | } else { |
| | | for (String value : values) { |
| | | result &= !isEmpty(value); |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 把通用字符编码的字符串转化为汉字编码。 |
| | | */ |
| | | public static String unicodeToChinese(String unicode) { |
| | | StringBuilder out = new StringBuilder(); |
| | | if (!isEmpty(unicode)) { |
| | | for (int i = 0; i < unicode.length(); i++) { |
| | | out.append(unicode.charAt(i)); |
| | | } |
| | | } |
| | | return out.toString(); |
| | | } |
| | | |
| | | /** |
| | | * 过滤不可见字符 |
| | | */ |
| | | public static String stripNonValidXmlCharacters(String input) { |
| | | if (input == null || ("".equals(input))) { |
| | | return ""; |
| | | } |
| | | StringBuilder out = new StringBuilder(); |
| | | char current; |
| | | for (int i = 0; i < input.length(); i++) { |
| | | current = input.charAt(i); |
| | | boolean flag = current == 0x9 || current == 0xA || current == 0xD || current >= 0x20 && current <= 0xD7FF || current >= 0xE000 && current <= 0xFFFD; |
| | | if (flag) { |
| | | out.append(current); |
| | | } |
| | | } |
| | | return out.toString(); |
| | | } |
| | | |
| | | public static String leftPad(String str, int size, char padChar) { |
| | | if (str == null) { |
| | | return null; |
| | | } else { |
| | | int pads = size - str.length(); |
| | | if (pads <= 0) { |
| | | return str; |
| | | } else { |
| | | return pads > 8192 ? leftPad(str, size, String.valueOf(padChar)) : padding(pads, padChar).concat(str); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public static String leftPad(String str, int size, String padStr) { |
| | | if (str == null) { |
| | | return null; |
| | | } else { |
| | | if (isEmpty(padStr)) { |
| | | padStr = " "; |
| | | } |
| | | |
| | | int padLen = padStr.length(); |
| | | int strLen = str.length(); |
| | | int pads = size - strLen; |
| | | if (pads <= 0) { |
| | | return str; |
| | | } else if (padLen == 1 && pads <= 8192) { |
| | | return leftPad(str, size, padStr.charAt(0)); |
| | | } else if (pads == padLen) { |
| | | return padStr.concat(str); |
| | | } else if (pads < padLen) { |
| | | return padStr.substring(0, pads).concat(str); |
| | | } else { |
| | | char[] padding = new char[pads]; |
| | | char[] padChars = padStr.toCharArray(); |
| | | |
| | | for (int i = 0; i < pads; ++i) { |
| | | padding[i] = padChars[i % padLen]; |
| | | } |
| | | |
| | | return (new String(padding)).concat(str); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private static String padding(int repeat, char padChar) throws IndexOutOfBoundsException { |
| | | if (repeat < 0) { |
| | | throw new IndexOutOfBoundsException("Cannot pad a negative amount: " + repeat); |
| | | } else { |
| | | char[] buf = new char[repeat]; |
| | | |
| | | Arrays.fill(buf, padChar); |
| | | |
| | | return new String(buf); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.cps.commom.http; |
| | | |
| | | |
| | | import com.yami.shop.cps.commom.constant.DtkApiConstant; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import javax.net.ssl.*; |
| | | import java.io.*; |
| | | import java.lang.reflect.Field; |
| | | import java.net.*; |
| | | import java.net.Proxy.Type; |
| | | import java.security.SecureRandom; |
| | | import java.security.cert.CertificateException; |
| | | import java.security.cert.X509Certificate; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | import java.util.Map.Entry; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * 网络工具类。 |
| | | * |
| | | * @author xx |
| | | * @since xx |
| | | */ |
| | | @Slf4j |
| | | public class WebUtils { |
| | | |
| | | private static final String DEFAULT_CHARSET = DtkApiConstant.Charset.UTF_8; |
| | | private static final String METHOD_POST = "POST"; |
| | | private static final String METHOD_GET = "GET"; |
| | | |
| | | private static SSLContext ctx = null; |
| | | |
| | | private static HostnameVerifier verifier = null; |
| | | |
| | | private static SSLSocketFactory socketFactory = null; |
| | | |
| | | private static int keepAliveTimeout = 0; |
| | | |
| | | /** |
| | | * 是否校验SSL服务端证书,默认为需要校验 |
| | | */ |
| | | private static volatile boolean needCheckServerTrusted = true; |
| | | |
| | | /** |
| | | * 设置是否校验SSL服务端证书 |
| | | * |
| | | * @param needCheckServerTrusted true:需要校验(默认,推荐); |
| | | * <p> |
| | | * false:不需要校验(仅当部署环境不便于进行服务端证书校验,且已有其他方式确保通信安全时,可以关闭SSL服务端证书校验功能) |
| | | */ |
| | | public static void setNeedCheckServerTrusted(boolean needCheckServerTrusted) { |
| | | WebUtils.needCheckServerTrusted = needCheckServerTrusted; |
| | | } |
| | | |
| | | /** |
| | | * 设置KeepAlive连接超时时间,一次HTTP请求完成后,底层TCP连接将尝试尽量保持该超时时间后才关闭,以便其他HTTP请求复用TCP连接 |
| | | * <p> |
| | | * KeepAlive连接超时时间设置为0,表示使用默认的KeepAlive连接缓存时长(目前为5s) |
| | | * <p> |
| | | * 连接并非一定能保持指定的KeepAlive超时时长,比如服务端断开了连接 |
| | | * <p> |
| | | * 注:该方法目前只在JDK8上测试有效 |
| | | * |
| | | * @param timeout KeepAlive超时时间,单位秒 |
| | | */ |
| | | public static void setKeepAliveTimeout(int timeout) { |
| | | if (timeout < 0 || timeout > 60) { |
| | | throw new RuntimeException("keep-alive timeout value must be between 0 and 60."); |
| | | } |
| | | keepAliveTimeout = timeout; |
| | | } |
| | | |
| | | private static class DefaultTrustManager implements X509TrustManager { |
| | | @Override |
| | | public X509Certificate[] getAcceptedIssuers() { |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public void checkClientTrusted(X509Certificate[] chain, |
| | | String authType) throws CertificateException { |
| | | } |
| | | |
| | | @Override |
| | | public void checkServerTrusted(X509Certificate[] chain, |
| | | String authType) throws CertificateException { |
| | | } |
| | | } |
| | | |
| | | static { |
| | | |
| | | try { |
| | | ctx = SSLContext.getInstance("TLS"); |
| | | ctx.init(new KeyManager[0], new TrustManager[]{new DefaultTrustManager()}, |
| | | new SecureRandom()); |
| | | |
| | | ctx.getClientSessionContext().setSessionTimeout(15); |
| | | ctx.getClientSessionContext().setSessionCacheSize(1000); |
| | | |
| | | socketFactory = ctx.getSocketFactory(); |
| | | } catch (Exception e) { |
| | | log.error(e.getMessage()); |
| | | } |
| | | |
| | | verifier = (hostname, session) -> { |
| | | return false; //不允许URL的主机名和服务器的标识主机名不匹配的情况 |
| | | }; |
| | | |
| | | } |
| | | |
| | | private WebUtils() { |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 执行HTTP GET请求。 |
| | | * |
| | | * @param url 请求地址 |
| | | * @param params 请求参数 |
| | | * @return 响应字符串 |
| | | * @throws IOException |
| | | */ |
| | | public static String doGet(String url, Map<String, String> params) throws IOException { |
| | | return doGet(url, params, DEFAULT_CHARSET); |
| | | } |
| | | |
| | | /** |
| | | * 执行HTTP GET请求。 |
| | | * |
| | | * @param url 请求地址 |
| | | * @param params 请求参数 |
| | | * @param charset 字符集,如UTF-8, GBK, GB2312 |
| | | * @return 响应字符串 |
| | | * @throws IOException |
| | | */ |
| | | public static String doGet(String url, Map<String, String> params, |
| | | String charset) throws IOException { |
| | | HttpURLConnection conn = null; |
| | | String rsp; |
| | | |
| | | try { |
| | | String ctype = "application/x-www-form-urlencoded;charset=" + charset; |
| | | String query = buildQuery(params, charset); |
| | | try { |
| | | conn = getConnection(buildGetUrl(url, query), METHOD_GET, ctype); |
| | | } catch (IOException e) { |
| | | Logger.logCommError(e, url, params.get("appKey"), null, params); |
| | | throw e; |
| | | } |
| | | |
| | | try { |
| | | rsp = getResponseAsString(conn); |
| | | } catch (IOException e) { |
| | | Logger.logCommError(e, conn, params.get("appKey"), null, params); |
| | | throw e; |
| | | } |
| | | |
| | | } finally { |
| | | if (conn != null) { |
| | | conn.disconnect(); |
| | | } |
| | | } |
| | | |
| | | return rsp; |
| | | } |
| | | |
| | | public static HttpURLConnection getConnection(URL url, String method, String ctype) throws IOException { |
| | | return getConnection(url, method, ctype, null); |
| | | } |
| | | |
| | | public static HttpURLConnection getConnection(URL url, String method, String ctype, |
| | | String proxyHost, int proxyPort) throws IOException { |
| | | Proxy proxy = new Proxy(Type.HTTP, new InetSocketAddress(proxyHost, proxyPort)); |
| | | return getConnection(url, method, ctype, proxy); |
| | | } |
| | | |
| | | private static HttpURLConnection getConnection(URL url, String method, String ctype, Proxy proxy) throws IOException { |
| | | HttpURLConnection conn = null; |
| | | if ("https".equals(url.getProtocol())) { |
| | | HttpsURLConnection connHttps = null; |
| | | if (proxy != null) { |
| | | connHttps = (HttpsURLConnection) url.openConnection(proxy); |
| | | } else { |
| | | connHttps = (HttpsURLConnection) url.openConnection(); |
| | | } |
| | | if (!needCheckServerTrusted) { |
| | | //设置不校验服务端证书的SSLContext |
| | | connHttps.setSSLSocketFactory(socketFactory); |
| | | connHttps.setHostnameVerifier(verifier); |
| | | } |
| | | conn = connHttps; |
| | | } else { |
| | | if (proxy != null) { |
| | | conn = (HttpURLConnection) url.openConnection(proxy); |
| | | } else { |
| | | conn = (HttpURLConnection) url.openConnection(); |
| | | } |
| | | } |
| | | |
| | | conn.setRequestMethod(method); |
| | | conn.setDoInput(true); |
| | | conn.setDoOutput(true); |
| | | conn.setRequestProperty("Accept", "text/plain,text/xml,text/javascript,text/html,application/json"); |
| | | conn.setRequestProperty("User-Agent", "aop-sdk-java"); |
| | | conn.setRequestProperty("Content-Type", ctype); |
| | | conn.setRequestProperty("Client-Sdk-Type","java"); |
| | | return conn; |
| | | } |
| | | |
| | | private static URL buildGetUrl(String strUrl, String query) throws IOException { |
| | | URL url = new URL(strUrl); |
| | | if (StringUtils.isEmpty(query)) { |
| | | return url; |
| | | } |
| | | |
| | | if (StringUtils.isEmpty(url.getQuery())) { |
| | | if (strUrl.endsWith("?")) { |
| | | strUrl = strUrl + query; |
| | | } else { |
| | | strUrl = strUrl + "?" + query; |
| | | } |
| | | } else { |
| | | if (strUrl.endsWith("&")) { |
| | | strUrl = strUrl + query; |
| | | } else { |
| | | strUrl = strUrl + "&" + query; |
| | | } |
| | | } |
| | | |
| | | return new URL(strUrl); |
| | | } |
| | | |
| | | public static String buildQuery(Map<String, String> params, String charset) throws IOException { |
| | | if (params == null || params.isEmpty()) { |
| | | return null; |
| | | } |
| | | |
| | | StringBuilder query = new StringBuilder(); |
| | | Set<Entry<String, String>> entries = params.entrySet(); |
| | | boolean hasParam = false; |
| | | |
| | | for (Entry<String, String> entry : entries) { |
| | | String name = entry.getKey(); |
| | | String value = entry.getValue(); |
| | | // 忽略参数名或参数值为空的参数 |
| | | if (StringUtils.areNotEmpty(name, value)) { |
| | | if (hasParam) { |
| | | query.append("&"); |
| | | } else { |
| | | hasParam = true; |
| | | } |
| | | |
| | | query.append(name).append("=").append(URLEncoder.encode(value, charset)); |
| | | } |
| | | } |
| | | |
| | | return query.toString(); |
| | | } |
| | | |
| | | protected static String getResponseAsString(HttpURLConnection conn) throws IOException { |
| | | String charset = getResponseCharset(conn.getContentType()); |
| | | |
| | | //此时设置KeepAlive超时所需数据结构才刚初始化完整,可以通过反射修改 |
| | | //同时也不宜将修改时机再滞后,因为可能后续连接缓存类已经消费了默认的KeepAliveTimeout值,再修改已经无效 |
| | | setKeepAliveTimeout(conn); |
| | | |
| | | InputStream es = conn.getErrorStream(); |
| | | if (es == null) { |
| | | return getStreamAsString(conn.getInputStream(), charset); |
| | | } else { |
| | | String msg = getStreamAsString(es, charset); |
| | | if (StringUtils.isEmpty(msg)) { |
| | | throw new IOException(conn.getResponseCode() + ":" + conn.getResponseMessage()); |
| | | } else { |
| | | throw new IOException(msg); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private static String getStreamAsString(InputStream stream, String charset) throws IOException { |
| | | try { |
| | | BufferedReader reader = new BufferedReader(new InputStreamReader(stream, charset)); |
| | | StringWriter writer = new StringWriter(); |
| | | |
| | | char[] chars = new char[256]; |
| | | int count = 0; |
| | | while ((count = reader.read(chars)) > 0) { |
| | | writer.write(chars, 0, count); |
| | | } |
| | | |
| | | return writer.toString(); |
| | | } finally { |
| | | if (stream != null) { |
| | | stream.close(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private static String getResponseCharset(String ctype) { |
| | | String charset = DEFAULT_CHARSET; |
| | | |
| | | if (!StringUtils.isEmpty(ctype)) { |
| | | String[] params = ctype.split(";"); |
| | | for (String param : params) { |
| | | param = param.trim(); |
| | | if (param.startsWith("charset")) { |
| | | String[] pair = param.split("=", 2); |
| | | if (pair.length == 2) { |
| | | if (!StringUtils.isEmpty(pair[1])) { |
| | | charset = pair[1].trim(); |
| | | } |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return charset; |
| | | } |
| | | |
| | | /** |
| | | * 使用默认的UTF-8字符集反编码请求参数值。 |
| | | * |
| | | * @param value 参数值 |
| | | * @return 反编码后的参数值 |
| | | */ |
| | | public static String decode(String value) { |
| | | return decode(value, DEFAULT_CHARSET); |
| | | } |
| | | |
| | | /** |
| | | * 使用默认的UTF-8字符集编码请求参数值。 |
| | | * |
| | | * @param value 参数值 |
| | | * @return 编码后的参数值 |
| | | */ |
| | | public static String encode(String value) { |
| | | return encode(value, DEFAULT_CHARSET); |
| | | } |
| | | |
| | | /** |
| | | * 使用指定的字符集反编码请求参数值。 |
| | | * |
| | | * @param value 参数值 |
| | | * @param charset 字符集 |
| | | * @return 反编码后的参数值 |
| | | */ |
| | | public static String decode(String value, String charset) { |
| | | String result = null; |
| | | if (!StringUtils.isEmpty(value)) { |
| | | try { |
| | | result = URLDecoder.decode(value, charset); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 使用指定的字符集编码请求参数值。 |
| | | * |
| | | * @param value 参数值 |
| | | * @param charset 字符集 |
| | | * @return 编码后的参数值 |
| | | */ |
| | | public static String encode(String value, String charset) { |
| | | String result = null; |
| | | if (!StringUtils.isEmpty(value)) { |
| | | try { |
| | | result = URLEncoder.encode(value, charset); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | private static Map<String, String> getParamsFromUrl(String url) { |
| | | Map<String, String> map = null; |
| | | if (url != null && url.indexOf('?') != -1) { |
| | | map = splitUrlQuery(url.substring(url.indexOf('?') + 1)); |
| | | } |
| | | if (map == null) { |
| | | map = new HashMap<>(); |
| | | } |
| | | return map; |
| | | } |
| | | |
| | | /** |
| | | * 从URL中提取所有的参数。 |
| | | * |
| | | * @param query URL地址 |
| | | * @return 参数映射 |
| | | */ |
| | | public static Map<String, String> splitUrlQuery(String query) { |
| | | Map<String, String> result = new HashMap<String, String>(); |
| | | |
| | | String[] pairs = query.split("&"); |
| | | if (pairs != null && pairs.length > 0) { |
| | | for (String pair : pairs) { |
| | | String[] param = pair.split("=", 2); |
| | | if (param != null && param.length == 2) { |
| | | result.put(param[0], param[1]); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | public static String buildForm(String baseUrl, Map<String, String> parameters) { |
| | | StringBuilder sb = new StringBuilder(); |
| | | sb.append("<form name=\"punchout_form\" method=\"post\" action=\""); |
| | | sb.append(baseUrl); |
| | | sb.append("\">\n"); |
| | | sb.append(buildHiddenFields(parameters)); |
| | | |
| | | sb.append("<input type=\"submit\" value=\"立即支付\" style=\"display:none\" >\n"); |
| | | sb.append("</form>\n"); |
| | | sb.append("<script>document.forms[0].submit();</script>"); |
| | | String form = sb.toString(); |
| | | return form; |
| | | } |
| | | |
| | | private static String buildHiddenFields(Map<String, String> parameters) { |
| | | if (parameters == null || parameters.isEmpty()) { |
| | | return ""; |
| | | } |
| | | StringBuilder sb = new StringBuilder(); |
| | | Set<String> keys = parameters.keySet(); |
| | | for (String key : keys) { |
| | | String value = parameters.get(key); |
| | | // 除去参数中的空值 |
| | | if (key == null || value == null) { |
| | | continue; |
| | | } |
| | | sb.append(buildHiddenField(key, value)); |
| | | } |
| | | return sb.toString(); |
| | | } |
| | | |
| | | private static String buildHiddenField(String key, String value) { |
| | | StringBuilder sb = new StringBuilder(); |
| | | sb.append("<input type=\"hidden\" name=\""); |
| | | sb.append(key); |
| | | |
| | | sb.append("\" value=\""); |
| | | //转义双引号 |
| | | String a = value.replace("\"", """); |
| | | sb.append(a).append("\">\n"); |
| | | return sb.toString(); |
| | | } |
| | | |
| | | /** |
| | | * 由于HttpUrlConnection不支持设置KeepAlive超时时间,该方法通过反射机制设置 |
| | | * |
| | | * @param connection 需要设置KeepAlive的连接 |
| | | */ |
| | | private static void setKeepAliveTimeout(HttpURLConnection connection) { |
| | | if (keepAliveTimeout == 0) { |
| | | return; |
| | | } |
| | | try { |
| | | |
| | | Field delegateHttpsUrlConnectionField = Class.forName("sun.net.www.protocol.https.HttpsURLConnectionImpl").getDeclaredField( |
| | | "delegate"); |
| | | delegateHttpsUrlConnectionField.setAccessible(true); |
| | | Object delegateHttpsUrlConnection = delegateHttpsUrlConnectionField.get(connection); |
| | | |
| | | Field httpClientField = Class.forName("sun.net.www.protocol.http.HttpURLConnection").getDeclaredField("http"); |
| | | httpClientField.setAccessible(true); |
| | | Object httpClient = httpClientField.get(delegateHttpsUrlConnection); |
| | | |
| | | Field keepAliveTimeoutField = Class.forName("sun.net.www.http.HttpClient").getDeclaredField("keepAliveTimeout"); |
| | | keepAliveTimeoutField.setAccessible(true); |
| | | keepAliveTimeoutField.setInt(httpClient, keepAliveTimeout); |
| | | } catch (Throwable ignored) { |
| | | //设置KeepAlive超时只是一种优化辅助手段,设置失败不应阻塞主链路,设置失败不应影响功能 |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.cps.commom.request.base; |
| | | |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Getter; |
| | | import lombok.Setter; |
| | | |
| | | /** |
| | | * dtk api: page param,independent of business entity |
| | | * |
| | | * @author 1 |
| | | * @date 2020/11/9 17:15 |
| | | */ |
| | | @Getter |
| | | @Setter |
| | | public class DtkPageParamRequest { |
| | | @ApiModelProperty(value = "每页条数,默认为100,最大值200,若小于10,则按10条处理,每页条数仅支持输入10,50,100,200", required = true, example = |
| | | "10") |
| | | private Integer pageSize; |
| | | @ApiModelProperty(value = "分页id,默认为1,支持传统的页码分页方式和scroll_id分页方式,根据用户自身需求传入值。示例1:商品入库,则首次传入1,后续传入接口返回的pageid" + |
| | | ",接口将持续返回符合条件的完整商品列表,该方式可以避免入口商品重复;示例2:根据pageSize和totalNum计算出总页数,按照需求返回指定页的商品(该方式可能在临近页取到重复商品)", required |
| | | = true, example = "1") |
| | | private String pageId; |
| | | } |
New file |
| | |
| | | package com.yami.shop.cps.commom.request.base; |
| | | |
| | | |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Getter; |
| | | import lombok.Setter; |
| | | |
| | | /** |
| | | * dtk api: url param,independent of business entity |
| | | * |
| | | * @author 1 |
| | | * @date 2020/11/9 17:15 |
| | | */ |
| | | @Getter |
| | | @Setter |
| | | public class DtkUrlParamRequest { |
| | | @ApiModelProperty(value = "请求地址", hidden = true) |
| | | private String requestUrl; |
| | | } |
New file |
| | |
| | | package com.yami.shop.cps.commom.request.mastertool; |
| | | |
| | | |
| | | import com.fasterxml.jackson.core.type.TypeReference; |
| | | import com.yami.shop.cps.commom.client.DtkApiRequest; |
| | | import com.yami.shop.cps.commom.response.base.DtkApiResponse; |
| | | import com.yami.shop.cps.commom.response.mastertool.DtkActivityLinkResponse; |
| | | import com.yami.shop.cps.commom.utils.ObjectUtil; |
| | | import com.yami.shop.cps.commom.utils.RequiredCheck; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Getter; |
| | | import lombok.Setter; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 官方活动会场转链请求参数实体 |
| | | * |
| | | * @author 1 |
| | | * @date 2020/11/10 18:04 |
| | | */ |
| | | @Getter |
| | | @Setter |
| | | public class DtkActivityLinkRequest implements DtkApiRequest<DtkApiResponse<DtkActivityLinkResponse>> { |
| | | @ApiModelProperty(value = "版本号", example = "v1.0.0") |
| | | private String version = "1.0.0"; |
| | | @RequiredCheck |
| | | @ApiModelProperty(value = "联盟官方活动ID,从联盟官方活动页获取或从大淘客官方活动推广接口获取", required = true) |
| | | private String promotionSceneId; |
| | | @ApiModelProperty(value = "推广pid,默认为在”我的应用“添加的pid") |
| | | private String pid; |
| | | @ApiModelProperty(value = "渠道id将会和传入的pid进行验证,验证通过将正常转链,请确认填入的渠道id是正确的") |
| | | private String relationId; |
| | | @ApiModelProperty(value = "自定义输入串,英文和数字组成,长度不能大于12个字符,区分不同的推广渠道") |
| | | private String unionId; |
| | | @ApiModelProperty("官方活动会场转链请求path") |
| | | private final String requestPath = "/tb-service/activity-link"; |
| | | |
| | | @Override |
| | | public Map<String, String> getTextParams() throws IllegalAccessException { |
| | | return ObjectUtil.objToMap(this); |
| | | } |
| | | |
| | | @Override |
| | | public String apiVersion() { |
| | | return this.version; |
| | | } |
| | | |
| | | @Override |
| | | public TypeReference<DtkApiResponse<DtkActivityLinkResponse>> responseType() { |
| | | return new TypeReference<DtkApiResponse<DtkActivityLinkResponse>>() { |
| | | }; |
| | | } |
| | | |
| | | @Override |
| | | public String requestUrl() { |
| | | return this.requestPath; |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.cps.commom.request.mastertool; |
| | | |
| | | import com.fasterxml.jackson.core.type.TypeReference; |
| | | import com.yami.shop.cps.commom.client.DtkApiRequest; |
| | | import com.yami.shop.cps.commom.response.base.DtkApiResponse; |
| | | import com.yami.shop.cps.commom.response.mastertool.DtkCommodityMaterialsResponse; |
| | | import com.yami.shop.cps.commom.utils.ObjectUtil; |
| | | import com.yami.shop.cps.commom.utils.RequiredCheck; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Getter; |
| | | import lombok.Setter; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 商品精推素材请求参数实体 |
| | | * |
| | | * @author 1 |
| | | * @date 2021/07/07 14:27 |
| | | */ |
| | | @Getter |
| | | @Setter |
| | | public class DtkCommodityMaterialsRequest implements DtkApiRequest<DtkApiResponse<List<DtkCommodityMaterialsResponse>>> { |
| | | @ApiModelProperty(value = "版本号", example = "v1.0.0") |
| | | private String version = "1.0.0"; |
| | | @RequiredCheck |
| | | @ApiModelProperty(value = "大淘客商品id或联盟商品id") |
| | | private String id; |
| | | @ApiModelProperty("商品精推素材转链请求path") |
| | | private final String requestPath = "/goods/material/list"; |
| | | |
| | | @Override |
| | | public Map<String, String> getTextParams() throws IllegalAccessException { |
| | | return ObjectUtil.objToMap(this); |
| | | } |
| | | |
| | | @Override |
| | | public String apiVersion() { |
| | | return this.version; |
| | | } |
| | | |
| | | @Override |
| | | public TypeReference<DtkApiResponse<List<DtkCommodityMaterialsResponse>>> responseType() { |
| | | return new TypeReference<DtkApiResponse<List<DtkCommodityMaterialsResponse>>>() { |
| | | }; |
| | | } |
| | | |
| | | @Override |
| | | public String requestUrl() { |
| | | return this.requestPath; |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.cps.commom.request.mastertool; |
| | | |
| | | import com.fasterxml.jackson.core.type.TypeReference; |
| | | import com.yami.shop.cps.commom.client.DtkApiRequest; |
| | | import com.yami.shop.cps.commom.response.base.DtkApiResponse; |
| | | import com.yami.shop.cps.commom.response.mastertool.DtkCouponQueryResponse; |
| | | import com.yami.shop.cps.commom.utils.ObjectUtil; |
| | | import com.yami.shop.cps.commom.utils.RequiredCheck; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Getter; |
| | | import lombok.Setter; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 优惠券查询请求参数实体 |
| | | * |
| | | * @author 1 |
| | | * @date 2021/07/07 14:27 |
| | | */ |
| | | @Getter |
| | | @Setter |
| | | public class DtkCouponQueryRequest implements DtkApiRequest<DtkApiResponse<DtkCouponQueryResponse>> { |
| | | @ApiModelProperty(value = "版本号", example = "v1.0.0") |
| | | private String version = "1.0.0"; |
| | | @RequiredCheck |
| | | @ApiModelProperty(value = "二合一链接,淘口令,或同时输入商品+优惠券链接") |
| | | private String content; |
| | | @ApiModelProperty("优惠券查询请求path") |
| | | private final String requestPath = "/dels/taobao/kit/coupon/get-coupon-info"; |
| | | |
| | | @Override |
| | | public Map<String, String> getTextParams() throws IllegalAccessException { |
| | | return ObjectUtil.objToMap(this); |
| | | } |
| | | |
| | | @Override |
| | | public String apiVersion() { |
| | | return this.version; |
| | | } |
| | | |
| | | @Override |
| | | public TypeReference<DtkApiResponse<DtkCouponQueryResponse>> responseType() { |
| | | return new TypeReference<DtkApiResponse<DtkCouponQueryResponse>>() { |
| | | }; |
| | | } |
| | | |
| | | @Override |
| | | public String requestUrl() { |
| | | return this.requestPath; |
| | | } |
| | | } |
New file |
| | |
| | | package com.yami.shop.cps.commom.request.mastertool; |
| | | |
| | | import com.fasterxml.jackson.core.type.TypeReference; |
| | | import com.yami.shop.cps.commom.client.DtkApiRequest; |
| | | import com.yami.shop.cps.commom.response.base.DtkApiResponse; |
| | | import com.yami.shop.cps.commom.response.mastertool.DtkCreatTaokoulingResponse; |
| | | import com.yami.shop.cps.commom.utils.ObjectUtil; |
| | | import com.yami.shop.cps.commom.utils.RequiredCheck; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Getter; |
| | | import lombok.Setter; |
| | | |
| | | import java.util.TreeMap; |
| | | |
| | | /** |
| | | * 淘口令生成请求参数实体 |
| | | * |
| | | * @author 1 |
| | | * @date 2020/11/10 18:05 |
| | | */ |
| | | @Getter |
| | | @Setter |
| | | public class DtkCreatTaokoulingRequest implements DtkApiRequest<DtkApiResponse<DtkCreatTaokoulingResponse>> { |
| | | @ApiModelProperty(value = "版本号", example = "v1.0.0") |
| | | private String version = "v1.0.0"; |
| | | @RequiredCheck |
| | | @ApiModelProperty(value = "口令弹框内容,长度大于5个字符", required = true) |
| | | private String text; |
| | | @RequiredCheck |
| | | @ApiModelProperty(value = "口令跳转目标页,如:https://uland.taobao" + |
| | | ".com/,必须以https开头,可以是二合一链接、长链接、短链接等各种淘宝高佣链接;支持渠道备案链接。该参数需要进行UrlEncode编码后传入", required = true) |
| | | private String url; |
| | | @ApiModelProperty(value = "口令弹框logoURL") |
| | | private String logo; |
| | | @ApiModelProperty(value = "生成口令的淘宝用户ID,非必传参数") |
| | | private String userId; |
| | | @ApiModelProperty("淘口令生成请求path") |
| | | private final String requestPath = "/tb-service/creat-taokouling"; |
| | | |
| | | @Override |
| | | public TypeReference<DtkApiResponse<DtkCreatTaokoulingResponse>> responseType() { |
| | | return new TypeReference<DtkApiResponse<DtkCreatTaokoulingResponse>>() { |
| | | }; |
| | | } |
| | | |
| | | @Override |
| | | public TreeMap<String, String> getTextParams() throws IllegalAccessException { |
| | | return ObjectUtil.objToMap(this); |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public String apiVersion() { |
| | | return this.version; |
| | | } |
| | | |
| | | @Override |
| | | public String requestUrl() { |
| | | return this.requestPath; |
| | | } |
| | | } |
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/mastertool/DtkCzmfTransformLinkRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/mastertool/DtkFirstOrderGiftMoneyRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/mastertool/DtkGetCollectionListRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/mastertool/DtkGetOrderDetailsRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/mastertool/DtkGetOwnerGoodsRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/mastertool/DtkGetPrivilegeLinkRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/mastertool/DtkGetSuperCategoryRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/mastertool/DtkGoodsCommentListRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/mastertool/DtkJdBatchTransformLinkRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/mastertool/DtkJdCommodityTransformLinkRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/mastertool/DtkJdLinkAnalysisRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/mastertool/DtkJdOrderQueryRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/mastertool/DtkJdOrderQueryV2Request.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/mastertool/DtkMergeRedEnvelopesRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/mastertool/DtkParseContentRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/mastertool/DtkParseTaokoulingRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/mastertool/DtkPddTransformLinkRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/mastertool/DtkShopConvertRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/mastertool/DtkTbCashGiftRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/mastertool/DtkTwdToTwdRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/mastertool/ShearPlateDistinguishRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/putstorage/DtkGoodsDetailsRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/putstorage/DtkGoodsListRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/putstorage/DtkJdCommodityDetailsRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/putstorage/DtkNewestGoodsRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/putstorage/DtkPddGoodsDetailsRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/putstorage/DtkPullGoodsByTimeRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/putstorage/DtkStaleGoodsByTimeRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/search/DtkGetDtkSearchGoodsRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/search/DtkGetTbServiceRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/search/DtkGetTop100Request.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/search/DtkHotSearchListRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/search/DtkJdGoodsTypeRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/search/DtkJdUnionQueryRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/search/DtkListSuperGoodsRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/search/DtkPddGoodsTypeRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/search/DtkPddOrderIncrementSearchRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/search/DtkPddUnionQueryRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/search/DtkSearchSuggestionRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/search/DtkTbkScPunishOrderGetRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/search/DtkTbkScRelationRefundRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkActivityCatalogueRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkActivityGoodsListRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkAlbumListRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkBigBrandDiscountRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkCarouselMapResponseRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkCatalogueRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkDdqGoodsListRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkExclusiveGoodsListRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkExplosiveGoodsListRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkFriendsCircleListRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkGetBrandGoodsListRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkGetBrandListRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkGetColumnListRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkGetHalfPriceDayRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkGetRankListRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkGetRankingListRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkGetTbTopicListRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkHighCommissionSelectedRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkHistoricalNewLowCommodityRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkJdCommodityDiscountPriceRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkJdNewYearCommodityRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkJdOneDollarPurchaseOrderInquiryRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkListSimilerGoodsByOpenRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkLiveMaterialGoodsListRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkMostPopularCommodityListRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkNineFreeShippingRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkOpGoodsListRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkPopularAnchorCommendRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkPriceTrendRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkRealTimeListRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkSingleAlbumCommodityRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkSubdivisionCategoryListRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkSuperDiscountGoodsRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkTipOffRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/DtkTopicGoodsListRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/subranking/DtkGetRankingListBaseRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/subranking/DtkGetRankingListByHotSearchRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/subranking/DtkGetRankingListByHotWordRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/subranking/DtkGetRankingListByHotWordUpRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/subranking/DtkGetRankingListByReBuyRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/request/special/subranking/DtkGetRankingListByTimeWholeHotRequest.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/DtkSingleAlbumCommodityResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/base/DtkApiResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/base/DtkDiffPageResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/base/DtkPageResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/base/DtkSearchPageResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkActivityLinkResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkCommodityMaterialsResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkCouponQueryResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkCreatTaokoulingResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkCzmfTransformLinkResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkFirstOrderGiftMoneyItemResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkFirstOrderGiftMoneyResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkGetCollectionListItemResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkGetOrderDetailsResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkGetOrderDetailsResultsItemsResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkGetOrderDetailsResultsResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkGetOwnerGoodsItemResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkGetPrivilegeLinkResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkGetSuperCategoryResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkGetSuperCategorySubResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkGoodsCommentListResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkJdBatchTransformLinkResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkJdCommodityTransformLinkResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkJdLinkAnalysisResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkJdOrderQueryResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkJdOrderQueryV2Response.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkMergeRedEnvelopesResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkParseContentOriginInfoResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkParseContentResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkPddTransformLinkResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkShopConvertResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkTbCashGiftResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/DtkTwdToTwdResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/MtOrderResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/mastertool/ShearPlateDistinguishResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/putstorage/DtkBaseItemResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/putstorage/DtkGoodsDetailsResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/putstorage/DtkGoodsListItemResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/putstorage/DtkJdCommodityDetailsResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/putstorage/DtkNewestGoodsResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/putstorage/DtkPddGoodsDetailsResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/putstorage/DtkStaleGoodsByTimeResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/search/DtkGetDtkSearchGoodsResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/search/DtkGetDtkSearchGoodsResponse1.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/search/DtkGetTbServiceImagesResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/search/DtkGetTbServiceResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/search/DtkGetTop100Response.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/search/DtkHotSearchListResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/search/DtkJdGoodsTypeResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/search/DtkJdUnionQueryResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/search/DtkListSuperGoodsResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/search/DtkPddGoodsTypeResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/search/DtkPddOrderIncrementSearchResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/search/DtkPddUnionQueryResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/search/DtkSearchSuggestionResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/search/DtkTbkScPunishOrderGetResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/search/DtkTbkScRelationRefundResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkActivityCatalogueResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkActivityGoodsListResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkAlbumListResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkBigBrandDiscountResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkCarouselMapResponseResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkCatalogueResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkDdqGoodsListItemResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkDdqGoodsListResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkDdqRoundListResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkExclusiveGoodsListResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkFriendsCircleListResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkGetBrandGoodsListResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkGetBrandListResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkGetColumnListResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkGetHalfPriceDayPriceItemResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkGetHalfPriceDayPriceResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkGetHalfPriceDayResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkGetHalfPriceDaySessionResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkGetRankingListMergeResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkGetTbTopicListResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkGetVideoGoodsCategoryResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkGetVideoGoodsListResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkHighCommissionSelectedResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkHistoricalNewLowCommodityResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkJdCommodityDiscountPriceResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkJdNewYearCommodityResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkJdOneDollarPurchaseOrderInquiryResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkListSimilerGoodsByOpenResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkLiveMaterialGoodsListResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkMostPopularCommodityListResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkNineFreeShippingResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkOpGoodsListResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkPopularAnchorCommendResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkPopularGoodsListResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkPriceTrendHistoricalPriceResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkPriceTrendResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkRealTimeListResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkSubdivisionCategoryListResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkSuperDiscountGoodsResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/DtkTipOffResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/subranking/DtkGetHotWordRankingResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/subranking/DtkGetRankingListByHotSearchResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/subranking/DtkGetRankingListByHotWordResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/subranking/DtkGetRankingListByHotWordUpResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/subranking/DtkGetRankingListByReBuyResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/subranking/DtkGetRankingListByTimeWholeHotResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/response/special/subranking/DtkRankingBaseResponse.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/service/CpsDdCategoryService.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/service/CpsDdOrderService.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/service/CpsJdCategoryService.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/service/CpsJdOrderService.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/service/CpsJtkOrderService.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/service/CpsMtActitvityService.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/service/CpsMtOrderService.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/service/CpsOrderService.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/service/CpsShopService.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/service/impl/CpsDdCategoryServiceImpl.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/service/impl/CpsDdOrderServiceImpl.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/service/impl/CpsJdCategoryServiceImpl.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/service/impl/CpsJdOrderServiceImpl.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/service/impl/CpsJtkOrderServiceImpl.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/service/impl/CpsMtActitvityServiceImpl.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/service/impl/CpsMtOrderServiceImpl.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/service/impl/CpsOrderServiceImpl.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/service/impl/CpsShopServiceImpl.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/utils/AESUtils.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/utils/Assert.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/utils/DTKUtils.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/utils/JsonUtil.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/utils/JtkUtils.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/utils/MTUtils.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/utils/ObjectUtil.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/utils/PddUtils.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/utils/RequiredCheck.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/utils/SignMd5Util.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/utils/SignUtils.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/utils/TBUtils.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/vo/JingDongVo.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/vo/JtkVo.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/vo/MtfxlmVo.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/vo/MtlmVo.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/vo/PddVo.java
yami-shop-cps/yami-shop-cps-common/src/main/java/com/yami/shop/cps/commom/vo/TaoBaoVo.java
yami-shop-cps/yami-shop-cps-common/src/main/resources/META-INF/MANIFEST.MF
yami-shop-cps/yami-shop-cps-platform/pom.xml
yami-shop-cps/yami-shop-cps-platform/src/main/java/com/yami/shop/cps/platform/config/SwaggerConfiguration.java
yami-shop-cps/yami-shop-cps-platform/src/main/java/com/yami/shop/cps/platform/controller/CpsController.java
yami-shop-delivery/pom.xml
yami-shop-delivery/yami-shop-delivery-api/pom.xml
yami-shop-delivery/yami-shop-delivery-api/src/main/java/com/yami/shop/delivery/api/config/SwaggerConfiguration.java
yami-shop-delivery/yami-shop-delivery-api/src/main/java/com/yami/shop/delivery/api/controller/MyDeliveryController.java
yami-shop-delivery/yami-shop-delivery-api/src/main/java/com/yami/shop/delivery/api/controller/MyStationOrderController.java
yami-shop-delivery/yami-shop-delivery-api/src/main/java/com/yami/shop/delivery/api/controller/OrderSelfStationController.java
yami-shop-delivery/yami-shop-delivery-api/src/main/java/com/yami/shop/delivery/api/controller/StationController.java
yami-shop-delivery/yami-shop-delivery-api/src/main/java/com/yami/shop/delivery/api/listener/CheckAddrListener.java
yami-shop-delivery/yami-shop-delivery-api/src/main/java/com/yami/shop/delivery/api/listener/GetUserStationListener.java
yami-shop-delivery/yami-shop-delivery-api/src/main/java/com/yami/shop/delivery/api/listener/SubmitOrderListener.java
yami-shop-delivery/yami-shop-delivery-api/src/main/java/com/yami/shop/delivery/api/manager/DeliveryOrderManager.java
yami-shop-delivery/yami-shop-delivery-common/pom.xml
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/constant/TransportFreeType.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/dao/DeliveryOrderItemMapper.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/dao/DeliveryOrderMapper.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/dao/OrderSelfStationMapper.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/dao/SameCityMapper.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/dao/TranscityFreeMapper.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/dao/TranscityMapper.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/dao/TransfeeFreeMapper.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/dao/TransfeeMapper.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/dao/TransportMapper.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/listener/SameCityListener.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/model/DeliveryOrder.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/model/DeliveryOrderItem.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/model/OrderSelfStation.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/model/SameCity.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/model/Transcity.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/model/TranscityFree.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/model/Transfee.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/model/TransfeeFree.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/model/Transport.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/param/DeliveryOrderItemParam.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/param/DvyOrderParam.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/param/OrderItemParam.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/param/OrderParam.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/param/StationParam.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/service/DeliveryOrderItemService.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/service/DeliveryOrderService.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/service/OrderSelfStationService.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/service/SameCityService.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/service/TranscityFreeService.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/service/TranscityService.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/service/TransfeeFreeService.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/service/TransfeeService.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/service/TransportManagerService.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/service/TransportService.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/service/impl/DeliveryOrderItemServiceImpl.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/service/impl/DeliveryOrderServiceImpl.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/service/impl/OrderSelfStationServiceImpl.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/service/impl/SameCityServiceImpl.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/service/impl/TranscityFreeServiceImpl.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/service/impl/TranscityServiceImpl.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/service/impl/TransfeeFreeServiceImpl.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/service/impl/TransfeeServiceImpl.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/service/impl/TransportManagerServiceImpl.java
yami-shop-delivery/yami-shop-delivery-common/src/main/java/com/yami/shop/delivery/common/service/impl/TransportServiceImpl.java
yami-shop-delivery/yami-shop-delivery-common/src/main/resources/mapper/DeliveryOrderItemMapper.xml
yami-shop-delivery/yami-shop-delivery-common/src/main/resources/mapper/DeliveryOrderMapper.xml
yami-shop-delivery/yami-shop-delivery-common/src/main/resources/mapper/OrderSelfStationMapper.xml
yami-shop-delivery/yami-shop-delivery-common/src/main/resources/mapper/SameCityMapper.xml
yami-shop-delivery/yami-shop-delivery-common/src/main/resources/mapper/TranscityFreeMapper.xml
yami-shop-delivery/yami-shop-delivery-common/src/main/resources/mapper/TranscityMapper.xml
yami-shop-delivery/yami-shop-delivery-common/src/main/resources/mapper/TransfeeFreeMapper.xml
yami-shop-delivery/yami-shop-delivery-common/src/main/resources/mapper/TransfeeMapper.xml
yami-shop-delivery/yami-shop-delivery-common/src/main/resources/mapper/TransportMapper.xml
yami-shop-delivery/yami-shop-delivery-multishop/pom.xml
yami-shop-delivery/yami-shop-delivery-multishop/src/main/java/com/yami/shop/delivery/multishop/config/SwaggerConfiguration.java
yami-shop-delivery/yami-shop-delivery-multishop/src/main/java/com/yami/shop/delivery/multishop/controller/OrderDeliveryController.java
yami-shop-delivery/yami-shop-delivery-multishop/src/main/java/com/yami/shop/delivery/multishop/controller/SameCityController.java
yami-shop-delivery/yami-shop-delivery-multishop/src/main/java/com/yami/shop/delivery/multishop/controller/StationController.java
yami-shop-delivery/yami-shop-delivery-multishop/src/main/java/com/yami/shop/delivery/multishop/controller/TransportController.java
yami-shop-delivery/yami-shop-delivery-multishop/src/main/java/com/yami/shop/delivery/multishop/listener/GetTransportNamesListener.java
yami-shop-delivery/yami-shop-delivery-multishop/src/main/java/com/yami/shop/delivery/multishop/listener/OrderChangeAddrListener.java
yami-shop-delivery/yami-shop-delivery-platform/pom.xml
yami-shop-delivery/yami-shop-delivery-platform/src/main/java/com/yami/shop/delivery/platform/config/SwaggerConfiguration.java
yami-shop-delivery/yami-shop-delivery-platform/src/main/java/com/yami/shop/delivery/platform/controller/OrderDeliveryController.java
yami-shop-delivery/yami-shop-delivery-platform/src/main/java/com/yami/shop/delivery/platform/controller/StationController.java
yami-shop-delivery/yami-shop-delivery-platform/src/main/java/com/yami/shop/delivery/platform/controller/TransportController.java |