shikeying
2022-11-14 450083f7d9d5b687c732acddefb56632f7b3d5ad
添加文本推荐API接口
1 文件已重命名
6个文件已添加
8个文件已修改
460 ■■■■■ 已修改文件
deploy-jar-template/pom.xml 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
deploy-jar-template/src/main/resources/application-dev.yml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
deploy-jar-template/src/main/resources/application-test.yml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
recommend-common/pom.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
recommend-common/src/main/java/com/iplatform/reccommon/ResponseValue.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
recommend-common/src/main/java/com/iplatform/reccommon/config/RecommendConfig.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
recommend-common/src/main/java/com/iplatform/reccommon/config/TextSimilarProperties.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
recommend-text/pom.xml 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
recommend-text/src/main/java/com/iplatform/rectext/api/TextResultApi.java 211 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
recommend-text/src/main/java/com/iplatform/rectext/pojo/SearchRequest.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
recommend-text/src/main/java/com/iplatform/rectext/pojo/TextSimilar.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
recommend-text/src/main/java/com/iplatform/rectext/pojo/UploadText.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
recommend-text/src/main/java/com/iplatform/rectext/scheduler/WriteCourseToMilvus.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
recommend-video/src/main/java/com/iplatform/recvideo/api/ShowResultApi.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
recommend-video/src/main/java/com/iplatform/recvideo/config/VideoSimilarConfig.java 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
deploy-jar-template/pom.xml
@@ -18,10 +18,10 @@
    <dependencies>
<!--        <dependency>-->
<!--            <groupId>com.iplatform</groupId>-->
<!--            <artifactId>recommend-text</artifactId>-->
<!--        </dependency>-->
        <dependency>
            <groupId>com.iplatform</groupId>
            <artifactId>recommend-text</artifactId>
        </dependency>
        <dependency>
            <groupId>com.iplatform</groupId>
deploy-jar-template/src/main/resources/application-dev.yml
@@ -109,6 +109,10 @@
    business-datasource-authentication: root
    business-datasource-certification: Bjjmy_2020
  text:
    # 文本相似度服务URL
    ai-service: http://116.198.39.83:54321
#sftp:
#  host: 124.70.39.177
#  port: 22
deploy-jar-template/src/main/resources/application-test.yml
@@ -109,6 +109,11 @@
    business-datasource-authentication: root
    business-datasource-certification: Bjjmy_2020
  text:
    # 文本相似度服务URL
#    ai-service: http://116.198.39.83:54321
    ai-service: http://127.0.0.1:54321
#sftp:
#  host: 116.198.40.76
#  port: 22
recommend-common/pom.xml
@@ -45,6 +45,13 @@
            <artifactId>iplatform-gather</artifactId>
        </dependency>
        <!-- RestTemplate依赖,2022/09/23 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>
recommend-common/src/main/java/com/iplatform/reccommon/ResponseValue.java
File was renamed from recommend-video/src/main/java/com/iplatform/recvideo/ResponseValue.java
@@ -1,4 +1,4 @@
package com.iplatform.recvideo;
package com.iplatform.reccommon;
import java.io.Serializable;
import java.util.List;
recommend-common/src/main/java/com/iplatform/reccommon/config/RecommendConfig.java
New file
@@ -0,0 +1,29 @@
package com.iplatform.reccommon.config;
import com.iplatform.core.PlatformConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RecommendConfig extends PlatformConfiguration {
    /**
     * 创建远程调用对象,临时使用内置Http配置,后续会单独发布模块支持 okHttp
     * @return
     * @date 2022-09-23
     */
    @Bean
    public RestTemplate restTemplate(){
        SimpleClientHttpRequestFactory clientHttpRequestFactory = new SimpleClientHttpRequestFactory();
        clientHttpRequestFactory.setConnectTimeout(10 * 1000);
        clientHttpRequestFactory.setReadTimeout(1200 * 1000);
        return new RestTemplate(clientHttpRequestFactory);
    }
    @Bean
    public TextSimilarProperties textSimilarProperties(){
        return new TextSimilarProperties();
    }
}
recommend-common/src/main/java/com/iplatform/reccommon/config/TextSimilarProperties.java
New file
@@ -0,0 +1,17 @@
package com.iplatform.reccommon.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "recommend.text")
public class TextSimilarProperties {
    private String aiService;
    public String getAiService() {
        return aiService;
    }
    public void setAiService(String aiService) {
        this.aiService = aiService;
    }
}
recommend-text/pom.xml
@@ -24,21 +24,27 @@
        </dependency>
        <!-- 平台模块:文本相似度相似度,2022/09/08 -->
        <dependency>
            <groupId>com.iplatform</groupId>
            <artifactId>iplatform-ml-similarity</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.logging.log4j</groupId>
                    <artifactId>log4j-slf4j-impl</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
<!--        <dependency>-->
<!--            <groupId>com.iplatform</groupId>-->
<!--            <artifactId>iplatform-ml-similarity</artifactId>-->
<!--            <exclusions>-->
<!--                <exclusion>-->
<!--                    <groupId>org.slf4j</groupId>-->
<!--                    <artifactId>slf4j-api</artifactId>-->
<!--                </exclusion>-->
<!--                <exclusion>-->
<!--                    <groupId>org.apache.logging.log4j</groupId>-->
<!--                    <artifactId>log4j-slf4j-impl</artifactId>-->
<!--                </exclusion>-->
<!--            </exclusions>-->
<!--        </dependency>-->
        <!-- RestTemplate依赖,2022/09/23 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>
recommend-text/src/main/java/com/iplatform/rectext/api/TextResultApi.java
New file
@@ -0,0 +1,211 @@
package com.iplatform.rectext.api;
import com.iplatform.reccommon.ResponseValue;
import com.iplatform.reccommon.config.TextSimilarProperties;
import com.iplatform.rectext.pojo.SearchRequest;
import com.iplatform.rectext.pojo.TextSimilar;
import com.iplatform.rectext.pojo.UploadText;
import com.walker.infrastructure.utils.JsonUtils;
import com.walker.infrastructure.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/text")
public class TextResultApi {
    private final transient Logger logger = LoggerFactory.getLogger(this.getClass());
    private RestTemplate restTemplate = null;
    private TextSimilarProperties textSimilarProperties = null;
    @Autowired
    public TextResultApi(RestTemplate restTemplate, TextSimilarProperties textSimilarProperties){
        this.restTemplate = restTemplate;
        this.textSimilarProperties = textSimilarProperties;
    }
    /**
     * 业务上传课程文本分析数据。<p></p>
     * 1.请求参数格式:<br>
     * <pre>
     *     {
     *      "type":"kecheng",                           // 文本分类,业务设置标识字符串
     *      "title":["10","20","30"],                   // title为课程ID
     *      "text":["课程描述1","课程描述2","课程描述3"]    // text为课程描述等一个字符串
     *     }
     * </pre>
     * 2.响应格式:<br>
     * <pre>
     *     {"state":true, "code":1, "msg":"success"}    // 1 成功,其他失败
     * </pre>
     * @param json
     * @return
     * @author 时克英
     * @date 2022-11-03
     */
    @RequestMapping("/upload")
    public ResponseValue uploadText(@RequestBody String json){
        if(StringUtils.isEmpty(json)){
            return ResponseValue.error("上传的课程分析数据为空");
        }
        String url = this.textSimilarProperties.getAiService();
        logger.info("upload text url = " + url);
        try {
            UploadText uploadText = JsonUtils.jsonStringToObject(json, UploadText.class);
            String error = this.postUploadText(url, uploadText);
            if(error != null){
                return ResponseValue.error(error);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return ResponseValue.success();
    }
    /**
     * 给定一句话(或标签文本内容)检索出相似的课程列表,最多40个。<br>
     * 需要业务根据评分排序使用,可设置一个阈值,分数高的排前面。<p></p>
     * 1.请求参数格式:<br>
     * <pre>
     *     {"query":"他是一个会计师", "type":"kecheng"}
     * </pre>
     *
     * 2.响应格式:<br>
     * <pre>
     *     {
     *     "state": true,
     *     "code": 1,
     *     "msg": "success",
     *     "data": [
     *         {
     *         "dis": 0.3613262176513672,
     *         "id": "9",
     *         "text": "会计培训_会计全科班报名学费,零会计基础知识,欲全面学习会计专业技能,达到一般企业的熟练会计水平",
     *         "type": "kecheng"
     *         },
     *         {
     *         "dis": 0.3019663691520691,
     *         "id": "2",
     *         "text": "初级会计师考试包含哪几门呢?初级会计师考试一直是考试两门,分别为《初级会计实务》和《经济法基础》。参加初级资格考试的人员,在一个考试年度内通过全部科目的考试,才可获得初级资格证书。",
     *         "type": "kecheng"
     *         },
     *         {
     *         "dis": 0.29971787333488464,
     *         "id": "8",
     *         "text": "湖州市淘宝美工培训 淘宝电商培训报名热线,2022年湖州市春华职业培训学校开设电脑系列课程:办公、平面、美工、设计、制版、淘宝等;会计课程:基础会计,初中级会计考证,会计实务,会计全科班等,成人在职专科本科学历进修,淘宝美工爱好者、淘宝店铺经营者、平面设计爱好者。掌握网店主页美工设计、海报、焦点图、宝贝详情页的美工设计,图片空间,网站代码,实现视觉营销",
     *         "type": "kecheng"
     *         },
     *         {
     *         "dis": 0.23417186737060547,
     *         "id": "7",
     *         "text": "2022年台州玉环县成人教育学历进修报名,学习形式有自考,函授与远程教育,学制短,文凭电子注册,国家教育部承认,高升本设置专业:会计,专升本设置专业:会计,机电一体化,工商管理",
     *         "type": "kecheng"
     *         },
     *         {
     *         "dis": 0.22891874611377716,
     *         "id": "10",
     *         "text": "需要掌握财务知识的企业管理人员也可学习该课程。参加考试成绩合格颁发ATEP全国会计实务资格初级证书及会计从业资格证书",
     *         "type": "kecheng"
     *         },
     *         {
     *         "dis": 0.11250658333301544,
     *         "id": "11",
     *         "text": "海宁市成人函授大学会计专科、本科学历招生,东北农业大学网络教育学院创建于2000年7月,是全国首批三十一所远程教育试点学校之一,也是全国第一所进行现代远程教育试点的高等农业院校",
     *         "type": "kecheng"
     *         },
     *         {
     *         "dis": 0.10873384773731232,
     *         "id": "13",
     *         "text": "宁波杭州湾淘宝培训 电商运营推广班报名学费,春华淘宝开店培训班招收零基础学员、淘宝开店创业者、全职妈妈、打工仔、淘宝新手卖家,对有志于网络销售,淘宝开店等的社会各界人士,对网络零售和电子商务有更深入的理解,学习网店的建设;对网店的流程各方面都比较了解,能够独立运营网店,淘宝会员注册、支付宝实名认证、网上购物流程、淘宝店铺注册",
     *         "type": "kecheng"
     *         },
     *         {
     *         "dis": 0.07954521477222443,
     *         "id": "3",
     *         "text": "一、二级消防师考试最新教,2022年版教材明确为一、二级注册消防工程师共用,同时按照考试大纲及考查范围对一级注册消防工程师和二级注册消防工程师学习",
     *         "type": "kecheng"
     *         }
     *     ],
     *     "total": 8
     * }
     * </pre>
     * @param json
     * @return
     */
    @RequestMapping("/search")
    public ResponseValue searchTextList(@RequestBody String json){
        if(StringUtils.isEmpty(json)){
            return ResponseValue.error("缺少查询条件:{'query':'demo'}");
        }
        String url = this.textSimilarProperties.getAiService();
        logger.info("upload text url = " + url);
        try {
            SearchRequest request = JsonUtils.jsonStringToObject(json, SearchRequest.class);
            List<TextSimilar> list = this.getSearchResultList(url, request);
            if(list == null){
                return ResponseValue.error("推荐系统未返回任何相似文本集合");
            }
            return ResponseValue.success(list);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    private List<TextSimilar> getSearchResultList(String url, SearchRequest request){
        ResponseEntity<String> entity = restTemplate.postForEntity(url + "/ai/text/search", request, String.class);
        if(entity == null){
            return null;
        }
        String jsonData = entity.getBody();
        try {
            List<TextSimilar> list = JsonUtils.jsonStringToObject(jsonData, List.class);
            if(StringUtils.isEmptyList(list)){
                logger.error("\"python返回文本相似集合结果为空!\"");
                return null;
            }
            return list;
        } catch (Exception e) {
            logger.error("解析json结果错误:" + jsonData, e);
            return null;
        }
    }
    private String postUploadText(String url, UploadText request){
        ResponseEntity<String> entity = restTemplate.postForEntity(url + "/ai/text/upload", request, String.class);
        if(entity == null){
            return null;
        }
        String jsonData = entity.getBody();
        try {
            Map<String, Object> map = JsonUtils.jsonStringToObject(jsonData, Map.class);
            if(map == null || !map.containsKey("code")){
                logger.error("python返回结果为空,或者没有code标志,无法判断调用加载视频成功!");
                return "python返回结果为空,或者没有code标志,无法判断调用加载视频成功!";
            }
            String code = map.get("code").toString();
            if(code.equals("0")){
                logger.info("python upload_text_to_server() 处理成功! ");
                return null;
            }
//            logger.warn("python notify_gather_once() 加载视频处理失败, batchId = " + batchId);
            return map.get("msg") == null? "错误": map.get("msg").toString();
        } catch (Exception e) {
            logger.error("解析json结果错误:" + jsonData, e);
            return e.getMessage();
        }
    }
}
recommend-text/src/main/java/com/iplatform/rectext/pojo/SearchRequest.java
New file
@@ -0,0 +1,27 @@
package com.iplatform.rectext.pojo;
import java.io.Serializable;
public class SearchRequest implements Serializable {
    private String query = null;
    private String type = null;
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public String getQuery() {
        return query;
    }
    public void setQuery(String query) {
        this.query = query;
    }
}
recommend-text/src/main/java/com/iplatform/rectext/pojo/TextSimilar.java
New file
@@ -0,0 +1,40 @@
package com.iplatform.rectext.pojo;
import java.io.Serializable;
/**
 * 文本相似搜索结果对象。
 * @date 2022-11-03
 */
public class TextSimilar implements Serializable {
    private String id;
    private double dis = 0;
    private String text;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public double getDis() {
        return dis;
    }
    public void setDis(double dis) {
        this.dis = dis;
    }
    public String getText() {
        return text;
    }
    public void setText(String text) {
        this.text = text;
    }
}
recommend-text/src/main/java/com/iplatform/rectext/pojo/UploadText.java
New file
@@ -0,0 +1,44 @@
package com.iplatform.rectext.pojo;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
 * 业务上传的文本分析数据,主要是课程id与课程描述。
 * @author 时克英
 * @date 2022-11-03
 */
public class UploadText implements Serializable {
    private List<String> title = new ArrayList<>();
    private List<String> text = new ArrayList<>();
    private String type;
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public List<String> getTitle() {
        return title;
    }
    public void setTitle(List<String> title) {
        this.title = title;
    }
    public List<String> getText() {
        return text;
    }
    public void setText(List<String> text) {
        this.text = text;
    }
}
recommend-text/src/main/java/com/iplatform/rectext/scheduler/WriteCourseToMilvus.java
@@ -12,6 +12,7 @@
 *     2)增量拉取数据,数据先组织好写入中间表,然后调用sdk写入milvus
 * </pre>
 */
@Deprecated
public class WriteCourseToMilvus extends GatherScheduler {
    private GatherTask gatherTask;
recommend-video/src/main/java/com/iplatform/recvideo/api/ShowResultApi.java
@@ -1,7 +1,7 @@
package com.iplatform.recvideo.api;
import com.iplatform.model.po.Rc_video_user;
import com.iplatform.recvideo.ResponseValue;
import com.iplatform.reccommon.ResponseValue;
import com.iplatform.recvideo.service.VideoShowServiceImpl;
import com.walker.infrastructure.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
recommend-video/src/main/java/com/iplatform/recvideo/config/VideoSimilarConfig.java
@@ -3,8 +3,6 @@
import com.iplatform.core.PlatformConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class VideoSimilarConfig extends PlatformConfiguration {
@@ -14,16 +12,19 @@
        return new VideoSimilarProperties();
    }
    /**
     * 创建远程调用对象,临时使用内置Http配置,后续会单独发布模块支持 okHttp
     * @return
     * @date 2022-09-23
     */
    @Bean
    public RestTemplate restTemplate(){
        SimpleClientHttpRequestFactory clientHttpRequestFactory = new SimpleClientHttpRequestFactory();
        clientHttpRequestFactory.setConnectTimeout(10 * 1000);
        clientHttpRequestFactory.setReadTimeout(1200 * 1000);
        return new RestTemplate(clientHttpRequestFactory);
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //~ RestTemplate 移到common包中,2022-11-03
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//    /**
//     * 创建远程调用对象,临时使用内置Http配置,后续会单独发布模块支持 okHttp
//     * @return
//     * @date 2022-09-23
//     */
//    @Bean
//    public RestTemplate restTemplate(){
//        SimpleClientHttpRequestFactory clientHttpRequestFactory = new SimpleClientHttpRequestFactory();
//        clientHttpRequestFactory.setConnectTimeout(10 * 1000);
//        clientHttpRequestFactory.setReadTimeout(1200 * 1000);
//        return new RestTemplate(clientHttpRequestFactory);
//    }
}