Selaa lähdekoodia

1、增加品牌模块
2、优化旧平台数据同步
3、增加社交绑定及相关第三方登录接口

rayson 9 kuukautta sitten
vanhempi
commit
9ae934b558
26 muutettua tiedostoa jossa 944 lisäystä ja 204 poistoa
  1. 1 1
      citu-module-system/citu-module-system-biz/src/main/java/com/citu/module/system/service/social/SocialClientServiceImpl.java
  2. 6 0
      citu-module-system/citu-module-system-biz/src/main/resources/application.yaml
  3. 3 0
      menduner/menduner-system-api/src/main/java/com/citu/module/menduner/system/enums/ErrorCodeConstants.java
  4. 94 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/brand/BrandController.java
  5. 98 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/social/AppSocialUserController.java
  6. 28 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/social/vo/AppSocialUserBindReqVO.java
  7. 19 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/social/vo/AppSocialUserRespVO.java
  8. 24 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/social/vo/AppSocialUserUnbindReqVO.java
  9. 39 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/social/vo/AppSocialWxaQrcodeReqVO.java
  10. 27 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/social/vo/AppSocialWxaSubscribeTemplateRespVO.java
  11. 1 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/recruit/job/AppRecruitJobAdvertisedController.java
  12. 43 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/base/brand/BrandPageReqVO.java
  13. 56 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/base/brand/BrandRespVO.java
  14. 43 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/base/brand/BrandSaveReqVO.java
  15. 23 11
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/dataobject/brand/BrandDO.java
  16. 0 47
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/dataobject/hotel/HotelBrandDO.java
  17. 1 1
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/dataobject/hotel/HotelCompanyDO.java
  18. 29 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/brand/BrandMapper.java
  19. 0 15
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/hotel/HotelBrandMapper.java
  20. 0 14
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/hotel/HotelSubBrandMapper.java
  21. 124 113
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/old/MdeOldSyncService.java
  22. 56 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/brand/BrandService.java
  23. 72 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/brand/BrandServiceImpl.java
  24. 3 1
      menduner/menduner-system-biz/src/main/resources/i18n/messages_en_US.properties
  25. 3 1
      menduner/menduner-system-biz/src/main/resources/i18n/messages_zh_CN.properties
  26. 151 0
      menduner/menduner-system-biz/src/test/java/com/citu/module/menduner/system/service/brand/BrandServiceImplTest.java

+ 1 - 1
citu-module-system/citu-module-system-biz/src/main/java/com/citu/module/system/service/social/SocialClientServiceImpl.java

@@ -78,7 +78,7 @@ public class SocialClientServiceImpl implements SocialClientService {
      *
      * 1. release:正式版
      * 2. trial:体验版
-     * 3. developer:开发版
+     * 3. develop:开发版
      */
     @Value("${citu.wxa-code.env-version:release}")
     public String envVersion;

+ 6 - 0
citu-module-system/citu-module-system-biz/src/main/resources/application.yaml

@@ -192,5 +192,11 @@ citu:
     send-maximum-quantity-per-day: 10
     begin-code: 123680 # 这里配置 9999 的原因是,测试方便。
     end-code: 999999 # 这里配置 9999 的原因是,测试方便。
+  # 小程序码要打开的小程序版本
+  wxa-code:
+    env-version: develop
+  # 订阅消息跳转小程序类型
+  wxa-subscribe-message:
+    miniprogram-state: formal
 
 debug: false

+ 3 - 0
menduner/menduner-system-api/src/main/java/com/citu/module/menduner/system/enums/ErrorCodeConstants.java

@@ -484,4 +484,7 @@ public interface ErrorCodeConstants {
 
     // ========== 用户实名制 1_100_047_000 ==========
     ErrorCode USER_AUTH_NOT_EXISTS = new ErrorCode(1_100_047_001, "用户实名制不存在");
+
+    // ========== 品牌 1_100_048_000 ==========
+    ErrorCode BRAND_NOT_EXISTS = new ErrorCode(1_100_048_001, "品牌不存在");
 }

+ 94 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/brand/BrandController.java

@@ -0,0 +1,94 @@
+package com.citu.module.menduner.system.controller.admin.brand;
+
+
+import com.citu.framework.apilog.core.annotation.ApiAccessLog;
+import com.citu.framework.common.pojo.CommonResult;
+import com.citu.framework.common.pojo.PageParam;
+import com.citu.framework.common.pojo.PageResult;
+import com.citu.framework.common.util.object.BeanUtils;
+import com.citu.framework.excel.core.util.ExcelUtils;
+import com.citu.module.menduner.system.controller.base.brand.BrandPageReqVO;
+import com.citu.module.menduner.system.controller.base.brand.BrandRespVO;
+import com.citu.module.menduner.system.controller.base.brand.BrandSaveReqVO;
+import com.citu.module.menduner.system.dal.dataobject.brand.BrandDO;
+import com.citu.module.menduner.system.service.brand.BrandService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import java.io.IOException;
+import java.util.List;
+
+import static com.citu.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
+import static com.citu.framework.common.pojo.CommonResult.success;
+
+@Tag(name = "管理后台 - 品牌")
+@RestController
+@RequestMapping("/menduner/system/brand")
+@Validated
+public class BrandController {
+
+    @Resource
+    private BrandService brandService;
+
+    @PostMapping("/create")
+    @Operation(summary = "创建品牌")
+    @PreAuthorize("@ss.hasPermission('menduner:system:brand:create')")
+    public CommonResult<Long> createBrand(@Valid @RequestBody BrandSaveReqVO createReqVO) {
+        return success(brandService.createBrand(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新品牌")
+    @PreAuthorize("@ss.hasPermission('menduner:system:brand:update')")
+    public CommonResult<Boolean> updateBrand(@Valid @RequestBody BrandSaveReqVO updateReqVO) {
+        brandService.updateBrand(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除品牌")
+    @Parameter(name = "id", description = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('menduner:system:brand:delete')")
+    public CommonResult<Boolean> deleteBrand(@RequestParam("id") Long id) {
+        brandService.deleteBrand(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得品牌")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('menduner:system:brand:query')")
+    public CommonResult<BrandRespVO> getBrand(@RequestParam("id") Long id) {
+        BrandDO brand = brandService.getBrand(id);
+        return success(BeanUtils.toBean(brand, BrandRespVO.class));
+    }
+
+    @GetMapping("/page")
+    @Operation(summary = "获得品牌分页")
+    @PreAuthorize("@ss.hasPermission('menduner:system:brand:query')")
+    public CommonResult<PageResult<BrandRespVO>> getBrandPage(@Valid BrandPageReqVO pageReqVO) {
+        PageResult<BrandDO> pageResult = brandService.getBrandPage(pageReqVO);
+        return success(BeanUtils.toBean(pageResult, BrandRespVO.class));
+    }
+
+    @GetMapping("/export-excel")
+    @Operation(summary = "导出品牌 Excel")
+    @PreAuthorize("@ss.hasPermission('menduner:system:brand:export')")
+    @ApiAccessLog(operateType = EXPORT)
+    public void exportBrandExcel(@Valid BrandPageReqVO pageReqVO,
+                                 HttpServletResponse response) throws IOException {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        List<BrandDO> list = brandService.getBrandPage(pageReqVO).getList();
+        // 导出 Excel
+        ExcelUtils.write(response, "品牌.xls", "数据", BrandRespVO.class,
+                BeanUtils.toBean(list, BrandRespVO.class));
+    }
+
+}

+ 98 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/social/AppSocialUserController.java

@@ -0,0 +1,98 @@
+package com.citu.module.menduner.system.controller.app.jobhunt.social;
+
+import cn.hutool.core.codec.Base64;
+import com.citu.framework.common.enums.UserTypeEnum;
+import com.citu.framework.common.pojo.CommonResult;
+import com.citu.framework.common.util.object.BeanUtils;
+import com.citu.framework.security.core.annotations.PreAuthenticated;
+import com.citu.module.menduner.common.util.LoginUserContext;
+import com.citu.module.menduner.system.controller.app.jobhunt.social.vo.AppSocialUserBindReqVO;
+import com.citu.module.menduner.system.controller.app.jobhunt.social.vo.AppSocialUserRespVO;
+import com.citu.module.menduner.system.controller.app.jobhunt.social.vo.AppSocialUserUnbindReqVO;
+import com.citu.module.menduner.system.controller.app.jobhunt.social.vo.AppSocialWxaSubscribeTemplateRespVO;
+import com.citu.module.system.api.social.SocialClientApi;
+import com.citu.module.system.api.social.SocialUserApi;
+import com.citu.module.system.api.social.dto.*;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import java.util.List;
+
+import static com.citu.framework.common.pojo.CommonResult.success;
+
+@Tag(name = "求职端 - 社交用户")
+@RestController
+@RequestMapping("/menduner/system/social-user")
+@Validated
+@Slf4j
+public class AppSocialUserController {
+
+    @Resource
+    private SocialUserApi socialUserApi;
+    @Resource
+    private SocialClientApi socialClientApi;
+
+    @PostMapping("/bind")
+    @Operation(summary = "社交绑定,使用 code 授权码")
+    public CommonResult<String> socialBind(@RequestBody @Valid AppSocialUserBindReqVO reqVO) {
+        SocialUserBindReqDTO reqDTO = new SocialUserBindReqDTO(
+                LoginUserContext.getUserId(),
+                UserTypeEnum.MEMBER.getValue(),
+                reqVO.getType(),
+                reqVO.getCode(),
+                reqVO.getState()
+        );
+        String openid = socialUserApi.bindSocialUser(reqDTO).getCheckedData();
+        return success(openid);
+    }
+
+    @DeleteMapping("/unbind")
+    @Operation(summary = "取消社交绑定")
+    @PreAuthenticated
+    public CommonResult<Boolean> socialUnbind(@RequestBody AppSocialUserUnbindReqVO reqVO) {
+        SocialUserUnbindReqDTO reqDTO = new SocialUserUnbindReqDTO(
+                LoginUserContext.getUserId(),
+                UserTypeEnum.MEMBER.getValue(),
+                reqVO.getType(),
+                reqVO.getOpenid()
+        );
+        socialUserApi.unbindSocialUser(reqDTO).getCheckedData();
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得社交用户")
+    @Parameter(name = "type", description = "社交平台的类型,参见 SocialTypeEnum 枚举值", required = true, example = "10")
+    @PreAuthenticated
+    public CommonResult<AppSocialUserRespVO> getSocialUser(@RequestParam("type") Integer type) {
+        SocialUserRespDTO socialUser = socialUserApi.getSocialUserByUserId(
+                UserTypeEnum.MEMBER.getValue(),
+                LoginUserContext.getUserId(),
+                type
+        ).getCheckedData();
+        return success(BeanUtils.toBean(socialUser, AppSocialUserRespVO.class));
+    }
+
+    @PostMapping("/wxa-qrcode")
+    @Operation(summary = "获得微信小程序码(base64 image)")
+    public CommonResult<String> getWxaQrcode(@RequestBody @Valid SocialWxQrcodeReqDTO reqVO) {
+        byte[] wxQrcode = socialClientApi.getWxaQrcode(reqVO).getCheckedData();
+        return success(Base64.encode(wxQrcode));
+    }
+
+    @GetMapping("/get-subscribe-template-list")
+    @Operation(summary = "获得微信小程订阅模板列表")
+    public CommonResult<List<AppSocialWxaSubscribeTemplateRespVO>> getSubscribeTemplateList() {
+        List<SocialWxaSubscribeTemplateRespDTO> template = socialClientApi.getWxaSubscribeTemplateList(
+                UserTypeEnum.MEMBER.getValue()
+        ).getCheckedData();
+        return success(BeanUtils.toBean(template, AppSocialWxaSubscribeTemplateRespVO.class));
+    }
+
+}

+ 28 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/social/vo/AppSocialUserBindReqVO.java

@@ -0,0 +1,28 @@
+package com.citu.module.menduner.system.controller.app.jobhunt.social.vo;
+
+import com.citu.framework.common.validation.InEnum;
+import com.citu.module.system.enums.social.SocialTypeEnum;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+@Schema(description = "用户 APP - 社交绑定 Request VO,使用 code 授权码")
+@Data
+public class AppSocialUserBindReqVO {
+
+    @Schema(description = "社交平台的类型,参见 SocialTypeEnum 枚举值", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
+    @InEnum(SocialTypeEnum.class)
+    @NotNull(message = "社交平台的类型不能为空")
+    private Integer type;
+
+    @Schema(description = "授权码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    @NotEmpty(message = "授权码不能为空")
+    private String code;
+
+    @Schema(description = "state", requiredMode = Schema.RequiredMode.REQUIRED, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62")
+    @NotEmpty(message = "state 不能为空")
+    private String state;
+
+}

+ 19 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/social/vo/AppSocialUserRespVO.java

@@ -0,0 +1,19 @@
+package com.citu.module.menduner.system.controller.app.jobhunt.social.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "用户 APP - 社交用户 Response VO")
+@Data
+public class AppSocialUserRespVO {
+
+    @Schema(description = "社交用户的 openid", requiredMode = Schema.RequiredMode.REQUIRED, example = "IPRmJ0wvBptiPIlGEZiPewGwiEiE")
+    private String openid;
+
+    @Schema(description = "社交用户的昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "Rayson")
+    private String nickname;
+
+    @Schema(description = "社交用户的头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.png")
+    private String avatar;
+
+}

+ 24 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/social/vo/AppSocialUserUnbindReqVO.java

@@ -0,0 +1,24 @@
+package com.citu.module.menduner.system.controller.app.jobhunt.social.vo;
+
+import com.citu.framework.common.validation.InEnum;
+import com.citu.module.system.enums.social.SocialTypeEnum;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+@Schema(description = "用户 APP - 取消社交绑定 Request VO")
+@Data
+public class AppSocialUserUnbindReqVO {
+
+    @Schema(description = "社交平台的类型,参见 SocialTypeEnum 枚举值", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
+    @InEnum(SocialTypeEnum.class)
+    @NotNull(message = "社交平台的类型不能为空")
+    private Integer type;
+
+    @Schema(description = "社交用户的 openid", requiredMode = Schema.RequiredMode.REQUIRED, example = "IPRmJ0wvBptiPIlGEZiPewGwiEiE")
+    @NotEmpty(message = "社交用户的 openid 不能为空")
+    private String openid;
+
+}

+ 39 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/social/vo/AppSocialWxaQrcodeReqVO.java

@@ -0,0 +1,39 @@
+package com.citu.module.menduner.system.controller.app.jobhunt.social.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+
+
+@Schema(description = "用户 APP - 获得获取小程序码 Request VO")
+@Data
+public class AppSocialWxaQrcodeReqVO {
+
+    /**
+     * 页面路径不能携带参数(参数请放在scene字段里)
+     */
+    @Schema(description = "场景值", requiredMode = Schema.RequiredMode.REQUIRED, example = "1001")
+    private String scene;
+
+    /**
+     * 默认是主页,页面 page,例如 pages/index/index,根路径前不要填加 /,不能携带参数(参数请放在scene字段里),
+     * 如果不填写这个字段,默认跳主页面。scancode_time为系统保留参数,不允许配置
+     */
+    @Schema(description = "页面路径", requiredMode = Schema.RequiredMode.REQUIRED, example = "pages/goods/index")
+    @NotEmpty(message = "页面路径不能为空")
+    private String path;
+
+    @Schema(description = "二维码宽度", requiredMode = Schema.RequiredMode.REQUIRED, example = "430")
+    private Integer width;
+
+    @Schema(description = "是/否自动配置线条颜色", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    private Boolean autoColor;
+
+    @Schema(description = "是/否检查 page 是否存在", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    private Boolean checkPath;
+
+    @Schema(description = "是/否需要透明底色", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    private Boolean hyaline;
+
+}

+ 27 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/social/vo/AppSocialWxaSubscribeTemplateRespVO.java

@@ -0,0 +1,27 @@
+package com.citu.module.menduner.system.controller.app.jobhunt.social.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "用户 APP - 获得小程序订阅模版 Response VO")
+@Data
+public class AppSocialWxaSubscribeTemplateRespVO {
+
+    @Schema(description = "模版编号", requiredMode = Schema.RequiredMode.REQUIRED,
+            example = "9Aw5ZV1j9xdWTFEkqCpZ7mIBbSC34khK55OtzUPl0rU")
+    private String id;
+
+    @Schema(description = "模版标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "订单支付通知")
+    private String title;
+
+    @Schema(description = "模版内容", requiredMode = Schema.RequiredMode.REQUIRED,
+            example = "{ {result.DATA} }\\n\\n领奖金额:{ {withdrawMoney.DATA} }\\n领奖时间:    { {withdrawTime.DATA} }")
+    private String content;
+
+    @Schema(description = "模板内容示例", requiredMode = Schema.RequiredMode.REQUIRED, example = "下单时间:2016年8月8日")
+    private String example;
+
+    @Schema(description = "模版类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
+    private Integer type; // 2 为一次性订阅,3 为长期订阅
+
+}

+ 1 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/recruit/job/AppRecruitJobAdvertisedController.java

@@ -1,6 +1,7 @@
 package com.citu.module.menduner.system.controller.app.recruit.job;
 
 
+import cn.hutool.core.collection.CollUtil;
 import com.citu.framework.apilog.core.annotation.ApiAccessLog;
 import com.citu.framework.common.pojo.CommonResult;
 import com.citu.framework.common.pojo.PageParam;

+ 43 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/base/brand/BrandPageReqVO.java

@@ -0,0 +1,43 @@
+package com.citu.module.menduner.system.controller.base.brand;
+
+
+import com.citu.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDateTime;
+
+import static com.citu.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@Schema(description = "管理后台 - 品牌分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class BrandPageReqVO extends PageParam {
+
+    @Schema(description = "上级id", example = "2611")
+    private Long parentId;
+
+    @Schema(description = "品牌等级类型", example = "1")
+    private String type;
+
+    @Schema(description = "品牌名称(中文)")
+    private String nameCn;
+
+    @Schema(description = "品牌名称(英文)")
+    private String nameEn;
+
+    @Schema(description = "国际区分[1-国际;2-国内]")
+    private String international;
+
+    @Schema(description = "层级")
+    private Boolean level;
+
+    @Schema(description = "创建时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] createTime;
+
+}

+ 56 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/base/brand/BrandRespVO.java

@@ -0,0 +1,56 @@
+package com.citu.module.menduner.system.controller.base.brand;
+
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 品牌 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class BrandRespVO {
+
+    @Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "24719")
+    @ExcelProperty("id")
+    private Long id;
+
+    @Schema(description = "上级id", requiredMode = Schema.RequiredMode.REQUIRED, example = "2611")
+    @ExcelProperty("上级id")
+    private Long parentId;
+
+    @Schema(description = "品牌等级类型", example = "1")
+    @ExcelProperty("品牌等级类型")
+    private String type;
+
+    @Schema(description = "logo地址")
+    @ExcelProperty("logo地址")
+    private String logo;
+
+    @Schema(description = "品牌名称(中文)", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("品牌名称(中文)")
+    private String nameCn;
+
+    @Schema(description = "品牌名称(英文)")
+    @ExcelProperty("品牌名称(英文)")
+    private String nameEn;
+
+    @Schema(description = "国际区分[1-国际;2-国内]")
+    @ExcelProperty("国际区分[1-国际;2-国内]")
+    private String international;
+
+    @Schema(description = "层级")
+    @ExcelProperty("层级")
+    private Boolean level;
+
+    @Schema(description = "排序")
+    @ExcelProperty("排序")
+    private Integer sort;
+
+    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("创建时间")
+    private LocalDateTime createTime;
+
+}

+ 43 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/base/brand/BrandSaveReqVO.java

@@ -0,0 +1,43 @@
+package com.citu.module.menduner.system.controller.base.brand;
+
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+@Schema(description = "管理后台 - 品牌新增/修改 Request VO")
+@Data
+public class BrandSaveReqVO {
+
+    @Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "24719")
+    private Long id;
+
+    @Schema(description = "上级id", requiredMode = Schema.RequiredMode.REQUIRED, example = "2611")
+    @NotNull(message = "上级id不能为空")
+    private Long parentId;
+
+    @Schema(description = "品牌等级类型", example = "1")
+    private String type;
+
+    @Schema(description = "logo地址")
+    private String logo;
+
+    @Schema(description = "品牌名称(中文)", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotEmpty(message = "品牌名称(中文)不能为空")
+    private String nameCn;
+
+    @Schema(description = "品牌名称(英文)")
+    private String nameEn;
+
+    @Schema(description = "国际区分[1-国际;2-国内]")
+    private String international;
+
+    @Schema(description = "层级")
+    private Boolean level;
+
+    @Schema(description = "排序")
+    private Integer sort;
+
+}

+ 23 - 11
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/dataobject/hotel/HotelSubBrandDO.java → menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/dataobject/brand/BrandDO.java

@@ -1,4 +1,4 @@
-package com.citu.module.menduner.system.dal.dataobject.hotel;
+package com.citu.module.menduner.system.dal.dataobject.brand;
 
 
 import com.baomidou.mybatisplus.annotation.KeySequence;
@@ -8,19 +8,19 @@ import com.citu.framework.tenant.core.db.TenantBaseDO;
 import lombok.*;
 
 /**
- * 酒店子品牌 DO
+ * 品牌 DO
  *
  * @author Rayson
  */
-@TableName("mde_hotel_sub_brand")
-@KeySequence("mde_hotel_sub_brand_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@TableName("mde_brand")
+@KeySequence("mde_brand_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
 @Data
 @EqualsAndHashCode(callSuper = true)
 @ToString(callSuper = true)
 @Builder
 @NoArgsConstructor
 @AllArgsConstructor
-public class HotelSubBrandDO extends TenantBaseDO {
+public class BrandDO extends TenantBaseDO {
 
     /**
      * id
@@ -28,9 +28,17 @@ public class HotelSubBrandDO extends TenantBaseDO {
     @TableId
     private Long id;
     /**
-     * 主品牌id
+     * 上级id
      */
-    private Long brandId;
+    private Long parentId;
+    /**
+     * 等级类型
+     */
+    private String type;
+    /**
+     * logo图片地址
+     */
+    private String logo;
     /**
      * 品牌名称(中文)
      */
@@ -39,17 +47,21 @@ public class HotelSubBrandDO extends TenantBaseDO {
      * 品牌名称(英文)
      */
     private String nameEn;
-    /**
-     * 酒店级别
-     */
-    private String level;
     /**
      * 国际区分[1-国际;2-国内]
      */
     private String international;
+    /**
+     * 层级
+     */
+    private Integer level;
     /**
      * 排序
      */
     private Integer sort;
+    /**
+     * 外部id
+     */
+    private Long foreignId;
 
 }

+ 0 - 47
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/dataobject/hotel/HotelBrandDO.java

@@ -1,47 +0,0 @@
-package com.citu.module.menduner.system.dal.dataobject.hotel;
-
-
-import com.baomidou.mybatisplus.annotation.KeySequence;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.citu.framework.tenant.core.db.TenantBaseDO;
-import lombok.*;
-
-/**
- * 酒店主品牌 DO
- *
- * @author Rayson
- */
-@TableName("mde_hotel_brand")
-@KeySequence("mde_hotel_brand_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-@Builder
-@NoArgsConstructor
-@AllArgsConstructor
-public class HotelBrandDO extends TenantBaseDO {
-
-    /**
-     * id
-     */
-    @TableId
-    private Long id;
-    /**
-     * 品牌名称(中文)
-     */
-    private String nameCn;
-    /**
-     * 品牌名称(英文)
-     */
-    private String nameEn;
-    /**
-     * 国际区分[1-国际;2-国内]
-     */
-    private String international;
-    /**
-     * 排序
-     */
-    private Integer sort;
-
-}

+ 1 - 1
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/dataobject/hotel/HotelCompanyDO.java

@@ -30,7 +30,7 @@ public class HotelCompanyDO extends TenantBaseDO {
     /**
      * 酒店子品牌id
      */
-    private Long subBrandId;
+    private Long brandId;
     /**
      * 品牌名称(中文)
      */

+ 29 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/brand/BrandMapper.java

@@ -0,0 +1,29 @@
+package com.citu.module.menduner.system.dal.mysql.brand;
+
+import com.citu.framework.common.pojo.PageResult;
+import com.citu.framework.mybatis.core.mapper.BaseMapperX;
+import com.citu.framework.mybatis.core.query.LambdaQueryWrapperX;
+import com.citu.module.menduner.system.controller.base.brand.BrandPageReqVO;
+import com.citu.module.menduner.system.dal.dataobject.brand.BrandDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 品牌 Mapper
+ *
+ * @author Rayson
+ */
+@Mapper
+public interface BrandMapper extends BaseMapperX<BrandDO> {
+
+    default PageResult<BrandDO> selectPage(BrandPageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<BrandDO>()
+                .eqIfPresent(BrandDO::getParentId, reqVO.getParentId())
+                .eqIfPresent(BrandDO::getType, reqVO.getType())
+                .likeIfPresent(BrandDO::getNameCn, reqVO.getNameCn())
+                .likeIfPresent(BrandDO::getNameEn, reqVO.getNameEn())
+                .eqIfPresent(BrandDO::getInternational, reqVO.getInternational())
+                .eqIfPresent(BrandDO::getLevel, reqVO.getLevel())
+                .betweenIfPresent(BrandDO::getCreateTime, reqVO.getCreateTime())
+                .orderByDesc(BrandDO::getId));
+    }
+}

+ 0 - 15
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/hotel/HotelBrandMapper.java

@@ -1,15 +0,0 @@
-package com.citu.module.menduner.system.dal.mysql.hotel;
-
-
-import com.citu.framework.mybatis.core.mapper.BaseMapperX;
-import com.citu.module.menduner.system.dal.dataobject.hotel.HotelBrandDO;
-import org.apache.ibatis.annotations.Mapper;
-
-/**
- * 酒店主品牌 Mapper
- *
- * @author Rayson
- */
-@Mapper
-public interface HotelBrandMapper extends BaseMapperX<HotelBrandDO> {
-}

+ 0 - 14
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/hotel/HotelSubBrandMapper.java

@@ -1,14 +0,0 @@
-package com.citu.module.menduner.system.dal.mysql.hotel;
-
-import com.citu.framework.mybatis.core.mapper.BaseMapperX;
-import com.citu.module.menduner.system.dal.dataobject.hotel.HotelSubBrandDO;
-import org.apache.ibatis.annotations.Mapper;
-
-/**
- * 酒店子品牌 Mapper
- *
- * @author Rayson
- */
-@Mapper
-public interface HotelSubBrandMapper extends BaseMapperX<HotelSubBrandDO> {
-}

+ 124 - 113
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/old/MdeOldSyncService.java

@@ -1,6 +1,7 @@
 package com.citu.module.menduner.system.old;
 
 import cn.hutool.core.collection.CollUtil;
+import com.citu.framework.common.util.date.DateUtils;
 import com.citu.framework.common.util.object.ObjectUtils;
 import com.citu.framework.mybatis.core.query.LambdaQueryWrapperX;
 import com.citu.framework.tenant.core.aop.TenantIgnore;
@@ -11,9 +12,8 @@ import com.citu.module.menduner.system.dal.dataobject.eduexp.EduExpDO;
 import com.citu.module.menduner.system.dal.dataobject.enterprise.EnterpriseAddressDO;
 import com.citu.module.menduner.system.dal.dataobject.enterprise.EnterpriseDO;
 import com.citu.module.menduner.system.dal.dataobject.enterprise.EnterpriseUserBindDO;
-import com.citu.module.menduner.system.dal.dataobject.hotel.HotelBrandDO;
+import com.citu.module.menduner.system.dal.dataobject.brand.BrandDO;
 import com.citu.module.menduner.system.dal.dataobject.hotel.HotelCompanyDO;
-import com.citu.module.menduner.system.dal.dataobject.hotel.HotelSubBrandDO;
 import com.citu.module.menduner.system.dal.dataobject.job.JobAdvertisedDO;
 import com.citu.module.menduner.system.dal.dataobject.job.JobCvRelDO;
 import com.citu.module.menduner.system.dal.dataobject.job.JobInterestedDO;
@@ -27,9 +27,8 @@ import com.citu.module.menduner.system.dal.mysql.eduexp.EduExpMapper;
 import com.citu.module.menduner.system.dal.mysql.enterprise.EnterpriseAddressMapper;
 import com.citu.module.menduner.system.dal.mysql.enterprise.EnterpriseMapper;
 import com.citu.module.menduner.system.dal.mysql.enterprise.EnterpriseUserBindMapper;
-import com.citu.module.menduner.system.dal.mysql.hotel.HotelBrandMapper;
+import com.citu.module.menduner.system.dal.mysql.brand.BrandMapper;
 import com.citu.module.menduner.system.dal.mysql.hotel.HotelCompanyMapper;
-import com.citu.module.menduner.system.dal.mysql.hotel.HotelSubBrandMapper;
 import com.citu.module.menduner.system.dal.mysql.job.JobAdvertisedMapper;
 import com.citu.module.menduner.system.dal.mysql.job.JobCvRelMapper;
 import com.citu.module.menduner.system.dal.mysql.job.JobInterestedMapper;
@@ -58,6 +57,8 @@ import java.time.temporal.ChronoUnit;
 import java.util.*;
 import java.util.stream.Collectors;
 
+import static com.citu.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
+
 /**
  * 门墩儿 老平台的数据同步
  **/
@@ -138,9 +139,7 @@ public class MdeOldSyncService {
     @Resource
     private OldMdeSubscribedPositionsMapper oldSubscribedPositionsMapper;
     @Resource
-    private HotelBrandMapper hotelBrandMapper;
-    @Resource
-    private HotelSubBrandMapper hotelSubBrandMapper;
+    private BrandMapper brandMapper;
     @Resource
     private HotelCompanyMapper hotelCompanyMapper;
     @Resource
@@ -358,20 +357,6 @@ public class MdeOldSyncService {
 
         List<OldMdePosition> oldMdePositionList = oldPositionMapper.selectList(OldMdePosition::getDelFlag, 0);
 
-//        Long top = 8L;
-//        PositionDO topPosition = positionMapper.selectOne(PositionDO::getNameEn, "old");
-//        if (null == topPosition) {
-//            setCommon(topPosition);
-//            positionMapper.insert(PositionDO.builder()
-//                    .id(top)
-//                    .parentId(0L)
-//                    .nameCn("old")
-//                    .nameEn("old")
-//                    .level(1)
-//                    .sort(0)
-//                    .build());
-//
-//        }
         Long leader = 9L;
         oldDepartmentList.stream().forEach(
                 oldMdeDepartment -> {
@@ -454,87 +439,87 @@ public class MdeOldSyncService {
         );
         userMap.putAll(userList.stream().collect(Collectors.toMap(OldMdeUser::getUserCode, v -> v)));
         // 新增用户 or 人才基本信息
-//        userList.stream().forEach(oldMdeUser -> {
-//
-//            MdeUserDO userDO = null;
-//            if (oldMdeUser.getIdentityFlag().equals("1")) {
-//                // 企业用户,判断预留的手机号有没有注册过用户
-//                if (StringUtils.hasText(oldMdeUser.getEntPhone())) {
-//                    // 手机号不为空
-//                    MdeUserDO enterpriseUser = mdeUserMapper.selectOne(MdeUserDO::getPhone, oldMdeUser.getEntPhone());
-//                    if (null != enterpriseUser) {
-//                        // 存在了,不再创建用户
-//                        return;
-//                    }
-//                } else {
-//                    // 企业预留的手机号为空
-//                }
-//            } else {
-//                // 求职端用户
-//                userDO = mdeUserMapper.selectOne(MdeUserDO::getId, oldMdeUser.getUserCode());
-//                if (null == userDO) {
-//                    MdeUserDO userNameUserDO = mdeUserMapper.selectOne(MdeUserDO::getUsername, oldMdeUser.getUserName());
-//                    if (null != userNameUserDO) {
-//                        // 根据账号名也匹配到数据,说明是同一个用户,直接使用账号名(手机号)匹配到的数据
-//                        userDO = userNameUserDO;
-//                    }
-//                }
-//
-//            }
-//
-//            // 账户信息
-//            MdeUserDO insertionDO = MdeUserDO.builder()
-//                    .id(null == userDO ? oldMdeUser.getUserCode() : userDO.getId())
-//                    .username(oldMdeUser.getIdentityFlag().equals("0") ? oldMdeUser.getUserName() : oldMdeUser.getEntPhone())
-//                    // 重置密码手机号后6位
-//                    .password(passwordEncoder.encode("147258369"))
-//                    .email(oldMdeUser.getEmail())
-//                    // 有座机,大坑
-//                    // 个人用户getUserName是手机号,企业用户是邮箱,所以企业用户取getEntPhone
-//                    .phone(oldMdeUser.getIdentityFlag().equals("0") ? oldMdeUser.getUserName() : oldMdeUser.getEntPhone())
-//                    .avatar(null == oldMdeUser.getHeadPortrait() ? null : url + oldMdeUser.getHeadPortrait())
-//                    .status(MendunerStatusEnum.ENABLE.getStatus())
-//                    .build();
-//
-//
-//            // 人才基本信息
-//            PersonInfoDO personInfoDO = personInfoMapper.getByUserId(oldMdeUser.getUserCode());
-//            personInfoDO = PersonInfoDO.builder()
-//                    .id(personInfoDO != null ? personInfoDO.getId() : null)
-//                    .userId(oldMdeUser.getUserCode())
-//                    .name(oldMdeUser.getName())
-//                    .foreignName(oldMdeUser.getForeignName())
-//                    .email(oldMdeUser.getEmail())
-//                    .firstWorkTime(null == oldMdeUser.getFirstWork() ? null : oldMdeUser.getFirstWork().atStartOfDay())
-//                    .jobType(JobTypeEnum.FULL_TIME.getType())
-//                    .jobStatus(oldMdeUser.getWorkStatus())
-//                    .advantage(oldMdeUser.getIntroduction())
-//                    .avatar(null == oldMdeUser.getHeadPortrait() ? null : url + oldMdeUser.getHeadPortrait())
-//                    .build();
-//
-//            if (null != oldMdeUser.getBirthday()) {
-//                // 生日转换
-//                personInfoDO.setBirthday(DateUtils.of(oldMdeUser.getBirthday(), FORMAT_YEAR_MONTH_DAY).atStartOfDay());
-//            }
-//
-//            if (oldMdeUser.getIdentityFlag().equals("0")) {
-//                // 企业基本信息 不新增人才信息,只有普通用户才新增
-//                setCommon(personInfoDO);
-//                personInfoMapper.insertOrUpdate(personInfoDO);
-//            }
-//
-//            if (oldMdeUser.getIdentityFlag().equals("0")) {
-//                // 个人
-//                insertionDO.setPhone(oldMdeUser.getUserName().contains("+") ? null : oldMdeUser.getUserName());
-//            } else {
-//                // 企业
-//                insertionDO.setPhone(oldMdeUser.getEntPhone());
-//            }
-//
-//
-//            setCommon(insertionDO);
-//            mdeUserMapper.insertOrUpdate(insertionDO);
-//        });
+        userList.stream().forEach(oldMdeUser -> {
+
+            MdeUserDO userDO = null;
+            if (oldMdeUser.getIdentityFlag().equals("1")) {
+                // 企业用户,判断预留的手机号有没有注册过用户
+                if (StringUtils.hasText(oldMdeUser.getEntPhone())) {
+                    // 手机号不为空
+                    MdeUserDO enterpriseUser = mdeUserMapper.selectOne(MdeUserDO::getPhone, oldMdeUser.getEntPhone());
+                    if (null != enterpriseUser) {
+                        // 存在了,不再创建用户
+                        return;
+                    }
+                } else {
+                    // 企业预留的手机号为空
+                }
+            } else {
+                // 求职端用户
+                userDO = mdeUserMapper.selectOne(MdeUserDO::getId, oldMdeUser.getUserCode());
+                if (null == userDO) {
+                    MdeUserDO userNameUserDO = mdeUserMapper.selectOne(MdeUserDO::getUsername, oldMdeUser.getUserName());
+                    if (null != userNameUserDO) {
+                        // 根据账号名也匹配到数据,说明是同一个用户,直接使用账号名(手机号)匹配到的数据
+                        userDO = userNameUserDO;
+                    }
+                }
+
+            }
+
+            // 账户信息
+            MdeUserDO insertionDO = MdeUserDO.builder()
+                    .id(null == userDO ? oldMdeUser.getUserCode() : userDO.getId())
+                    .username(oldMdeUser.getIdentityFlag().equals("0") ? oldMdeUser.getUserName() : oldMdeUser.getEntPhone())
+                    // 重置密码手机号后6位
+                    .password(passwordEncoder.encode("147258369"))
+                    .email(oldMdeUser.getEmail())
+                    // 有座机,大坑
+                    // 个人用户getUserName是手机号,企业用户是邮箱,所以企业用户取getEntPhone
+                    .phone(oldMdeUser.getIdentityFlag().equals("0") ? oldMdeUser.getUserName() : oldMdeUser.getEntPhone())
+                    .avatar(null == oldMdeUser.getHeadPortrait() ? null : url + oldMdeUser.getHeadPortrait())
+                    .status(MendunerStatusEnum.ENABLE.getStatus())
+                    .build();
+
+
+            // 人才基本信息
+            PersonInfoDO personInfoDO = personInfoMapper.getByUserId(oldMdeUser.getUserCode());
+            personInfoDO = PersonInfoDO.builder()
+                    .id(personInfoDO != null ? personInfoDO.getId() : null)
+                    .userId(oldMdeUser.getUserCode())
+                    .name(oldMdeUser.getName())
+                    .foreignName(oldMdeUser.getForeignName())
+                    .email(oldMdeUser.getEmail())
+                    .firstWorkTime(null == oldMdeUser.getFirstWork() ? null : oldMdeUser.getFirstWork().atStartOfDay())
+                    .jobType(JobTypeEnum.FULL_TIME.getType())
+                    .jobStatus(oldMdeUser.getWorkStatus())
+                    .advantage(oldMdeUser.getIntroduction())
+                    .avatar(null == oldMdeUser.getHeadPortrait() ? null : url + oldMdeUser.getHeadPortrait())
+                    .build();
+
+            if (null != oldMdeUser.getBirthday()) {
+                // 生日转换
+                personInfoDO.setBirthday(DateUtils.of(oldMdeUser.getBirthday(), FORMAT_YEAR_MONTH_DAY).atStartOfDay());
+            }
+
+            if (oldMdeUser.getIdentityFlag().equals("0")) {
+                // 企业基本信息 不新增人才信息,只有普通用户才新增
+                setCommon(personInfoDO);
+                personInfoMapper.insertOrUpdate(personInfoDO);
+            }
+
+            if (oldMdeUser.getIdentityFlag().equals("0")) {
+                // 个人
+                insertionDO.setPhone(oldMdeUser.getUserName().contains("+") ? null : oldMdeUser.getUserName());
+            } else {
+                // 企业
+                insertionDO.setPhone(oldMdeUser.getEntPhone());
+            }
+
+
+            setCommon(insertionDO);
+            mdeUserMapper.insertOrUpdate(insertionDO);
+        });
 
 
         // 企业用户
@@ -935,43 +920,69 @@ public class MdeOldSyncService {
 
 
     public void syncHotel() {
+        // 主品牌
         List<OldHotelBrand> brandList = oldHotelBrandMapper.selectList();
         brandList.forEach(brand -> {
-            HotelBrandDO hotelBrandDO = hotelBrandMapper.selectOne(HotelBrandDO::getId, Long.valueOf(brand.getBrandId()));
-            HotelBrandDO insertDO = HotelBrandDO.builder()
-                    .id(null == hotelBrandDO ? Long.valueOf(brand.getBrandId()) : hotelBrandDO.getId())
+            BrandDO brandDO = brandMapper.selectOne(BrandDO::getForeignId, Long.valueOf(brand.getBrandId())
+                    ,BrandDO::getLevel,0);
+            BrandDO insertDO = BrandDO.builder()
+                    .id(null == brandDO ? null : brandDO.getId())
+                    .foreignId(Long.valueOf(brand.getBrandId()))
                     .nameCn(brand.getBrandNameCn())
                     .nameEn(brand.getBrandNameEn())
+                    .parentId(0L)
+                    .level(0)
+                    .type(null)
                     .international(brand.getInternational())
                     .sort(brand.getSortId())
                     .build();
 
             setCommon(insertDO);
-            hotelBrandMapper.insertOrUpdate(insertDO);
+            brandMapper.insertOrUpdate(insertDO);
         });
+
+        // 子品牌
         List<OldHotelSubbrand> subbrandList = oldHotelSubbrandMapper.selectList();
         subbrandList.forEach(subbrand -> {
-            HotelSubBrandDO hotelSubBrandDO = hotelSubBrandMapper.selectOne(HotelSubBrandDO::getId, Long.valueOf(subbrand.getSubbrandId()));
-            HotelSubBrandDO insertDO = HotelSubBrandDO.builder()
-                    .id(null == hotelSubBrandDO ? Long.valueOf(subbrand.getSubbrandId()) : hotelSubBrandDO.getId())
-                    .brandId(Long.valueOf(subbrand.getBrandId()))
+            BrandDO brandDO = brandMapper.selectOne(BrandDO::getForeignId, Long.valueOf(subbrand.getSubbrandId())
+                    ,BrandDO::getLevel,1);
+
+            BrandDO parentDO =  brandMapper.selectOne(BrandDO::getForeignId, Long.valueOf(subbrand.getBrandId())
+                    ,BrandDO::getLevel,0);
+            if(null == parentDO) {
+                return;
+            }
+            BrandDO insertDO = BrandDO.builder()
+                    .id(null == brandDO ? null : brandDO.getId())
+                    .foreignId(Long.valueOf(subbrand.getSubbrandId()))
                     .nameCn(subbrand.getSubbrandNameCn())
                     .nameEn(subbrand.getSubbrandNameEn())
-                    .level(String.valueOf(subbrand.getHotelLevel()))
+                    .parentId(parentDO.getId())
+                    .level(1)
+                    .type(String.valueOf(subbrand.getHotelLevel()))
                     .international(subbrand.getInternational())
                     .sort(subbrand.getSortId())
                     .build();
+
             setCommon(insertDO);
-            hotelSubBrandMapper.insertOrUpdate(insertDO);
+            brandMapper.insertOrUpdate(insertDO);
         });
+
+        // 酒店公司
         List<OldHotelCompany> companyList = oldHotelCompanyMapper.selectList();
         companyList.forEach(company -> {
             HotelCompanyDO hotelCompanyDO = hotelCompanyMapper.selectOne(HotelCompanyDO::getId, Long.valueOf(company.getHotelId()));
+            BrandDO brandDO = brandMapper.selectOne(BrandDO::getForeignId, Long.valueOf(company.getSubbrandId())
+                    ,BrandDO::getLevel,1);
+            if(null == brandDO) {
+                return;
+            }
+
             HotelCompanyDO insertDO = HotelCompanyDO.builder()
                     .id(null == hotelCompanyDO ? Long.valueOf(company.getHotelId()) : hotelCompanyDO.getId())
                     .nameCn(company.getHotelNameCn())
                     .nameEn(company.getHotelNameEn())
-                    .subBrandId(Long.valueOf(company.getSubbrandId()))
+                    .brandId(brandDO.getId())
                     .addressCn(company.getHotelAddressCn())
                     .addressEn(company.getHotelAddressEn())
                     .zipCode(company.getHotelZipcode())

+ 56 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/brand/BrandService.java

@@ -0,0 +1,56 @@
+package com.citu.module.menduner.system.service.brand;
+
+
+import com.citu.framework.common.pojo.PageResult;
+import com.citu.module.menduner.system.controller.base.brand.BrandPageReqVO;
+import com.citu.module.menduner.system.controller.base.brand.BrandSaveReqVO;
+import com.citu.module.menduner.system.dal.dataobject.brand.BrandDO;
+
+import javax.validation.Valid;
+
+/**
+ * 品牌 Service 接口
+ *
+ * @author Rayson
+ */
+public interface BrandService {
+
+    /**
+     * 创建品牌
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createBrand(@Valid BrandSaveReqVO createReqVO);
+
+    /**
+     * 更新品牌
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateBrand(@Valid BrandSaveReqVO updateReqVO);
+
+    /**
+     * 删除品牌
+     *
+     * @param id 编号
+     */
+    void deleteBrand(Long id);
+
+    /**
+     * 获得品牌
+     *
+     * @param id 编号
+     * @return 品牌
+     */
+    BrandDO getBrand(Long id);
+
+    /**
+     * 获得品牌分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 品牌分页
+     */
+    PageResult<BrandDO> getBrandPage(BrandPageReqVO pageReqVO);
+
+}

+ 72 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/brand/BrandServiceImpl.java

@@ -0,0 +1,72 @@
+package com.citu.module.menduner.system.service.brand;
+
+
+import com.citu.framework.common.pojo.PageResult;
+import com.citu.framework.common.util.object.BeanUtils;
+import com.citu.module.menduner.system.controller.base.brand.BrandPageReqVO;
+import com.citu.module.menduner.system.controller.base.brand.BrandSaveReqVO;
+import com.citu.module.menduner.system.dal.dataobject.brand.BrandDO;
+import com.citu.module.menduner.system.dal.mysql.brand.BrandMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+
+import static com.citu.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static com.citu.module.menduner.system.enums.ErrorCodeConstants.BRAND_NOT_EXISTS;
+
+/**
+ * 品牌 Service 实现类
+ *
+ * @author Rayson
+ */
+@Service
+@Validated
+public class BrandServiceImpl implements BrandService {
+
+    @Resource
+    private BrandMapper brandMapper;
+
+    @Override
+    public Long createBrand(BrandSaveReqVO createReqVO) {
+        // 插入
+        BrandDO brand = BeanUtils.toBean(createReqVO, BrandDO.class);
+        brandMapper.insert(brand);
+        // 返回
+        return brand.getId();
+    }
+
+    @Override
+    public void updateBrand(BrandSaveReqVO updateReqVO) {
+        // 校验存在
+        validateBrandExists(updateReqVO.getId());
+        // 更新
+        BrandDO updateObj = BeanUtils.toBean(updateReqVO, BrandDO.class);
+        brandMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteBrand(Long id) {
+        // 校验存在
+        validateBrandExists(id);
+        // 删除
+        brandMapper.deleteById(id);
+    }
+
+    private void validateBrandExists(Long id) {
+        if (brandMapper.selectById(id) == null) {
+            throw exception(BRAND_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public BrandDO getBrand(Long id) {
+        return brandMapper.selectById(id);
+    }
+
+    @Override
+    public PageResult<BrandDO> getBrandPage(BrandPageReqVO pageReqVO) {
+        return brandMapper.selectPage(pageReqVO);
+    }
+
+}

+ 3 - 1
menduner/menduner-system-biz/src/main/resources/i18n/messages_en_US.properties

@@ -345,4 +345,6 @@
 1_100_046_013=Product amount cannot be empty
 1_100_046_014=Transaction order cancellation failed, order is not in the 'Pending Payment' status
 # ========== 用户实名制 1_100_047_000 ==========
-1_100_047_001=User real name system does not exist
+1_100_047_001=User real name system does not exist
+# ========== 品牌 1_100_048_000 ==========
+1_100_048_001=Brand does not exist

+ 3 - 1
menduner/menduner-system-biz/src/main/resources/i18n/messages_zh_CN.properties

@@ -348,4 +348,6 @@
 1_100_046_013=商品金额不能为空
 1_100_046_014=交易订单取消失败,订单不是【待支付】状态
 # ========== 用户实名制 1_100_047_000 ==========
-1_100_047_001=用户实名制不存在
+1_100_047_001=用户实名制不存在
+# ========== 品牌 1_100_048_000 ==========
+1_100_048_001=品牌不存在

+ 151 - 0
menduner/menduner-system-biz/src/test/java/com/citu/module/menduner/system/service/brand/BrandServiceImplTest.java

@@ -0,0 +1,151 @@
+package com.citu.module.menduner.system.service.brand;
+
+
+import com.citu.framework.common.pojo.PageResult;
+import com.citu.framework.test.core.ut.BaseDbUnitTest;
+import com.citu.module.menduner.system.controller.base.brand.BrandPageReqVO;
+import com.citu.module.menduner.system.controller.base.brand.BrandSaveReqVO;
+import com.citu.module.menduner.system.dal.dataobject.brand.BrandDO;
+import com.citu.module.menduner.system.dal.mysql.brand.BrandMapper;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+import org.springframework.context.annotation.Import;
+
+import javax.annotation.Resource;
+
+import static com.citu.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
+import static com.citu.framework.common.util.object.ObjectUtils.cloneIgnoreId;
+import static com.citu.framework.test.core.util.AssertUtils.assertPojoEquals;
+import static com.citu.framework.test.core.util.AssertUtils.assertServiceException;
+import static com.citu.framework.test.core.util.RandomUtils.randomLongId;
+import static com.citu.framework.test.core.util.RandomUtils.randomPojo;
+import static com.citu.module.menduner.system.enums.ErrorCodeConstants.BRAND_NOT_EXISTS;
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * {@link BrandServiceImpl} 的单元测试类
+ *
+ * @author Rayson
+ */
+@Import(BrandServiceImpl.class)
+public class BrandServiceImplTest extends BaseDbUnitTest {
+
+    @Resource
+    private BrandServiceImpl brandService;
+
+    @Resource
+    private BrandMapper brandMapper;
+
+    @Test
+    public void testCreateBrand_success() {
+        // 准备参数
+        BrandSaveReqVO createReqVO = randomPojo(BrandSaveReqVO.class).setId(null);
+
+        // 调用
+        Long brandId = brandService.createBrand(createReqVO);
+        // 断言
+        assertNotNull(brandId);
+        // 校验记录的属性是否正确
+        BrandDO brand = brandMapper.selectById(brandId);
+        assertPojoEquals(createReqVO, brand, "id");
+    }
+
+    @Test
+    public void testUpdateBrand_success() {
+        // mock 数据
+        BrandDO dbBrand = randomPojo(BrandDO.class);
+        brandMapper.insert(dbBrand);// @Sql: 先插入出一条存在的数据
+        // 准备参数
+        BrandSaveReqVO updateReqVO = randomPojo(BrandSaveReqVO.class, o -> {
+            o.setId(dbBrand.getId()); // 设置更新的 ID
+        });
+
+        // 调用
+        brandService.updateBrand(updateReqVO);
+        // 校验是否更新正确
+        BrandDO brand = brandMapper.selectById(updateReqVO.getId()); // 获取最新的
+        assertPojoEquals(updateReqVO, brand);
+    }
+
+    @Test
+    public void testUpdateBrand_notExists() {
+        // 准备参数
+        BrandSaveReqVO updateReqVO = randomPojo(BrandSaveReqVO.class);
+
+        // 调用, 并断言异常
+        assertServiceException(() -> brandService.updateBrand(updateReqVO), BRAND_NOT_EXISTS);
+    }
+
+    @Test
+    public void testDeleteBrand_success() {
+        // mock 数据
+        BrandDO dbBrand = randomPojo(BrandDO.class);
+        brandMapper.insert(dbBrand);// @Sql: 先插入出一条存在的数据
+        // 准备参数
+        Long id = dbBrand.getId();
+
+        // 调用
+        brandService.deleteBrand(id);
+        // 校验数据不存在了
+        assertNull(brandMapper.selectById(id));
+    }
+
+    @Test
+    public void testDeleteBrand_notExists() {
+        // 准备参数
+        Long id = randomLongId();
+
+        // 调用, 并断言异常
+        assertServiceException(() -> brandService.deleteBrand(id), BRAND_NOT_EXISTS);
+    }
+
+    @Test
+    @Disabled  // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
+    public void testGetBrandPage() {
+        // mock 数据
+        BrandDO dbBrand = randomPojo(BrandDO.class, o -> { // 等会查询到
+            o.setParentId(null);
+            o.setType(null);
+            o.setNameCn(null);
+            o.setNameEn(null);
+            o.setInternational(null);
+            o.setLevel(null);
+            o.setForeignId(null);
+            o.setCreateTime(null);
+        });
+        brandMapper.insert(dbBrand);
+        // 测试 parentId 不匹配
+        brandMapper.insert(cloneIgnoreId(dbBrand, o -> o.setParentId(null)));
+        // 测试 type 不匹配
+        brandMapper.insert(cloneIgnoreId(dbBrand, o -> o.setType(null)));
+        // 测试 nameCn 不匹配
+        brandMapper.insert(cloneIgnoreId(dbBrand, o -> o.setNameCn(null)));
+        // 测试 nameEn 不匹配
+        brandMapper.insert(cloneIgnoreId(dbBrand, o -> o.setNameEn(null)));
+        // 测试 international 不匹配
+        brandMapper.insert(cloneIgnoreId(dbBrand, o -> o.setInternational(null)));
+        // 测试 level 不匹配
+        brandMapper.insert(cloneIgnoreId(dbBrand, o -> o.setLevel(null)));
+        // 测试 foreignId 不匹配
+        brandMapper.insert(cloneIgnoreId(dbBrand, o -> o.setForeignId(null)));
+        // 测试 createTime 不匹配
+        brandMapper.insert(cloneIgnoreId(dbBrand, o -> o.setCreateTime(null)));
+        // 准备参数
+        BrandPageReqVO reqVO = new BrandPageReqVO();
+        reqVO.setParentId(null);
+        reqVO.setType(null);
+        reqVO.setNameCn(null);
+        reqVO.setNameEn(null);
+        reqVO.setInternational(null);
+        reqVO.setLevel(null);
+        reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
+
+        // 调用
+        PageResult<BrandDO> pageResult = brandService.getBrandPage(reqVO);
+        // 断言
+        assertEquals(1, pageResult.getTotal());
+        assertEquals(1, pageResult.getList().size());
+        assertPojoEquals(dbBrand, pageResult.getList().get(0));
+    }
+
+}