Преглед на файлове

Merge branch 'refs/heads/master' into develop_rayson

# Conflicts:
#	citu-gateway/src/main/resources/banner.txt
rayson преди 10 месеца
родител
ревизия
b45a8b07f5
променени са 33 файла, в които са добавени 1864 реда и са изтрити 2 реда
  1. 14 1
      citu-gateway/src/main/resources/banner.txt
  2. 19 0
      citu-module-mall/citu-module-statistics-biz/Dockerfile
  3. 3 0
      citu-module-mall/citu-module-trade-biz/src/main/java/com/citu/module/trade/controller/app/brokerage/AppBrokerageUserController.java
  4. 1 1
      citu-module-member/citu-module-member-biz/src/main/java/com/citu/module/member/service/auth/MemberAuthServiceImpl.java
  5. 6 0
      menduner/menduner-im-api/pom.xml
  6. 4 0
      menduner/menduner-im-biz/src/main/java/com/citu/module/menduner/im/controller/app/base/user/UserJobMsgVo.java
  7. 25 0
      menduner/menduner-im-biz/src/main/resources/mapper/user/UserMsgMapper.xml
  8. 33 0
      menduner/menduner-mall-api/pom.xml
  9. 7 0
      menduner/menduner-mall-api/src/main/java/com/citu/module/menduner/mall/Main.java
  10. 23 0
      menduner/menduner-mall-api/src/main/java/com/citu/module/menduner/mall/enums/ApiConstants.java
  11. 16 0
      menduner/menduner-mall-biz/Dockerfile
  12. 82 0
      menduner/menduner-mall-biz/pom.xml
  13. 18 0
      menduner/menduner-mall-biz/src/main/java/com/citu/module/menduner/mall/MendunerMallApplication.java
  14. 4 0
      menduner/menduner-mall-biz/src/main/java/com/citu/module/menduner/mall/controller/app/packageinfo.java
  15. 9 0
      menduner/menduner-mall-biz/src/main/java/com/citu/module/menduner/mall/framework/rpc/config/RpcConfiguration.java
  16. 4 0
      menduner/menduner-mall-biz/src/main/java/com/citu/module/menduner/mall/framework/rpc/package-info.java
  17. 38 0
      menduner/menduner-mall-biz/src/main/java/com/citu/module/menduner/mall/framework/security/config/SecurityConfiguration.java
  18. 144 0
      menduner/menduner-mall-biz/src/main/java/com/citu/module/menduner/mall/mybatis/plugin/SqlInterceptor.java
  19. 3 0
      menduner/menduner-mall-biz/src/main/resources/bootstrap-local.yaml
  20. 38 0
      menduner/menduner-mall-biz/src/main/resources/bootstrap.yaml
  21. 0 0
      menduner/menduner-mall-biz/src/main/resources/i18n/messages.properties
  22. 244 0
      menduner/menduner-mall-biz/src/main/resources/i18n/messages_en_US.properties
  23. 247 0
      menduner/menduner-mall-biz/src/main/resources/i18n/messages_zh_CN.properties
  24. 0 0
      menduner/menduner-mall-biz/src/main/resources/i18n/messages_zh_HK.properties
  25. 76 0
      menduner/menduner-mall-biz/src/main/resources/logback-spring.xml
  26. 60 0
      menduner/menduner-mall-biz/src/test/resources/application-unit-test.yaml
  27. 4 0
      menduner/menduner-mall-biz/src/test/resources/logback.xml
  28. 32 0
      menduner/menduner-mall-biz/src/test/resources/sql/clean.sql
  29. 556 0
      menduner/menduner-mall-biz/src/test/resources/sql/create_tables.sql
  30. 56 0
      menduner/menduner-reward-biz/src/main/java/com/citu/module/menduner/reward/controller/base/auth/vo/AppAuthLoginReqVO.java
  31. 38 0
      menduner/menduner-reward-biz/src/main/java/com/citu/module/menduner/reward/controller/base/auth/vo/AppAuthLoginRespVO.java
  32. 58 0
      menduner/menduner-reward-biz/src/main/java/com/citu/module/menduner/reward/controller/base/auth/vo/AppAuthSmsLoginReqVO.java
  33. 2 0
      menduner/pom.xml

+ 14 - 1
citu-gateway/src/main/resources/banner.txt

@@ -1,4 +1,17 @@
-
+Rayson http://www.iocoder.cn
 Application Version: ${citu.info.version}
 Spring Boot Version: ${spring-boot.version}
 
+.__   __.   ______      .______    __    __    _______
+|  \ |  |  /  __  \     |   _  \  |  |  |  |  /  _____|
+|   \|  | |  |  |  |    |  |_)  | |  |  |  | |  |  __
+|  . `  | |  |  |  |    |   _  <  |  |  |  | |  | |_ |
+|  |\   | |  `--'  |    |  |_)  | |  `--'  | |  |__| |
+|__| \__|  \______/     |______/   \______/   \______|
+
+███╗   ██╗ ██████╗     ██████╗ ██╗   ██╗ ██████╗
+████╗  ██║██╔═══██╗    ██╔══██╗██║   ██║██╔════╝
+██╔██╗ ██║██║   ██║    ██████╔╝██║   ██║██║  ███╗
+██║╚██╗██║██║   ██║    ██╔══██╗██║   ██║██║   ██║
+██║ ╚████║╚██████╔╝    ██████╔╝╚██████╔╝╚██████╔╝
+╚═╝  ╚═══╝ ╚═════╝     ╚═════╝  ╚═════╝  ╚═════╝

+ 19 - 0
citu-module-mall/citu-module-statistics-biz/Dockerfile

@@ -0,0 +1,19 @@
+## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性
+## 感谢复旦核博士的建议!灰子哥,牛皮!
+FROM adoptopenjdk/openjdk11
+
+## 创建目录,并使用它作为工作目录
+RUN mkdir -p /citu-module-statistics-biz
+WORKDIR /citu-module-statistics-biz
+## 将后端项目的 Jar 文件,复制到镜像中
+COPY ./target/citu-module-statistics-biz.jar app.jar
+
+## 设置 TZ 时区
+## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
+ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms512m -Xmx512m"
+
+## 暴露后端项目的 48080 端口
+EXPOSE 48100
+
+## 启动后端项目
+CMD java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar

+ 3 - 0
citu-module-mall/citu-module-trade-biz/src/main/java/com/citu/module/trade/controller/app/brokerage/AppBrokerageUserController.java

@@ -1,6 +1,7 @@
 package com.citu.module.trade.controller.app.brokerage;
 
 import cn.hutool.core.date.LocalDateTimeUtil;
+import com.alibaba.fastjson.JSON;
 import com.citu.framework.common.pojo.CommonResult;
 import com.citu.framework.common.pojo.PageResult;
 import com.citu.framework.security.core.annotations.PreAuthenticated;
@@ -80,6 +81,8 @@ public class AppBrokerageUserController {
     public CommonResult<AppBrokerageUserMySummaryRespVO> getBrokerageUserSummary() {
         // 查询当前登录用户信息
         BrokerageUserDO brokerageUser = brokerageUserService.getBrokerageUser(getLoginUserId());
+        log.info("查询当前登录用户信息:{},当前账户id:{}", brokerageUser, getLoginUserId());
+        System.out.println("查询当前登录用户信息:"+(null==brokerageUser?"null": JSON.toJSONString(brokerageUser))+",当前账户id:"+getLoginUserId());
         // 统计用户昨日的佣金
         LocalDateTime yesterday = LocalDateTime.now().minusDays(1);
         LocalDateTime beginTime = LocalDateTimeUtil.beginOfDay(yesterday);

+ 1 - 1
citu-module-member/citu-module-member-biz/src/main/java/com/citu/module/member/service/auth/MemberAuthServiceImpl.java

@@ -82,7 +82,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
     public AppAuthLoginRespVO smsLogin(AppAuthSmsLoginReqVO reqVO) {
         // 校验验证码
         String userIp = getClientIP();
-        smsCodeApi.useSmsCode(AuthConvert.INSTANCE.convert(reqVO, SmsSceneEnum.MEMBER_LOGIN.getScene(), userIp)).getCheckedData();
+        smsCodeApi.useSmsCode(AuthConvert.INSTANCE.convert(reqVO, SmsSceneEnum.MENDUNER_LOGIN.getScene(), userIp)).getCheckedData();
 
         // 获得获得注册用户
         MemberUserDO user = userService.createUserIfAbsent(reqVO.getMobile(), userIp, getTerminal());

+ 6 - 0
menduner/menduner-im-api/pom.xml

@@ -16,6 +16,12 @@
 
 
     <dependencies>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.8.26</version>
+        </dependency>
+
         <dependency>
             <groupId>com.citu</groupId>
             <artifactId>menduner-common</artifactId>

+ 4 - 0
menduner/menduner-im-biz/src/main/java/com/citu/module/menduner/im/controller/app/base/user/UserJobMsgVo.java

@@ -0,0 +1,4 @@
+package com.citu.module.menduner.im.controller.app.base.user;
+
+public class UserJobMsgVo {
+}

+ 25 - 0
menduner/menduner-im-biz/src/main/resources/mapper/user/UserMsgMapper.xml

@@ -0,0 +1,25 @@
+<?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.citu.module.menduner.im.dal.mysql.UserMsgMapper">
+
+
+    <select id="getJobMsg" resultType="com.citu.module.menduner.im.controller.app.base.user.UserJobMsgVo">
+
+
+        select payload from im_user_msg tab  inner join (
+            select
+                channel_id,max(im_user_msg_id) as id
+             from
+                 im_user_msg
+             WHERE type = 102
+               and from_uid =#{uid}
+               and channel_id in
+             <foreach collection="toUid" open="(" close=")" separator="," item="item">
+                 #{item}
+             </foreach>
+             group by channel_id
+             )tab2
+             on tab.im_user_msg_id = tab2.id
+
+    </select>
+</mapper>

+ 33 - 0
menduner/menduner-mall-api/pom.xml

@@ -0,0 +1,33 @@
+<?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.citu</groupId>
+        <artifactId>menduner</artifactId>
+        <version>${revision}</version>
+    </parent>
+
+    <artifactId>menduner-mall-api</artifactId>
+
+    <properties>
+        <maven.compiler.source>11</maven.compiler.source>
+        <maven.compiler.target>11</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.8.26</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.citu</groupId>
+            <artifactId>menduner-common</artifactId>
+            <version>${revision}</version>
+        </dependency>
+    </dependencies>
+
+</project>

+ 7 - 0
menduner/menduner-mall-api/src/main/java/com/citu/module/menduner/mall/Main.java

@@ -0,0 +1,7 @@
+package com.citu.module.menduner.mall;
+
+public class Main {
+    public static void main(String[] args) {
+        System.out.println("Hello world!");
+    }
+}

+ 23 - 0
menduner/menduner-mall-api/src/main/java/com/citu/module/menduner/mall/enums/ApiConstants.java

@@ -0,0 +1,23 @@
+package com.citu.module.menduner.mall.enums;
+
+import com.citu.framework.common.enums.RpcConstants;
+
+/**
+ * API 相关的枚举
+ *
+ * @author Rayson
+ */
+public class ApiConstants {
+
+    /**
+     * 服务名
+     *
+     * 注意,需要保证和 spring.application.name 保持一致
+     */
+    public static final String NAME = "menduner-im-server";
+
+    public static final String PREFIX = RpcConstants.RPC_API_PREFIX +  "/menduner/mall";
+
+    public static final String VERSION = "1.0.0";
+
+}

+ 16 - 0
menduner/menduner-mall-biz/Dockerfile

@@ -0,0 +1,16 @@
+## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性
+## 感谢复旦核博士的建议!灰子哥,牛皮!
+FROM adoptopenjdk/openjdk11
+
+## 将后端项目的 Jar 文件,复制到镜像中
+ADD target/menduner-mall-biz.jar app.jar
+
+## 设置 TZ 时区
+## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
+ENV TZ=Asia/Shanghai
+
+## 暴露后端项目的 48201 端口
+EXPOSE 48201
+
+## 启动后端项目
+CMD java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar

+ 82 - 0
menduner/menduner-mall-biz/pom.xml

@@ -0,0 +1,82 @@
+<?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.citu</groupId>
+        <artifactId>menduner</artifactId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>menduner-mall-biz</artifactId>
+    <packaging>jar</packaging>
+
+    <name>${project.artifactId}</name>
+    <description>
+        门墩儿商城 模块
+    </description>
+
+    <dependencies>
+        <!-- Spring Cloud 基础 -->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-bootstrap</artifactId>
+        </dependency>
+
+        <!-- 依赖服务 -->
+        <dependency>
+            <groupId>com.citu</groupId>
+            <artifactId>menduner-mall-api</artifactId>
+            <version>${revision}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.citu</groupId>
+            <artifactId>menduner-system-api</artifactId>
+            <version>${revision}</version>
+        </dependency>
+
+
+        <!-- Registry 注册中心相关 -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+        </dependency>
+
+        <!-- Config 配置中心相关 -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+        </dependency>
+
+        <!-- Test 测试相关 -->
+        <dependency>
+            <groupId>com.citu</groupId>
+            <artifactId>citu-spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <!-- 设置构建的 jar 包名 -->
+        <finalName>${project.artifactId}</finalName>
+        <plugins>
+            <!-- 打包 -->
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>${spring.boot.version}</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal> <!-- 将引入的 jar 打入其中 -->
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 18 - 0
menduner/menduner-mall-biz/src/main/java/com/citu/module/menduner/mall/MendunerMallApplication.java

@@ -0,0 +1,18 @@
+package com.citu.module.menduner.mall;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.ConfigurableApplicationContext;
+
+/**
+ * 项目的启动类
+ */
+@SpringBootApplication
+public class MendunerMallApplication {
+    public static ConfigurableApplicationContext applicationContext;
+
+    public static void main(String[] args) {
+        applicationContext=SpringApplication.run(MendunerMallApplication.class, args);
+    }
+}

+ 4 - 0
menduner/menduner-mall-biz/src/main/java/com/citu/module/menduner/mall/controller/app/packageinfo.java

@@ -0,0 +1,4 @@
+package com.citu.module.menduner.mall.controller.app;
+
+public class packageinfo {
+}

+ 9 - 0
menduner/menduner-mall-biz/src/main/java/com/citu/module/menduner/mall/framework/rpc/config/RpcConfiguration.java

@@ -0,0 +1,9 @@
+package com.citu.module.menduner.mall.framework.rpc.config;
+
+import com.citu.module.menduner.system.api.user.UserApi;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration(proxyBeanMethods = false)
+public class RpcConfiguration {
+}

+ 4 - 0
menduner/menduner-mall-biz/src/main/java/com/citu/module/menduner/mall/framework/rpc/package-info.java

@@ -0,0 +1,4 @@
+/**
+ * 占位
+ */
+package com.citu.module.menduner.mall.framework.rpc;

+ 38 - 0
menduner/menduner-mall-biz/src/main/java/com/citu/module/menduner/mall/framework/security/config/SecurityConfiguration.java

@@ -0,0 +1,38 @@
+package com.citu.module.menduner.mall.framework.security.config;
+
+import com.citu.framework.security.config.AuthorizeRequestsCustomizer;
+import com.citu.module.menduner.mall.enums.ApiConstants;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
+
+/**
+ * menduner 模块的 Security 配置
+ */
+@Configuration("mendunerMiSecurityConfiguration")
+public class SecurityConfiguration {
+
+    @Bean("mendunerMiAuthorizeRequestsCustomizer")
+    public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() {
+        return new AuthorizeRequestsCustomizer() {
+
+            @Override
+            public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) {
+                // TODO 芋艿:这个每个项目都需要重复配置,得捉摸有没通用的方案
+                // Swagger 接口文档
+                registry.antMatchers("/v3/api-docs/**").permitAll() // 元数据
+                        .antMatchers("/swagger-ui.html").permitAll(); // Swagger UI
+                // Druid 监控
+                registry.antMatchers("/druid/**").anonymous();
+                // Spring Boot Actuator 的安全配置
+                registry.antMatchers("/actuator").anonymous()
+                        .antMatchers("/actuator/**").anonymous();
+                // RPC 服务的安全配置
+                registry.antMatchers(ApiConstants.PREFIX + "/**").permitAll();
+            }
+
+        };
+    }
+
+}

+ 144 - 0
menduner/menduner-mall-biz/src/main/java/com/citu/module/menduner/mall/mybatis/plugin/SqlInterceptor.java

@@ -0,0 +1,144 @@
+package com.citu.module.menduner.mall.mybatis.plugin;
+
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.cache.CacheKey;
+import org.apache.ibatis.executor.Executor;
+import org.apache.ibatis.mapping.BoundSql;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.mapping.ParameterMapping;
+import org.apache.ibatis.mapping.SqlCommandType;
+import org.apache.ibatis.plugin.*;
+import org.apache.ibatis.reflection.MetaObject;
+import org.apache.ibatis.session.Configuration;
+import org.apache.ibatis.session.ResultHandler;
+import org.apache.ibatis.session.RowBounds;
+import org.apache.ibatis.type.TypeHandlerRegistry;
+
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * 1.可以用来分析SQL执行效率
+ * 2.可以用来获取实际执行的SQL
+ */
+
+@Intercepts({
+        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
+        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),
+        @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})}
+)
+@Slf4j
+public class SqlInterceptor implements Interceptor {
+//    private static final Log log = LogFactory.getLog(SqlInterceptor.class);    
+    /**
+     * 最小打印时间 sql时间超过这个值才打印日志 毫秒
+     **/
+    private int MIN_SIZE = 0;
+
+    @Override
+    public Object intercept(Invocation invocation) throws Throwable {
+        // 判断是否需要执行插件,避免浪费性能
+        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
+        Object parameter = null;
+        if (invocation.getArgs().length > 1) {
+            parameter = invocation.getArgs()[1];
+        }
+        String sqlId = mappedStatement.getId();
+        BoundSql boundSql = mappedStatement.getBoundSql(parameter);
+        Configuration configuration = mappedStatement.getConfiguration();
+
+        long startTime = System.currentTimeMillis();
+        Object result = null;
+        try {
+            result = invocation.proceed();
+        } finally {
+            try {
+                long sqlCostTime = System.currentTimeMillis() - startTime;
+                String sql = getSql(configuration, boundSql);
+                formatSqlLog(mappedStatement.getSqlCommandType(), sqlId, sql, sqlCostTime, result);
+            } catch (Exception ignored) {
+                log.error("SQL插件执行失败 Mapper:{} 参数对象:{}", sqlId, JSON.toJSONString(boundSql.getParameterObject()), ignored);
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public Object plugin(Object target) {
+        return Plugin.wrap(target, this);
+    }
+
+    @Override
+    public void setProperties(Properties properties) {
+        if (properties == null) {
+            return;
+        }
+        if (properties.containsKey("minLogSize")) {
+            MIN_SIZE = Integer.valueOf(properties.getProperty("minLogSize"));
+        }
+    }
+
+    private String getSql(Configuration configuration, BoundSql boundSql) {
+        // 输入sql字符串空判断
+        String sql = boundSql.getSql();
+        if (StrUtil.isBlank(sql)) {
+            return "";
+        }
+
+        //去掉换行符
+        sql = sql.replaceAll("[\\s\n ]+", " ");
+
+        //填充占位符, 目前基本不用mybatis存储过程调用,故此处不做考虑
+        Object parameterObject = boundSql.getParameterObject();
+        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
+        if (!parameterMappings.isEmpty() && parameterObject != null) {
+            TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
+            if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
+                sql = this.replacePlaceholder(sql, parameterObject);
+            } else {
+                MetaObject metaObject = configuration.newMetaObject(parameterObject);
+                for (ParameterMapping parameterMapping : parameterMappings) {
+                    String propertyName = parameterMapping.getProperty();
+                    if (metaObject.hasGetter(propertyName)) {
+                        Object obj = metaObject.getValue(propertyName);
+                        sql = replacePlaceholder(sql, obj);
+                    } else if (boundSql.hasAdditionalParameter(propertyName)) {
+                        Object obj = boundSql.getAdditionalParameter(propertyName);
+                        sql = replacePlaceholder(sql, obj);
+                    }
+                }
+            }
+        }
+        return sql;
+    }
+
+    private String replacePlaceholder(String sql, Object parameterObject) {
+        String result;
+        if (parameterObject == null) {
+            result = "NULL";
+        } else if (parameterObject instanceof String) {
+            result = String.format("'%s'", parameterObject.toString());
+        } else if (parameterObject instanceof Date) {
+            result = String.format("'%s'", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(parameterObject));
+        } else {
+            result = parameterObject.toString();
+        }
+        return sql.replaceFirst("\\?", result);
+    }
+
+    private void formatSqlLog(SqlCommandType sqlCommandType, String sqlId, String sql, long costTime, Object obj) {
+        if (costTime > MIN_SIZE) {
+            if (sqlCommandType == SqlCommandType.UPDATE || sqlCommandType == SqlCommandType.INSERT || sqlCommandType == SqlCommandType.DELETE) {
+                log.info("[执行时长{}ms] [{}] {}; 影响行数:{}", costTime, sqlId, sql, obj);
+            }
+            if (sqlCommandType == SqlCommandType.SELECT) {
+                log.info("[执行时长{}ms] [{}] {}; 结果行数:{}", costTime, sqlId, sql, null==obj?"无":((Collection<?>) obj).size());
+            }
+        }
+    }
+}

+ 3 - 0
menduner/menduner-mall-biz/src/main/resources/bootstrap-local.yaml

@@ -0,0 +1,3 @@
+--- #################### 注册中心相关配置 ####################
+
+

+ 38 - 0
menduner/menduner-mall-biz/src/main/resources/bootstrap.yaml

@@ -0,0 +1,38 @@
+spring:
+  messages:
+    basename: i18n/messages
+    encoding: UTF-8
+  application:
+    name: mall-server
+  main:
+    allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。
+    allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务
+  profiles:
+    active: prod
+  cloud:
+    nacos:
+      server-addr: ${nacosHost:127.0.0.1:8848}
+      discovery:
+        namespace: menduner-dev # 命名空间。这里使用 dev 开发环境
+        metadata:
+          version: 1.0.0 # 服务实例的版本号,可用于灰度发布
+      # Nacos Config 配置项,对应 NacosConfigProperties 配置属性类
+      config:
+        server-addr: ${nacosHost:127.0.0.1:8848} # Nacos 服务器地址
+        namespace: menduner-dev # 命名空间 dev 的ID,不能直接使用 dev 名称。创建命名空间的时候需要指定ID为 dev,这里使用 dev 开发环境
+        group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
+        name: ${spring.application.name} # 使用的 Nacos 配置集的 dataId,默认为 spring.application.name
+        file-extension: yaml # 使用的 Nacos 配置集的 dataId 的文件拓展名,同时也是 Nacos 配置集的配置格式,默认为 properties
+
+server:
+  port: 48202
+
+# 日志文件配置。注意,如果 logging.file.name 不放在 bootstrap.yaml 配置文件,而是放在 application.yaml 中,会导致出现 LOG_FILE_IS_UNDEFINED 文件
+logging:
+  file:
+    name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径
+citu:
+  info:
+    version: 1.0.0
+    base-package: com.citu.module.menduner.im
+

+ 0 - 0
menduner/menduner-mall-biz/src/main/resources/i18n/messages.properties


+ 244 - 0
menduner/menduner-mall-biz/src/main/resources/i18n/messages_en_US.properties

@@ -0,0 +1,244 @@
+# ========== 系统 ==========
+0=Successful
+# ========== 客户端错误段 ==========
+400=incorrect request parameters
+401=account not logged in
+403=no permission for this operation
+404=request not found
+405=incorrect request method
+423=request failed, please try again later # concurrent request, not allowed
+429=request too frequent, please try again later
+
+# ========== 服务端错误段 ==========
+500=system abnormality
+501=function not implemented/not enabled
+502=incorrect configuration item
+# ========== 自定义错误段 ==========
+900=duplicate request, please try again later # duplicate request
+901=demonstration mode, write operation prohibited
+999=unknown error
+# ========== 公共 1_099_000_000 ==========
+1_099_000_001=Status cannot be empty
+1_099_000_002=The modification status must be {value}
+1_099_000_003=Display order cannot be empty
+1_099_000_004=Superior ID cannot be empty
+1_099_000_005=id cannot be empty
+1_099_000_006=User ID cannot be empty
+1_099_000_007=Enterprise ID cannot be empty
+# ========== 人才信息-人才档案 1_100_001_000 ==========
+1_100_001_001=Personal Profile Does Not Exist
+1_100_001_002=Personal advantage cannot be empty
+1_100_001_003=Real name cannot be empty
+1_100_001_004=Contact phone number cannot be empty
+1_100_001_005=Birthdate cannot be empty
+1_100_001_006=Work experience cannot be empty
+1_100_001_007=Education cannot be empty
+1_100_001_008=Job search status cannot be empty
+1_100_001_009=City cannot be empty
+1_100_001_010=Frequently used email cannot be empty
+1_100_001_011=Please fill in your personal basic information first
+# ========== 行业信息 1_100_002_000 ==========
+1_100_002_001=Industry information does not exist
+# ========== 职位信息 1_100_003_000 ==========
+1_100_003_001=Position information does not exist
+1_100_003_002=Position type cannot be empty
+1_100_003_003=Position name cannot be empty
+# ========== 地区 1_100_004_000 ==========
+1_100_004_001=Region does not exist
+1_100_004_002=Popular regions already exist, please do not add them again
+1_100_004_003=Work area cannot be empty
+# ========== 简历附件 1_100_005_000 ==========
+1_100_005_001=Resume attachment does not exist
+1_100_005_002=Upload a maximum of 5 resume attachments
+# ========== 教育经历 1_100_006_000 ==========
+1_100_006_001=Educational experience does not exist
+1_100_006_002=No education selected
+1_100_006_003=No educational system type selected
+1_100_006_004=No school start date selected
+1_100_006_005=No end date selected for school
+# ========== 求职意向 1_100_007_000 ==========
+1_100_007_001=Job search intention does not exist
+1_100_007_002=No expected position selected
+1_100_007_003=No expected industry selected
+1_100_007_004=No job search type selected
+1_100_007_005=No minimum salary requirement filled in
+1_100_007_006=No maximum salary requirement filled in
+1_100_007_007=No work city selected
+# ========== 专业 1_100_008_000 ==========
+1_100_008_001=Major does not exist
+# ========== 职位标签 1_100_009_000 ==========
+1_100_009_001=Position tag does not exist
+1_100_009_002=Position tag cannot be empty
+# ========== 学校 1_100_010_000 ==========
+1_100_010_001=School does not exist
+# ========== 人才证书 1_100_011_000 ==========
+1_100_011_001=Personnel certificate does not exist
+1_100_011_002=Certificate Chinese name cannot be empty
+1_100_011_003=Certificate English name cannot be empty
+# ========== 工作经历 1_100_012_000 ==========
+1_100_012_001=Work experience does not exist
+1_100_012_002=No start date selected for employment
+1_100_027_003=No end time selected for employment
+# ========== 人才技能 1_100_013_000 ==========
+1_100_013_001=Personnel skill does not exist
+1_100_013_002=The skill already exists
+# ========== 证书 1_100_014_000 ==========
+1_100_014_001=Certificate does not exist
+# ========== 访问量 1_100_015_000 ==========
+1_100_015_001=The traffic does not exist
+1_100_015_002=Business type does not exist
+1_100_015_003=Business ID does not exist
+1_100_015_004=Access date does not exist
+# ========== 用户登录 1_100_016_000 ==========
+1_100_016_001=User does not exist
+1_100_016_002=Unregistered user with phone number
+1_100_016_003=Modifying phone failed, the phone number ({}) has already been used
+1_100_016_004=User account already exists
+1_100_016_005=Phone number already exists
+1_100_016_006=Email already exists
+1_100_016_007=Phone number cannot be empty
+1_100_016_008=Importing user data cannot be empty!
+1_100_016_009=User password verification failed
+1_100_016_010=The user named [{}] has been disabled
+1_100_016_011=User creation failed due to exceeding the maximum tenant quota ({}) for tenants!
+1_100_016_012=The new password cannot be empty
+1_100_016_013=Phone verification code cannot be empty
+1_100_016_014=The length of the mobile verification code is 4-6 digits
+1_100_016_015=The length of the phone number is 8-11 digits
+1_100_016_016=Phone verification codes must all be numbers
+1_100_016_017=Password length is 4-16 bits
+1_100_016_018=User ID cannot be empty
+1_100_016_019=Password cannot be empty
+1_100_016_020=User account cannot be empty
+# ========== AUTH 模块 1_100_017_000 ==========
+1_100_017_001=Login failed, incorrect account and password
+1_100_017_002=Login failed, account disabled
+1_100_017_003=Login failed, unable to resolve third-party login information
+1_100_017_004=The phone number has already been used
+1_100_017_005=Incorrect verification code, reason: {}
+1_100_017_006=Account not bound, needs to be bound
+1_100_017_007=Token has expired
+1_100_017_008=Phone number does not exist
+1_100_017_009=Sending scene cannot be empty
+1_100_017_010=Phone code cannot be empty
+1_100_017_011=Login code cannot be empty
+1_100_017_012=State cannot be empty
+1_100_017_013=Authorization code cannot be empty
+1_100_017_014=The type of social platform cannot be empty
+1_100_017_015=The verification code cannot be empty
+1_100_017_016=No enterprise selected
+1_100_017_017=Unregistered user, please register individual user first before applying for enterprise user
+1_100_017_018=Access token cannot be empty
+# ========== 角色模块 1_100_018_000 ==========
+1_100_018_001=Character does not exist
+1_100_018_002=A role named [{}] already exists
+1_100_018_003=A role with code [{}] already exists
+1_100_018_004=Cannot operate on roles with built-in system types
+1_100_018_005=The character named [{}] has been disabled
+1_100_018_006=Encoding [{}] cannot be used
+1_100_018_007=Role number cannot be empty
+1_100_018_008=Role name cannot be empty
+1_100_018_009=The length of the character name cannot exceed 30 characters
+1_100_018_010=Character flag cannot be empty
+1_100_018_011=The character flag cannot exceed 100 characters in length
+1_100_018_012=Data range cannot be empty
+1_100_018_013=The data range must be {value}
+# ========== 企业信息 1_100_019_000 ==========
+1_100_019_001=Enterprise information does not exist
+1_100_019_002=Enterprise code cannot be empty
+1_100_019_003=No company name filled in
+1_100_019_004=Enterprise alias not filled in
+1_100_019_005=Company profile not filled in
+1_100_019_006=No industry selected
+1_100_019_007=No financing stage selected
+1_100_019_008=No personnel size selected
+1_100_019_009=No work hours filled in
+# ========== 企业工商信息  1_100_020_001 ==========
+1_100_020_001=Enterprise business information does not exist
+1_100_020_002=No company name filled in
+1_100_020_003=Unified social credit code not filled in
+# ========== 企业注册申请 1_100_021_000 ==========
+1_100_021_001=The enterprise registration application does not exist
+1_100_021_002=Enterprise registration application has been approved
+1_100_021_003=The enterprise registration application has been approved and cannot be rejected
+1_100_021_004=Enterprise name cannot be empty
+1_100_021_005=Contact number cannot be empty
+1_100_021_006=Contact email cannot be empty
+1_100_021_007=Business license not uploaded
+1_100_021_008=Unified social credit code cannot be empty
+1_100_021_009=Enterprise registered
+1_100_021_010=The enterprise has applied for review, please do not resubmit
+# ========== 企业地址 1_100_022_001 ==========
+1_100_022_001=The company address does not exist
+# ========== 企业登录用户 1_100_023_000 ==========
+1_100_023_001=Enterprise login user does not exist
+1_100_023_002=Name cannot be empty
+1_100_023_003=The account has been disabled
+1_100_023_004=This account is an administrator account and cannot be operated
+# ========== 企业岗位信息 1_100_024_000 ==========
+1_100_024_001=Enterprise position information does not exist
+1_100_024_002=The Chinese name of the position cannot be empty
+1_100_024_003=Position English cannot be empty
+# ========== 招聘职位 1_100_025_000 ==========
+1_100_025_001=Recruitment position does not exist
+1_100_025_002=Recruitment position ID cannot be empty
+1_100_025_003=Position name cannot be empty
+1_100_025_004=Recruitment type cannot be empty
+1_100_025_005=The publishing user ID cannot be empty
+1_100_025_006=Work experience cannot be empty
+1_100_025_007=Educational requirements cannot be empty
+# ========== 企业招聘者浏览 1_100_026_000 ==========
+1_100_026_001=Enterprise recruiter browsing does not exist
+# ========== 人才-企业关注订阅 1_100_027_000 ==========
+1_100_027_001=Enterprise follow subscription does not exist
+1_100_027_002=Enterprise has followed and subscribed, please do not click again
+# ========== 人才-浏览记录 1_100_028_000 ==========
+1_100_028_001=Browsing history does not exist
+# ========== 人才-招聘职位收藏 1_100_029_000 ==========
+1_100_029_001=Recruitment position collection does not exist
+1_100_029_002=Position has been saved, please do not click again
+# ========== 培训经历 1_100_030_000 ==========
+1_100_030_001=Training experience does not exist
+1_100_030_002=Training start time cannot be empty
+1_100_030_003=Training end time cannot be empty
+1_100_030_004=Training institution name cannot be empty
+1_100_030_005=Training course cannot be empty
+# ========== 项目经历 1_100_031_000 ==========
+1_100_031_001=Project experience does not exist
+1_100_031_002=Project name not filled in
+1_100_031_003=Project start time cannot be empty
+1_100_031_004=Project end time cannot be empty
+# ========== 职业技能 1_100_032_000 ==========
+1_100_032_001=Vocational skill does not exist
+1_100_032_002=There are sub profession skills that cannot be deleted
+1_100_032_003=Parent level vocational skill does not exist
+1_100_032_004=Unable to set oneself as a parent vocational skill
+1_100_032_005=There is already a vocational skill with the Chinese name for this skill
+1_100_032_006=Cannot set one's own child Skill as the parent Skill
+# ========== 企业用户申请 1_100_034_000 ==========
+1_100_034_001=Enterprise user application does not exist
+1_100_034_002=User application has been approved
+1_100_034_003=The user's application has been approved and cannot be rejected
+1_100_034_005=Applied for review, please do not resubmit
+# ========== 招聘职位简历投递 1_100_034_000 ==========
+1_100_035_001=Recruitment position resume submission does not exist
+1_100_035_002=The position has been submitted
+1_100_035_003=No resume attachment selected
+1_100_035_004=Recruitment position ID cannot be empty
+1_100_035_005=This position is currently not allowed for delivery
+1_100_035_006=Recruitment for this position has been suspended
+# ========== 众聘-简历投递 1_100_036_000 ==========
+1_100_036_001=The submitted resume does not exist
+1_100_036_002=The posted position ID cannot be empty
+1_100_036_003=The user ID for posting positions cannot be empty
+1_100_036_004=Referee ID cannot be empty
+1_100_036_005=The delivery user ID cannot be empty
+1_100_036_006=The name of the sender cannot be empty
+1_100_036_007=The contact phone number of the deliveryman cannot be empty
+1_100_036_008=Resume attachment cannot be empty
+# ========== 众聘-佣金比例 1_100_037_000 ==========
+1_100_037_001=Commission ratio does not exist
+1_100_037_002=Commission ratio cannot be empty
+1_100_037_003=Commission ratio cannot be less than 0
+# ========== 用户账户 1_100_038_000 ==========
+1_100_038_001=User account does not exist

+ 247 - 0
menduner/menduner-mall-biz/src/main/resources/i18n/messages_zh_CN.properties

@@ -0,0 +1,247 @@
+# ========== 系统 ==========
+0=成功
+# ========== 客户端错误段 ==========
+400=请求参数不正确
+401=账号未登录
+403=没有该操作权限
+404=请求未找到
+405=请求方法不正确
+423=请求失败,请稍后重试 # 并发请求,不允许
+429=请求过于频繁,请稍后重试
+
+# ========== 服务端错误段 ==========
+500=系统异常
+501=功能未实现/未开启
+502=错误的配置项
+# ========== 自定义错误段 ==========
+900=重复请求,请稍后重试 # 重复请求
+901=演示模式,禁止写操作
+999=未知错误
+# ========== 公共 1_099_000_000 ==========
+1_099_000_001=帐号状态不能为空
+1_099_000_002=修改状态必须是 {value}
+1_099_000_003=显示顺序不能为空
+1_099_000_004=上级id不能为空
+1_099_000_005=id不能为空
+1_099_000_006=用户id不能为空
+1_099_000_007=企业id不能为空
+# ========== 人才信息-人才档案 1_100_001_000 ==========
+1_100_001_001=人才档案不存在
+1_100_001_002=人才优势不能为空
+1_100_001_003=真实姓名不能为空
+1_100_001_004=联系手机号不能为空
+1_100_001_005=出生日期不能为空
+1_100_001_006=工作经验不能为空
+1_100_001_007=学历不能为空
+1_100_001_008=求职状态不能为空
+1_100_001_009=所在城市不能为空
+1_100_001_010=常用邮箱不能为空
+1_100_001_011=请先填写人才基本信息
+# ========== 行业信息 1_100_002_000 ==========
+1_100_002_001=行业信息不存在
+# ========== 职位信息 1_100_003_000 ==========
+1_100_003_001=职位信息不存在
+1_100_003_002=职位类型不能为空
+1_100_003_003=职位名称不能为空
+# ========== 地区 1_100_004_000 ==========
+1_100_004_001=地区不存在
+1_100_004_002=热门地区已存在,请勿重复添加
+1_100_004_003=工作地区不能为空
+# ========== 简历附件 1_100_005_000 ==========
+1_100_005_001=简历附件不存在
+1_100_005_002=简历附件最多上传5份
+# ========== 教育经历 1_100_006_000 ==========
+1_100_006_001=教育经历不存在
+1_100_006_002=未选择学历
+1_100_006_003=未选择学制类型
+1_100_006_004=未选择在校开始日期
+1_100_006_005=未选择在校结束日期
+# ========== 求职意向 1_100_007_000 ==========
+1_100_007_001=求职意向不存在
+1_100_007_002=未选择期望职位
+1_100_007_003=未选择期望行业
+1_100_007_004=未选择求职类型
+1_100_007_005=未填写薪酬最低要求
+1_100_007_006=未填写薪酬最高要求
+1_100_007_007=未选择工作城市
+# ========== 专业 1_100_008_000 ==========
+1_100_008_001=专业不存在
+# ========== 职位标签 1_100_009_000 ==========
+1_100_009_001=职位标签不存在
+1_100_009_002=职位标签不能为空
+# ========== 学校 1_100_010_000 ==========
+1_100_010_001=学校不存在
+# ========== 人才证书 1_100_011_000 ==========
+1_100_011_001=人才证书不存在
+1_100_011_002=证书中文名称不能为空
+1_100_011_003=证书英文名称不能为空
+# ========== 工作经历 1_100_012_000 ==========
+1_100_012_001=工作经历不存在
+1_100_012_002=未选择在职开始日期
+1_100_027_003=未选择在职结束时间
+# ========== 人才技能 1_100_013_000 ==========
+1_100_013_001=人才技能不存在
+1_100_013_002=该技能已存在
+# ========== 证书 1_100_014_000 ==========
+1_100_014_001=证书不存在
+# ========== 访问量 1_100_015_000 ==========
+1_100_015_001=访问量不存在
+1_100_015_002=业务类型不存在
+1_100_015_003=业务id不存在
+1_100_015_004=访问日期不存在
+# ========== 用户登录 1_100_016_000 ==========
+1_100_016_001=用户不存在
+1_100_016_002=手机号未注册用户
+1_100_016_003=修改手机失败,该手机号({})已经被使用
+1_100_016_004=用户账号已经存在
+1_100_016_005=手机号已经存在
+1_100_016_006=邮箱已经存在
+1_100_016_007=手机号不能为空
+1_100_016_008=导入用户数据不能为空!
+1_100_016_009=用户密码校验失败
+1_100_016_010=名字为【{}】的用户已被禁用
+1_100_016_011=创建用户失败,原因:超过租户最大租户配额({})!
+1_100_016_012=新密码不能为空
+1_100_016_013=手机验证码不能为空
+1_100_016_014=手机验证码长度为 4-6 位
+1_100_016_015=手机号码长度为 8-11 位
+1_100_016_016=手机验证码必须都是数字
+1_100_016_017=密码长度为 4-16 位
+1_100_016_018=用户编号不能为空
+1_100_016_019=密码不能为空
+1_100_016_020=用户账号不能为空
+# ========== AUTH 模块 1_100_017_000 ==========
+1_100_017_001=登录失败,账号密码不正确
+1_100_017_002=登录失败,账号被禁用
+1_100_017_003=登录失败,解析不到三方登录信息
+1_100_017_004=手机号已经被使用
+1_100_017_005=验证码不正确,原因:{}
+1_100_017_006=未绑定账号,需要进行绑定
+1_100_017_007=Token 已经过期
+1_100_017_008=手机号不存在
+1_100_017_009=发送场景不能为空
+1_100_017_010=手机code不能为空
+1_100_017_011=登录code不能为空
+1_100_017_012=state不能为空
+1_100_017_013=授权码不能为空
+1_100_017_014=社交平台的类型不能为空
+1_100_017_015=验证码不能为空
+1_100_017_016=未选择企业
+1_100_017_017=未注册用户,请先注册人才用户再申请企业用户
+1_100_017_018=访问令牌不能为空
+# ========== 角色模块 1_100_018_000 ==========
+1_100_018_001=角色不存在
+1_100_018_002=已经存在名为【{}】的角色
+1_100_018_003=已经存在编码为【{}】的角色
+1_100_018_004=不能操作类型为系统内置的角色
+1_100_018_005=名字为【{}】的角色已被禁用
+1_100_018_006=编码【{}】不能使用
+1_100_018_007=角色编号不能为空
+1_100_018_008=角色名称不能为空
+1_100_018_009=角色名称长度不能超过 30 个字符
+1_100_018_010=角色标志不能为空
+1_100_018_011=角色标志长度不能超过 100 个字符
+1_100_018_012=数据范围不能为空
+1_100_018_013=数据范围必须是 {value}
+# ========== 企业信息 1_100_019_000 ==========
+1_100_019_001=企业信息不存在
+1_100_019_002=企业编码不能为空
+1_100_019_003=未填写企业名称
+1_100_019_004=未填写企业别称
+1_100_019_005=未填写公司简介
+1_100_019_006=未选择所在行业
+1_100_019_007=未选择融资阶段
+1_100_019_008=未选择人员规模
+1_100_019_009=未填写上班时间
+# ========== 企业工商信息  1_100_020_001 ==========
+1_100_020_001=企业工商信息不存在
+1_100_020_002=未填写企业名称
+1_100_020_003=未填写统一社会信用代码
+# ========== 企业注册申请 1_100_021_000 ==========
+1_100_021_001=企业注册申请不存在
+1_100_021_002=企业注册申请已审批
+1_100_021_003=企业注册申请已审批通过,无法拒绝
+1_100_021_004=企业名称不能为空
+1_100_021_005=联系电话不能为空
+1_100_021_006=联系邮箱不能为空
+1_100_021_007=未上传营业执照
+1_100_021_008=统一社会信用代码不能为空
+1_100_021_009=企业已注册
+1_100_021_010=企业申请审核中,请勿重复提交
+# ========== 企业地址 1_100_022_001 ==========
+1_100_022_001=企业地址不存在
+# ========== 企业登录用户 1_100_023_000 ==========
+1_100_023_001=企业登录用户不存在
+1_100_023_002=名称不能为空
+1_100_023_003=该账户已被禁用
+1_100_023_004=该账户为管理员账户,无法操作
+# ========== 企业岗位信息 1_100_024_000 ==========
+1_100_024_001=企业岗位信息不存在
+1_100_024_002=岗位中文名称不能为空
+1_100_024_003=岗位英文不能为空
+# ========== 招聘职位 1_100_025_000 ==========
+1_100_025_001=招聘职位不存在
+1_100_025_002=招聘职位id不能为空
+1_100_025_003=职位名称不能为空
+1_100_025_004=招聘类型不能为空
+1_100_025_005=发布用户id不能为空
+1_100_025_006=工作经验不能为空
+1_100_025_007=学历要求不能为空
+# ========== 企业招聘者浏览 1_100_026_000 ==========
+1_100_026_001=企业招聘者浏览不存在
+# ========== 人才-企业关注订阅 1_100_027_000 ==========
+1_100_027_001=企业关注订阅不存在
+1_100_027_002=企业已关注订阅,请勿重复点击
+# ========== 人才-浏览记录 1_100_028_000 ==========
+1_100_028_001=浏览记录不存在
+# ========== 人才-招聘职位收藏 1_100_029_000 ==========
+1_100_029_001=招聘职位收藏不存在
+1_100_029_002=职位已收藏,请勿重复点击
+# ========== 培训经历 1_100_030_000 ==========
+1_100_030_001=培训经历不存在
+1_100_030_002=培训开始时间不能为空
+1_100_030_003=培训结束时间不能为空
+1_100_030_004=培训机构名称不能为空
+1_100_030_005=培训课程不能为空
+# ========== 项目经历 1_100_031_000 ==========
+1_100_031_001=项目经历不存在
+1_100_031_002=未填写项目名称
+1_100_031_003=项目开始时间不能为空
+1_100_031_004=项目结束时间不能为空
+# ========== 职业技能 1_100_032_000 ==========
+1_100_032_001=职业技能不存在
+1_100_032_002=存在存在子职业技能,无法删除
+1_100_032_003=父级职业技能不存在
+1_100_032_004=不能设置自己为父职业技能
+1_100_032_005=已经存在该技能中文名称的职业技能
+1_100_032_006=不能设置自己的子Skill为父Skill
+# ========== 企业用户申请 1_100_034_000 ==========
+1_100_034_001=企业用户申请不存在
+1_100_034_002=用户申请已审批
+1_100_034_003=用户申请申请已审批通过,无法拒绝
+1_100_034_005=已申请审核中,请勿重复提交
+# ========== 招聘职位简历投递 1_100_035_000 ==========
+1_100_035_001=招聘职位简历投递不存在
+1_100_035_002=该职位已投递
+1_100_035_003=未选择简历附件
+1_100_035_004=招聘职位id不能为空
+1_100_035_005=该职位暂不允许投递
+1_100_035_006=该职位停止招聘
+1_100_035_007=简历附件标题不能为空
+1_100_035_008=简历附件地址不能为空
+1_100_035_009=投递的简历状态不能为空
+# ========== 众聘-简历投递 1_100_036_000 ==========
+1_100_036_001=投递简历不存在
+1_100_036_002=发布的职位id不能为空
+1_100_036_003=发布职位的用户id不能为空
+1_100_036_004=推荐人id不能为空
+1_100_036_005=投递用户id不能为空
+1_100_036_006=投递人名称不能为空
+1_100_036_007=投递人联系电话不能为空
+1_100_036_008=简历附件不能为空
+# ========== 众聘-佣金比例 1_100_037_000 ==========
+1_100_037_001=佣金比例不存在
+1_100_037_002=佣金比例不能为空
+1_100_037_003=佣金比例不能小于0
+# ========== 用户账户 1_100_038_000 ==========
+1_100_038_001=用户账户不存在

+ 0 - 0
menduner/menduner-mall-biz/src/main/resources/i18n/messages_zh_HK.properties


+ 76 - 0
menduner/menduner-mall-biz/src/main/resources/logback-spring.xml

@@ -0,0 +1,76 @@
+<configuration>
+    <!-- 引用 Spring Boot 的 logback 基础配置 -->
+    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
+    <!-- 变量 citu.info.base-package,基础业务包 -->
+    <springProperty scope="context" name="citu.info.base-package" source="citu.info.base-package"/>
+    <!-- 格式化输出:%d 表示日期,%X{tid} SkWalking 链路追踪编号,%thread 表示线程名,%-5level:级别从左显示 5 个字符宽度,%msg:日志消息,%n是换行符 -->
+    <property name="PATTERN_DEFAULT" value="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} | %highlight(${LOG_LEVEL_PATTERN:-%5p} ${PID:- }) | %boldYellow(%thread [%tid]) %boldGreen(%-40.40logger{39}) | %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
+
+    <!-- 控制台 Appender -->
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">     
+        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
+            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
+                <pattern>${PATTERN_DEFAULT}</pattern>
+            </layout>
+        </encoder>
+    </appender>
+
+    <!-- 文件 Appender -->
+    <!-- 参考 Spring Boot 的 file-appender.xml 编写 -->
+    <appender name="FILE"  class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
+            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
+                <pattern>${PATTERN_DEFAULT}</pattern>
+            </layout>
+        </encoder>
+        <!-- 日志文件名 -->
+        <file>${LOG_FILE}</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <!-- 滚动后的日志文件名 -->
+            <fileNamePattern>${LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN:-${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz}</fileNamePattern>
+            <!-- 启动服务时,是否清理历史日志,一般不建议清理 -->
+            <cleanHistoryOnStart>${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false}</cleanHistoryOnStart>
+            <!-- 日志文件,到达多少容量,进行滚动 -->
+            <maxFileSize>${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE:-10MB}</maxFileSize>
+            <!-- 日志文件的总大小,0 表示不限制 -->
+            <totalSizeCap>${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP:-0}</totalSizeCap>
+            <!-- 日志文件的保留天数 -->
+            <maxHistory>${LOGBACK_ROLLINGPOLICY_MAX_HISTORY:-30}</maxHistory>
+        </rollingPolicy>
+    </appender>
+    <!-- 异步写入日志,提升性能 -->
+    <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
+        <!-- 不丢失日志。默认的,如果队列的 80% 已满,则会丢弃 TRACT、DEBUG、INFO 级别的日志 -->
+        <discardingThreshold>0</discardingThreshold>
+        <!-- 更改默认的队列的深度,该值会影响性能。默认值为 256 -->
+        <queueSize>256</queueSize>
+        <appender-ref ref="FILE"/>
+    </appender>
+
+    <!-- SkyWalking GRPC 日志收集,实现日志中心。注意:SkyWalking 8.4.0 版本开始支持 -->
+    <appender name="GRPC" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
+        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
+            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
+                <pattern>${PATTERN_DEFAULT}</pattern>
+            </layout>
+        </encoder>
+    </appender>
+
+    <!-- 本地环境 -->
+    <springProfile name="local">
+        <root level="INFO">
+            <appender-ref ref="STDOUT"/>
+            <appender-ref ref="GRPC"/> <!-- 本地环境下,如果不想接入 SkyWalking 日志服务,可以注释掉本行 -->
+            <appender-ref ref="ASYNC"/>  <!-- 本地环境下,如果不想打印日志,可以注释掉本行 -->
+        </root>
+    </springProfile>
+    <!-- 其它环境 -->
+    <springProfile name="dev,test,stage,prod,default">
+        <root level="INFO">
+            <appender-ref ref="STDOUT"/>
+            <appender-ref ref="ASYNC"/>
+            <appender-ref ref="GRPC"/>
+        </root>
+    </springProfile>
+
+</configuration>

+ 60 - 0
menduner/menduner-mall-biz/src/test/resources/application-unit-test.yaml

@@ -0,0 +1,60 @@
+spring:
+  main:
+    lazy-initialization: true # 开启懒加载,加快速度
+    banner-mode: off # 单元测试,禁用 Banner
+
+--- #################### 数据库相关配置 ####################
+
+spring:
+  # 数据源配置项
+  datasource:
+    name: ruoyi-vue-pro
+    url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写
+    driver-class-name: org.h2.Driver
+    username: sa
+    password:
+    druid:
+      async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度
+      initial-size: 1 # 单元测试,配置为 1,提升启动速度
+  sql:
+    init:
+      schema-locations: classpath:/sql/create_tables.sql
+
+  # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
+  redis:
+    host: 127.0.0.1 # 地址
+    port: 16379 # 端口(单元测试,使用 16379 端口)
+    database: 0 # 数据库索引
+  # elasticsearch 配置项
+  elasticsearch:
+    uris: http://192.168.3.80:9200
+
+mybatis:
+  lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试
+
+mybatis-plus:
+  global-config:
+    db-config:
+      id-type: AUTO # H2 主键递增
+
+--- #################### 定时任务相关配置 ####################
+
+--- #################### 配置中心相关配置 ####################
+
+--- #################### 服务保障相关配置 ####################
+
+# Lock4j 配置项(单元测试,禁用 Lock4j)
+
+--- #################### 监控相关配置 ####################
+
+--- #################### 芋道相关配置 ####################
+
+# 芋道配置项,设置当前项目所有自定义的配置
+citu:
+  info:
+    base-package: com.citu.module
+  captcha:
+    timeout: 5m
+    width: 160
+    height: 60
+    enable: true

+ 4 - 0
menduner/menduner-mall-biz/src/test/resources/logback.xml

@@ -0,0 +1,4 @@
+<configuration>
+    <!-- 引用 Spring Boot 的 logback 基础配置 -->
+    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
+</configuration>

+ 32 - 0
menduner/menduner-mall-biz/src/test/resources/sql/clean.sql

@@ -0,0 +1,32 @@
+DELETE FROM "mde_area";
+DELETE FROM "mde_certificate";
+DELETE FROM "mde_user_skill";
+DELETE FROM "mde_work_exp";
+DELETE FROM "mde_user_certificate";
+DELETE FROM "mde_school";
+DELETE FROM "mde_position_tag";
+DELETE FROM "mde_major";
+DELETE FROM "mde_job_interested";
+DELETE FROM "mde_edu_exp";
+DELETE FROM "mde_cv_attachment";
+
+DELETE FROM "mde_user";
+DELETE FROM "mde_job_advertised";
+DELETE FROM "mde_enterprise";
+DELETE FROM "mde_enterprise_business";
+DELETE FROM "mde_enterprise_register";
+DELETE FROM "mde_enterprise_user_bind";
+DELETE FROM "mde_enterprise_post";
+DELETE FROM "mde_enterprise_user_look";
+DELETE FROM "mde_person_enterprise_attention";
+DELETE FROM "mde_person_browse_record";
+DELETE FROM "mde_person_job_collection";
+DELETE FROM "mde_train_exp";
+DELETE FROM "mde_project_exp";
+DELETE FROM "mde_skill";
+DELETE FROM "mde_enterprise_user_apply";
+DELETE FROM "mde_job_cv_rel";
+
+DELETE FROM "mde_hire_job_cv_rel";
+DELETE FROM "mde_hire_commission_ratio";
+DELETE FROM "mde_user_account";

+ 556 - 0
menduner/menduner-mall-biz/src/test/resources/sql/create_tables.sql

@@ -0,0 +1,556 @@
+CREATE TABLE IF NOT EXISTS "mde_area" (
+                                          "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+                                          "name" varchar,
+                                          "type" int,
+                                          "parent_id" bigint,
+                                          "creator" varchar DEFAULT '',
+                                          "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+                                          "updater" varchar DEFAULT '',
+                                          "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+                                          "deleted" bit NOT NULL DEFAULT FALSE,
+                                          "tenant_id" bigint NOT NULL DEFAULT 0,
+                                          PRIMARY KEY ("id")
+) COMMENT '地区表';
+  
+   CREATE TABLE IF NOT EXISTS "mde_certificate" (
+                                                    "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+                                                    "name_cn" varchar NOT NULL,
+                                                    "name_en" varchar,
+                                                    "parent_id" bigint NOT NULL,
+                                                    "level" bit,
+                                                    "creator" varchar DEFAULT '',
+                                                    "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+                                                    "updater" varchar DEFAULT '',
+                                                    "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+                                                    "deleted" bit NOT NULL DEFAULT FALSE,
+                                                    "tenant_id" bigint NOT NULL DEFAULT 0,
+                                                    PRIMARY KEY ("id")
+   ) COMMENT '证书表';
+  
+   CREATE TABLE IF NOT EXISTS "mde_user_skill" (
+                                                   "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+                                                   "user_id" bigint NOT NULL,
+                                                   "name" varchar,
+                                                   "level" int,
+                                                   "creator" varchar DEFAULT '',
+                                                   "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+                                                   "updater" varchar DEFAULT '',
+                                                   "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+                                                   "deleted" bit NOT NULL DEFAULT FALSE,
+                                                   "tenant_id" bigint NOT NULL DEFAULT 0,
+                                                   PRIMARY KEY ("id")
+   ) COMMENT '人才技能表';
+  
+   CREATE TABLE IF NOT EXISTS "mde_work_exp" (
+                                                 "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+                                                 "user_id" bigint NOT NULL,
+                                                 "enterprise_id" bigint,
+                                                 "enterprise_name" varchar,
+                                                 "industry_id" bigint,
+                                                 "dept_name" varchar,
+                                                 "position_id" bigint,
+                                                 "position_name" varchar,
+                                                 "start_time" varchar,
+                                                 "end_time" varchar,
+                                                 "content" varchar,
+                                                 "achievement" varchar,
+                                                 "pay" varchar,
+                                                 "pay_type" int,
+                                                 "currency_type" int,
+                                                 "skill_list" varchar,
+                                                 "creator" varchar DEFAULT '',
+                                                 "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+                                                 "updater" varchar DEFAULT '',
+                                                 "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+                                                 "deleted" bit NOT NULL DEFAULT FALSE,
+                                                 "tenant_id" bigint NOT NULL DEFAULT 0,
+                                                 PRIMARY KEY ("id")
+   ) COMMENT '工作经历表';
+  
+   CREATE TABLE IF NOT EXISTS "mde_user_certificate" (
+                                                         "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+                                                         "user_id" bigint NOT NULL,
+                                                         "certificate_id" bigint,
+                                                         "creator" varchar DEFAULT '',
+                                                         "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+                                                         "updater" varchar DEFAULT '',
+                                                         "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+                                                         "deleted" bit NOT NULL DEFAULT FALSE,
+                                                         "tenant_id" bigint NOT NULL DEFAULT 0,
+                                                         PRIMARY KEY ("id")
+   ) COMMENT '人才证书表';
+  
+   CREATE TABLE IF NOT EXISTS "mde_school" (
+                                               "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+                                               "name" varchar,
+                                               "area_id" bigint,
+                                               "address" varchar,
+                                               "longitude" varchar,
+                                               "latitude" varchar,
+                                               "status" int NOT NULL,
+                                               "creator" varchar DEFAULT '',
+                                               "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+                                               "updater" varchar DEFAULT '',
+                                               "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+                                               "deleted" bit NOT NULL DEFAULT FALSE,
+                                               "tenant_id" bigint NOT NULL DEFAULT 0,
+                                               PRIMARY KEY ("id")
+   ) COMMENT '学校表';
+  
+   CREATE TABLE IF NOT EXISTS "mde_position_tag" (
+                                                     "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+                                                     "position_id" bigint,
+                                                     "label" varchar,
+                                                     "creator" varchar DEFAULT '',
+                                                     "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+                                                     "updater" varchar DEFAULT '',
+                                                     "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+                                                     "deleted" bit NOT NULL DEFAULT FALSE,
+                                                     "tenant_id" bigint NOT NULL DEFAULT 0,
+                                                     PRIMARY KEY ("id")
+   ) COMMENT '职位标签表';
+  
+   CREATE TABLE IF NOT EXISTS "mde_major" (
+                                              "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+                                              "name_cn" varchar,
+                                              "name__en" varchar,
+                                              "status" int NOT NULL,
+                                              "creator" varchar DEFAULT '',
+                                              "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+                                              "updater" varchar DEFAULT '',
+                                              "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+                                              "deleted" bit NOT NULL DEFAULT FALSE,
+                                              "tenant_id" bigint NOT NULL DEFAULT 0,
+                                              PRIMARY KEY ("id")
+   ) COMMENT '专业表';
+  
+   CREATE TABLE IF NOT EXISTS "mde_job_interested" (
+                                                       "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+                                                       "user_id" bigint,
+                                                       "job_type" int,
+                                                       "position_id" bigint,
+                                                       "industry_id_list" varchar,
+                                                       "pay_min" varchar,
+                                                       "pay_max" varchar,
+                                                       "work_area_id" bigint,
+                                                       "interested_area_id_list" varchar,
+                                                       "creator" varchar DEFAULT '',
+                                                       "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+                                                       "updater" varchar DEFAULT '',
+                                                       "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+                                                       "deleted" bit NOT NULL DEFAULT FALSE,
+                                                       "tenant_id" bigint NOT NULL DEFAULT 0,
+                                                       PRIMARY KEY ("id")
+   ) COMMENT '求职意向表';
+  
+   CREATE TABLE IF NOT EXISTS "mde_edu_exp" (
+                                                "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+                                                "user_id" bigint,
+                                                "school_id" bigint,
+                                                "school_name" varchar,
+                                                "education_type" int,
+                                                "education_system_type" int,
+                                                "major_id" bigint,
+                                                "major" varchar,
+                                                "start_time" varchar,
+                                                "end_time" varchar,
+                                                "content" varchar,
+                                                "creator" varchar DEFAULT '',
+                                                "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+                                                "updater" varchar DEFAULT '',
+                                                "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+                                                "deleted" bit NOT NULL DEFAULT FALSE,
+                                                "tenant_id" bigint NOT NULL DEFAULT 0,
+                                                PRIMARY KEY ("id")
+   ) COMMENT '教育经历表';
+  
+   CREATE TABLE IF NOT EXISTS "mde_cv_attachment" (
+                                                      "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+                                                      "user_id" bigint,
+                                                      "title" varchar,
+                                                      "url" varchar,
+                                                      "creator" varchar DEFAULT '',
+                                                      "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+                                                      "updater" varchar DEFAULT '',
+                                                      "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+                                                      "deleted" bit NOT NULL DEFAULT FALSE,
+                                                      "tenant_id" bigint NOT NULL DEFAULT 0,
+                                                      PRIMARY KEY ("id")
+   ) COMMENT '简历附件表';
+
+CREATE TABLE IF NOT EXISTS "mde_user" (
+                                          "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+                                          "username" varchar NOT NULL,
+                                          "password" varchar NOT NULL,
+                                          "email" varchar,
+                                          "phone" varchar,
+                                          "avatar" varchar,
+                                          "status" int NOT NULL,
+                                          "register_ip" varchar,
+                                          "register_terminal" varchar,
+                                          "login_ip" varchar,
+                                          "login_date" varchar,
+                                          "creator" varchar DEFAULT '',
+                                          "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+                                          "updater" varchar DEFAULT '',
+                                          "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+                                          "deleted" bit NOT NULL DEFAULT FALSE,
+                                          "tenant_id" bigint NOT NULL,
+                                          PRIMARY KEY ("id")
+) COMMENT '用户登录表';
+
+CREATE TABLE IF NOT EXISTS "mde_job_advertised" (
+                                                    "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+                                                    "enterprise_id" bigint NOT NULL,
+                                                    "user_id" bigint NOT NULL,
+                                                    "area_id" bigint NOT NULL,
+                                                    "name" varchar NOT NULL,
+                                                    "position_id" bigint NOT NULL,
+                                                    "type" int NOT NULL,
+                                                    "exp_type" int NOT NULL,
+                                                    "edu_type" int NOT NULL,
+                                                    "pay_from" int,
+                                                    "pay_to" int,
+                                                    "tag_list" varchar,
+                                                    "content" varchar,
+                                                    "requirement" varchar,
+                                                    "address" varchar,
+                                                    "longitude" varchar,
+                                                    "latitude" varchar,
+                                                    "status" int,
+                                                    "creator" varchar DEFAULT '',
+                                                    "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+                                                    "updater" varchar DEFAULT '',
+                                                    "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+                                                    "deleted" bit NOT NULL DEFAULT FALSE,
+                                                    "tenant_id" bigint NOT NULL,
+                                                    PRIMARY KEY ("id")
+) COMMENT '招聘职位表';
+
+CREATE TABLE IF NOT EXISTS "mde_enterprise" (
+                                                "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+                                                "name" varchar,
+                                                "another_name" varchar,
+                                                "website" varchar,
+                                                "introduce" varchar,
+                                                "contact" varchar,
+                                                "phone" varchar,
+                                                "logo_url" varchar,
+                                                "industry_id" bigint,
+                                                "financing_status" int,
+                                                "scale" int,
+                                                "welfare_list" varchar,
+                                                "album_list" varchar,
+                                                "work_time" varchar,
+                                                "develop_history" varchar,
+                                                "received_honors" varchar,
+                                                "creator" varchar DEFAULT '',
+                                                "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+                                                "updater" varchar DEFAULT '',
+                                                "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+                                                "deleted" bit NOT NULL DEFAULT FALSE,
+                                                "tenant_id" bigint NOT NULL,
+                                                PRIMARY KEY ("id")
+) COMMENT '企业信息表';
+
+CREATE TABLE IF NOT EXISTS "mde_enterprise_business" (
+                                                         "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+                                                         "enterprise_id" bigint,
+                                                         "code" varchar,
+                                                         "name" varchar,
+                                                         "type" varchar,
+                                                         "area" varchar,
+                                                         "address" varchar,
+                                                         "representative" varchar,
+                                                         "establishment_time" varchar,
+                                                         "registered_capital" varchar,
+                                                         "approval_time" varchar,
+                                                         "former_name" varchar,
+                                                         "industry" varchar,
+                                                         "registration_authority" varchar,
+                                                         "business_status" varchar,
+                                                         "business_term" varchar,
+                                                         "business_scope" varchar,
+                                                         "creator" varchar DEFAULT '',
+                                                         "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+                                                         "updater" varchar DEFAULT '',
+                                                         "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+                                                         "deleted" bit NOT NULL DEFAULT FALSE,
+                                                         "tenant_id" bigint NOT NULL,
+                                                         PRIMARY KEY ("id")
+) COMMENT '企业工商信息表';
+
+CREATE TABLE IF NOT EXISTS "mde_enterprise_register" (
+                                                         "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+                                                         "user_id" bigint,
+                                                         "name" varchar,
+                                                         "phone" varchar,
+                                                         "email" varchar,
+                                                         "business_license_url" varchar,
+                                                         "status" int NOT NULL,
+                                                         "reason" varchar,
+                                                         "remark" varchar,
+                                                         "creator" varchar DEFAULT '',
+                                                         "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+                                                         "updater" varchar DEFAULT '',
+                                                         "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+                                                         "deleted" bit NOT NULL DEFAULT FALSE,
+                                                         "tenant_id" bigint NOT NULL,
+                                                         PRIMARY KEY ("id")
+) COMMENT '企业注册申请表';
+
+CREATE TABLE IF NOT EXISTS "mde_enterprise_address" (
+                                                        "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+                                                        "enterprise_id" bigint,
+                                                        "address" varchar,
+                                                        "longitude" varchar,
+                                                        "latitude" varchar,
+                                                        "creator" varchar DEFAULT '',
+                                                        "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+                                                        "updater" varchar DEFAULT '',
+                                                        "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+                                                        "deleted" bit NOT NULL DEFAULT FALSE,
+                                                        "tenant_id" bigint NOT NULL,
+                                                        PRIMARY KEY ("id")
+) COMMENT '企业地址表';
+
+CREATE TABLE IF NOT EXISTS "mde_enterprise_user_bind" (
+    "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    "enterprise_id" bigint NOT NULL,
+    "user_id" varchar NOT NULL,
+    "status" int NOT NULL,
+    "login_ip" varchar,
+    "login_date" varchar,
+    "user_type" int,
+    "creator" varchar DEFAULT '',
+    "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "updater" varchar DEFAULT '',
+    "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+    "deleted" bit NOT NULL DEFAULT FALSE,
+    "tenant_id" bigint NOT NULL,
+    PRIMARY KEY ("id")
+) COMMENT '企业登录用户表';
+
+-- 将该建表 SQL 语句,添加到 citu-module-menduner.system-biz 模块的 test/resources/sql/create_tables.sql 文件里
+CREATE TABLE IF NOT EXISTS "mde_enterprise_post" (
+    "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    "enterprise_id" bigint,
+    "code" varchar,
+    "name_cn" varchar NOT NULL,
+    "name_en" varchar NOT NULL,
+    "sort" int NOT NULL,
+    "status" int NOT NULL,
+    "remark" varchar,
+    "creator" varchar DEFAULT '',
+    "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "updater" varchar DEFAULT '',
+    "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+    "deleted" bit NOT NULL DEFAULT FALSE,
+    "tenant_id" bigint NOT NULL,
+    PRIMARY KEY ("id")
+) COMMENT '企业岗位信息表';
+
+-- 将该建表 SQL 语句,添加到 citu-module-menduner.system-biz 模块的 test/resources/sql/create_tables.sql 文件里
+CREATE TABLE IF NOT EXISTS "mde_enterprise_user_look" (
+    "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    "enterprise_id" bigint,
+    "user_id" bigint NOT NULL,
+    "user_name" varchar,
+    "user_post_name" varchar,
+    "look_user_id" bigint,
+    "creator" varchar DEFAULT '',
+    "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "updater" varchar DEFAULT '',
+    "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+    "deleted" bit NOT NULL DEFAULT FALSE,
+    "tenant_id" bigint NOT NULL,
+    PRIMARY KEY ("id")
+) COMMENT '门墩儿 - 企业招聘者浏览表';
+
+CREATE TABLE IF NOT EXISTS "mde_person_enterprise_attention" (
+    "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    "user_id" bigint,
+    "enterprise_id" bigint,
+    "creator" varchar DEFAULT '',
+    "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "updater" varchar DEFAULT '',
+    "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+    "deleted" bit NOT NULL DEFAULT FALSE,
+    "tenant_id" bigint NOT NULL,
+    PRIMARY KEY ("id")
+) COMMENT '人才-企业关注订阅表';
+
+CREATE TABLE IF NOT EXISTS "mde_person_browse_record" (
+    "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    "user_id" bigint NOT NULL,
+    "job_id" bigint NOT NULL,
+    "area_id" bigint,
+    "position_id" bigint,
+    "enterprise_id" bigint,
+    "area_name" varchar,
+    "job_name" varchar,
+    "type" int,
+    "exp_type" int,
+    "edu_type" int,
+    "pay_from" varchar,
+    "pay_to" varchar,
+    "pay_unit" int,
+    "currency_type" int,
+    "tag_list" varchar NOT NULL,
+    "contact_user_id" bigint,
+    "contact_user_name" varchar,
+    "contact_user_post_name" varchar,
+    "enterprise_name" varchar,
+    "industry_id" bigint,
+    "financing_status" int,
+    "scale" int,
+    "creator" varchar DEFAULT '',
+    "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "updater" varchar DEFAULT '',
+    "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+    "deleted" bit NOT NULL DEFAULT FALSE,
+    "tenant_id" bigint NOT NULL,
+    PRIMARY KEY ("id")
+) COMMENT '人才-浏览记录';
+
+CREATE TABLE IF NOT EXISTS "mde_person_job_collection" (
+    "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    "user_id" bigint,
+    "job_id" bigint,
+    "creator" varchar DEFAULT '',
+    "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "updater" varchar DEFAULT '',
+    "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+    "deleted" bit NOT NULL DEFAULT FALSE,
+    "tenant_id" bigint NOT NULL,
+    PRIMARY KEY ("id")
+) COMMENT '人才-招聘职位收藏表';
+
+CREATE TABLE IF NOT EXISTS "mde_train_exp" (
+    "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    "user_id" bigint,
+    "start_time" varchar,
+    "end_time" varchar,
+    "org_name" varchar,
+    "course" varchar,
+    "content" varchar,
+    "creator" varchar DEFAULT '',
+    "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "updater" varchar DEFAULT '',
+    "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+    "deleted" bit NOT NULL DEFAULT FALSE,
+    PRIMARY KEY ("id")
+) COMMENT '培训经历表';
+
+CREATE TABLE IF NOT EXISTS "mde_project_exp" (
+    "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    "user_id" bigint,
+    "name" varchar,
+    "start_time" varchar,
+    "end_time" varchar,
+    "content" varchar,
+    "creator" varchar DEFAULT '',
+    "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "updater" varchar DEFAULT '',
+    "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+    "deleted" bit NOT NULL DEFAULT FALSE,
+    PRIMARY KEY ("id")
+) COMMENT '项目经历表';
+
+CREATE TABLE IF NOT EXISTS "mde_skill" (
+    "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    "name_cn" varchar,
+    "name_en" varchar,
+    "parent_id" bigint,
+    "level" bit,
+    "creator" varchar DEFAULT '',
+    "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "updater" varchar DEFAULT '',
+    "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+    "deleted" bit NOT NULL DEFAULT FALSE,
+    "tenant_id" bigint NOT NULL,
+    PRIMARY KEY ("id")
+) COMMENT '职业技能表';
+
+CREATE TABLE IF NOT EXISTS "mde_enterprise_user_apply" (
+    "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    "user_id" bigint NOT NULL,
+    "enterprise_id" bigint NOT NULL,
+    "post_id" bigint,
+    "name" varchar,
+    "status" varchar NOT NULL,
+    "reason" varchar,
+    "remark" varchar,
+    "creator" varchar DEFAULT '',
+    "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "updater" varchar DEFAULT '',
+    "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+    "deleted" bit NOT NULL DEFAULT FALSE,
+    "tenant_id" bigint NOT NULL,
+    PRIMARY KEY ("id")
+) COMMENT '企业用户申请';
+
+CREATE TABLE IF NOT EXISTS "mde_job_cv_rel" (
+    "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    "enterprise_id" bigint NOT NULL,
+    "job_id" bigint NOT NULL,
+    "publish_user_id" bigint NOT NULL,
+    "user_id" bigint NOT NULL,
+    "title" varchar NOT NULL,
+    "url" varchar NOT NULL,
+    "status" varchar NOT NULL,
+    "creator" varchar DEFAULT '',
+    "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "updater" varchar DEFAULT '',
+    "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+    "deleted" bit NOT NULL DEFAULT FALSE,
+    "tenant_id" bigint NOT NULL,
+    PRIMARY KEY ("id")
+) COMMENT '招聘职位简历投递表';
+
+CREATE TABLE IF NOT EXISTS "mde_hire_job_cv_rel" (
+    "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    "enterprise_id" bigint NOT NULL,
+    "job_id" bigint NOT NULL,
+    "publish_user_id" bigint NOT NULL,
+    "recommend_user_id" bigint NOT NULL,
+    "user_id" bigint NOT NULL,
+    "name" varchar,
+    "phone" varchar,
+    "url" varchar NOT NULL,
+    "status" varchar NOT NULL,
+    "creator" varchar DEFAULT '',
+    "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "updater" varchar DEFAULT '',
+    "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+    "deleted" bit NOT NULL DEFAULT FALSE,
+    "tenant_id" bigint NOT NULL,
+    PRIMARY KEY ("id")
+) COMMENT '门墩儿-众聘-简历投递表';
+
+CREATE TABLE IF NOT EXISTS "mde_hire_commission_ratio" (
+    "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    "enterprise_id" bigint NOT NULL,
+    "user_id" varchar NOT NULL,
+    "rate" varchar,
+    "creator" varchar DEFAULT '',
+    "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "updater" varchar DEFAULT '',
+    "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+    "deleted" bit NOT NULL DEFAULT FALSE,
+    "tenant_id" bigint NOT NULL,
+    PRIMARY KEY ("id")
+) COMMENT '门墩儿-众聘-佣金比例表';
+
+CREATE TABLE IF NOT EXISTS "mde_user_account" (
+    "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    "user_id" varchar NOT NULL,
+    "balance" varchar,
+    "creator" varchar DEFAULT '',
+    "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "updater" varchar DEFAULT '',
+    "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+    "deleted" bit NOT NULL DEFAULT FALSE,
+    "tenant_id" bigint NOT NULL,
+    PRIMARY KEY ("id")
+) COMMENT '门墩儿-用户账户表';

+ 56 - 0
menduner/menduner-reward-biz/src/main/java/com/citu/module/menduner/reward/controller/base/auth/vo/AppAuthLoginReqVO.java

@@ -0,0 +1,56 @@
+package com.citu.module.menduner.reward.controller.base.auth.vo;
+
+import cn.hutool.core.util.StrUtil;
+import com.citu.framework.common.validation.InEnum;
+import com.citu.framework.common.validation.Mobile;
+import com.citu.module.system.enums.social.SocialTypeEnum;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.AssertTrue;
+import javax.validation.constraints.NotEmpty;
+
+@Schema(description = "用户 APP - 手机 + 密码登录 Request VO,如果登录并绑定社交用户,需要传递 social 开头的参数")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class AppAuthLoginReqVO {
+
+    @Schema(description = "手机号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15601691300")
+    @NotEmpty(message = "手机号不能为空")
+    @Mobile
+    private String mobile;
+
+    @Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "buzhidao")
+    @NotEmpty(message = "密码不能为空")
+    @Length(min = 4, max = 16, message = "密码长度为 4-16 位")
+    private String password;
+
+    // ========== 绑定社交登录时,需要传递如下参数 ==========
+
+    @Schema(description = "社交平台的类型,参见 SocialTypeEnum 枚举值", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
+    @InEnum(SocialTypeEnum.class)
+    private Integer socialType;
+
+    @Schema(description = "授权码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    private String socialCode;
+
+    @Schema(description = "state", requiredMode = Schema.RequiredMode.REQUIRED, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62")
+    private String socialState;
+
+    @AssertTrue(message = "授权码不能为空")
+    public boolean isSocialCodeValid() {
+        return socialType == null || StrUtil.isNotEmpty(socialCode);
+    }
+
+    @AssertTrue(message = "授权 state 不能为空")
+    public boolean isSocialState() {
+        return socialType == null || StrUtil.isNotEmpty(socialState);
+    }
+
+}

+ 38 - 0
menduner/menduner-reward-biz/src/main/java/com/citu/module/menduner/reward/controller/base/auth/vo/AppAuthLoginRespVO.java

@@ -0,0 +1,38 @@
+package com.citu.module.menduner.reward.controller.base.auth.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "用户 APP - 登录 Response VO")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class AppAuthLoginRespVO {
+
+    @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    private Long userId;
+
+    @Schema(description = "访问令牌", requiredMode = Schema.RequiredMode.REQUIRED, example = "happy")
+    private String accessToken;
+
+    @Schema(description = "刷新令牌", requiredMode = Schema.RequiredMode.REQUIRED, example = "nice")
+    private String refreshToken;
+
+    @Schema(description = "过期时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    private LocalDateTime expiresTime;
+
+    /**
+     * 仅社交登录、社交绑定时会返回
+     *
+     * 为什么需要返回?微信公众号、微信小程序支付需要传递 openid 给支付接口
+     */
+    @Schema(description = "社交用户 openid", example = "qq768")
+    private String openid;
+
+}

+ 58 - 0
menduner/menduner-reward-biz/src/main/java/com/citu/module/menduner/reward/controller/base/auth/vo/AppAuthSmsLoginReqVO.java

@@ -0,0 +1,58 @@
+package com.citu.module.menduner.reward.controller.base.auth.vo;
+
+import cn.hutool.core.util.StrUtil;
+import com.citu.framework.common.validation.InEnum;
+import com.citu.framework.common.validation.Mobile;
+import com.citu.module.system.enums.social.SocialTypeEnum;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.AssertTrue;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.Pattern;
+
+@Schema(description = "用户 APP - 手机 + 验证码登录 Request VO,如果登录并绑定社交用户,需要传递 social 开头的参数")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class AppAuthSmsLoginReqVO {
+
+    @Schema(description = "手机号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15601691300")
+    @NotEmpty(message = "手机号不能为空")
+    @Mobile
+    private String mobile;
+
+    @Schema(description = "手机验证码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    @NotEmpty(message = "手机验证码不能为空")
+    @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位")
+    @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字")
+    private String code;
+
+    // ========== 绑定社交登录时,需要传递如下参数 ==========
+
+    @Schema(description = "社交平台的类型,参见 SocialTypeEnum 枚举值", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
+    @InEnum(SocialTypeEnum.class)
+    private Integer socialType;
+
+    @Schema(description = "授权码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    private String socialCode;
+
+    @Schema(description = "state", requiredMode = Schema.RequiredMode.REQUIRED, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62")
+    private String socialState;
+
+    @AssertTrue(message = "授权码不能为空")
+    public boolean isSocialCodeValid() {
+        return socialType == null || StrUtil.isNotEmpty(socialCode);
+    }
+
+    @AssertTrue(message = "授权 state 不能为空")
+    public boolean isSocialState() {
+        return socialType == null || StrUtil.isNotEmpty(socialState);
+    }
+
+}

+ 2 - 0
menduner/pom.xml

@@ -20,6 +20,8 @@
         <module>menduner-reward-biz</module>
         <module>menduner-im-api</module>
         <module>menduner-im-biz</module>
+        <module>menduner-mall-api</module>
+        <module>menduner-mall-biz</module>
     </modules>
     <description>
         门墩儿相关