Browse Source

Merge branch 'wyp/1217-articleCategory' of Server/long-article-recommend into master

fengzhoutian 6 months ago
parent
commit
5039621e05

+ 22 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/config/ManagementServiceConfiguration.java

@@ -0,0 +1,22 @@
+package com.tzld.longarticle.recommend.server.config;
+
+
+import org.apache.catalina.connector.Connector;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
+import org.springframework.boot.web.server.WebServerFactoryCustomizer;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class ManagementServiceConfiguration implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
+    @Value("${server.internal-port:8081}")
+    private Integer port;
+
+    @Override
+    public void customize(TomcatServletWebServerFactory factory) {
+        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
+        connector.setScheme("http");
+        connector.setPort(port);
+        factory.addAdditionalTomcatConnectors(connector);
+    }
+}

+ 9 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/mapper/longArticle/LongArticleBaseMapper.java

@@ -6,6 +6,7 @@ import com.tzld.longarticle.recommend.server.model.dto.LongArticlesMatchVideos;
 import com.tzld.longarticle.recommend.server.model.dto.LongArticlesText;
 import com.tzld.longarticle.recommend.server.model.entity.longArticle.*;
 import com.tzld.longarticle.recommend.server.model.param.ArticleVideoPoolSourceParam;
+import com.tzld.longarticle.recommend.server.model.vo.ArticleCategoryListVO;
 import org.apache.ibatis.annotations.Mapper;
 
 import java.util.List;
@@ -69,4 +70,12 @@ public interface LongArticleBaseMapper {
     List<String> getFilterColdLongArticleTitle();
 
     List<String> getExistsOssPath();
+
+    Integer articleCategoryCount(String title);
+
+    List<ArticleCategoryListVO> articleCategoryList(String title, Integer offset, Integer pageSize);
+
+    void updateArticleCategory(String title, String category);
+
+    void updateDatastatScoreCategory(String title, String category);
 }

+ 12 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/model/param/ArticleCategoryListParam.java

@@ -0,0 +1,12 @@
+package com.tzld.longarticle.recommend.server.model.param;
+
+
+import lombok.Data;
+
+@Data
+public class ArticleCategoryListParam {
+    private String title;
+
+    private Integer pageNum = 1;
+    private Integer pageSize = 50;
+}

+ 9 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/model/param/ArticleCategoryUpdateParam.java

@@ -0,0 +1,9 @@
+package com.tzld.longarticle.recommend.server.model.param;
+
+import lombok.Data;
+
+@Data
+public class ArticleCategoryUpdateParam {
+    private String title;
+    private String category;
+}

+ 12 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/model/vo/ArticleCategoryListVO.java

@@ -0,0 +1,12 @@
+package com.tzld.longarticle.recommend.server.model.vo;
+
+import lombok.Data;
+
+@Data
+public class ArticleCategoryListVO {
+
+    private String produceContentId;
+    private String title;
+    private String category;
+
+}

+ 36 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/recommend/ArticleCategoryService.java

@@ -0,0 +1,36 @@
+package com.tzld.longarticle.recommend.server.service.recommend;
+
+import com.tzld.longarticle.recommend.server.mapper.longArticle.LongArticleBaseMapper;
+import com.tzld.longarticle.recommend.server.model.param.ArticleCategoryListParam;
+import com.tzld.longarticle.recommend.server.model.param.ArticleCategoryUpdateParam;
+import com.tzld.longarticle.recommend.server.model.vo.ArticleCategoryListVO;
+import com.tzld.longarticle.recommend.server.util.page.Page;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@Slf4j
+public class ArticleCategoryService {
+
+    @Autowired
+    private LongArticleBaseMapper longArticleBaseMapper;
+
+
+    public Page<ArticleCategoryListVO> articleCategoryList(ArticleCategoryListParam param) {
+        int offset = (param.getPageNum() - 1) * param.getPageSize();
+        int count = longArticleBaseMapper.articleCategoryCount(param.getTitle());
+        List<ArticleCategoryListVO> list = longArticleBaseMapper.articleCategoryList(param.getTitle(), offset, param.getPageSize());
+        Page<ArticleCategoryListVO> page = new Page<>(param.getPageNum(), param.getPageSize());
+        page.setTotalSize(count);
+        page.setObjs(list);
+        return page;
+    }
+
+    public void articleCategoryUpdate(ArticleCategoryUpdateParam param) {
+        longArticleBaseMapper.updateArticleCategory(param.getTitle(), param.getCategory());
+        longArticleBaseMapper.updateDatastatScoreCategory(param.getTitle(), param.getCategory());
+    }
+}

+ 32 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/web/InternalApiFilter.java

@@ -0,0 +1,32 @@
+package com.tzld.longarticle.recommend.server.web;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+@Component
+public class InternalApiFilter extends OncePerRequestFilter {
+    @Value("${server.internal-port:8081}")
+    private Integer port;
+
+    private static final String INTERNAL_API_PATH = "/internal";
+
+    @Override
+    protected void doFilterInternal(HttpServletRequest request,
+                                    HttpServletResponse response,
+                                    FilterChain filterChain) throws ServletException, IOException {
+        if (request.getServletPath().startsWith(INTERNAL_API_PATH)) {
+            if (request.getServerPort() != port) {
+                response.sendError(HttpServletResponse.SC_FORBIDDEN);
+                return;
+            }
+        }
+        filterChain.doFilter(request, response);
+    }
+}

+ 31 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/web/recommend/ArticleCategoryController.java

@@ -0,0 +1,31 @@
+package com.tzld.longarticle.recommend.server.web.recommend;
+
+import com.tzld.longarticle.recommend.server.common.response.CommonResponse;
+import com.tzld.longarticle.recommend.server.model.param.ArticleCategoryListParam;
+import com.tzld.longarticle.recommend.server.model.param.ArticleCategoryUpdateParam;
+import com.tzld.longarticle.recommend.server.model.vo.ArticleCategoryListVO;
+import com.tzld.longarticle.recommend.server.service.recommend.ArticleCategoryService;
+import com.tzld.longarticle.recommend.server.util.page.Page;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/internal/articleCategory")
+@Slf4j
+public class ArticleCategoryController {
+
+    @Autowired
+    private ArticleCategoryService service;
+
+    @PostMapping("/list")
+    public CommonResponse<Page<ArticleCategoryListVO>> articleCategoryList(@RequestBody ArticleCategoryListParam param) {
+        return CommonResponse.success(service.articleCategoryList(param));
+    }
+
+    @PostMapping("/updateCategory")
+    public CommonResponse<Void> articleCategoryUpdate(@RequestBody ArticleCategoryUpdateParam param) {
+        service.articleCategoryUpdate(param);
+        return CommonResponse.success();
+    }
+}

+ 32 - 0
long-article-recommend-service/src/main/resources/mapper/longArticle/LongArticleBaseMapper.xml

@@ -260,4 +260,36 @@
         select distinct oss_path from long_articles_video_audit
     </select>
 
+    <select id="articleCategoryList"
+            resultType="com.tzld.longarticle.recommend.server.model.vo.ArticleCategoryListVO">
+        select produce_content_id, title, category
+        from article_category
+        <where>
+            <if test="title != null and title != ''">
+                and title like concat('%', #{title}, '%')
+            </if>
+        </where>
+        limit #{offset}, #{pageSize}
+    </select>
+
+    <select id="articleCategoryCount" resultType="java.lang.Integer">
+        select count(1)
+        from article_category
+        <where>
+            <if test="title!= null and title!= ''">
+                and title like concat('%', #{title}, '%')
+            </if>
+        </where>
+    </select>
+
+    <update id="updateArticleCategory">
+        update article_category set category = #{category} where title = #{title};
+    </update>
+
+    <update id="updateDatastatScoreCategory">
+        update datastat_score
+        set original_category = category, category = #{category}
+        where title = #{title} and category != #{category};
+    </update>
+
 </mapper>

+ 202 - 0
long-article-recommend-service/src/main/resources/static/home.html

@@ -0,0 +1,202 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>文章品类管理</title>
+    <!-- 引入 Bootstrap 样式 -->
+    <link href="https://gcore.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
+    <script src="https://gcore.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
+</head>
+<body>
+<div class="container mt-5">
+    <!-- 查询部分 -->
+    <div class="card">
+        <div class="card-header bg-primary text-white">
+            <h5>查询数据</h5>
+        </div>
+        <div class="card-body">
+            <div class="row g-3 align-items-center">
+                <div class="col-md-2">
+                    <label for="titleInput" class="form-label">标题</label>
+                </div>
+                <div class="col-md-8">
+                    <input type="text" class="form-control" id="titleInput" placeholder="请输入标题">
+                </div>
+                <div class="col-md-2">
+                    <button class="btn btn-success w-100" onclick="queryData(1)">查询</button>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <!-- 数据展示表格 -->
+    <div class="card mt-4">
+        <div class="card-header bg-secondary text-white">
+            <h5>数据列表</h5>
+        </div>
+        <div class="card-body">
+            <table class="table table-bordered table-hover">
+                <thead class="table-light">
+                <tr>
+                    <th>produce_content_id</th>
+                    <th>标题</th>
+                    <th>品类</th>
+                    <th>操作</th>
+                </tr>
+                </thead>
+                <tbody id="dataTableBody">
+                <!-- 动态数据填充 -->
+                </tbody>
+            </table>
+
+            <!-- 分页控件 -->
+            <nav aria-label="Page navigation">
+                <ul class="pagination justify-content-center" id="pagination">
+                    <!-- 分页按钮将在这里生成 -->
+                </ul>
+            </nav>
+        </div>
+    </div>
+</div>
+
+<!-- JavaScript 脚本 -->
+<script>
+    let currentPage = 1; // 当前页码
+    const pageSize = 50; // 每页显示的数据条数
+
+    window.onload = function () {
+        queryData(currentPage); // 页面加载后自动执行查询,查询第一页数据
+    };
+
+    // 查询数据:调用后端接口,支持分页
+    function queryData(page) {
+        currentPage = page; // 更新当前页码
+        const title = document.getElementById('titleInput').value;
+
+        // 调用后端查询接口
+        fetch(`http://127.0.0.1:8001/articleCategory/list`, { // 替换为实际接口
+            method: 'POST',
+            headers: {
+                'Content-Type': 'application/json',
+                'Access-Control-Allow-Origin': '*'
+            },
+            body: JSON.stringify({title: title, pageNum: currentPage, pageSize: pageSize})
+        })
+            .then(response => response.json())
+            .then(data => {
+                console.log('查询结果:', data);
+                populateTable(data.data.objs); // 渲染数据表格
+                totalPage = data.data.totalSize / pageSize;
+                renderPagination(totalPage); // 渲染分页控件
+            })
+            .catch(error => {
+                console.error('查询失败:', error);
+                alert('查询失败,请检查接口连接!');
+            });
+    }
+
+    // 渲染数据到表格
+    function populateTable(data) {
+        const tableBody = document.getElementById('dataTableBody');
+        tableBody.innerHTML = ''; // 清空旧数据
+
+        data.forEach(item => {
+            const row = `
+                    <tr>
+                        <td>${item.produceContentId}</td>
+                        <td>${item.title}</td>
+                        <td><input type="text" class="form-control" id="category-${item.produceContentId}" value="${item.category}"></td>
+                        <td>
+                            <button class="btn btn-primary btn-sm" onclick="submitData('${item.produceContentId}', '${item.title}')">提交</button>
+                        </td>
+                    </tr>
+                `;
+            tableBody.insertAdjacentHTML('beforeend', row);
+        });
+    }
+
+    // 渲染分页控件
+    function renderPagination(totalPages) {
+        const pagination = document.getElementById('pagination');
+        pagination.innerHTML = ''; // 清空旧分页
+
+        const maxVisiblePages = 5; // 最多显示的页码按钮数量
+        let startPage = Math.max(1, currentPage - Math.floor(maxVisiblePages / 2));
+        let endPage = Math.min(totalPages, startPage + maxVisiblePages - 1);
+
+        // 上一页按钮
+        pagination.insertAdjacentHTML('beforeend', `
+        <li class="page-item ${currentPage === 1 ? 'disabled' : ''}">
+            <a class="page-link" href="#" onclick="queryData(${currentPage - 1})">上一页</a>
+        </li>
+    `);
+
+        // 显示前面的省略号(如果有的话)
+        if (startPage > 1) {
+            pagination.insertAdjacentHTML('beforeend', `
+            <li class="page-item">
+                <a class="page-link" href="#" onclick="queryData(1)">1</a>
+            </li>
+            <li class="page-item disabled">
+                <span class="page-link">...</span>
+            </li>
+        `);
+        }
+
+        // 数字页码按钮
+        for (let i = startPage; i <= endPage; i++) {
+            pagination.insertAdjacentHTML('beforeend', `
+            <li class="page-item ${currentPage === i ? 'active' : ''}">
+                <a class="page-link" href="#" onclick="queryData(${i})">${i}</a>
+            </li>
+        `);
+        }
+
+        // 显示后面的省略号(如果有的话)
+        if (endPage < totalPages) {
+            pagination.insertAdjacentHTML('beforeend', `
+            <li class="page-item disabled">
+                <span class="page-link">...</span>
+            </li>
+            <li class="page-item">
+                <a class="page-link" href="#" onclick="queryData(${totalPages})">${totalPages}</a>
+            </li>
+        `);
+        }
+
+        // 下一页按钮
+        pagination.insertAdjacentHTML('beforeend', `
+        <li class="page-item ${currentPage === totalPages ? 'disabled' : ''}">
+            <a class="page-link" href="#" onclick="queryData(${currentPage + 1})">下一页</a>
+        </li>
+    `);
+    }
+
+    // 提交修改:调用后端接口
+    function submitData(id, title) {
+        ele = document.getElementById(`category-` + id);
+        const categoryInput = document.getElementById(`category-` + id).value; // 获取输入框的值
+
+        // 调用后端更新接口
+        fetch('http://127.0.0.1:8001/articleCategory/updateCategory', { // 替换为实际接口
+            method: 'POST',
+            headers: {
+                'Content-Type': 'application/json',
+                'Access-Control-Allow-Origin': '*'
+            },
+            body: JSON.stringify({title: title, category: categoryInput})
+        })
+            .then(response => response.json())
+            .then(data => {
+                console.log('修改结果:', data);
+                alert('修改成功!');
+            })
+            .catch(error => {
+                console.error('修改失败:', error);
+                alert('修改失败,请检查接口连接!');
+            });
+    }
+</script>
+</body>
+</html>