作者 钟来

Default Changelist

@@ -30,10 +30,12 @@ public class ChatGPTApiController { @@ -30,10 +30,12 @@ public class ChatGPTApiController {
30 @PostMapping("/sendFreeMessage") 30 @PostMapping("/sendFreeMessage")
31 public String sendFreeMessage(@RequestBody String jsonStr) 31 public String sendFreeMessage(@RequestBody String jsonStr)
32 { 32 {
  33 + logger.info("请求内容:{}", jsonStr);
33 int timeout = 3000000; 34 int timeout = 3000000;
34 Map<String,String> map = new HashMap<>(); 35 Map<String,String> map = new HashMap<>();
35 map.put("Authorization","Bearer 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"); 36 map.put("Authorization","Bearer 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");
36 String str = HttpRequest.post("https://api.openai.com/v1/chat/completions").setReadTimeout(timeout).timeout(timeout).addHeaders(map).body(jsonStr).execute().body(); 37 String str = HttpRequest.post("https://api.openai.com/v1/chat/completions").setReadTimeout(timeout).timeout(timeout).addHeaders(map).body(jsonStr).execute().body();
  38 + logger.info("返回内容:{}", str);
37 return str; 39 return str;
38 } 40 }
39 41
@@ -41,10 +43,12 @@ public class ChatGPTApiController { @@ -41,10 +43,12 @@ public class ChatGPTApiController {
41 @PostMapping("/sendNotFreeMessage") 43 @PostMapping("/sendNotFreeMessage")
42 public String sendNotFreeMessage(@RequestBody String jsonStr) 44 public String sendNotFreeMessage(@RequestBody String jsonStr)
43 { 45 {
  46 + logger.info("请求内容:{}", jsonStr);
44 int timeout = 3000000; 47 int timeout = 3000000;
45 Map<String,String> map = new HashMap<>(); 48 Map<String,String> map = new HashMap<>();
46 map.put("Authorization","Bearer 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"); 49 map.put("Authorization","Bearer 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");
47 String str = HttpRequest.post("https://api.openai.com/v1/chat/completions").setReadTimeout(timeout).timeout(timeout).addHeaders(map).body(jsonStr).execute().body(); 50 String str = HttpRequest.post("https://api.openai.com/v1/chat/completions").setReadTimeout(timeout).timeout(timeout).addHeaders(map).body(jsonStr).execute().body();
  51 + logger.info("返回内容:{}", str);
48 return str; 52 return str;
49 } 53 }
50 54
@@ -8,10 +8,7 @@ import com.ruoyi.common.core.domain.AjaxResult; @@ -8,10 +8,7 @@ import com.ruoyi.common.core.domain.AjaxResult;
8 import com.ruoyi.common.core.domain.Message; 8 import com.ruoyi.common.core.domain.Message;
9 import com.ruoyi.common.core.domain.MessageCode; 9 import com.ruoyi.common.core.domain.MessageCode;
10 import com.ruoyi.common.core.redis.RedisCache; 10 import com.ruoyi.common.core.redis.RedisCache;
11 -import com.ruoyi.common.utils.Arith;  
12 -import com.ruoyi.common.utils.DateUtils;  
13 -import com.ruoyi.common.utils.SecurityUtils;  
14 -import com.ruoyi.common.utils.StringUtils; 11 +import com.ruoyi.common.utils.*;
15 import com.ruoyi.common.utils.bean.BeanUtils; 12 import com.ruoyi.common.utils.bean.BeanUtils;
16 import com.ruoyi.system.login.dto.OpenAiLoginUser; 13 import com.ruoyi.system.login.dto.OpenAiLoginUser;
17 import com.ruoyi.system.login.dto.OpenAiUserInfo; 14 import com.ruoyi.system.login.dto.OpenAiUserInfo;
@@ -243,12 +240,12 @@ public class ChatGPTController extends BaseController { @@ -243,12 +240,12 @@ public class ChatGPTController extends BaseController {
243 */ 240 */
244 private CompletionResult3_5 sendGPTAi(List<ChatRoomMessages> messageList) 241 private CompletionResult3_5 sendGPTAi(List<ChatRoomMessages> messageList)
245 { 242 {
246 - logger.info("请求内容:{}",messageList); 243 + logger.info("请求内容:{}",GsonConstructor.get().toJson(messageList));
247 JSONObject jsonObject = new JSONObject(); 244 JSONObject jsonObject = new JSONObject();
248 jsonObject.put("model","gpt-3.5-turbo-0301"); 245 jsonObject.put("model","gpt-3.5-turbo-0301");
249 jsonObject.put("messages",messageList); 246 jsonObject.put("messages",messageList);
250 - String str = HttpUtil.post("http://23.224.171.145:8086/chatGPTApi/sendNotFreeMessage",jsonObject.toString());  
251 -// String str = HttpUtil.post("https://free.chatgpt.njlaikun.com/v1/chat/completions",jsonObject.toString()); 247 +// String str = HttpUtil.post("http://23.224.171.145:8086/chatGPTApi/sendNotFreeMessage",jsonObject.toString());
  248 + String str = HttpUtil.post("https://free.chatgpt.njlaikun.com/v1/chat/completions",jsonObject.toString());
252 249
253 logger.info("返回的数据:{}",str); 250 logger.info("返回的数据:{}",str);
254 CompletionResult3_5 completionResult = JSONObject.parseObject(str, CompletionResult3_5.class); 251 CompletionResult3_5 completionResult = JSONObject.parseObject(str, CompletionResult3_5.class);
@@ -262,12 +259,12 @@ public class ChatGPTController extends BaseController { @@ -262,12 +259,12 @@ public class ChatGPTController extends BaseController {
262 */ 259 */
263 private CompletionResult3_5 sendFreeGPTAi(List<ChatRoomMessages> messageList) 260 private CompletionResult3_5 sendFreeGPTAi(List<ChatRoomMessages> messageList)
264 { 261 {
265 - logger.info("请求内容:{}",messageList); 262 + logger.info("请求内容:{}", GsonConstructor.get().toJson(messageList));
266 JSONObject jsonObject = new JSONObject(); 263 JSONObject jsonObject = new JSONObject();
267 jsonObject.put("model","gpt-3.5-turbo-0301"); 264 jsonObject.put("model","gpt-3.5-turbo-0301");
268 jsonObject.put("messages",messageList); 265 jsonObject.put("messages",messageList);
269 - String str = HttpUtil.post("https://23.224.171.145:8086/chatGPTApi/sendFreeMessage",jsonObject.toString());  
270 -// String str = HttpUtil.post("https://free.chatgpt.njlaikun.com/v1/chat/completions",jsonObject.toString()); 266 +// String str = HttpUtil.post("http://23.224.171.145:8086/chatGPTApi/sendFreeMessage",jsonObject.toString());
  267 + String str = HttpUtil.post("https://free.chatgpt.njlaikun.com/v1/chat/completions",jsonObject.toString());
271 268
272 logger.info("返回的数据:{}",str); 269 logger.info("返回的数据:{}",str);
273 CompletionResult3_5 completionResult = JSONObject.parseObject(str, CompletionResult3_5.class); 270 CompletionResult3_5 completionResult = JSONObject.parseObject(str, CompletionResult3_5.class);
@@ -46,7 +46,7 @@ public class OpenAiUserLoginController extends BaseController { @@ -46,7 +46,7 @@ public class OpenAiUserLoginController extends BaseController {
46 @ApiImplicitParam(value = "验证码",name = "code"), 46 @ApiImplicitParam(value = "验证码",name = "code"),
47 }) 47 })
48 @PostMapping("/userpassLogin") 48 @PostMapping("/userpassLogin")
49 - public AjaxResult userpassLogin(String code, String key) 49 + public AjaxResult userpassLogin(String code, String key,String promo_code)
50 { 50 {
51 //验证验证码 51 //验证验证码
52 String str = HttpUtil.post("http://ly.userlogin.yu2le.com/userLogin/verificationCode?key="+key+"&code="+code,new HashMap<>()); 52 String str = HttpUtil.post("http://ly.userlogin.yu2le.com/userLogin/verificationCode?key="+key+"&code="+code,new HashMap<>());
1 package com.zhonglai.luhui.openai.controller; 1 package com.zhonglai.luhui.openai.controller;
2 2
  3 +import cn.hutool.core.bean.BeanUtil;
  4 +import cn.hutool.core.lang.Validator;
3 import com.ruoyi.common.config.RuoYiConfig; 5 import com.ruoyi.common.config.RuoYiConfig;
4 import com.ruoyi.common.core.controller.BaseController; 6 import com.ruoyi.common.core.controller.BaseController;
5 import com.ruoyi.common.core.domain.AjaxResult; 7 import com.ruoyi.common.core.domain.AjaxResult;
6 import com.ruoyi.common.core.page.TableDataInfo; 8 import com.ruoyi.common.core.page.TableDataInfo;
  9 +import com.ruoyi.common.utils.DateUtils;
7 import com.ruoyi.common.utils.StringUtils; 10 import com.ruoyi.common.utils.StringUtils;
8 import com.ruoyi.common.utils.file.FileUploadUtils; 11 import com.ruoyi.common.utils.file.FileUploadUtils;
9 import com.ruoyi.common.utils.file.FileUtils; 12 import com.ruoyi.common.utils.file.FileUtils;
@@ -11,17 +14,19 @@ import com.ruoyi.framework.config.ServerConfig; @@ -11,17 +14,19 @@ import com.ruoyi.framework.config.ServerConfig;
11 import com.ruoyi.system.login.dto.OpenAiLoginUser; 14 import com.ruoyi.system.login.dto.OpenAiLoginUser;
12 import com.ruoyi.system.login.dto.OpenAiUserInfo; 15 import com.ruoyi.system.login.dto.OpenAiUserInfo;
13 import com.ruoyi.system.service.PublicService; 16 import com.ruoyi.system.service.PublicService;
  17 +import com.zhonglai.luhui.openai.dto.CompletionChoiceMessage3_5;
  18 +import com.zhonglai.luhui.openai.dto.UserFlowPacketRemainLog;
  19 +import com.zhonglai.luhui.openai.service.VipServiceImpl;
14 import io.swagger.annotations.Api; 20 import io.swagger.annotations.Api;
15 import io.swagger.annotations.ApiImplicitParam; 21 import io.swagger.annotations.ApiImplicitParam;
16 import io.swagger.annotations.ApiImplicitParams; 22 import io.swagger.annotations.ApiImplicitParams;
17 import io.swagger.annotations.ApiOperation; 23 import io.swagger.annotations.ApiOperation;
18 import org.springframework.beans.factory.annotation.Autowired; 24 import org.springframework.beans.factory.annotation.Autowired;
19 -import org.springframework.web.bind.annotation.GetMapping;  
20 -import org.springframework.web.bind.annotation.PostMapping;  
21 -import org.springframework.web.bind.annotation.RequestMapping;  
22 -import org.springframework.web.bind.annotation.RestController; 25 +import org.springframework.transaction.annotation.Transactional;
  26 +import org.springframework.web.bind.annotation.*;
23 import org.springframework.web.multipart.MultipartFile; 27 import org.springframework.web.multipart.MultipartFile;
24 28
  29 +import java.math.BigDecimal;
25 import java.util.ArrayList; 30 import java.util.ArrayList;
26 import java.util.List; 31 import java.util.List;
27 import java.util.Map; 32 import java.util.Map;
@@ -37,6 +42,9 @@ public class UserInfoController extends BaseController { @@ -37,6 +42,9 @@ public class UserInfoController extends BaseController {
37 42
38 @Autowired 43 @Autowired
39 private PublicService publicService; 44 private PublicService publicService;
  45 +
  46 + @Autowired
  47 + private VipServiceImpl vipService;
40 @ApiOperation("获取用户信息") 48 @ApiOperation("获取用户信息")
41 @GetMapping("/getUserInfo") 49 @GetMapping("/getUserInfo")
42 public AjaxResult getUserInfo() 50 public AjaxResult getUserInfo()
@@ -84,7 +92,7 @@ public class UserInfoController extends BaseController { @@ -84,7 +92,7 @@ public class UserInfoController extends BaseController {
84 public TableDataInfo useFlowPacketRemainLog() 92 public TableDataInfo useFlowPacketRemainLog()
85 { 93 {
86 startPage(); 94 startPage();
87 - List<Map<String,Object>> list = publicService.getObjectListBySQL("SELECT * FROM `lk_openai`.`user_flow_packet_remain_log` WHERE `user_id`="+getUserId().intValue()+" and `type`=2 order by create_time desc"); 95 + List<Map<String,Object>> list = publicService.getObjectListBySQL("SELECT * FROM `lk_openai`.`user_flow_packet_remain_log` WHERE `user_id`="+getUserId().intValue()+" and (`type`=2 or `type`=3) order by create_time desc");
88 return getDataTable(list); 96 return getDataTable(list);
89 } 97 }
90 98
@@ -137,4 +145,127 @@ public class UserInfoController extends BaseController { @@ -137,4 +145,127 @@ public class UserInfoController extends BaseController {
137 return AjaxResult.error(e.getMessage()); 145 return AjaxResult.error(e.getMessage());
138 } 146 }
139 } 147 }
  148 +
  149 +
  150 +
  151 + @ApiOperation("代币代充")
  152 + @ApiImplicitParams({
  153 + @ApiImplicitParam(value = "需要充值的手机号",name = "phone"),
  154 + @ApiImplicitParam(value = "充值代币数量",name = "number")
  155 + })
  156 + @Transactional
  157 + @PostMapping("/agencyCharge/{phone}/{number}")
  158 + public AjaxResult agencyCharge(@PathVariable String phone,@PathVariable Long number)
  159 + {
  160 + if(!Validator.isMobile(phone))
  161 + {
  162 + return AjaxResult.error("请输入正确的手机号");
  163 + }
  164 +
  165 + if(null == number || number<=0)
  166 + {
  167 + return AjaxResult.error("充值代币数量不合法");
  168 + }
  169 + List<Map<String,Object>> userList = publicService.getObjectListBySQL("SELECT * FROM `lk_openai`.`user_info` WHERE phone='"+phone+"'");
  170 + if(null == userList || userList.size()==0)
  171 + {
  172 + return AjaxResult.error("用户没有登陆,请提现用户使用手机号登陆以后,再充值");
  173 + }
  174 +
  175 + OpenAiUserInfo myOpenAiUserInfo = publicService.getObjectForTableName(OpenAiUserInfo.class,"id",getUserId().toString(),"`lk_openai`.`user_info`");
  176 + if(myOpenAiUserInfo.getFlow_packet_remain()-number<=0)
  177 + {
  178 + return AjaxResult.error("您的余额不足请先为您自己充值");
  179 + }
  180 + if(myOpenAiUserInfo.getRole()-1!=0)
  181 + {
  182 + return AjaxResult.error("您不是代理商请先升级成代理商");
  183 + }
  184 +
  185 + BigDecimal[] bs = vipService.getUnitprice();
  186 + BigDecimal openaiUnitprice = bs[0];
  187 + BigDecimal realityUnitprice = bs[1];
  188 + if(openaiUnitprice.doubleValue()==0 || realityUnitprice.doubleValue()==0)
  189 + {
  190 + return AjaxResult.error("系统未配置流量单价,请联系管理员");
  191 + }
  192 +
  193 + //减去自己的余额
  194 + publicService.updateBySql("UPDATE `lk_openai`.`user_info` SET flow_packet_remain=flow_packet_remain-"+number+" WHERE id="+myOpenAiUserInfo.getId());
  195 + UserFlowPacketRemainLog userFlowPacketRemainLog = new UserFlowPacketRemainLog();
  196 + userFlowPacketRemainLog.setCreate_time(DateUtils.getNowTimeMilly());
  197 + userFlowPacketRemainLog.setUser_id(myOpenAiUserInfo.getId());
  198 + userFlowPacketRemainLog.setType(3); //消费
  199 +
  200 + StringBuffer stringBuffer = new StringBuffer();
  201 + stringBuffer.append("为手机号:");
  202 + stringBuffer.append(phone);
  203 + stringBuffer.append(" 的用户代充:");
  204 + stringBuffer.append(number);
  205 + stringBuffer.append(" 代币");
  206 + stringBuffer.append(";");
  207 + stringBuffer.append("剩余代币: ");
  208 + stringBuffer.append(myOpenAiUserInfo.getFlow_packet_remain()-number);
  209 + stringBuffer.append(" ;");
  210 + userFlowPacketRemainLog.setDescribe(stringBuffer.toString());
  211 + userFlowPacketRemainLog.setTotal_tokens(number);
  212 + userFlowPacketRemainLog.setOpenai_money((openaiUnitprice.multiply(new BigDecimal(userFlowPacketRemainLog.getTotal_tokens()))).divide(new BigDecimal(1000),6,BigDecimal.ROUND_HALF_UP));
  213 + userFlowPacketRemainLog.setReality_money((realityUnitprice.multiply(new BigDecimal(userFlowPacketRemainLog.getTotal_tokens()))).divide(new BigDecimal(1000),6,BigDecimal.ROUND_HALF_UP));
  214 + publicService.insertToTable(userFlowPacketRemainLog,"`lk_openai`.`user_flow_packet_remain_log`");
  215 +
  216 + OpenAiUserInfo openAiUserInfo = BeanUtil.mapToBean(userList.get(0),OpenAiUserInfo.class,null);
  217 + //添加客户的余额,和总额
  218 + publicService.updateBySql("UPDATE `lk_openai`.`user_info` SET flow_packet_remain=flow_packet_remain+"+number+",flow_packet_total=flow_packet_total+"+number+" WHERE id="+openAiUserInfo.getId());
  219 +
  220 + userFlowPacketRemainLog = new UserFlowPacketRemainLog();
  221 + userFlowPacketRemainLog.setCreate_time(DateUtils.getNowTimeMilly());
  222 + userFlowPacketRemainLog.setUser_id(openAiUserInfo.getId());
  223 + userFlowPacketRemainLog.setType(3); //消费
  224 + stringBuffer = new StringBuffer();
  225 + stringBuffer.append("代理商");
  226 + stringBuffer.append(myOpenAiUserInfo.getNickname());
  227 + stringBuffer.append("手机号:");
  228 + stringBuffer.append(myOpenAiUserInfo.getPhone());
  229 + stringBuffer.append(" 为您充值代币: ");
  230 + stringBuffer.append(number);
  231 + stringBuffer.append(" ;");
  232 +
  233 + userFlowPacketRemainLog.setDescribe(stringBuffer.toString());
  234 + userFlowPacketRemainLog.setTotal_tokens(number);
  235 +
  236 + userFlowPacketRemainLog.setOpenai_money((openaiUnitprice.multiply(new BigDecimal(userFlowPacketRemainLog.getTotal_tokens()))).divide(new BigDecimal(1000),6,BigDecimal.ROUND_HALF_UP));
  237 + userFlowPacketRemainLog.setReality_money((realityUnitprice.multiply(new BigDecimal(userFlowPacketRemainLog.getTotal_tokens()))).divide(new BigDecimal(1000),6,BigDecimal.ROUND_HALF_UP));
  238 + publicService.insertToTable(userFlowPacketRemainLog,"`lk_openai`.`user_flow_packet_remain_log`");
  239 + return AjaxResult.success("充值成功!");
  240 + }
  241 +
  242 +
  243 + @ApiOperation("升级为代理商")
  244 + @ApiImplicitParams({
  245 + @ApiImplicitParam(value = "推荐码",name = "promo_code"),
  246 + })
  247 + @Transactional
  248 + @PostMapping("/agencyCharge/{promo_code}")
  249 + public AjaxResult agencyCharge(@PathVariable String promo_code)
  250 + {
  251 + OpenAiUserInfo myOpenAiUserInfo = publicService.getObjectForTableName(OpenAiUserInfo.class,"id",getUserId().toString(),"`lk_openai`.`user_info`");
  252 + if(myOpenAiUserInfo.getRole()-1==0)
  253 + {
  254 + return AjaxResult.error("您已经是代理商,无法重复申请");
  255 + }
  256 +
  257 + OpenAiUserInfo pOpenAiUserInfo = publicService.getObjectForTableName(OpenAiUserInfo.class,"promo_code",promo_code,"`lk_openai`.`user_info`");
  258 + if(null == pOpenAiUserInfo || pOpenAiUserInfo.getRole()-1!=0 || pOpenAiUserInfo.getState()==0 ||pOpenAiUserInfo.getState()==2)
  259 + {
  260 + return AjaxResult.error("该代理商不存在或者已被禁止");
  261 + }
  262 +
  263 + OpenAiUserInfo upadduser = new OpenAiUserInfo();
  264 + upadduser.setId(myOpenAiUserInfo.getId());
  265 + upadduser.setPromo_code(Integer.toHexString((myOpenAiUserInfo.getId()+":"+DateUtils.getNowTimeMilly()).hashCode()).toUpperCase());
  266 + upadduser.setRole(1);
  267 + upadduser.setPid(pOpenAiUserInfo.getId());
  268 + return AjaxResult.success(publicService.updateObjectByTable(upadduser,"id","`lk_openai`.`user_info`"));
  269 +
  270 + }
140 } 271 }
@@ -10,7 +10,7 @@ public class UserFlowPacketRemainLog { @@ -10,7 +10,7 @@ public class UserFlowPacketRemainLog {
10 private BigDecimal openai_money; //bigint(20) DEFAULT NULL COMMENT 'openai费用(美元)', 10 private BigDecimal openai_money; //bigint(20) DEFAULT NULL COMMENT 'openai费用(美元)',
11 private BigDecimal reality_money; //bigint(20) DEFAULT NULL COMMENT '实际费用(人民币)' 11 private BigDecimal reality_money; //bigint(20) DEFAULT NULL COMMENT '实际费用(人民币)'
12 private String describe; //描述 12 private String describe; //描述
13 - private Integer type; //int(11) DEFAULT NULL COMMENT '类型(1充值,2消费)', 13 + private Integer type; //int(11) DEFAULT NULL COMMENT '类型(1充值,2消费,3代充)',
14 14
15 public Integer getType() { 15 public Integer getType() {
16 return type; 16 return type;
@@ -34,6 +34,7 @@ public class ChatgptDetailsServiceImpl implements UserDetailsService { @@ -34,6 +34,7 @@ public class ChatgptDetailsServiceImpl implements UserDetailsService {
34 adduser.setFlow_packet_total(10000); 34 adduser.setFlow_packet_total(10000);
35 adduser.setState(1); 35 adduser.setState(1);
36 publicService.insertToTable(adduser,"`lk_openai`.`user_info`"); 36 publicService.insertToTable(adduser,"`lk_openai`.`user_info`");
  37 +
37 log.info("新增用户{},成功",username); 38 log.info("新增用户{},成功",username);
38 openAiUserInfo = adduser; 39 openAiUserInfo = adduser;
39 } 40 }
1 -# 项目相关配置 jhlt: # 名称 name: zhonglai # 版本 version: 3.8.2 # 版权年份 copyrightYear: 2022 # 获取ip地址开关 addressEnabled: false # 开发环境配置 server: # 服务器的HTTP端口,默认为8080 port: 8082 servlet: # 应用的访问路径 context-path: / tomcat: # tomcat的URI编码 uri-encoding: UTF-8 # 连接数满后的排队数,默认为100 accept-count: 1000 threads: # tomcat最大线程数,默认为200 max: 800 # Tomcat启动初始化的线程数,默认值10 min-spare: 100 # 日志配置 logging: level: com.ruoyi: debug org.springframework: warn # Spring配置 spring: # 资源信息 messages: # 国际化资源文件路径 basename: i18n/messages profiles: active: druid # 文件上传 servlet: multipart: # 单个文件大小 max-file-size: 10MB # 设置总上传的文件大小 max-request-size: 20MB # 服务模块 devtools: restart: # 热部署开关 enabled: true # redis 配置 redis: # 地址 host: 47.112.163.61 # 端口,默认为6379 port: 9527 # 数据库索引 database: 1 # 密码 password: Luhui586 # 连接超时时间 timeout: 10s lettuce: pool: # 连接池中的最小空闲连接 min-idle: 0 # 连接池中的最大空闲连接 max-idle: 8 # 连接池的最大数据库连接数 max-active: 8 # #连接池最大阻塞等待时间(使用负值表示没有限制) max-wait: -1ms # token配置 token: # 令牌自定义标识 header: Authorization # 令牌密钥 secret: abcdefghijklmnopqrstuvwxyz # 令牌有效期(默认30分钟) expireTime: 1440 rediskey: lh-openai # MyBatis配置 mybatis: # 搜索指定包别名 typeAliasesPackage: com.ruoyi.**.domain # 配置mapper的扫描,找到所有的mapper.xml映射文件 mapperLocations: classpath*:mapper/**/*Mapper.xml # 加载全局的配置文件 configLocation: classpath:mybatis/mybatis-config.xml # PageHelper分页插件 pagehelper: helperDialect: mysql supportMethodsArguments: true params: count=countSql # Swagger配置 swagger: # 是否开启swagger enabled: true # 请求前缀 pathMapping: /dev-api # 防止XSS攻击 xss: # 过滤开关 enabled: true # 排除链接(多个用逗号分隔) excludes: /system/notice # 匹配链接 urlPatterns: /system/*,/monitor/*,/tool/* mqtt: client: device_life: 180 # NameServer地址 rocketmq: name-server: 47.115.144.179:9876 # 默认的消息组 producer: group: deviceCommand send-message-timeout: 30000 send-topic: lh-chat-gpt send-tags: 1 sys: ## // 对于登录login 注册register 验证码captchaImage 允许匿名访问 antMatchers: /login,/register,/captchaImage,/getCacheObject,/v2/api-docs,/openAiUserLogin/*,/chatGPTStream/upUserFlowPacketRemain chatgpt: token: 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 timeout: 5000  
  1 +# 项目相关配置 jhlt: # 名称 name: zhonglai # 版本 version: 3.8.2 # 版权年份 copyrightYear: 2022 # 获取ip地址开关 addressEnabled: false profile: D:/ruoyi/uploadPath # 开发环境配置 server: # 服务器的HTTP端口,默认为8080 port: 8082 servlet: # 应用的访问路径 context-path: / tomcat: # tomcat的URI编码 uri-encoding: UTF-8 # 连接数满后的排队数,默认为100 accept-count: 1000 threads: # tomcat最大线程数,默认为200 max: 800 # Tomcat启动初始化的线程数,默认值10 min-spare: 100 # 日志配置 logging: level: com.ruoyi: debug org.springframework: warn # Spring配置 spring: # 资源信息 messages: # 国际化资源文件路径 basename: i18n/messages profiles: active: druid # 文件上传 servlet: multipart: # 单个文件大小 max-file-size: 10MB # 设置总上传的文件大小 max-request-size: 20MB # 服务模块 devtools: restart: # 热部署开关 enabled: true # redis 配置 redis: # 地址 host: 47.112.163.61 # 端口,默认为6379 port: 9527 # 数据库索引 database: 1 # 密码 password: Luhui586 # 连接超时时间 timeout: 10s lettuce: pool: # 连接池中的最小空闲连接 min-idle: 0 # 连接池中的最大空闲连接 max-idle: 8 # 连接池的最大数据库连接数 max-active: 8 # #连接池最大阻塞等待时间(使用负值表示没有限制) max-wait: -1ms # token配置 token: # 令牌自定义标识 header: Authorization # 令牌密钥 secret: abcdefghijklmnopqrstuvwxyz # 令牌有效期(默认30分钟) expireTime: 1440 rediskey: lh-openai # MyBatis配置 mybatis: # 搜索指定包别名 typeAliasesPackage: com.ruoyi.**.domain # 配置mapper的扫描,找到所有的mapper.xml映射文件 mapperLocations: classpath*:mapper/**/*Mapper.xml # 加载全局的配置文件 configLocation: classpath:mybatis/mybatis-config.xml # PageHelper分页插件 pagehelper: helperDialect: mysql supportMethodsArguments: true params: count=countSql # Swagger配置 swagger: # 是否开启swagger enabled: true # 请求前缀 pathMapping: /dev-api # 防止XSS攻击 xss: # 过滤开关 enabled: true # 排除链接(多个用逗号分隔) excludes: /system/notice # 匹配链接 urlPatterns: /system/*,/monitor/*,/tool/* mqtt: client: device_life: 180 # NameServer地址 rocketmq: name-server: 47.115.144.179:9876 # 默认的消息组 producer: group: deviceCommand send-message-timeout: 30000 send-topic: lh-chat-gpt send-tags: 1 sys: ## // 对于登录login 注册register 验证码captchaImage 允许匿名访问 antMatchers: /login,/register,/captchaImage,/getCacheObject,/v2/api-docs,/openAiUserLogin/*,/chatGPTStream/upUserFlowPacketRemain chatgpt: token: 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 timeout: 5000
@@ -6,8 +6,11 @@ import org.springframework.data.redis.core.BoundSetOperations; @@ -6,8 +6,11 @@ import org.springframework.data.redis.core.BoundSetOperations;
6 import org.springframework.data.redis.core.HashOperations; 6 import org.springframework.data.redis.core.HashOperations;
7 import org.springframework.data.redis.core.RedisTemplate; 7 import org.springframework.data.redis.core.RedisTemplate;
8 import org.springframework.data.redis.core.ValueOperations; 8 import org.springframework.data.redis.core.ValueOperations;
  9 +import org.springframework.data.redis.core.script.DefaultRedisScript;
  10 +import org.springframework.data.redis.core.script.RedisScript;
9 import org.springframework.stereotype.Component; 11 import org.springframework.stereotype.Component;
10 12
  13 +import java.time.Duration;
11 import java.util.*; 14 import java.util.*;
12 import java.util.concurrent.TimeUnit; 15 import java.util.concurrent.TimeUnit;
13 16
@@ -256,4 +259,27 @@ public class RedisCache @@ -256,4 +259,27 @@ public class RedisCache
256 Map<String, String> map = JSONObject.parseObject(s,HashMap.class); 259 Map<String, String> map = JSONObject.parseObject(s,HashMap.class);
257 setCacheMap(key, map); 260 setCacheMap(key, map);
258 } 261 }
  262 +
  263 + //分布式锁过期时间 s 可以根据业务自己调节
  264 + private static final Long LOCK_REDIS_TIMEOUT = 10L;
  265 + //分布式锁休眠 至 再次尝试获取 的等待时间 ms 可以根据业务自己调节
  266 + public static final Long LOCK_REDIS_WAIT = 500L;
  267 +
  268 + /**
  269 + * 加锁
  270 + **/
  271 + public Boolean getLock(String key,String value){
  272 + Boolean lockStatus = this.redisTemplate.opsForValue().setIfAbsent(key,value, Duration.ofSeconds(LOCK_REDIS_TIMEOUT));
  273 + return lockStatus;
  274 + }
  275 +
  276 + /**
  277 + * 释放锁
  278 + **/
  279 + public Long releaseLock(String key,String value){
  280 + String luaScript = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
  281 + RedisScript<Long> redisScript = new DefaultRedisScript<>(luaScript,Long.class);
  282 + Long releaseStatus = (Long)this.redisTemplate.execute(redisScript, Collections.singletonList(key),value);
  283 + return releaseStatus;
  284 + }
259 } 285 }
@@ -4,6 +4,7 @@ package com.ruoyi.system.login.dto; @@ -4,6 +4,7 @@ package com.ruoyi.system.login.dto;
4 import com.ruoyi.system.domain.tool.PublicSQLConfig; 4 import com.ruoyi.system.domain.tool.PublicSQLConfig;
5 5
6 import java.io.Serializable; 6 import java.io.Serializable;
  7 +import java.math.BigDecimal;
7 8
8 /** 9 /**
9 * 用户信息 10 * 用户信息
@@ -21,6 +22,51 @@ public class OpenAiUserInfo implements Serializable { @@ -21,6 +22,51 @@ public class OpenAiUserInfo implements Serializable {
21 private Integer flow_packet_remain; //流量包余额 22 private Integer flow_packet_remain; //流量包余额
22 private Integer flow_packet_total; //流量包总额 23 private Integer flow_packet_total; //流量包总额
23 private Integer state; //状态(0禁用,1正常,2过期,3锁定) 24 private Integer state; //状态(0禁用,1正常,2过期,3锁定)
  25 + private Integer role; //角色(0普通用户,1代理商)
  26 + private Integer pid; //上级id
  27 + private BigDecimal unitprice; //流量单价
  28 + private BigDecimal default_below_unitprice; //默认下级流量单价
  29 + private String promo_code; //推广码
  30 +
  31 + public String getPromo_code() {
  32 + return promo_code;
  33 + }
  34 +
  35 + public void setPromo_code(String promo_code) {
  36 + this.promo_code = promo_code;
  37 + }
  38 +
  39 + public Integer getRole() {
  40 + return role;
  41 + }
  42 +
  43 + public void setRole(Integer role) {
  44 + this.role = role;
  45 + }
  46 +
  47 + public Integer getPid() {
  48 + return pid;
  49 + }
  50 +
  51 + public void setPid(Integer pid) {
  52 + this.pid = pid;
  53 + }
  54 +
  55 + public BigDecimal getUnitprice() {
  56 + return unitprice;
  57 + }
  58 +
  59 + public void setUnitprice(BigDecimal unitprice) {
  60 + this.unitprice = unitprice;
  61 + }
  62 +
  63 + public BigDecimal getDefault_below_unitprice() {
  64 + return default_below_unitprice;
  65 + }
  66 +
  67 + public void setDefault_below_unitprice(BigDecimal default_below_unitprice) {
  68 + this.default_below_unitprice = default_below_unitprice;
  69 + }
24 70
25 public Integer getState() { 71 public Integer getState() {
26 return state; 72 return state;