From 29674c95a7c1f57233c4182a72d01917a0be9689 Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Thu, 05 Feb 2026 10:36:54 +0800
Subject: [PATCH] feat(ai): 添加产品问答标签功能
---
src/main/java/cc/mrbird/febs/ai/controller/productQuestionLabel/AiProductQuestionLabelController.java | 9 ++
src/main/java/cc/mrbird/febs/ai/service/AiProductQuestionService.java | 2
src/main/java/cc/mrbird/febs/ai/controller/productQuestion/ViewController.java | 13 +++
src/main/java/cc/mrbird/febs/ai/controller/product/ViewController.java | 8 +
src/main/java/cc/mrbird/febs/ai/service/impl/AiProductQuestionServiceImpl.java | 14 +++
src/main/java/cc/mrbird/febs/ai/controller/productQuestion/AiProductQuestionController.java | 7 +
src/main/java/cc/mrbird/febs/ai/service/AiProductQuestionLabelService.java | 3
src/main/resources/templates/febs/views/modules/ai/productQuestion/list.html | 24 ++++++
src/main/resources/templates/febs/views/modules/ai/productQuestion/labelSet.html | 105 ++++++++++++++++++++++++++
src/main/java/cc/mrbird/febs/ai/service/impl/AiProductQuestionLabelServiceImpl.java | 11 ++
10 files changed, 195 insertions(+), 1 deletions(-)
diff --git a/src/main/java/cc/mrbird/febs/ai/controller/product/ViewController.java b/src/main/java/cc/mrbird/febs/ai/controller/product/ViewController.java
index d56592e..7655652 100644
--- a/src/main/java/cc/mrbird/febs/ai/controller/product/ViewController.java
+++ b/src/main/java/cc/mrbird/febs/ai/controller/product/ViewController.java
@@ -182,8 +182,14 @@
vos = allList.stream().map(AiProductQuestion -> {
AdminMoveChooseInfoVo vo = new AdminMoveChooseInfoVo();
vo.setId(AiProductQuestion.getId());
+ String name = AiProductQuestion.getTitle();
String difficulty = AiProductQuestion.getDifficulty() == 1 ? "简单" : AiProductQuestion.getDifficulty() == 2 ? "中等" : "困难";
- vo.setName(difficulty+"-"+AiProductQuestion.getTitle());
+ name = difficulty+"-"+name;
+ String label = AiProductQuestion.getLabel();
+ if (StrUtil.isNotEmpty(label)){
+ name = label+"-"+name;
+ }
+ vo.setName(name);
return vo;
}).collect(Collectors.toList());
}
diff --git a/src/main/java/cc/mrbird/febs/ai/controller/productQuestion/AiProductQuestionController.java b/src/main/java/cc/mrbird/febs/ai/controller/productQuestion/AiProductQuestionController.java
index 075ec0a..e94209a 100644
--- a/src/main/java/cc/mrbird/febs/ai/controller/productQuestion/AiProductQuestionController.java
+++ b/src/main/java/cc/mrbird/febs/ai/controller/productQuestion/AiProductQuestionController.java
@@ -146,4 +146,11 @@
public FebsResponse importDeliver(@RequestBody MultipartFile file){
return aiProductQuestionService.importDeliver(file);
}
+
+ @PostMapping("updateLabel")
+ @ControllerEndpoint(operation = "更新标签", exceptionMessage = "操作失败")
+ public FebsResponse updateLabel(@RequestBody @Valid AiProductQuestion dto) {
+
+ return aiProductQuestionService.updateLabel(dto.getIds(), dto.getLabel());
+ }
}
diff --git a/src/main/java/cc/mrbird/febs/ai/controller/productQuestion/ViewController.java b/src/main/java/cc/mrbird/febs/ai/controller/productQuestion/ViewController.java
index 06ce0ad..564a4d4 100644
--- a/src/main/java/cc/mrbird/febs/ai/controller/productQuestion/ViewController.java
+++ b/src/main/java/cc/mrbird/febs/ai/controller/productQuestion/ViewController.java
@@ -7,6 +7,7 @@
import cc.mrbird.febs.ai.service.AiProductQuestionService;
import cc.mrbird.febs.common.entity.FebsConstant;
import cc.mrbird.febs.common.utils.FebsUtil;
+import cc.mrbird.febs.mall.entity.MallMember;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
@@ -17,7 +18,9 @@
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* @author Administrator
@@ -72,4 +75,14 @@
model.addAttribute("aiProductQuestion", entity);
return FebsUtil.view("modules/ai/productQuestion/info");
}
+
+
+ @GetMapping("labelSet/{strIds}")
+ @RequiresPermissions("productQuestionList:labelSet")
+ public String vipLevelSetting(@PathVariable(value = "strIds") String strIds, Model model) {
+ Map<String, Object> data = new HashMap<>();
+ data.put("ids", strIds);
+ model.addAttribute("labelSet", data);
+ return FebsUtil.view("modules/ai/productQuestion/labelSet");
+ }
}
diff --git a/src/main/java/cc/mrbird/febs/ai/controller/productQuestionLabel/AiProductQuestionLabelController.java b/src/main/java/cc/mrbird/febs/ai/controller/productQuestionLabel/AiProductQuestionLabelController.java
index de10253..0d6a72d 100644
--- a/src/main/java/cc/mrbird/febs/ai/controller/productQuestionLabel/AiProductQuestionLabelController.java
+++ b/src/main/java/cc/mrbird/febs/ai/controller/productQuestionLabel/AiProductQuestionLabelController.java
@@ -14,6 +14,7 @@
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
+import java.util.List;
import java.util.Map;
/**
@@ -51,4 +52,12 @@
return aiProductQuestionLabelService.update(dto);
}
+
+ @GetMapping("listAll")
+ @ControllerEndpoint(operation = "获取所有标签", exceptionMessage = "获取标签失败")
+ public FebsResponse listAll() {
+ String companyId = getCurrentUserCompanyId();
+ List<AiProductQuestionLabel> labels = aiProductQuestionLabelService.listAllByCompanyId(companyId);
+ return new FebsResponse().success().data(labels);
+ }
}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/AiProductQuestionLabelService.java b/src/main/java/cc/mrbird/febs/ai/service/AiProductQuestionLabelService.java
index 79594e5..8c5663b 100644
--- a/src/main/java/cc/mrbird/febs/ai/service/AiProductQuestionLabelService.java
+++ b/src/main/java/cc/mrbird/febs/ai/service/AiProductQuestionLabelService.java
@@ -6,6 +6,7 @@
import cc.mrbird.febs.common.entity.QueryRequest;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
+import java.util.List;
public interface AiProductQuestionLabelService extends IService<AiProductQuestionLabel> {
@@ -16,4 +17,6 @@
FebsResponse add(AiProductQuestionLabel dto);
FebsResponse update(AiProductQuestionLabel dto);
+
+ List<AiProductQuestionLabel> listAllByCompanyId(String companyId);
}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/AiProductQuestionService.java b/src/main/java/cc/mrbird/febs/ai/service/AiProductQuestionService.java
index 7da398f..70c3ceb 100644
--- a/src/main/java/cc/mrbird/febs/ai/service/AiProductQuestionService.java
+++ b/src/main/java/cc/mrbird/febs/ai/service/AiProductQuestionService.java
@@ -58,4 +58,6 @@
void exportProductQuestion(AiProductQuestion dto, HttpServletResponse response);
FebsResponse importDeliver(MultipartFile file);
+
+ FebsResponse updateLabel(String ids, String label);
}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductQuestionLabelServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductQuestionLabelServiceImpl.java
index 0d0755c..526b489 100644
--- a/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductQuestionLabelServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductQuestionLabelServiceImpl.java
@@ -19,6 +19,7 @@
import org.springframework.stereotype.Service;
import java.util.Date;
+import java.util.List;
@Slf4j
@Service
@@ -72,4 +73,14 @@
}
return new FebsResponse().success().message("操作成功");
}
+
+ @Override
+ public List<AiProductQuestionLabel> listAllByCompanyId(String companyId) {
+ LambdaQueryWrapper<AiProductQuestionLabel> query = Wrappers.lambdaQuery(AiProductQuestionLabel.class);
+ if (StrUtil.isNotEmpty(companyId)){
+ query.eq(AiProductQuestionLabel::getCompanyId, companyId);
+ }
+ query.orderByDesc(AiProductQuestionLabel::getCreatedTime);
+ return aiProductQuestionLabelMapper.selectList(query);
+ }
}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductQuestionServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductQuestionServiceImpl.java
index 7c7d764..ad48fa6 100644
--- a/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductQuestionServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductQuestionServiceImpl.java
@@ -640,4 +640,18 @@
}
+ @Override
+ public FebsResponse updateLabel(String ids, String label) {
+ if (StrUtil.isEmpty(ids)) {
+ throw new FebsException("参数错误");
+ }
+ List<String> idList = StrUtil.split(ids, ',');
+ this.update(null,
+ Wrappers.lambdaUpdate(AiProductQuestion.class)
+ .set(AiProductQuestion::getLabel, label)
+ .set(AiProductQuestion::getUpdatedTime, new Date())
+ .in(AiProductQuestion::getId, idList));
+ return new FebsResponse().success().message("操作成功");
+ }
+
}
diff --git a/src/main/resources/templates/febs/views/modules/ai/productQuestion/labelSet.html b/src/main/resources/templates/febs/views/modules/ai/productQuestion/labelSet.html
new file mode 100644
index 0000000..15c9114
--- /dev/null
+++ b/src/main/resources/templates/febs/views/modules/ai/productQuestion/labelSet.html
@@ -0,0 +1,105 @@
+<style>
+ #labelSet {
+ padding: 20px 25px 25px 0;
+ }
+
+ #labelSet .layui-treeSelect .ztree li a, .ztree li span {
+ margin: 0 0 2px 3px !important;
+ }
+ #labelSet #data-permission-tree-block {
+ border: 1px solid #eee;
+ border-radius: 2px;
+ padding: 3px 0;
+ }
+ #labelSet .layui-treeSelect .ztree li span.button.switch {
+ top: 1px;
+ left: 3px;
+ }
+
+</style>
+<div class="layui-fluid" id="labelSet">
+ <form class="layui-form" action="" lay-filter="labelSet-form">
+ <div class="layui-form-item febs-hide">
+ <label class="layui-form-label febs-form-item-require">id:</label>
+ <div class="layui-input-block">
+ <input type="text" name="ids">
+ </div>
+ </div>
+ <div class="layui-form-item">
+ <div class="layui-inline">
+ <label class="layui-form-label">标签:</label>
+ <div class="layui-input-inline">
+ <select lay-verify="required" name="label" class="labelSet-level" id="labelNameSet">
+ <option value="">请选择</option>
+ </select>
+ </div>
+ </div>
+ </div>
+ <div class="layui-form-item febs-hide">
+ <button class="layui-btn" lay-submit="" lay-filter="labelSet-form-submit" id="submit"></button>
+ </div>
+ </form>
+</div>
+
+<script data-th-inline="javascript">
+ layui.use(['febs', 'form', 'formSelects', 'validate', 'treeSelect', 'eleTree'], function () {
+ var $ = layui.jquery,
+ febs = layui.febs,
+ layer = layui.layer,
+ formSelects = layui.formSelects,
+ treeSelect = layui.treeSelect,
+ form = layui.form,
+ eleTree = layui.eleTree,
+ labelSet = [[${labelSet}]],
+ $view = $('#labelSet'),
+ validate = layui.validate,
+ _deptTree;
+
+ form.render();
+
+ initLabelSetLevel();
+
+ function initLabelSetLevel() {
+ form.val("labelSet-form", {
+ "ids": labelSet.ids
+ });
+ }
+
+ //(下拉框)
+ $.get(ctx + 'admin/aiProductQuestionLabel/listAll', function (res) {
+ var data = res.data;
+ for (var k in data)
+ {
+ $(".labelSet-level").append("<option value='" + data[k].name + "'>" + data[k].name + "</option>");
+ }
+ layui.use('form', function () {
+ var form = layui.form;
+ form.render();
+ });
+ });
+
+ form.on('submit(labelSet-form-submit)', function (data) {
+ $.ajax({
+ 'url':ctx + 'admin/productQuestion/updateLabel',
+ 'type':'post',
+ 'dataType':'json',
+ 'headers' : {'Content-Type' : 'application/json;charset=utf-8'}, //接口json格式
+ 'traditional': true,//ajax传递数组必须添加属性
+ 'data':JSON.stringify(data.field),
+ 'success':function (data) {
+ if(data.code==200){
+ layer.closeAll();
+ febs.alert.success(data.message);
+ }else{
+ febs.alert.warn(data.message);
+ }
+ },
+ 'error':function () {
+ febs.alert.warn('服务器繁忙');
+ }
+ })
+ return false;
+ });
+
+ });
+</script>
\ No newline at end of file
diff --git a/src/main/resources/templates/febs/views/modules/ai/productQuestion/list.html b/src/main/resources/templates/febs/views/modules/ai/productQuestion/list.html
index ed4f8dc..f468053 100644
--- a/src/main/resources/templates/febs/views/modules/ai/productQuestion/list.html
+++ b/src/main/resources/templates/febs/views/modules/ai/productQuestion/list.html
@@ -56,6 +56,7 @@
<button class="layui-btn layui-btn-sm layui-btn-primary febs-button-green-plain" shiro:hasPermission="productQuestionList:aiAdd" lay-event="productQuestionStateOpen">启用</button>
<button class="layui-btn layui-btn-sm layui-btn-primary febs-button-green-plain" shiro:hasPermission="productQuestionList:aiAdd" lay-event="productQuestionStateClose">禁用</button>
<button class="layui-btn layui-btn-sm layui-btn-primary febs-button-green-plain" shiro:hasPermission="productQuestionList:aiAdd" lay-event="productQuestionDelete">删除</button>
+ <button class="layui-btn layui-btn-sm layui-btn-primary febs-button-green-plain" shiro:hasPermission="productQuestionList:aiAdd" lay-event="productQuestionAddLabel">打标签</button>
<button class="layui-btn layui-btn-sm layui-btn-primary febs-button-blue-plain" shiro:hasPermission="productQuestionList:aiAdd" lay-event="exportProductQuestion">导出</button>
<button class="layui-btn layui-btn-sm layui-btn-primary febs-button-blue-plain" shiro:hasPermission="productQuestionList:aiAdd" id="importProductQuestion" lay-event="importProductQuestion">导入</button>
</div>
@@ -267,6 +268,28 @@
});
window.location.href = ctx + "admin/productQuestion/exportProductQuestion?ids="+ids;
}
+ if (layEvent === 'productQuestionAddLabel') {
+ var checkData = table.checkStatus('productQuestionTable').data;
+ if (checkData.length <= 0) {
+ febs.alert.warn('请选择');
+ return;
+ }
+ var ids = [];
+ layui.each(checkData, function (key, item) {
+ ids.push(item.id)
+ });
+ let strIds = ids.join(',');
+ febs.modal.open('打标签', 'modules/ai/productQuestion/labelSet/' + strIds, {
+ btn: ['确定', '取消'],
+ area:['100%','100%'],
+ yes: function (index, layero) {
+ $('#labelSet').find('#submit').trigger('click');
+ },
+ btn2: function () {
+ layer.closeAll();
+ }
+ });
+ }
});
upload.render({
@@ -310,6 +333,7 @@
{field: 'state', title: '状态', templet: '#productQuestionStateSwitch', minWidth: 130,align:'center'},
{field: 'productCategoryName', title: '分类', minWidth: 100,align:'center'},
{field: 'title', title: '题目', minWidth: 100,align:'center'},
+ {field: 'label', title: '标签', minWidth: 100,align:'center'},
{templet:"#difficultyFormat", title: '难度', minWidth: 140,align:'center'},
{field: 'companyId', title: '公司编码', minWidth: 150,align:'center'},
]]
--
Gitblit v1.9.1