瀏覽代碼

增加广告模块
增加APP应用模块- 题库-题目-答题记录
增加广告渠道列表

marxjaw 5 月之前
父節點
當前提交
75ffb5c508
共有 49 個文件被更改,包括 1468 次插入11 次删除
  1. 2 0
      pom.xml
  2. 88 0
      yt-advertise/advertise-service/pom.xml
  3. 15 0
      yt-advertise/advertise-service/src/main/java/com/ytpm/AdvertiseApplication.java
  4. 15 0
      yt-advertise/advertise-service/src/main/java/com/ytpm/enums/AndroidFirstCategoryEnum.java
  5. 74 0
      yt-advertise/advertise-service/src/main/java/com/ytpm/enums/AndroidSecondCategoryEnum.java
  6. 30 0
      yt-advertise/advertise-service/src/main/java/com/ytpm/enums/StoreTypeEnum.java
  7. 30 0
      yt-advertise/advertise-service/src/main/java/com/ytpm/param/AddAppParam.java
  8. 12 0
      yt-advertise/advertise-service/src/main/java/com/ytpm/service/TakuApiService.java
  9. 19 0
      yt-advertise/advertise-service/src/main/java/com/ytpm/service/impl/TakuApiServiceImpl.java
  10. 87 0
      yt-advertise/advertise-service/src/main/java/com/ytpm/util/TakuRequestUtil.java
  11. 0 0
      yt-advertise/advertise-service/src/main/resources/bootstrap.yml
  12. 108 0
      yt-advertise/pom.xml
  13. 3 3
      yt-agent/agent-service/src/main/java/com/ytpm/config/ResourceServerConfig.java
  14. 30 0
      yt-agent/agent-service/src/main/java/com/ytpm/controller/AgentChannelController.java
  15. 14 0
      yt-agent/agent-service/src/main/java/com/ytpm/dao/ChannelMapper.java
  16. 40 0
      yt-agent/agent-service/src/main/java/com/ytpm/handle/AgentAuthExceptionEntryPoint.java
  17. 11 0
      yt-agent/agent-service/src/main/java/com/ytpm/service/ChannelService.java
  18. 25 0
      yt-agent/agent-service/src/main/java/com/ytpm/service/impl/ChannelServiceImpl.java
  19. 10 0
      yt-agent/agent-service/src/main/resources/mapper/ChannelMapper.xml
  20. 77 0
      yt-app/app-service/pom.xml
  21. 21 0
      yt-app/app-service/src/main/java/com/ytpm/AppApplication.java
  22. 104 0
      yt-app/app-service/src/main/java/com/ytpm/config/CustomUserAuthenticationConverter.java
  23. 72 0
      yt-app/app-service/src/main/java/com/ytpm/config/ResourceServerConfig.java
  24. 40 0
      yt-app/app-service/src/main/java/com/ytpm/config/swagger/SwaggerConfig.java
  25. 42 0
      yt-app/app-service/src/main/java/com/ytpm/controller/QuestionController.java
  26. 39 0
      yt-app/app-service/src/main/java/com/ytpm/controller/WxController.java
  27. 14 0
      yt-app/app-service/src/main/java/com/ytpm/dao/AgentUserMapper.java
  28. 23 0
      yt-app/app-service/src/main/java/com/ytpm/dao/QuestionMapper.java
  29. 1 1
      yt-app/app-service/src/main/java/com/ytpm/handle/AppAuthExceptionEntryPoint.java
  30. 17 0
      yt-app/app-service/src/main/java/com/ytpm/service/QuestionService.java
  31. 44 0
      yt-app/app-service/src/main/java/com/ytpm/service/impl/QuestionServiceImpl.java
  32. 35 0
      yt-app/app-service/src/main/resources/bootstrap.yml
  33. 12 0
      yt-app/app-service/src/main/resources/mapper/AgentUserMapper.xml
  34. 36 0
      yt-app/app-service/src/main/resources/mapper/QuestionMapper.xml
  35. 112 0
      yt-app/pom.xml
  36. 16 0
      yt-common/src/main/java/com/ytpm/agent/model/YtChannel.java
  37. 28 0
      yt-common/src/main/java/com/ytpm/agent/view/AgentChannelView.java
  38. 15 0
      yt-common/src/main/java/com/ytpm/app/model/YtDyzAnswerRecord.java
  39. 15 0
      yt-common/src/main/java/com/ytpm/app/model/YtDyzQuestion.java
  40. 11 0
      yt-common/src/main/java/com/ytpm/app/model/YtDyzQuestionItem.java
  41. 22 0
      yt-common/src/main/java/com/ytpm/app/param/AnswerRecordParam.java
  42. 22 0
      yt-common/src/main/java/com/ytpm/app/view/QuestionItemListView.java
  43. 27 0
      yt-common/src/main/java/com/ytpm/app/view/QuestionListView.java
  44. 1 1
      yt-gateway/src/main/resources/bootstrap.yml
  45. 3 1
      yt-oauth/oauth-service/src/main/java/com/ytpm/util/EncryptUtil.java
  46. 1 1
      yt-oauth/oauth-service/src/main/resources/bootstrap.yml
  47. 1 0
      yt-risk/pom.xml
  48. 3 3
      yt-risk/risk-manage/src/main/java/com/ytpm/config/ResourceServerConfig.java
  49. 1 1
      yt-risk/risk-manage/src/main/java/com/ytpm/config/handle/RiskAuthExceptionEntryPoint.java

+ 2 - 0
pom.xml

@@ -14,6 +14,8 @@
         <module>yt-oauth</module>
         <module>yt-agent</module>
         <module>yt-risk</module>
+        <module>yt-app</module>
+        <module>yt-advertise</module>
     </modules>
 
     <properties>

+ 88 - 0
yt-advertise/advertise-service/pom.xml

@@ -0,0 +1,88 @@
+<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.ytpm</groupId>
+        <artifactId>yt-advertise</artifactId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>advertise-service</artifactId>
+    <packaging>jar</packaging>
+
+    <name>advertise-service</name>
+    <url>http://maven.apache.org</url>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-oauth2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>31.0-jre</version>
+        </dependency>
+        <dependency>
+            <groupId>com.ytpm</groupId>
+            <artifactId>agent-feign</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>com.ytpm</groupId>
+            <artifactId>risk-feign</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.5.2</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpcore</artifactId>
+            <version>4.4.5</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <finalName>app-service</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.8.1</version>
+                <configuration>
+                    <source>8</source>
+                    <target>8</target>
+                    <encoding>utf-8</encoding>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.5.3</version>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <includeSystemScope>true</includeSystemScope>
+                    <mainClass>com.ytpm.AdvertiseApplication</mainClass>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 15 - 0
yt-advertise/advertise-service/src/main/java/com/ytpm/AdvertiseApplication.java

@@ -0,0 +1,15 @@
+package com.ytpm;
+
+import org.springframework.boot.SpringApplication;
+
+/**
+ * Hello world!
+ *
+ */
+public class AdvertiseApplication
+{
+    public static void main( String[] args )
+    {
+        SpringApplication.run(AdvertiseApplication.class, args);
+    }
+}

+ 15 - 0
yt-advertise/advertise-service/src/main/java/com/ytpm/enums/AndroidFirstCategoryEnum.java

@@ -0,0 +1,15 @@
+package com.ytpm.enums;
+
+public enum AndroidFirstCategoryEnum {
+    APP(1,"App"),
+    GAME(2,"Game"),
+    FAMILY(3,"Family"),
+    ;
+    private int code;
+    private String desc;
+
+    AndroidFirstCategoryEnum(int code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+}

+ 74 - 0
yt-advertise/advertise-service/src/main/java/com/ytpm/enums/AndroidSecondCategoryEnum.java

@@ -0,0 +1,74 @@
+package com.ytpm.enums;
+
+public enum AndroidSecondCategoryEnum {
+    Daydream("Daydream",1,"Daydream"),
+    Android("Wear",1,"Android Wear"),
+    Design("Design",1,"Art & Design"),
+    Auto("Vehicles",1,"Auto & Vehicles"),
+    Beauty("Beauty",1,"Beauty"),
+    Books("Books",1,"Books & Reference"),
+    Business("Business",1,"Business"),
+    Comics("Comics",1,"Comics"),
+    Communication("Communication",1,"Communication"),
+    Dating("Dating",1,"Dating"),
+    Education("Education",1,"Education"),
+    Entertainment("Entertainment",1,"Entertainment"),
+    Events("Events",1,"Events"),
+    Finance("Finance",1,"Finance"),
+    Food("Drink",1,"Food & Drink"),
+    Health("Fitness",1,"Health & Fitness"),
+    House("House",1,"House & Home"),
+    Libraries("Libraries",1,"Libraries & Demo"),
+    Lifestyle("Lifestyle",1,"Lifestyle"),
+    Maps("Maps",1,"Maps & Navigation"),
+    Medical("Medical",1,"Medical"),
+    MusicAudio("Music",1,"Music & Audio"),
+    News("News",1,"News & Magazines"),
+    Parenting("Parenting",1,"Parenting"),
+    Personalisation("Personalisation",1,"Personalisation"),
+    Photography("Photography",1,"Photography"),
+    Productivity("Productivity",1,"Productivity"),
+    Shopping("Shopping",1,"Shopping"),
+    Social("Social",1,"Social"),
+    Sports("Sports",1,"Sports"),
+    Tools("Tools",1,"Tools"),
+    Travel("Travel",1,"Travel & Local"),
+    Video("Video",1,"Video Players & Editors"),
+    Weather("Weather",1,"Weather"),
+    Action("Action",2,"Action"),
+    Adventure("Adventure",2,"Adventure"),
+    Arcade("Arcade",2,"Arcade"),
+    Board("Board",2,"Board"),
+    Card("Card",2,"Card"),
+    Casino("Casino",2,"Casino"),
+    Casual("Casual",2,"Casual"),
+    Educational("Educational",2,"Educational"),
+    Music("Music",2,"Music"),
+    Puzzle("Puzzle",2,"Puzzle"),
+    Racing("Racing",2,"Racing"),
+    RolePlaying("RolePlaying",2,"Role Playing"),
+    Simulation("Simulation",2,"Simulation"),
+    SportsGame("SportsGame",2,"Sports"),
+    Strategy("Strategy",2,"Strategy"),
+    Trivia("Trivia",2,"Trivia"),
+    Word("Word",2,"Word"),
+    Ages5("Ages5",3,"Ages 5 & Under"),
+    Ages6("Ages6",3,"Ages 6-8"),
+    Ages9("Ages9",3,"Ages 9 & Over"),
+    ActionAdventure("ActionAdventure",3,"Action & Adventure"),
+    Brain("Brain",3,"Brain Games"),
+    Creativity("Creativity",3,"Creativity"),
+    EducationGame("EducationGame",3,"Education"),
+    MusicAndVideo("MusicAndVideo",3,"Music and video"),
+    Pretend("Pretend",3,"Pretend play"),
+    ;
+    private String code;
+    private int parentCode;
+    private String name;
+
+    AndroidSecondCategoryEnum(String code, int parentCode, String name) {
+        this.code = code;
+        this.parentCode = parentCode;
+        this.name = name;
+    }
+}

+ 30 - 0
yt-advertise/advertise-service/src/main/java/com/ytpm/enums/StoreTypeEnum.java

@@ -0,0 +1,30 @@
+package com.ytpm.enums;
+
+public enum StoreTypeEnum {
+    IOS(1,"iOS App Store"),
+    GOOGLE_PLAY(2,"Google Play"),
+    HUAWEI(3,"华为商店"),
+    XIAOMI(4,"小米应用商店"),
+    OPPO(5,"OPPO应用商店"),
+    VIVO(6,"vivo应用商店"),
+    TENCENT(7,"应用宝"),
+    TAP(8,"TapTap"),
+    Amazon(9,"Amazon应用商店"),
+    samsung(10,"三星应用商店"),
+    XIAOMI_NATION(11,"小米海外应用市场"),
+    HUAWEI_NATION(12,"华为海外应用市场"),
+    ROKU(13,"Roku"),
+    SSTV(14,"Samsung Smart TV"),
+    MICROSOFT(15,"Microsoft"),
+    LG(16,"LG Smart TV"),
+    VIZIO(17,"Vizio"),
+    OTHERS(99,"其他"),
+    ;
+    private int code;
+    private String desc;
+
+    StoreTypeEnum(int code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+}

+ 30 - 0
yt-advertise/advertise-service/src/main/java/com/ytpm/param/AddAppParam.java

@@ -0,0 +1,30 @@
+package com.ytpm.param;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class AddAppParam {
+    @ApiModelProperty(value = "1-安卓 2-IOS",required = true)
+    private Integer platform;
+    @ApiModelProperty(value = "应用名称", required = true)
+    private String name;
+    @ApiModelProperty(value = "是否应用商店上架 1-否 2-是 ",required = true)
+    private Integer store_on_sale;
+    @ApiModelProperty(value = "商店类型 枚举类StoreTypeEnum", required = false)
+    private Integer store_type;
+    @ApiModelProperty(value = "应用商店链接",required  = false)
+    private String store_url;
+    @ApiModelProperty(value = "应用包名",required = true)
+    private String package_name;
+    @ApiModelProperty(value = "一级分类", required = true)
+    private String category;
+    @ApiModelProperty(value = "二级分类",required = true)
+    private String sub_category;
+    @ApiModelProperty(value = "屏幕方向 1-竖屏 2-横屏 3-所有",required = true)
+    private Integer screen_orientation;
+    @ApiModelProperty(value = "是否遵守COPPA协议 1-否 2-是", required = true)
+    private Integer coppa;
+    @ApiModelProperty(value = "是否遵守CCPA协议 1-否 2-是", required = true)
+    private Integer ccpa;
+}

+ 12 - 0
yt-advertise/advertise-service/src/main/java/com/ytpm/service/TakuApiService.java

@@ -0,0 +1,12 @@
+package com.ytpm.service;
+
+import com.ytpm.general.Result;
+import com.ytpm.param.AddAppParam;
+
+public interface TakuApiService {
+    /**
+     * 新增应用
+     * @return
+     */
+   Result<?> addApps(AddAppParam param);
+}

+ 19 - 0
yt-advertise/advertise-service/src/main/java/com/ytpm/service/impl/TakuApiServiceImpl.java

@@ -0,0 +1,19 @@
+package com.ytpm.service.impl;
+
+import com.ytpm.general.Result;
+import com.ytpm.param.AddAppParam;
+import com.ytpm.service.TakuApiService;
+import org.springframework.stereotype.Service;
+
+@Service
+public class TakuApiServiceImpl implements TakuApiService {
+
+    /**
+     * 新增应用
+     */
+    @Override
+    public Result<?> addApps(AddAppParam param) {
+
+        return null;
+    }
+}

+ 87 - 0
yt-advertise/advertise-service/src/main/java/com/ytpm/util/TakuRequestUtil.java

@@ -0,0 +1,87 @@
+package com.ytpm.util;
+
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+
+import java.net.URL;
+
+public class TakuRequestUtil {
+
+    public final static String CONTENT_TYPE = "application/json";
+    public final static String PUBLISHER_KEY = "537981a7286b9b3dd2ba02609fe22ceeaccbf896";
+
+    public static void main(String[] args){
+        // POST example:
+        System.out.println("post response: " + doRequest(HttpPost.METHOD_NAME, "https://openapi.toponad.com/v1/apps", "{\"limit\":1}"));
+        // GET example:
+//        System.out.println("get response: " + doRequest(HttpGet.METHOD_NAME, "https://openapi.toponad.com/v1/waterfall/units?placement_id=xxx", ""));
+    }
+
+    public String doPost(String url, String reqBody) {
+        return doRequest(HttpPost.METHOD_NAME, url, reqBody);
+    }
+
+    public String doGet(String url, String reqBody) {
+        return this.doRequest(HttpGet.METHOD_NAME, url, "");
+    }
+
+    public static String doRequest(String httpMethod, String reqUrl, String reqBody) {
+        String result = null;
+        try {
+            CloseableHttpClient httpClient = HttpClients.createDefault();
+            HttpRequestBase httpRequest = null;
+            if (httpMethod.equals(HttpPost.METHOD_NAME)) {
+                HttpPost httpPost = new HttpPost(reqUrl);
+                httpPost.setEntity(new StringEntity(reqBody,"utf-8")); // 兼容中文
+//                httpPost.setEntity(new StringEntity(reqBody));
+                httpRequest = httpPost;
+            } else if (httpMethod.equals(HttpGet.METHOD_NAME)) {
+                httpRequest = new HttpGet(reqUrl);
+            } else {
+                // TODO
+            }
+            // create the final signature
+            String contentMD5 = DigestUtils.md5Hex(reqBody).toUpperCase();
+            String nowMillis = System.currentTimeMillis() + "";
+            String headerStr = "X-Up-Key:" + PUBLISHER_KEY + "\n" + "X-Up-Timestamp:" + nowMillis;
+            String relativePath = new URL(reqUrl).getPath();
+            String finalSign = genSignature(httpMethod, contentMD5, CONTENT_TYPE, headerStr, relativePath);
+            // set the headers
+            httpRequest.setHeader("Content-Type", CONTENT_TYPE);
+            httpRequest.setHeader("X-Up-Timestamp", nowMillis);
+            httpRequest.setHeader("X-Up-Key", PUBLISHER_KEY);
+            httpRequest.setHeader("X-Up-Signature", finalSign);
+
+            HttpResponse response = httpClient.execute(httpRequest);
+            if (response != null) {
+                HttpEntity resEntity = response.getEntity();
+                result = resEntity != null ? EntityUtils.toString(resEntity, "utf-8") : "";
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return result;
+    }
+
+    /**
+     * 获取签名
+     */
+    public static String genSignature(String httpMethod, String contentMD5,
+                                      String contentType, String headerStr, String relativePath) {
+        StringBuffer buf = new StringBuffer();
+        buf.append(httpMethod).append('\n').
+                append(contentMD5).append('\n').
+                append(contentType).append('\n').
+                append(headerStr).append('\n').
+                append(relativePath);
+        return DigestUtils.md5Hex(buf.toString()).toUpperCase();
+
+    }}

+ 0 - 0
yt-advertise/advertise-service/src/main/resources/bootstrap.yml


+ 108 - 0
yt-advertise/pom.xml

@@ -0,0 +1,108 @@
+<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.ytpm</groupId>
+        <artifactId>yt_platform</artifactId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>yt-advertise</artifactId>
+    <packaging>pom</packaging>
+    <description>广告API</description>
+    <modules>
+        <module>advertise-service</module>
+    </modules>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-openfeign</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>guava</artifactId>
+                    <groupId>com.google.guava</groupId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>jsr305</artifactId>
+                    <groupId>com.google.code.findbugs</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-logging</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-log4j2</artifactId>
+        </dependency>
+
+        <!--Spring Cloud Alibaba-->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>guava</artifactId>
+                    <groupId>com.google.guava</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+        </dependency>
+
+        <!--database-->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>jsqlparser</artifactId>
+                    <groupId>com.github.jsqlparser</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>com.ytpm</groupId>
+            <artifactId>yt-common</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>guava</artifactId>
+                    <groupId>com.google.guava</groupId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>jsqlparser</artifactId>
+                    <groupId>com.github.jsqlparser</groupId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>jsr305</artifactId>
+                    <groupId>com.google.code.findbugs</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+    </dependencies>
+</project>

+ 3 - 3
yt-agent/agent-service/src/main/java/com/ytpm/config/ResourceServerConfig.java

@@ -1,6 +1,6 @@
 package com.ytpm.config;
 
-import com.ytpm.handle.AuthExceptionEntryPoint;
+import com.ytpm.handle.AgentAuthExceptionEntryPoint;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
@@ -32,7 +32,7 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
     private RedisConnectionFactory redisConnectionFactory;
 
     @Autowired
-    private AuthExceptionEntryPoint authExceptionEntryPoint;
+    private AgentAuthExceptionEntryPoint agentAuthExceptionEntryPoint;
 
     @Autowired
     private CustomUserAuthenticationConverter userAuthenticationConverter;
@@ -56,7 +56,7 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
 
     @Override
     public void configure(ResourceServerSecurityConfigurer resources) {
-        resources.authenticationEntryPoint(authExceptionEntryPoint);
+        resources.authenticationEntryPoint(agentAuthExceptionEntryPoint);
         resources.resourceId("agent-service");
     }
 

+ 30 - 0
yt-agent/agent-service/src/main/java/com/ytpm/controller/AgentChannelController.java

@@ -0,0 +1,30 @@
+package com.ytpm.controller;
+
+import com.ytpm.agent.view.AgentChannelView;
+import com.ytpm.general.ResultTable;
+import com.ytpm.service.ChannelService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+@Api(tags = "广告渠道管理模块")
+@RestController
+@RequestMapping("/channel")
+public class AgentChannelController {
+
+    @Resource
+    private ChannelService channelService;
+
+    /**
+     * 获取广告渠道列表
+     */
+    @ApiOperation("获取广告渠道列表")
+    @PostMapping("/list")
+    public ResultTable<AgentChannelView> list(){
+        return channelService.channelList();
+    }
+}

+ 14 - 0
yt-agent/agent-service/src/main/java/com/ytpm/dao/ChannelMapper.java

@@ -0,0 +1,14 @@
+package com.ytpm.dao;
+
+import com.ytpm.agent.view.AgentChannelView;
+import org.mapstruct.Mapper;
+
+import java.util.List;
+
+@Mapper
+public interface ChannelMapper {
+    /**
+     * 获取渠道商列表
+     */
+    List<AgentChannelView> channelList();
+}

+ 40 - 0
yt-agent/agent-service/src/main/java/com/ytpm/handle/AgentAuthExceptionEntryPoint.java

@@ -0,0 +1,40 @@
+package com.ytpm.handle;
+
+import com.alibaba.fastjson.JSONObject;
+import com.ytpm.general.RepMessage;
+import com.ytpm.general.StatusCode;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
+import org.springframework.security.web.AuthenticationEntryPoint;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * 客户端未授权的访问处理逻辑
+ */
+@Component
+@Slf4j
+public class AgentAuthExceptionEntryPoint implements AuthenticationEntryPoint {
+    @Override
+    public void commence(HttpServletRequest request, HttpServletResponse response,
+                         AuthenticationException authException) {
+        Throwable cause = authException.getCause();
+        response.setHeader("Content-Type", "application/json;charset=UTF-8");
+        try {
+            JSONObject body = new JSONObject();
+            body.put("code", StatusCode.MANAGE_NOT_LOGIN);
+            body.put("message", RepMessage.TOKEN_EXPIRE);
+            if (!(cause instanceof InvalidTokenException)) {
+                body.put("code", StatusCode.MANAGE_NOT_LOGIN);
+                body.put("message", RepMessage.TOKEN_INVALID);
+            }
+            response.getWriter().write(body.toJSONString());
+        } catch (IOException e) {
+            log.error("token认证失败={}", e);
+        }
+    }
+}

+ 11 - 0
yt-agent/agent-service/src/main/java/com/ytpm/service/ChannelService.java

@@ -0,0 +1,11 @@
+package com.ytpm.service;
+
+import com.ytpm.agent.view.AgentChannelView;
+import com.ytpm.general.ResultTable;
+
+public interface ChannelService {
+    /**
+     * 获取渠道商列表
+     */
+    ResultTable<AgentChannelView> channelList();
+}

+ 25 - 0
yt-agent/agent-service/src/main/java/com/ytpm/service/impl/ChannelServiceImpl.java

@@ -0,0 +1,25 @@
+package com.ytpm.service.impl;
+
+import com.github.pagehelper.PageInfo;
+import com.ytpm.agent.view.AgentChannelView;
+import com.ytpm.dao.ChannelMapper;
+import com.ytpm.general.ResultTable;
+import com.ytpm.service.ChannelService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+@Service
+public class ChannelServiceImpl implements ChannelService {
+
+    @Resource
+    private ChannelMapper channelMapper;
+
+    /**
+     * 获取渠道商列表
+     */
+    @Override
+    public ResultTable<AgentChannelView> channelList() {
+        return ResultTable.resultTableOk(new PageInfo<AgentChannelView>(channelMapper.channelList()));
+    }
+}

+ 10 - 0
yt-agent/agent-service/src/main/resources/mapper/ChannelMapper.xml

@@ -0,0 +1,10 @@
+<?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.ytpm.dao.ChannelMapper">
+
+    <select id="channelList" resultType="com.ytpm.agent.view.AgentChannelView">
+        select
+            channel_id, channel_name, login_type, channel_account, channel_pwd, channel_status, api_key, api_secret, remark
+        from yt_channel
+    </select>
+</mapper>

+ 77 - 0
yt-app/app-service/pom.xml

@@ -0,0 +1,77 @@
+<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.ytpm</groupId>
+        <artifactId>yt-app</artifactId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>app-service</artifactId>
+    <packaging>jar</packaging>
+
+    <name>app-service</name>
+    <url>http://maven.apache.org</url>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-oauth2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>31.0-jre</version>
+        </dependency>
+        <dependency>
+            <groupId>com.ytpm</groupId>
+            <artifactId>agent-feign</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>com.ytpm</groupId>
+            <artifactId>risk-feign</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <finalName>app-service</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.8.1</version>
+                <configuration>
+                    <source>8</source>
+                    <target>8</target>
+                    <encoding>utf-8</encoding>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.5.3</version>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <includeSystemScope>true</includeSystemScope>
+                    <mainClass>com.ytpm.AppApplication</mainClass>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 21 - 0
yt-app/app-service/src/main/java/com/ytpm/AppApplication.java

@@ -0,0 +1,21 @@
+package com.ytpm;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@SpringBootApplication
+@EnableDiscoveryClient
+@MapperScan(basePackages = "com.ytpm.dao")
+//@EnableFeignClients(basePackages = {"com.ytpm.feign"})
+public class AppApplication
+{
+    public static void main( String[] args )
+    {
+        SpringApplication.run(AppApplication.class, args);
+    }
+}

+ 104 - 0
yt-app/app-service/src/main/java/com/ytpm/config/CustomUserAuthenticationConverter.java

@@ -0,0 +1,104 @@
+package com.ytpm.config;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.ytpm.agent.view.AgentUserInfo;
+import com.ytpm.constant.StrConstant;
+import com.ytpm.dao.AgentUserMapper;
+import com.ytpm.util.RedisService;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.AuthorityUtils;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.oauth2.provider.token.UserAuthenticationConverter;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * 自定义Security上下文信息
+ */
+@Data
+@Component
+@Slf4j
+public class CustomUserAuthenticationConverter implements UserAuthenticationConverter {
+    private Collection<? extends GrantedAuthority> defaultAuthorities =
+            new ArrayList<>(AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ADMIN"));
+    private UserDetailsService userDetailsService;
+
+    @Autowired
+    private RedisService redisService;
+    @Autowired
+    private AgentUserMapper userMapper;
+
+    @Override
+    public Map<String, ?> convertUserAuthentication(Authentication authentication) {
+        Map<String, Object> response = new LinkedHashMap();
+        response.put("username", authentication.getName());
+        if (authentication.getAuthorities() != null && !authentication.getAuthorities().isEmpty()) {
+            response.put("authorities", AuthorityUtils.authorityListToSet(authentication.getAuthorities()));
+        }
+        return response;
+    }
+
+    @Override
+    public Authentication extractAuthentication(Map<String, ?> map) {
+        if (map.containsKey("user_name")) {
+            String userName = (String) map.get("user_name");
+            Object principal;
+            Collection<? extends GrantedAuthority> authorities = this.getAuthorities(map);
+            AgentUserInfo user = userMapper.getCurrentUserInfo(userName);
+            if(Objects.isNull(user)){
+                log.error("当前用户不存在,应该退出登录");
+                return null;
+            }
+            String key = StrConstant.USER_INFO_PRE + userName ;
+            if (redisService.hasKey(key)) {
+                String str = redisService.getStr(key);
+                AgentUserInfo jwtUser = JSONObject.parseObject(str, AgentUserInfo.class);
+                principal = jwtUser;
+                authorities = jwtUser.getAuthorities();
+            } else {
+                AgentUserInfo jwtUser = new AgentUserInfo();
+                BeanUtil.copyProperties(user,jwtUser);
+                authorities = jwtUser.getAuthorities();
+                principal = jwtUser;
+                redisService.setStr(key, JSON.toJSONString(user));
+            }
+            return new UsernamePasswordAuthenticationToken(principal, "N/A", authorities);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * 用户资源授权的方法重写  暂时未使用
+     *
+     * @param map
+     * @return
+     */
+    private Collection<? extends GrantedAuthority> getAuthorities(Map<String, ?> map) {
+        if (!map.containsKey("authorities")) {
+            return this.defaultAuthorities;
+        } else {
+            Object authorities = map.get("authorities");
+            if (authorities instanceof String) {
+                return AuthorityUtils.commaSeparatedStringToAuthorityList((String) authorities);
+            } else if (authorities instanceof Collection) {
+                return AuthorityUtils.commaSeparatedStringToAuthorityList(StringUtils.collectionToCommaDelimitedString((Collection) authorities));
+            } else {
+                throw new IllegalArgumentException("Authorities must be either a String or a Collection");
+            }
+        }
+    }
+}

+ 72 - 0
yt-app/app-service/src/main/java/com/ytpm/config/ResourceServerConfig.java

@@ -0,0 +1,72 @@
+package com.ytpm.config;
+
+import com.ytpm.handle.AppAuthExceptionEntryPoint;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
+import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
+import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter;
+import org.springframework.security.oauth2.provider.token.RemoteTokenServices;
+import org.springframework.security.oauth2.provider.token.TokenStore;
+import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
+
+
+@Configuration
+@EnableResourceServer
+public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
+    @Value("${security.oauth2.client.client-id}")
+    private String clientId;
+
+    @Value("${security.oauth2.client.client-secret}")
+    private String secret;
+
+    @Value("${security.oauth2.authorization.check-token-access}")
+    private String checkTokenEndpointUrl;
+
+    @Autowired
+    private RedisConnectionFactory redisConnectionFactory;
+
+    @Autowired
+    private AppAuthExceptionEntryPoint appAuthExceptionEntryPoint;
+
+    @Autowired
+    private CustomUserAuthenticationConverter userAuthenticationConverter;
+
+    @Bean
+    public TokenStore redisTokenStore() {
+        return new RedisTokenStore(redisConnectionFactory);
+    }
+
+    @Bean
+    public RemoteTokenServices tokenService() {
+        RemoteTokenServices tokenService = new RemoteTokenServices();
+        tokenService.setClientId(clientId);
+        tokenService.setClientSecret(secret);
+        tokenService.setCheckTokenEndpointUrl(checkTokenEndpointUrl);
+        DefaultAccessTokenConverter defaultAccessTokenConverter = new DefaultAccessTokenConverter();
+        defaultAccessTokenConverter.setUserTokenConverter(userAuthenticationConverter);
+        tokenService.setAccessTokenConverter(defaultAccessTokenConverter);
+        return tokenService;
+    }
+
+    @Override
+    public void configure(ResourceServerSecurityConfigurer resources) {
+        resources.authenticationEntryPoint(appAuthExceptionEntryPoint);
+        resources.resourceId("app-service");
+    }
+
+    @Override
+    public void configure(HttpSecurity http) throws Exception {
+        http.headers().frameOptions().disable()
+                .and()
+                .authorizeRequests().antMatchers("/question/**","/api/public/**","/doc.html","/api/v2/**","/v2/api-docs", "/configuration/ui", "/swagger-resources", "/configuration/security",
+                        "/swagger-ui.html", "/webjars/**","/swagger-resources/configuration/ui","/swagger-ui.html").permitAll()
+                .anyRequest().authenticated();
+    }
+
+}

+ 40 - 0
yt-app/app-service/src/main/java/com/ytpm/config/swagger/SwaggerConfig.java

@@ -0,0 +1,40 @@
+package com.ytpm.config.swagger;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Contact;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+@Configuration
+@EnableSwagger2
+public class SwaggerConfig {
+    private static final String VERSION = "1.0.0";
+
+    @Bean
+    public Docket createApi(){
+        return new Docket(DocumentationType.SWAGGER_2)
+                .apiInfo(apiInfo())
+                .select()
+                .apis(RequestHandlerSelectors.basePackage("com.ytpm.controller"))
+                .paths(PathSelectors.any())
+                .build();
+    }
+
+    private ApiInfo apiInfo() {
+        return new ApiInfoBuilder()
+                .title("")
+                .contact(new Contact("易推网络","http://www.sourcetreasure.com/index.html","marxjaw6466@163.com"))
+                .description("代理商管理系统")
+                .termsOfServiceUrl("https://juejin.cn/user/4310510864972254")
+                .license("The Apache License, Version 2.0")
+                .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")
+                .version(VERSION)
+                .build();
+    }
+}

+ 42 - 0
yt-app/app-service/src/main/java/com/ytpm/controller/QuestionController.java

@@ -0,0 +1,42 @@
+package com.ytpm.controller;
+
+import com.ytpm.app.param.AnswerRecordParam;
+import com.ytpm.app.view.QuestionListView;
+import com.ytpm.general.Result;
+import com.ytpm.general.ResultTable;
+import com.ytpm.service.QuestionService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@Api(tags = "题目管理模块")
+@RestController
+@RequestMapping("/question")
+public class QuestionController {
+
+    @Autowired
+    private QuestionService questionService;
+
+    /**
+     * 获取题库
+     */
+    @ApiOperation("获取题库")
+    @GetMapping("/list")
+    public ResultTable<QuestionListView> questionList(){
+        return questionService.questionList();
+    }
+
+    /**
+     * 回答问题
+     */
+    @ApiOperation("回答问题")
+    @PostMapping("/answerQuestion")
+    public Result<String> answerQuestion(@RequestBody AnswerRecordParam param){
+        return questionService.answerQuestion(param);
+    }
+}

+ 39 - 0
yt-app/app-service/src/main/java/com/ytpm/controller/WxController.java

@@ -0,0 +1,39 @@
+package com.ytpm.controller;
+
+import com.ytpm.feign.RiskFeign;
+import com.ytpm.general.Result;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@Api(tags = "微信开放能力模块")
+@RestController
+@RequestMapping("/wx")
+public class WxController {
+
+    @Autowired
+    private RiskFeign riskFeign;
+
+    @PostMapping("/login")
+    @ApiOperation("微信登录")
+    public Result<?> wxLogin(@RequestParam("code")String code) {
+        //拿到授权码 请求微信登录返回access_token
+
+        //添加用户登录记录
+        return Result.resultOk();
+    }
+
+    @GetMapping("/checkRisk")
+    @ApiOperation("校验用户是否满足风控规则")
+    public Result<?> checkRisk(@Param("userId")String userId) {
+//        riskFeign.checkUserRisk(userId);
+        return Result.resultOk();
+    }
+
+}

+ 14 - 0
yt-app/app-service/src/main/java/com/ytpm/dao/AgentUserMapper.java

@@ -0,0 +1,14 @@
+package com.ytpm.dao;
+
+import com.ytpm.agent.view.AgentUserInfo;
+import org.apache.ibatis.annotations.Param;
+import org.mapstruct.Mapper;
+
+@Mapper
+public interface AgentUserMapper {
+    /**
+     * 获取当前登录用户信息
+     * @param loginName 用户名
+     */
+    AgentUserInfo getCurrentUserInfo(@Param("loginName")String loginName);
+}

+ 23 - 0
yt-app/app-service/src/main/java/com/ytpm/dao/QuestionMapper.java

@@ -0,0 +1,23 @@
+package com.ytpm.dao;
+
+import com.ytpm.app.model.YtDyzAnswerRecord;
+import com.ytpm.app.view.QuestionListView;
+import com.ytpm.general.Result;
+import org.apache.ibatis.annotations.Param;
+import org.mapstruct.Mapper;
+
+import java.util.List;
+
+@Mapper
+public interface QuestionMapper {
+
+    /**
+     * 获取题库
+     */
+    List<QuestionListView> questionList(@Param("appId")String appId);
+
+    /**
+     * 回答问题
+     */
+    void saveAnswerRecord(YtDyzAnswerRecord record);
+}

+ 1 - 1
yt-agent/agent-service/src/main/java/com/ytpm/handle/AuthExceptionEntryPoint.java → yt-app/app-service/src/main/java/com/ytpm/handle/AppAuthExceptionEntryPoint.java

@@ -18,7 +18,7 @@ import java.io.IOException;
  */
 @Component
 @Slf4j
-public class AuthExceptionEntryPoint implements AuthenticationEntryPoint {
+public class AppAuthExceptionEntryPoint implements AuthenticationEntryPoint {
     @Override
     public void commence(HttpServletRequest request, HttpServletResponse response,
                          AuthenticationException authException) {

+ 17 - 0
yt-app/app-service/src/main/java/com/ytpm/service/QuestionService.java

@@ -0,0 +1,17 @@
+package com.ytpm.service;
+
+import com.ytpm.app.param.AnswerRecordParam;
+import com.ytpm.app.view.QuestionListView;
+import com.ytpm.general.Result;
+import com.ytpm.general.ResultTable;
+
+public interface QuestionService {
+    /**
+     * 获取题库
+     */
+    ResultTable<QuestionListView> questionList();
+    /**
+     * 回答问题
+     */
+    Result<String> answerQuestion(AnswerRecordParam param);
+}

+ 44 - 0
yt-app/app-service/src/main/java/com/ytpm/service/impl/QuestionServiceImpl.java

@@ -0,0 +1,44 @@
+package com.ytpm.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.IdUtil;
+import com.github.pagehelper.PageInfo;
+import com.ytpm.app.model.YtDyzAnswerRecord;
+import com.ytpm.app.param.AnswerRecordParam;
+import com.ytpm.app.view.QuestionListView;
+import com.ytpm.dao.QuestionMapper;
+import com.ytpm.general.RepMessage;
+import com.ytpm.general.Result;
+import com.ytpm.general.ResultTable;
+import com.ytpm.service.QuestionService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.Date;
+
+@Service
+public class QuestionServiceImpl implements QuestionService {
+
+    @Resource
+    private QuestionMapper questionMapper;
+
+    /**
+     * 获取题库
+     */
+    @Override
+    public ResultTable<QuestionListView> questionList() {
+        return ResultTable.resultTableOk(new PageInfo<QuestionListView>(questionMapper.questionList("AP_202505210009")));
+    }
+    /**
+     * 回答问题
+     */
+    @Override
+    public Result<String> answerQuestion(AnswerRecordParam param) {
+        YtDyzAnswerRecord record = new YtDyzAnswerRecord();
+        BeanUtil.copyProperties(param,record);
+        record.setRecordId(IdUtil.fastSimpleUUID());
+        record.setAnswerTime(new Date());
+        questionMapper.saveAnswerRecord(record);
+        return Result.resultOk(RepMessage.SAVE_SUCCESS);
+    }
+}

+ 35 - 0
yt-app/app-service/src/main/resources/bootstrap.yml

@@ -0,0 +1,35 @@
+spring:
+  profiles:
+    active: local
+---
+spring:
+  profiles: local
+  main:
+    allow-bean-definition-overriding: true
+  application:
+    name: app-service
+  cloud:
+    nacos:
+      discovery:
+        server-addr: 127.0.0.1:8848
+        namespace: 52439154-ea03-4121-9759-44d0cacc4765
+      config:
+        server-addr: 127.0.0.1:8848
+        file-extension: yml
+        namespace: 52439154-ea03-4121-9759-44d0cacc4765
+---
+spring:
+  profiles: dev
+  main:
+    allow-bean-definition-overriding: true
+  application:
+    name: app-service
+  cloud:
+    nacos:
+      discovery:
+        server-addr: 127.0.0.1:8848
+        namespace: ad14a1aa-fe06-473a-9050-9afa26ec0020
+      config:
+        server-addr: 127.0.0.1:8848
+        file-extension: yml
+        namespace: ad14a1aa-fe06-473a-9050-9afa26ec0020

+ 12 - 0
yt-app/app-service/src/main/resources/mapper/AgentUserMapper.xml

@@ -0,0 +1,12 @@
+<?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.ytpm.dao.AgentUserMapper">
+
+    <select id="getCurrentUserInfo" resultType="com.ytpm.agent.view.AgentUserInfo">
+        select
+            user_id, nick_name, head_image, login_name, encrypt_pwd, salt, phone, last_login_time, last_login_ip, phone_brand, phone_model, account_status, channel_id, user_type, login_days, total_income, app_id, registry_time, transfer_amount
+        from yt_platform_user
+        where account_status = 1
+        and login_name = #{loginName}
+    </select>
+</mapper>

+ 36 - 0
yt-app/app-service/src/main/resources/mapper/QuestionMapper.xml

@@ -0,0 +1,36 @@
+<?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.ytpm.dao.QuestionMapper">
+
+    <resultMap id="questionListMap" type="com.ytpm.app.view.QuestionListView">
+        <id column="question_id" property="questionId" />
+        <result column="question_content" property="questionContent" />
+        <result column="question_reward" property="questionReward" />
+        <result column="correct_item" property="correctItem" />
+        <collection property="itemList" ofType="com.ytpm.app.view.QuestionItemListView">
+            <id column="item_id" property="itemId" />
+            <result column="item_header" property="itemHeader" />
+            <result column="item_content" property="itemContent" />
+            <result column="question_id" property="questionId" />
+        </collection>
+    </resultMap>
+    <insert id="saveAnswerRecord">
+        insert into yt_dyz_answer_record (record_id, question_id, item_id, duration, answer_time, user_id)
+        values (#{recordId},#{questionId},#{itemId},#{duration},#{answerTime},#{userId});
+    </insert>
+    <select id="questionList" resultMap="questionListMap">
+        SELECT
+            ydq.question_id,
+            ydq.question_content,
+            ydq.question_reward,
+            ydq.correct_item,
+            ydqi.item_id,
+            ydqi.item_header,
+            ydqi.item_content,
+            ydqi.question_id
+        FROM yt_dyz_question ydq
+        LEFT JOIN yt_dyz_question_item ydqi
+        ON ydq.question_id = ydqi.question_id
+        where app_id = #{appId}
+    </select>
+</mapper>

+ 112 - 0
yt-app/pom.xml

@@ -0,0 +1,112 @@
+<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.ytpm</groupId>
+        <artifactId>yt_platform</artifactId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>yt-app</artifactId>
+    <packaging>pom</packaging>
+    <description>易推应用管理</description>
+
+    <name>yt-app</name>
+    <url>http://maven.apache.org</url>
+    <modules>
+        <module>app-service</module>
+    </modules>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-openfeign</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>guava</artifactId>
+                    <groupId>com.google.guava</groupId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>jsr305</artifactId>
+                    <groupId>com.google.code.findbugs</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-logging</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-log4j2</artifactId>
+        </dependency>
+
+        <!--Spring Cloud Alibaba-->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>guava</artifactId>
+                    <groupId>com.google.guava</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+        </dependency>
+
+        <!--database-->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>jsqlparser</artifactId>
+                    <groupId>com.github.jsqlparser</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>com.ytpm</groupId>
+            <artifactId>yt-common</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>guava</artifactId>
+                    <groupId>com.google.guava</groupId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>jsqlparser</artifactId>
+                    <groupId>com.github.jsqlparser</groupId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>jsr305</artifactId>
+                    <groupId>com.google.code.findbugs</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+    </dependencies>
+</project>

+ 16 - 0
yt-common/src/main/java/com/ytpm/agent/model/YtChannel.java

@@ -0,0 +1,16 @@
+package com.ytpm.agent.model;
+
+import lombok.Data;
+
+@Data
+public class YtChannel {
+    private String channelId;
+    private String channelName;
+    private Integer loginType;
+    private String channelAccount;
+    private String channelPwd;
+    private Integer channelStatus;
+    private String apiKey;
+    private String apiSecret;
+    private String remark;
+}

+ 28 - 0
yt-common/src/main/java/com/ytpm/agent/view/AgentChannelView.java

@@ -0,0 +1,28 @@
+package com.ytpm.agent.view;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel("广告渠道信息")
+public class AgentChannelView {
+    @ApiModelProperty("渠道ID")
+    private String channelId;
+    @ApiModelProperty("渠道名称")
+    private String channelName;
+    @ApiModelProperty("登录类型 1-账号密码 2-微信")
+    private Integer loginType;
+    @ApiModelProperty("渠道账号")
+    private String channelAccount;
+    @ApiModelProperty("渠道密码")
+    private String channelPwd;
+    @ApiModelProperty("渠道状态")
+    private Integer channelStatus;
+    @ApiModelProperty("请求秘钥")
+    private String apiKey;
+    @ApiModelProperty("请求密令")
+    private String apiSecret;
+    @ApiModelProperty("备注")
+    private String remark;
+}

+ 15 - 0
yt-common/src/main/java/com/ytpm/app/model/YtDyzAnswerRecord.java

@@ -0,0 +1,15 @@
+package com.ytpm.app.model;
+
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class YtDyzAnswerRecord {
+    private String recordId;
+    private String questionId;
+    private String itemId;
+    private Long duration;
+    private Date answerTime;
+    private String userId;
+}

+ 15 - 0
yt-common/src/main/java/com/ytpm/app/model/YtDyzQuestion.java

@@ -0,0 +1,15 @@
+package com.ytpm.app.model;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class YtDyzQuestion {
+    private String questionId;
+    private String questionContent;
+    private BigDecimal questionReward;
+    private String appId;
+    private String correctItem;
+
+}

+ 11 - 0
yt-common/src/main/java/com/ytpm/app/model/YtDyzQuestionItem.java

@@ -0,0 +1,11 @@
+package com.ytpm.app.model;
+
+import lombok.Data;
+
+@Data
+public class YtDyzQuestionItem {
+    private String itemId;
+    private String itemHeader;
+    private String itemContent;
+    private String questionId;
+}

+ 22 - 0
yt-common/src/main/java/com/ytpm/app/param/AnswerRecordParam.java

@@ -0,0 +1,22 @@
+package com.ytpm.app.param;
+
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+
+@Data
+@ApiModel("答题记录入参")
+public class AnswerRecordParam {
+    @ApiModelProperty("答题记录ID")
+    private String recordId;
+    @ApiModelProperty("问题ID")
+    private String questionId;
+    @ApiModelProperty("回答选项ID")
+    private String itemId;
+    @ApiModelProperty("答题耗时,从题目展示开始")
+    private Long duration;
+    @ApiModelProperty("用户ID")
+    private String userId;
+}

+ 22 - 0
yt-common/src/main/java/com/ytpm/app/view/QuestionItemListView.java

@@ -0,0 +1,22 @@
+package com.ytpm.app.view;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@ApiModel("问题列表返回类")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class QuestionItemListView {
+    @ApiModelProperty("选项ID")
+    private String itemId;
+    @ApiModelProperty("选项标头 a. 1. 没有则不展示")
+    private String itemHeader;
+    @ApiModelProperty("选项内容")
+    private String itemContent;
+    @ApiModelProperty("问题ID")
+    private String questionId;
+}

+ 27 - 0
yt-common/src/main/java/com/ytpm/app/view/QuestionListView.java

@@ -0,0 +1,27 @@
+package com.ytpm.app.view;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@ApiModel("问题列表返回类")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class QuestionListView {
+    @ApiModelProperty("问题ID")
+    private String questionId;
+    @ApiModelProperty("问题内容")
+    private String questionContent;
+    @ApiModelProperty("问题奖励")
+    private BigDecimal questionReward;
+    @ApiModelProperty("正确选项")
+    private String correctItem;
+    @ApiModelProperty("选项列表")
+    private List<QuestionItemListView> itemList;
+}

+ 1 - 1
yt-gateway/src/main/resources/bootstrap.yml

@@ -1,6 +1,6 @@
 spring:
   profiles:
-    active: dev
+    active: local
 ---
 spring:
   profiles: local

+ 3 - 1
yt-oauth/oauth-service/src/main/java/com/ytpm/util/EncryptUtil.java

@@ -7,9 +7,11 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  */
 public class EncryptUtil {
     private final static String CLIENT_SECRET = "yt-secret-2025";
+    private final static String CLIENT_APP_SECRET = "ytApp-secret@2025";
     private final static String PWD = "p@ssw0rd";
+    private final static String YT_PWD = "ytAdvise";
     public static void main(String[] args) {
         BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
-        System.err.println(encoder.encode(CLIENT_SECRET));
+        System.err.println(encoder.encode(CLIENT_APP_SECRET));
     }
 }

+ 1 - 1
yt-oauth/oauth-service/src/main/resources/bootstrap.yml

@@ -1,6 +1,6 @@
 spring:
   profiles:
-    active: dev
+    active: local
 ---
 spring:
   profiles: local

+ 1 - 0
yt-risk/pom.xml

@@ -9,6 +9,7 @@
 
     <artifactId>yt-risk</artifactId>
     <packaging>pom</packaging>
+    <description>风控中心</description>
 
     <name>yt-risk</name>
     <url>http://maven.apache.org</url>

+ 3 - 3
yt-risk/risk-manage/src/main/java/com/ytpm/config/ResourceServerConfig.java

@@ -1,6 +1,6 @@
 package com.ytpm.config;
 
-import com.ytpm.config.handle.AuthExceptionEntryPoint;
+import com.ytpm.config.handle.RiskAuthExceptionEntryPoint;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
@@ -32,7 +32,7 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
     private RedisConnectionFactory redisConnectionFactory;
 
     @Autowired
-    private AuthExceptionEntryPoint authExceptionEntryPoint;
+    private RiskAuthExceptionEntryPoint riskAuthExceptionEntryPoint;
 
     @Autowired
     private CustomUserAuthenticationConverter userAuthenticationConverter;
@@ -56,7 +56,7 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
 
     @Override
     public void configure(ResourceServerSecurityConfigurer resources) {
-        resources.authenticationEntryPoint(authExceptionEntryPoint);
+        resources.authenticationEntryPoint(riskAuthExceptionEntryPoint);
         resources.resourceId("agent-service");
     }
 

+ 1 - 1
yt-risk/risk-manage/src/main/java/com/ytpm/config/handle/AuthExceptionEntryPoint.java → yt-risk/risk-manage/src/main/java/com/ytpm/config/handle/RiskAuthExceptionEntryPoint.java

@@ -18,7 +18,7 @@ import java.io.IOException;
  */
 @Component
 @Slf4j
-public class AuthExceptionEntryPoint implements AuthenticationEntryPoint {
+public class RiskAuthExceptionEntryPoint implements AuthenticationEntryPoint {
     @Override
     public void commence(HttpServletRequest request, HttpServletResponse response,
                          AuthenticationException authException) {