Commit 1f910992d6a8f5aa5b24dc652bde62de9b341ab8

Authored by YunaiV
1 parent fdb10aec

trade:新增是否自提的配置项

Showing 12 changed files with 100 additions and 42 deletions
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/number/NumberUtils.java
@@ -13,4 +13,28 @@ public class NumberUtils { @@ -13,4 +13,28 @@ public class NumberUtils {
13 return StrUtil.isNotEmpty(str) ? Long.valueOf(str) : null; 13 return StrUtil.isNotEmpty(str) ? Long.valueOf(str) : null;
14 } 14 }
15 15
  16 + /**
  17 + * 通过经纬度获取地球上两点之间的距离
  18 + *
  19 + * 参考 <<a href="https://gitee.com/dromara/hutool/blob/1caabb586b1f95aec66a21d039c5695df5e0f4c1/hutool-core/src/main/java/cn/hutool/core/util/DistanceUtil.java">DistanceUtil</a>> 实现,目前它已经被 hutool 删除
  20 + *
  21 + * @param lat1 经度1
  22 + * @param lng1 纬度1
  23 + * @param lat2 经度2
  24 + * @param lng2 纬度2
  25 + * @return 距离,单位:千米
  26 + */
  27 + public static double getDistance(double lat1, double lng1, double lat2, double lng2) {
  28 + double radLat1 = lat1 * Math.PI / 180.0;
  29 + double radLat2 = lat2 * Math.PI / 180.0;
  30 + double a = radLat1 - radLat2;
  31 + double b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0;
  32 + double distance = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
  33 + + Math.cos(radLat1) * Math.cos(radLat2)
  34 + * Math.pow(Math.sin(b / 2), 2)));
  35 + distance = distance * 6378.137;
  36 + distance = Math.round(distance * 10000d) / 10000d;
  37 + return distance;
  38 + }
  39 +
16 } 40 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/TradeConfigController.java
@@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO; @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
8 import cn.iocoder.yudao.module.trade.service.config.TradeConfigService; 8 import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
9 import io.swagger.v3.oas.annotations.Operation; 9 import io.swagger.v3.oas.annotations.Operation;
10 import io.swagger.v3.oas.annotations.tags.Tag; 10 import io.swagger.v3.oas.annotations.tags.Tag;
  11 +import org.springframework.beans.factory.annotation.Value;
11 import org.springframework.security.access.prepost.PreAuthorize; 12 import org.springframework.security.access.prepost.PreAuthorize;
12 import org.springframework.validation.annotation.Validated; 13 import org.springframework.validation.annotation.Validated;
13 import org.springframework.web.bind.annotation.*; 14 import org.springframework.web.bind.annotation.*;
@@ -26,6 +27,9 @@ public class TradeConfigController { @@ -26,6 +27,9 @@ public class TradeConfigController {
26 @Resource 27 @Resource
27 private TradeConfigService tradeConfigService; 28 private TradeConfigService tradeConfigService;
28 29
  30 + @Value("${yudao.tencent-lbs-key}")
  31 + private String tencentLbsKey;
  32 +
29 @PutMapping("/save") 33 @PutMapping("/save")
30 @Operation(summary = "更新交易中心配置") 34 @Operation(summary = "更新交易中心配置")
31 @PreAuthorize("@ss.hasPermission('trade:config:save')") 35 @PreAuthorize("@ss.hasPermission('trade:config:save')")
@@ -39,7 +43,11 @@ public class TradeConfigController { @@ -39,7 +43,11 @@ public class TradeConfigController {
39 @PreAuthorize("@ss.hasPermission('trade:config:query')") 43 @PreAuthorize("@ss.hasPermission('trade:config:query')")
40 public CommonResult<TradeConfigRespVO> getConfig() { 44 public CommonResult<TradeConfigRespVO> getConfig() {
41 TradeConfigDO config = tradeConfigService.getTradeConfig(); 45 TradeConfigDO config = tradeConfigService.getTradeConfig();
42 - return success(TradeConfigConvert.INSTANCE.convert(config)); 46 + TradeConfigRespVO configVO = TradeConfigConvert.INSTANCE.convert(config);
  47 + if (configVO != null) {
  48 + configVO.setTencentLbsKey(tencentLbsKey);
  49 + }
  50 + return success(configVO);
43 } 51 }
44 52
45 } 53 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/vo/TradeConfigBaseVO.java
@@ -44,6 +44,10 @@ public class TradeConfigBaseVO { @@ -44,6 +44,10 @@ public class TradeConfigBaseVO {
44 @PositiveOrZero(message = "全场包邮的最小金额不能是负数") 44 @PositiveOrZero(message = "全场包邮的最小金额不能是负数")
45 private Integer deliveryExpressFreePrice; 45 private Integer deliveryExpressFreePrice;
46 46
  47 + @Schema(description = "是否开启自提", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
  48 + @NotNull(message = "是否开启自提不能为空")
  49 + private Boolean deliveryPickUpEnabled;
  50 +
47 // ========== 分销相关 ========== 51 // ========== 分销相关 ==========
48 52
49 @Schema(description = "是否启用分佣", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") 53 @Schema(description = "是否启用分佣", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/vo/TradeConfigRespVO.java
@@ -14,4 +14,7 @@ public class TradeConfigRespVO extends TradeConfigBaseVO { @@ -14,4 +14,7 @@ public class TradeConfigRespVO extends TradeConfigBaseVO {
14 @Schema(description = "自增主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") 14 @Schema(description = "自增主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
15 private Long id; 15 private Long id;
16 16
  17 + @Schema(description = "腾讯地图 KEY", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
  18 + private String tencentLbsKey;
  19 +
17 } 20 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/config/AppTradeConfigController.java
@@ -10,6 +10,7 @@ import io.swagger.v3.oas.annotations.Operation; @@ -10,6 +10,7 @@ import io.swagger.v3.oas.annotations.Operation;
10 import io.swagger.v3.oas.annotations.tags.Tag; 10 import io.swagger.v3.oas.annotations.tags.Tag;
11 import lombok.RequiredArgsConstructor; 11 import lombok.RequiredArgsConstructor;
12 import lombok.extern.slf4j.Slf4j; 12 import lombok.extern.slf4j.Slf4j;
  13 +import org.springframework.beans.factory.annotation.Value;
13 import org.springframework.validation.annotation.Validated; 14 import org.springframework.validation.annotation.Validated;
14 import org.springframework.web.bind.annotation.GetMapping; 15 import org.springframework.web.bind.annotation.GetMapping;
15 import org.springframework.web.bind.annotation.RequestMapping; 16 import org.springframework.web.bind.annotation.RequestMapping;
@@ -30,11 +31,14 @@ public class AppTradeConfigController { @@ -30,11 +31,14 @@ public class AppTradeConfigController {
30 @Resource 31 @Resource
31 private TradeConfigService tradeConfigService; 32 private TradeConfigService tradeConfigService;
32 33
  34 + @Value("${yudao.tencent-lbs-key}")
  35 + private String tencentLbsKey;
  36 +
33 @GetMapping("/get") 37 @GetMapping("/get")
34 @Operation(summary = "获得交易配置") 38 @Operation(summary = "获得交易配置")
35 public CommonResult<AppTradeConfigRespVO> getTradeConfig() { 39 public CommonResult<AppTradeConfigRespVO> getTradeConfig() {
36 - TradeConfigDO tradeConfig = ObjUtil.defaultIfNull(tradeConfigService.getTradeConfig(), new TradeConfigDO());  
37 - return success(TradeConfigConvert.INSTANCE.convert02(tradeConfig)); 40 + TradeConfigDO config = ObjUtil.defaultIfNull(tradeConfigService.getTradeConfig(), new TradeConfigDO());
  41 + return success(TradeConfigConvert.INSTANCE.convert02(config).setTencentLbsKey(tencentLbsKey));
38 } 42 }
39 43
40 } 44 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/config/vo/AppTradeConfigRespVO.java
@@ -3,12 +3,22 @@ package cn.iocoder.yudao.module.trade.controller.app.config.vo; @@ -3,12 +3,22 @@ package cn.iocoder.yudao.module.trade.controller.app.config.vo;
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.Data; 4 import lombok.Data;
5 5
  6 +import javax.validation.constraints.NotNull;
6 import java.util.List; 7 import java.util.List;
7 8
8 @Schema(description = "用户 App - 交易配置 Response VO") 9 @Schema(description = "用户 App - 交易配置 Response VO")
9 @Data 10 @Data
10 public class AppTradeConfigRespVO { 11 public class AppTradeConfigRespVO {
11 12
  13 + @Schema(description = "腾讯地图 KEY", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
  14 + private String tencentLbsKey;
  15 +
  16 + // ========== 配送相关 ==========
  17 +
  18 + @Schema(description = "是否开启自提", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
  19 + @NotNull(message = "是否开启自提不能为空")
  20 + private Boolean deliveryPickUpEnabled;
  21 +
12 // ========== 售后相关 ========== 22 // ========== 售后相关 ==========
13 23
14 @Schema(description = "售后的退款理由", requiredMode = Schema.RequiredMode.REQUIRED) 24 @Schema(description = "售后的退款理由", requiredMode = Schema.RequiredMode.REQUIRED)
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/delivery/AppDeliverPickUpStoreController.java
1 package cn.iocoder.yudao.module.trade.controller.app.delivery; 1 package cn.iocoder.yudao.module.trade.controller.app.delivery;
2 2
3 -import cn.hutool.core.util.RandomUtil; 3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
4 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5 import cn.iocoder.yudao.module.trade.controller.app.delivery.vo.pickup.AppDeliveryPickUpStoreRespVO; 5 import cn.iocoder.yudao.module.trade.controller.app.delivery.vo.pickup.AppDeliveryPickUpStoreRespVO;
  6 +import cn.iocoder.yudao.module.trade.convert.delivery.DeliveryPickUpStoreConvert;
  7 +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO;
  8 +import cn.iocoder.yudao.module.trade.service.delivery.DeliveryPickUpStoreService;
6 import io.swagger.v3.oas.annotations.Operation; 9 import io.swagger.v3.oas.annotations.Operation;
7 import io.swagger.v3.oas.annotations.Parameter; 10 import io.swagger.v3.oas.annotations.Parameter;
  11 +import io.swagger.v3.oas.annotations.Parameters;
8 import io.swagger.v3.oas.annotations.tags.Tag; 12 import io.swagger.v3.oas.annotations.tags.Tag;
9 import org.springframework.validation.annotation.Validated; 13 import org.springframework.validation.annotation.Validated;
10 import org.springframework.web.bind.annotation.GetMapping; 14 import org.springframework.web.bind.annotation.GetMapping;
@@ -12,9 +16,8 @@ import org.springframework.web.bind.annotation.RequestMapping; @@ -12,9 +16,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
12 import org.springframework.web.bind.annotation.RequestParam; 16 import org.springframework.web.bind.annotation.RequestParam;
13 import org.springframework.web.bind.annotation.RestController; 17 import org.springframework.web.bind.annotation.RestController;
14 18
15 -import java.util.ArrayList; 19 +import javax.annotation.Resource;
16 import java.util.List; 20 import java.util.List;
17 -import java.util.Random;  
18 21
19 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 22 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
20 23
@@ -24,51 +27,29 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -24,51 +27,29 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
24 @Validated 27 @Validated
25 public class AppDeliverPickUpStoreController { 28 public class AppDeliverPickUpStoreController {
26 29
27 - // TODO 待实现[门店自提]:如果 latitude、longitude 非空,计算经纬度,并排序。计算的库,可以使用 hutool 的 DistanceUtil 计算。 30 + @Resource
  31 + private DeliveryPickUpStoreService deliveryPickUpStoreService;
  32 +
28 @GetMapping("/list") 33 @GetMapping("/list")
29 @Operation(summary = "获得自提门店列表") 34 @Operation(summary = "获得自提门店列表")
  35 + @Parameters({
  36 + @Parameter(name = "latitude", description = "精度", example = "110"),
  37 + @Parameter(name = "longitude", description = "纬度", example = "120")
  38 + })
30 public CommonResult<List<AppDeliveryPickUpStoreRespVO>> getDeliveryPickUpStoreList( 39 public CommonResult<List<AppDeliveryPickUpStoreRespVO>> getDeliveryPickUpStoreList(
31 @RequestParam(value = "latitude", required = false) Double latitude, 40 @RequestParam(value = "latitude", required = false) Double latitude,
32 @RequestParam(value = "longitude", required = false) Double longitude) { 41 @RequestParam(value = "longitude", required = false) Double longitude) {
33 - List<AppDeliveryPickUpStoreRespVO> list = new ArrayList<>();  
34 - Random random = new Random();  
35 - for (int i = 0; i < 10; i++) {  
36 - AppDeliveryPickUpStoreRespVO store = new AppDeliveryPickUpStoreRespVO();  
37 - store.setId(random.nextLong());  
38 - store.setName(RandomUtil.randomString(10));  
39 - store.setLogo("https://www.iocoder.cn/" + (i + 1) + ".png");  
40 - store.setPhone("15601691300");  
41 - store.setAreaId(random.nextInt(100000));  
42 - store.setAreaName("上海-" + RandomUtil.randomString(10));  
43 - store.setDetailAddress("普陀区-" + RandomUtil.randomString(10));  
44 - store.setLatitude(random.nextDouble() * 10);  
45 - store.setLongitude(random.nextDouble() * 10);  
46 - store.setDistance(random.nextInt(1000));  
47 -  
48 - list.add(store);  
49 - }  
50 -  
51 - return success(list); 42 + List<DeliveryPickUpStoreDO> list = deliveryPickUpStoreService.getDeliveryPickUpStoreListByStatus(
  43 + CommonStatusEnum.ENABLE.getStatus());
  44 + return success(DeliveryPickUpStoreConvert.INSTANCE.convertList(list, latitude, longitude));
52 } 45 }
53 46
54 - // TODO 待实现[门店自提]:  
55 @GetMapping("/get") 47 @GetMapping("/get")
56 @Operation(summary = "获得自提门店") 48 @Operation(summary = "获得自提门店")
57 @Parameter(name = "id", description = "门店编号") 49 @Parameter(name = "id", description = "门店编号")
58 public CommonResult<AppDeliveryPickUpStoreRespVO> getOrder(@RequestParam("id") Long id) { 50 public CommonResult<AppDeliveryPickUpStoreRespVO> getOrder(@RequestParam("id") Long id) {
59 - AppDeliveryPickUpStoreRespVO store = new AppDeliveryPickUpStoreRespVO();  
60 - Random random = new Random();  
61 - store.setId(random.nextLong());  
62 - store.setName(RandomUtil.randomString(10));  
63 - store.setLogo("https://www.iocoder.cn/" + (1) + ".png");  
64 - store.setPhone("15601691300");  
65 - store.setAreaId(random.nextInt(100000));  
66 - store.setAreaName("上海-" + RandomUtil.randomString(10));  
67 - store.setDetailAddress("普陀区-" + RandomUtil.randomString(10));  
68 - store.setLatitude(random.nextDouble() * 10);  
69 - store.setLongitude(random.nextDouble() * 10);  
70 - store.setDistance(random.nextInt(1000));  
71 - return success(store); 51 + DeliveryPickUpStoreDO store = deliveryPickUpStoreService.getDeliveryPickUpStore(id);
  52 + return success(DeliveryPickUpStoreConvert.INSTANCE.convert03(store));
72 } 53 }
73 54
74 } 55 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/delivery/vo/pickup/AppDeliveryPickUpStoreRespVO.java
@@ -34,7 +34,7 @@ public class AppDeliveryPickUpStoreRespVO { @@ -34,7 +34,7 @@ public class AppDeliveryPickUpStoreRespVO {
34 @Schema(description = "经度", requiredMode = Schema.RequiredMode.REQUIRED, example = "6.99") 34 @Schema(description = "经度", requiredMode = Schema.RequiredMode.REQUIRED, example = "6.99")
35 private Double longitude; 35 private Double longitude;
36 36
37 - @Schema(description = "距离,单位:米", example = "100") // 只有在用户传递了经纬度时,才进行计算  
38 - private Integer distance; 37 + @Schema(description = "距离,单位:千米", example = "100") // 只有在用户传递了经纬度时,才进行计算
  38 + private Double distance;
39 39
40 } 40 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryPickUpStoreConvert.java
1 package cn.iocoder.yudao.module.trade.convert.delivery; 1 package cn.iocoder.yudao.module.trade.convert.delivery;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  5 +import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
4 import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; 6 import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
5 import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreCreateReqVO; 7 import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreCreateReqVO;
6 import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreRespVO; 8 import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreRespVO;
7 import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreSimpleRespVO; 9 import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreSimpleRespVO;
8 import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreUpdateReqVO; 10 import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreUpdateReqVO;
  11 +import cn.iocoder.yudao.module.trade.controller.app.delivery.vo.pickup.AppDeliveryPickUpStoreRespVO;
9 import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO; 12 import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO;
10 import org.mapstruct.Mapper; 13 import org.mapstruct.Mapper;
11 import org.mapstruct.Mapping; 14 import org.mapstruct.Mapping;
@@ -38,4 +41,18 @@ public interface DeliveryPickUpStoreConvert { @@ -38,4 +41,18 @@ public interface DeliveryPickUpStoreConvert {
38 return AreaUtils.format(areaId); 41 return AreaUtils.format(areaId);
39 } 42 }
40 43
  44 + default List<AppDeliveryPickUpStoreRespVO> convertList(List<DeliveryPickUpStoreDO> list,
  45 + Double latitude, Double longitude) {
  46 + List<AppDeliveryPickUpStoreRespVO> voList = CollectionUtils.convertList(list, store -> {
  47 + AppDeliveryPickUpStoreRespVO storeVO = convert03(store);
  48 + if (latitude != null && longitude != null) {
  49 + storeVO.setDistance(NumberUtils.getDistance(latitude, longitude, storeVO.getLatitude(), storeVO.getLongitude()));
  50 + }
  51 + return storeVO;
  52 + });
  53 + return voList;
  54 + }
  55 + @Mapping(source = "areaId", target = "areaName", qualifiedByName = "convertAreaIdToAreaName")
  56 + AppDeliveryPickUpStoreRespVO convert03(DeliveryPickUpStoreDO bean);
  57 +
41 } 58 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/config/TradeConfigDO.java
@@ -59,6 +59,11 @@ public class TradeConfigDO extends BaseDO { @@ -59,6 +59,11 @@ public class TradeConfigDO extends BaseDO {
59 */ 59 */
60 private Integer deliveryExpressFreePrice; 60 private Integer deliveryExpressFreePrice;
61 61
  62 + /**
  63 + * 是否开启自提
  64 + */
  65 + private Boolean deliveryPickUpEnabled;
  66 +
62 // ========== 分销相关 ========== 67 // ========== 分销相关 ==========
63 68
64 /** 69 /**
yudao-server/src/main/resources/application-dev.yaml
@@ -170,6 +170,7 @@ yudao: @@ -170,6 +170,7 @@ yudao:
170 order-notify-url: http://yunai.natapp1.cc/admin-api/pay/notify/order # 支付渠道的【支付】回调地址 170 order-notify-url: http://yunai.natapp1.cc/admin-api/pay/notify/order # 支付渠道的【支付】回调地址
171 refund-notify-url: http://yunai.natapp1.cc/admin-api/pay/notify/refund # 支付渠道的【退款】回调地址 171 refund-notify-url: http://yunai.natapp1.cc/admin-api/pay/notify/refund # 支付渠道的【退款】回调地址
172 demo: true # 开启演示模式 172 demo: true # 开启演示模式
  173 + tencent-lbs-key: TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E # QQ 地图的密钥 https://lbs.qq.com/service/staticV2/staticGuide/staticDoc
173 174
174 justauth: 175 justauth:
175 enabled: true 176 enabled: true
yudao-server/src/main/resources/application-local.yaml
@@ -213,6 +213,7 @@ yudao: @@ -213,6 +213,7 @@ yudao:
213 error-code: # 错误码相关配置项 213 error-code: # 错误码相关配置项
214 enable: false 214 enable: false
215 demo: false # 关闭演示模式 215 demo: false # 关闭演示模式
  216 + tencent-lbs-key: TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E # QQ 地图的密钥 https://lbs.qq.com/service/staticV2/staticGuide/staticDoc
216 clean-job: 217 clean-job:
217 access-retain-day: 7 218 access-retain-day: 7
218 error-retain-day: 8 219 error-retain-day: 8