From 490bceb5d9e911a5c4f687dd6570b6699ca11915 Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Tue, 16 Sep 2025 17:27:11 +0800
Subject: [PATCH] feat(ai): 添加会员角色知识点配置功能
---
src/main/java/cc/mrbird/febs/ai/service/AiProductPointService.java | 1
src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberRoleServiceImpl.java | 32 +++++
src/main/java/cc/mrbird/febs/ai/service/impl/AiProductPointServiceImpl.java | 8 +
src/main/java/cc/mrbird/febs/ai/controller/memberRole/AiMemberRoleController.java | 7 +
src/main/java/cc/mrbird/febs/ai/service/AiMemberRolePointService.java | 14 ++
src/main/resources/templates/febs/views/modules/ai/memberRole/list.html | 19 +++
src/main/java/cc/mrbird/febs/ai/controller/memberRole/ViewController.java | 54 ++++++++-
src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberRolePointServiceImpl.java | 29 ++++
src/main/java/cc/mrbird/febs/ai/service/impl/AiProductServiceImpl.java | 11 +
src/main/resources/templates/febs/views/modules/ai/memberRole/productSet.html | 2
src/main/java/cc/mrbird/febs/ai/service/AiMemberRoleService.java | 2
src/main/resources/templates/febs/views/modules/ai/memberRole/productPointSet.html | 128 +++++++++++++++++++++
12 files changed, 295 insertions(+), 12 deletions(-)
diff --git a/src/main/java/cc/mrbird/febs/ai/controller/memberRole/AiMemberRoleController.java b/src/main/java/cc/mrbird/febs/ai/controller/memberRole/AiMemberRoleController.java
index 5c9d160..30c585c 100644
--- a/src/main/java/cc/mrbird/febs/ai/controller/memberRole/AiMemberRoleController.java
+++ b/src/main/java/cc/mrbird/febs/ai/controller/memberRole/AiMemberRoleController.java
@@ -77,4 +77,11 @@
return aiMemberRoleService.productSet(dto);
}
+
+ @PostMapping("productPointSet")
+ @ControllerEndpoint(operation = "产品知识点配置", exceptionMessage = "操作失败")
+ public FebsResponse productPointSet(@RequestBody @Valid AdminMoveChooseInfoDto dto) {
+
+ return aiMemberRoleService.productPointSet(dto);
+ }
}
diff --git a/src/main/java/cc/mrbird/febs/ai/controller/memberRole/ViewController.java b/src/main/java/cc/mrbird/febs/ai/controller/memberRole/ViewController.java
index b333218..87396e8 100644
--- a/src/main/java/cc/mrbird/febs/ai/controller/memberRole/ViewController.java
+++ b/src/main/java/cc/mrbird/febs/ai/controller/memberRole/ViewController.java
@@ -1,12 +1,8 @@
package cc.mrbird.febs.ai.controller.memberRole;
-import cc.mrbird.febs.ai.entity.AiMemberRole;
-import cc.mrbird.febs.ai.entity.AiMemberRoleProduct;
-import cc.mrbird.febs.ai.entity.AiProduct;
+import cc.mrbird.febs.ai.entity.*;
import cc.mrbird.febs.ai.res.AdminMoveChooseInfoVo;
-import cc.mrbird.febs.ai.service.AiMemberRoleProductService;
-import cc.mrbird.febs.ai.service.AiMemberRoleService;
-import cc.mrbird.febs.ai.service.AiProductService;
+import cc.mrbird.febs.ai.service.*;
import cc.mrbird.febs.common.entity.FebsConstant;
import cc.mrbird.febs.common.utils.FebsUtil;
import cn.hutool.core.collection.CollUtil;
@@ -38,7 +34,9 @@
private final AiMemberRoleService aiMemberRoleService;
private final AiMemberRoleProductService aiMemberRoleProductService;
+ private final AiMemberRolePointService aiMemberRolePointService;
private final AiProductService aiProductService;
+ private final AiProductPointService aiProductPointService;
@GetMapping("list")
@RequiresPermissions("memberRoleList:view")
@@ -75,6 +73,8 @@
LambdaQueryWrapper<AiMemberRoleProduct> query = Wrappers.lambdaQuery(AiMemberRoleProduct.class);
if(StrUtil.isNotEmpty(id)){
query.eq(AiMemberRoleProduct::getRoleId, id);
+ }
+ if(StrUtil.isNotEmpty(companyId)){
query.eq(AiMemberRoleProduct::getCompanyId, companyId);
}
List<AiMemberRoleProduct> selectedList = aiMemberRoleProductService.selectListByQuery(query);
@@ -101,4 +101,46 @@
model.addAttribute("chooseId", id);
return FebsUtil.view("modules/ai/memberRole/productSet");
}
+
+ @GetMapping("productPointSet/{id}")
+ @RequiresPermissions("memberRoleList:productPointSet")
+ public String productPointSet(@PathVariable String id, Model model) {
+ List<AdminMoveChooseInfoVo> vos = new ArrayList<>();
+ Set<String> productPointIds = new HashSet<>();
+
+ AiMemberRole entity = aiMemberRoleService.getById(id);
+ String companyId = entity.getCompanyId();
+ if(ObjectUtil.isNotNull(entity)){
+ //右侧数据
+ LambdaQueryWrapper<AiMemberRolePoint> query = Wrappers.lambdaQuery(AiMemberRolePoint.class);
+ if(StrUtil.isNotEmpty(id)){
+ query.eq(AiMemberRolePoint::getRoleId, id);
+ }
+ if(StrUtil.isNotEmpty(companyId)){
+ query.eq(AiMemberRolePoint::getCompanyId, companyId);
+ }
+ List<AiMemberRolePoint> selectedList = aiMemberRolePointService.selectListByQuery(query);
+ if(CollUtil.isNotEmpty(selectedList)){
+ //stream流操作happyMemberLabelRecords,获取memberId的set集合
+ productPointIds = selectedList.stream().map(AiMemberRolePoint::getProductPointId).collect(Collectors.toSet());
+ }
+
+ //左侧数据
+ List<AiProductPoint> allList = aiProductPointService.selectList(companyId);
+ if(CollUtil.isNotEmpty(allList)){
+ //stream流操作mallMembers,生成一个新的List<MallMemberVo>
+ vos = allList.stream().map(AiProductPoint -> {
+ AdminMoveChooseInfoVo vo = new AdminMoveChooseInfoVo();
+ vo.setId(AiProductPoint.getId());
+ vo.setName(AiProductPoint.getTitle());
+ return vo;
+ }).collect(Collectors.toList());
+ }
+ }
+
+ model.addAttribute("productPointAll", vos);
+ model.addAttribute("productPointSelected", productPointIds);
+ model.addAttribute("choosePointId", id);
+ return FebsUtil.view("modules/ai/memberRole/productPointSet");
+ }
}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/AiMemberRolePointService.java b/src/main/java/cc/mrbird/febs/ai/service/AiMemberRolePointService.java
new file mode 100644
index 0000000..eea5a14
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/AiMemberRolePointService.java
@@ -0,0 +1,14 @@
+package cc.mrbird.febs.ai.service;
+
+import cc.mrbird.febs.ai.entity.AiMemberRolePoint;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.List;
+
+public interface AiMemberRolePointService extends IService<AiMemberRolePoint> {
+
+ List<AiMemberRolePoint> selectListByQuery(LambdaQueryWrapper<AiMemberRolePoint> query);
+
+ void deleteByQuery(LambdaQueryWrapper<AiMemberRolePoint> eq);
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/AiMemberRoleService.java b/src/main/java/cc/mrbird/febs/ai/service/AiMemberRoleService.java
index e7c15f3..a39ae57 100644
--- a/src/main/java/cc/mrbird/febs/ai/service/AiMemberRoleService.java
+++ b/src/main/java/cc/mrbird/febs/ai/service/AiMemberRoleService.java
@@ -34,4 +34,6 @@
FebsResponse delete(String id);
FebsResponse productSet(AdminMoveChooseInfoDto dto);
+
+ FebsResponse productPointSet(AdminMoveChooseInfoDto dto);
}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/AiProductPointService.java b/src/main/java/cc/mrbird/febs/ai/service/AiProductPointService.java
index a75ed32..9e23052 100644
--- a/src/main/java/cc/mrbird/febs/ai/service/AiProductPointService.java
+++ b/src/main/java/cc/mrbird/febs/ai/service/AiProductPointService.java
@@ -34,4 +34,5 @@
List<AiProductPoint> pointTree(String companyId);
+ List<AiProductPoint> selectList(String companyId);
}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberRolePointServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberRolePointServiceImpl.java
new file mode 100644
index 0000000..0100c57
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberRolePointServiceImpl.java
@@ -0,0 +1,29 @@
+package cc.mrbird.febs.ai.service.impl;
+
+import cc.mrbird.febs.ai.entity.AiMemberRolePoint;
+import cc.mrbird.febs.ai.mapper.AiMemberRolePointMapper;
+import cc.mrbird.febs.ai.service.AiMemberRolePointService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class AiMemberRolePointServiceImpl extends ServiceImpl<AiMemberRolePointMapper, AiMemberRolePoint> implements AiMemberRolePointService {
+
+ private final AiMemberRolePointMapper aiMemberRolePointMapper;
+ @Override
+ public List<AiMemberRolePoint> selectListByQuery(LambdaQueryWrapper<AiMemberRolePoint> query) {
+ return aiMemberRolePointMapper.selectList( query);
+ }
+
+ @Override
+ public void deleteByQuery(LambdaQueryWrapper<AiMemberRolePoint> eq) {
+ aiMemberRolePointMapper.delete( eq);
+ }
+}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberRoleServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberRoleServiceImpl.java
index 2151bc3..488e56b 100644
--- a/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberRoleServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberRoleServiceImpl.java
@@ -1,9 +1,11 @@
package cc.mrbird.febs.ai.service.impl;
import cc.mrbird.febs.ai.entity.AiMemberRole;
+import cc.mrbird.febs.ai.entity.AiMemberRolePoint;
import cc.mrbird.febs.ai.entity.AiMemberRoleProduct;
import cc.mrbird.febs.ai.mapper.AiMemberRoleMapper;
import cc.mrbird.febs.ai.req.AdminMoveChooseInfoDto;
+import cc.mrbird.febs.ai.service.AiMemberRolePointService;
import cc.mrbird.febs.ai.service.AiMemberRoleProductService;
import cc.mrbird.febs.ai.service.AiMemberRoleService;
import cc.mrbird.febs.ai.service.AiProductService;
@@ -40,6 +42,7 @@
private final AiMemberRoleMapper aiMemberRoleMapper;
private final AiProductService aiProductService;
private final AiMemberRoleProductService aiMemberRoleProductService;
+ private final AiMemberRolePointService aiMemberRolePointService;
private final IUserService iUserService;
@Override
@@ -148,4 +151,33 @@
}
return new FebsResponse().success().message("操作成功");
}
+
+ @Override
+ public FebsResponse productPointSet(AdminMoveChooseInfoDto dto) {
+
+ String chooseId = dto.getChooseId();
+ List<String> chooseIds = dto.getChooseIds();
+ AiMemberRole aiMemberRole = this.getById(chooseId);
+ if (ObjectUtil.isNotNull(aiMemberRole)) {
+ String companyId = aiMemberRole.getCompanyId();
+ aiMemberRolePointService.deleteByQuery(
+ Wrappers.lambdaQuery(AiMemberRolePoint.class)
+ .eq(AiMemberRolePoint::getRoleId,chooseId)
+ .eq(AiMemberRolePoint::getCompanyId,companyId)
+ );
+ if(CollUtil.isNotEmpty(chooseIds)){
+ Date createdTime = new Date();
+ for (String item : chooseIds){
+ AiMemberRolePoint entity = new AiMemberRolePoint();
+ entity.setId(UUID.getSimpleUUIDString());
+ entity.setRoleId(chooseId);
+ entity.setProductPointId(item);
+ entity.setCompanyId(companyId);
+ entity.setCreatedTime(createdTime);
+ aiMemberRolePointService.getBaseMapper().insert(entity);
+ }
+ }
+ }
+ return new FebsResponse().success().message("操作成功");
+ }
}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductPointServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductPointServiceImpl.java
index c496f82..4bde82d 100644
--- a/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductPointServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductPointServiceImpl.java
@@ -131,6 +131,14 @@
return aiProductPointMapper.selectList(query);
}
+ @Override
+ public List<AiProductPoint> selectList(String companyId) {
+ LambdaQueryWrapper<AiProductPoint> query = Wrappers.lambdaQuery(AiProductPoint.class);
+ if (StrUtil.isNotEmpty(companyId)){
+ query.eq(AiProductPoint::getCompanyId, companyId);
+ }
+ return aiProductPointMapper.selectList(query);
+ }
}
diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductServiceImpl.java
index 2a934fb..3135b2e 100644
--- a/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiProductServiceImpl.java
@@ -162,11 +162,12 @@
@Override
public List<AiProduct> selectList(String companyId) {
- return aiProductMapper.selectList(
- Wrappers.lambdaQuery(AiProduct.class)
- .eq(AiProduct::getCompanyId, companyId)
- .ne(AiProduct::getState, 2)
- );
+ LambdaQueryWrapper<AiProduct> query = Wrappers.lambdaQuery(AiProduct.class);
+ if (StrUtil.isNotEmpty(companyId)){
+ query.eq(AiProduct::getCompanyId, companyId);
+ }
+ query.ne(AiProduct::getState, 2);
+ return aiProductMapper.selectList(query);
}
@Override
diff --git a/src/main/resources/templates/febs/views/modules/ai/memberRole/list.html b/src/main/resources/templates/febs/views/modules/ai/memberRole/list.html
index fb030b9..476dca4 100644
--- a/src/main/resources/templates/febs/views/modules/ai/memberRole/list.html
+++ b/src/main/resources/templates/febs/views/modules/ai/memberRole/list.html
@@ -47,6 +47,7 @@
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm layui-btn-primary febs-button-green-plain" shiro:hasPermission="memberRoleList:add" lay-event="memberRoleAdd">新增</button>
<button class="layui-btn layui-btn-sm layui-btn-primary febs-button-green-plain" shiro:hasPermission="memberRoleList:productSet" lay-event="productSet">产品配置</button>
+ <button class="layui-btn layui-btn-sm layui-btn-primary febs-button-green-plain" shiro:hasPermission="memberRoleList:productPointSet" lay-event="productPointSet">知识点配置</button>
</div>
</script>
@@ -193,6 +194,24 @@
}
});
}
+
+ if (layEvent === 'productPointSet') {
+ var checkData = table.checkStatus('memberRoleTable').data;
+ if (checkData.length > 1 || checkData.length === 0) {
+ febs.alert.warn('每次操作只能操作一行数据');
+ return;
+ }
+ febs.modal.open('知识点配置', 'modules/ai/memberRole/productPointSet/' + checkData[0].id, {
+ btn: ['提交', '取消'],
+ area:['100%','100%'],
+ yes: function (index, layero) {
+ $('#productPoint-set').find('#submit').trigger('click');
+ },
+ btn2: function () {
+ layer.closeAll();
+ }
+ });
+ }
});
function initMemberRoleTable() {
diff --git a/src/main/resources/templates/febs/views/modules/ai/memberRole/productPointSet.html b/src/main/resources/templates/febs/views/modules/ai/memberRole/productPointSet.html
new file mode 100644
index 0000000..bf937bc
--- /dev/null
+++ b/src/main/resources/templates/febs/views/modules/ai/memberRole/productPointSet.html
@@ -0,0 +1,128 @@
+<div class="layui-fluid layui-anim febs-anim" id="productPoint-set" lay-title="知识点配置">
+ <div class="layui-row febs-container">
+ <div class="layui-col-md12">
+ <div class="layui-fluid" id="product-type-set">
+ <form class="layui-form" action="" lay-filter="product-type-set-form">
+ <div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
+ <ul class="layui-tab-title">
+ <li class="layui-this">知识点配置</li>
+ </ul>
+ <div class="layui-tab-content">
+ <input type="text" name="chooseId"
+ placeholder="" autoComplete="off" class="layui-input febs-hide">
+ <div class="layui-tab-item layui-show">
+ <div class="layui-form-item">
+ <div id="productPointSetMove"></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="layui-form-item febs-hide">
+ <button class="layui-btn" lay-submit="" lay-filter="product-type-set-form-submit" id="submit">保存</button>
+ </div>
+ </form>
+ </div>
+ </div>
+ </div>
+</div>
+
+<script data-th-inline="javascript">
+ layui.use(['febs','form', 'transfer'], function () {
+ var $ = layui.jquery,
+ febs = layui.febs,
+ layer = layui.layer,
+ form = layui.form,
+ transfer = layui.transfer,
+ productTypeAll = [[${productPointAll}]],
+ productTypeChoose = [[${productPointSelected}]],
+ chooseId = [[${choosePointId}]],
+ $view = $('#productPoint-set'),
+
+ $productPointSetQuery = $view.find('#productPointSetQuery')
+ ;
+
+ // 查询按钮
+ $productPointSetQuery.on('click', function () {
+ console.log(transfer.getData('productPointSet-set'))
+
+ let data1 = transfer.getData('productPointSet-set');
+ //获取data1中的value,返回一个数组
+ let productPointIdList = data1.map(function(item){
+ return item.value;
+ });
+
+ console.log(productPointIdList)
+ });
+
+
+ form.render();
+
+ initProductTypeSet();
+
+ function initProductTypeSet() {
+ console.log("productTypeAll:", productTypeAll); // 调试信息
+ console.log("productTypeChoose:", productTypeChoose); // 调试信息
+ console.log("chooseId:", chooseId); // 调试信息
+ form.val("product-type-set-form", {
+ "chooseId": chooseId,
+ });
+ // 转换数据格式(假设接口返回的数据结构需要处理)
+ var dataLeft = productTypeAll.map(function(item){
+ return {
+ value: item.id, // 值字段
+ title: item.name // 显示文本
+ }
+ });
+ var dataRight = productTypeChoose.map(function(item){
+ return {
+ value: item, // 值字段
+ }
+ });
+
+ // 渲染穿梭框
+ transfer.render({
+ elem: '#productPointSetMove',
+ data: dataLeft,
+ id: 'productPointSet-set', // 唯一标识
+ title: ['待选择列表', '已选择列表'],
+ width: 300,
+ height: 400,
+ showSearch: true,
+ value: productTypeChoose,
+ });
+ }
+
+ form.on('submit(product-type-set-form-submit)', function (data) {
+ let data1 = transfer.getData('productPointSet-set');
+ //获取data1中的value,返回一个数组
+ let productPointIdList = data1.map(function(item){
+ return item.value;
+ });
+ data.field.chooseIds = productPointIdList;
+ data.field.chooseId = chooseId;
+ $.ajax({
+ 'url':ctx + 'admin/memberRole/productPointSet',
+ '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);
+ $('#febs-memberRole').find('#query').click();
+ }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/memberRole/productSet.html b/src/main/resources/templates/febs/views/modules/ai/memberRole/productSet.html
index 7e412a3..249c749 100644
--- a/src/main/resources/templates/febs/views/modules/ai/memberRole/productSet.html
+++ b/src/main/resources/templates/febs/views/modules/ai/memberRole/productSet.html
@@ -111,7 +111,7 @@
if(data.code==200){
layer.closeAll();
febs.alert.success(data.message);
- $('#febs-type').find('#query').click();
+ $('#febs-memberRole').find('#query').click();
}else{
febs.alert.warn(data.message);
}
--
Gitblit v1.9.1