commit
68edff71a5
@ -1,6 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17 (2)" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/ruoyi-study.iml" filepath="$PROJECT_DIR$/.idea/ruoyi-study.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,39 @@
|
||||
package com.ruoyi.system.Enum;
|
||||
|
||||
/**
|
||||
* @author: Larry
|
||||
* @Date: 2023 /12 /06 / 15:23
|
||||
* @Description:
|
||||
*/
|
||||
public enum VideoTagEnum {
|
||||
ACTION(1, "鬼畜"),
|
||||
COMEDY(2, "色情"),
|
||||
DRAMA(3, "运动"),
|
||||
ROMANCE(4, "火影忍者");
|
||||
|
||||
private int id;
|
||||
private String type;
|
||||
|
||||
VideoTagEnum(int id, String type) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public static VideoTagEnum getById(int id) {
|
||||
for (VideoTagEnum tag : values()) {
|
||||
if (tag.getId() == id) {
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid VideoTagEnum id: " + id);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,40 @@
|
||||
package com.ruoyi.system.Interceptor;
|
||||
|
||||
import com.zy.util.BaseContext;
|
||||
import com.zy.util.TokenUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author: Larry
|
||||
* @Date: 2023 /11 /22 / 21:40
|
||||
* @Description:
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class LoginInterceptor implements HandlerInterceptor {
|
||||
@Resource
|
||||
RedisTemplate<String,String> redisTemplate;
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
String token = request.getHeader("token");
|
||||
log.info(token);
|
||||
Long userId = TokenUtil.verifyToken(token);
|
||||
if (userId > 0) {
|
||||
BaseContext.setCurrentId(userId);
|
||||
Date passTime = TokenUtil.getTokenExpirationTime(token);
|
||||
log.info(passTime.toString());
|
||||
redisTemplate.opsForValue().set("token"+userId,passTime.toString(),1, TimeUnit.HOURS);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.ruoyi.system.Interceptor;
|
||||
|
||||
import com.zy.util.TokenUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* @author: Larry
|
||||
* @Date: 2023 /11 /23 / 8:40
|
||||
* @Description:
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class RefreshTokenInterceptor implements HandlerInterceptor {
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
String token = request.getHeader("token");
|
||||
try {
|
||||
Long id = TokenUtil.verifyToken(token);
|
||||
TokenUtil.generateRefreshToken(id);
|
||||
log.info("刷新成功");
|
||||
return true ;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
package com.ruoyi.system.adapter.repository;
|
||||
|
||||
import cn.bugstack.domain.activity.adapter.repository.IActivityRepository;
|
||||
import cn.bugstack.domain.activity.model.valobj.GroupBuyActivityDiscountVO;
|
||||
import cn.bugstack.domain.activity.model.valobj.SkuVO;
|
||||
import cn.bugstack.infrastructure.dao.IGroupBuyActivityDao;
|
||||
import cn.bugstack.infrastructure.dao.IGroupBuyDiscountDao;
|
||||
import cn.bugstack.infrastructure.dao.ISkuDao;
|
||||
import cn.bugstack.infrastructure.dao.po.GroupBuyActivity;
|
||||
import cn.bugstack.infrastructure.dao.po.GroupBuyDiscount;
|
||||
import cn.bugstack.infrastructure.dao.po.Sku;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* @author Fuzhengwei bugstack.cn @小傅哥
|
||||
* @description 活动仓储
|
||||
* @create 2024-12-21 10:10
|
||||
*/
|
||||
@Repository
|
||||
public class ActivityRepository implements IActivityRepository {
|
||||
|
||||
@Resource
|
||||
private IGroupBuyActivityDao groupBuyActivityDao;
|
||||
@Resource
|
||||
private IGroupBuyDiscountDao groupBuyDiscountDao;
|
||||
|
||||
@Resource
|
||||
private ISkuDao skuDao;
|
||||
|
||||
@Override
|
||||
public GroupBuyActivityDiscountVO queryGroupBuyActivityDiscountVO(String source, String channel) {
|
||||
// 根据SC渠道值查询配置中最新的1个有效的活动
|
||||
GroupBuyActivity groupBuyActivityReq = new GroupBuyActivity();
|
||||
groupBuyActivityReq.setSource(source);
|
||||
groupBuyActivityReq.setChannel(channel);
|
||||
GroupBuyActivity groupBuyActivityRes = groupBuyActivityDao.queryValidGroupBuyActivity(groupBuyActivityReq);
|
||||
|
||||
String discountId = groupBuyActivityRes.getDiscountId();
|
||||
|
||||
GroupBuyDiscount groupBuyDiscountRes = groupBuyDiscountDao.queryGroupBuyActivityDiscountByDiscountId(discountId);
|
||||
GroupBuyActivityDiscountVO.GroupBuyDiscount groupBuyDiscount = GroupBuyActivityDiscountVO.GroupBuyDiscount.builder()
|
||||
.discountName(groupBuyDiscountRes.getDiscountName())
|
||||
.discountDesc(groupBuyDiscountRes.getDiscountDesc())
|
||||
.discountType(groupBuyDiscountRes.getDiscountType())
|
||||
.marketPlan(groupBuyDiscountRes.getMarketPlan())
|
||||
.marketExpr(groupBuyDiscountRes.getMarketExpr())
|
||||
.tagId(groupBuyDiscountRes.getTagId())
|
||||
.build();
|
||||
|
||||
return GroupBuyActivityDiscountVO.builder()
|
||||
.activityId(groupBuyActivityRes.getActivityId())
|
||||
.activityName(groupBuyActivityRes.getActivityName())
|
||||
.source(groupBuyActivityRes.getSource())
|
||||
.channel(groupBuyActivityRes.getChannel())
|
||||
.goodsId(groupBuyActivityRes.getGoodsId())
|
||||
.groupBuyDiscount(groupBuyDiscount)
|
||||
.groupType(groupBuyActivityRes.getGroupType())
|
||||
.takeLimitCount(groupBuyActivityRes.getTakeLimitCount())
|
||||
.target(groupBuyActivityRes.getTarget())
|
||||
.validTime(groupBuyActivityRes.getValidTime())
|
||||
.status(groupBuyActivityRes.getStatus())
|
||||
.startTime(groupBuyActivityRes.getStartTime())
|
||||
.endTime(groupBuyActivityRes.getEndTime())
|
||||
.tagId(groupBuyActivityRes.getTagId())
|
||||
.tagScope(groupBuyActivityRes.getTagScope())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SkuVO querySkuByGoodsId(String goodsId) {
|
||||
Sku sku = skuDao.querySkuByGoodsId(goodsId);
|
||||
return SkuVO.builder()
|
||||
.goodsId(sku.getGoodsId())
|
||||
.goodsName(sku.getGoodsName())
|
||||
.originalPrice(sku.getOriginalPrice())
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.ruoyi.system.ai.annotation;
|
||||
import com.muta.ai.chain.DefaultChainFactory;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
/**
|
||||
* @author: Larry
|
||||
* @Date: 2024 /05 /01 / 0:10
|
||||
* @Description: 规则过滤注解
|
||||
*/
|
||||
@Target({ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface LogicStrategy {
|
||||
DefaultChainFactory.LogicModel logicMode();
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package com.ruoyi.system.ai.chain;
|
||||
|
||||
import com.muta.ai.annotation.LogicStrategy;
|
||||
import com.muta.ai.chain.MusicProcessAggregate;
|
||||
import com.muta.ai.domain.RuleLogicEntity;
|
||||
import com.muta.ai.chain.UserAccountQuotaEntity;
|
||||
import com.muta.ai.chain.DefaultChainFactory;
|
||||
import com.muta.ai.chain.AbstractLogicChain;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author Fuzhengwei bugstack.cn @小傅哥
|
||||
* @description 黑名单责任链
|
||||
* @create 2024-01-20 10:23
|
||||
*/
|
||||
@Slf4j
|
||||
@Component("rule_blacklist")
|
||||
@LogicStrategy(logicMode = DefaultChainFactory.LogicModel.RULE_BLACKLIST)
|
||||
public class BackListLogicChain extends AbstractLogicChain {
|
||||
|
||||
;
|
||||
|
||||
@Override
|
||||
protected String ruleModel() {
|
||||
return DefaultChainFactory.LogicModel.RULE_BLACKLIST.getCode();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RuleLogicEntity<MusicProcessAggregate> logic(UserAccountQuotaEntity userAccountQuotaEntity, MusicProcessAggregate chatProcessAggregate) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.ruoyi.system.ai.chain;
|
||||
|
||||
import com.muta.ai.annotation.LogicStrategy;
|
||||
import com.muta.ai.chain.MusicProcessAggregate;
|
||||
import com.muta.ai.domain.RuleLogicEntity;
|
||||
import com.muta.ai.chain.UserAccountQuotaEntity;
|
||||
import com.muta.ai.chain.DefaultChainFactory;
|
||||
import com.muta.ai.chain.AbstractLogicChain;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author Fuzhengwei bugstack.cn @小傅哥
|
||||
* @description 默认的责任链「作为最后一个链」
|
||||
* @create 2024-01-20 10:06
|
||||
*/
|
||||
@Slf4j
|
||||
@Component("rule_default")
|
||||
@LogicStrategy(logicMode = DefaultChainFactory.LogicModel.RULE_DEFAULT)
|
||||
public class DefaultLogicChain extends AbstractLogicChain {
|
||||
|
||||
|
||||
@Override
|
||||
protected String ruleModel() {
|
||||
return DefaultChainFactory.LogicModel.RULE_DEFAULT.getCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RuleLogicEntity<MusicProcessAggregate> logic(UserAccountQuotaEntity userAccountQuotaEntity, MusicProcessAggregate chatProcessAggregate) {
|
||||
System.out.println("测试注入");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.ruoyi.system.ai.chain;
|
||||
|
||||
import com.muta.ai.domain.RuleLogicEntity;
|
||||
|
||||
/**
|
||||
* @author Fuzhengwei bugstack.cn @小傅哥
|
||||
* @description 抽奖策略规则责任链接口
|
||||
* @create 2024-01-20 09:40
|
||||
*/
|
||||
public interface ILogicChain<T> extends ILogicChainArmory<T>, Cloneable {
|
||||
|
||||
/**
|
||||
* 责任链接口
|
||||
*/
|
||||
RuleLogicEntity<MusicProcessAggregate> logic(UserAccountQuotaEntity userAccountQuotaEntity, MusicProcessAggregate data);
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.ruoyi.system.ai.chain;
|
||||
|
||||
/**
|
||||
* @author Fuzhengwei bugstack.cn @小傅哥
|
||||
* @description 责任链装配
|
||||
* @create 2024-01-20 11:53
|
||||
*/
|
||||
public interface ILogicChainArmory<T> {
|
||||
|
||||
ILogicChain<T> next();
|
||||
|
||||
ILogicChain<T> appendNext(ILogicChain<T> next);
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.ruoyi.system.ai.chain;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Fuzhengwei bugstack.cn @小傅哥
|
||||
* @description
|
||||
* @create 2023-07-22 21:09
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class MusicProcessAggregate {
|
||||
/**
|
||||
* 歌手ID
|
||||
*/
|
||||
private Long singerId;
|
||||
/**
|
||||
* 音乐ID
|
||||
*/
|
||||
private Integer musicId;
|
||||
/** 提示词 */
|
||||
private String prompt;
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.ruoyi.system.ai.chain;
|
||||
|
||||
|
||||
import com.muta.ai.annotation.LogicStrategy;
|
||||
import com.muta.ai.chain.MusicProcessAggregate;
|
||||
import com.muta.ai.domain.RuleLogicEntity;
|
||||
import com.muta.ai.chain.UserAccountQuotaEntity;
|
||||
import com.muta.ai.chain.DefaultChainFactory;
|
||||
import com.muta.ai.chain.AbstractLogicChain;
|
||||
import com.muta.system.service.IUserExtraService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* @author Fuzhengwei bugstack.cn @小傅哥
|
||||
* @description 权重抽奖责任链
|
||||
* @create 2024-01-20 10:38
|
||||
*/
|
||||
@Slf4j
|
||||
@Component("rule_UserAccountQuota")
|
||||
@LogicStrategy(logicMode = DefaultChainFactory.LogicModel.RULE_WEIGHT)
|
||||
public class RuleWeightLogicChain extends AbstractLogicChain {
|
||||
@Resource
|
||||
private IUserExtraService userExtraService;
|
||||
|
||||
@Override
|
||||
protected String ruleModel() {
|
||||
return DefaultChainFactory.LogicModel.RULE_WEIGHT.getCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RuleLogicEntity<MusicProcessAggregate> logic(UserAccountQuotaEntity userAccountQuotaEntity, MusicProcessAggregate chatProcessAggregate) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package com.ruoyi.system.ai.chain;
|
||||
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Fuzhengwei bugstack.cn @小傅哥
|
||||
* @description 用户账户额度实体对象
|
||||
* @create 2023-10-03 16:49
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class UserAccountQuotaEntity {
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long userId;
|
||||
/**
|
||||
* 剩余额度
|
||||
*/
|
||||
private Integer integral;
|
||||
/**
|
||||
* 会员等级
|
||||
*/
|
||||
private Integer vipGrade;
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.ruoyi.system.ai.config;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author: Larry
|
||||
* @Date: 2024 /05 /11 / 14:18
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class ChatConfig {
|
||||
private Long id;
|
||||
private Long userId;
|
||||
private float temperature;
|
||||
private Integer maxToken;
|
||||
private Integer n;
|
||||
private float top;
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.ruoyi.system.ai.config;
|
||||
|
||||
import com.github.houbb.sensitive.word.api.IWordAllow;
|
||||
import org.apache.commons.compress.utils.Lists;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 自定义敏感词白名单
|
||||
*
|
||||
* @author Larry
|
||||
* @date 2024-05-18 15:07:01
|
||||
*/
|
||||
public class CustomWordAllow implements IWordAllow {
|
||||
|
||||
/**
|
||||
* 允许的内容-返回的内容不被当做敏感词
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<String> allow() {
|
||||
// 可以获取数据库数据或文件内容
|
||||
List<String> list = new ArrayList<>();
|
||||
list.add("草");
|
||||
list.add("小草");
|
||||
list.add("");
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.ruoyi.system.ai.config;
|
||||
|
||||
import com.github.houbb.sensitive.word.api.IWordDeny;
|
||||
import org.apache.commons.compress.utils.Lists;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 自定义敏感词黑名单
|
||||
*
|
||||
* @author Larry
|
||||
* @date 2024-05-08 14:59:51
|
||||
*/
|
||||
public class CustomWordDeny implements IWordDeny {
|
||||
|
||||
/**
|
||||
* 拒绝出现的数据-返回的内容被当做是敏感词
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<String> deny() {
|
||||
// 可以获取数据库数据或文件内容
|
||||
List<String> list = new ArrayList<>();
|
||||
list.add("测试");
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package com.ruoyi.system.ai.config;//package com.muta.ai.config;
|
||||
//
|
||||
//import com.muta.ai.chain.UserAccountQuotaEntity;
|
||||
//import com.muta.ai.service.ILogicFilter;
|
||||
//import com.muta.ai.service.impl.SensitiveWordFilter;
|
||||
//import com.muta.ai.service.impl.TokenFilter;
|
||||
//import com.muta.ai.service.impl.UserQuotaFilter;
|
||||
//
|
||||
//import javax.annotation.PostConstruct;
|
||||
//import javax.annotation.Resource;
|
||||
//import java.util.Map;
|
||||
//import java.util.concurrent.ConcurrentHashMap;
|
||||
//
|
||||
///**
|
||||
// * @author: Larry
|
||||
// * @Date: 2024 /05 /09 / 20:35
|
||||
// * @Description:
|
||||
// */
|
||||
//public class LogicConfig {
|
||||
// public Map<String, ILogicFilter<UserAccountQuotaEntity>> logicFilterMap = new ConcurrentHashMap<>();
|
||||
// @Resource
|
||||
// private SensitiveWordFilter sensitiveWordFilter;
|
||||
// @Resource
|
||||
// private TokenFilter tokenFilter;
|
||||
// @Resource
|
||||
// private UserQuotaFilter userQuotaFilter;
|
||||
// @PostConstruct
|
||||
// private void init(){
|
||||
// logicFilterMap.put(LogicModel.SENSITIVE_WORD.code,sensitiveWordFilter);
|
||||
// logicFilterMap.put(LogicModel.MAX_TOKEN.code,tokenFilter);
|
||||
// logicFilterMap.put(LogicModel.USER_QUOTA.code, userQuotaFilter);
|
||||
//
|
||||
// }
|
||||
// public enum LogicModel {
|
||||
//
|
||||
// NULL("NULL", "放行不用过滤"),
|
||||
// MAX_TOKEN("TOKEN_LIMIT", "限制最大会话数"),
|
||||
// SENSITIVE_WORD("SENSITIVE_WORD", "敏感词过滤"),
|
||||
// USER_QUOTA("USER_QUOTA", "用户额度过滤"),
|
||||
//// MODEL_TYPE("MODEL_TYPE", "模型可用范围过滤"),
|
||||
//// ACCOUNT_STATUS("ACCOUNT_STATUS", "账户状态过滤"),
|
||||
//
|
||||
// ;
|
||||
//
|
||||
// private String code;
|
||||
// private String info;
|
||||
//
|
||||
// LogicModel(String code, String info) {
|
||||
// this.code = code;
|
||||
// this.info = info;
|
||||
// }
|
||||
//
|
||||
// public String getCode() {
|
||||
// return code;
|
||||
// }
|
||||
//
|
||||
// public void setCode(String code) {
|
||||
// this.code = code;
|
||||
// }
|
||||
//
|
||||
// public String getInfo() {
|
||||
// return info;
|
||||
// }
|
||||
//
|
||||
// public void setInfo(String info) {
|
||||
// this.info = info;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
@ -0,0 +1,30 @@
|
||||
package com.ruoyi.system.ai.config;
|
||||
|
||||
import com.github.houbb.sensitive.word.bs.SensitiveWordBs;
|
||||
import com.github.houbb.sensitive.word.core.SensitiveWordHelper;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 敏感词过滤配置
|
||||
*
|
||||
* @author 一个肥鲇鱼
|
||||
* @date 2023-09-08 14:28:45
|
||||
*/
|
||||
@Configuration
|
||||
public class SensitiveWordConfig {
|
||||
|
||||
/**
|
||||
* 初始化引导类
|
||||
*
|
||||
* @return 初始化引导类
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Bean(value = "sensitiveWordBsBean")
|
||||
public SensitiveWordBs sensitiveWordBs() {
|
||||
System.out.println("测试");
|
||||
// 设置系统默认敏感词
|
||||
return SensitiveWordBs.newInstance().wordDeny(new CustomWordDeny()).wordAllow(new CustomWordAllow()).init();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.ruoyi.system.ai.config;
|
||||
|
||||
import org.springframework.boot.web.servlet.ServletContextInitializer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
|
||||
import org.springframework.web.util.WebAppRootListener;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
/**
|
||||
* @author Frankiefly
|
||||
* 2024/3/23
|
||||
*/
|
||||
|
||||
@Configuration
|
||||
public class WebSocketConfiguration implements ServletContextInitializer {
|
||||
|
||||
@Bean
|
||||
public ServerEndpointExporter serverEndpointExporter(){
|
||||
return new ServerEndpointExporter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartup(ServletContext servletContext) throws ServletException {
|
||||
servletContext.addListener(WebAppRootListener.class);
|
||||
//这里设置了1024M的缓冲区
|
||||
//Tomcat每次请求过来时在创建session时都会把这个webSocketContainer作为参数传进去所以对所有的session都生效了
|
||||
servletContext.setInitParameter("org.apache.tomcat.websocket.textBufferSize","1024000");
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,524 @@
|
||||
package com.ruoyi.system.ai.config.server;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.google.gson.Gson;
|
||||
import com.muta.ai.domain.ChatCompletionMessage;
|
||||
import io.reactivex.BackpressureStrategy;
|
||||
import io.reactivex.Flowable;
|
||||
import netscape.javascript.JSObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Client {
|
||||
private static final String DEFAULT_BASE_URL = "https://api.moonshot.cn/v1";
|
||||
|
||||
private static final String CHAT_COMPLETION_SUFFIX = "/chat/completions";
|
||||
private static final String MODELS_SUFFIX = "/models";
|
||||
private static final String FILES_SUFFIX = "/files";
|
||||
|
||||
private String baseUrl;
|
||||
private String apiKey;
|
||||
|
||||
public Client(String apiKey) {
|
||||
this(apiKey, DEFAULT_BASE_URL);
|
||||
}
|
||||
|
||||
public Client(String apiKey, String baseUrl) {
|
||||
this.apiKey = apiKey;
|
||||
if (baseUrl.endsWith("/")) {
|
||||
baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
|
||||
}
|
||||
this.baseUrl = baseUrl;
|
||||
}
|
||||
|
||||
public String getChatCompletionUrl() {
|
||||
return baseUrl + CHAT_COMPLETION_SUFFIX;
|
||||
}
|
||||
|
||||
public String getModelsUrl() {
|
||||
return baseUrl + MODELS_SUFFIX;
|
||||
}
|
||||
|
||||
public String getFilesUrl() {
|
||||
return baseUrl + FILES_SUFFIX;
|
||||
}
|
||||
|
||||
public String getApiKey() {
|
||||
return apiKey;
|
||||
}
|
||||
|
||||
public ModelsList ListModels() throws IOException {
|
||||
okhttp3.OkHttpClient client = new okhttp3.OkHttpClient();
|
||||
okhttp3.Request request = new okhttp3.Request.Builder()
|
||||
.url(getModelsUrl())
|
||||
.addHeader("Authorization", "Bearer " + getApiKey())
|
||||
.build();
|
||||
try {
|
||||
okhttp3.Response response = client.newCall(request).execute();
|
||||
String body = response.body().string();
|
||||
Gson gson = new Gson();
|
||||
return gson.fromJson(body, ModelsList.class);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public ChatCompletionResponse ChatCompletion(ChatCompletionRequest request) throws IOException {
|
||||
request.stream = false;
|
||||
okhttp3.OkHttpClient client = new okhttp3.OkHttpClient();
|
||||
okhttp3.MediaType mediaType = okhttp3.MediaType.parse("application/json");
|
||||
okhttp3.RequestBody body = okhttp3.RequestBody.create(mediaType, new Gson().toJson(request));
|
||||
okhttp3.Request httpRequest = new okhttp3.Request.Builder()
|
||||
.url(getChatCompletionUrl())
|
||||
.addHeader("Authorization", "Bearer " + getApiKey())
|
||||
.addHeader("Content-Type", "application/json")
|
||||
.post(body)
|
||||
.build();
|
||||
try {
|
||||
okhttp3.Response response = client.newCall(httpRequest).execute();
|
||||
String responseBody = response.body().string();
|
||||
System.out.println(responseBody);
|
||||
Gson gson = new Gson();
|
||||
return gson.fromJson(responseBody, ChatCompletionResponse.class);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// return a stream of ChatCompletionStreamResponse
|
||||
public Flowable<ChatCompletionStreamResponse> ChatCompletionStream(ChatCompletionRequest request) throws IOException {
|
||||
request.stream = true;
|
||||
okhttp3.OkHttpClient client = new okhttp3.OkHttpClient();
|
||||
okhttp3.MediaType mediaType = okhttp3.MediaType.parse("application/json");
|
||||
okhttp3.RequestBody body = okhttp3.RequestBody.create(mediaType, new Gson().toJson(request));
|
||||
okhttp3.Request httpRequest = new okhttp3.Request.Builder()
|
||||
.url(getChatCompletionUrl())
|
||||
.addHeader("Authorization", "Bearer " + getApiKey())
|
||||
.addHeader("Content-Type", "application/json")
|
||||
.post(body)
|
||||
.build();
|
||||
okhttp3.Response response = client.newCall(httpRequest).execute();
|
||||
if (response.code() != 200) {
|
||||
System.err.println(response);
|
||||
throw new RuntimeException("Failed to start stream: " + response.body().string());
|
||||
}
|
||||
|
||||
// get response body line by line
|
||||
return Flowable.create(emitter -> {
|
||||
okhttp3.ResponseBody responseBody = response.body();
|
||||
if (responseBody == null) {
|
||||
emitter.onError(new RuntimeException("Response body is null"));
|
||||
return;
|
||||
}
|
||||
String line;
|
||||
while ((line = responseBody.source().readUtf8Line()) != null) {
|
||||
if (line.startsWith("data:")) {
|
||||
line = line.substring(5);
|
||||
line = line.trim();
|
||||
}
|
||||
if (Objects.equals(line, "[DONE]")) {
|
||||
emitter.onComplete();
|
||||
return;
|
||||
}
|
||||
line = line.trim();
|
||||
if (line.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
//System.out.println(line);
|
||||
Gson gson = new Gson();
|
||||
ChatCompletionStreamResponse streamResponse = gson.fromJson(line, ChatCompletionStreamResponse.class);
|
||||
emitter.onNext(streamResponse);
|
||||
}
|
||||
emitter.onComplete();
|
||||
}, BackpressureStrategy.BUFFER);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
enum ChatMessageRole {
|
||||
SYSTEM, USER, ASSISTANT;
|
||||
|
||||
public String value() {
|
||||
return this.name().toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
class ChatCompletionStreamChoiceDelta {
|
||||
private String content;
|
||||
private String role;
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public String getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public void setRole(String role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public ChatCompletionStreamChoiceDelta(String content, String role) {
|
||||
this.content = content;
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ChatCompletionStreamChoiceDelta{" +
|
||||
"content='" + content + '\'' +
|
||||
", role='" + role + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
class Usage {
|
||||
private int prompt_tokens;
|
||||
private int completion_tokens;
|
||||
private int total_tokens;
|
||||
|
||||
public int getPrompt_tokens() {
|
||||
return prompt_tokens;
|
||||
}
|
||||
|
||||
public void setPrompt_tokens(int prompt_tokens) {
|
||||
this.prompt_tokens = prompt_tokens;
|
||||
}
|
||||
|
||||
public int getCompletion_tokens() {
|
||||
return completion_tokens;
|
||||
}
|
||||
|
||||
public void setCompletion_tokens(int completion_tokens) {
|
||||
this.completion_tokens = completion_tokens;
|
||||
}
|
||||
|
||||
public int getTotal_tokens() {
|
||||
return total_tokens;
|
||||
}
|
||||
|
||||
public void setTotal_tokens(int total_tokens) {
|
||||
this.total_tokens = total_tokens;
|
||||
}
|
||||
|
||||
public Usage(int prompt_tokens, int completion_tokens, int total_tokens) {
|
||||
this.prompt_tokens = prompt_tokens;
|
||||
this.completion_tokens = completion_tokens;
|
||||
this.total_tokens = total_tokens;
|
||||
}
|
||||
|
||||
public Usage() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Usage{" +
|
||||
"prompt_tokens=" + prompt_tokens +
|
||||
", completion_tokens=" + completion_tokens +
|
||||
", total_tokens=" + total_tokens +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
class ChatCompletionStreamChoice {
|
||||
private int index;
|
||||
private ChatCompletionStreamChoiceDelta delta;
|
||||
|
||||
@SerializedName("finish_reason")
|
||||
private String finishReason;
|
||||
private Usage usage;
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public ChatCompletionStreamChoiceDelta getDelta() {
|
||||
return delta;
|
||||
}
|
||||
|
||||
public String getFinishReason() {
|
||||
return finishReason;
|
||||
}
|
||||
|
||||
public Usage getUsage() {
|
||||
return usage;
|
||||
}
|
||||
|
||||
public void setIndex(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public void setDelta(ChatCompletionStreamChoiceDelta delta) {
|
||||
this.delta = delta;
|
||||
}
|
||||
|
||||
public void setFinishReason(String finishReason) {
|
||||
this.finishReason = finishReason;
|
||||
}
|
||||
|
||||
public void setUsage(Usage usage) {
|
||||
this.usage = usage;
|
||||
}
|
||||
|
||||
public ChatCompletionStreamChoice(int index, ChatCompletionStreamChoiceDelta delta, String finishReason, Usage usage) {
|
||||
this.index = index;
|
||||
this.delta = delta;
|
||||
this.finishReason = finishReason;
|
||||
this.usage = usage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ChatCompletionStreamChoice{" +
|
||||
"index=" + index +
|
||||
", delta=" + delta +
|
||||
", finishReason='" + finishReason + '\'' +
|
||||
", usage=" + usage +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
class ChatCompletionStreamResponse {
|
||||
private String id;
|
||||
private String object;
|
||||
private long created;
|
||||
private String model;
|
||||
private List<ChatCompletionStreamChoice> choices;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
public long getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public String getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public List<ChatCompletionStreamChoice> getChoices() {
|
||||
return choices;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setObject(String object) {
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
public void setCreated(long created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ChatCompletionStreamResponse{" +
|
||||
"id='" + id + '\'' +
|
||||
", object='" + object + '\'' +
|
||||
", created=" + created +
|
||||
", model='" + model + '\'' +
|
||||
", choices=" + choices +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
class ChatCompletionChoice {
|
||||
private int index;
|
||||
private ChatCompletionMessage message;
|
||||
|
||||
@SerializedName("finish_reason")
|
||||
private String finishReason;
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public ChatCompletionMessage getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public String getFinishReason() {
|
||||
return finishReason;
|
||||
}
|
||||
|
||||
public void setIndex(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public void setMessage(ChatCompletionMessage message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public void setFinishReason(String finishReason) {
|
||||
this.finishReason = finishReason;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ChatCompletionResponse {
|
||||
private String id;
|
||||
private String object;
|
||||
private long created;
|
||||
private String model;
|
||||
private List<ChatCompletionChoice> choices;
|
||||
private Usage usage;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
public long getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public String getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public List<ChatCompletionChoice> getChoices() {
|
||||
if (choices == null) {
|
||||
return List.of();
|
||||
}
|
||||
return choices;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ChatCompletionRequest {
|
||||
public String model;
|
||||
public List<ChatCompletionMessage> messages;
|
||||
|
||||
@SerializedName("max_tokens")
|
||||
public int maxTokens;
|
||||
|
||||
@SerializedName("temperature")
|
||||
public float temperature;
|
||||
public float topP;
|
||||
|
||||
public Integer n;
|
||||
public boolean stream;
|
||||
public List<String> stop;
|
||||
|
||||
@SerializedName("presence_penalty")
|
||||
public float presencePenalty;
|
||||
|
||||
@SerializedName("frequency_penalty")
|
||||
public float frequencyPenalty;
|
||||
|
||||
public String user;
|
||||
|
||||
public List<ChatCompletionMessage> getMessages() {
|
||||
return messages;
|
||||
}
|
||||
|
||||
public ChatCompletionRequest(String model, List<ChatCompletionMessage> messages, int maxTokens, float temperature, int n, float topP) {
|
||||
this.model = model;
|
||||
this.messages = messages;
|
||||
this.maxTokens = maxTokens;
|
||||
this.temperature = temperature;
|
||||
this.n = n;
|
||||
this.topP = topP;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Model {
|
||||
private String id;
|
||||
private String object;
|
||||
|
||||
@SerializedName("owner_by")
|
||||
private String ownedBy;
|
||||
private String root;
|
||||
private String parent;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
public String getOwnedBy() {
|
||||
return ownedBy;
|
||||
}
|
||||
|
||||
public String getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
public String getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setObject(String object) {
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
public void setOwnedBy(String ownedBy) {
|
||||
this.ownedBy = ownedBy;
|
||||
}
|
||||
|
||||
public void setRoot(String root) {
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
public void setParent(String parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public Model(String id, String object, String ownedBy, String root, String parent) {
|
||||
this.id = id;
|
||||
this.object = object;
|
||||
this.ownedBy = ownedBy;
|
||||
this.root = root;
|
||||
this.parent = parent;
|
||||
}
|
||||
}
|
||||
|
||||
class ModelsList {
|
||||
private List<Model> data;
|
||||
|
||||
public List<Model> getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(List<Model> data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public ModelsList(List<Model> data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,187 @@
|
||||
package com.ruoyi.system.ai.config.server;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.muta.ai.chain.MusicProcessAggregate;
|
||||
import com.muta.ai.chain.UserAccountQuotaEntity;
|
||||
import com.muta.ai.config.ChatConfig;
|
||||
import com.muta.ai.domain.*;
|
||||
import com.muta.ai.enums.LogicCheckEnum;
|
||||
import com.muta.ai.service.IChatConfigService;
|
||||
import com.muta.ai.service.IMessageFileService;
|
||||
import com.muta.ai.service.impl.KimiChatService;
|
||||
import com.muta.common.utils.StringUtils;
|
||||
import org.json.JSONObject;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
import javax.annotation.Resource;
|
||||
import javax.websocket.*;
|
||||
import javax.websocket.server.PathParam;
|
||||
import javax.websocket.server.ServerEndpoint;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@Component
|
||||
@ServerEndpoint(value = "/chatgpt/{sid}")
|
||||
public class WebSocketServer {
|
||||
|
||||
private static IChatConfigService chatConfigService;
|
||||
|
||||
private static RedisTemplate<String, ChatCompletionMessage> redisTemplate;
|
||||
|
||||
private static KimiChatService kimiChatService;
|
||||
|
||||
private static IMessageFileService messageFileService;
|
||||
|
||||
@Resource
|
||||
public void setChatConfigService(IChatConfigService chatConfigService) {
|
||||
WebSocketServer.chatConfigService = chatConfigService;
|
||||
}
|
||||
|
||||
@Resource
|
||||
public void setMessageFileService(IMessageFileService messageFileService) {
|
||||
WebSocketServer.messageFileService = messageFileService;
|
||||
}
|
||||
|
||||
@Resource
|
||||
public void setKimiChatService(KimiChatService kimiChatService) {
|
||||
WebSocketServer.kimiChatService = kimiChatService;
|
||||
}
|
||||
|
||||
@Resource
|
||||
public void setChatgptService(RedisTemplate redisTemplate) {
|
||||
WebSocketServer.redisTemplate = redisTemplate;
|
||||
}
|
||||
|
||||
private static Map<String, Session> sessionMap = new HashMap<>();
|
||||
|
||||
@OnOpen
|
||||
public void onOpen(Session session, @PathParam("sid") String sid) {
|
||||
System.out.println("客户端: " + sid + "建立连接");
|
||||
sessionMap.put(sid, session);
|
||||
}
|
||||
|
||||
@OnMessage
|
||||
public void onMessage(String jsonFrom, @PathParam("sid") String sid) throws Exception {
|
||||
JSONObject jsonParse = new JSONObject(jsonFrom);
|
||||
|
||||
String url = jsonFrom.contains("\"url\"") ? jsonParse.getString("url") : null;
|
||||
String content = jsonParse.getString("content");
|
||||
String model = jsonParse.getString("model");
|
||||
|
||||
if (StringUtils.isNotEmpty(url)) {
|
||||
content += " " + messageFileService.getContentByUrl(url);
|
||||
}
|
||||
|
||||
Long userId = Long.valueOf(sid.split(":")[0]);
|
||||
|
||||
List<ChatCompletionMessage> history = redisTemplate.opsForSet().members(sid).stream().collect(Collectors.toList());
|
||||
List<ChatCompletionMessage> messages = CollectionUtil.isEmpty(history) ? new ArrayList<>() : history;
|
||||
messages.add(new ChatCompletionMessage(ChatMessageRole.USER.value(), content));
|
||||
|
||||
for (ChatCompletionMessage message : messages) {
|
||||
System.out.println(message.toString());
|
||||
}
|
||||
|
||||
|
||||
MusicProcessAggregate chatProcessAggregate = kimiChatService.initChatData(userId, model, messages);
|
||||
System.out.println(chatProcessAggregate.toString());
|
||||
UserAccountQuotaEntity userAccountQuotaEntity = kimiChatService.initUserData(userId);
|
||||
System.out.println(userAccountQuotaEntity.toString());
|
||||
//
|
||||
RuleLogicEntity<MusicProcessAggregate> logicRes = kimiChatService.doCheckLogic(chatProcessAggregate, userAccountQuotaEntity);
|
||||
if(logicRes.getType().equals(LogicCheckEnum.REFUSE)){
|
||||
sendToClient(sid, logicRes.getInfo());
|
||||
}
|
||||
else {
|
||||
System.err.println(chatProcessAggregate.getKey());
|
||||
Client client = new Client(chatProcessAggregate.getKey());
|
||||
StringBuffer stringBuffer = new StringBuffer();
|
||||
|
||||
AtomicBoolean flag = new AtomicBoolean(true);
|
||||
AtomicReference<String> role = new AtomicReference<>();
|
||||
ChatConfig config = chatConfigService.selectChatConfigById(userId);
|
||||
|
||||
|
||||
try {
|
||||
|
||||
String finalContent = content;
|
||||
client.ChatCompletionStream(new ChatCompletionRequest(
|
||||
model,
|
||||
messages,
|
||||
userAccountQuotaEntity.getMaxToken(),
|
||||
config.getTemperature(),
|
||||
config.getN(),
|
||||
config.getTop()
|
||||
)).subscribe(
|
||||
streamResponse -> {
|
||||
if (streamResponse.getChoices().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (ChatCompletionStreamChoice choice : streamResponse.getChoices()) {
|
||||
if (flag.getAndSet(false)) {
|
||||
role.set(choice.getDelta().getRole());
|
||||
}
|
||||
String finishReason = choice.getFinishReason();
|
||||
System.out.println(choice.getDelta().getContent());
|
||||
stringBuffer.append(choice.getDelta().getContent());
|
||||
if (finishReason != null) {
|
||||
System.out.println(streamResponse);
|
||||
System.out.println(sid);
|
||||
MessageEntity messageEntity
|
||||
= MessageEntity.builder()
|
||||
.model(streamResponse.getModel())
|
||||
.role(role.get())
|
||||
.userId(userId)
|
||||
.content(stringBuffer.toString())
|
||||
.finishReason(finishReason)
|
||||
.promptTokens(choice.getUsage().getPrompt_tokens())
|
||||
.completionTokens(choice.getUsage().getCompletion_tokens())
|
||||
.totalTokens(choice.getUsage().getTotal_tokens())
|
||||
.sessionId(sid)
|
||||
.build();
|
||||
|
||||
System.out.println(messageEntity.toString());
|
||||
kimiChatService.PostRule(chatProcessAggregate,userAccountQuotaEntity, messageEntity);
|
||||
continue;
|
||||
}
|
||||
sendToClient(sid, choice.getDelta().getContent());
|
||||
}
|
||||
},
|
||||
error -> {
|
||||
error.printStackTrace();
|
||||
},
|
||||
() -> {
|
||||
System.out.println("complete");
|
||||
|
||||
// redisTemplate.opsForSet().remove(sid);
|
||||
// Set<ChatCompletionMessage> members = redisTemplate.opsForSet().members(sid);
|
||||
// members.add(new ChatCompletionMessage(ChatMessageRole.USER.value(), finalContent));
|
||||
redisTemplate.opsForSet().add(sid, new ChatCompletionMessage(ChatMessageRole.USER.value(), finalContent));
|
||||
}
|
||||
);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OnClose
|
||||
public void onClose(@PathParam("sid") String sid){
|
||||
System.out.println("连接断开: " + sid);
|
||||
sessionMap.remove(sid);
|
||||
}
|
||||
|
||||
public void sendToClient(String sid, String result){
|
||||
Session session = sessionMap.get(sid);
|
||||
try {
|
||||
session.getBasicRemote().sendText(result);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,50 @@
|
||||
package com.ruoyi.system.ai.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.muta.common.core.MutaBaseEntity;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class AiKey extends MutaBaseEntity {
|
||||
|
||||
/** 主键 */
|
||||
@TableId(value = "id",type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/** key值 */
|
||||
@TableField("`key`")
|
||||
private String key;
|
||||
|
||||
/** 代理 */
|
||||
@TableField("`host`")
|
||||
private String host;
|
||||
|
||||
/** 可用模型 */
|
||||
@TableField("`model_list`")
|
||||
private String modelList;
|
||||
|
||||
/** ai类型 */
|
||||
@TableField("`type`")
|
||||
private Integer type;
|
||||
|
||||
/** 状态 */
|
||||
@TableField("`status`")
|
||||
private String status;
|
||||
|
||||
/** 额度 */
|
||||
@TableField("`limit`")
|
||||
private BigDecimal limit;
|
||||
/** 用户id */
|
||||
@TableField("`user_id`")
|
||||
private Long userId;
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.ruoyi.system.ai.domain;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class ChatCompletionMessage {
|
||||
public String role;
|
||||
public String name;
|
||||
public String content;
|
||||
public Boolean partial;
|
||||
|
||||
public ChatCompletionMessage(String role, String content) {
|
||||
this.role = role;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public ChatCompletionMessage(String role, String name, String content, Boolean partial) {
|
||||
this.role = role;
|
||||
this.name = name;
|
||||
this.content = content;
|
||||
this.partial = partial;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public Boolean getPartial() {
|
||||
return partial;
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.ruoyi.system.ai.domain;//package com.muta.ai.domain;
|
||||
//
|
||||
//import com.baomidou.mybatisplus.annotation.TableName;
|
||||
//import lombok.AllArgsConstructor;
|
||||
//import lombok.Builder;
|
||||
//import lombok.Data;
|
||||
//import lombok.NoArgsConstructor;
|
||||
//
|
||||
///**
|
||||
// * @author: Larry
|
||||
// * @Date: 2024 /05 /11 / 14:18
|
||||
// * @Description:
|
||||
// */
|
||||
//@Data
|
||||
//@AllArgsConstructor
|
||||
//@NoArgsConstructor
|
||||
//@Builder
|
||||
//@TableName("chat_config")
|
||||
//public class ChatConfig {
|
||||
// private Long id;
|
||||
// private Long userId;
|
||||
// private float temperature;
|
||||
// private String maxToken;
|
||||
// private Integer n;
|
||||
// private float top;
|
||||
//}
|
@ -0,0 +1,46 @@
|
||||
package com.ruoyi.system.ai.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.muta.common.core.MutaBaseEntity;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author: Larry
|
||||
* @Date: 2024 /05 /09 / 13:17
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class MessageEntity extends MutaBaseEntity {
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
private Long userId;
|
||||
|
||||
private String content;
|
||||
|
||||
private String role;
|
||||
|
||||
private String model;
|
||||
|
||||
private String url;
|
||||
|
||||
private String finishReason;
|
||||
|
||||
private String sessionId;
|
||||
|
||||
private Integer promptTokens;
|
||||
|
||||
private Integer completionTokens;
|
||||
|
||||
private Integer totalTokens;
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.ruoyi.system.ai.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.muta.common.core.MutaBaseEntity;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author 马兰友
|
||||
* @Date: 2024/05/13/15:52
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class MessageSession extends MutaBaseEntity {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@TableId(type = IdType.AUTO)
|
||||
@JsonFormat(shape =JsonFormat.Shape.STRING)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* userId
|
||||
*/
|
||||
@JsonFormat(shape =JsonFormat.Shape.STRING)
|
||||
private Long userId;
|
||||
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.ruoyi.system.ai.domain;
|
||||
import com.muta.ai.enums.LogicCheckEnum;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author Fuzhengwei bugstack.cn @小傅哥
|
||||
* @description 规则校验结果实体
|
||||
* @create 2023-09-16 17:02
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class RuleLogicEntity<T> {
|
||||
|
||||
private LogicCheckEnum type;
|
||||
private String info;
|
||||
private T data;
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.ruoyi.system.ai.domain.dto;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author: Larry
|
||||
* @Date: 2024 /05 /10 / 18:41
|
||||
* @Description:
|
||||
*/
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
@Builder
|
||||
public class MessageHistoryKimi {
|
||||
private String role;
|
||||
|
||||
private String content;
|
||||
|
||||
public MessageHistoryKimi(String role, String content) {
|
||||
this.role = role;
|
||||
this.content = content;
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package com.ruoyi.system.ai.domain.dto;
|
||||
|
||||
import com.muta.ai.domain.ChatCompletionMessage;
|
||||
import com.muta.ai.domain.MessageEntity;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author: Larry
|
||||
* @Date: 2024 /05 /21 / 17:55
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class PostDTO {
|
||||
private MessageEntity message;
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long userId;
|
||||
/**
|
||||
* 所选模型
|
||||
*/
|
||||
private String model;
|
||||
/** 历史消息 */
|
||||
private List<ChatCompletionMessage> messages;
|
||||
/**
|
||||
* 所用key
|
||||
*/
|
||||
private String key;
|
||||
/**
|
||||
* 模型单位积分对应key
|
||||
*/
|
||||
private Integer modelConsumer;
|
||||
/**
|
||||
* 上下文token数量
|
||||
*/
|
||||
private Integer tokenNum;
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.ruoyi.system.ai.domain.event;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author: Larry
|
||||
* @Date: 2024 /05 /15 / 17:44
|
||||
* @Description:
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
@Builder
|
||||
public class MessageEvent implements Serializable {
|
||||
private static final long serialVersionUID = 3349917261877342192L;
|
||||
private Long userId;
|
||||
private String finishReason;
|
||||
private String promptTokens;
|
||||
private String completionTokens;
|
||||
private Integer totalTokens;
|
||||
private String content;
|
||||
private String role;
|
||||
private String model;
|
||||
private String username;
|
||||
private Long sessionId;
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package com.ruoyi.system.ai.enums;
|
||||
|
||||
|
||||
public enum RoleEnum {
|
||||
system,
|
||||
user,
|
||||
assistant;
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.ruoyi.system.ai.factory;//package com.muta.ai.factory;
|
||||
//
|
||||
//
|
||||
//import com.muta.ai.annotation.LogicStrategy;
|
||||
//import com.muta.ai.config.LogicConfig;
|
||||
//import com.muta.ai.chain.UserAccountQuotaEntity;
|
||||
//import com.muta.ai.service.ILogicFilter;
|
||||
//import org.springframework.core.annotation.AnnotationUtils;
|
||||
//import org.springframework.stereotype.Service;
|
||||
//
|
||||
//import javax.annotation.PostConstruct;
|
||||
//import javax.annotation.Resource;
|
||||
//import java.util.List;
|
||||
//import java.util.Map;
|
||||
//import java.util.concurrent.ConcurrentHashMap;
|
||||
//
|
||||
///**
|
||||
// * @author Fuzhengwei bugstack.cn @小傅哥
|
||||
// * @description 规则工厂
|
||||
// * @create 2023-09-16 17:42
|
||||
// */
|
||||
//@Service
|
||||
//public class DefaultLogicFactory extends LogicConfig {
|
||||
//
|
||||
// //后期可加入参数,自动选择过滤器
|
||||
// public Map<String, ILogicFilter<UserAccountQuotaEntity>> openLogicFilter() {
|
||||
// return logicFilterMap;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// * 规则逻辑枚举
|
||||
// */
|
||||
//
|
||||
//}
|
@ -0,0 +1,70 @@
|
||||
package com.ruoyi.system.ai.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.muta.ai.domain.AiKey;
|
||||
import com.muta.common.annotation.AutoFill;
|
||||
import com.muta.common.enums.BaseOperatorType;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
/**
|
||||
* 【请填写功能名称】Mapper接口
|
||||
*
|
||||
* @author mutaai
|
||||
* @date 2024-05-16
|
||||
*/
|
||||
@Mapper
|
||||
public interface AiKeyMapper extends BaseMapper<AiKey> {
|
||||
/**
|
||||
* 查询【请填写功能名称】
|
||||
*
|
||||
* @param id 【请填写功能名称】主键
|
||||
* @return 【请填写功能名称】
|
||||
*/
|
||||
public AiKey selectAiKeyById(Long id);
|
||||
|
||||
/**
|
||||
* 查询【请填写功能名称】列表
|
||||
*
|
||||
* @return 【请填写功能名称】集合
|
||||
*/
|
||||
public List<AiKey> selectAiKeyList();
|
||||
|
||||
/**
|
||||
* 新增【请填写功能名称】
|
||||
*
|
||||
* @param aiKey 【请填写功能名称】
|
||||
* @return 结果
|
||||
*/
|
||||
@AutoFill(BaseOperatorType.INSERT)
|
||||
public int insertAiKey(AiKey aiKey);
|
||||
|
||||
/**
|
||||
* 修改【请填写功能名称】
|
||||
*
|
||||
* @param aiKey 【请填写功能名称】
|
||||
* @return 结果
|
||||
*/
|
||||
@AutoFill(BaseOperatorType.UPDATE)
|
||||
public int updateAiKey(AiKey aiKey);
|
||||
|
||||
/**
|
||||
* 删除【请填写功能名称】
|
||||
*
|
||||
* @param id 【请填写功能名称】主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteAiKeyById(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除【请填写功能名称】
|
||||
*
|
||||
* @param ids 需要删除的数据主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteAiKeyByIds(Long[] ids);
|
||||
|
||||
@Select("select `key`, host, model_list, type, status, `limit`, create_time, create_by, update_time, update_by, user_id, is_del from ai_key where is_del = 0 and user_id = #{userId}")
|
||||
List<AiKey> list(Long userId);
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package com.ruoyi.system.ai.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.muta.ai.config.ChatConfig;
|
||||
|
||||
/**
|
||||
* 【请填写功能名称】Mapper接口
|
||||
*
|
||||
* @author mutaai
|
||||
* @date 2024-05-13
|
||||
*/
|
||||
public interface ChatConfigMapper extends BaseMapper<ChatConfig> {
|
||||
/**
|
||||
* 查询【请填写功能名称】
|
||||
*
|
||||
* @param id 【请填写功能名称】主键
|
||||
* @return 【请填写功能名称】
|
||||
*/
|
||||
public ChatConfig selectChatConfigById(Long id);
|
||||
|
||||
/**
|
||||
* 查询【请填写功能名称】列表
|
||||
*
|
||||
* @param chatConfig 【请填写功能名称】
|
||||
* @return 【请填写功能名称】集合
|
||||
*/
|
||||
public List<ChatConfig> selectChatConfigList(ChatConfig chatConfig);
|
||||
|
||||
/**
|
||||
* 新增【请填写功能名称】
|
||||
*
|
||||
* @param chatConfig 【请填写功能名称】
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertChatConfig(ChatConfig chatConfig);
|
||||
|
||||
/**
|
||||
* 修改【请填写功能名称】
|
||||
*
|
||||
* @param chatConfig 【请填写功能名称】
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateChatConfig(ChatConfig chatConfig);
|
||||
|
||||
/**
|
||||
* 删除【请填写功能名称】
|
||||
*
|
||||
* @param id 【请填写功能名称】主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteChatConfigById(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除【请填写功能名称】
|
||||
*
|
||||
* @param ids 需要删除的数据主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteChatConfigByIds(Long[] ids);
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.ruoyi.system.ai.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.muta.ai.domain.MessageFile;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* @author 马兰友
|
||||
* @Date: 2024/05/17/15:16
|
||||
*/
|
||||
@Mapper
|
||||
public interface MessageFileMapper extends BaseMapper<MessageFile> {
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.ruoyi.system.ai.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.muta.ai.domain.MessageEntity;
|
||||
import com.muta.common.core.domain.entity.SysUser;
|
||||
import com.muta.system.domain.Message;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author: Larry
|
||||
* @Date: 2024 /05 /20 / 13:02
|
||||
* @Description:
|
||||
*/
|
||||
@Mapper
|
||||
public interface MessageMapper extends BaseMapper<MessageEntity> {
|
||||
|
||||
List<MessageEntity> selectByFilter(SysUser sysUser);
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.ruoyi.system.ai.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.muta.ai.domain.MessageSession;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* @author 马兰友
|
||||
* @Date: 2024/05/13/16:09
|
||||
*/
|
||||
@Mapper
|
||||
public interface MessageSessionMapper extends BaseMapper<MessageSession> {
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.ruoyi.system.ai.mq.listener;//package com.muta.ai.mq.listener;
|
||||
//
|
||||
//import cn.hutool.json.JSONUtil;
|
||||
//import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
//import com.muta.ai.domain.MessageEntity;
|
||||
//import com.muta.ai.domain.event.MessageEvent;
|
||||
//import com.muta.ai.service.IMessageService;
|
||||
//import com.muta.ai.service.impl.BaseChatService;
|
||||
//import com.rabbitmq.client.Channel;
|
||||
//import org.springframework.amqp.core.Message;
|
||||
//import org.springframework.amqp.rabbit.annotation.RabbitHandler;
|
||||
//import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||
//import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
//import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
||||
//import org.springframework.amqp.support.converter.MessageConverter;
|
||||
//import org.springframework.beans.factory.annotation.Autowired;
|
||||
//import org.springframework.context.annotation.Bean;
|
||||
//import org.springframework.stereotype.Component;
|
||||
//
|
||||
//import javax.annotation.Resource;
|
||||
//
|
||||
///**
|
||||
// * @author: Larry
|
||||
// * @Date: 2024 /05 /15 / 17:44
|
||||
// * @Description:
|
||||
// */
|
||||
//@Component
|
||||
//
|
||||
//public class MessageListener {
|
||||
// @Resource
|
||||
// private BaseChatService baseChatService;
|
||||
// @RabbitHandler
|
||||
// @RabbitListener(queues = "message.queue")
|
||||
// public void listenMessage(String message, Channel channel){
|
||||
// MessageEntity messageEntity = JSONUtil.toBean(message, MessageEntity.class);
|
||||
// System.out.println(messageEntity.getContent());
|
||||
// }
|
||||
//
|
||||
//}
|
@ -0,0 +1,87 @@
|
||||
package com.ruoyi.system.ai.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.muta.ai.domain.AiKey;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* 【请填写功能名称】Service接口
|
||||
*
|
||||
* @author mutaai
|
||||
* @date 2024-05-16
|
||||
*/
|
||||
public interface IAiKeyService extends IService<AiKey> {
|
||||
/**
|
||||
* 查询【请填写功能名称】
|
||||
*
|
||||
* @param id 【请填写功能名称】主键
|
||||
* @return 【请填写功能名称】
|
||||
*/
|
||||
public AiKey selectAiKeyById(Long id);
|
||||
|
||||
/**
|
||||
* 查询【请填写功能名称】列表
|
||||
*
|
||||
* @return 【请填写功能名称】集合
|
||||
*/
|
||||
public List<AiKey> selectAiKeyList();
|
||||
|
||||
/**
|
||||
* 新增【请填写功能名称】
|
||||
*
|
||||
* @param aiKey 【请填写功能名称】
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertAiKey(AiKey aiKey);
|
||||
|
||||
/**
|
||||
* 修改【请填写功能名称】
|
||||
*
|
||||
* @param aiKey 【请填写功能名称】
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateAiKey(AiKey aiKey);
|
||||
|
||||
/**
|
||||
* 批量删除【请填写功能名称】
|
||||
*
|
||||
* @param ids 需要删除的【请填写功能名称】主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteAiKeyByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 删除【请填写功能名称】信息
|
||||
*
|
||||
* @param id 【请填写功能名称】主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteAiKeyById(Long id);
|
||||
|
||||
/**
|
||||
* 查询额度
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public String getLimitByKey(String key);
|
||||
|
||||
/**
|
||||
* 判断key是否可用
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public Integer isAvailable(String key);
|
||||
|
||||
/**
|
||||
* 通过id获得AiKey(String)
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
List<AiKey> getAiKeyStrById(Long userId);
|
||||
|
||||
/**
|
||||
* 刷新Key额度
|
||||
*/
|
||||
void updateKeyLimit();
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package com.ruoyi.system.ai.service;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.muta.ai.config.ChatConfig;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 【请填写功能名称】Service接口
|
||||
*
|
||||
* @author mutaai
|
||||
* @date 2024-05-13
|
||||
*/
|
||||
public interface IChatConfigService extends IService<ChatConfig> {
|
||||
/**
|
||||
* 查询【请填写功能名称】
|
||||
*
|
||||
* @param id 【请填写功能名称】主键
|
||||
* @return 【请填写功能名称】
|
||||
*/
|
||||
public ChatConfig selectChatConfigById(Long id);
|
||||
|
||||
/**
|
||||
* 查询【请填写功能名称】列表
|
||||
*
|
||||
* @param chatConfig 【请填写功能名称】
|
||||
* @return 【请填写功能名称】集合
|
||||
*/
|
||||
public List<ChatConfig> selectChatConfigList(ChatConfig chatConfig);
|
||||
|
||||
/**
|
||||
* 新增【请填写功能名称】
|
||||
*
|
||||
* @param chatConfig 【请填写功能名称】
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertChatConfig(ChatConfig chatConfig);
|
||||
|
||||
/**
|
||||
* 修改【请填写功能名称】
|
||||
*
|
||||
* @param chatConfig 【请填写功能名称】
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateChatConfig(ChatConfig chatConfig);
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.ruoyi.system.ai.service;
|
||||
|
||||
import com.muta.ai.domain.ChatCompletionMessage;
|
||||
import com.muta.ai.chain.MusicProcessAggregate;
|
||||
import com.muta.ai.chain.UserAccountQuotaEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author: Larry
|
||||
* @Date: 2024 /05 /09 / 20:06
|
||||
* @Description:
|
||||
*/
|
||||
public interface IChatService {
|
||||
|
||||
|
||||
|
||||
MusicProcessAggregate initChatData(Long userId, String model, List<ChatCompletionMessage> messages);
|
||||
UserAccountQuotaEntity initUserData(Long userId);
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.ruoyi.system.ai.service;
|
||||
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* @author: Larry
|
||||
* @Date: 2024 /05 /15 / 20:59
|
||||
* @Description:
|
||||
*/
|
||||
public interface IChatUploadService {
|
||||
String upload(MultipartFile file);
|
||||
String analyzeFile(String path);
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.ruoyi.system.ai.service;
|
||||
|
||||
|
||||
import com.muta.ai.chain.MusicProcessAggregate;
|
||||
import com.muta.ai.domain.RuleLogicEntity;
|
||||
|
||||
/**
|
||||
* @author Fuzhengwei bugstack.cn @小傅哥
|
||||
* @description 规则过滤接口
|
||||
* @create 2023-09-16 16:59
|
||||
*/
|
||||
public interface ILogicFilter<T> {
|
||||
|
||||
RuleLogicEntity<MusicProcessAggregate> filter(MusicProcessAggregate chatProcess, T data) throws Exception;
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.ruoyi.system.ai.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.muta.ai.domain.MessageFile;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* @author 马兰友
|
||||
* @Date: 2024/05/17/15:15
|
||||
*/
|
||||
public interface IMessageFileService extends IService<MessageFile> {
|
||||
MessageFile upload(MultipartFile file) throws Exception;
|
||||
|
||||
//根据url获取文件解析信息
|
||||
String getContentByUrl(String url);
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.ruoyi.system.ai.service;
|
||||
|
||||
import com.muta.ai.domain.MessageEntity;
|
||||
import com.muta.common.core.domain.entity.SysUser;
|
||||
import com.muta.system.domain.Message;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author: Larry
|
||||
* @Date: 2024 /05 /20 / 13:01
|
||||
* @Description:
|
||||
*/
|
||||
public interface IMessageService {
|
||||
//根据权限返回对应消息列表
|
||||
List<MessageEntity> getList(SysUser sysUser);
|
||||
|
||||
void add(MessageEntity message);
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.ruoyi.system.ai.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.muta.ai.domain.MessageSession;
|
||||
|
||||
/**
|
||||
* @author 马兰友
|
||||
* @Date: 2024/05/13/16:07
|
||||
*/
|
||||
public interface IMessageSessionService extends IService<MessageSession> {
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.ruoyi.system.ai.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IModelService {
|
||||
List<String> getModelList();
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
package com.ruoyi.system.ai.service.impl;//package com.muta.ai.service.impl;
|
||||
//
|
||||
//import com.muta.ai.chain.MusicProcessAggregate;
|
||||
//import com.muta.ai.domain.MessageEntity;
|
||||
//import com.muta.ai.domain.RuleLogicEntity;
|
||||
//import com.muta.ai.chain.UserAccountQuotaEntity;
|
||||
//import com.muta.ai.enums.LogicCheckEnum;
|
||||
//import com.muta.ai.factory.DefaultLogicFactory;
|
||||
//import com.muta.ai.service.ILogicFilter;
|
||||
//import com.muta.ai.service.IMessageService;
|
||||
//import com.muta.common.constant.Constants;
|
||||
//import com.muta.common.core.domain.entity.UserExtra;
|
||||
//import com.muta.common.utils.SecurityUtils;
|
||||
//import com.muta.log.domain.IntegralLog;
|
||||
//import com.muta.log.service.impl.MessageIntegralLogServiceImpl;
|
||||
//import com.muta.system.mapper.UserExtraMapper;
|
||||
//import org.springframework.transaction.annotation.Transactional;
|
||||
//
|
||||
//import javax.annotation.Resource;
|
||||
//import java.util.Map;
|
||||
//
|
||||
///**
|
||||
// * @author: Larry
|
||||
// * @Date: 2024 /05 /09 / 16:05
|
||||
// * @Description: 前置过滤规则处理
|
||||
// */
|
||||
//public class BaseChatService {
|
||||
// @Resource
|
||||
// private DefaultLogicFactory logicFactory;
|
||||
// //后面可拓展为根据需要传入对应过滤器执行
|
||||
// @Resource
|
||||
// private UserExtraMapper userExtraMapper;
|
||||
// @Resource
|
||||
// private IMessageService messageService;
|
||||
// @Resource
|
||||
// private MessageIntegralLogServiceImpl messageIntegralLogService;
|
||||
// //前置过滤
|
||||
// protected RuleLogicEntity<MusicProcessAggregate> doCheckLogic(MusicProcessAggregate chatProcess, UserAccountQuotaEntity userAccountQuotaEntity) throws Exception {
|
||||
// //获得所有的拦截器
|
||||
// Map<String, ILogicFilter<UserAccountQuotaEntity>> logicFilterMap = logicFactory.openLogicFilter();
|
||||
// //定义返回结果
|
||||
// RuleLogicEntity<MusicProcessAggregate> entity = null;
|
||||
// //遍历所有拦截器,如果拦截则结束并返回,否则放行
|
||||
// for (ILogicFilter<UserAccountQuotaEntity> filter : logicFilterMap.values()) {
|
||||
// entity = filter.filter(chatProcess,userAccountQuotaEntity);
|
||||
// if(entity.getType().equals(LogicCheckEnum.REFUSE)){
|
||||
// return entity;
|
||||
// }
|
||||
// }
|
||||
// //全部方向后通过
|
||||
// return entity != null ? entity : RuleLogicEntity.<MusicProcessAggregate>builder()
|
||||
// .type(LogicCheckEnum.SUCCESS).data(chatProcess).build();
|
||||
//
|
||||
// }
|
||||
// //后置过滤
|
||||
// @Transactional
|
||||
// public void PostRule(MusicProcessAggregate chatProcess, UserAccountQuotaEntity userAccountQuotaEntity, MessageEntity message){
|
||||
// double result = chatProcess.getTokenNum() / (double) chatProcess.getModelConsumer();
|
||||
// Integer consumption = Math.toIntExact(Math.round(result));
|
||||
// //扣减积分
|
||||
// increaseIntegral(consumption,userAccountQuotaEntity.getUserId());
|
||||
// //新增积分记录
|
||||
// IntegralLog integralLog = IntegralLog.builder()
|
||||
// .value(consumption+"积分")
|
||||
// .build();
|
||||
// messageIntegralLogService.insertLog(integralLog);
|
||||
// //新增消息记录
|
||||
//// messageService.add(message);
|
||||
// }
|
||||
// private void increaseIntegral(Integer integral,Long userId){
|
||||
// userExtraMapper.IncreaseIntegralByUserId(integral,userId);
|
||||
// }
|
||||
//
|
||||
//
|
||||
//}
|
@ -0,0 +1,83 @@
|
||||
package com.ruoyi.system.ai.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import java.util.List;
|
||||
|
||||
import com.muta.ai.config.ChatConfig;
|
||||
import com.muta.ai.mapper.ChatConfigMapper;
|
||||
import com.muta.ai.service.IChatConfigService;
|
||||
import com.muta.common.utils.SecurityUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 【请填写功能名称】Service业务层处理
|
||||
*
|
||||
* @author mutaai
|
||||
* @date 2024-05-13
|
||||
*/
|
||||
@Service
|
||||
public class ChatConfigServiceImpl extends ServiceImpl<ChatConfigMapper, ChatConfig> implements IChatConfigService {
|
||||
@Resource
|
||||
private ChatConfigMapper chatConfigMapper;
|
||||
|
||||
/**
|
||||
* 查询【请填写功能名称】
|
||||
*
|
||||
* @param 【请填写功能名称】主键
|
||||
* @return 【请填写功能名称】
|
||||
*/
|
||||
@Override
|
||||
public ChatConfig selectChatConfigById(Long userId) {
|
||||
LambdaQueryWrapper<ChatConfig> chatConfigLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
chatConfigLambdaQueryWrapper.eq(userId!=null,ChatConfig::getUserId, userId);
|
||||
return chatConfigMapper.selectOne(chatConfigLambdaQueryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询【请填写功能名称】列表
|
||||
*
|
||||
* @param chatConfig 【请填写功能名称】
|
||||
* @return 【请填写功能名称】
|
||||
*/
|
||||
@Override
|
||||
public List<ChatConfig> selectChatConfigList(ChatConfig chatConfig) {
|
||||
return chatConfigMapper.selectChatConfigList(chatConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增【请填写功能名称】
|
||||
*
|
||||
* @param chatConfig 【请填写功能名称】
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int insertChatConfig(ChatConfig chatConfig) {
|
||||
return chatConfigMapper.insert(chatConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改【请填写功能名称】
|
||||
*
|
||||
* @param chatConfig 【请填写功能名称】
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int updateChatConfig(ChatConfig chatConfig) {
|
||||
System.out.println(chatConfig.getUserId());
|
||||
LambdaQueryWrapper<ChatConfig> chatConfigLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
chatConfigLambdaQueryWrapper.eq(SecurityUtils.getUserId()!=null,ChatConfig::getUserId, SecurityUtils.getUserId());
|
||||
return chatConfigMapper.update(chatConfig,chatConfigLambdaQueryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除【请填写功能名称】
|
||||
*
|
||||
* @param ids 需要删除的【请填写功能名称】主键
|
||||
* @return 结果
|
||||
*/
|
||||
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
package com.ruoyi.system.ai.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.muta.ai.domain.MessageFile;
|
||||
import com.muta.ai.mapper.MessageFileMapper;
|
||||
import com.muta.ai.service.IMessageFileService;
|
||||
import com.muta.ai.util.DocumentReaderUtils;
|
||||
import com.muta.common.core.service.ISysFileService;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* @author 马兰友
|
||||
* @Date: 2024/05/17/15:15
|
||||
*/
|
||||
@Service
|
||||
public class MessageFileServiceImpl extends ServiceImpl<MessageFileMapper, MessageFile> implements IMessageFileService {
|
||||
|
||||
@Resource
|
||||
private MessageFileMapper messageFileMapper;
|
||||
|
||||
@Resource
|
||||
private ISysFileService aliOssServiceImpl;
|
||||
|
||||
@Resource
|
||||
@Qualifier("asyncPoolTaskExecutor")
|
||||
ThreadPoolTaskExecutor executor;
|
||||
|
||||
|
||||
@Override
|
||||
public MessageFile upload(MultipartFile file) throws Exception {
|
||||
MessageFile messageFile = new MessageFile();
|
||||
messageFile.setUrl(aliOssServiceImpl.uploadFile(file));
|
||||
File tempFile = multipartFile2File(file);
|
||||
messageFile.setAnalysisContent(DocumentReaderUtils.readDocument(tempFile));
|
||||
if (tempFile.exists()) {
|
||||
tempFile.delete();
|
||||
}
|
||||
messageFile.setName(file.getOriginalFilename());
|
||||
messageFile.setSize(formatFileSize(file.getSize()));
|
||||
messageFileMapper.insert(messageFile);
|
||||
|
||||
return messageFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentByUrl(String url) {
|
||||
LambdaQueryWrapper<MessageFile> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.eq(MessageFile::getUrl, url);
|
||||
MessageFile messageFile = messageFileMapper.selectOne(lqw);
|
||||
return messageFile.getAnalysisContent();
|
||||
}
|
||||
|
||||
private CompletableFuture<MessageFile> futureUpload(MultipartFile file){
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
MessageFile messageFile = new MessageFile();
|
||||
messageFile.setUrl(aliOssServiceImpl.uploadFile(file));
|
||||
File tempFile = multipartFile2File(file);
|
||||
messageFile.setAnalysisContent(DocumentReaderUtils.readDocument(tempFile));
|
||||
deleteTempFile(tempFile);
|
||||
messageFile.setName(file.getOriginalFilename());
|
||||
messageFile.setSize(formatFileSize(file.getSize()));
|
||||
messageFileMapper.insert(messageFile);
|
||||
return messageFile;
|
||||
} catch (Exception e) {
|
||||
// 根据需要处理异常,或者重新抛出
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}, executor); // 使用提供的线程池执行上传任务
|
||||
}
|
||||
|
||||
private void deleteTempFile(File tempFile) throws IOException {
|
||||
if (tempFile.exists()) {
|
||||
boolean delete = tempFile.delete();
|
||||
if (!delete) {
|
||||
throw new IOException("Failed to delete temporary file: " + tempFile.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public File multipartFile2File (MultipartFile multipartFile) throws IOException {
|
||||
// 获取原始文件名
|
||||
String originalFilename = multipartFile.getOriginalFilename();
|
||||
// 获取文件扩展名
|
||||
String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
|
||||
// 创建临时文件
|
||||
File file = File.createTempFile("temp-" + UUID.randomUUID(), fileExtension);
|
||||
System.err.println(file);
|
||||
// 将MultipartFile对象的内容写入临时文件
|
||||
multipartFile.transferTo(file);
|
||||
return file;
|
||||
}
|
||||
public String formatFileSize(long bytes) {
|
||||
double kilobytes = bytes / 1024.0;
|
||||
double megabytes = kilobytes / 1024.0;
|
||||
|
||||
if (megabytes >= 1) {
|
||||
return String.format("%.2f MB", megabytes);
|
||||
} else {
|
||||
return String.format("%.2f KB", kilobytes);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.ruoyi.system.ai.service.impl;
|
||||
|
||||
import com.muta.ai.domain.MessageEntity;
|
||||
import com.muta.ai.mapper.MessageMapper;
|
||||
import com.muta.ai.service.IMessageService;
|
||||
import com.muta.common.core.domain.entity.SysUser;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author: Larry
|
||||
* @Date: 2024 /05 /20 / 13:01
|
||||
* @Description:
|
||||
*/
|
||||
@Service
|
||||
public class MessageServiceImpl implements IMessageService {
|
||||
@Resource
|
||||
private MessageMapper messageMapper;
|
||||
|
||||
@Override
|
||||
public void add(MessageEntity message) {
|
||||
messageMapper.insert(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MessageEntity> getList(SysUser sysUser) {
|
||||
return messageMapper.selectByFilter(sysUser);
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.ruoyi.system.ai.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.muta.ai.domain.MessageSession;
|
||||
import com.muta.ai.mapper.MessageSessionMapper;
|
||||
import com.muta.ai.service.IMessageSessionService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author 马兰友
|
||||
* @Date: 2024/05/13/16:07
|
||||
*/
|
||||
@Service
|
||||
public class MessageSessionServiceImpl extends ServiceImpl<MessageSessionMapper, MessageSession> implements IMessageSessionService {
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package com.ruoyi.system.ai.service.impl;//package com.muta.ai.service.impl;
|
||||
//
|
||||
//import com.github.houbb.sensitive.word.bs.SensitiveWordBs;
|
||||
//import com.github.houbb.sensitive.word.core.SensitiveWordHelper;
|
||||
//import com.muta.ai.annotation.LogicStrategy;
|
||||
//import com.muta.ai.domain.*;
|
||||
//import com.muta.ai.enums.LogicCheckEnum;
|
||||
//import com.muta.ai.factory.DefaultLogicFactory;
|
||||
//import com.muta.ai.service.ILogicFilter;
|
||||
//import com.muta.common.annotation.Log;
|
||||
//import lombok.extern.slf4j.Slf4j;
|
||||
//import org.springframework.beans.factory.annotation.Qualifier;
|
||||
//import org.springframework.stereotype.Component;
|
||||
//
|
||||
//import javax.annotation.Resource;
|
||||
//import java.util.List;
|
||||
//
|
||||
///**
|
||||
// * @author Larry
|
||||
// * @description 敏感词过滤
|
||||
// * @create 2024-05-10 17:39
|
||||
// */
|
||||
//@Slf4j
|
||||
//@Component
|
||||
//@LogicStrategy(logicMode = DefaultLogicFactory.LogicModel.SENSITIVE_WORD)
|
||||
//public class SensitiveWordFilter implements ILogicFilter<UserAccountQuotaEntity> {
|
||||
// @Resource
|
||||
// @Qualifier("sensitiveWordBsBean")
|
||||
// SensitiveWordBs sensitiveWordBs;
|
||||
// @Override
|
||||
// public RuleLogicEntity<MusicProcessAggregate> filter(MusicProcessAggregate chatProcess, UserAccountQuotaEntity data) throws Exception {
|
||||
// //只对当前的信息进行敏感词过滤
|
||||
// ChatCompletionMessage nowMessage = chatProcess.getMessages().get(chatProcess.getMessages().size() -1);
|
||||
// System.out.println();
|
||||
// //调用外部依赖进行敏感词查找
|
||||
// if (sensitiveWordBs.contains(nowMessage.getContent())) {
|
||||
// //如果有敏感词,返回相关结果
|
||||
// return RuleLogicEntity.<MusicProcessAggregate>builder()
|
||||
// .type(LogicCheckEnum.REFUSE)
|
||||
// .info("您的对话含有敏感词,请注意!")
|
||||
// .data(chatProcess).build();
|
||||
// }
|
||||
//
|
||||
// return RuleLogicEntity.<MusicProcessAggregate>builder()
|
||||
// .type(LogicCheckEnum.SUCCESS).data(chatProcess).build();
|
||||
// }
|
||||
//
|
||||
// public static void main(String[] args) {
|
||||
//
|
||||
//
|
||||
// }
|
||||
//}
|
@ -0,0 +1,46 @@
|
||||
package com.ruoyi.system.ai.service.impl;//package com.muta.ai.service.impl;
|
||||
//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
//import com.muta.ai.annotation.LogicStrategy;
|
||||
//import com.muta.ai.chain.MusicProcessAggregate;
|
||||
//import com.muta.ai.domain.RuleLogicEntity;
|
||||
//import com.muta.ai.chain.UserAccountQuotaEntity;
|
||||
//import com.muta.ai.enums.LogicCheckEnum;
|
||||
//import com.muta.ai.factory.DefaultLogicFactory;
|
||||
//import com.muta.ai.service.ILogicFilter;
|
||||
//import com.muta.common.core.domain.entity.UserExtra;
|
||||
//import com.muta.system.mapper.UserExtraMapper;
|
||||
//import com.muta.system.service.ICommonSettingService;
|
||||
//import com.muta.system.service.impl.CommonSettingServiceImpl;
|
||||
//import lombok.extern.slf4j.Slf4j;
|
||||
//import org.springframework.stereotype.Component;
|
||||
//
|
||||
//import javax.annotation.Resource;
|
||||
//
|
||||
///**
|
||||
// * @author Fuzhengwei bugstack.cn @小傅哥
|
||||
// * @description 用户额度扣减规则过滤
|
||||
// * @create 2023-10-03 16:48
|
||||
// */
|
||||
//@Slf4j
|
||||
//@Component
|
||||
//@LogicStrategy(logicMode = DefaultLogicFactory.LogicModel.USER_QUOTA)
|
||||
//public class UserQuotaFilter implements ILogicFilter<UserAccountQuotaEntity> {
|
||||
// //调用基础业务查询积分
|
||||
// @Resource
|
||||
// private UserExtraMapper userExtraMapper;
|
||||
// @Override
|
||||
// public RuleLogicEntity<MusicProcessAggregate> filter(MusicProcessAggregate chatProcess, UserAccountQuotaEntity data) throws Exception {
|
||||
//
|
||||
// if(data.getIntegral()<chatProcess.getModelConsumer() * chatProcess.getTokenNum()){
|
||||
// return RuleLogicEntity.<MusicProcessAggregate>builder()
|
||||
// .info("积分不足,请及时充值")
|
||||
// .type(LogicCheckEnum.REFUSE)
|
||||
// .data(chatProcess).build();
|
||||
// }
|
||||
//
|
||||
// return RuleLogicEntity.<MusicProcessAggregate>builder()
|
||||
// .type(LogicCheckEnum.SUCCESS).data(chatProcess).build();
|
||||
// }
|
||||
//
|
||||
//
|
||||
//}
|
@ -0,0 +1,154 @@
|
||||
package com.ruoyi.system.ai.util;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.ContentType;
|
||||
import cn.hutool.http.Header;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.Method;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.muta.ai.domain.dto.MessageHistoryKimi;
|
||||
import lombok.NonNull;
|
||||
import lombok.SneakyThrows;
|
||||
import okhttp3.*;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
public class MoonshotAiUtils {
|
||||
|
||||
private static final String API_KEY = "sk-SgNVCgBxkVPVHjINo708cqiuXPNMNKWdT2JORNkika6FOAht";
|
||||
private static final String MODELS_URL = "https://api.moonshot.cn/v1/models";
|
||||
private static final String FILES_URL = "https://api.moonshot.cn/v1/files";
|
||||
private static final String ESTIMATE_TOKEN_COUNT_URL = "https://api.moonshot.cn/v1/tokenizers/estimate-token-count";
|
||||
private static final String CHAT_COMPLETION_URL = "https://api.moonshot.cn/v1/chat/completions";
|
||||
|
||||
private static final String CHECK_BALANCE ="https://api.moonshot.cn/v1/users/me/balance";
|
||||
public static String getModelList() {
|
||||
return getCommonRequest(MODELS_URL)
|
||||
.execute()
|
||||
.body();
|
||||
}
|
||||
public static String getBalance() {
|
||||
return getCommonRequest(CHECK_BALANCE)
|
||||
.execute()
|
||||
.body();
|
||||
}
|
||||
public static String getBalanceByKey(String key) {
|
||||
return getCommonRequestByKey(CHECK_BALANCE, key)
|
||||
.execute()
|
||||
.body();
|
||||
}
|
||||
|
||||
public static String uploadFile(@NonNull File file) {
|
||||
return getCommonRequest(FILES_URL)
|
||||
.method(Method.POST)
|
||||
.header("purpose", "file-extract")
|
||||
.form("file", file)
|
||||
.execute()
|
||||
.body();
|
||||
}
|
||||
|
||||
public static String getFileList() {
|
||||
return getCommonRequest(FILES_URL)
|
||||
.execute()
|
||||
.body();
|
||||
}
|
||||
|
||||
public static String deleteFile(@NonNull String fileId) {
|
||||
return getCommonRequest(FILES_URL + "/" + fileId)
|
||||
.method(Method.DELETE)
|
||||
.execute()
|
||||
.body();
|
||||
}
|
||||
|
||||
public static String getFileDetail(@NonNull String fileId) {
|
||||
return getCommonRequest(FILES_URL + "/" + fileId)
|
||||
.execute()
|
||||
.body();
|
||||
}
|
||||
|
||||
public static String getFileContent(@NonNull String fileId) {
|
||||
return getCommonRequest(FILES_URL + "/" + fileId + "/content")
|
||||
.execute()
|
||||
.body();
|
||||
}
|
||||
|
||||
public static String estimateTokenCount(@NonNull String model, @NonNull List<MessageHistoryKimi> messages) {
|
||||
String requestBody = new JSONObject()
|
||||
.putOpt("model", model)
|
||||
.putOpt("messages", messages)
|
||||
.toString();
|
||||
return getCommonRequest(ESTIMATE_TOKEN_COUNT_URL)
|
||||
.method(Method.POST)
|
||||
.header(Header.CONTENT_TYPE, ContentType.JSON.getValue())
|
||||
.body(requestBody)
|
||||
.execute()
|
||||
.body();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static void chat(@NonNull String model, @NonNull List<MessageHistoryKimi> messages) {
|
||||
String requestBody = new JSONObject()
|
||||
.putOpt("model", model)
|
||||
.putOpt("messages", messages)
|
||||
.putOpt("stream", true)
|
||||
.toString();
|
||||
|
||||
Request okhttpRequest = new Request.Builder()
|
||||
.url(CHAT_COMPLETION_URL)
|
||||
.post(RequestBody.create(MediaType.get(ContentType.JSON.getValue()), requestBody))
|
||||
.addHeader("Authorization", "Bearer " + API_KEY)
|
||||
.build();
|
||||
Call call = new OkHttpClient().newCall(okhttpRequest);
|
||||
Response okhttpResponse = call.execute();
|
||||
BufferedReader reader = new BufferedReader(okhttpResponse.body().charStream());
|
||||
String line;
|
||||
StringBuffer content = new StringBuffer();
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (StrUtil.isBlank(line)) {
|
||||
continue;
|
||||
}
|
||||
if (JSONUtil.isTypeJSON(line)) {
|
||||
Optional.of(JSONUtil.parseObj(line))
|
||||
.map(x -> x.getJSONObject("error"))
|
||||
.map(x -> x.getStr("message"))
|
||||
.ifPresent(x -> System.out.println("error: " + x));
|
||||
return;
|
||||
}
|
||||
line = StrUtil.replace(line, "data: ", StrUtil.EMPTY);
|
||||
if (StrUtil.equals("[DONE]", line) || !JSONUtil.isTypeJSON(line)) {
|
||||
System.out.println(content);
|
||||
return;
|
||||
}
|
||||
Optional.of(JSONUtil.parseObj(line))
|
||||
.map(x -> x.getJSONArray("choices"))
|
||||
.filter(CollUtil::isNotEmpty)
|
||||
.map(x -> (JSONObject) x.get(0))
|
||||
.map(x -> x.getJSONObject("delta"))
|
||||
.map(x -> x.getStr("content"))
|
||||
.ifPresent(x ->{
|
||||
System.out.println("rowData: " + x);
|
||||
content.append(x);
|
||||
} );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static HttpRequest getCommonRequest(@NonNull String url) {
|
||||
return HttpRequest.of(url).header(Header.AUTHORIZATION, "Bearer " + API_KEY);
|
||||
}
|
||||
|
||||
private static HttpRequest getCommonRequestByKey(@NonNull String url, @NonNull String key) {
|
||||
return HttpRequest.of(url).header(Header.AUTHORIZATION, "Bearer " + key);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package com.ruoyi.system.aipay;
|
||||
|
||||
import com.alipay.api.AlipayApiException;
|
||||
import com.alipay.api.AlipayClient;
|
||||
import com.alipay.api.DefaultAlipayClient;
|
||||
import com.alipay.api.AlipayConfig;
|
||||
import com.alipay.api.request.AlipayUserInfoShareRequest;
|
||||
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
|
||||
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
|
||||
|
||||
import com.alipay.api.FileItem;
|
||||
import com.alipay.api.response.AlipayUserInfoShareResponse;
|
||||
import com.muta.pay.config.AliPayConfig;
|
||||
|
||||
import java.util.Base64;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AlipaySystemOauthToken {
|
||||
|
||||
public static void main(String[] args) throws AlipayApiException {
|
||||
// AlipayClient alipayClient1 = AliPayConfig.getInstance();
|
||||
// AlipayUserInfoShareRequest request1 = new AlipayUserInfoShareRequest();
|
||||
// AlipayUserInfoShareResponse response1 = alipayClient1.execute(request1,accessToken);
|
||||
// if(response1.isSuccess()){
|
||||
// System.out.println("调用成功");
|
||||
// } else {
|
||||
// System.out.println("调用失败");
|
||||
// }
|
||||
// 初始化SDK
|
||||
AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
|
||||
|
||||
// 构造请求参数以调用接口
|
||||
AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
|
||||
|
||||
// // 设置刷新令牌
|
||||
// request.setRefreshToken("201208134b203fe6c11548bcabd8da5bb087a83b");
|
||||
//
|
||||
// // 设置授权码
|
||||
// request.setCode("4b203fe6c11548bcabd8da5bb087a83b");
|
||||
|
||||
// 设置授权方式
|
||||
request.setGrantType("authorization_code");
|
||||
|
||||
AlipaySystemOauthTokenResponse response = alipayClient.execute(request);
|
||||
System.out.println(response.getBody());
|
||||
|
||||
if (response.isSuccess()) {
|
||||
System.out.println("调用成功");
|
||||
} else {
|
||||
System.out.println("调用失败");
|
||||
// sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
|
||||
// String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
|
||||
// System.out.println(diagnosisUrl);
|
||||
}
|
||||
}
|
||||
|
||||
private static AlipayConfig getAlipayConfig() {
|
||||
AlipayConfig alipayConfig = new AlipayConfig();
|
||||
alipayConfig.setServerUrl(AliPayConfig.PAY_GATEWAY);
|
||||
alipayConfig.setAppId(AliPayConfig.APPID);
|
||||
alipayConfig.setPrivateKey(AliPayConfig.APP_PRI_KEY);
|
||||
alipayConfig.setFormat("json");
|
||||
alipayConfig.setAlipayPublicKey(AliPayConfig.APP_PUB_KEY);
|
||||
alipayConfig.setCharset("UTF-8");
|
||||
alipayConfig.setSignType("RSA2");
|
||||
return alipayConfig;
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.ruoyi.system.aipay;
|
||||
|
||||
/**
|
||||
* @author: Larry
|
||||
* @Date: 2024 /08 /01 / 16:15
|
||||
* @Description:
|
||||
*/
|
||||
public class TestLogin {
|
||||
|
||||
public void test(){
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package com.ruoyi.system.basics.domain.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author 马兰友
|
||||
* @Date: 2024/05/06/16:36
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class KamilConDefDTO {
|
||||
|
||||
private String key;
|
||||
private Integer value;
|
||||
private Integer type;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date endTime;
|
||||
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.ruoyi.system.basics.factory.kamil;
|
||||
|
||||
import com.muta.basics.domain.Kamil;
|
||||
|
||||
/**
|
||||
* @author 马兰友
|
||||
* @Date: 2024/04/22/19:45
|
||||
*/
|
||||
public interface KamilConsumption {
|
||||
|
||||
void consumption(Kamil kamil);
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.ruoyi.system.basics.factory.kamil;
|
||||
|
||||
import com.muta.basics.factory.kamil.impl.SvipKamilConsumption;
|
||||
import com.muta.basics.factory.kamil.impl.VipKamilConsumption;
|
||||
import com.muta.basics.factory.kamil.impl.IntegrationKamilConsumption;
|
||||
import com.muta.basics.domain.Kamil;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @author 马兰友
|
||||
* @Date: 2024/04/22/18:31
|
||||
*/
|
||||
@Service
|
||||
public class KamilTypeFactory {
|
||||
public Map<Integer, KamilConsumption> kamilConsumptionMap = new ConcurrentHashMap<>();
|
||||
@Resource
|
||||
private IntegrationKamilConsumption integrationKamilConsumption;
|
||||
@Resource
|
||||
private VipKamilConsumption vipKamilConsumption;
|
||||
@Resource
|
||||
private SvipKamilConsumption svipKamilConsumption;
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
kamilConsumptionMap.put(0, integrationKamilConsumption);
|
||||
kamilConsumptionMap.put(1, vipKamilConsumption);
|
||||
kamilConsumptionMap.put(2, svipKamilConsumption);
|
||||
}
|
||||
public void consumption(Kamil kamil) {
|
||||
KamilConsumption kamilConsumption = kamilConsumptionMap.get(kamil.getType());
|
||||
kamilConsumption.consumption(kamil);
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package com.ruoyi.system.basics.factory.kamil.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.muta.basics.factory.kamil.KamilConsumption;
|
||||
import com.muta.common.annotation.IntegralLogInsert;
|
||||
import com.muta.common.constant.OperationConstants;
|
||||
import com.muta.common.core.domain.entity.UserExtra;
|
||||
import com.muta.common.utils.SecurityUtils;
|
||||
import com.muta.basics.domain.Kamil;
|
||||
import com.muta.system.mapper.UserExtraMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* @author 马兰友
|
||||
* @Date: 2024/04/22/19:48
|
||||
*/
|
||||
@Service
|
||||
public class IntegrationKamilConsumption implements KamilConsumption {
|
||||
|
||||
@Resource
|
||||
private UserExtraMapper userExtraMapper;
|
||||
|
||||
@Override
|
||||
@IntegralLogInsert(operation = OperationConstants.Kamil)
|
||||
public void consumption(Kamil kamil) {
|
||||
LambdaQueryWrapper<UserExtra> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.eq(UserExtra::getUserId, SecurityUtils.getUserId());
|
||||
UserExtra userExtra = userExtraMapper.selectOne(lqw);
|
||||
Integer value = kamil.getValue();
|
||||
userExtra.setIntegral(userExtra.getIntegral() + value);
|
||||
userExtraMapper.updateById(userExtra);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.ruoyi.system.basics.factory.kamil.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.muta.basics.factory.kamil.KamilConsumption;
|
||||
import com.muta.common.annotation.IntegralLogInsert;
|
||||
import com.muta.common.constant.OperationConstants;
|
||||
import com.muta.common.core.domain.entity.UserExtra;
|
||||
import com.muta.common.utils.SecurityUtils;
|
||||
import com.muta.basics.domain.Kamil;
|
||||
import com.muta.system.domain.Vip;
|
||||
import com.muta.system.mapper.UserExtraMapper;
|
||||
import com.muta.system.mapper.VipMapper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author 马兰友
|
||||
* @Date: 2024/04/22/19:49
|
||||
*/
|
||||
@Component
|
||||
public class SvipKamilConsumption implements KamilConsumption {
|
||||
|
||||
@Resource
|
||||
private VipMapper vipMapper;
|
||||
|
||||
@Override
|
||||
@IntegralLogInsert(operation = OperationConstants.Kamil)
|
||||
public void consumption(Kamil kamil) {
|
||||
LambdaQueryWrapper<Vip> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.eq(Vip::getUserId, SecurityUtils.getUserId());
|
||||
Vip vip = vipMapper.selectOne(lqw);
|
||||
Integer value = kamil.getValue();
|
||||
Date now = new Date();
|
||||
|
||||
Date svipExpireTime = vip.getSvipExpireTime();
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
//首先判断用户当前是不是svip 若是则在截止日期后加上value天
|
||||
if (null != svipExpireTime && svipExpireTime.after(now))
|
||||
calendar.setTime(vip.getVipExpireTime());
|
||||
|
||||
else {
|
||||
//若不是 则在从今天开始加上value天 作为截止日期 并更新开始时间为今日
|
||||
calendar.setTime(now);
|
||||
vip.setSvipBeginTime(now);
|
||||
}
|
||||
calendar.add(Calendar.DAY_OF_YEAR, value);
|
||||
vip.setSvipExpireTime(calendar.getTime());
|
||||
vipMapper.updateById(vip);
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.ruoyi.system.basics.factory.kamil.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.muta.basics.factory.kamil.KamilConsumption;
|
||||
import com.muta.common.annotation.IntegralLogInsert;
|
||||
import com.muta.common.constant.OperationConstants;
|
||||
import com.muta.common.core.domain.entity.UserExtra;
|
||||
import com.muta.common.utils.SecurityUtils;
|
||||
import com.muta.basics.domain.Kamil;
|
||||
import com.muta.system.domain.Vip;
|
||||
import com.muta.system.mapper.UserExtraMapper;
|
||||
import com.muta.system.mapper.VipMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author 马兰友
|
||||
* @Date: 2024/04/22/19:49
|
||||
*/
|
||||
@Service
|
||||
public class VipKamilConsumption implements KamilConsumption {
|
||||
|
||||
@Resource
|
||||
private UserExtraMapper userExtraMapper;
|
||||
@Resource
|
||||
private VipMapper vipMapper;
|
||||
|
||||
@Override
|
||||
@IntegralLogInsert(operation = OperationConstants.Kamil)
|
||||
public void consumption(Kamil kamil) {
|
||||
LambdaQueryWrapper<Vip> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.eq(Vip::getUserId, SecurityUtils.getUserId());
|
||||
Vip vip = vipMapper.selectOne(lqw);
|
||||
Integer value = kamil.getValue();
|
||||
Date now = new Date();
|
||||
Date vipExpireTime = vip.getVipExpireTime();
|
||||
Calendar expCalendar = Calendar.getInstance();
|
||||
//首先判断用户当前是不是svip 若是则在截止日期后加上value天
|
||||
if (null != vipExpireTime && vipExpireTime.after(now))
|
||||
expCalendar.setTime(vip.getVipExpireTime());
|
||||
else {
|
||||
//若不是 则在从今天开始加上value天 作为截止日期 并更新开始日期为今日
|
||||
expCalendar.setTime(now);
|
||||
vip.setVipBeginTime(now);
|
||||
}
|
||||
expCalendar.add(Calendar.DAY_OF_YEAR, value);
|
||||
vip.setVipExpireTime(expCalendar.getTime());
|
||||
vipMapper.updateById(vip);
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package com.ruoyi.system.basics.mapper;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.muta.basics.domain.Kamil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 【请填写功能名称】Mapper接口
|
||||
*
|
||||
* @author mutaai
|
||||
* @date 2024-04-21
|
||||
*/
|
||||
public interface KamilMapper extends BaseMapper<Kamil> {
|
||||
/**
|
||||
* 查询【请填写功能名称】
|
||||
*
|
||||
* @param id 【请填写功能名称】主键
|
||||
* @return 【请填写功能名称】
|
||||
*/
|
||||
public Kamil selectKamilById(String id);
|
||||
|
||||
/**
|
||||
* 查询【请填写功能名称】列表
|
||||
*
|
||||
* @param kamil 【请填写功能名称】
|
||||
* @return 【请填写功能名称】集合
|
||||
*/
|
||||
public List<Kamil> selectKamilList(Kamil kamil);
|
||||
|
||||
/**
|
||||
* 新增【请填写功能名称】
|
||||
*
|
||||
* @param kamil 【请填写功能名称】
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertKamil(Kamil kamil);
|
||||
|
||||
/**
|
||||
* 修改【请填写功能名称】
|
||||
*
|
||||
* @param kamil 【请填写功能名称】
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateKamil(Kamil kamil);
|
||||
|
||||
/**
|
||||
* 删除【请填写功能名称】
|
||||
*
|
||||
* @param id 【请填写功能名称】主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteKamilById(String id);
|
||||
|
||||
/**
|
||||
* 批量删除【请填写功能名称】
|
||||
*
|
||||
* @param ids 需要删除的数据主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteKamilByIds(String[] ids);
|
||||
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package com.ruoyi.system.basics.service;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.muta.common.core.domain.AjaxResult;
|
||||
import com.muta.basics.domain.Kamil;
|
||||
import com.muta.basics.domain.dto.KamilAddDTO;
|
||||
import com.muta.basics.domain.dto.KamilConDefDTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 【请填写功能名称】Service接口
|
||||
*
|
||||
* @author mutaai
|
||||
* @date 2024-04-21
|
||||
*/
|
||||
public interface IKamilService extends IService<Kamil> {
|
||||
/**
|
||||
* 查询【请填写功能名称】
|
||||
*
|
||||
* @param id 【请填写功能名称】主键
|
||||
* @return 【请填写功能名称】
|
||||
*/
|
||||
public Kamil selectKamilById(String id);
|
||||
|
||||
/**
|
||||
* 查询【请填写功能名称】列表
|
||||
*
|
||||
* @param kamil 【请填写功能名称】
|
||||
* @return 【请填写功能名称】集合
|
||||
*/
|
||||
public List<Kamil> selectKamilList(Kamil kamil);
|
||||
|
||||
/**
|
||||
* 新增【请填写功能名称】
|
||||
*
|
||||
* @param kamil 【请填写功能名称】
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertKamil(Kamil kamil);
|
||||
|
||||
/**
|
||||
* 修改【请填写功能名称】
|
||||
*
|
||||
* @param kamil 【请填写功能名称】
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateKamil(Kamil kamil);
|
||||
|
||||
/**
|
||||
* 批量删除【请填写功能名称】
|
||||
*
|
||||
* @param ids 需要删除的【请填写功能名称】主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteKamilByIds(String[] ids);
|
||||
|
||||
/**
|
||||
* 删除【请填写功能名称】信息
|
||||
*
|
||||
* @param id 【请填写功能名称】主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteKamilById(String id);
|
||||
|
||||
void addBatch(KamilAddDTO kamilAddDTO);
|
||||
|
||||
AjaxResult use(String key);
|
||||
|
||||
AjaxResult conDef(KamilConDefDTO kamilConDefDTO);
|
||||
}
|
@ -0,0 +1,190 @@
|
||||
package com.ruoyi.system.basics.service.impl;
|
||||
|
||||
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.crypto.digest.MD5;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.muta.common.annotation.RepeatSubmit;
|
||||
import com.muta.common.core.domain.AjaxResult;
|
||||
import com.muta.common.utils.DateUtils;
|
||||
import com.muta.common.utils.SecurityUtils;
|
||||
import com.muta.basics.domain.dto.KamilConDefDTO;
|
||||
import com.muta.basics.factory.kamil.KamilTypeFactory;
|
||||
import com.muta.basics.domain.Kamil;
|
||||
import com.muta.basics.domain.dto.KamilAddDTO;
|
||||
import com.muta.basics.mapper.KamilMapper;
|
||||
import com.muta.basics.service.IKamilService;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static com.muta.common.constant.CacheConstants.KAMIL_KEY;
|
||||
|
||||
|
||||
/**
|
||||
* 【请填写功能名称】Service业务层处理
|
||||
*
|
||||
* @author mutaai
|
||||
* @date 2024-04-21
|
||||
*/
|
||||
@Service
|
||||
public class KamilServiceImpl extends ServiceImpl<KamilMapper, Kamil> implements IKamilService {
|
||||
@Resource
|
||||
private KamilMapper kamilMapper;
|
||||
|
||||
@Resource
|
||||
private KamilTypeFactory kamilTypeFactory;
|
||||
|
||||
@Resource
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
/**
|
||||
* 查询【请填写功能名称】
|
||||
*
|
||||
* @param id 【请填写功能名称】主键
|
||||
* @return 【请填写功能名称】
|
||||
*/
|
||||
@Override
|
||||
public Kamil selectKamilById(String id) {
|
||||
return kamilMapper.selectKamilById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询【请填写功能名称】列表
|
||||
*
|
||||
* @param kamil 【请填写功能名称】
|
||||
* @return 【请填写功能名称】
|
||||
*/
|
||||
@Override
|
||||
public List<Kamil> selectKamilList(Kamil kamil) {
|
||||
return kamilMapper.selectList(new LambdaQueryWrapper<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增【请填写功能名称】
|
||||
*
|
||||
* @param kamil 【请填写功能名称】
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int insertKamil(Kamil kamil) {
|
||||
kamil.setCreateTime(DateUtils.getNowDate());
|
||||
return kamilMapper.insertKamil(kamil);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改【请填写功能名称】
|
||||
*
|
||||
* @param kamil 【请填写功能名称】
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int updateKamil(Kamil kamil) {
|
||||
kamil.setUpdateTime(DateUtils.getNowDate());
|
||||
return kamilMapper.updateKamil(kamil);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除【请填写功能名称】
|
||||
*
|
||||
* @param ids 需要删除的【请填写功能名称】主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteKamilByIds(String[] ids) {
|
||||
return kamilMapper.deleteKamilByIds(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除【请填写功能名称】信息
|
||||
*
|
||||
* @param id 【请填写功能名称】主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteKamilById(String id) {
|
||||
return kamilMapper.deleteKamilById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void addBatch(KamilAddDTO kamilAddDTO) {
|
||||
int n = kamilAddDTO.getQuantity();
|
||||
Kamil kamil = new Kamil();
|
||||
kamil.setType(kamilAddDTO.getType());
|
||||
kamil.setValue(kamilAddDTO.getValue());
|
||||
//生成n个卡密
|
||||
for (int i = 0; i < n; i++) {
|
||||
//卡密的key为对当前时间戳进行md5加密获得的32位字符串
|
||||
kamil.setKey(MD5.create().digestHex(String.valueOf(System.currentTimeMillis())));
|
||||
kamilMapper.insert(kamil);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@RepeatSubmit
|
||||
public AjaxResult use(String key) {
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
LambdaQueryWrapper<Kamil> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.eq(Kamil::getKey, key);
|
||||
//根据用户输入的key查找卡密 对其存在与否以及状态进行判断
|
||||
Kamil kamil = kamilMapper.selectOne(lqw);
|
||||
System.out.println(kamil);
|
||||
if (ObjUtil.isEmpty(kamil))
|
||||
return AjaxResult.error("卡密不存在");
|
||||
if (kamil.getEndTime() == null) {
|
||||
if (kamil.getStatus() == 1)
|
||||
return AjaxResult.error("卡密已被使用");
|
||||
//校验通过 修改数据库卡密状态
|
||||
kamil.setStatus(1);
|
||||
kamil.setUserId(userId);
|
||||
kamilMapper.updateById(kamil);
|
||||
} else {
|
||||
//是存在截止时间的自定义卡密
|
||||
if (kamil.getEndTime().before(new Date())) {
|
||||
//判断是否已过期
|
||||
if (kamil.getStatus() == 0) {
|
||||
//过期 且status为0 则将其status设置为1 并将该key从redis中删除
|
||||
kamil.setStatus(1);
|
||||
stringRedisTemplate.delete(KAMIL_KEY + key);
|
||||
kamilMapper.updateById(kamil);
|
||||
}
|
||||
return AjaxResult.error("卡密已过期");
|
||||
}
|
||||
//该卡密未过期 判断该用户是否使用过 也就是判断以该卡密的key为 key的set列表中有没有该用户的userId 若有 则使用过
|
||||
if (Boolean.TRUE.equals(stringRedisTemplate.opsForSet().isMember(KAMIL_KEY + key, userId.toString()))) {
|
||||
return AjaxResult.error("您已使用过该卡密");
|
||||
} else {
|
||||
//没使用过该卡密 将用户id添加到set列表中
|
||||
stringRedisTemplate.opsForSet().add(KAMIL_KEY + key, userId.toString());
|
||||
}
|
||||
}
|
||||
//调用工厂 消耗卡密 为用户增加相应的值
|
||||
kamilTypeFactory.consumption(kamil);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AjaxResult conDef(KamilConDefDTO kamilConDefDTO) {
|
||||
Kamil kamil = new Kamil();
|
||||
LambdaQueryWrapper<Kamil> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.eq(Kamil::getKey, kamilConDefDTO.getKey()); //构建查询条件 查询卡密的key是否被占用
|
||||
if (ObjectUtil.isNotEmpty(kamilMapper.selectList(lqw))) {
|
||||
return AjaxResult.error("卡密已存在"); //卡密已存在 返回错误信息 生成失败
|
||||
};
|
||||
//校验成功 将dto中的值拷贝到kamil对象中
|
||||
kamil.setKey(kamilConDefDTO.getKey());
|
||||
kamil.setValue(kamilConDefDTO.getValue());
|
||||
kamil.setType(kamilConDefDTO.getType());
|
||||
kamil.setEndTime(kamilConDefDTO.getEndTime());
|
||||
//新增
|
||||
kamilMapper.insert(kamil);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.ruoyi.system.dao;
|
||||
|
||||
import cn.bugstack.infrastructure.dao.po.GroupBuyActivity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Fuzhengwei bugstack.cn @小傅哥
|
||||
* @description 拼团活动Dao
|
||||
* @create 2024-12-07 10:10
|
||||
*/
|
||||
@Mapper
|
||||
public interface IGroupBuyActivityDao {
|
||||
|
||||
List<GroupBuyActivity> queryGroupBuyActivityList();
|
||||
|
||||
GroupBuyActivity queryValidGroupBuyActivity(GroupBuyActivity groupBuyActivityReq);
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.ruoyi.system.dao;
|
||||
|
||||
import cn.bugstack.infrastructure.dao.po.GroupBuyDiscount;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Fuzhengwei bugstack.cn @小傅哥
|
||||
* @description 折扣配置Dao
|
||||
* @create 2024-12-07 10:10
|
||||
*/
|
||||
@Mapper
|
||||
public interface IGroupBuyDiscountDao {
|
||||
|
||||
List<GroupBuyDiscount> queryGroupBuyDiscountList();
|
||||
|
||||
GroupBuyDiscount queryGroupBuyActivityDiscountByDiscountId(String discountId);
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.ruoyi.system.dao;
|
||||
|
||||
import cn.bugstack.infrastructure.dao.po.Sku;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* @author Fuzhengwei bugstack.cn @小傅哥
|
||||
* @description 商品查询
|
||||
* @create 2024-12-21 10:48
|
||||
*/
|
||||
@Mapper
|
||||
public interface ISkuDao {
|
||||
|
||||
Sku querySkuByGoodsId(String goodsId);
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.ruoyi.system.dao.po;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author Fuzhengwei bugstack.cn @小傅哥
|
||||
* @description 商品信息
|
||||
* @create 2024-12-21 10:45
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class Sku {
|
||||
|
||||
/** 自增 */
|
||||
private Long id;
|
||||
/** 来源 */
|
||||
private String source;
|
||||
/** 渠道 */
|
||||
private String channel;
|
||||
/** 商品ID */
|
||||
private String goodsId;
|
||||
/** 商品名称 */
|
||||
private String goodsName;
|
||||
/** 原始价格 */
|
||||
private BigDecimal originalPrice;
|
||||
/** 创建时间 */
|
||||
private Date createTime;
|
||||
/** 更新时间 */
|
||||
private Date updateTime;
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.ruoyi.system.distribution.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class FundsLog {
|
||||
|
||||
private Long id;
|
||||
private String consumer;
|
||||
private String beneficiaries;
|
||||
private BigDecimal consume;
|
||||
private BigDecimal earnings;
|
||||
private Integer persent;
|
||||
private Long userId;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss")
|
||||
private LocalDateTime createTime;
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.ruoyi.system.distribution.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author: Larry
|
||||
* @Date: 2024 /04 /27 / 15:34
|
||||
* @Description:
|
||||
*/
|
||||
@Mapper
|
||||
public interface DistributionDataMapper {
|
||||
public List<String> usernameList(Long id);
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.ruoyi.system.distribution.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.muta.common.core.domain.entity.SysUser;
|
||||
import com.muta.distribution.domain.FundsLog;
|
||||
import com.muta.system.domain.SigninLog;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface FundsLogMapper extends BaseMapper<FundsLog> {
|
||||
|
||||
List<SigninLog> logList(SysUser sysUser);
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package com.ruoyi.system.distribution.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface DistributionService {
|
||||
|
||||
void benefit(Double basic);
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package com.ruoyi.system.distribution.service.impl;
|
||||
|
||||
import com.muta.common.core.domain.entity.SysUser;
|
||||
import com.muta.common.core.domain.entity.UserExtra;
|
||||
import com.muta.common.utils.SecurityUtils;
|
||||
import com.muta.distribution.domain.FundsLog;
|
||||
import com.muta.distribution.mapper.FundsLogMapper;
|
||||
import com.muta.system.service.ISysUserService;
|
||||
import com.muta.system.service.IUserExtraService;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author: Larry
|
||||
* @Date: 2024 /08 /12 / 1:23
|
||||
* @Description:
|
||||
*/
|
||||
public class DistributionService {
|
||||
@Resource
|
||||
private IUserExtraService userExtraService;
|
||||
@Resource
|
||||
private FundsLogMapper fundsLogMapper;
|
||||
@Resource
|
||||
private ISysUserService sysUserService;
|
||||
|
||||
public void distribute(BigDecimal money){
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
SysUser sysUser = sysUserService.selectUserById(userId);
|
||||
SysUser father = sysUserService.selectUserById(sysUser.getUserExtra().getLowestId());
|
||||
//如果最近代理直接是管理员
|
||||
if(SecurityUtils.isAdmin(sysUser.getUserExtra().getLowestId())){
|
||||
FundsLog fundsLog = new FundsLog();
|
||||
fundsLog.setConsume(money);
|
||||
fundsLog.setPersent(100);
|
||||
fundsLog.setBeneficiaries(SecurityUtils.getUsername());
|
||||
fundsLogMapper.insert(fundsLog);
|
||||
}
|
||||
//如果是一级代理
|
||||
else if(father.getRoleId() == 1){
|
||||
//一级
|
||||
FundsLog fundsLog = new FundsLog();
|
||||
fundsLog.setConsume(money.divide(BigDecimal.valueOf(father.getUserExtra().getPercentage())));
|
||||
fundsLog.setPersent(father.getUserExtra().getPercentage());
|
||||
fundsLog.setBeneficiaries(SecurityUtils.getUsername());
|
||||
fundsLogMapper.insert(fundsLog);
|
||||
//超管
|
||||
FundsLog fundsLog1 = new FundsLog();
|
||||
fundsLog.setConsume(money.subtract(money.divide(BigDecimal.valueOf(father.getUserExtra().getPercentage()))));
|
||||
fundsLog.setPersent(100);
|
||||
fundsLog.setBeneficiaries(SecurityUtils.getUsername());
|
||||
fundsLogMapper.insert(fundsLog);
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,225 @@
|
||||
package com.ruoyi.system.distribution.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.muta.common.core.domain.entity.UserExtra;
|
||||
import com.muta.common.utils.SecurityUtils;
|
||||
import com.muta.distribution.domain.FundsLog;
|
||||
import com.muta.distribution.mapper.FundsLogMapper;
|
||||
import com.muta.distribution.service.DistributionService;
|
||||
import com.muta.log.service.impl.DistributionIntegralServiceImpl;
|
||||
import com.muta.system.mapper.UserExtraMapper;
|
||||
import com.muta.system.service.ISysUserService;
|
||||
import com.muta.system.service.IUserExtraService;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
|
||||
@Service
|
||||
public class DistributionServiceImpl implements DistributionService {
|
||||
|
||||
@Resource
|
||||
private IUserExtraService userExtraService;
|
||||
|
||||
@Resource
|
||||
private ISysUserService sysUserService;
|
||||
|
||||
@Resource
|
||||
private FundsLogMapper fundsLogMapper;
|
||||
|
||||
@Resource
|
||||
private UserExtraMapper userExtraMapper;
|
||||
|
||||
@Resource
|
||||
private DistributionIntegralServiceImpl distributionIntegralService;
|
||||
|
||||
|
||||
/*@Override
|
||||
public void efit(Double basic) {
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
Long pid = 0L, lid = 0L, fid = 0L;
|
||||
double persent;
|
||||
double template = basic;
|
||||
|
||||
do {
|
||||
LambdaQueryWrapper<UserExtra> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.eq(UserExtra::getUserId, userId);
|
||||
UserExtra tree = userExtraService.getOne(lqw);
|
||||
|
||||
pid = tree.getSuperiorId();
|
||||
lid = tree.getLowestId();
|
||||
fid = tree.getFirstId();
|
||||
|
||||
userId = check(pid, lid, fid) ? doCash(tree, basic) : doIntegral(pid, template);
|
||||
LambdaQueryWrapper<UserExtra> fatherLqw = new LambdaQueryWrapper<>();
|
||||
fatherLqw.eq(UserExtra::getUserId, pid);
|
||||
UserExtra father = userExtraService.getOne(fatherLqw);
|
||||
|
||||
persent = father.getPercentage();
|
||||
template *= persent;
|
||||
} while (check(pid, lid, fid));
|
||||
}
|
||||
|
||||
public Long doIntegral(Long pid, double template) {
|
||||
LambdaQueryWrapper<UserExtra> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.eq(UserExtra::getUserId, pid);
|
||||
UserExtra one = userExtraService.getOne(lqw);
|
||||
|
||||
LambdaQueryWrapper<UserExtra> fatherLqw = new LambdaQueryWrapper<>();
|
||||
fatherLqw.eq(UserExtra::getUserId, one.getSuperiorId());
|
||||
UserExtra father = userExtraService.getOne(fatherLqw);
|
||||
|
||||
one.setIntegral((int) (one.getIntegral() + template));
|
||||
if (!check(one.getSuperiorId(), one.getLowestId(), one.getFirstId()))
|
||||
one.setIntegral((int) (one.getIntegral() - template * father.getPercentage()));
|
||||
|
||||
// TODO 积分记录
|
||||
userExtraMapper.update(one, lqw);
|
||||
|
||||
return pid;
|
||||
}*/
|
||||
|
||||
public Long doCash(UserExtra tree, double baisc) {
|
||||
double persent = 1;
|
||||
|
||||
while (!Objects.equals(tree.getSuperiorId(), tree.getLowestId())) {
|
||||
System.out.println("find");
|
||||
LambdaQueryWrapper<UserExtra> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.eq(UserExtra::getUserId, tree.getSuperiorId());
|
||||
tree = userExtraMapper.selectOne(lqw);
|
||||
}
|
||||
|
||||
do {
|
||||
System.err.println("cash");
|
||||
UserExtra last = tree;
|
||||
LambdaQueryWrapper<UserExtra> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.eq(UserExtra::getUserId, tree.getSuperiorId());
|
||||
tree = userExtraService.getOne(lqw);
|
||||
System.err.println("last=>" + last);
|
||||
System.err.println("tree=>" + tree);
|
||||
BigDecimal before = tree.getCash();
|
||||
|
||||
tree.setCash(tree.getCash().add(new BigDecimal(String.valueOf(baisc * persent))));
|
||||
baisc *= persent;
|
||||
if (ObjectUtils.isNotEmpty(tree.getSuperiorId())) {
|
||||
LambdaQueryWrapper<UserExtra> fatherLqw = new LambdaQueryWrapper<>();
|
||||
|
||||
fatherLqw.eq(UserExtra::getUserId, tree.getSuperiorId());
|
||||
UserExtra father = userExtraService.getOne(fatherLqw);
|
||||
|
||||
persent = (double) father.getPercentage() / 100;
|
||||
tree.setCash(tree.getCash().subtract(new BigDecimal(String.valueOf(baisc * persent))));
|
||||
}
|
||||
BigDecimal after = tree.getCash();
|
||||
|
||||
fundsLogMapper.insert(FundsLog.builder()
|
||||
.consume(new BigDecimal(String.valueOf(baisc)))
|
||||
.earnings(after.subtract(before))
|
||||
.consumer(sysUserService.getNameById(last.getUserId()))
|
||||
.beneficiaries(sysUserService.getNameById(tree.getUserId()))
|
||||
.persent(tree.getPercentage())
|
||||
.createTime(LocalDateTime.now())
|
||||
.userId(last.getUserId())
|
||||
.build());
|
||||
userExtraMapper.update(tree, lqw);
|
||||
} while (ObjectUtils.isNotEmpty(tree.getSuperiorId()));
|
||||
|
||||
return tree.getUserId();
|
||||
}
|
||||
|
||||
public boolean check(Long pid, Long lid, Long fid) {
|
||||
return Objects.equals(pid, lid) || Objects.equals(pid, fid) || pid == 1L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void benefit(Double basic) {
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
if(SecurityUtils.isAdmin(SecurityUtils.getUserId())){
|
||||
return;
|
||||
}
|
||||
UserExtra user = userExtraMapper.selectOne(new LambdaQueryWrapper<UserExtra>().eq(UserExtra::getUserId, userId));
|
||||
|
||||
if (!check(user.getSuperiorId(), user.getLowestId(), user.getFirstId())) {
|
||||
UserExtra father = userExtraMapper.selectOne(new LambdaQueryWrapper<UserExtra>().eq(UserExtra::getUserId, user.getSuperiorId()));
|
||||
father.setIntegral(father.getIntegral() + 100);
|
||||
|
||||
distributionIntegralService.insertDisLog(father.getId());
|
||||
|
||||
userExtraMapper.update(father, new LambdaQueryWrapper<UserExtra>().eq(UserExtra::getUserId, user.getSuperiorId()));
|
||||
}
|
||||
|
||||
doCash(user, basic);
|
||||
|
||||
// UserExtra lowest = userExtraMapper.selectOne(new LambdaQueryWrapper<UserExtra>().eq(UserExtra::getUserId, user.getLowestId()));
|
||||
// UserExtra first = userExtraMapper.selectOne(new LambdaQueryWrapper<UserExtra>().eq(UserExtra::getUserId, user.getFirstId()));
|
||||
// UserExtra root = userExtraMapper.selectOne(new LambdaQueryWrapper<UserExtra>().eq(UserExtra::getUserId, 1L));
|
||||
//
|
||||
//
|
||||
// double persent = 1;
|
||||
// if (ObjectUtils.isNotEmpty(lowest) && lowest.getId() != 1L) {
|
||||
// lowest.setCash(lowest.getCash().add(new BigDecimal(String.valueOf(basic * persent))));
|
||||
// BigDecimal bl = lowest.getCash();
|
||||
// BigDecimal bf = first.getCash();
|
||||
// BigDecimal br = root.getCash();
|
||||
// if (lowest.getFirstId() != null) {
|
||||
// persent = (double) first.getPercentage() / 100;
|
||||
// lowest.setCash(lowest.getCash().subtract(new BigDecimal(String.valueOf(basic * persent))));
|
||||
//
|
||||
// first.setCash(first.getCash().add(new BigDecimal(String.valueOf(basic * persent))));
|
||||
//
|
||||
// basic *= persent;
|
||||
// persent = (double) root.getPercentage() / 100;
|
||||
// first.setCash(first.getCash().subtract(new BigDecimal(String.valueOf(basic * persent))));
|
||||
// root.setCash(root.getCash().add(new BigDecimal(String.valueOf(basic * persent))));
|
||||
//
|
||||
// // TODO 资金记录
|
||||
//
|
||||
// userExtraMapper.update(first, new LambdaQueryWrapper<UserExtra>().eq(UserExtra::getUserId, lowest.getFirstId()));
|
||||
// userExtraMapper.update(root, new LambdaQueryWrapper<UserExtra>().eq(UserExtra::getUserId, 1L));
|
||||
// }
|
||||
// BigDecimal al = lowest.getCash();
|
||||
// BigDecimal af = first.getCash();
|
||||
// BigDecimal ar = root.getCash();
|
||||
//
|
||||
// fundsLogMapper.insert(FundsLog.builder()
|
||||
// .beneficiaries(sysUserService.getNameById(lowest.getUserId()))
|
||||
// .consumer(sysUserService.getNameById(userId))
|
||||
// .consume(new BigDecimal(String.valueOf(basic)))
|
||||
// .earnings(al.subtract(bl))
|
||||
// .persent(lowest.getPercentage())
|
||||
// .build());
|
||||
//
|
||||
// if (ObjectUtils.isNotEmpty(first))
|
||||
// fundsLogMapper.insert(FundsLog.builder()
|
||||
// .beneficiaries(sysUserService.getNameById(first.getUserId()))
|
||||
// .consumer(sysUserService.getNameById(lowest.getUserId()))
|
||||
// .consume(al.subtract(bl))
|
||||
// .earnings(af.subtract(bf))
|
||||
// .persent(first.getPercentage())
|
||||
// .build());
|
||||
//
|
||||
// if (ObjectUtils.isNotEmpty())
|
||||
//
|
||||
// userExtraMapper.update(lowest, new LambdaQueryWrapper<UserExtra>().eq(UserExtra::getUserId, user.getLowestId()));
|
||||
// } else if (ObjectUtils.isNotEmpty(first)) {
|
||||
// first.setCash(first.getCash().add(new BigDecimal(String.valueOf(basic * persent))));
|
||||
//
|
||||
// persent = (double) root.getPercentage() / 100;
|
||||
// first.setCash(first.getCash().subtract(new BigDecimal(String.valueOf(basic * persent))));
|
||||
// root.setCash(root.getCash().add(new BigDecimal(String.valueOf(basic * persent))));
|
||||
//
|
||||
// userExtraMapper.update(first, new LambdaQueryWrapper<UserExtra>().eq(UserExtra::getUserId, lowest.getFirstId()));
|
||||
// userExtraMapper.update(root, new LambdaQueryWrapper<UserExtra>().eq(UserExtra::getUserId, 1L));
|
||||
// } else {
|
||||
// root.setCash(root.getCash().add(new BigDecimal(String.valueOf(basic * persent))));
|
||||
//
|
||||
// userExtraMapper.update(root, new LambdaQueryWrapper<UserExtra>().eq(UserExtra::getUserId, 1L));
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.ruoyi.system.file;
|
||||
|
||||
import com.muta.common.config.AliConfig;
|
||||
import com.muta.common.core.service.ISysFileService;
|
||||
import com.muta.common.utils.oss.OSSSignatureExample;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* @author: Larry
|
||||
* @Date: 2024 /06 /06 / 16:23
|
||||
* @Description:
|
||||
*/
|
||||
@Component
|
||||
public class FileSignature {
|
||||
@Resource
|
||||
private ISysFileService aliOssService;
|
||||
public String getSignUrl(String fileUrl){
|
||||
AliConfig aliConfig = new AliConfig();
|
||||
aliOssService.getConfig(aliConfig);
|
||||
return OSSSignatureExample.generateSignedUrl(aliConfig, fileUrl.substring(fileUrl.lastIndexOf("/") + 1));
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
package com.ruoyi.system.gateway.dto;
|
@ -0,0 +1,27 @@
|
||||
package com.ruoyi.system.handler;
|
||||
import com.zy.exception.ConditionException;
|
||||
import com.zy.util.JsonResponse;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
@ControllerAdvice
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
public class CommonGlobalExceptionHandler {
|
||||
|
||||
@ExceptionHandler(value = Exception.class)
|
||||
@ResponseBody
|
||||
public JsonResponse<String> commonExceptionHandler(HttpServletRequest request, Exception e){
|
||||
String errorMsg = e.getMessage();
|
||||
if(e instanceof ConditionException){
|
||||
String errorCode = ((ConditionException)e).getCode();
|
||||
return new JsonResponse<>(errorCode, errorMsg);
|
||||
}else{
|
||||
return new JsonResponse<>("500",errorMsg);
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue