commit 3af22ea7dd8522cb5eb9d92b5565b74a3b31cfea
Author: tianea <tianxyy80@gmail.com>
Date:   Wed Feb 16 10:45:36 2022 +0800

    first commit

diff --git a/backend/._readme.txt b/backend/._readme.txt
new file mode 100644
index 0000000..093bf05
Binary files /dev/null and b/backend/._readme.txt differ
diff --git a/backend/readme.txt b/backend/readme.txt
new file mode 100644
index 0000000..8d257bf
--- /dev/null
+++ b/backend/readme.txt
@@ -0,0 +1 @@
+后台管理
\ No newline at end of file
diff --git a/front/._readme.txt b/front/._readme.txt
new file mode 100644
index 0000000..872f619
Binary files /dev/null and b/front/._readme.txt differ
diff --git a/front/readme.txt b/front/readme.txt
new file mode 100644
index 0000000..0fe5825
--- /dev/null
+++ b/front/readme.txt
@@ -0,0 +1 @@
+学生端
\ No newline at end of file
diff --git a/tz/.gitignore b/tz/.gitignore
new file mode 100644
index 0000000..ad52113
--- /dev/null
+++ b/tz/.gitignore
@@ -0,0 +1,55 @@
+# Created by .ignore support plugin (hsz.mobi)
+### Java template
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+### macOS template
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+.idea
+*.iml
diff --git a/tz/common/common-core/pom.xml b/tz/common/common-core/pom.xml
new file mode 100644
index 0000000..b2d7ba5
--- /dev/null
+++ b/tz/common/common-core/pom.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>common</artifactId>
+        <groupId>com.tz</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>common-core</artifactId>
+
+    <dependencies>
+        <!-- hutool -->
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.3.8</version>
+        </dependency>
+
+        <!-- jwt -->
+        <dependency>
+            <groupId>com.auth0</groupId>
+            <artifactId>java-jwt</artifactId>
+            <version>3.10.3</version>
+        </dependency>
+
+        <!-- excel -->
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+            <version>3.17</version>
+        </dependency>
+
+        <!-- ECharts -->
+        <dependency>
+            <groupId>com.github.abel533</groupId>
+            <artifactId>ECharts</artifactId>
+            <version>3.0.0.6</version>
+        </dependency>
+
+        <!-- jsoup -->
+        <dependency>
+            <groupId>org.jsoup</groupId>
+            <artifactId>jsoup</artifactId>
+            <version>1.14.2</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>itextpdf</artifactId>
+            <version>5.5.13.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.spring4all</groupId>
+            <artifactId>swagger-spring-boot-starter</artifactId>
+            <version>1.9.1.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>com.github.xiaoymin</groupId>
+            <artifactId>knife4j-spring-ui</artifactId>
+            <version>2.0.7</version>
+        </dependency>
+
+        <!-- org.apache.httpcomponents -->
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpmime</artifactId>
+        </dependency>
+
+        <!-- log -->
+        <dependency>
+            <groupId>net.logstash.logback</groupId>
+            <artifactId>logstash-logback-encoder</artifactId>
+            <version>6.4</version>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>log4j-over-slf4j</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl-over-slf4j</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jul-to-slf4j</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+        <!-- org.apache.httpcomponents -->
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpmime</artifactId>
+        </dependency>
+        <!-- web -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/tz/common/common-core/src/main/java/com/tz/platform/common/core/base/Base.java b/tz/common/common-core/src/main/java/com/tz/platform/common/core/base/Base.java
new file mode 100644
index 0000000..bd4296b
--- /dev/null
+++ b/tz/common/common-core/src/main/java/com/tz/platform/common/core/base/Base.java
@@ -0,0 +1,38 @@
+package com.tz.platform.common.core.base;
+
+import cn.hutool.json.JSONUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+public class Base {
+    protected static final String REGEX_MOBILE = "^((13[0-9])|(14[5,7,9])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199)\\d{8}$";// 手机号码校验
+
+    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    protected static final ExecutorService callbackExecutor = Executors.newFixedThreadPool(50);
+
+    public final static Integer FREEZE = 3;// 冻结状态
+
+    public final static BigDecimal LECTURER_DEFAULT_PROPORTION = BigDecimal.valueOf(0.70); // 讲师默认分成
+
+    public static String getString(Map<String, Object> map, String key) {
+        if (null != map.get(key)) {
+            return map.get(key).toString();
+        }
+        return "";
+    }
+
+    public static Map<String, Object> getMap() {
+        return new HashMap<>();
+    }
+
+    public void log(Object obj) {
+        logger.info(JSONUtil.toJsonPrettyStr(obj));
+    }
+}
diff --git a/tz/common/common-core/src/main/java/com/tz/platform/common/core/base/BaseException.java b/tz/common/common-core/src/main/java/com/tz/platform/common/core/base/BaseException.java
new file mode 100644
index 0000000..3a71350
--- /dev/null
+++ b/tz/common/common-core/src/main/java/com/tz/platform/common/core/base/BaseException.java
@@ -0,0 +1,39 @@
+package com.tz.platform.common.core.base;
+
+import com.tz.platform.common.core.enmus.ResultEnum;
+
+public class BaseException  extends RuntimeException {
+    /**
+     * 异常码
+     */
+    protected int code;
+
+    public BaseException() {
+        super("系统异常");
+        this.code = 99;
+    }
+
+    public BaseException(ResultEnum resultEnum) {
+        super(resultEnum.getDesc());
+        this.code = resultEnum.getCode();
+    }
+
+    public BaseException(String message) {
+        super(message);
+        this.code = 99;
+    }
+
+    public BaseException(int code, String message) {
+        super(message);
+        this.code = code;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+}
diff --git a/tz/common/common-core/src/main/java/com/tz/platform/common/core/base/Result.java b/tz/common/common-core/src/main/java/com/tz/platform/common/core/base/Result.java
new file mode 100644
index 0000000..1939bf4
--- /dev/null
+++ b/tz/common/common-core/src/main/java/com/tz/platform/common/core/base/Result.java
@@ -0,0 +1,86 @@
+package com.tz.platform.common.core.base;
+
+import com.tz.platform.common.core.enmus.ResultEnum;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Serializable;
+
+public class Result<T extends Serializable> implements Serializable {
+    private static final Logger logger = LoggerFactory.getLogger(Result.class);
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 错误码
+     */
+    private Integer code = ResultEnum.ERROR.getCode();
+
+    /**
+     * 错误信息
+     */
+    private String msg = null;
+
+    /**
+     * 返回结果实体
+     */
+    private T data = null;
+
+    public Result() {
+    }
+
+    private Result(int code, String msg, T data) {
+        this.code = code;
+        this.msg = msg;
+        this.data = data;
+    }
+
+    public static <T extends Serializable> Result<T> error(String msg) {
+        logger.debug("返回错误:code={}, msg={}", ResultEnum.ERROR.getCode(), msg);
+        return new Result<T>(ResultEnum.ERROR.getCode(), msg, null);
+    }
+
+    public static <T extends Serializable> Result<T> error(ResultEnum resultEnum) {
+        logger.debug("返回错误:code={}, msg={}", resultEnum.getCode(), resultEnum.getDesc());
+        return new Result<T>(resultEnum.getCode(), resultEnum.getDesc(), null);
+    }
+
+    public static <T extends Serializable> Result<T> error(int code, String msg) {
+        logger.debug("返回错误:code={}, msg={}", code, msg);
+        return new Result<T>(code, msg, null);
+    }
+
+    public static <T extends Serializable> Result<T> success(T data) {
+        return new Result<T>(ResultEnum.SUCCESS.getCode(), "", data);
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+
+    @Override
+    public String toString() {
+        return "Result [code=" + code + ", msg=" + msg + ", data=" + data + "]";
+    }
+
+}
diff --git a/tz/common/common-core/src/main/java/com/tz/platform/common/core/config/SystemUtil.java b/tz/common/common-core/src/main/java/com/tz/platform/common/core/config/SystemUtil.java
new file mode 100644
index 0000000..0ed47c0
--- /dev/null
+++ b/tz/common/common-core/src/main/java/com/tz/platform/common/core/config/SystemUtil.java
@@ -0,0 +1,27 @@
+package com.tz.platform.common.core.config;
+
+import java.io.IOException;
+import java.util.Properties;
+
+public class SystemUtil {
+    private SystemUtil() {
+    }
+
+    private static final Properties properties = new Properties();
+
+    static {
+        try {
+            properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("system.properties"));
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private static String getProperty(String keyName) {
+        return properties.getProperty(keyName, "").trim();
+    }
+
+    public static final String PIC_PATH = getProperty("pic_path");
+
+
+}
diff --git a/tz/common/common-core/src/main/java/com/tz/platform/common/core/enmus/LoginStatusEnum.java b/tz/common/common-core/src/main/java/com/tz/platform/common/core/enmus/LoginStatusEnum.java
new file mode 100644
index 0000000..96d9571
--- /dev/null
+++ b/tz/common/common-core/src/main/java/com/tz/platform/common/core/enmus/LoginStatusEnum.java
@@ -0,0 +1,19 @@
+package com.tz.platform.common.core.enmus;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum LoginStatusEnum {
+    SUCCESS(1, "登录成功", ""),
+    //
+    FAIL(0, "登录失败", "red");
+
+    private Integer code;
+
+    private String desc;
+
+    private String color;
+
+}
diff --git a/tz/common/common-core/src/main/java/com/tz/platform/common/core/enmus/RedisPreEnum.java b/tz/common/common-core/src/main/java/com/tz/platform/common/core/enmus/RedisPreEnum.java
new file mode 100644
index 0000000..d34241b
--- /dev/null
+++ b/tz/common/common-core/src/main/java/com/tz/platform/common/core/enmus/RedisPreEnum.java
@@ -0,0 +1,14 @@
+package com.tz.platform.common.core.enmus;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum  RedisPreEnum {
+    ADMINI_MENU("admini_menu_", "管理员菜单-admini_menu_");
+    private String code;
+
+    private String desc;
+
+}
diff --git a/tz/common/common-core/src/main/java/com/tz/platform/common/core/enmus/ResultEnum.java b/tz/common/common-core/src/main/java/com/tz/platform/common/core/enmus/ResultEnum.java
new file mode 100644
index 0000000..22fd120
--- /dev/null
+++ b/tz/common/common-core/src/main/java/com/tz/platform/common/core/enmus/ResultEnum.java
@@ -0,0 +1,40 @@
+package com.tz.platform.common.core.enmus;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum ResultEnum {
+    // 成功
+    SUCCESS(200, "成功"),
+
+    // token异常
+    TOKEN_PAST(301, "token过期"), TOKEN_ERROR(302, "token异常"),
+    // 登录异常
+    LOGIN_ERROR(303, "登录异常"), REMOTE_ERROR(304, "异地登录"),
+
+    MENU_PAST(305, "菜单过期"), MENU_NO(306, "没此权限,请联系管理员!"),
+
+    // 课程异常,4开头
+    COURSE_SAVE_FAIL(403, "添加失败"), COURSE_UPDATE_FAIL(404, "更新失败"), COURSE_DELETE_FAIL(405, "删除失败"),
+    //
+    COLLECTION(406, "已收藏"), USER_ADVICE(406, "保存建议失败,不能重复提建议"), COURSE_AUDIT_FAIL(407, "审核失败"),
+
+    // 用户异常,5开头
+    LECTURER_REQUISITION_REGISTERED(501, "申请失败!该手机没注册,请先注册账号"), LECTURER_REQUISITION_WAIT(502, "申请失败!该账号已提交申请入驻成为讲师,待审核中,在7个工作日内会有相关人员与您联系确认"), LECTURER_REQUISITION_YET(503, "申请失败!该账号已成为讲师,请直接登录"),
+    //
+    USER_SAVE_FAIL(504, "添加失败"), USER_UPDATE_FAIL(505, "更新失败"), LECTURER_REQUISITION_FAIL(506, "申请失败!该账号已提交申请入驻成为讲师,审核不通过,请联系平台管理员"), USER_LECTURER_AUDIT(507, "审核失败"), USER_SEND_FAIL(508, "发送失败"),
+    USER_DELETE_FAIL(509, "删除失败"),
+
+    // 系統异常,6开头
+    SYSTEM_SAVE_FAIL(601, "添加失败"), SYSTEM_UPDATE_FAIL(602, "更新失败"), SYSTEM_DELETE_FAIL(603, "删除失败"),
+
+    // 错误
+    ERROR(999, "错误");
+
+    private Integer code;
+
+    private String desc;
+
+}
diff --git a/tz/common/common-core/src/main/java/com/tz/platform/common/core/enmus/UserTypeEnum.java b/tz/common/common-core/src/main/java/com/tz/platform/common/core/enmus/UserTypeEnum.java
new file mode 100644
index 0000000..2b91fc1
--- /dev/null
+++ b/tz/common/common-core/src/main/java/com/tz/platform/common/core/enmus/UserTypeEnum.java
@@ -0,0 +1,14 @@
+package com.tz.platform.common.core.enmus;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum UserTypeEnum {
+    USER(1, "用户"), TEACHER(2, "教师") ,ADMIN(3,"管理员");
+
+    private Integer code;
+
+    private String desc;
+}
diff --git a/tz/common/common-core/src/main/java/com/tz/platform/common/core/tools/BeanUtils.java b/tz/common/common-core/src/main/java/com/tz/platform/common/core/tools/BeanUtils.java
new file mode 100644
index 0000000..342fc60
--- /dev/null
+++ b/tz/common/common-core/src/main/java/com/tz/platform/common/core/tools/BeanUtils.java
@@ -0,0 +1,61 @@
+package com.tz.platform.common.core.tools;
+
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class BeanUtils<T extends Serializable> {
+    private BeanUtils() {
+    }
+
+    /**
+     * @param source
+     * @param clazz
+     * @return
+     * @throws IllegalAccessException
+     * @throws InvocationTargetException
+     * @throws InstantiationException
+     */
+    public static <T> T copyProperties(Object source, Class<T> clazz) {
+        if (source == null) {
+            return null;
+        }
+        T t = null;
+        try {
+            t = clazz.newInstance();
+            org.springframework.beans.BeanUtils.copyProperties(source, t);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return t;
+    }
+
+    /**
+     * @param source
+     * @param clazz
+     * @return
+     * @throws IllegalAccessException
+     * @throws InvocationTargetException
+     * @throws InstantiationException
+     */
+    public static <T> List<T> copyProperties(List<?> source, Class<T> clazz) {
+        if (source == null || source.size() == 0) {
+            return Collections.emptyList();
+        }
+        List<T> res = new ArrayList<>(source.size());
+        for (Object o : source) {
+            T t = null;
+            try {
+                t = clazz.newInstance();
+                org.springframework.beans.BeanUtils.copyProperties(o, t);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            res.add(t);
+        }
+        return res;
+    }
+}
diff --git a/tz/common/common-core/src/main/java/com/tz/platform/common/core/tools/HttpUtil.java b/tz/common/common-core/src/main/java/com/tz/platform/common/core/tools/HttpUtil.java
new file mode 100644
index 0000000..fa6da71
--- /dev/null
+++ b/tz/common/common-core/src/main/java/com/tz/platform/common/core/tools/HttpUtil.java
@@ -0,0 +1,100 @@
+package com.tz.platform.common.core.tools;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HTTP;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.client.SimpleClientHttpRequestFactory;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class HttpUtil {
+    private static final String APPLICATION_JSON = "application/json";
+    private static final String CONTENT_TYPE_TEXT_JSON = "text/json";
+    private static final String CHARSET_UTF_8 = "UTF-8";
+    private static final int TIMEOUT = 10000;
+
+    private HttpUtil() {
+    }
+
+    private static final Logger logger = LoggerFactory.getLogger(HttpUtil.class);
+
+    private static SimpleClientHttpRequestFactory requestFactory = null;
+
+    static {
+        requestFactory = new SimpleClientHttpRequestFactory();
+        requestFactory.setConnectTimeout(60000); // 连接超时时间,单位=毫秒
+        requestFactory.setReadTimeout(60000); // 读取超时时间,单位=毫秒
+    }
+
+    private static RestTemplate restTemplate = new RestTemplate(requestFactory);
+
+    public static JsonNode postForObject(String url, Map<String, Object> map) {
+        logger.info("POST 请求, url={},map={}", url, map.toString());
+        return restTemplate.postForObject(url, map, JsonNode.class);
+    }
+
+    /**
+     * @param url
+     * @param param
+     * @return
+     */
+    public static String postForPay(String url, Map<String, Object> param) {
+        logger.info("POST 请求, url={},map={}", url, param.toString());
+        try {
+            HttpPost httpPost = new HttpPost(url.trim());
+            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(TIMEOUT).setConnectionRequestTimeout(TIMEOUT).setSocketTimeout(TIMEOUT).build();
+            httpPost.setConfig(requestConfig);
+            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
+            for (Map.Entry<String, Object> entry : param.entrySet()) {
+                nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
+            }
+            StringEntity se = new UrlEncodedFormEntity(nvps, CHARSET_UTF_8);
+            httpPost.setEntity(se);
+            HttpResponse httpResponse = HttpClientBuilder.create().build().execute(httpPost);
+            return EntityUtils.toString(httpResponse.getEntity(), CHARSET_UTF_8);
+        } catch (Exception e) {
+            logger.info("HTTP请求出错", e);
+            e.printStackTrace();
+        }
+        return "";
+    }
+
+    /**
+     * @param url
+     * @param param
+     * @return
+     */
+    public static String post(String url, Map<String, Object> param) {
+        logger.info("POST 请求, url={},map={}", url, param.toString());
+        try {
+            HttpPost httpPost = new HttpPost(url.trim());
+            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(TIMEOUT).setConnectionRequestTimeout(TIMEOUT).setSocketTimeout(TIMEOUT).build();
+            httpPost.setConfig(requestConfig);
+            httpPost.addHeader(HTTP.CONTENT_TYPE, APPLICATION_JSON);
+            StringEntity se = new StringEntity(param.toString(), CHARSET_UTF_8);
+            se.setContentType(CONTENT_TYPE_TEXT_JSON);
+            se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, APPLICATION_JSON));
+            httpPost.setEntity(se);
+            HttpResponse httpResponse = HttpClientBuilder.create().build().execute(httpPost);
+            return EntityUtils.toString(httpResponse.getEntity(), CHARSET_UTF_8);
+        } catch (Exception e) {
+            logger.info("HTTP请求出错", e);
+            e.printStackTrace();
+        }
+        return "";
+    }
+}
diff --git a/tz/common/common-core/src/main/java/com/tz/platform/common/core/tools/JSUtil.java b/tz/common/common-core/src/main/java/com/tz/platform/common/core/tools/JSUtil.java
new file mode 100644
index 0000000..298ce4c
--- /dev/null
+++ b/tz/common/common-core/src/main/java/com/tz/platform/common/core/tools/JSUtil.java
@@ -0,0 +1,43 @@
+package com.tz.platform.common.core.tools;
+
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.List;
+
+@Slf4j
+public class JSUtil {
+    private JSUtil() {
+    }
+
+    public static String toJSONString(Object obj) {
+        try {
+            return JSONUtil.toJsonStr(obj);
+        } catch (Exception e) {
+            log.error("json序列化失败", e);
+            return "";
+        }
+    }
+
+    public static <T> T parseObject(String jsonString, Class<T> elementClasses) {
+        try {
+            JSONObject jsonObject = JSONUtil.parseObj(jsonString);
+            return jsonObject.toBean(elementClasses);
+        } catch (Exception e) {
+            log.error("json解析失败,原字符串={}", jsonString);
+            return null;
+        }
+    }
+
+    public static <T> List<T> parseArray(String jsonString, Class<T> elementClasses) {
+        try {
+            JSONArray jsonArray = JSONUtil.parseArray(jsonString);
+            return jsonArray.toList(elementClasses);
+        } catch (Exception e) {
+            log.error("json解析失败,原因:", e);
+            return null;
+        }
+    }
+}
diff --git a/tz/common/common-core/src/main/java/com/tz/platform/common/core/tools/JWTUtil.java b/tz/common/common-core/src/main/java/com/tz/platform/common/core/tools/JWTUtil.java
new file mode 100644
index 0000000..5ecf0f0
--- /dev/null
+++ b/tz/common/common-core/src/main/java/com/tz/platform/common/core/tools/JWTUtil.java
@@ -0,0 +1,61 @@
+package com.tz.platform.common.core.tools;
+
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.auth0.jwt.exceptions.JWTCreationException;
+import com.auth0.jwt.exceptions.JWTVerificationException;
+import com.auth0.jwt.interfaces.DecodedJWT;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Date;
+
+public class JWTUtil {
+    protected static final Logger logger = LoggerFactory.getLogger(JWTUtil.class);
+
+    private static final String TOKEN_SECRET = "eyJhbGciOiJIUzI1NiJ9";
+    private static final String ISSUER = "RONCOO";
+    public static final String USERNO = "userNo";
+    public static final Long DATE = 30 * 24 * 3600 * 1000L; // 1个月
+
+    /**
+     * @param userNo
+     * @param date
+     * @return
+     * @throws IllegalArgumentException
+     * @throws JWTCreationException
+     * @throws UnsupportedEncodingException
+     */
+    public static String create(Long userNo, Long date) {
+        try {
+            return JWT.create().withIssuer(ISSUER).withClaim(USERNO, userNo.toString()).withExpiresAt(new Date(System.currentTimeMillis() + date)).sign(Algorithm.HMAC256(TOKEN_SECRET));
+        } catch (Exception e) {
+            logger.error("JWT生成失败", e);
+            return "";
+        }
+    }
+
+    /**
+     * @param token
+     * @return
+     * @throws JWTVerificationException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedEncodingException
+     */
+    public static DecodedJWT verify(String token) throws JWTVerificationException, IllegalArgumentException, UnsupportedEncodingException {
+        return JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer(ISSUER).build().verify(token);
+    }
+
+    /**
+     * @param decodedJWT
+     * @return
+     * @throws JWTVerificationException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedEncodingException
+     */
+    public static Long getUserNo(DecodedJWT decodedJWT) {
+        return Long.valueOf(decodedJWT.getClaim(USERNO).asString());
+    }
+
+}
diff --git a/tz/common/common-core/src/main/java/com/tz/platform/common/core/tools/SHA1Util.java b/tz/common/common-core/src/main/java/com/tz/platform/common/core/tools/SHA1Util.java
new file mode 100644
index 0000000..b1c3638
--- /dev/null
+++ b/tz/common/common-core/src/main/java/com/tz/platform/common/core/tools/SHA1Util.java
@@ -0,0 +1,50 @@
+package com.tz.platform.common.core.tools;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class SHA1Util {
+    private SHA1Util() {
+    }
+
+    public static final String getSign(String message) {
+        MessageDigest md = null;
+        String tmpStr = null;
+        try {
+            md = MessageDigest.getInstance("SHA-1");
+            byte[] digest = md.digest(message.getBytes());
+            tmpStr = byteToStr(digest);
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+        return tmpStr;
+    }
+
+    /**
+     * 将字节数组转换为十六进制字符串
+     *
+     * @param byteArray
+     * @return
+     */
+    private static String byteToStr(byte[] byteArray) {
+        String strDigest = "";
+        for (int i = 0; i < byteArray.length; i++) {
+            strDigest += byteToHexStr(byteArray[i]);
+        }
+        return strDigest;
+    }
+
+    /**
+     * 将字节转换为十六进制字符串
+     *
+     * @param mByte
+     * @return
+     */
+    private static String byteToHexStr(byte mByte) {
+        char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+        char[] tempArr = new char[2];
+        tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
+        tempArr[1] = Digit[mByte & 0X0F];
+        return new String(tempArr);
+    }
+}
diff --git a/tz/common/common-core/src/main/resources/logback-tz.xml b/tz/common/common-core/src/main/resources/logback-tz.xml
new file mode 100644
index 0000000..99cd557
--- /dev/null
+++ b/tz/common/common-core/src/main/resources/logback-tz.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
+
+    <springProperty name="springApplicationName" source="spring.application.name" defaultValue="tz-platform"/>
+    <springProperty name="FILE_PATH" source="management.endpoint.logfile.external-file"
+                    defaultValue="/home/tz/logs"/>
+
+    <property name="PATTERN" value="%-12(%d{yyyy-MM-dd HH:mm:ss.SSS}) |-%-5level [%thread] %c [%L] -|   %msg%n"/>
+
+    <!-- 本地环境 -->
+    <springProfile name="local">
+        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+            <encoder>
+                <pattern>${PATTERN}</pattern>
+            </encoder>
+        </appender>
+        <logger name="com.tz" level="debug"/>
+        <logger name="org.springframework.jdbc.core.JdbcTemplate" level="debug"/>
+        <root level="info">
+            <appender-ref ref="CONSOLE"/>
+        </root>
+    </springProfile>
+
+    <!-- 生产环境 -->
+    <springProfile name="prod">
+        <appender name="PROD_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+            <file>${FILE_PATH}/warn</file>
+            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                <fileNamePattern>${FILE_PATH}/warn.%d{yyyy-MM-dd}.log</fileNamePattern>
+                <MaxHistory>30</MaxHistory>
+            </rollingPolicy>
+            <layout class="ch.qos.logback.classic.PatternLayout">
+                <pattern>${PATTERN}</pattern>
+            </layout>
+        </appender>
+
+        <appender name="LOGSTASH" class="ch.qos.logback.core.rolling.RollingFileAppender">
+            <file>${FILE_PATH}/json</file>
+            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                <fileNamePattern>${FILE_PATH}/json.%d{yyyy-MM-dd}.gz</fileNamePattern>
+                <maxHistory>7</maxHistory>
+            </rollingPolicy>
+            <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
+                <providers>
+                    <timestamp>
+                        <timeZone>UTC</timeZone>
+                    </timestamp>
+                    <pattern>
+                        <pattern>
+                            {
+                            "severity": "%level",
+                            "service": "${springApplicationName:-}",
+                            "trace": "%X{X-B3-TraceId:-}",
+                            "span": "%X{X-B3-SpanId:-}",
+                            "parent": "%X{X-B3-ParentSpanId:-}",
+                            "exportable": "%X{X-Span-Export:-}",
+                            "pid": "${PID:-}",
+                            "thread": "%thread",
+                            "class": "%logger{40}",
+                            "rest": "%message"
+                            }
+                        </pattern>
+                    </pattern>
+                </providers>
+            </encoder>
+        </appender>
+
+        <logger name="com.tz" level="warn"/>
+
+        <root level="warn">
+            <appender-ref ref="PROD_FILE"/>
+            <!--<appender-ref ref="LOGSTASH" />-->
+        </root>
+    </springProfile>
+
+    <!-- 开发、测试环境 -->
+    <springProfile name="!local">
+        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+            <encoder>
+                <pattern>${PATTERN}</pattern>
+            </encoder>
+        </appender>
+        <appender name="TEST-FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+            <!-- 文件路径 -->
+            <file>${FILE_PATH}/info</file>
+            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                <!-- 文件名称 -->
+                <fileNamePattern>${FILE_PATH}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
+                <!-- 文件最大保存历史数量 -->
+                <MaxHistory>7</MaxHistory>
+            </rollingPolicy>
+
+            <layout class="ch.qos.logback.classic.PatternLayout">
+                <pattern>${PATTERN}</pattern>
+            </layout>
+        </appender>
+
+        <logger name="com.tz" level="debug"/>
+        <logger name="org.springframework.cloud.netflix.zuul" level="debug"/>
+        <logger name="org.springframework.jdbc.core.JdbcTemplate" level="debug"/>
+
+        <root level="info">
+            <appender-ref ref="CONSOLE"/>
+            <appender-ref ref="TEST-FILE"/>
+        </root>
+    </springProfile>
+</configuration>
diff --git a/tz/common/common-core/src/main/resources/system.properties b/tz/common/common-core/src/main/resources/system.properties
new file mode 100644
index 0000000..1189973
--- /dev/null
+++ b/tz/common/common-core/src/main/resources/system.properties
@@ -0,0 +1 @@
+pic_path=/Volumes/Lexar/www/pic
\ No newline at end of file
diff --git a/tz/common/common-core/target/classes/logback-tz.xml b/tz/common/common-core/target/classes/logback-tz.xml
new file mode 100644
index 0000000..99cd557
--- /dev/null
+++ b/tz/common/common-core/target/classes/logback-tz.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
+
+    <springProperty name="springApplicationName" source="spring.application.name" defaultValue="tz-platform"/>
+    <springProperty name="FILE_PATH" source="management.endpoint.logfile.external-file"
+                    defaultValue="/home/tz/logs"/>
+
+    <property name="PATTERN" value="%-12(%d{yyyy-MM-dd HH:mm:ss.SSS}) |-%-5level [%thread] %c [%L] -|   %msg%n"/>
+
+    <!-- 本地环境 -->
+    <springProfile name="local">
+        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+            <encoder>
+                <pattern>${PATTERN}</pattern>
+            </encoder>
+        </appender>
+        <logger name="com.tz" level="debug"/>
+        <logger name="org.springframework.jdbc.core.JdbcTemplate" level="debug"/>
+        <root level="info">
+            <appender-ref ref="CONSOLE"/>
+        </root>
+    </springProfile>
+
+    <!-- 生产环境 -->
+    <springProfile name="prod">
+        <appender name="PROD_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+            <file>${FILE_PATH}/warn</file>
+            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                <fileNamePattern>${FILE_PATH}/warn.%d{yyyy-MM-dd}.log</fileNamePattern>
+                <MaxHistory>30</MaxHistory>
+            </rollingPolicy>
+            <layout class="ch.qos.logback.classic.PatternLayout">
+                <pattern>${PATTERN}</pattern>
+            </layout>
+        </appender>
+
+        <appender name="LOGSTASH" class="ch.qos.logback.core.rolling.RollingFileAppender">
+            <file>${FILE_PATH}/json</file>
+            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                <fileNamePattern>${FILE_PATH}/json.%d{yyyy-MM-dd}.gz</fileNamePattern>
+                <maxHistory>7</maxHistory>
+            </rollingPolicy>
+            <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
+                <providers>
+                    <timestamp>
+                        <timeZone>UTC</timeZone>
+                    </timestamp>
+                    <pattern>
+                        <pattern>
+                            {
+                            "severity": "%level",
+                            "service": "${springApplicationName:-}",
+                            "trace": "%X{X-B3-TraceId:-}",
+                            "span": "%X{X-B3-SpanId:-}",
+                            "parent": "%X{X-B3-ParentSpanId:-}",
+                            "exportable": "%X{X-Span-Export:-}",
+                            "pid": "${PID:-}",
+                            "thread": "%thread",
+                            "class": "%logger{40}",
+                            "rest": "%message"
+                            }
+                        </pattern>
+                    </pattern>
+                </providers>
+            </encoder>
+        </appender>
+
+        <logger name="com.tz" level="warn"/>
+
+        <root level="warn">
+            <appender-ref ref="PROD_FILE"/>
+            <!--<appender-ref ref="LOGSTASH" />-->
+        </root>
+    </springProfile>
+
+    <!-- 开发、测试环境 -->
+    <springProfile name="!local">
+        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+            <encoder>
+                <pattern>${PATTERN}</pattern>
+            </encoder>
+        </appender>
+        <appender name="TEST-FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+            <!-- 文件路径 -->
+            <file>${FILE_PATH}/info</file>
+            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                <!-- 文件名称 -->
+                <fileNamePattern>${FILE_PATH}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
+                <!-- 文件最大保存历史数量 -->
+                <MaxHistory>7</MaxHistory>
+            </rollingPolicy>
+
+            <layout class="ch.qos.logback.classic.PatternLayout">
+                <pattern>${PATTERN}</pattern>
+            </layout>
+        </appender>
+
+        <logger name="com.tz" level="debug"/>
+        <logger name="org.springframework.cloud.netflix.zuul" level="debug"/>
+        <logger name="org.springframework.jdbc.core.JdbcTemplate" level="debug"/>
+
+        <root level="info">
+            <appender-ref ref="CONSOLE"/>
+            <appender-ref ref="TEST-FILE"/>
+        </root>
+    </springProfile>
+</configuration>
diff --git a/tz/common/common-core/target/classes/system.properties b/tz/common/common-core/target/classes/system.properties
new file mode 100644
index 0000000..1189973
--- /dev/null
+++ b/tz/common/common-core/target/classes/system.properties
@@ -0,0 +1 @@
+pic_path=/Volumes/Lexar/www/pic
\ No newline at end of file
diff --git a/tz/common/common-service/pom.xml b/tz/common/common-service/pom.xml
new file mode 100644
index 0000000..314f312
--- /dev/null
+++ b/tz/common/common-service/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>
+        <artifactId>common</artifactId>
+        <groupId>com.tz</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>common-service</artifactId>
+
+    <dependencies>
+        <!-- nacos -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+        </dependency>
+
+        <!-- sentinel -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-openfeign</artifactId>
+        </dependency>
+
+        <!-- Druid -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+            <version>1.1.21</version>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <!-- spring boot -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-devtools</artifactId>
+            <scope>runtime</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <!-- devtools -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-devtools</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+    </dependencies>
+
+
+</project>
\ No newline at end of file
diff --git a/tz/common/pom.xml b/tz/common/pom.xml
new file mode 100644
index 0000000..46757c9
--- /dev/null
+++ b/tz/common/pom.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>platform</artifactId>
+        <groupId>com.tz</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>common</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>common-service</module>
+        <module>common-core</module>
+    </modules>
+
+
+</project>
\ No newline at end of file
diff --git a/tz/competition/competition-service/pom.xml b/tz/competition/competition-service/pom.xml
new file mode 100644
index 0000000..de92584
--- /dev/null
+++ b/tz/competition/competition-service/pom.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>competition</artifactId>
+        <groupId>com.tz</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>competition-service</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.tz</groupId>
+            <artifactId>common-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.tz</groupId>
+            <artifactId>common-service</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.tz</groupId>
+            <artifactId>user-feign</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/tz/competition/competition-service/src/main/java/com/tz/platform/competitiion/CompetitionApplication.java b/tz/competition/competition-service/src/main/java/com/tz/platform/competitiion/CompetitionApplication.java
new file mode 100644
index 0000000..b68e817
--- /dev/null
+++ b/tz/competition/competition-service/src/main/java/com/tz/platform/competitiion/CompetitionApplication.java
@@ -0,0 +1,15 @@
+package com.tz.platform.competitiion;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+
+@SpringBootApplication
+@EnableDiscoveryClient
+@EnableFeignClients(basePackages = "com.tz.platform.feign")
+public class CompetitionApplication {
+    public static void main(String[] args) {
+        SpringApplication.run(CompetitionApplication.class,args);
+    }
+}
diff --git a/tz/competition/competition-service/src/main/java/com/tz/platform/competitiion/api/TestController.java b/tz/competition/competition-service/src/main/java/com/tz/platform/competitiion/api/TestController.java
new file mode 100644
index 0000000..d551557
--- /dev/null
+++ b/tz/competition/competition-service/src/main/java/com/tz/platform/competitiion/api/TestController.java
@@ -0,0 +1,30 @@
+package com.tz.platform.competitiion.api;
+
+import com.tz.platform.common.core.base.Result;
+import com.tz.platform.feign.user.IFeignUser;
+import com.tz.platform.feign.user.vo.UserVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping(value = "/api/competition")
+public class TestController {
+
+    @Autowired
+    private IFeignUser iFeignUser;
+
+    @GetMapping(value = "/user/{userNo}")
+    public String getUserByNo(@PathVariable(value = "userNo") Long userNo){
+        UserVo user = iFeignUser.getByUserNo(userNo);
+        return  user.getMobile();
+    }
+
+    @GetMapping(value = "/get/user/mobile/{mobile}")
+    public Result<Long> getByMobile(@PathVariable(value = "mobile") String mobile){
+        UserVo user = iFeignUser.getByMobile(mobile);
+        return Result.success(user.getId());
+    }
+}
diff --git a/tz/competition/competition-service/src/main/resources/bootstrap.yml b/tz/competition/competition-service/src/main/resources/bootstrap.yml
new file mode 100644
index 0000000..0b6e2ae
--- /dev/null
+++ b/tz/competition/competition-service/src/main/resources/bootstrap.yml
@@ -0,0 +1,17 @@
+server:
+  port: 50012
+spring:
+  application:
+    name: tz-competition-service
+  profiles:
+    active: dev
+  cloud:
+    nacos:
+      server-addr: 127.0.0.1:8848
+      username: nacos
+      password: nacos
+      config:
+        namespace: ${spring.profiles.active}
+        file-extension: yaml
+      discovery:
+        namespace: ${spring.profiles.active}
\ No newline at end of file
diff --git a/tz/competition/competition-service/target/classes/bootstrap.yml b/tz/competition/competition-service/target/classes/bootstrap.yml
new file mode 100644
index 0000000..0b6e2ae
--- /dev/null
+++ b/tz/competition/competition-service/target/classes/bootstrap.yml
@@ -0,0 +1,17 @@
+server:
+  port: 50012
+spring:
+  application:
+    name: tz-competition-service
+  profiles:
+    active: dev
+  cloud:
+    nacos:
+      server-addr: 127.0.0.1:8848
+      username: nacos
+      password: nacos
+      config:
+        namespace: ${spring.profiles.active}
+        file-extension: yaml
+      discovery:
+        namespace: ${spring.profiles.active}
\ No newline at end of file
diff --git a/tz/competition/pom.xml b/tz/competition/pom.xml
new file mode 100644
index 0000000..2afaa3b
--- /dev/null
+++ b/tz/competition/pom.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>platform</artifactId>
+        <groupId>com.tz</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>competition</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>competition-service</module>
+    </modules>
+
+
+
+
+</project>
\ No newline at end of file
diff --git a/tz/gateway/pom.xml b/tz/gateway/pom.xml
new file mode 100644
index 0000000..9b9570f
--- /dev/null
+++ b/tz/gateway/pom.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>platform</artifactId>
+        <groupId>com.tz</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>gateway</artifactId>
+
+    <dependencies>
+        <!-- Nacos -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+        </dependency>
+
+        <!-- gateway -->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-gateway</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-devtools</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.tz</groupId>
+            <artifactId>common-core</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-web</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>app-gateway</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.sonarsource.scanner.maven</groupId>
+                <artifactId>sonar-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+
+</project>
\ No newline at end of file
diff --git a/tz/gateway/src/main/java/com/tz/platform/gateway/GatewayApplication.java b/tz/gateway/src/main/java/com/tz/platform/gateway/GatewayApplication.java
new file mode 100644
index 0000000..2526920
--- /dev/null
+++ b/tz/gateway/src/main/java/com/tz/platform/gateway/GatewayApplication.java
@@ -0,0 +1,13 @@
+package com.tz.platform.gateway;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+
+@SpringBootApplication
+@EnableDiscoveryClient
+public class GatewayApplication {
+    public static void main(String[] args) {
+        SpringApplication.run(GatewayApplication.class,args);
+    }
+}
diff --git a/tz/gateway/src/main/java/com/tz/platform/gateway/GlobalErrorAttributes.java b/tz/gateway/src/main/java/com/tz/platform/gateway/GlobalErrorAttributes.java
new file mode 100644
index 0000000..9d83c01
--- /dev/null
+++ b/tz/gateway/src/main/java/com/tz/platform/gateway/GlobalErrorAttributes.java
@@ -0,0 +1,29 @@
+package com.tz.platform.gateway;
+
+import com.tz.platform.common.core.base.BaseException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.web.error.ErrorAttributeOptions;
+import org.springframework.boot.web.reactive.error.DefaultErrorAttributes;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Component;
+import org.springframework.web.reactive.function.server.ServerRequest;
+
+import java.util.Map;
+
+@Component
+@Slf4j
+public class GlobalErrorAttributes extends DefaultErrorAttributes {
+    @Override
+    public Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) {
+        Map<String, Object> map = super.getErrorAttributes(request, options);
+        log.error("系统异常,{}", map);
+        map.put("status", HttpStatus.OK.value());
+        Throwable error = this.getError(request);
+        if (error instanceof BaseException) {
+            BaseException be = (BaseException) error;
+            map.put("code", be.getCode());
+            map.put("msg", be.getMessage());
+        }
+        return map;
+    }
+}
diff --git a/tz/gateway/src/main/java/com/tz/platform/gateway/IndexController.java b/tz/gateway/src/main/java/com/tz/platform/gateway/IndexController.java
new file mode 100644
index 0000000..ea3716f
--- /dev/null
+++ b/tz/gateway/src/main/java/com/tz/platform/gateway/IndexController.java
@@ -0,0 +1,12 @@
+package com.tz.platform.gateway;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+import reactor.core.publisher.Mono;
+
+@RestController
+public class IndexController {
+
+    @GetMapping("/")
+    public Mono<String> index(){ return Mono.just("success");}
+}
diff --git a/tz/gateway/src/main/java/com/tz/platform/gateway/filter/TzGlobalFilter.java b/tz/gateway/src/main/java/com/tz/platform/gateway/filter/TzGlobalFilter.java
new file mode 100644
index 0000000..415468d
--- /dev/null
+++ b/tz/gateway/src/main/java/com/tz/platform/gateway/filter/TzGlobalFilter.java
@@ -0,0 +1,184 @@
+package com.tz.platform.gateway.filter;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.auth0.jwt.interfaces.DecodedJWT;
+import com.tz.platform.common.core.base.BaseException;
+import com.tz.platform.common.core.enmus.RedisPreEnum;
+import com.tz.platform.common.core.enmus.ResultEnum;
+import com.tz.platform.common.core.tools.JSUtil;
+import com.tz.platform.common.core.tools.JWTUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.filter.GlobalFilter;
+import org.springframework.cloud.gateway.filter.factory.rewrite.CachedBodyOutputMessage;
+import org.springframework.cloud.gateway.support.BodyInserterContext;
+import org.springframework.core.annotation.Order;
+import org.springframework.core.io.buffer.DataBuffer;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
+import org.springframework.util.StringUtils;
+import org.springframework.web.reactive.function.BodyInserter;
+import org.springframework.web.reactive.function.BodyInserters;
+import org.springframework.web.reactive.function.server.HandlerStrategies;
+import org.springframework.web.reactive.function.server.ServerRequest;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+@Order(0)
+public class TzGlobalFilter implements GlobalFilter {
+    private static final Logger logger = LoggerFactory.getLogger(TzGlobalFilter.class);
+
+    private static final String TOKEN = "token";
+    private static final String USERNO = "userNo";
+
+    @Autowired
+    private StringRedisTemplate stringRedisTemplate;
+
+    @Override
+    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+        ServerHttpRequest request = exchange.getRequest();
+        String uri = request.getPath().value();
+        if (uri.contains("/callback")) {
+            // 第三方回调接口,不鉴权
+            return chain.filter(exchange);
+        }
+        if (uri.contains("/api")) {
+            // 路径存在关键词:/api,不鉴权
+            return chain.filter(exchange);
+        }
+
+        // 解析token
+        Long userNo = getUserNoByToken(request);
+        if (uri.contains("/pc") && !uri.contains("/system/pc/menu/user/list") && !uri.contains("/system/pc/menu/user/button/list")) {
+            // 管理后台鉴权
+            if (!stringRedisTemplate.hasKey(RedisPreEnum.ADMINI_MENU.getCode().concat(userNo.toString()))) {
+                throw new BaseException(ResultEnum.MENU_PAST);
+            }
+            String tk = stringRedisTemplate.opsForValue().get(RedisPreEnum.ADMINI_MENU.getCode().concat(userNo.toString()));
+            // 校验接口是否有权限
+            if (!checkUri(uri, tk)) {
+                throw new BaseException(ResultEnum.MENU_NO);
+            }
+            // 更新时间,使用户菜单不过期
+            stringRedisTemplate.opsForValue().set(RedisPreEnum.ADMINI_MENU.getCode().concat(userNo.toString()), tk, 1, TimeUnit.HOURS);
+        }
+        return request(exchange, chain, modifiedBody(exchange, userNo));
+    }
+
+    // 校验用户是否有权限
+    private static Boolean checkUri(String uri, String tk) {
+        List<String> menuVOList1 = JSUtil.parseArray(tk, String.class);
+        if (StringUtils.hasText(uri) && uri.endsWith("/")) {
+            uri = uri.substring(0, uri.length() - 1);
+        }
+        for (String s : menuVOList1) {
+            if (s.contains(uri)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+
+    private Mono<String> modifiedBody(ServerWebExchange serverWebExchange, Long userNo) {
+        MediaType mediaType = serverWebExchange.getRequest().getHeaders().getContentType();
+        ServerRequest serverRequest = ServerRequest.create(serverWebExchange, HandlerStrategies.withDefaults().messageReaders());
+        return serverRequest.bodyToMono(String.class).flatMap(body -> {
+            JSONObject bodyJson;
+            if (MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(mediaType)) {
+                Map<String, Object> bodyMap = decodeBody(body);
+                bodyJson = JSONUtil.parseObj(bodyMap);
+            } else {
+                bodyJson = JSONUtil.parseObj(body);
+            }
+            if (ObjectUtil.isNotNull(userNo)) {
+                bodyJson.set(USERNO, userNo);
+            }
+            return Mono.just(JSONUtil.toJsonStr(bodyJson));
+        });
+    }
+
+    private Map<String, Object> decodeBody(String body) {
+        return Arrays.stream(body.split("&")).map(s -> s.split("=")).collect(Collectors.toMap(arr -> arr[0], arr -> arr[1]));
+    }
+
+    private Mono<Void> request(ServerWebExchange exchange, GatewayFilterChain chain, Mono<String> modifiedBody) {
+        BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, String.class);
+        HttpHeaders headers = new HttpHeaders();
+        headers.putAll(exchange.getRequest().getHeaders());
+        headers.remove(HttpHeaders.CONTENT_LENGTH);
+        CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers);
+        return bodyInserter.insert(outputMessage, new BodyInserterContext())
+                .then(Mono.defer(() -> {
+                    ServerHttpRequestDecorator decorator =
+                            new ServerHttpRequestDecorator(exchange.getRequest()) {
+                                @Override
+                                public HttpHeaders getHeaders() {
+                                    return headers;
+                                }
+
+                                @Override
+                                public Flux<DataBuffer> getBody() {
+                                    return outputMessage.getBody();
+                                }
+                            };
+                    return chain.filter(exchange.mutate().request(decorator).build());
+                }));
+    }
+
+    private Long getUserNoByToken(ServerHttpRequest request) {
+        // 头部
+        String token = request.getHeaders().getFirst(TOKEN);
+        if (StringUtils.isEmpty(token)) { // token不存在,则从报文里面获取
+            throw new BaseException("token不存在,请重新登录");
+        }
+        // 解析 token
+        DecodedJWT jwt = null;
+        try {
+            jwt = JWTUtil.verify(token);
+        } catch (Exception e) {
+            logger.error("token异常,token={}", token.toString());
+            throw new BaseException(ResultEnum.TOKEN_ERROR);
+        }
+
+        // 校验token
+        if (null == jwt) {
+            throw new BaseException(ResultEnum.TOKEN_ERROR);
+        }
+        Long userNo = JWTUtil.getUserNo(jwt);
+        if (userNo <= 0) {
+            throw new BaseException(ResultEnum.TOKEN_ERROR);
+        }
+
+        // 单点登录处理,注意,登录的时候必须要放入缓存
+//        if (!stringRedisTemplate.hasKey(userNo.toString())) {
+//            // 不存在,则登录异常,有效期为1小时
+//            throw new BaseException(ResultEnum.TOKEN_PAST);
+//        }
+//        // 存在,判断是否token相同
+//        String tk = stringRedisTemplate.opsForValue().get(userNo.toString());
+//        if (!token.equals(tk)) {
+//            // 不同则为不同的用户登录,这时候提示异地登录
+//            throw new BaseException(ResultEnum.REMOTE_ERROR);
+//        }
+
+        // 更新时间,使token不过期
+        stringRedisTemplate.opsForValue().set(userNo.toString(), token, 1, TimeUnit.HOURS);
+        return userNo;
+    }
+}
diff --git a/tz/gateway/src/main/resources/bootstrap.yml b/tz/gateway/src/main/resources/bootstrap.yml
new file mode 100644
index 0000000..71dbc38
--- /dev/null
+++ b/tz/gateway/src/main/resources/bootstrap.yml
@@ -0,0 +1,17 @@
+spring:
+  application:
+    name: tz-gateway
+  cloud:
+    nacos:
+      username: nacos
+      password: nacos
+      discovery:
+        server-addr: 127.0.0.1:8848
+        namespace: ${spring.profiles.active}
+      config:
+        file-extension: yaml
+        namespace: ${spring.profiles.active}
+  profiles:
+    active: dev
+server:
+  port: 50010
\ No newline at end of file
diff --git a/tz/gateway/target/classes/bootstrap.yml b/tz/gateway/target/classes/bootstrap.yml
new file mode 100644
index 0000000..71dbc38
--- /dev/null
+++ b/tz/gateway/target/classes/bootstrap.yml
@@ -0,0 +1,17 @@
+spring:
+  application:
+    name: tz-gateway
+  cloud:
+    nacos:
+      username: nacos
+      password: nacos
+      discovery:
+        server-addr: 127.0.0.1:8848
+        namespace: ${spring.profiles.active}
+      config:
+        file-extension: yaml
+        namespace: ${spring.profiles.active}
+  profiles:
+    active: dev
+server:
+  port: 50010
\ No newline at end of file
diff --git a/tz/pom.xml b/tz/pom.xml
new file mode 100644
index 0000000..cba95da
--- /dev/null
+++ b/tz/pom.xml
@@ -0,0 +1,126 @@
+<?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>
+
+    <groupId>com.tz</groupId>
+    <artifactId>platform</artifactId>
+    <packaging>pom</packaging>
+    <version>1.0-SNAPSHOT</version>
+    <modules>
+        <module>common</module>
+        <module>user</module>
+        <module>gateway</module>
+        <module>competition</module>
+    </modules>
+
+    <properties>
+        <java.version>1.8</java.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <!-- spring boot -->
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-starter-parent</artifactId>
+                <version>2.3.5.RELEASE</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+
+            <!-- spring cloud -->
+            <dependency>
+                <groupId>org.springframework.cloud</groupId>
+                <artifactId>spring-cloud-dependencies</artifactId>
+                <version>Hoxton.SR9</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+
+            <!-- spring cloud alibaba -->
+            <dependency>
+                <groupId>com.alibaba.cloud</groupId>
+                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
+                <version>2.2.6.RELEASE</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <dependency>
+                <groupId>com.tz</groupId>
+                <artifactId>common-service</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>com.tz</groupId>
+                <artifactId>common-core</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.tz</groupId>
+                <artifactId>user-feign</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
+        </dependencies>
+    </dependencyManagement>
+
+    <build>
+        <pluginManagement>
+            <plugins>
+                <!-- spring boot -->
+                <plugin>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-maven-plugin</artifactId>
+                    <configuration>
+                        <executable>true</executable>
+                    </configuration>
+                    <executions>
+                        <execution>
+                            <phase>package</phase>
+                            <goals>
+                                <goal>repackage</goal>
+                                <goal>build-info</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                </plugin>
+
+                <!-- compiler -->
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-compiler-plugin</artifactId>
+                    <configuration>
+                        <source>${java.version}</source>
+                        <target>${java.version}</target>
+                        <skip>true</skip>
+                        <encoding>${project.build.sourceEncoding}</encoding>
+                    </configuration>
+                </plugin>
+
+                <!-- sonar -->
+<!--                <plugin>-->
+<!--                    <groupId>org.sonarsource.scanner.maven</groupId>-->
+<!--                    <artifactId>sonar-maven-plugin</artifactId>-->
+<!--                    <version>3.6.0.1398</version>-->
+<!--                </plugin>-->
+
+                <!-- https://github.com/spotify/dockerfile-maven -->
+<!--                <plugin>-->
+<!--                    <groupId>com.spotify</groupId>-->
+<!--                    <artifactId>dockerfile-maven-plugin</artifactId>-->
+<!--                    <version>1.4.13</version>-->
+<!--                    <configuration>-->
+<!--                        <repository>harbor.roncoo.com/library/${project.artifactId}</repository>-->
+<!--                        <tag>${project.version}</tag>-->
+<!--                    </configuration>-->
+<!--                </plugin>-->
+            </plugins>
+        </pluginManagement>
+    </build>
+    
+</project>
\ No newline at end of file
diff --git a/tz/user/pom.xml b/tz/user/pom.xml
new file mode 100644
index 0000000..d1f86e4
--- /dev/null
+++ b/tz/user/pom.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>platform</artifactId>
+        <groupId>com.tz</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>user</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>user-service</module>
+        <module>user-feign</module>
+    </modules>
+
+
+
+</project>
\ No newline at end of file
diff --git a/tz/user/user-feign/pom.xml b/tz/user/user-feign/pom.xml
new file mode 100644
index 0000000..ea03bd3
--- /dev/null
+++ b/tz/user/user-feign/pom.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>user</artifactId>
+        <groupId>com.tz</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>user-feign</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.tz</groupId>
+            <artifactId>common-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-openfeign</artifactId>
+        </dependency>
+
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/tz/user/user-feign/src/main/java/com/tz/platform/feign/user/IFeignUser.java b/tz/user/user-feign/src/main/java/com/tz/platform/feign/user/IFeignUser.java
new file mode 100644
index 0000000..6cf1a9f
--- /dev/null
+++ b/tz/user/user-feign/src/main/java/com/tz/platform/feign/user/IFeignUser.java
@@ -0,0 +1,15 @@
+package com.tz.platform.feign.user;
+
+import com.tz.platform.feign.user.vo.UserVo;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+
+@FeignClient(value = "tz-user-service")
+public interface IFeignUser {
+
+    @GetMapping(value = "/feign/user/getByUserNo/{userNo}")
+    UserVo getByUserNo(@PathVariable(value = "userNo") Long userNo);
+    @GetMapping(value = "/feign/user/getByMobile/{mobile}")
+    UserVo getByMobile(@PathVariable(value = "mobile") String mobile);
+}
diff --git a/tz/user/user-feign/src/main/java/com/tz/platform/feign/user/qo/UserQO.java b/tz/user/user-feign/src/main/java/com/tz/platform/feign/user/qo/UserQO.java
new file mode 100644
index 0000000..348a09d
--- /dev/null
+++ b/tz/user/user-feign/src/main/java/com/tz/platform/feign/user/qo/UserQO.java
@@ -0,0 +1,57 @@
+package com.tz.platform.feign.user.qo;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+@Data
+@Accessors(chain = true)
+public class UserQO {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 当前页
+     */
+    private int pageCurrent;
+    /**
+     * 每页记录数
+     */
+    private int pageSize;
+    /**
+     * 主键
+     */
+    private Long id;
+    /**
+     * 创建时间
+     */
+    private Date gmtCreate;
+    /**
+     * 修改时间
+     */
+    private Date gmtModified;
+    /**
+     * 状态(1:正常,0:禁用)
+     */
+    private Integer statusId;
+    /**
+     * 用户编号
+     */
+    private Long userNo;
+    /**
+     * 手机号码
+     */
+    private String mobile;
+    /**
+     * 密码盐
+     */
+    private String mobileSalt;
+    /**
+     * 登录密码
+     */
+    private String mobilePsw;
+    /**
+     * 用户来源(client_id)
+     */
+    private String userSource;
+}
diff --git a/tz/user/user-feign/src/main/java/com/tz/platform/feign/user/vo/UserVo.java b/tz/user/user-feign/src/main/java/com/tz/platform/feign/user/vo/UserVo.java
new file mode 100644
index 0000000..41ca3e6
--- /dev/null
+++ b/tz/user/user-feign/src/main/java/com/tz/platform/feign/user/vo/UserVo.java
@@ -0,0 +1,49 @@
+package com.tz.platform.feign.user.vo;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+@Data
+@Accessors(chain = true)
+public class UserVo {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    private Long id;
+    /**
+     * 创建时间
+     */
+    private Date gmtCreate;
+    /**
+     * 修改时间
+     */
+    private Date gmtModified;
+    /**
+     * 状态(1:正常,0:禁用)
+     */
+    private Integer statusId;
+    /**
+     * 用户编号
+     */
+    private Long userNo;
+    /**
+     * 手机号码
+     */
+    private String mobile;
+    /**
+     * 密码盐
+     */
+    private String mobileSalt;
+    /**
+     * 登录密码
+     */
+    private String mobilePsw;
+    /**
+     * 用户来源(client_id)
+     */
+    private String userSource;
+}
diff --git a/tz/user/user-feign/target/classes/META-INF/userfeign.kotlin_module b/tz/user/user-feign/target/classes/META-INF/userfeign.kotlin_module
new file mode 100644
index 0000000..8fb6019
Binary files /dev/null and b/tz/user/user-feign/target/classes/META-INF/userfeign.kotlin_module differ
diff --git a/tz/user/user-service/pom.xml b/tz/user/user-service/pom.xml
new file mode 100644
index 0000000..a1f1b61
--- /dev/null
+++ b/tz/user/user-service/pom.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>user</artifactId>
+        <groupId>com.tz</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>user-service</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.tz</groupId>
+            <artifactId>common-service</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.tz</groupId>
+            <artifactId>common-core</artifactId>
+        </dependency>
+        <!-- test -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.tz</groupId>
+            <artifactId>user-feign</artifactId>
+        </dependency>
+
+
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/tz/user/user-service/src/main/java/com/tz/platform/Application.java b/tz/user/user-service/src/main/java/com/tz/platform/Application.java
new file mode 100644
index 0000000..cfc68d4
--- /dev/null
+++ b/tz/user/user-service/src/main/java/com/tz/platform/Application.java
@@ -0,0 +1,16 @@
+package com.tz.platform;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+
+
+@SpringBootApplication
+@EnableDiscoveryClient
+@EnableFeignClients
+public class Application {
+    public static void main(String[] args) {
+        SpringApplication.run(Application.class,args);
+    }
+}
diff --git a/tz/user/user-service/src/main/java/com/tz/platform/entity/User.java b/tz/user/user-service/src/main/java/com/tz/platform/entity/User.java
new file mode 100644
index 0000000..c066c7a
--- /dev/null
+++ b/tz/user/user-service/src/main/java/com/tz/platform/entity/User.java
@@ -0,0 +1,118 @@
+package com.tz.platform.entity;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Entity
+@Table(name = "user")
+public class User {
+
+    @Id
+    @GeneratedValue(strategy= GenerationType.IDENTITY)
+    private Long id;
+
+    private Date gmtCreate;
+
+    private Date gmtModified;
+
+    private Integer statusId;
+
+    private Long userNo;
+
+    private String mobile;
+
+    private String userName;
+
+    private String studentNo;
+
+    private String mobileSalt;
+
+    private String mobilePsw;
+
+
+    private static final long serialVersionUID = 1L;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Date getGmtCreate() {
+        return gmtCreate;
+    }
+
+    public void setGmtCreate(Date gmtCreate) {
+        this.gmtCreate = gmtCreate;
+    }
+
+    public Date getGmtModified() {
+        return gmtModified;
+    }
+
+    public void setGmtModified(Date gmtModified) {
+        this.gmtModified = gmtModified;
+    }
+
+    public Integer getStatusId() {
+        return statusId;
+    }
+
+    public void setStatusId(Integer statusId) {
+        this.statusId = statusId;
+    }
+
+    public Long getUserNo() {
+        return userNo;
+    }
+
+    public void setUserNo(Long userNo) {
+        this.userNo = userNo;
+    }
+
+    public String getMobile() {
+        return mobile;
+    }
+
+    public void setMobile(String mobile) {
+        this.mobile = mobile == null ? null : mobile.trim();
+    }
+
+    public String getMobileSalt() {
+        return mobileSalt;
+    }
+
+    public void setMobileSalt(String mobileSalt) {
+        this.mobileSalt = mobileSalt == null ? null : mobileSalt.trim();
+    }
+
+    public String getMobilePsw() {
+        return mobilePsw;
+    }
+
+    public void setMobilePsw(String mobilePsw) {
+        this.mobilePsw = mobilePsw == null ? null : mobilePsw.trim();
+    }
+
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getClass().getSimpleName());
+        sb.append(" [");
+        sb.append("Hash = ").append(hashCode());
+        sb.append(", id=").append(id);
+        sb.append(", gmtCreate=").append(gmtCreate);
+        sb.append(", gmtModified=").append(gmtModified);
+        sb.append(", statusId=").append(statusId);
+        sb.append(", userNo=").append(userNo);
+        sb.append(", mobile=").append(mobile);
+        sb.append(", mobileSalt=").append(mobileSalt);
+        sb.append(", mobilePsw=").append(mobilePsw);
+        sb.append(", serialVersionUID=").append(serialVersionUID);
+        sb.append("]");
+        return sb.toString();
+    }
+}
diff --git a/tz/user/user-service/src/main/java/com/tz/platform/repository/UserDao.java b/tz/user/user-service/src/main/java/com/tz/platform/repository/UserDao.java
new file mode 100644
index 0000000..65949fe
--- /dev/null
+++ b/tz/user/user-service/src/main/java/com/tz/platform/repository/UserDao.java
@@ -0,0 +1,10 @@
+package com.tz.platform.repository;
+
+import com.tz.platform.entity.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface UserDao extends JpaRepository<User,Long> {
+    User findByMobile(String mobile);
+}
diff --git a/tz/user/user-service/src/main/java/com/tz/platform/user/api/UserInfoController.java b/tz/user/user-service/src/main/java/com/tz/platform/user/api/UserInfoController.java
new file mode 100644
index 0000000..cfa6752
--- /dev/null
+++ b/tz/user/user-service/src/main/java/com/tz/platform/user/api/UserInfoController.java
@@ -0,0 +1,24 @@
+package com.tz.platform.user.api;
+
+import com.tz.platform.entity.User;
+import com.tz.platform.repository.UserDao;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+@RequestMapping(path = "/api/user")
+public class UserInfoController {
+
+    @Autowired
+    UserDao userDao;
+
+    @GetMapping(path = "test")
+    public String test(){
+        List<User> userList = userDao.findAll();
+        return "user count:"+userList.size();
+    }
+}
diff --git a/tz/user/user-service/src/main/java/com/tz/platform/user/api/biz/apiUserInfoBiz.java b/tz/user/user-service/src/main/java/com/tz/platform/user/api/biz/apiUserInfoBiz.java
new file mode 100644
index 0000000..5022353
--- /dev/null
+++ b/tz/user/user-service/src/main/java/com/tz/platform/user/api/biz/apiUserInfoBiz.java
@@ -0,0 +1,20 @@
+package com.tz.platform.user.api.biz;
+
+import com.tz.platform.common.core.base.Result;
+import com.tz.platform.repository.UserDao;
+import com.tz.platform.user.api.bo.UserLoginPasswordBO;
+import com.tz.platform.user.api.dto.UserLoginDTO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class apiUserInfoBiz {
+
+    @Autowired
+    private UserDao userDao;
+
+    public Result<UserLoginDTO> loginPassword(UserLoginPasswordBO userLoginPasswordBO){
+        UserLoginDTO userLoginDTO  = new UserLoginDTO();
+        return Result.success(userLoginDTO);
+    }
+}
diff --git a/tz/user/user-service/src/main/java/com/tz/platform/user/api/bo/UserLoginPasswordBO.java b/tz/user/user-service/src/main/java/com/tz/platform/user/api/bo/UserLoginPasswordBO.java
new file mode 100644
index 0000000..930d056
--- /dev/null
+++ b/tz/user/user-service/src/main/java/com/tz/platform/user/api/bo/UserLoginPasswordBO.java
@@ -0,0 +1,32 @@
+package com.tz.platform.user.api.bo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@Accessors(chain = true)
+public class UserLoginPasswordBO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 手机号码
+     */
+    @ApiModelProperty(value = "手机号", required = true)
+    private String mobile;
+    /**
+     * 登录密码
+     */
+    @ApiModelProperty(value = "密码", required = true)
+    private String password;
+    /**
+     * clientId
+     */
+    @ApiModelProperty(value = "clientId", required = true)
+    private String clientId;
+
+    private String ip;
+}
diff --git a/tz/user/user-service/src/main/java/com/tz/platform/user/api/dto/UserLoginDTO.java b/tz/user/user-service/src/main/java/com/tz/platform/user/api/dto/UserLoginDTO.java
new file mode 100644
index 0000000..37515e8
--- /dev/null
+++ b/tz/user/user-service/src/main/java/com/tz/platform/user/api/dto/UserLoginDTO.java
@@ -0,0 +1,33 @@
+package com.tz.platform.user.api.dto;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@Accessors(chain = true)
+public class UserLoginDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 用户编号
+     */
+    @ApiModelProperty(value = "用户编号")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long userNo;
+    /**
+     * 手机号码
+     */
+    @ApiModelProperty(value = "手机号")
+    private String mobile;
+    /**
+     * token,设置有效期为1天
+     */
+    @ApiModelProperty(value = "token,有效期为1天")
+    private String token;
+
+}
diff --git a/tz/user/user-service/src/main/java/com/tz/platform/user/feign/FeignUserController.java b/tz/user/user-service/src/main/java/com/tz/platform/user/feign/FeignUserController.java
new file mode 100644
index 0000000..c5ffacb
--- /dev/null
+++ b/tz/user/user-service/src/main/java/com/tz/platform/user/feign/FeignUserController.java
@@ -0,0 +1,25 @@
+package com.tz.platform.user.feign;
+
+import com.tz.platform.user.feign.biz.FeignUserBiz;
+import com.tz.platform.feign.user.IFeignUser;
+import com.tz.platform.feign.user.vo.UserVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class FeignUserController implements IFeignUser {
+
+    @Autowired
+    private FeignUserBiz feignUserBiz;
+
+    @Override
+    public UserVo getByUserNo(@PathVariable(value = "userNo") Long userNo) {
+        return feignUserBiz.getByUserNo(userNo);
+    }
+
+    @Override
+    public UserVo getByMobile(@PathVariable(value = "mobile") String mobile){
+        return feignUserBiz.getByMobile(mobile);
+    }
+}
diff --git a/tz/user/user-service/src/main/java/com/tz/platform/user/feign/biz/FeignUserBiz.java b/tz/user/user-service/src/main/java/com/tz/platform/user/feign/biz/FeignUserBiz.java
new file mode 100644
index 0000000..06ab827
--- /dev/null
+++ b/tz/user/user-service/src/main/java/com/tz/platform/user/feign/biz/FeignUserBiz.java
@@ -0,0 +1,24 @@
+package com.tz.platform.user.feign.biz;
+
+import com.tz.platform.common.core.tools.BeanUtils;
+import com.tz.platform.entity.User;
+import com.tz.platform.repository.UserDao;
+import com.tz.platform.feign.user.vo.UserVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class FeignUserBiz {
+    @Autowired
+    private UserDao userDao;
+
+    public UserVo getByUserNo(Long userNo){
+        User user = userDao.findById(userNo).get();
+        return BeanUtils.copyProperties(user,UserVo.class);
+    }
+
+    public UserVo getByMobile(String mobile){
+        User user = userDao.findByMobile(mobile);
+        return  BeanUtils.copyProperties(user,UserVo.class);
+    }
+}
diff --git a/tz/user/user-service/src/main/resources/bootstrap.yml b/tz/user/user-service/src/main/resources/bootstrap.yml
new file mode 100644
index 0000000..81b6d3e
--- /dev/null
+++ b/tz/user/user-service/src/main/resources/bootstrap.yml
@@ -0,0 +1,17 @@
+server:
+  port: 50011
+spring:
+  application:
+    name: tz-user-service
+  profiles:
+    active: dev
+  cloud:
+    nacos:
+      server-addr: 127.0.0.1:8848
+      username: nacos
+      password: nacos
+      config:
+        namespace: ${spring.profiles.active}
+        file-extension: yaml
+      discovery:
+        namespace: ${spring.profiles.active}
diff --git a/tz/user/user-service/src/test/java/com/tz/platform/repository/UserRepositoryTest.java b/tz/user/user-service/src/test/java/com/tz/platform/repository/UserRepositoryTest.java
new file mode 100644
index 0000000..50bcac2
--- /dev/null
+++ b/tz/user/user-service/src/test/java/com/tz/platform/repository/UserRepositoryTest.java
@@ -0,0 +1,26 @@
+package com.tz.platform.repository;
+
+import com.tz.platform.entity.User;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.annotation.Rollback;
+
+@SpringBootTest
+public class UserRepositoryTest {
+    @Autowired
+    private  UserDao userDao;
+
+    @Test
+    @Rollback
+    public void userSaveTest(){
+        User user = new User();
+        user.setUserNo(1L);
+        user.setMobile("18600024112");
+        user.setMobileSalt("");
+        user.setMobilePsw("11111111");
+        user.setUserSource("1123123");
+        userDao.save(user);
+    }
+
+}
diff --git a/tz/user/user-service/target/classes/bootstrap.yml b/tz/user/user-service/target/classes/bootstrap.yml
new file mode 100644
index 0000000..81b6d3e
--- /dev/null
+++ b/tz/user/user-service/target/classes/bootstrap.yml
@@ -0,0 +1,17 @@
+server:
+  port: 50011
+spring:
+  application:
+    name: tz-user-service
+  profiles:
+    active: dev
+  cloud:
+    nacos:
+      server-addr: 127.0.0.1:8848
+      username: nacos
+      password: nacos
+      config:
+        namespace: ${spring.profiles.active}
+        file-extension: yaml
+      discovery:
+        namespace: ${spring.profiles.active}