feat: add core entities, controllers, services, and mappers across multi-module project
This commit is contained in:
commit
4335344af7
1456 files changed
+58308
No files matched your search
Whitespace-only changes.
Whitespace-only changes.
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4" />
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>AI_Questioning</artifactId>
|
||||
<groupId>cn.unizk</groupId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>applet</artifactId>
|
||||
|
||||
<name>applet</name>
|
||||
<!-- FIXME change it to the project's website -->
|
||||
<url>http://www.example.com</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.release>8</maven.compiler.release>
|
||||
</properties>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
<version>2.6.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-api -->
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-api</artifactId>
|
||||
<version>0.11.5</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-impl -->
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-impl</artifactId>
|
||||
<version>0.11.5</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-jackson -->
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-jackson</artifactId>
|
||||
<version>0.11.5</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.wechatpay-apiv3</groupId>
|
||||
<artifactId>wechatpay-java</artifactId>
|
||||
<version>0.2.17</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk18on -->
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk18on</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.huifu.bspay.sdk</groupId>
|
||||
<artifactId>dg-java-sdk</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.java-websocket/Java-WebSocket -->
|
||||
<dependency>
|
||||
<groupId>org.java-websocket</groupId>
|
||||
<artifactId>Java-WebSocket</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.squareup.okio/okio -->
|
||||
<dependency>
|
||||
<groupId>com.squareup.okio</groupId>
|
||||
<artifactId>okio</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.volcengine</groupId>
|
||||
<artifactId>volcengine-java-sdk-ark-runtime</artifactId>
|
||||
<version>LATEST</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.unizk</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
|
||||
<plugins>
|
||||
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>2.1.1.RELEASE</version>
|
||||
<configuration>
|
||||
<fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>8</source>
|
||||
<target>8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,16 @@
|
||||
package cn.unizk;
|
||||
|
||||
import cn.unizk.config.WxProperties;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
@SpringBootApplication
|
||||
@MapperScan(basePackages = {"cn.unizk.mapper"})
|
||||
@EnableScheduling
|
||||
public class AIQuestioningApp {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AIQuestioningApp.class,args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
package cn.unizk.config;
|
||||
|
||||
import cn.unizk.filter.JkCorsFilter;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.cors.reactive.CorsWebFilter;
|
||||
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
*/
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/9/13 17:09
|
||||
* @Version 1.0
|
||||
**//*
|
||||
|
||||
@Configuration
|
||||
public class FilterConfig {
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean<JkCorsFilter> jkCorsFilter(){
|
||||
FilterRegistrationBean<JkCorsFilter> filterRegistrationBean = new FilterRegistrationBean<>();
|
||||
filterRegistrationBean.setFilter(new JkCorsFilter());
|
||||
filterRegistrationBean.addUrlPatterns("/h5/*");
|
||||
filterRegistrationBean.setOrder(1);
|
||||
return filterRegistrationBean;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CorsWebFilter corsFilter() {
|
||||
CorsConfiguration config = new CorsConfiguration();
|
||||
config.addAllowedOrigin("http://369.peaktcm.com:9000");
|
||||
config.addExposedHeader("Authorization");
|
||||
config.addAllowedHeader("*");
|
||||
config.addAllowedMethod("*");
|
||||
config.setAllowCredentials(true);
|
||||
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
source.registerCorsConfiguration("/**", config);
|
||||
|
||||
return new CorsWebFilter(source);
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,22 @@
|
||||
package cn.unizk.config;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/8/27 10:18
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "jk")
|
||||
public class JkProperties {
|
||||
|
||||
private String secretKey;
|
||||
private Integer tokenExpireTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package cn.unizk.config;
|
||||
|
||||
import cn.unizk.interceptor.AppletLoginInterceptor;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/8/21 14:52
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Configuration
|
||||
public class ResourceConfig implements WebMvcConfigurer {
|
||||
|
||||
@Resource
|
||||
private AppletLoginInterceptor appletLoginInterceptor;
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(appletLoginInterceptor).addPathPatterns("/**")
|
||||
.excludePathPatterns(
|
||||
"/ai/saveConversation",
|
||||
"/applet/login",
|
||||
"/applet/jkLogin",
|
||||
"/applet/sendPhoneCode",
|
||||
"/applet/bindPhoneNumber",
|
||||
"/applet/wxPay/paySuccessCallBack",
|
||||
"/applet/test/**",
|
||||
"/h5/**",
|
||||
"/applet/dict/getDictByType",
|
||||
"/applet/product/carousel",
|
||||
"/applet/product/list",
|
||||
"/applet/product/getExquisite",
|
||||
"/applet/getStores",
|
||||
"/applet/getStoreById",
|
||||
"/applet/huifuPay/callback",
|
||||
"/applet/huifuPay/configureAppletCallback",
|
||||
"/applet/getAppletQrCode",
|
||||
"/hf/webhook/**",
|
||||
"/ai/getQustion/**",
|
||||
"applet/getReportById/**",
|
||||
"/applet/user/rememberDia",
|
||||
"/applet/product/byId",
|
||||
"/applet/combo/getCombos",
|
||||
"/ai/**",
|
||||
"/applet/doubao/**",
|
||||
"/applet/golf/**",
|
||||
"/applet/wechat/pay",
|
||||
"/applet/module/**",
|
||||
"/applet/loginByPhone",
|
||||
"/applet/sendPhoneCode",
|
||||
"/applet/oneClickLogin");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package cn.unizk.config;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/7/9 17:14
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "wx")
|
||||
@Getter
|
||||
@Setter
|
||||
public class WxProperties {
|
||||
private String appid;
|
||||
private String secret;
|
||||
private final PlaceOrder placeOrder = new PlaceOrder();
|
||||
private final Pay pay = new Pay();
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class PlaceOrder {
|
||||
private String notifyUrl;
|
||||
private String placeOrderUrl;
|
||||
private Long expireTime; //单位分钟
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class Pay {
|
||||
private String domain;
|
||||
private String mchid;
|
||||
private String serialNo;
|
||||
private String closeOrderApi;
|
||||
private String platformCertSerial;
|
||||
private String apiV3Key;
|
||||
private String orderSearchUri;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package cn.unizk.constant;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/7/9 13:45
|
||||
* @Version 1.0
|
||||
**/
|
||||
public class WxConstant {
|
||||
|
||||
public static final String GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/stable_token";
|
||||
public static final String APPLET_LOGIN_URL = "https://api.weixin.qq.com/sns/jscode2session";
|
||||
public static final String APPLET_LOGIN_SIGN = "applet-auth";
|
||||
public static final String CACHE_TOKEN_KEY = "jk-applet-";
|
||||
public static final String authorization_type = "WECHATPAY2-SHA256-RSA2048 ";
|
||||
public static final String WX_ACCESS_TOKEN = "access_token";
|
||||
}
|
||||
@@ -0,0 +1,517 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.cache.LocalCache;
|
||||
import cn.unizk.entity.po.*;
|
||||
import cn.unizk.entity.vo.*;
|
||||
import cn.unizk.enums.ContentTypeEnum;
|
||||
import cn.unizk.exception.ServiceException;
|
||||
import cn.unizk.mapper.DiagnosisTemplateMapper;
|
||||
import cn.unizk.mapper.StoreAccountMapper;
|
||||
import cn.unizk.mapper.TreatParameterMapper;
|
||||
import cn.unizk.service.*;
|
||||
import cn.unizk.utils.IatModelZh;
|
||||
import cn.unizk.utils.WebIATWS;
|
||||
import cn.unizk.utils.XfSpeechToTextUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.WebSocket;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.InputStreamResource;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.file.Files;
|
||||
import java.security.SignatureException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/7/7 15:55
|
||||
* @Version 1.0
|
||||
**/
|
||||
|
||||
@RestController
|
||||
@Slf4j
|
||||
@RequestMapping({"/ai"})
|
||||
public class AIAdviceController {
|
||||
|
||||
@Value("${xf.appid}")
|
||||
private String appid;
|
||||
@Value("${xf.long-sound.keySecret}")
|
||||
private String longSoundKeySecret;
|
||||
@Value("${xf.instant.host}")
|
||||
private String hostUrl;
|
||||
@Value("${xf.instant.APISecret}")
|
||||
private String apiSecret;
|
||||
@Value("${xf.instant.apiKey}")
|
||||
private String apiKey;
|
||||
@Resource
|
||||
private WxUserSessionService userSessionService;
|
||||
@Resource
|
||||
private QuestionService questionService;
|
||||
@Resource
|
||||
private StoreAccountMapper accountMapper;
|
||||
|
||||
@Resource
|
||||
private AIAdviceService aiAdviceService;
|
||||
@Value("${spring.profiles.active}")
|
||||
private String active;
|
||||
@Resource
|
||||
private DiagnosisTemplateMapper diagnosisTemplateMapper;
|
||||
@Resource
|
||||
private TreatParameterMapper treatParameterMapper;
|
||||
@Resource
|
||||
private SysDictService sysDictService;
|
||||
|
||||
|
||||
|
||||
@PostMapping("/askForAdvice")
|
||||
public ReplyVo reply(@RequestBody ReplyVo vo){
|
||||
/**
|
||||
* 如果下一条消息要展示图片,那么vo.setNextContentType(ContentTypeEnum.IMAGE.name());
|
||||
* 如果下一条消息要弹出性别选择,那么vo.setNextContentType(ContentTypeEnum.SEX.name());
|
||||
* 如果下一条消息要弹出年龄选择,那么vo.setNextContentType(ContentTypeEnum.AGE.name());
|
||||
* 如果下一条消息要弹出体重选择,那么vo.setNextContentType(ContentTypeEnum.WEIGHT.name());
|
||||
*/
|
||||
vo.setType("AI");
|
||||
return aiAdviceService.reply(vo);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/saveConversation")
|
||||
public ReplyVo saveConversation(@RequestBody List<Map<String, List<String>>> conversation,@RequestParam("openid") String openid){
|
||||
// List<Map<String,String>> maps = new ArrayList<>();
|
||||
// for (Map<String, List<String>> stringListMap : conversation) {
|
||||
// for (Map.Entry<String, List<String>> stringListEntry : stringListMap.entrySet()) {
|
||||
// List<String> value = stringListEntry.getValue();
|
||||
// Map<String,String> map = new HashMap<>();
|
||||
// map.put(stringListEntry.getKey(),value.get(0));
|
||||
// maps.add(map);
|
||||
// }
|
||||
// }
|
||||
|
||||
return aiAdviceService.saveConversation(conversation,openid);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* 获取诊疗报告 诊疗师,暂放
|
||||
* */
|
||||
|
||||
@PostMapping("/getTreatmentPlan")
|
||||
public JSONObject getTreatmentPlan(@RequestBody String sessionId){
|
||||
|
||||
return aiAdviceService.getTreatmentPlan(sessionId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@GetMapping("/getQustion/{sort}")
|
||||
public QuestionVo getQuestion(@PathVariable("sort") int sort){
|
||||
Question question = questionService.getOne(new LambdaQueryWrapper<Question>().eq(Question::getSort, sort));
|
||||
JSONObject options = JSONObject.parseObject(question.getOptions());
|
||||
List<Map<String,String>> optionValues = new ArrayList<>();
|
||||
options.forEach((k,v) -> {
|
||||
Map<String,String> item = new HashMap<>();
|
||||
item.put("value", (String) v);
|
||||
item.put("text", (String) v);
|
||||
optionValues.add(item);
|
||||
});
|
||||
QuestionVo questionVo = new QuestionVo();
|
||||
BeanUtils.copyProperties(question,questionVo);
|
||||
questionVo.setOptionValues(optionValues);
|
||||
return questionVo;
|
||||
}
|
||||
|
||||
@PostMapping("/speechToText")
|
||||
public String speechToText(@RequestParam("file") MultipartFile file) {
|
||||
log.info("originalFilename:{}",file.getOriginalFilename());
|
||||
log.info("name={},size={}",file.getName(),file.getSize());
|
||||
try {
|
||||
String s = XfSpeechToTextUtil.xfSpeechToText(file, appid, longSoundKeySecret);
|
||||
JSONObject res = JSONObject.parseObject(s);
|
||||
String orderId = res.getJSONObject("content").getString("orderId");
|
||||
String result = XfSpeechToTextUtil.getResult(orderId, appid, longSoundKeySecret);
|
||||
String parseStr = newJavaLfasr(result).toString();
|
||||
log.info("解析后的内容:{}",parseStr);
|
||||
return parseStr;
|
||||
} catch (SignatureException | InterruptedException | IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new ServiceException("语音识别失败");
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/instantToText/{openid}")
|
||||
public String instantToText(@RequestParam("file") MultipartFile file,@PathVariable("openid") String openid){
|
||||
try {
|
||||
String authUrl = WebIATWS.getAuthUrl(hostUrl, apiKey, apiSecret);
|
||||
OkHttpClient client = new OkHttpClient.Builder().build();
|
||||
//将url中的 schema http://和https://分别替换为ws:// 和 wss://
|
||||
String url = authUrl.toString().replace("http://", "ws://").replace("https://", "wss://");
|
||||
//System.out.println(url);
|
||||
Request request = new Request.Builder().url(url).build();
|
||||
// System.out.println(client.newCall(request).execute());
|
||||
//System.out.println("url===>" + url);
|
||||
WebSocket webSocket = client.newWebSocket(request, new WebIATWS(file,openid));
|
||||
long end = System.currentTimeMillis() + 5 * 1000;
|
||||
while (true){
|
||||
String msg = LocalCache.MESSAGE_QUEUE.get(openid);
|
||||
if (StringUtils.isNotBlank(msg)){
|
||||
LocalCache.MESSAGE_QUEUE.remove(openid);
|
||||
return msg;
|
||||
}else {
|
||||
if (System.currentTimeMillis() > end){
|
||||
throw new ServiceException("翻译结果等待超时");
|
||||
}
|
||||
log.info("等待翻译结果返回");
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
}
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
throw new ServiceException("语音识别失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 中文识别大模型API
|
||||
* @param file
|
||||
* @param openid
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/iatModelToText")
|
||||
public String iatModelToText(@RequestParam("file") MultipartFile file,@RequestParam("openid") String openid){
|
||||
/*try {
|
||||
String authUrl = IatModelZh.getAuthUrl();
|
||||
OkHttpClient client = new OkHttpClient.Builder().build();
|
||||
String url = authUrl.toString().replace("http://", "ws://").replace("https://", "wss://");
|
||||
Request request = new Request.Builder().url(url).build();
|
||||
InputStream inputStream = file.getInputStream();
|
||||
IatModelZh iatModelZh = new IatModelZh(file, openid);
|
||||
WebSocket webSocket = client.newWebSocket(request, iatModelZh);
|
||||
if (!iatModelZh.getLatch().await(10, TimeUnit.SECONDS)) {
|
||||
throw new ServiceException("大模型听写 超时");
|
||||
}
|
||||
String s = LocalCache.IAT_MODEL_MSG_QUEUE.get(openid);
|
||||
LocalCache.IAT_MODEL_MSG_QUEUE.remove(openid);
|
||||
return s;
|
||||
}catch (Exception e){
|
||||
log.error("大模型语音识别失败",e);
|
||||
throw new ServiceException("大模型语音识别失败");
|
||||
}*/
|
||||
return instantToText(file,openid);
|
||||
}
|
||||
|
||||
private static StringBuilder newJavaLfasr(String a){
|
||||
StringBuilder result= new StringBuilder();
|
||||
JSONObject jsonObject = JSON.parseObject(a);
|
||||
String str = jsonObject.getJSONObject("content").getString("orderResult");
|
||||
JSONArray json = JSONObject.parseObject(str).getJSONArray("lattice2");
|
||||
int length = json.size();
|
||||
for(int i = 0;i<length;i++) {
|
||||
int length2 = json.getJSONObject(i).getJSONObject("json_1best").getJSONObject("st").getJSONArray("rt").size();
|
||||
for(int j=0;j<length2;j++){
|
||||
int length3 =json.getJSONObject(i).getJSONObject("json_1best").getJSONObject("st").getJSONArray("rt").getJSONObject(j).getJSONArray("ws").size();
|
||||
for(int k=0;k<length3;k++){
|
||||
String resultTemp = json.getJSONObject(i).getJSONObject("json_1best").getJSONObject("st").getJSONArray("rt").getJSONObject(j).getJSONArray("ws").getJSONObject(k).getJSONArray("cw").getJSONObject(0).getString("w");
|
||||
result.append(resultTemp);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@PostMapping("/saveSession/{openid}")
|
||||
public ResultData saveSession(@RequestBody List<WxUserSession> sessions, @PathVariable("openid") String openid){
|
||||
Long maxSessionId = userSessionService.findMaxSessionId(openid);
|
||||
sessions.forEach(userSession -> {
|
||||
userSession.setOpenid(openid);
|
||||
// userSession.setSessionId(maxSessionId == null ? 1 : maxSessionId+1);
|
||||
userSession.setSessionTime(LocalDateTime.now());
|
||||
});
|
||||
userSessionService.saveBatch(sessions);
|
||||
return ResultData.success();
|
||||
}
|
||||
|
||||
@PostMapping("/manualAnswer")
|
||||
public ResultData<String> manualAnswer(@RequestBody ManualAnswerVO vo){
|
||||
ResultData<String> data = new ResultData<>();
|
||||
data.setCode(200);
|
||||
if (Objects.isNull(vo) || StringUtils.isBlank(vo.getMessage())){
|
||||
return ResultData.success();
|
||||
}
|
||||
String message = vo.getMessage();
|
||||
if ("1".equals(vo.getNumber())){
|
||||
if (message.contains("膝")){
|
||||
data.setData("true");
|
||||
return data;
|
||||
}
|
||||
data.setData("false");
|
||||
return data;
|
||||
}else if ("4".equals(vo.getNumber()) || "2".equals(vo.getNumber())){
|
||||
if (message.contains("不对")){
|
||||
data.setData("false");
|
||||
return data;
|
||||
}
|
||||
if (message.contains("不是")){
|
||||
data.setData("false");
|
||||
return data;
|
||||
}
|
||||
if (message.contains("对")){
|
||||
data.setData("true");
|
||||
return data;
|
||||
}
|
||||
if (message.contains("是")){
|
||||
data.setData("true");
|
||||
return data;
|
||||
}
|
||||
data.setData("false");
|
||||
return data;
|
||||
}else if ("3".equals(vo.getNumber())){
|
||||
message = parseStrTen(message);
|
||||
message = message.replace("和",",").replace("还有",",").replace("跟",",").replace("号",",").replace("区",",");
|
||||
List<String> list = new ArrayList<>();
|
||||
if (containsStandaloneOne(message)){
|
||||
list.add("1");
|
||||
}
|
||||
if (containsStandaloneTwo(message)){
|
||||
list.add("2");
|
||||
}
|
||||
if (containsStandaloneThree(message)){
|
||||
list.add("3");
|
||||
}
|
||||
if (message.contains("4")){
|
||||
list.add("4");
|
||||
}
|
||||
if (message.contains("5")){
|
||||
list.add("5");
|
||||
}
|
||||
if (message.contains("6")){
|
||||
list.add("6");
|
||||
}
|
||||
if ( message.contains("7")){
|
||||
list.add("7");
|
||||
}
|
||||
if (message.contains("8")){
|
||||
list.add("8");
|
||||
}
|
||||
if (message.contains("9")){
|
||||
list.add("9");
|
||||
}
|
||||
if (message.contains("10")){
|
||||
list.add("10");
|
||||
}
|
||||
if (message.contains("11")){
|
||||
list.add("11");
|
||||
}
|
||||
if (message.contains("12")){
|
||||
list.add("12");
|
||||
}
|
||||
if (message.contains("13")){
|
||||
list.add("13");
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(list)){
|
||||
String collect = String.join(",", list);
|
||||
data.setData(collect);
|
||||
return data;
|
||||
}else {
|
||||
data.setData("false");
|
||||
return data;
|
||||
}
|
||||
}else {
|
||||
List<String> list = new ArrayList<>();
|
||||
if (message.contains("一") || message.contains("1")){
|
||||
list.add("1");
|
||||
}
|
||||
if (message.contains("二") || message.contains("2")){
|
||||
list.add("2");
|
||||
}
|
||||
if (message.contains("三") || message.contains("3")){
|
||||
list.add("3");
|
||||
}
|
||||
if (message.contains("四") || message.contains("4")){
|
||||
list.add("4");
|
||||
}
|
||||
if (message.contains("五") || message.contains("5")){
|
||||
list.add("5");
|
||||
}
|
||||
if (message.contains("六") || message.contains("6")){
|
||||
list.add("6");
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(list)){
|
||||
String join = String.join(",", list);
|
||||
data.setData(join);
|
||||
return data;
|
||||
}else {
|
||||
data.setData("false");
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/answer")
|
||||
public ResultData<String> answer(@RequestBody QuestionAnswerVO vo){
|
||||
ResultData<String> data = new ResultData<>();
|
||||
data.setCode(200);
|
||||
return data;
|
||||
}
|
||||
|
||||
private boolean containsStandaloneOne(String str) {
|
||||
if (str == null) {
|
||||
return false;
|
||||
}
|
||||
return Pattern.compile("\\b1\\b").matcher(str).find();
|
||||
}
|
||||
private boolean containsStandaloneTwo(String str) {
|
||||
if (str == null) {
|
||||
return false;
|
||||
}
|
||||
return Pattern.compile("\\b2\\b").matcher(str).find();
|
||||
}
|
||||
private boolean containsStandaloneThree(String str) {
|
||||
if (str == null) {
|
||||
return false;
|
||||
}
|
||||
return Pattern.compile("\\b3\\b").matcher(str).find();
|
||||
}
|
||||
|
||||
private String parseStrTen(String msg){
|
||||
if (msg == null){
|
||||
return msg;
|
||||
}
|
||||
String s = msg;
|
||||
|
||||
if (msg.contains("十一") || msg.contains("十二") || msg.contains("十三")){
|
||||
s = msg.replace("十一", "11").replace("十二", "12").replace("十三", "13");
|
||||
}else {
|
||||
if (msg.contains("十")){
|
||||
s = msg.replace("十","10");
|
||||
}
|
||||
}
|
||||
if (msg.contains("一")){
|
||||
s = s.replace("一","1");
|
||||
}
|
||||
if (msg.contains("二")){
|
||||
s = s.replace("二","2");
|
||||
}
|
||||
if (msg.contains("三")){
|
||||
s = s.replace("三","3");
|
||||
}
|
||||
if (msg.contains("四")){
|
||||
s = s.replace("四","4");
|
||||
}
|
||||
if (msg.contains("五")){
|
||||
s = s.replace("五","5");
|
||||
}
|
||||
if (msg.contains("六")){
|
||||
s = s.replace("六","6");
|
||||
}
|
||||
if (msg.contains("七")){
|
||||
s = s.replace("七","7");
|
||||
}
|
||||
if (msg.contains("八")){
|
||||
s = s.replace("八","8");
|
||||
}
|
||||
if (msg.contains("九")){
|
||||
s = s.replace("九","9");
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
@GetMapping("/toVoice")
|
||||
public ResponseEntity<InputStreamResource> toVoice(@RequestParam("text") String text){
|
||||
SysDict sysDict = sysDictService.getOne(new LambdaQueryWrapper<SysDict>().eq(SysDict::getDictType, "xf_voice"));
|
||||
if (sysDict == null || "0".equals(sysDict.getDictValue())){
|
||||
return ResponseEntity.ok(null);
|
||||
}
|
||||
File tempFile = null;
|
||||
File dir;
|
||||
try {
|
||||
if ("dev".equals(active)){
|
||||
dir = new File("D:\\code\\temp");
|
||||
}else {
|
||||
dir = new File("/opt/jkzyjava/temp");
|
||||
}
|
||||
dir.mkdirs();
|
||||
tempFile = File.createTempFile("temp", ".mp3",dir);
|
||||
String filePath = tempFile.getAbsolutePath();
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
WebTtsWsService.tts(text,filePath,latch);
|
||||
if (!latch.await(10, TimeUnit.SECONDS)) {
|
||||
throw new ServiceException("TTS 超时");
|
||||
}
|
||||
|
||||
byte[] audioData = Files.readAllBytes(tempFile.toPath());
|
||||
InputStreamResource resource = new InputStreamResource(new ByteArrayInputStream(audioData));
|
||||
return ResponseEntity.ok()
|
||||
.contentType(MediaType.parseMediaType("audio/mpeg"))
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"speech.mp3\"")
|
||||
.body(resource);
|
||||
} catch (Exception e) {
|
||||
log.error("文字转语音发生异常",e);
|
||||
throw new ServiceException("服务异常");
|
||||
}finally {
|
||||
if (tempFile != null){
|
||||
File file = tempFile;
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
log.info("删除临时文件");
|
||||
file.delete();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
log.warn("删除临时文件线程被中断");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/addTreat")
|
||||
public boolean addTreat(){
|
||||
List<DiagnosisTemplate> diagnosisTemplates = diagnosisTemplateMapper.selectList(null);
|
||||
for (DiagnosisTemplate diagnosisTemplate : diagnosisTemplates) {
|
||||
TreatParameter treatParameter = new TreatParameter();
|
||||
treatParameter.setSymptomsName(diagnosisTemplate.getLocation());
|
||||
treatParameterMapper.insert(treatParameter);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*@GetMapping("/abcount")
|
||||
public ResultData data(){
|
||||
StoreAccount account = new StoreAccount();
|
||||
account.setStoreId(3);
|
||||
account.setAvailableBalance(BigDecimal.valueOf(1.00));
|
||||
account.setBalance(BigDecimal.valueOf(1.00));
|
||||
accountMapper.insert(account);
|
||||
return ResultData.success();
|
||||
}*/
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.constant.WxConstant;
|
||||
import cn.unizk.entity.po.AppletModule;
|
||||
import cn.unizk.entity.po.MobileAppUser;
|
||||
import cn.unizk.entity.po.ModulePerms;
|
||||
import cn.unizk.mapper.AppletModuleMapper;
|
||||
import cn.unizk.mapper.MobileAppUserMapper;
|
||||
import cn.unizk.utils.JkSecurityUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2026/8/6 10:27
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet/module")
|
||||
public class ApplicationModuleController {
|
||||
|
||||
@Resource
|
||||
private AppletModuleMapper appletModuleMapper;
|
||||
@Resource
|
||||
private MobileAppUserMapper mobileAppUserMapper;
|
||||
|
||||
@GetMapping("/getModule")
|
||||
public List<AppletModule> getModule(HttpServletRequest request){
|
||||
String token = request.getHeader(WxConstant.APPLET_LOGIN_SIGN);
|
||||
if (StringUtils.isBlank(token)){
|
||||
return appletModuleMapper.getModule("mp","C");
|
||||
}
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(token);
|
||||
MobileAppUser user = mobileAppUserMapper.selectById(currentUser);
|
||||
if (Objects.isNull(user)){
|
||||
return appletModuleMapper.getModule("mp","C");
|
||||
}
|
||||
return appletModuleMapper.getModule("mp",user.getUserType());
|
||||
}
|
||||
|
||||
/* @GetMapping("/getModule")
|
||||
public List<AppletModule> getM(){
|
||||
return appletModuleMapper.selectList(null);
|
||||
}*/
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.entity.po.ClinicWorkLog;
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.entity.vo.UniPage;
|
||||
import cn.unizk.mapper.ClinicWorkLogMapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2026/8/20 14:36
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet/clinic")
|
||||
public class ClinicWorkLogController {
|
||||
|
||||
@Resource
|
||||
private ClinicWorkLogMapper clinicWorkLogMapper;
|
||||
|
||||
@PostMapping("/list")
|
||||
public Page<ClinicWorkLog> list(@RequestBody UniPage<ClinicWorkLog> uniPage){
|
||||
Page<ClinicWorkLog> page = (Page<ClinicWorkLog>) uniPage.getPage();
|
||||
LambdaQueryWrapper<ClinicWorkLog> queryWrapper = uniPage.buildQueryWrapper(query -> {
|
||||
LambdaQueryWrapper<ClinicWorkLog> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.like(StringUtils.isNotBlank(query.getName()), ClinicWorkLog::getName, query.getName());
|
||||
wrapper.like(StringUtils.isNotBlank(query.getPhoneNumber()), ClinicWorkLog::getPhoneNumber, query.getPhoneNumber());
|
||||
wrapper.orderByDesc(ClinicWorkLog::getCreateTime);
|
||||
return wrapper;
|
||||
});
|
||||
return clinicWorkLogMapper.selectPage(page,queryWrapper);
|
||||
}
|
||||
|
||||
@PostMapping("/addLog")
|
||||
public ResultData addLog(@RequestBody ClinicWorkLog log){
|
||||
if (log.getCreateTime() == null){
|
||||
log.setCreateTime(LocalDate.now());
|
||||
}
|
||||
clinicWorkLogMapper.insert(log);
|
||||
return ResultData.success();
|
||||
}
|
||||
|
||||
@PostMapping("/editLog")
|
||||
public ResultData editLog(@RequestBody ClinicWorkLog log){
|
||||
clinicWorkLogMapper.updateById(log);
|
||||
return ResultData.success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.constant.UniConstant;
|
||||
import cn.unizk.entity.po.Combo;
|
||||
import cn.unizk.entity.po.Device;
|
||||
import cn.unizk.entity.vo.UniPage;
|
||||
import cn.unizk.exception.ServiceException;
|
||||
import cn.unizk.service.ComboService;
|
||||
import cn.unizk.service.DeviceService;
|
||||
import cn.unizk.utils.JkSecurityUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/8/30 17:23
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet/combo")
|
||||
@Slf4j
|
||||
public class ComboController {
|
||||
|
||||
@Resource
|
||||
private ComboService comboService;
|
||||
@Resource
|
||||
private DeviceService deviceService;
|
||||
|
||||
@GetMapping("/listByDevice")
|
||||
public Page<Combo> list(UniPage uniPage, @RequestParam(value = "deviceId", required = false) String deviceId, HttpServletRequest request) {
|
||||
String channelId = request.getHeader(UniConstant.CHANNEL_HEADER);
|
||||
log.info("从请求体中获取到的channelId={}",channelId);
|
||||
Page<Combo> page = new Page<>();
|
||||
page.setCurrent(uniPage.getCurrentPage());
|
||||
page.setSize(uniPage.getPageSize());
|
||||
if (StringUtils.isNotBlank(channelId)) {
|
||||
return comboService.page(page, new LambdaQueryWrapper<Combo>()
|
||||
.eq(Combo::getChannelId, channelId)
|
||||
.and(w -> {
|
||||
w.eq(StringUtils.isNotBlank(deviceId), Combo::getDeviceId, deviceId)
|
||||
.or()
|
||||
.isNull(Combo::getDeviceId)
|
||||
.or()
|
||||
.isNull(Combo::getChannelId);
|
||||
})
|
||||
.orderByAsc(Combo::getComboPrice));
|
||||
}
|
||||
return comboService.page(page, new LambdaQueryWrapper<Combo>()
|
||||
.isNull(Combo::getChannelId)
|
||||
.and(w -> {
|
||||
w.eq(StringUtils.isNotBlank(deviceId), Combo::getDeviceId, deviceId)
|
||||
.or()
|
||||
.isNull(Combo::getDeviceId);
|
||||
})
|
||||
.orderByAsc(Combo::getComboPrice));
|
||||
}
|
||||
|
||||
@GetMapping("/getCombos")
|
||||
public Page<Combo> getCombos(@RequestParam("storeId") Integer storeId, @RequestParam(value = "comboName", required = false) String comboName, UniPage uniPage, HttpServletRequest request) {
|
||||
/*WxUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (Objects.isNull(currentUser)) {
|
||||
throw new ServiceException(401, "登录已过期");
|
||||
}*/
|
||||
String channelId = request.getHeader("channelId");
|
||||
log.info("从请求体中获取到的channelId={}",channelId);
|
||||
Page<Combo> page = new Page<>(uniPage.getCurrentPage(), uniPage.getPageSize());
|
||||
List<Device> devices = deviceService.list(new LambdaQueryWrapper<Device>().eq(Device::getStoreId, storeId));
|
||||
if (CollectionUtils.isNotEmpty(devices)) {
|
||||
List<String> deviceIds = devices.stream().map(Device::getDeviceId).collect(Collectors.toList());
|
||||
return comboService.page(page, new LambdaQueryWrapper<Combo>()
|
||||
.and(wrapper ->{
|
||||
wrapper.in(Combo::getDeviceId, deviceIds)
|
||||
.or()
|
||||
.isNull(Combo::getDeviceId);
|
||||
})
|
||||
.like(StringUtils.isNotBlank(comboName), Combo::getComboName, comboName)
|
||||
.and(wrapper -> {
|
||||
wrapper.eq(StringUtils.isNotBlank(channelId), Combo::getChannelId, channelId)
|
||||
.or()
|
||||
.isNull(Combo::getChannelId);
|
||||
}));
|
||||
}
|
||||
page.setRecords(new ArrayList<>());
|
||||
return page;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.unizk.entity.dto.ElectronicSignatureDTO;
|
||||
import cn.unizk.entity.po.*;
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.entity.vo.UniPage;
|
||||
import cn.unizk.entity.vo.UserConsultationRecordVO;
|
||||
import cn.unizk.exception.ServiceException;
|
||||
import cn.unizk.mapper.*;
|
||||
import cn.unizk.service.impl.DoubaoServiceImpl;
|
||||
import cn.unizk.utils.JkSecurityUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2026/8/18 11:22
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet/consultation")
|
||||
@Slf4j
|
||||
public class ConsultationController {
|
||||
|
||||
@Resource
|
||||
private UserConsultationRecordMapper consultationRecordMapper;
|
||||
@Resource
|
||||
private DoubaoServiceImpl doubaoService;
|
||||
@Resource
|
||||
private TreatParameterMapper treatParameterMapper;
|
||||
@Resource
|
||||
private MobileAppUserMapper mobileAppUserMapper;
|
||||
@Resource
|
||||
private JkPhysioMapper jkPhysioMapper;
|
||||
@Resource
|
||||
private ClinicWorkLogMapper clinicWorkLogMapper;
|
||||
|
||||
|
||||
@PostMapping("/electronicSignature")
|
||||
public ResultData electronicSignature(@RequestBody ElectronicSignatureDTO dto){
|
||||
UserConsultationRecord consultationRecord = consultationRecordMapper.selectById(dto.getId());
|
||||
if ("electronicPrescriptionUrl".equals(dto.getName())){
|
||||
consultationRecord.setElectronicPrescriptionUrl(dto.getUrl());
|
||||
}
|
||||
if ("coordinatorSignUrl".equals(dto.getName())){
|
||||
consultationRecord.setCoordinatorSignUrl(dto.getUrl());
|
||||
}
|
||||
if ("proofreaderSignUrl".equals(dto.getName())){
|
||||
consultationRecord.setProofreaderSignUrl(dto.getUrl());
|
||||
}
|
||||
consultationRecordMapper.updateById(consultationRecord);
|
||||
return ResultData.success();
|
||||
}
|
||||
|
||||
@PostMapping("/saveRecord")
|
||||
public UserConsultationRecordVO saveRecord(HttpServletRequest request, @RequestBody UserConsultationRecordVO vo){
|
||||
if (vo.getPattern() == null){
|
||||
throw new ServiceException("pattern???");
|
||||
}
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (Objects.isNull(currentUser)){
|
||||
throw new ServiceException(401,"登录已过期");
|
||||
}
|
||||
TreatParameter treatParameter = null;
|
||||
StringBuilder part = new StringBuilder();
|
||||
StringBuilder syName = new StringBuilder();
|
||||
if (!vo.getPainAreaNo().contains(",")){
|
||||
treatParameter = treatParameterMapper.selectById(Integer.parseInt(vo.getPainAreaNo()));
|
||||
part.append(treatParameter.getPart());
|
||||
syName.append(treatParameter.getSymptomsName());
|
||||
}else {
|
||||
String[] split = vo.getPainAreaNo().split(",");
|
||||
for (String s : split) {
|
||||
TreatParameter parameter = treatParameterMapper.selectById(Integer.parseInt(s));
|
||||
part.append(parameter.getPart()).append(";");
|
||||
syName.append(parameter.getSymptomsName()).append(";");
|
||||
}
|
||||
}
|
||||
String s = RandomStringUtils.randomNumeric(10);
|
||||
String yyyyMMdd = DateUtil.format(new Date(), "yyyyMMdd");
|
||||
UserConsultationRecord consultationRecord = new UserConsultationRecord();
|
||||
BeanUtils.copyProperties(vo,consultationRecord);
|
||||
String number = "JK-" + yyyyMMdd + s;
|
||||
consultationRecord.setBatchNumber(number);
|
||||
consultationRecord.setUserId(currentUser.getId());
|
||||
consultationRecord.setPainArea(part.toString());
|
||||
Map<Integer, String> cqs = vo.getCqs();
|
||||
String one = cqs.get(11);
|
||||
String two = cqs.get(12);
|
||||
String three = cqs.get(13);
|
||||
String four = cqs.get(14);
|
||||
StringBuilder cb = new StringBuilder();
|
||||
if (vo.getPattern() == 1){
|
||||
if (one.equals("怕冷,遇冷加重,热敷舒服") || two.equals("膝盖沉重肿胀,阴天积液加重")){
|
||||
cb.append("寒湿痹阻型,");
|
||||
}
|
||||
if (one.equals("怕热,局部发热,冷敷舒服")){
|
||||
cb.append("湿热瘀阻型,");
|
||||
}
|
||||
if (three.equals("走路、干活后疼得厉害,休息减轻") || four.equals("腰部腿脚无酸软乏力")){
|
||||
cb.append("筋脉瘀滞劳损型,");
|
||||
}
|
||||
if (four.equals("经常腰酸腿软,上下楼无力打软腿") && (vo.getPainDuration().equals("一年以上") || vo.getPainDuration().equals("三年以上"))){
|
||||
cb.append("肝肾亏虚型");
|
||||
}
|
||||
}else {
|
||||
String input1 = "患者回答:" + one;
|
||||
String input2 = "请判断患者回答的内容意思如果是怕冷,遇冷加重,热敷舒服则回复yes;如果是怕热,局部发热,冷敷舒服则回复no;如果都不是则回复false。不要回复其他多余文字";
|
||||
String drawConclusion = doubaoService.drawConclusion(input1, input2);
|
||||
if (drawConclusion.equals("yes")){
|
||||
cb.append("寒湿痹阻型,");
|
||||
}
|
||||
if (drawConclusion.equals("no")){
|
||||
cb.append("湿热瘀阻型,");
|
||||
}
|
||||
input1 = "患者回答:" + two;
|
||||
input2 = "请判断患者回答的内容意思如果是膝盖沉重肿胀,阴天积液加重则回复yes;如果不是则回复no。不要回复其他多余文字";
|
||||
String yy = doubaoService.drawConclusion(input1, input2);
|
||||
if (yy.equals("yes")){
|
||||
cb.append("寒湿痹阻型,");
|
||||
}
|
||||
input1 = "患者回答:" + three;
|
||||
input2 = "请判断患者回答的内容意思如果是走路、干活后疼得厉害,休息减轻则回复yes;如果不是则回复no。不要回复其他多余文字";
|
||||
String a = doubaoService.drawConclusion(input1, input2);
|
||||
if (a.equals("yes")){
|
||||
cb.append("筋脉瘀滞劳损型,");
|
||||
}
|
||||
input1 = "患者回答:" + four;
|
||||
input2 = "请判断患者回答的内容意思如果是腰部腿脚无酸软乏力则回复yes;如果是经常腰酸腿软,上下楼无力打软腿则回复no;如果都不是则回复false。不要回复其他多余文字";
|
||||
String n = doubaoService.drawConclusion(input1, input2);
|
||||
if (n.equals("yes")){
|
||||
cb.append("筋脉瘀滞劳损型,");
|
||||
}
|
||||
if (n.equals("no")){
|
||||
cb.append("肝肾亏虚型");
|
||||
}
|
||||
}
|
||||
StringBuilder desc = new StringBuilder();
|
||||
StringBuilder append = desc.append("患者姓名:").append(vo.getPatientName()).append(",").append("病因:").append(syName)
|
||||
.append(",").append("疼痛等级:").append(vo.getLevel()).append(",").append("诱发动作:").append(vo.getInducedAction())
|
||||
.append(",").append("伴随症状:").append(vo.getSymptoms()).append(",").append("中医诊断:").append(cb);
|
||||
String input2 = "上述是患者的病痛信息,请你给出禁忌与注意事项,50字左右";
|
||||
String taboo = doubaoService.drawConclusion(append.toString(), input2);
|
||||
MobileAppUser user = mobileAppUserMapper.selectById(currentUser.getId());
|
||||
log.info("taboo:{}",taboo);
|
||||
consultationRecord.setTaboo(taboo);
|
||||
String drugPrice = getDrugPrice();
|
||||
consultationRecord.setDrugPrice(drugPrice);
|
||||
consultationRecord.setChineseDiagnosis(cb.toString());
|
||||
consultationRecord.setWesternDiagnosis(syName.toString());
|
||||
consultationRecord.setDepartment("中医科");
|
||||
consultationRecord.setPhoneNumber(user.getPhoneNumber());
|
||||
consultationRecord.setCreateTime(LocalDate.now());
|
||||
consultationRecordMapper.insert(consultationRecord);
|
||||
UserConsultationRecordVO recordVO = new UserConsultationRecordVO();
|
||||
BeanUtils.copyProperties(consultationRecord,recordVO);
|
||||
recordVO.setClinicalDia(syName.toString());
|
||||
int month = DateUtil.month(new Date()) + 1;
|
||||
int day = DateUtil.thisDayOfMonth();
|
||||
String yyyy = DateUtil.format(new Date(), "yyyy");
|
||||
String currentTime = yyyy + "年" + month + "月" + day + "日";
|
||||
recordVO.setCurrentTime(currentTime);
|
||||
recordVO.setDrugPrice(drugPrice);
|
||||
recordVO.setGender(user.getGender());
|
||||
recordVO.setAge(user.getAge());
|
||||
recordVO.setPhoneNumber(currentUser.getPhoneNumber());
|
||||
ClinicWorkLog clinicWorkLog = clinicWorkLogMapper.selectOne(new LambdaQueryWrapper<ClinicWorkLog>().eq(ClinicWorkLog::getPhoneNumber, user.getPhoneNumber())
|
||||
.eq(ClinicWorkLog::getCreateTime, consultationRecord.getCreateTime())
|
||||
.orderByDesc(ClinicWorkLog::getId)
|
||||
.last("limit 1"));
|
||||
|
||||
if (Objects.nonNull(clinicWorkLog)){
|
||||
recordVO.setMedicalTreatment(clinicWorkLog.getMedicalTreatment());
|
||||
}
|
||||
return recordVO;
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/getPrescriptionList")
|
||||
public Page<UserConsultationRecord> getPrescriptionList(HttpServletRequest request, @RequestBody UniPage<UserConsultationRecord> uniPage){
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (Objects.isNull(currentUser)){
|
||||
throw new ServiceException(401,"登录已过期");
|
||||
}
|
||||
JkPhysio jkPhysio = jkPhysioMapper.selectOne(new LambdaQueryWrapper<JkPhysio>().eq(JkPhysio::getPhysioTel, currentUser.getPhoneNumber()));
|
||||
if (Objects.isNull(jkPhysio)){
|
||||
throw new ServiceException("暂无理疗师身份信息!");
|
||||
}
|
||||
LambdaQueryWrapper<UserConsultationRecord> lambdaQueryWrapper = uniPage.buildQueryWrapper(query -> {
|
||||
LambdaQueryWrapper<UserConsultationRecord> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(StringUtils.isNotBlank(query.getPatientName()), UserConsultationRecord::getPatientName, query.getPatientName());
|
||||
wrapper.orderByDesc(UserConsultationRecord::getCreateTime);
|
||||
return wrapper;
|
||||
});
|
||||
Page<UserConsultationRecord> page = (Page<UserConsultationRecord>) uniPage.getPage();
|
||||
return consultationRecordMapper.selectPage(page,lambdaQueryWrapper);
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/getPrescription")
|
||||
public UserConsultationRecordVO prescription(@RequestParam("id") Integer id){
|
||||
UserConsultationRecord consultationRecord = consultationRecordMapper.selectById(id);
|
||||
MobileAppUser user = mobileAppUserMapper.selectById(consultationRecord.getUserId());
|
||||
ClinicWorkLog clinicWorkLog = clinicWorkLogMapper.selectOne(new LambdaQueryWrapper<ClinicWorkLog>().eq(ClinicWorkLog::getPhoneNumber, consultationRecord.getPhoneNumber())
|
||||
.eq(ClinicWorkLog::getCreateTime, consultationRecord.getCreateTime())
|
||||
.orderByDesc(ClinicWorkLog::getId)
|
||||
.last("limit 1"));
|
||||
UserConsultationRecordVO vo = new UserConsultationRecordVO();
|
||||
BeanUtils.copyProperties(consultationRecord,vo);
|
||||
LocalDate createTime = consultationRecord.getCreateTime();
|
||||
int yyyy = DateUtil.year(DateUtil.date(createTime));
|
||||
int month = DateUtil.month(DateUtil.date(createTime)) + 1;
|
||||
int day = DateUtil.dayOfMonth(DateUtil.date(createTime));
|
||||
String currentTime = yyyy + "年" + month + "月" + day + "日";
|
||||
vo.setCurrentTime(currentTime);
|
||||
vo.setAge(user.getAge());
|
||||
vo.setGender(user.getGender());
|
||||
vo.setClinicalDia(consultationRecord.getWesternDiagnosis());
|
||||
if (Objects.nonNull(clinicWorkLog)){
|
||||
vo.setMedicalTreatment(clinicWorkLog.getMedicalTreatment());
|
||||
}
|
||||
return vo;
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/getOwnPrescriptionList")
|
||||
public Page<UserConsultationRecord> getOwnPrescriptionList(HttpServletRequest request,@RequestBody UniPage<UserConsultationRecord> uniPage){
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (Objects.isNull(currentUser)){
|
||||
throw new ServiceException(401,"登录已过期");
|
||||
}
|
||||
Page<UserConsultationRecord> page = (Page<UserConsultationRecord>) uniPage.getPage();
|
||||
LambdaQueryWrapper<UserConsultationRecord> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(UserConsultationRecord::getUserId,currentUser.getId());
|
||||
wrapper.orderByDesc(UserConsultationRecord::getCreateTime);
|
||||
return consultationRecordMapper.selectPage(page,wrapper);
|
||||
}
|
||||
|
||||
/*@GetMapping("/getOwnPrescription")
|
||||
public UserConsultationRecordVO getOwnPrescription(@RequestParam("id") Integer id){
|
||||
|
||||
}*/
|
||||
|
||||
private String getDrugPrice(){
|
||||
while (true){
|
||||
String s = RandomStringUtils.randomNumeric(3);
|
||||
if (!s.startsWith("0")){
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.constant.UniConstant;
|
||||
import cn.unizk.entity.po.Chapter;
|
||||
import cn.unizk.entity.po.MobileAppUser;
|
||||
import cn.unizk.entity.po.MobileUserHaveCourse;
|
||||
import cn.unizk.entity.po.MobileUserVideoProgress;
|
||||
import cn.unizk.entity.vo.*;
|
||||
import cn.unizk.exception.ServiceException;
|
||||
import cn.unizk.mapper.*;
|
||||
import cn.unizk.utils.BeanCopyUtils;
|
||||
import cn.unizk.utils.JkSecurityUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.data.redis.core.HashOperations;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2026/3/9 17:43
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet/course")
|
||||
public class CourseStudyController {
|
||||
|
||||
@Resource
|
||||
private CourseMapper courseMapper;
|
||||
@Resource
|
||||
private MobileUserHaveCourseMapper mobileUserHaveCourseMapper;
|
||||
@Resource
|
||||
private MobileUserVideoProgressMapper mobileUserVideoProgressMapper;
|
||||
@Resource
|
||||
private ChapterMapper chapterMapper;
|
||||
@Resource(name = "kryoRedisTemplate")
|
||||
private RedisTemplate redisTemplate;
|
||||
|
||||
@GetMapping("/coursePage")
|
||||
public Page<CourseVO> courseVOPage(@RequestParam(value = "currentPage", required = false, defaultValue = "1") int currentPage,
|
||||
@RequestParam(value = "pageSize", required = false, defaultValue = "10") int pageSize,
|
||||
@RequestParam(value = "title", required = false) String title, HttpServletRequest request) {
|
||||
|
||||
/*MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (Objects.isNull(currentUser)) {
|
||||
throw new ServiceException(401, "登录已过期,请重新登录");
|
||||
}*/
|
||||
// List<MobileUserHaveCourse> userHaveCourses = mobileUserHaveCourseMapper.selectList(new LambdaQueryWrapper<MobileUserHaveCourse>().eq(MobileUserHaveCourse::getMobileUserId, currentUser.getId()));
|
||||
Page<CourseVO> page = new Page<>(currentPage, pageSize);
|
||||
List<CourseVO> courseVOS = courseMapper.voPage(page, title);
|
||||
courseVOS.forEach(vo -> vo.setUnlock(1));
|
||||
/* if (CollectionUtils.isEmpty(userHaveCourses)) {
|
||||
courseVOS.forEach(vo -> {
|
||||
vo.setUnlock(0);
|
||||
});
|
||||
} else {
|
||||
List<Integer> courseIds = userHaveCourses.stream().map(MobileUserHaveCourse::getCourseId).collect(Collectors.toList());
|
||||
for (CourseVO courseVO : courseVOS) {
|
||||
if (courseIds.contains(courseVO.getCourseId())) {
|
||||
courseVO.setUnlock(1);
|
||||
List<Chapter> chapters = chapterMapper.selectList(new LambdaQueryWrapper<Chapter>().eq(Chapter::getCourseId, courseVO.getCourseId()));
|
||||
if (CollectionUtils.isEmpty(chapters)){
|
||||
continue;
|
||||
}
|
||||
List<Integer> collect = chapters.stream().map(Chapter::getChapterId).collect(Collectors.toList());
|
||||
List<MobileUserVideoProgress> wxUserVideoProgresses = mobileUserVideoProgressMapper.selectList(new LambdaQueryWrapper<MobileUserVideoProgress>().eq(MobileUserVideoProgress::getMobileUserId, currentUser.getId())
|
||||
.in(MobileUserVideoProgress::getChapterId, collect));
|
||||
if (CollectionUtils.isEmpty(wxUserVideoProgresses)) {
|
||||
courseVO.setProgress(0);
|
||||
} else {
|
||||
List<Integer> progresses = wxUserVideoProgresses.stream().map(MobileUserVideoProgress::getProgress).collect(Collectors.toList());
|
||||
int sum = 0;
|
||||
for (Integer progress : progresses) {
|
||||
sum += progress;
|
||||
}
|
||||
int i = sum / progresses.size();
|
||||
courseVO.setProgress(i);
|
||||
}
|
||||
} else {
|
||||
courseVO.setUnlock(0);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
page.setRecords(courseVOS);
|
||||
return page;
|
||||
}
|
||||
|
||||
@GetMapping("/chapters")
|
||||
public Page<ChapterVO> voPage(@RequestParam(value = "currentPage", required = false, defaultValue = "1") int currentPage,
|
||||
@RequestParam(value = "pageSize", required = false, defaultValue = "50") int pageSize,
|
||||
@RequestParam("courseId") Integer courseId, HttpServletRequest request) {
|
||||
|
||||
/* MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (Objects.isNull(currentUser)){
|
||||
throw new ServiceException(401, "登录已过期,请重新登录");
|
||||
}
|
||||
MobileUserHaveCourse userHaveCourse = mobileUserHaveCourseMapper.selectOne(new LambdaQueryWrapper<MobileUserHaveCourse>().eq(MobileUserHaveCourse::getMobileUserId, currentUser.getId())
|
||||
.eq(MobileUserHaveCourse::getCourseId, courseId));
|
||||
if (Objects.isNull(userHaveCourse)){
|
||||
return new Page<>();
|
||||
}
|
||||
Page<Chapter> page = new Page<>(currentPage,pageSize);
|
||||
Page<Chapter> chapterPage = chapterMapper.selectPage(page, new LambdaQueryWrapper<Chapter>().eq(Chapter::getCourseId, courseId));
|
||||
List<Chapter> chapters = chapterPage.getRecords();
|
||||
if (CollectionUtils.isEmpty(chapters)){
|
||||
return new Page<>();
|
||||
}
|
||||
Collection<ChapterVO> chapterVOS = BeanCopyUtils.copyArrays(chapters, ChapterVO::new);
|
||||
for (ChapterVO chapterVO : chapterVOS) {
|
||||
MobileUserVideoProgress wxUserVideoProgress = mobileUserVideoProgressMapper.selectOne(new LambdaQueryWrapper<MobileUserVideoProgress>()
|
||||
.eq(MobileUserVideoProgress::getMobileUserId, currentUser.getId())
|
||||
.eq(MobileUserVideoProgress::getChapterId, chapterVO.getChapterId()));
|
||||
if (Objects.isNull(wxUserVideoProgress)){
|
||||
chapterVO.setProgress(0);
|
||||
}else {
|
||||
chapterVO.setProgress(wxUserVideoProgress.getProgress());
|
||||
}
|
||||
}
|
||||
Page<ChapterVO> voPage = new Page<>(chapterPage.getCurrent(),chapterPage.getSize());
|
||||
voPage.setTotal(chapterPage.getTotal());
|
||||
voPage.setRecords((List<ChapterVO>) chapterVOS);*/
|
||||
|
||||
pageSize = 50;
|
||||
Page<Chapter> page = new Page<>(currentPage,pageSize);
|
||||
Page<Chapter> chapterPage = chapterMapper.selectPage(page, new LambdaQueryWrapper<Chapter>().eq(Chapter::getCourseId, courseId));
|
||||
List<Chapter> chapters = chapterPage.getRecords();
|
||||
if (CollectionUtils.isEmpty(chapters)){
|
||||
return new Page<>();
|
||||
}
|
||||
Collection<ChapterVO> chapterVOS = BeanCopyUtils.copyArrays(chapters, ChapterVO::new);
|
||||
Page<ChapterVO> voPage = new Page<>(chapterPage.getCurrent(),chapterPage.getSize());
|
||||
voPage.setTotal(chapterPage.getTotal());
|
||||
chapterVOS.forEach(chapterVO -> chapterVO.setProgress(80));
|
||||
voPage.setRecords((List<ChapterVO>) chapterVOS);
|
||||
return voPage;
|
||||
}
|
||||
|
||||
@PostMapping("/reportWatch")
|
||||
public ResultData reportWatch(@RequestBody @Validated VideoProgressVO videoProgressVO,HttpServletRequest request){
|
||||
/*MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (Objects.isNull(currentUser)){
|
||||
throw new ServiceException(401, "登录已过期,请重新登录");
|
||||
}*/
|
||||
/*String key = UniConstant.VIDEO_PROGRESS_CACHE + currentUser.getId() + ":" + videoProgressVO.getChapterId();
|
||||
HashOperations<String, String, Object> ops = redisTemplate.opsForHash();
|
||||
ops.put(key, "lastPosition", videoProgressVO.getLastPosition());
|
||||
ops.increment(key,"spentTime",videoProgressVO.getSpentTime());
|
||||
redisTemplate.expire(key, 10, TimeUnit.MINUTES);
|
||||
return ResultData.success();*/
|
||||
/* MobileUserVideoProgress wxUserVideoProgress = mobileUserVideoProgressMapper.selectOne(new LambdaQueryWrapper<MobileUserVideoProgress>().eq(MobileUserVideoProgress::getChapterId, videoProgressVO.getChapterId())
|
||||
.eq(MobileUserVideoProgress::getMobileUserId, currentUser.getId()));
|
||||
if (Objects.isNull(wxUserVideoProgress)){
|
||||
MobileUserVideoProgress videoProgress = new MobileUserVideoProgress();
|
||||
videoProgress.setChapterId(videoProgressVO.getChapterId());
|
||||
videoProgress.setMobileUserId(currentUser.getId());
|
||||
videoProgress.setLastPosition(videoProgressVO.getLastPosition());
|
||||
videoProgress.setSpentTime(videoProgressVO.getSpentTime());
|
||||
videoProgress.setUpdateTime(LocalDateTime.now());
|
||||
Chapter chapter = chapterMapper.selectById(videoProgressVO.getChapterId());
|
||||
if (Objects.nonNull(chapter)){
|
||||
Integer p = (videoProgressVO.getLastPosition() * 100) / chapter.getVideoDuration();
|
||||
videoProgress.setProgress(p);
|
||||
}else {
|
||||
videoProgress.setProgress(0);
|
||||
}
|
||||
mobileUserVideoProgressMapper.insert(videoProgress);
|
||||
}else {
|
||||
wxUserVideoProgress.setSpentTime(videoProgressVO.getSpentTime());
|
||||
if (videoProgressVO.getLastPosition() > wxUserVideoProgress.getLastPosition()){
|
||||
wxUserVideoProgress.setLastPosition(videoProgressVO.getLastPosition());
|
||||
Chapter chapter = chapterMapper.selectById(videoProgressVO.getChapterId());
|
||||
if (Objects.nonNull(chapter)){
|
||||
Integer p = (videoProgressVO.getLastPosition() * 100) / chapter.getVideoDuration();
|
||||
wxUserVideoProgress.setProgress(p);
|
||||
}else {
|
||||
wxUserVideoProgress.setProgress(0);
|
||||
}
|
||||
}
|
||||
mobileUserVideoProgressMapper.updateById(wxUserVideoProgress);
|
||||
}*/
|
||||
return ResultData.success();
|
||||
}
|
||||
|
||||
@PostMapping("/reportTotalDuration")
|
||||
public ResultData reportTotalDuration(@RequestParam("totalDuration") Integer totalDuration,@RequestParam("chapterId") Integer chapterId){
|
||||
Chapter chapter = new Chapter();
|
||||
chapter.setChapterId(chapterId);
|
||||
chapter.setVideoDuration(totalDuration);
|
||||
chapterMapper.updateById(chapter);
|
||||
return ResultData.success();
|
||||
}
|
||||
|
||||
@PostMapping("/buyCourse")
|
||||
public void buyCourse(@Validated @RequestBody BuyCourseVO vo){
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.entity.vo.QuestionAnswerVO;
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.entity.vo.SeverityVO;
|
||||
import cn.unizk.exception.ServiceException;
|
||||
import cn.unizk.service.impl.DoubaoServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2026/5/12 15:37
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet/doubao")
|
||||
@Slf4j
|
||||
public class DoubaoAIController {
|
||||
|
||||
@Resource
|
||||
private DoubaoServiceImpl doubaoService;
|
||||
|
||||
@PostMapping("/getAnswer")
|
||||
public ResultData getAnswer(@RequestBody QuestionAnswerVO vo){
|
||||
log.info("进入getAnswer接口,AI判断回答---------------");
|
||||
String input1 = String.format("问题:%s?回答:%s",vo.getQuestion(),vo.getAnswer());
|
||||
String input2 = "请判断:回答和问题是否相干?只需要回答【相干】或【不相干】,不要多余文字。";
|
||||
String result = doubaoService.drawConclusion(input1, input2);
|
||||
ResultData data = new ResultData();
|
||||
if ("【相干】".equals(result)){
|
||||
data.setCode(200);
|
||||
}else {
|
||||
data.setCode(300);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
@PostMapping("/severity")
|
||||
public ResultData<String> severity(@RequestBody SeverityVO vo){
|
||||
if (Objects.isNull(vo)){
|
||||
throw new ServiceException("requestBody cannot empty");
|
||||
}
|
||||
if (vo.getId() != 6 && vo.getId() != 8){
|
||||
throw new ServiceException("无效ID");
|
||||
}
|
||||
ResultData<String> data = new ResultData<>();
|
||||
data.setCode(200);
|
||||
if (vo.getId() == 6){
|
||||
String input2 = "请判断:回答内容包含的时间是否小于或等于一个月?只需要回答【yes】或【no】,不要多余文字";
|
||||
String input1 = String.format("回答内容:%s",vo.getAnswer());
|
||||
String s = doubaoService.drawConclusion(input1, input2);
|
||||
log.info("ai回复:",s);
|
||||
if ("【yes】".contains(s)){
|
||||
data.setData("000");
|
||||
}else {
|
||||
data.setData("111");
|
||||
}
|
||||
return data;
|
||||
}
|
||||
if (vo.getId() == 8){
|
||||
String input2 = "假设回复内容是患者回复疼痛程度情况的,请判断:回复内容的疼痛程度是否是轻度或者比轻度更轻?只需要回答【yes】或【no】,不要多余文字";
|
||||
String input1 = String.format("回复内容:%s",vo.getAnswer());
|
||||
String s = doubaoService.drawConclusion(input1, input2);
|
||||
log.info("豆包返回:",s);
|
||||
if ("【yes】".contains(s)){
|
||||
data.setData("000");
|
||||
}else {
|
||||
data.setData("111");
|
||||
}
|
||||
return data;
|
||||
}
|
||||
throw new ServiceException("系统异常");
|
||||
}
|
||||
|
||||
@PostMapping("/getReport")
|
||||
public ResultData<String> getReport(@RequestBody String text){
|
||||
String input2 = "请你将上述这句话用尽可能简洁的文字总结出来";
|
||||
String conclusion = doubaoService.drawConclusion(text, input2);
|
||||
ResultData<String> data = new ResultData<>();
|
||||
data.setCode(200);
|
||||
data.setData(conclusion);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.entity.po.SysFile;
|
||||
import cn.unizk.entity.vo.MinioRespVO;
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.enums.FileType;
|
||||
import cn.unizk.exception.ServiceException;
|
||||
import cn.unizk.service.FileService;
|
||||
import cn.unizk.service.FileUploadService;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/10/9 17:19
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet/file")
|
||||
public class FileController {
|
||||
|
||||
@Resource
|
||||
private FileService fileService;
|
||||
@Resource
|
||||
private FileUploadService fileUploadService;
|
||||
|
||||
@GetMapping("/getById/{id}")
|
||||
public SysFile getById(@PathVariable("id") Integer id){
|
||||
return fileService.getById(id);
|
||||
}
|
||||
|
||||
@PostMapping("/uploadFile")
|
||||
public ResultData<MinioRespVO> uploadFile(@RequestParam("file") MultipartFile file){
|
||||
String originalFilename = file.getOriginalFilename();
|
||||
if (StringUtils.isBlank(originalFilename) || originalFilename.lastIndexOf(".") == -1){
|
||||
throw new ServiceException("文件格式不正确");
|
||||
}
|
||||
String fileType = originalFilename.substring(originalFilename.lastIndexOf("."));
|
||||
Set<String> types = ImmutableSet.of(".png",".jpg",".jpeg",".ico");
|
||||
if (!types.contains(fileType)){
|
||||
throw new ServiceException("目前只支持上传png,jpg,jpeg,ico类型文件");
|
||||
}
|
||||
String bucketName = FileType.getMinioBucketName(file.getContentType()).getBucketName();
|
||||
return fileUploadService.simpleUpload(file, bucketName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.entity.po.Appointments;
|
||||
import cn.unizk.entity.po.GolfCustInfo;
|
||||
import cn.unizk.entity.po.MobileAppUser;
|
||||
import cn.unizk.entity.po.MobileAppointments;
|
||||
import cn.unizk.entity.vo.GrfReportVO;
|
||||
import cn.unizk.entity.vo.GrfdialogueVO;
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.mapper.*;
|
||||
import cn.unizk.service.impl.DoubaoServiceImpl;
|
||||
import cn.unizk.utils.JkSecurityUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2026/6/5 11:26
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet/golf")
|
||||
@Slf4j
|
||||
public class GolfController {
|
||||
|
||||
@Resource
|
||||
private DoubaoServiceImpl doubaoService;
|
||||
@Resource
|
||||
private GolfCustInfoMapper golfCustInfoMapper;
|
||||
@Resource
|
||||
private MobileAppUserMapper mobileAppUserMapper;
|
||||
@Resource
|
||||
private MobileAppointmentsMapper mobileAppointmentsMapper;
|
||||
|
||||
@PostMapping("/judgeOne")
|
||||
public ResultData judgeOne(@Validated @RequestBody GrfdialogueVO vo){
|
||||
ResultData data = new ResultData();
|
||||
if (StringUtils.isBlank(vo.getQuestion())){
|
||||
String input1 = "请判断下面的回答是否是肩部,腰部,肘部,手腕,膝关节,髋关节,颈部,踝关节有关这8个部位的内容,只需要回答是或不是。";
|
||||
String s = doubaoService.drawConclusion(input1, vo.getAnswer());
|
||||
log.info(s);
|
||||
System.out.println(String.format("【%s】",s));
|
||||
if ("是".equals(s)){
|
||||
data.setCode(200);
|
||||
return data;
|
||||
}
|
||||
data.setCode(300);
|
||||
return data;
|
||||
}else {
|
||||
String question = vo.getQuestion();
|
||||
switch (question){
|
||||
case "2":
|
||||
vo.setQuestion("请问您肌肉发紧僵硬吗?");
|
||||
break;
|
||||
case "3":
|
||||
vo.setQuestion("请问您关节活动怎么样?");
|
||||
break;
|
||||
case "4":
|
||||
vo.setQuestion("请问您挥杆有没有不适症状?");
|
||||
break;
|
||||
}
|
||||
String input1 = String.format("问题:%s;回答:%s",vo.getQuestion(),vo.getAnswer());
|
||||
String input2 = "请判断:回答和问题是否相干?只需要回答相干或不相干,不要多余文字。";
|
||||
String s = doubaoService.drawConclusion(input1, input2);
|
||||
if ("相干".equals(s)){
|
||||
data.setCode(200);
|
||||
}else {
|
||||
data.setCode(300);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/saveCustInfo")
|
||||
public ResultData saveCustInfo(@Validated @RequestBody GolfCustInfo custInfo){
|
||||
golfCustInfoMapper.insert(custInfo);
|
||||
return ResultData.success(custInfo.getId());
|
||||
}
|
||||
|
||||
@PostMapping("/getReport")
|
||||
public ResultData<GrfReportVO> getReport(@RequestParam("id") Integer id,
|
||||
HttpServletRequest request,
|
||||
@RequestBody GrfReportVO vo){
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
GolfCustInfo golfCustInfo = golfCustInfoMapper.selectById(id);
|
||||
String sex = golfCustInfo.getGender() == 0 ? "女" : "男";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("就诊人:").append(golfCustInfo.getCustName())
|
||||
.append("性别:").append(sex).append("年龄:").append(golfCustInfo.getAge())
|
||||
.append("高尔夫球龄:").append(golfCustInfo.getGolfingAge())
|
||||
.append("每周打球次数:").append(golfCustInfo.getWeekFrequency())
|
||||
.append("患者陈述:").append(vo.getAnswer1()).append(",").append(vo.getAnswer2())
|
||||
.append(",").append(vo.getAnswer3()).append(",").append(vo.getAnswer4());
|
||||
|
||||
String conclusion = doubaoService.drawConclusion("请你把下面内容总结成一段话,并且这段话要包括病情分析,比如是得了肩周炎,腰椎间盘突出还是其他什么病,并给出调理建议", sb.toString());
|
||||
vo.setReport(conclusion);
|
||||
vo.setName(golfCustInfo.getCustName());
|
||||
vo.setGender(golfCustInfo.getGender()==0 ? "女" : "男");
|
||||
vo.setAge(golfCustInfo.getAge());
|
||||
vo.setPhoneNumber(golfCustInfo.getPhoneNumber());
|
||||
vo.setGolfingAge(golfCustInfo.getGolfingAge());
|
||||
vo.setWeekFrequency(golfCustInfo.getWeekFrequency());
|
||||
new Thread(() -> {
|
||||
List<Integer> numbers = new ArrayList<>();
|
||||
for (int i = 1; i <= 13; i++) {
|
||||
numbers.add(i);
|
||||
}
|
||||
Collections.shuffle(numbers);
|
||||
MobileAppUser user = new MobileAppUser();
|
||||
user.setId((currentUser).getId());
|
||||
user.setPainNumber(String.valueOf(numbers.get(0)) + "," + numbers.get(1));
|
||||
mobileAppUserMapper.updateById(user);
|
||||
}).start();
|
||||
return ResultData.success(vo);
|
||||
|
||||
}
|
||||
|
||||
@PostMapping("/evaluation")
|
||||
public ResultData evaluation(@RequestBody MobileAppointments appointments){
|
||||
MobileAppointments app = new MobileAppointments();
|
||||
app.setId(appointments.getId());
|
||||
app.setTreatRating(appointments.getTreatRating());
|
||||
app.setEvaluation(appointments.getEvaluation());
|
||||
app.setStatus("commented");
|
||||
mobileAppointmentsMapper.updateById(app);
|
||||
return ResultData.success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.constant.UniConstant;
|
||||
import cn.unizk.entity.po.*;
|
||||
import cn.unizk.entity.vo.ComboVO;
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.enums.OrderStatus;
|
||||
import cn.unizk.exception.ServiceException;
|
||||
import cn.unizk.mapper.MobileAppUserMapper;
|
||||
import cn.unizk.mapper.MobileOrderMapper;
|
||||
import cn.unizk.mapper.PhysioSchedulesMapper;
|
||||
import cn.unizk.mapper.UserDeviceTreatRecordMapper;
|
||||
import cn.unizk.service.ComboService;
|
||||
import cn.unizk.service.DeviceService;
|
||||
import cn.unizk.service.WxUserService;
|
||||
import cn.unizk.utils.AESUtil;
|
||||
import cn.unizk.utils.SendSmsUtil;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/9/11 12:00
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/h5")
|
||||
@CrossOrigin(origins = {"http://369.peaktcm.com:9000","http://peaktcm.com","http://peaktcm.com:9000","http://139.9.2.195:8080"},allowCredentials = "true",
|
||||
exposedHeaders = {"Authorization"})
|
||||
public class H5ComboController {
|
||||
|
||||
@Resource
|
||||
private MobileOrderMapper mobileOrderMapper;
|
||||
@Resource
|
||||
private ComboService comboService;
|
||||
@Resource
|
||||
private MobileAppUserMapper mobileAppUserMapper;
|
||||
@Autowired
|
||||
@Qualifier("kryoRedisTemplate")
|
||||
private RedisTemplate<String,Object> redisTemplate;
|
||||
@Resource
|
||||
private UserDeviceTreatRecordMapper treatRecordMapper;
|
||||
@Resource
|
||||
private DeviceService deviceService;
|
||||
@Resource
|
||||
private PhysioSchedulesMapper physioSchedulesMapper;
|
||||
|
||||
@GetMapping("/getCombos")
|
||||
public List<ComboVO> getCombos(HttpServletResponse response, @RequestParam("deviceId") String deviceId, @RequestParam("phoneNumber") String phoneNumber,
|
||||
@RequestParam("code") String code){
|
||||
log.info("deviceId={},phoneNumber={},code={}",deviceId,phoneNumber,code);
|
||||
validatePhoneCode(phoneNumber,code);
|
||||
MobileAppUser one = mobileAppUserMapper.selectOne(new LambdaQueryWrapper<MobileAppUser>().eq(MobileAppUser::getPhoneNumber, phoneNumber));
|
||||
if (Objects.isNull(one)){
|
||||
throw new ServiceException("您不是吉客中医微信小程序的用户");
|
||||
}
|
||||
List<MobileOrder> wxOrders = mobileOrderMapper.selectList(new LambdaQueryWrapper<MobileOrder>()
|
||||
.eq(MobileOrder::getMobileUserId, one.getId())
|
||||
.eq(MobileOrder::getDeviceId, deviceId)
|
||||
.in(MobileOrder::getStatus,OrderStatus.paid.name(),OrderStatus.unverified.name())
|
||||
.isNotNull(MobileOrder::getComboId));
|
||||
if (CollectionUtils.isEmpty(wxOrders)){
|
||||
throw new ServiceException("抱歉,您在此设备上没有购买套餐");
|
||||
}
|
||||
String encrypt = phoneNumber;
|
||||
try {
|
||||
encrypt = AESUtil.encrypt(phoneNumber);
|
||||
} catch (Exception e) {
|
||||
log.error("手机号加密异常",e);
|
||||
}
|
||||
response.setHeader("Authorization",encrypt);
|
||||
response.setHeader("Access-Control-Expose-Headers", "Authorization");
|
||||
List<ComboVO> list = new ArrayList<>();
|
||||
for (MobileOrder wxOrder : wxOrders) {
|
||||
Combo combo = comboService.getById(wxOrder.getComboId());
|
||||
ComboVO vo = new ComboVO();
|
||||
BeanUtils.copyProperties(combo,vo);
|
||||
vo.setOrderId(wxOrder.getOrderId());
|
||||
list.add(vo);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@GetMapping("/sendPhoneCode")
|
||||
public ResultData sendPhoneCode(@RequestParam("phoneNumber") String phoneNumber){
|
||||
String code = RandomStringUtils.randomNumeric(6);
|
||||
/*redisTemplate.opsForValue().set("h5:"+phoneNumber,"888888");
|
||||
return ResultData.success();*/
|
||||
try {
|
||||
String s = SendSmsUtil.sendPhoneCode(phoneNumber, code);
|
||||
JSONObject res = JSONObject.parseObject(s);
|
||||
Integer statusCode = res.getInteger("statusCode");
|
||||
if (statusCode != null && statusCode == 200){
|
||||
redisTemplate.opsForValue().set("h5:"+phoneNumber,code,300, TimeUnit.SECONDS);
|
||||
return ResultData.success();
|
||||
}
|
||||
return ResultData.failure(500,"验证码发送失败");
|
||||
} catch (ExecutionException | InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
throw new ServiceException("验证码发送失败");
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/writeOff")
|
||||
public int writeOff(HttpServletRequest request,@RequestParam("orderId") String orderId){
|
||||
String encrypt = request.getHeader("Token");
|
||||
if (StringUtils.isBlank(encrypt)){
|
||||
throw new ServiceException("No permission");
|
||||
}
|
||||
String decrypt = encrypt;
|
||||
try {
|
||||
decrypt = AESUtil.decrypt(encrypt);
|
||||
} catch (Exception e) {
|
||||
log.error("手机号解密异常",e);
|
||||
}
|
||||
// MobileOrder wxOrder = orderService.getOrderByIdAndPhone(orderId, decrypt);
|
||||
MobileOrder mobileOrder = mobileOrderMapper.selectOrderByIdAndPhone(orderId, decrypt);
|
||||
if (Objects.isNull(mobileOrder)){
|
||||
throw new ServiceException("No permission");
|
||||
}
|
||||
if (!OrderStatus.unverified.name().equals(mobileOrder.getStatus())){
|
||||
throw new ServiceException("该套餐已核销过了!");
|
||||
}
|
||||
Combo combo = comboService.getById(mobileOrder.getComboId());
|
||||
if (Objects.isNull(combo) || StringUtils.isBlank(combo.getDeviceId())){
|
||||
throw new ServiceException("套餐或设备不存在,无法核销!");
|
||||
}
|
||||
Device dv = deviceService.getById(combo.getDeviceId());
|
||||
if (dv.getTreatStatus() == 1 || dv.getOperatingStatus() == 0){
|
||||
throw new ServiceException("此设备正在被使用,等待使用完再进行核销!");
|
||||
}
|
||||
UserDeviceTreatRecord treatRecord = new UserDeviceTreatRecord();
|
||||
treatRecord.setDeviceId(combo.getDeviceId());
|
||||
treatRecord.setUserId(mobileOrder.getMobileUserId());
|
||||
treatRecord.setCreateTime(LocalDateTime.now());
|
||||
treatRecordMapper.insert(treatRecord);
|
||||
Device device = new Device();
|
||||
device.setDeviceId(combo.getDeviceId());
|
||||
device.setTreatStatus(1);
|
||||
deviceService.updateById(device);
|
||||
mobileOrder.setStatus(OrderStatus.verified.name());
|
||||
String redisKey = UniConstant.REDIS_CURRENT_DEVICE_USER + dv.getDeviceId();
|
||||
redisTemplate.opsForValue().set(redisKey,mobileOrder.getMobileUserId(),10,TimeUnit.MINUTES);
|
||||
return mobileOrderMapper.updateById(mobileOrder);
|
||||
}
|
||||
|
||||
@GetMapping("/getAuthQrcode")
|
||||
public void getAuthQrcode(HttpServletResponse response){
|
||||
// QRcodeUtil.generateQrcode(response);
|
||||
}
|
||||
|
||||
private void validatePhoneCode(String phone,String code){
|
||||
String cacheCode = (String) redisTemplate.opsForValue().get("h5:"+phone);
|
||||
if (StringUtils.isBlank(cacheCode) || !cacheCode.equals(code)){
|
||||
throw new ServiceException("验证码错误");
|
||||
}
|
||||
redisTemplate.delete("h5:"+phone);
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/addData")
|
||||
public Integer addData(){
|
||||
List<String> slotCodes = Lists.newArrayList("M1","M2","M3","A1","A2","A3","A4");
|
||||
List<PhysioSchedules> list = new ArrayList<>();
|
||||
for (String slotCode : slotCodes) {
|
||||
PhysioSchedules physioSchedules = new PhysioSchedules();
|
||||
physioSchedules.setPhysioId(8);
|
||||
physioSchedules.setTimeSlotCode(slotCode);
|
||||
physioSchedules.setMaxBookings(1);
|
||||
physioSchedules.setActive(1);
|
||||
list.add(physioSchedules);
|
||||
}
|
||||
physioSchedulesMapper.insert(list);
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.entity.po.Device;
|
||||
import cn.unizk.huifupay.config.properties.HuiFuProperties;
|
||||
import cn.unizk.service.DeviceService;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2026/3/10 17:39
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Controller
|
||||
@RequestMapping("/h5/scan")
|
||||
public class H5PowerOnController {
|
||||
|
||||
@Resource
|
||||
private DeviceService deviceService;
|
||||
@Resource
|
||||
private HuiFuProperties huiFuProperties;
|
||||
|
||||
@GetMapping("/toPayPage")
|
||||
public String toPayPage(@RequestParam("deviceId") String deviceId){
|
||||
Device device = deviceService.getById(deviceId);
|
||||
if (Objects.isNull(device) || device.getForcePay() != 1){
|
||||
return "redirect:/h5/hello.html?deviceId=" + deviceId;
|
||||
}
|
||||
return "redirect:/h5/pay.html?deviceId=" + deviceId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.unizk.config.WxProperties;
|
||||
import cn.unizk.entity.po.MobileOrder;
|
||||
import cn.unizk.entity.vo.MobileOrderVO;
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.enums.OrderStatus;
|
||||
import cn.unizk.huifupay.config.properties.HuiFuProperties;
|
||||
import cn.unizk.huifupay.utils.HfUtil;
|
||||
import cn.unizk.huifupay.utils.HuifuSignUtil;
|
||||
import cn.unizk.mapper.MobileOrderMapper;
|
||||
import cn.unizk.service.PayService;
|
||||
import cn.unizk.utils.HttpUtil;
|
||||
import cn.unizk.wxPay.vo.WxPlaceOrderResVO;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.mime.MultipartEntityBuilder;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.*;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Clock;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/9/29 11:31
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet/huifuPay")
|
||||
@Slf4j
|
||||
public class HuiFuPayController {
|
||||
|
||||
@Resource
|
||||
private HuiFuProperties huiFuProperties;
|
||||
@Resource
|
||||
private WxProperties wxProperties;
|
||||
|
||||
@Resource(name = "huifu")
|
||||
private PayService payService;
|
||||
@Resource
|
||||
private MobileOrderMapper mobileOrderMapper;
|
||||
|
||||
@PostMapping("/placeOrder")
|
||||
public WxPlaceOrderResVO placeOrder(@RequestBody MobileOrderVO vo){
|
||||
return payService.wxPlaceOrder(vo);
|
||||
}
|
||||
|
||||
@PostMapping("/configureApplet")
|
||||
public String configureApplet(){
|
||||
return payService.configureApplet();
|
||||
}
|
||||
|
||||
@PostMapping("/realNameCheck")
|
||||
public ResultData realNameCheck(){
|
||||
JSONObject object = JSONObject.of();
|
||||
object.put("sys_id",huiFuProperties.getHuifuId());
|
||||
object.put("product_id",huiFuProperties.getProductId());
|
||||
JSONObject data = JSONObject.of();
|
||||
data.put("req_seq_id",HfUtil.getReqSeqId());
|
||||
data.put("req_date",DateUtil.format(new Date(),"yyyyMMdd"));
|
||||
data.put("huifu_id",huiFuProperties.getHuifuId());
|
||||
data.put("pay_scene","02");
|
||||
data.put("owner","Y");
|
||||
data.put("identification_address","山东省青岛市市北区包头路24号甲");
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
JSONObject ubo_info_list = JSONObject.of();
|
||||
ubo_info_list.put("ubo_id_doc_type","00");
|
||||
ubo_info_list.put("ubo_id_doc_copy","d36573e8-beda-34d8-9647-ee75d02e6f6b");
|
||||
ubo_info_list.put("ubo_id_doc_copy_back","c7ed0c5e-bb3a-31b6-ac1d-37c02c702da9");
|
||||
ubo_info_list.put("ubo_id_doc_name","陈静");
|
||||
ubo_info_list.put("ubo_id_doc_number","370203197102050021");
|
||||
ubo_info_list.put("ubo_id_doc_address","山东省青岛市市北区包头路24号甲");
|
||||
ubo_info_list.put("ubo_period_begin","20150902");
|
||||
ubo_info_list.put("ubo_period_end","20350902");
|
||||
jsonArray.add(ubo_info_list);
|
||||
data.put("ubo_info_list",jsonArray.toString());
|
||||
data.put("name","陈静");
|
||||
data.put("mobile","13686435231");
|
||||
data.put("id_card_number","370203197102050021");
|
||||
data.put("contact_type","LEGAL");
|
||||
object.put("data",data);
|
||||
String sign = HuifuSignUtil.sign(data, huiFuProperties.getPrivateKey());
|
||||
object.put("sign",sign);
|
||||
String url = "https://api.huifu.com/v2/merchant/busi/realname";
|
||||
log.info("参数:{}",object);
|
||||
String s = HttpUtil.doPostJson(url, null, object);
|
||||
log.info("汇付实名认证返回:{}",s);
|
||||
return ResultData.success(JSONObject.parseObject(s));
|
||||
}
|
||||
|
||||
@PostMapping("/uploadHfData")
|
||||
public String uploadHfData(@RequestParam("file")MultipartFile file,@RequestParam("fileType") String fileType){
|
||||
//图片上传接口地址
|
||||
String url = "https://api.huifu.com/v2/supplementary/picture";
|
||||
// 请求参数
|
||||
Map<String, Object> params = new HashMap<String, Object>();
|
||||
// 请求流水号,需保证当天商户下唯一,推荐采用日期时间+几位流水号的形式
|
||||
params.put("req_seq_id", HfUtil.getReqSeqId());
|
||||
params.put("req_date", DateUtil.format(new Date(),"yyyyMMdd"));
|
||||
params.put("file_type", fileType);
|
||||
//如果商户还未成功进件huifu_id可以为空
|
||||
params.put("huifu_id", huiFuProperties.getHuifuId());
|
||||
String data = JSON.toJSONString(params);
|
||||
log.info("data={}",data);
|
||||
|
||||
CloseableHttpClient httpclient1 = HttpClients.createDefault();
|
||||
CloseableHttpResponse response = null;
|
||||
String result = null;
|
||||
|
||||
try {
|
||||
File tempFile = File.createTempFile("upload", ".jpg");
|
||||
file.transferTo(tempFile);
|
||||
HttpPost httpPost = new HttpPost(url);
|
||||
ContentType contentType = ContentType.create("text/plain", Charset.forName("UTF-8"));
|
||||
MultipartEntityBuilder mEntityBuilder = MultipartEntityBuilder.create();
|
||||
mEntityBuilder.addTextBody("sys_id", huiFuProperties.getHuifuId(), contentType);
|
||||
mEntityBuilder.addTextBody("product_id", huiFuProperties.getProductId(), contentType);
|
||||
mEntityBuilder.addTextBody("data", data, contentType);
|
||||
mEntityBuilder.addBinaryBody("file", tempFile);
|
||||
|
||||
httpPost.setEntity(mEntityBuilder.build());
|
||||
response = httpclient1.execute(httpPost);
|
||||
int statusCode = response.getStatusLine().getStatusCode();
|
||||
if (statusCode == HttpStatus.SC_OK) {
|
||||
HttpEntity resEntity = response.getEntity();
|
||||
result = EntityUtils.toString(resEntity);
|
||||
System.out.print(result);
|
||||
tempFile.deleteOnExit();
|
||||
return result;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "fail";
|
||||
}
|
||||
|
||||
@PostMapping("/callback")
|
||||
public String callback(@RequestBody String messageBody){
|
||||
log.info("汇付支付成功回调数据:{}",messageBody);
|
||||
try {
|
||||
String decode = URLDecoder.decode(messageBody, "utf-8");
|
||||
String resp_data = decode.split("&resp_data=")[1];
|
||||
JSONObject jsonObject = JSONObject.parseObject(resp_data);
|
||||
String trans_stat = jsonObject.getString("trans_stat");
|
||||
String req_seq_id = jsonObject.getString("req_seq_id");
|
||||
List<MobileOrder> wxOrders = mobileOrderMapper.selectList(new LambdaQueryWrapper<MobileOrder>().eq(MobileOrder::getOutTradeNo, req_seq_id));
|
||||
if (CollectionUtils.isEmpty(wxOrders)){
|
||||
log.info("查无此单,交易流水号:{}",req_seq_id);
|
||||
return "fail";
|
||||
}
|
||||
if ("S".equals(trans_stat)){
|
||||
log.info("交易成功");
|
||||
//修改订单状态
|
||||
for (MobileOrder wxOrder : wxOrders) {
|
||||
if (wxOrder.getComboId() != null){
|
||||
wxOrder.setDeliveryWay("自提");
|
||||
}
|
||||
if (wxOrder.getComboId() != null || wxOrder.getDeliveryWay().equals("自提")){
|
||||
wxOrder.setStatus(OrderStatus.unverified.name());
|
||||
}else if (wxOrder.getComboId() == null && wxOrder.getDeliveryWay().equals("配送")){
|
||||
wxOrder.setStatus(OrderStatus.not_shipped.name());
|
||||
}else if(wxOrder.getDeliveryWay().equals("配送")){
|
||||
wxOrder.setStatus(OrderStatus.not_shipped.name());
|
||||
}else if(StringUtils.isNotBlank(wxOrder.getReceivingAddress())){
|
||||
wxOrder.setStatus(OrderStatus.not_shipped.name());
|
||||
}else {
|
||||
wxOrder.setStatus(OrderStatus.paid.name());
|
||||
}
|
||||
wxOrder.setPayTime(LocalDateTime.now(Clock.systemDefaultZone()));
|
||||
mobileOrderMapper.updateById(wxOrder);
|
||||
}
|
||||
return "success";
|
||||
}else if ("F".equals(trans_stat)){
|
||||
log.info("交易失败");
|
||||
return "fail";
|
||||
}
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
log.error("支付回调解码失败",e);
|
||||
return "fail";
|
||||
}
|
||||
return "fail";
|
||||
}
|
||||
|
||||
@RequestMapping("/configureAppletCallback")
|
||||
public String configureAppletCallback(@RequestBody String messageBody){
|
||||
log.info("汇付配置微信商户小程序审核消息:{}",messageBody);
|
||||
return "success";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.entity.dto.CashOutDTO;
|
||||
import cn.unizk.entity.dto.CashOutResponse;
|
||||
import cn.unizk.entity.po.MobileAppUser;
|
||||
import cn.unizk.entity.vo.PayCourseVO;
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.exception.ServiceException;
|
||||
import cn.unizk.huifupay.dto.HuifuPlaceOrderParamBaseDTO;
|
||||
import cn.unizk.huifupay.service.HuiFuVendorPayService;
|
||||
import cn.unizk.huifupay.vo.DeviceScanPayVO;
|
||||
import cn.unizk.huifupay.vo.RechargeVO;
|
||||
import cn.unizk.utils.JkSecurityUtil;
|
||||
import cn.unizk.wxPay.vo.WxPlaceOrderResVO;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2026/3/11 14:14
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet/huiFuVendor")
|
||||
public class HuiFuVendorPayController {
|
||||
|
||||
@Resource
|
||||
private HuiFuVendorPayService vendorPayService;
|
||||
|
||||
@PostMapping("/pay")
|
||||
public WxPlaceOrderResVO pay(@RequestBody DeviceScanPayVO vo, HttpServletRequest request){
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (Objects.isNull(currentUser) || !currentUser.getId().equals(vo.getUserId())){
|
||||
throw new ServiceException(401,"非法访问!");
|
||||
}
|
||||
vo.setUserId(currentUser.getId());
|
||||
return vendorPayService.vendorPay(vo);
|
||||
}
|
||||
|
||||
@PostMapping("/cashOut")
|
||||
public CashOutResponse cashOut(@RequestBody CashOutDTO dto){
|
||||
return vendorPayService.profitSharingPay(dto);
|
||||
|
||||
}
|
||||
|
||||
@PostMapping("/coursePay")
|
||||
public WxPlaceOrderResVO coursePay(@RequestBody PayCourseVO vo,HttpServletRequest request){
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (Objects.isNull(currentUser) || !currentUser.getId().equals(vo.getUserId())){
|
||||
throw new ServiceException(401,"非法访问!");
|
||||
}
|
||||
vo.setUserId(currentUser.getId());
|
||||
return vendorPayService.coursePay(vo);
|
||||
}
|
||||
|
||||
@PostMapping("/vipRecharge")
|
||||
public WxPlaceOrderResVO vipRecharge(@RequestBody RechargeVO vo,HttpServletRequest request){
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (currentUser == null || !currentUser.getId().equals(vo.getUserId())){
|
||||
throw new ServiceException(401,"非法访问!");
|
||||
}
|
||||
vo.setUserId(currentUser.getId());
|
||||
return vendorPayService.recharge(vo);
|
||||
}
|
||||
|
||||
@PostMapping("/activeMembership")
|
||||
public WxPlaceOrderResVO activeMembership(@RequestBody HuifuPlaceOrderParamBaseDTO dto,HttpServletRequest request){
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (currentUser == null || !currentUser.getId().equals(dto.getUserId())){
|
||||
throw new ServiceException(401,"非法访问!");
|
||||
}
|
||||
dto.setUserId(currentUser.getId());
|
||||
return vendorPayService.activeMembership(dto);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,307 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.constant.UniConstant;
|
||||
import cn.unizk.entity.dto.HuifuSyncRefundResDTO;
|
||||
import cn.unizk.entity.po.*;
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.enums.OrderAfterSaleStatus;
|
||||
import cn.unizk.enums.OrderStatus;
|
||||
import cn.unizk.exception.ServiceException;
|
||||
import cn.unizk.mapper.*;
|
||||
import cn.unizk.service.WxUserService;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.google.gson.Gson;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.net.URLDecoder;
|
||||
import java.time.Clock;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/10/23 15:56
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/hf/webhook")
|
||||
@Slf4j
|
||||
public class HuifuWebhookController {
|
||||
|
||||
@Resource
|
||||
private MobileOrderMapper mobileOrderMapper;
|
||||
@Resource
|
||||
private DeviceMapper deviceMapper;
|
||||
@Resource
|
||||
private StoreAccountMapper storeAccountMapper;
|
||||
@Resource
|
||||
private JkStoreMapper jkStoreMapper;
|
||||
@Resource
|
||||
private MobileAppUserMapper mobileAppUserMapper;
|
||||
@Resource
|
||||
private MobileUserHaveCourseMapper mobileUserHaveCourseMapper;
|
||||
@Resource
|
||||
private ChildStoreAccountMapper childStoreAccountMapper;
|
||||
@Resource(name = "kryoRedisTemplate")
|
||||
private RedisTemplate redisTemplate;
|
||||
@Resource
|
||||
private WxVipRechargeMapper vipRechargeMapper;
|
||||
@Resource
|
||||
private MobileAppUserAccountMapper mobileAppUserAccountMapper;
|
||||
|
||||
|
||||
@PostMapping("/refundCallback")
|
||||
public String refundCallback(@RequestBody String body) throws UnsupportedEncodingException {
|
||||
log.info("退款回调接口收到请求参数:{}",body);
|
||||
String decode = URLDecoder.decode(body, "utf-8");
|
||||
String resp_data = decode.split("&resp_data=")[1];
|
||||
JSONObject jsonObject = JSONObject.parseObject(resp_data);
|
||||
String sub_resp_code = jsonObject.getString("sub_resp_code");
|
||||
if ("00000000".equals(sub_resp_code)){
|
||||
String req_seq_id = jsonObject.getString("req_seq_id");
|
||||
List<MobileOrder> wxOrders = mobileOrderMapper.selectList(new LambdaQueryWrapper<MobileOrder>().eq(MobileOrder::getRefundReqSeqId, req_seq_id));
|
||||
if (CollectionUtils.isNotEmpty(wxOrders)){
|
||||
log.info("此订单是微信小程序订单,交易流水号:{}",req_seq_id);
|
||||
String trans_stat = jsonObject.getString("trans_stat");
|
||||
if ("S".equals(trans_stat)){
|
||||
for (MobileOrder wxOrder : wxOrders) {
|
||||
wxOrder.setStatus(OrderStatus.refunded.name());
|
||||
wxOrder.setRefundFinishTime(LocalDateTime.now());
|
||||
if (wxOrder.getAfterSaleStatus().equals(OrderAfterSaleStatus.ONLY_TUI_KUAN.getKey())){
|
||||
wxOrder.setAfterSaleStatus(OrderAfterSaleStatus.TUI_KUAN_SUCCESS.getKey());
|
||||
}
|
||||
if (wxOrder.getAfterSaleStatus().equals(OrderAfterSaleStatus.TUI_HUO_TUI_KUAN.getKey())){
|
||||
wxOrder.setAfterSaleStatus(OrderAfterSaleStatus.TUI_HUO_TUI_KUAN_SUCCESS.getKey());
|
||||
}
|
||||
}
|
||||
mobileOrderMapper.updateById(wxOrders);
|
||||
return "ok";
|
||||
}else if ("F".equals(trans_stat)){
|
||||
log.info("退款失败,原因:{}",jsonObject.getString("sub_resp_desc"));
|
||||
}else if ("P".equals(trans_stat)){
|
||||
log.info("交易中交易中交易中交易中交易中交易中交易中交易中交易中");
|
||||
}
|
||||
}else {
|
||||
List<MobileOrder> mobileOrders = mobileOrderMapper.selectList(new LambdaQueryWrapper<MobileOrder>().eq(MobileOrder::getRefundReqSeqId, req_seq_id));
|
||||
if (CollectionUtils.isNotEmpty(mobileOrders)){
|
||||
log.info("此订单是微信小程序订单,交易流水号:{}",req_seq_id);
|
||||
String trans_stat = jsonObject.getString("trans_stat");
|
||||
if ("S".equals(trans_stat)){
|
||||
for (MobileOrder mobileOrder : mobileOrders) {
|
||||
mobileOrder.setStatus(OrderStatus.refunded.name());
|
||||
mobileOrder.setRefundFinishTime(LocalDateTime.now());
|
||||
if (mobileOrder.getAfterSaleStatus().equals(OrderAfterSaleStatus.ONLY_TUI_KUAN.getKey())){
|
||||
mobileOrder.setAfterSaleStatus(OrderAfterSaleStatus.TUI_KUAN_SUCCESS.getKey());
|
||||
}
|
||||
if (mobileOrder.getAfterSaleStatus().equals(OrderAfterSaleStatus.TUI_HUO_TUI_KUAN.getKey())){
|
||||
mobileOrder.setAfterSaleStatus(OrderAfterSaleStatus.TUI_HUO_TUI_KUAN_SUCCESS.getKey());
|
||||
}
|
||||
}
|
||||
mobileOrderMapper.updateById(mobileOrders);
|
||||
return "ok";
|
||||
}else if ("F".equals(trans_stat)){
|
||||
log.info("退款失败,原因:{}",jsonObject.getString("sub_resp_desc"));
|
||||
}else if ("P".equals(trans_stat)){
|
||||
log.info("交易中交易中交易中交易中交易中交易中交易中交易中交易中");
|
||||
}
|
||||
}else {
|
||||
log.info("微信小程序和APP端都查不到该订单,交易流水号:{}",req_seq_id);
|
||||
return "fail";
|
||||
}
|
||||
}
|
||||
}else {
|
||||
log.info("退款失败,原因:{}",jsonObject.getString("sub_resp_desc"));
|
||||
}
|
||||
return "fail";
|
||||
}
|
||||
|
||||
@PostMapping("/vendorPaySuccess")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String callback(@RequestBody String messageBody){
|
||||
log.info("汇付商户支付成功回调数据:{}",messageBody);
|
||||
try {
|
||||
String decode = URLDecoder.decode(messageBody, "utf-8");
|
||||
String resp_data = decode.split("&resp_data=")[1];
|
||||
JSONObject jsonObject = JSONObject.parseObject(resp_data);
|
||||
String trans_stat = jsonObject.getString("trans_stat");
|
||||
String req_seq_id = jsonObject.getString("req_seq_id");
|
||||
List<MobileOrder> wxOrders = mobileOrderMapper.selectList(new LambdaQueryWrapper<MobileOrder>().eq(MobileOrder::getOutTradeNo, req_seq_id));
|
||||
if (CollectionUtils.isEmpty(wxOrders)){
|
||||
log.info("查无此单,交易流水号:{}",req_seq_id);
|
||||
return "fail";
|
||||
}
|
||||
MobileOrder wxOrder = wxOrders.get(0);
|
||||
if (OrderStatus.paid.name().equals(wxOrder.getStatus())){
|
||||
return "success";
|
||||
}
|
||||
if ("S".equals(trans_stat)){
|
||||
log.info("交易成功");
|
||||
//修改订单状态
|
||||
if (wxOrder.getOrderType() != null && wxOrder.getOrderType() == 1){
|
||||
scanPay(wxOrder);
|
||||
}else if (wxOrder.getOrderType() != null && wxOrder.getOrderType() == 3){
|
||||
coursePay(wxOrder);
|
||||
}else if (wxOrder.getOrderType() != null && wxOrder.getOrderType() == 4){
|
||||
vipRecharge(wxOrder);
|
||||
}else if (wxOrder.getOrderType() != null && wxOrder.getOrderType() == 6){
|
||||
activeMember(wxOrder);
|
||||
}
|
||||
|
||||
return "success";
|
||||
}else if ("F".equals(trans_stat)){
|
||||
log.info("交易失败");
|
||||
return "fail";
|
||||
}
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
log.error("支付回调解码失败",e);
|
||||
return "fail";
|
||||
}
|
||||
return "fail";
|
||||
}
|
||||
|
||||
private void activeMember(MobileOrder wxOrder){
|
||||
wxOrder.setStatus(OrderStatus.paid.name());
|
||||
wxOrder.setPayTime(LocalDateTime.now());
|
||||
mobileOrderMapper.updateById(wxOrder);
|
||||
MobileAppUser wxUser = mobileAppUserMapper.selectOne(new LambdaQueryWrapper<MobileAppUser>().eq(MobileAppUser::getId, wxOrder.getMobileUserId()));
|
||||
wxUser.setHasMember(1);
|
||||
mobileAppUserMapper.updateById(wxUser);
|
||||
}
|
||||
|
||||
private void scanPay(MobileOrder wxOrder){
|
||||
wxOrder.setStatus(OrderStatus.paid.name());
|
||||
Device device = deviceMapper.selectById(wxOrder.getDeviceId());
|
||||
wxOrder.setStoreId(device.getStoreId());
|
||||
wxOrder.setPayTime(LocalDateTime.now());
|
||||
mobileOrderMapper.updateById(wxOrder);
|
||||
|
||||
/* JkStore jkStore = jkStoreMapper.selectById(device.getStoreId());
|
||||
List<ChildStoreAccount> childStoreAccounts = childStoreAccountMapper.selectList(new LambdaQueryWrapper<ChildStoreAccount>().eq(ChildStoreAccount::getStoreId, jkStore.getId()));
|
||||
if (CollectionUtils.isEmpty(childStoreAccounts)){
|
||||
singleFz(wxOrder,jkStore);
|
||||
}else {
|
||||
multipleFz(wxOrder,jkStore,childStoreAccounts);
|
||||
}*/
|
||||
device.setDeviceId(wxOrder.getDeviceId());
|
||||
device.setStatus("1");
|
||||
device.setForcePay(2);
|
||||
deviceMapper.updateById(device);
|
||||
try {
|
||||
redisTemplate.opsForValue().set(UniConstant.DEVICE_ID+device.getDeviceId(),wxOrder.getMobileUserId(),24, TimeUnit.HOURS);
|
||||
}catch (Exception e){
|
||||
log.info("将理疗用户加入缓存发生异常,{}",e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void singleFz(MobileOrder wxOrder,JkStore jkStore){
|
||||
StoreAccount storeAccount = storeAccountMapper.selectOne(new LambdaQueryWrapper<StoreAccount>().eq(StoreAccount::getStoreId, jkStore.getId()));
|
||||
if (Objects.isNull(storeAccount)){
|
||||
StoreAccount account = new StoreAccount();
|
||||
account.setStoreId(jkStore.getId());
|
||||
BigDecimal amount = wxOrder.getTotalPrice().multiply(jkStore.getProfitSharingPercentage()).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN);
|
||||
log.info("门店ID->{},分得的金额是:{},=================",jkStore.getId(),amount);
|
||||
account.setBalance(amount);
|
||||
account.setAvailableBalance(amount);
|
||||
account.setFreezeBalance(BigDecimal.valueOf(0.00));
|
||||
storeAccountMapper.insert(account);
|
||||
}else {
|
||||
BigDecimal amount = wxOrder.getTotalPrice().multiply(jkStore.getProfitSharingPercentage()).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN);
|
||||
BigDecimal balance = storeAccount.getBalance().add(amount);
|
||||
BigDecimal avaBalance = storeAccount.getAvailableBalance().add(amount);
|
||||
log.info("门店ID->{},分得的金额是:{},+++++++++++++++++++",jkStore.getId(),amount);
|
||||
storeAccount.setBalance(balance);
|
||||
storeAccount.setAvailableBalance(avaBalance);
|
||||
storeAccountMapper.updateById(storeAccount);
|
||||
}
|
||||
}
|
||||
|
||||
private void multipleFz(MobileOrder wxOrder,JkStore jkStore,List<ChildStoreAccount> childStoreAccounts){
|
||||
StoreAccount storeAccount = storeAccountMapper.selectOne(new LambdaQueryWrapper<StoreAccount>().eq(StoreAccount::getStoreId, jkStore.getId()));
|
||||
if (Objects.isNull(storeAccount)){
|
||||
StoreAccount account = new StoreAccount();
|
||||
account.setStoreId(jkStore.getId());
|
||||
BigDecimal amount = wxOrder.getTotalPrice().multiply(jkStore.getProfitSharingPercentage()).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN);
|
||||
BigDecimal totalPercent = new BigDecimal("0.00");
|
||||
for (ChildStoreAccount childStoreAccount : childStoreAccounts) {
|
||||
totalPercent = totalPercent.add(childStoreAccount.getPercentage());
|
||||
}
|
||||
BigDecimal surPercent = new BigDecimal("100.00").subtract(totalPercent);
|
||||
BigDecimal masterStoreAmount = amount.multiply(surPercent).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN);
|
||||
log.info("多方分账,主门店门店ID->{},分得的金额是:{},",jkStore.getId(),masterStoreAmount);
|
||||
account.setBalance(masterStoreAmount);
|
||||
account.setAvailableBalance(masterStoreAmount);
|
||||
account.setFreezeBalance(BigDecimal.valueOf(0.00));
|
||||
storeAccountMapper.insert(account);
|
||||
for (ChildStoreAccount childStoreAccount : childStoreAccounts) {
|
||||
BigDecimal b = amount.multiply(childStoreAccount.getPercentage()).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN);
|
||||
childStoreAccount.setAccountBalance(childStoreAccount.getAccountBalance().add(b));
|
||||
}
|
||||
childStoreAccountMapper.updateById(childStoreAccounts);
|
||||
}else {
|
||||
BigDecimal amount = wxOrder.getTotalPrice().multiply(jkStore.getProfitSharingPercentage()).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN);
|
||||
BigDecimal totalPercent = new BigDecimal("0.00");
|
||||
for (ChildStoreAccount childStoreAccount : childStoreAccounts) {
|
||||
totalPercent = totalPercent.add(childStoreAccount.getPercentage());
|
||||
}
|
||||
BigDecimal surPercent = new BigDecimal("100.00").subtract(totalPercent);
|
||||
BigDecimal masterStoreAmount = amount.multiply(surPercent).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN);
|
||||
log.info("多方分账,主门店门店ID->{},分得的金额是:{},",jkStore.getId(),masterStoreAmount);
|
||||
storeAccount.setBalance(storeAccount.getBalance().add(masterStoreAmount));
|
||||
storeAccount.setAvailableBalance(storeAccount.getAvailableBalance().add(masterStoreAmount));
|
||||
storeAccountMapper.updateById(storeAccount);
|
||||
for (ChildStoreAccount childStoreAccount : childStoreAccounts) {
|
||||
BigDecimal b = amount.multiply(childStoreAccount.getPercentage()).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN);
|
||||
childStoreAccount.setAccountBalance(childStoreAccount.getAccountBalance().add(b));
|
||||
}
|
||||
childStoreAccountMapper.updateById(childStoreAccounts);
|
||||
}
|
||||
}
|
||||
|
||||
private void coursePay(MobileOrder wxOrder){
|
||||
wxOrder.setStatus(OrderStatus.paid.name());
|
||||
wxOrder.setPayTime(LocalDateTime.now());
|
||||
mobileOrderMapper.updateById(wxOrder);
|
||||
MobileAppUser wxUser = mobileAppUserMapper.selectOne(new LambdaQueryWrapper<MobileAppUser>().eq(MobileAppUser::getId, wxOrder.getMobileUserId()));
|
||||
MobileUserHaveCourse userHaveCourse = new MobileUserHaveCourse();
|
||||
userHaveCourse.setBuyTime(LocalDateTime.now());
|
||||
userHaveCourse.setMobileUserId(wxUser.getId());
|
||||
userHaveCourse.setCourseId(wxOrder.getCourseId());
|
||||
userHaveCourse.setStatus(1);
|
||||
mobileUserHaveCourseMapper.insert(userHaveCourse);
|
||||
}
|
||||
|
||||
public void vipRecharge(MobileOrder wxOrder){
|
||||
wxOrder.setStatus(OrderStatus.paid.name());
|
||||
wxOrder.setPayTime(LocalDateTime.now());
|
||||
mobileOrderMapper.updateById(wxOrder);
|
||||
WxVipRecharge vipRecharge = vipRechargeMapper.selectOne(new LambdaQueryWrapper<WxVipRecharge>().eq(WxVipRecharge::getOrderId, wxOrder.getOrderId()));
|
||||
vipRecharge.setPayStatus(1);
|
||||
vipRechargeMapper.updateById(vipRecharge);
|
||||
BigDecimal totalAmount = vipRecharge.getRechargeAmount().add(vipRecharge.getPresentAmount());
|
||||
MobileAppUserAccount wxUserAccount = mobileAppUserAccountMapper.selectOne(new LambdaQueryWrapper<MobileAppUserAccount>().eq(MobileAppUserAccount::getMobileUserId, wxOrder.getMobileUserId()));
|
||||
if (Objects.isNull(wxUserAccount)){
|
||||
MobileAppUserAccount account = new MobileAppUserAccount();
|
||||
account.setAccountBalance(totalAmount);
|
||||
account.setMobileUserId(wxOrder.getMobileUserId());
|
||||
mobileAppUserAccountMapper.insert(account);
|
||||
}else {
|
||||
wxUserAccount.setAccountBalance(wxUserAccount.getAccountBalance().add(totalAmount));
|
||||
mobileAppUserAccountMapper.updateById(wxUserAccount);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.entity.po.InventoryStatistics;
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.entity.vo.UniPage;
|
||||
import cn.unizk.mapper.InventoryStatisticsMapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2026/8/20 10:31
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet/inventory")
|
||||
public class InventoryController {
|
||||
|
||||
@Resource
|
||||
InventoryStatisticsMapper inventoryStatisticsMapper;
|
||||
|
||||
|
||||
@PostMapping("/getStatistics")
|
||||
public Page<InventoryStatistics> page(@RequestBody UniPage<InventoryStatistics> uniPage){
|
||||
Page<InventoryStatistics> page = (Page<InventoryStatistics>) uniPage.getPage();
|
||||
LambdaQueryWrapper<InventoryStatistics> queryWrapper = uniPage.buildQueryWrapper(query -> {
|
||||
LambdaQueryWrapper<InventoryStatistics> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(query.getType() != null,InventoryStatistics::getType,query.getType());
|
||||
wrapper.like(StringUtils.isNotBlank(query.getProductName()), InventoryStatistics::getProductName, query.getProductName());
|
||||
wrapper.orderByDesc(InventoryStatistics::getCreateTime);
|
||||
return wrapper;
|
||||
});
|
||||
return inventoryStatisticsMapper.selectPage(page,queryWrapper);
|
||||
}
|
||||
|
||||
@PostMapping("/addStatistics")
|
||||
public ResultData addStatistics(@RequestBody InventoryStatistics statistics){
|
||||
statistics.setRemainingQuantity(statistics.getQuantityInStock() - statistics.getOutboundQuantity());
|
||||
statistics.setCreateTime(LocalDate.now());
|
||||
inventoryStatisticsMapper.insert(statistics);
|
||||
return ResultData.success();
|
||||
}
|
||||
|
||||
@PostMapping("/updateStatistics")
|
||||
public ResultData updateStatistics(@RequestBody InventoryStatistics statistics){
|
||||
statistics.setRemainingQuantity(statistics.getQuantityInStock() - statistics.getOutboundQuantity());
|
||||
inventoryStatisticsMapper.updateById(statistics);
|
||||
return ResultData.success();
|
||||
}
|
||||
|
||||
@PostMapping("/deleteStatistics")
|
||||
public ResultData deleteStatistics(@RequestParam("id") Integer id){
|
||||
inventoryStatisticsMapper.deleteById(id);
|
||||
return ResultData.success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.entity.po.JkProduct;
|
||||
import cn.unizk.entity.po.ProductCarousel;
|
||||
import cn.unizk.entity.vo.JkProductVO;
|
||||
import cn.unizk.entity.vo.UniPage;
|
||||
import cn.unizk.service.JkProductService;
|
||||
import cn.unizk.service.ProductCarouselService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/8/21 18:57
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet/product")
|
||||
public class JkProductController {
|
||||
|
||||
@Resource
|
||||
private JkProductService productService;
|
||||
@Resource
|
||||
private ProductCarouselService carouselService;
|
||||
|
||||
@GetMapping("/list")
|
||||
public Page<JkProduct> list(UniPage uniPage, @RequestParam(value = "dictValue",required = false) String dictValue,
|
||||
@RequestParam(value = "product",required = false) String product,
|
||||
@RequestParam(value = "priceSort",required = false) String priceSort,
|
||||
@RequestParam(value = "saleSort",required = false) String saleSort) {
|
||||
Page<JkProduct> page = new Page<>();
|
||||
page.setCurrent(uniPage.getCurrentPage());
|
||||
page.setSize(uniPage.getPageSize());
|
||||
boolean priceS = !"desc".equals(priceSort);
|
||||
boolean saleS = !"desc".equals(saleSort);
|
||||
return productService.page(page, new LambdaQueryWrapper<JkProduct>()
|
||||
.eq(JkProduct::getProductStatus, "上架")
|
||||
.eq(StringUtils.isNotBlank(dictValue),JkProduct::getProductType, dictValue)
|
||||
.like(StringUtils.isNotBlank(product),JkProduct::getProductName,product)
|
||||
.gt(JkProduct::getProductStock, 0)
|
||||
.orderBy(StringUtils.isNotBlank(priceSort),priceS,JkProduct::getProductPrice)
|
||||
.orderBy(StringUtils.isNotBlank(saleSort),saleS,JkProduct::getSales));
|
||||
}
|
||||
|
||||
@GetMapping("/getExquisite")
|
||||
public Page<JkProduct> listExquisite(UniPage uniPage){
|
||||
Page<JkProduct> page = uniPage.getPage();
|
||||
return productService.page(page,new LambdaQueryWrapper<JkProduct>().eq(JkProduct::getExquisite,"true"));
|
||||
}
|
||||
|
||||
@GetMapping("/carousel")
|
||||
public List<ProductCarousel> getCarousel(){
|
||||
return carouselService.list(new LambdaQueryWrapper<ProductCarousel>()
|
||||
.eq(ProductCarousel::getType,"outer"));
|
||||
}
|
||||
|
||||
@GetMapping("/byId")
|
||||
public JkProductVO byId(@RequestParam("productId") Integer productId){
|
||||
JkProduct jkProduct = productService.getById(productId);
|
||||
if (Objects.isNull(jkProduct)){
|
||||
return new JkProductVO();
|
||||
}
|
||||
List<ProductCarousel> list = carouselService.list(new LambdaQueryWrapper<ProductCarousel>().eq(ProductCarousel::getProductId, productId));
|
||||
JkProductVO jkProductVO = new JkProductVO();
|
||||
BeanUtils.copyProperties(jkProduct,jkProductVO);
|
||||
jkProductVO.setProductCarousels(list);
|
||||
return jkProductVO;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.entity.po.JkStore;
|
||||
import cn.unizk.entity.po.SysDict;
|
||||
import cn.unizk.entity.vo.JkStoreReqVO;
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.entity.vo.UniPage;
|
||||
import cn.unizk.service.JkStoreService;
|
||||
import cn.unizk.service.SysDictService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/8/19 11:28
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RequestMapping("/applet")
|
||||
@Slf4j
|
||||
@RestController
|
||||
public class JkStoreController {
|
||||
|
||||
@Resource
|
||||
private JkStoreService jkStoreService;
|
||||
@Resource
|
||||
private SysDictService sysDictService;
|
||||
|
||||
|
||||
@PostMapping("/getStores")
|
||||
public IPage<JkStore> getStores(@RequestBody UniPage<JkStore> uniPage){
|
||||
Page<JkStore> page = new Page<>();
|
||||
page.setCurrent(uniPage.getCurrentPage());
|
||||
page.setSize(uniPage.getPageSize());
|
||||
LambdaQueryWrapper<JkStore> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(JkStore::getStatus, "营业");
|
||||
JkStore jkStore = uniPage.getQueryBody();
|
||||
if (jkStore != null && StringUtils.isNotBlank(jkStore.getType())){
|
||||
wrapper.eq(JkStore::getType,jkStore.getType());
|
||||
}
|
||||
return jkStoreService.getBaseMapper().selectPage(page, wrapper);
|
||||
}
|
||||
|
||||
@GetMapping("/getStoreById")
|
||||
public JkStore getStoreById(@RequestParam("storeId") Integer storeId){
|
||||
return jkStoreService.getById(storeId);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param vo
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/nearest")
|
||||
public JkStore nearest(@RequestBody JkStoreReqVO vo){
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/getScanPayPrice")
|
||||
public ResultData getScanPayPrice(@RequestParam(value = "storeId",required = false) Integer storeId,@RequestParam(value = "deviceId",required = false) String deviceId){
|
||||
log.info("storeId={},deviceId={}",storeId,deviceId);
|
||||
SysDict sysDict = sysDictService.getById(26);
|
||||
ResultData<String> data = new ResultData<>();
|
||||
data.setCode(200);
|
||||
data.setData(sysDict.getDictValue());
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.entity.po.SysDict;
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.service.SysDictService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2026/4/30 11:02
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet/member")
|
||||
public class MemberController {
|
||||
|
||||
@Resource
|
||||
private SysDictService sysDictService;
|
||||
|
||||
@GetMapping("/getCost")
|
||||
public ResultData getCost(){
|
||||
SysDict activeMember = sysDictService.getOne(new LambdaQueryWrapper<SysDict>().eq(SysDict::getDictType, "active_member"));
|
||||
ResultData<String> data = new ResultData<>();
|
||||
if (activeMember == null){
|
||||
data.setData("888.00");
|
||||
}else {
|
||||
data.setData(activeMember.getDictValue());
|
||||
}
|
||||
data.setCode(200);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.entity.po.Joint;
|
||||
import cn.unizk.entity.po.PhysioThirteenArea;
|
||||
import cn.unizk.entity.vo.JointVO;
|
||||
import cn.unizk.mapper.JointMapper;
|
||||
import cn.unizk.mapper.PhysioThirteenAreaMapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2026/9/2 16:43
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet/physioArea")
|
||||
public class Physio13AreaController {
|
||||
|
||||
@Resource
|
||||
private PhysioThirteenAreaMapper physioThirteenAreaMapper;
|
||||
@Resource
|
||||
private JointMapper jointMapper;
|
||||
|
||||
|
||||
|
||||
/* @GetMapping("/list")
|
||||
public List<PhysioThirteenArea> list(@RequestParam("type") Integer type){
|
||||
List<PhysioThirteenArea> physioThirteenAreas = physioThirteenAreaMapper.selectList(new LambdaQueryWrapper<PhysioThirteenArea>().eq(PhysioThirteenArea::getType,type));
|
||||
physioThirteenAreas.forEach( area -> {
|
||||
area.setCause(null);
|
||||
area.setImproveMethod(null);
|
||||
area.setExplanation(null);
|
||||
area.setPictureUrl(null);
|
||||
});
|
||||
return physioThirteenAreas;
|
||||
}*/
|
||||
|
||||
@GetMapping("/list")
|
||||
public List<JointVO> list() {
|
||||
return jointMapper.selectJointVOList();
|
||||
}
|
||||
|
||||
@GetMapping("/getOneById")
|
||||
public PhysioThirteenArea area(@RequestParam("id") Integer id) {
|
||||
return physioThirteenAreaMapper.selectById(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.unizk.entity.po.*;
|
||||
import cn.unizk.entity.vo.*;
|
||||
import cn.unizk.exception.ServiceException;
|
||||
import cn.unizk.mapper.*;
|
||||
import cn.unizk.utils.BeanCopyUtils;
|
||||
import cn.unizk.utils.JkSecurityUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2026/5/18 17:18
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet/appointment")
|
||||
@Slf4j
|
||||
public class PhysioAppointmentController {
|
||||
|
||||
@Resource
|
||||
private DailySchedulesMapper dailySchedulesMapper;
|
||||
@Resource
|
||||
private MobileUserMedicalVisitInfoMapper mobileUserMedicalVisitInfoMapper;
|
||||
@Resource
|
||||
private MobileAppointmentsMapper mobileAppointmentsMapper;
|
||||
@Resource
|
||||
private JkPhysioMapper jkPhysioMapper;
|
||||
@Resource
|
||||
private JkStoreMapper storeMapper;
|
||||
@Resource
|
||||
private TimeSlotsMapper timeSlotsMapper;
|
||||
@Resource
|
||||
private MobileAppUserMapper mobileAppUserMapper;
|
||||
|
||||
|
||||
@PostMapping("/getPhysioAppointment")
|
||||
public List<DailySchedulesVO> getPhysioAppointment(@RequestBody AppointmentVO vo){
|
||||
return dailySchedulesMapper.getCanAppointment(vo.getPhysioId(),vo.getDateTime());
|
||||
}
|
||||
|
||||
@PostMapping("/appointment")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResultData appointment(HttpServletRequest request,@RequestBody AppointmentVO2 vo2){
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
DailySchedules dailySchedules = dailySchedulesMapper.selectById(vo2.getDailyScheduleId());
|
||||
if (Objects.isNull(dailySchedules)){
|
||||
throw new ServiceException("无法预约,请稍后重试");
|
||||
}
|
||||
if (dailySchedules.getMaxBookings() - dailySchedules.getBookedCount() < 1){
|
||||
if ("available".equals(dailySchedules.getStatus())){
|
||||
dailySchedules.setStatus("full");
|
||||
dailySchedulesMapper.updateById(dailySchedules);
|
||||
}
|
||||
throw new ServiceException("该时间段已满号,请预约其他时间");
|
||||
}
|
||||
MobileUserMedicalVisitInfo userMedicalVisitInfo = mobileUserMedicalVisitInfoMapper.selectById(vo2.getMedicalVisitId());
|
||||
MobileAppointments appointments = new MobileAppointments();
|
||||
String appointment_no = IdUtil.getSnowflakeNextIdStr();
|
||||
appointments.setAppointmentNo(appointment_no);
|
||||
appointments.setMobileUserId(currentUser.getId());
|
||||
appointments.setDailyScheduleId(vo2.getDailyScheduleId());
|
||||
appointments.setVisitDate(dailySchedules.getScheduleDate());
|
||||
appointments.setTimeSlotCode(vo2.getTimeSlotCode());
|
||||
appointments.setPayAmount(vo2.getPayAmount());
|
||||
appointments.setPayStatus(1);
|
||||
appointments.setPhysioId(dailySchedules.getPhysioId());
|
||||
appointments.setPatientName(userMedicalVisitInfo.getName());
|
||||
appointments.setPatientPhone(userMedicalVisitInfo.getPhoneNumber());
|
||||
appointments.setStatus("confirmed");
|
||||
appointments.setRemark(vo2.getRemark());
|
||||
mobileAppointmentsMapper.insert(appointments);
|
||||
if (dailySchedules.getMaxBookings() - dailySchedules.getBookedCount() < 2){
|
||||
dailySchedules.setStatus("full");
|
||||
}
|
||||
dailySchedules.setBookedCount(dailySchedules.getBookedCount() + 1);
|
||||
dailySchedulesMapper.updateById(dailySchedules);
|
||||
try {
|
||||
JkPhysio jkPhysio = jkPhysioMapper.selectById(appointments.getPhysioId());
|
||||
MobileAppUser user = mobileAppUserMapper.selectById(currentUser.getId());
|
||||
if (user.getFirstStoreId() == null && user.getFirstPhysioId() == null){
|
||||
user.setId(currentUser.getId());
|
||||
user.setFirstPhysioId(jkPhysio.getId());
|
||||
user.setFirstStoreId(jkPhysio.getStoreId());
|
||||
mobileAppUserMapper.updateById(user);
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("首次门店首次技师绑定失败:",e);
|
||||
}
|
||||
return ResultData.success();
|
||||
}
|
||||
|
||||
@PostMapping("/addOrUpdateMedicalVisitInfo")
|
||||
public ResultData addMedicalVisitInfo(HttpServletRequest request, @RequestBody MobileUserMedicalVisitInfo info){
|
||||
if (info.getId() == null){
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
List<MobileUserMedicalVisitInfo> wxUserMedicalVisitInfos = mobileUserMedicalVisitInfoMapper.selectList(new LambdaQueryWrapper<MobileUserMedicalVisitInfo>().eq(MobileUserMedicalVisitInfo::getMobileUserId, currentUser
|
||||
.getId()));
|
||||
if (wxUserMedicalVisitInfos.size() >= 3){
|
||||
throw new ServiceException("最多只能添加3张就诊卡");
|
||||
}
|
||||
info.setMobileUserId(currentUser.getId());
|
||||
info.setCreateTime(LocalDateTime.now());
|
||||
mobileUserMedicalVisitInfoMapper.insert(info);
|
||||
}else {
|
||||
if (info.getItsDefault() == 1){
|
||||
mobileUserMedicalVisitInfoMapper.update(new LambdaUpdateWrapper<MobileUserMedicalVisitInfo>().set(MobileUserMedicalVisitInfo::getItsDefault,0));
|
||||
}
|
||||
mobileUserMedicalVisitInfoMapper.updateById(info);
|
||||
}
|
||||
return ResultData.success();
|
||||
}
|
||||
|
||||
@GetMapping("/getDefaultVisitInfo")
|
||||
public ResultData getDefVisitInfo(HttpServletRequest request){
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
MobileUserMedicalVisitInfo wxUserMedicalVisitInfo = mobileUserMedicalVisitInfoMapper.selectOne(new LambdaQueryWrapper<MobileUserMedicalVisitInfo>().eq(MobileUserMedicalVisitInfo::getMobileUserId, currentUser.getId()).eq(MobileUserMedicalVisitInfo::getItsDefault,1));
|
||||
ResultData<MobileUserMedicalVisitInfo> resultData = new ResultData<>();
|
||||
if (Objects.nonNull(wxUserMedicalVisitInfo)){
|
||||
resultData.setData(wxUserMedicalVisitInfo);
|
||||
}else {
|
||||
MobileUserMedicalVisitInfo visitInfo = mobileUserMedicalVisitInfoMapper.selectLatest(currentUser.getId());
|
||||
resultData.setData(visitInfo);
|
||||
}
|
||||
resultData.setCode(200);
|
||||
return resultData;
|
||||
}
|
||||
|
||||
@DeleteMapping("/deleteVisitInfo")
|
||||
public ResultData deleteVisitInfo(@RequestParam("id") Integer id){
|
||||
mobileUserMedicalVisitInfoMapper.deleteById(id);
|
||||
return ResultData.success();
|
||||
}
|
||||
|
||||
@GetMapping("/getVisitInfo")
|
||||
public ResultData getVisitInfo(HttpServletRequest request){
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
List<MobileUserMedicalVisitInfo> wxUserMedicalVisitInfos = mobileUserMedicalVisitInfoMapper.selectList(new LambdaQueryWrapper<MobileUserMedicalVisitInfo>().eq(MobileUserMedicalVisitInfo::getMobileUserId, currentUser.getId()));
|
||||
return ResultData.success(wxUserMedicalVisitInfos);
|
||||
}
|
||||
|
||||
@GetMapping("/getAvailableSituation")
|
||||
public List<AppointmentVO3> getAv(@RequestParam(value = "physioId",required = false) Integer physioId,@RequestParam("storeId") Integer storeId){
|
||||
List<JkPhysio> jkPhysios = jkPhysioMapper.selectList(new LambdaQueryWrapper<JkPhysio>().eq(JkPhysio::getStoreId, storeId));
|
||||
List<Integer> physioIds = jkPhysios.stream().map(JkPhysio::getId).collect(Collectors.toList());
|
||||
List<AppointmentVO3> appointmentVO3s = dailySchedulesMapper.selectMedicalyoumeihao(physioId,physioIds);
|
||||
for (AppointmentVO3 appointmentVO3 : appointmentVO3s) {
|
||||
if (appointmentVO3.getScheduleDate().equals(LocalDate.now())){
|
||||
LocalTime time = LocalTime.now();
|
||||
TimeSlots timeSlots = timeSlotsMapper.selectLastOne();
|
||||
if (time.isAfter(timeSlots.getStartTime())){
|
||||
appointmentVO3.setHasAvailable("无号");
|
||||
appointmentVO3.setAvailableSlotsCount(0);
|
||||
appointmentVO3.setTotalAvailableCount(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return appointmentVO3s;
|
||||
}
|
||||
|
||||
@PostMapping("/getAllPhysioActive")
|
||||
public List<AppointmentVO4> getAll(@RequestBody DailySchedulesVO dailySchedules){
|
||||
if (Objects.isNull(dailySchedules) || dailySchedules.getScheduleDate() == null){
|
||||
throw new ServiceException("scheduleDate cannot null");
|
||||
}
|
||||
if (dailySchedules.getStoreId() == null){
|
||||
throw new ServiceException("storeId cannot null");
|
||||
}
|
||||
List<JkPhysio> jkPhysios = jkPhysioMapper.selectList(new LambdaQueryWrapper<JkPhysio>().eq(JkPhysio::getStoreId, dailySchedules.getStoreId()));
|
||||
List<Integer> physioIds = jkPhysios.stream().map(JkPhysio::getId).collect(Collectors.toList());
|
||||
return dailySchedulesMapper.selectYoumeihaoByDate(dailySchedules.getScheduleDate(),physioIds);
|
||||
}
|
||||
|
||||
@GetMapping("/getAppointments")
|
||||
public Page<AppointmentsVO5> getAppointments(HttpServletRequest request,@RequestParam(value = "currentPage",required = false,defaultValue = "1") Integer currentPage,
|
||||
@RequestParam(value = "pageSize",required = false,defaultValue = "10") Integer pageSize){
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (Objects.isNull(currentUser)){
|
||||
throw new ServiceException(401,"请重新登录");
|
||||
}
|
||||
Page<MobileAppointments> page = new Page<>(currentPage,pageSize);
|
||||
Page<MobileAppointments> appointmentsPage = mobileAppointmentsMapper.selectPage(page, new LambdaQueryWrapper<MobileAppointments>().eq(MobileAppointments::getMobileUserId, currentUser.getId())
|
||||
.orderByDesc(MobileAppointments::getCreatedAt));
|
||||
List<MobileAppointments> appointments = appointmentsPage.getRecords();
|
||||
if (CollectionUtils.isEmpty(appointments)){
|
||||
return new Page<>();
|
||||
}
|
||||
Collection<AppointmentsVO5> appointmentsVO5s = BeanCopyUtils.copyArrays(appointments, AppointmentsVO5::new);
|
||||
for (AppointmentsVO5 vo5 : appointmentsVO5s) {
|
||||
JkPhysio jkPhysio = jkPhysioMapper.selectById(vo5.getPhysioId());
|
||||
JkStore jkStore = storeMapper.selectById(jkPhysio.getStoreId());
|
||||
vo5.setPhysioName(jkPhysio.getPhysioName());
|
||||
vo5.setStoreName(jkStore.getStoreName());
|
||||
vo5.setStoreAddress(jkStore.getAddress());
|
||||
TimeSlots timeSlots = timeSlotsMapper.selectOne(new LambdaQueryWrapper<TimeSlots>().eq(TimeSlots::getSlotCode, vo5.getTimeSlotCode()));
|
||||
vo5.setTimeSlots(timeSlots);
|
||||
}
|
||||
Page<AppointmentsVO5> vo5Page = new Page<>();
|
||||
vo5Page.setTotal(page.getTotal());
|
||||
vo5Page.setRecords((List<AppointmentsVO5>) appointmentsVO5s);
|
||||
vo5Page.setCurrent(page.getCurrent());
|
||||
vo5Page.setSize(page.getSize());
|
||||
return vo5Page;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.entity.po.*;
|
||||
import cn.unizk.entity.vo.*;
|
||||
import cn.unizk.exception.ServiceException;
|
||||
import cn.unizk.huifupay.vo.ReportTypeVO;
|
||||
import cn.unizk.mapper.*;
|
||||
import cn.unizk.service.JkPhysioService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/8/21 16:58
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet")
|
||||
public class PhysioController {
|
||||
|
||||
@Resource
|
||||
private JkPhysioService physioService;
|
||||
@Resource
|
||||
private ReportTemplateMapper reportTemplateMapper;
|
||||
@Resource
|
||||
private SubHealthDietaryRegulationMapper regulationMapper;
|
||||
@Resource
|
||||
private PhysioExamMapper examMapper;
|
||||
@Resource
|
||||
private ExamScoreMapper scoreMapper;
|
||||
@Resource
|
||||
private MobileOrderMapper mobileOrderMapper;
|
||||
@Resource
|
||||
private MobileAppUserMapper mobileAppUserMapper;
|
||||
@Resource
|
||||
private TreatParameterMapper treatParameterMapper;
|
||||
|
||||
@GetMapping("/getPhysios")
|
||||
public IPage<JkPhysio> getPhysios(@RequestParam("storeId") Integer storeId, UniPage uniPage) {
|
||||
Page<JkPhysio> page = new Page<>();
|
||||
page.setCurrent(uniPage.getCurrentPage());
|
||||
return physioService.getBaseMapper().selectPage(page, new LambdaQueryWrapper<JkPhysio>()
|
||||
.eq(JkPhysio::getStoreId, storeId).eq(JkPhysio::getAudit, 1).eq(JkPhysio::getStatus, "启用"));
|
||||
}
|
||||
|
||||
@PostMapping("/getReportById/{id}")
|
||||
public ReportTemplateVO getReportById(@PathVariable("id") Integer id, @RequestBody ReportTypeVO vo) {
|
||||
TreatParameter treatParameter = treatParameterMapper.selectById(id);
|
||||
String text = "<p>尊敬的客户您好!经诊断您可能患有"+treatParameter.getSymptomsName()+",非常理解您正承受着膝关节疼痛带来的不适与困扰," +
|
||||
"考虑到您目前关节疼痛症状较为严重,为了能精准对症缓解您的病痛," +
|
||||
"我们现将您的相关情况转接至上一级专业接待机构。那边配备经验更丰富的护理人员与配" +
|
||||
"套诊疗资源,会为您提供更全面、专业且细致优质的诊疗服务,请您稍作等候配合转接。</p>";
|
||||
ReportTemplateVO templateVO = new ReportTemplateVO();
|
||||
if (vo.getResult() == 2) {
|
||||
templateVO.setType(vo.getResult());
|
||||
templateVO.setId(randomNum());
|
||||
templateVO.setText(text);
|
||||
return templateVO;
|
||||
}
|
||||
if (vo.getResult() == 1) {
|
||||
ReportTemplate reportTemplate = reportTemplateMapper.selectById(id);
|
||||
BeanUtils.copyProperties(reportTemplate, templateVO);
|
||||
templateVO.setType(vo.getResult());
|
||||
return templateVO;
|
||||
}
|
||||
throw new ServiceException("系统异常");
|
||||
}
|
||||
|
||||
private Integer randomNum() {
|
||||
List<Integer> numbers = new ArrayList<>();
|
||||
for (int i = 1; i <= 13; i++) {
|
||||
numbers.add(i);
|
||||
}
|
||||
|
||||
// 2. 打乱列表顺序
|
||||
Collections.shuffle(numbers);
|
||||
return numbers.get(0);
|
||||
}
|
||||
|
||||
@GetMapping("/getRegulation")
|
||||
public List<SubHealthDietaryRegulation> getRegulation(@RequestParam(value = "name", required = false) String name) {
|
||||
return regulationMapper.selectList(new LambdaQueryWrapper<SubHealthDietaryRegulation>()
|
||||
.like(StringUtils.isNotBlank(name), SubHealthDietaryRegulation::getSymptomDescription, name));
|
||||
}
|
||||
|
||||
@PostMapping("/getFoodTherapy")
|
||||
public ResultData getFoodTherapy(@RequestBody RegulationVO vo) {
|
||||
if (Objects.isNull(vo) || CollectionUtils.isEmpty(vo.getNumbers())) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
ResultData<String> data = new ResultData<>();
|
||||
data.setCode(200);
|
||||
String s = "根据您的症状以及过往病史的描述,您可能由于{reason}的原因引起的,并且身体可能缺乏{n},建议您做一下{z},更精准地查出病因。日常食疗建议多补充{f}。{s}";
|
||||
List<String> numbers = vo.getNumbers();
|
||||
if (numbers.size() == 1) {
|
||||
SubHealthDietaryRegulation regulation = regulationMapper.selectById(vo.getNumbers().get(0));
|
||||
String f = regulation.getFruitSuggestion() + ";" + regulation.getVegetableSuggestion();
|
||||
String result = s.replace("{reason}", regulation.getCommonReasons()).replace("{n}", regulation.getLackNutrients()).replace("{z}", regulation.getDiagnosticReference())
|
||||
.replace("{f}", f).replace("{s}", regulation.getDetectAndAdd());
|
||||
data.setData(result);
|
||||
} else {
|
||||
List<SubHealthDietaryRegulation> regulations = regulationMapper.selectByIds(numbers);
|
||||
List<String> reasons = new ArrayList<>();
|
||||
List<String> zd = new ArrayList<>();
|
||||
List<String> ns = new ArrayList<>();
|
||||
List<String> sgs = new ArrayList<>();
|
||||
List<String> vgs = new ArrayList<>();
|
||||
List<String> jcbc = new ArrayList<>();
|
||||
for (SubHealthDietaryRegulation regulation : regulations) {
|
||||
String commonReasons = regulation.getCommonReasons();
|
||||
String diagnosticReference = regulation.getDiagnosticReference();
|
||||
String vegetableSuggestion = regulation.getVegetableSuggestion();
|
||||
String fruitSuggestion = regulation.getFruitSuggestion();
|
||||
@NotBlank(message = "lackNutrients cannot be empty") String lackNutrients = regulation.getLackNutrients();
|
||||
hb(commonReasons, reasons);
|
||||
hb(diagnosticReference, zd);
|
||||
hb(vegetableSuggestion, vgs);
|
||||
hb(fruitSuggestion, sgs);
|
||||
hb(lackNutrients, ns);
|
||||
@NotBlank(message = "detectAndAdd cannot be empty") String detectAndAdd = regulation.getDetectAndAdd();
|
||||
String replace = detectAndAdd.replace("检测:", "").replace("补充:", "");
|
||||
jcbc.add(replace);
|
||||
}
|
||||
String r = String.join("、", reasons);
|
||||
String n = String.join("、", ns);
|
||||
String z = String.join("、", zd);
|
||||
sgs.addAll(vgs);
|
||||
String f = String.join("、", sgs);
|
||||
String jb = "微量元素检测与补充:" + String.join(";", jcbc);
|
||||
String replace = s.replace("{reason}", r).replace("{n}", n).replace("{z}", z).replace("{f}", f).replace("{s}", jb);
|
||||
data.setData(replace);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private void hb(String s, List<String> list) {
|
||||
if (s.contains("、")) {
|
||||
String[] split = s.split("、");
|
||||
List<String> item = new ArrayList<>();
|
||||
for (String t : split) {
|
||||
if (!list.contains(t)) {
|
||||
item.add(t);
|
||||
}
|
||||
}
|
||||
list.addAll(item);
|
||||
} else {
|
||||
if (!list.contains(s)) {
|
||||
list.add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/physioExams")
|
||||
public List<PhysioExamVO> physioExams(@RequestParam("subject") Integer subject) {
|
||||
List<PhysioExam> physioExams = examMapper.selectList(new LambdaQueryWrapper<PhysioExam>()
|
||||
.eq(PhysioExam::getSubject, subject));
|
||||
if (CollectionUtils.isEmpty(physioExams)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<PhysioExamVO> vos = new ArrayList<>();
|
||||
for (PhysioExam physioExam : physioExams) {
|
||||
PhysioExamVO vo = new PhysioExamVO();
|
||||
vo.setId(physioExam.getId());
|
||||
vo.setType(physioExam.getType());
|
||||
vo.setAnswers(Arrays.asList(physioExam.getAnswer().split("&")));
|
||||
vo.setTitle(physioExam.getTitle());
|
||||
vos.add(vo);
|
||||
}
|
||||
return vos;
|
||||
}
|
||||
|
||||
@PostMapping("/gradeExam")
|
||||
public Integer gradeExam(@RequestBody List<GradeExamVO> examVOS) {
|
||||
if (CollectionUtils.isEmpty(examVOS)) {
|
||||
return 0;
|
||||
}
|
||||
List<Integer> collect = examVOS.stream().map(GradeExamVO::getExamId)
|
||||
.collect(Collectors.toList());
|
||||
List<PhysioExam> physioExams = examMapper.selectByIds(collect);
|
||||
Map<Integer, PhysioExam> map = physioExams.stream()
|
||||
.collect(Collectors.toMap(PhysioExam::getId, Function.identity()));
|
||||
List<Integer> list = new ArrayList<>();
|
||||
for (GradeExamVO examVO : examVOS) {
|
||||
if (StringUtils.isBlank(examVO.getAnswer())) {
|
||||
continue;
|
||||
}
|
||||
if (map.get(examVO.getExamId()).getCorrectAnswer().equals(examVO.getAnswer())) {
|
||||
list.add(map.get(examVO.getExamId()).getType());
|
||||
}
|
||||
}
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
return 0;
|
||||
}
|
||||
List<Integer> distInt = list.stream().distinct().collect(Collectors.toList());
|
||||
// examScoreMapper.selectByIds(distInt),查出examScore,再统计分数。
|
||||
List<ExamScore> scoreList = scoreMapper.selectByIds(distInt);
|
||||
Map<Integer, Integer> scoreMap = scoreList.stream().collect(Collectors.toMap(ExamScore::getId, ExamScore::getScore));
|
||||
int totalScore = 0;
|
||||
for (Integer integer : list) {
|
||||
Integer score = scoreMap.get(integer);
|
||||
totalScore += score;
|
||||
}
|
||||
return totalScore;
|
||||
}
|
||||
|
||||
@GetMapping("/getChuFang")
|
||||
public ResultData<List<TreatParameter>> getChuFang(@RequestParam("physioId") Integer physioId){
|
||||
List<MobileOrder> wxOrders = mobileOrderMapper.selectList(new LambdaQueryWrapper<MobileOrder>().eq(MobileOrder::getPhysioId, physioId));
|
||||
if (CollectionUtils.isEmpty(wxOrders)){
|
||||
return ResultData.success();
|
||||
}
|
||||
List<Integer> openids = wxOrders.stream().map(MobileOrder::getMobileUserId).distinct().collect(Collectors.toList());
|
||||
List<MobileAppUser> wxUsers = mobileAppUserMapper.selectList(new LambdaQueryWrapper<MobileAppUser>().in(MobileAppUser::getId, openids));
|
||||
if (CollectionUtils.isEmpty(wxUsers)){
|
||||
return ResultData.success();
|
||||
}
|
||||
List<String> collect = wxUsers.stream().filter(u -> StringUtils.isNotBlank(u.getPainNumber())).map(MobileAppUser::getPainNumber).collect(Collectors.toList());
|
||||
List<TreatParameter> list = new ArrayList<>();
|
||||
for (String s : collect) {
|
||||
if (s.contains(",")){
|
||||
String[] split = s.split(",");
|
||||
for (String p : split) {
|
||||
TreatParameter treatParameter = treatParameterMapper.selectById(p);
|
||||
list.add(treatParameter);
|
||||
}
|
||||
}else {
|
||||
TreatParameter treatParameter = treatParameterMapper.selectById(s);
|
||||
list.add(treatParameter);
|
||||
}
|
||||
}
|
||||
ResultData<List<TreatParameter>> data = new ResultData<>();
|
||||
data.setCode(200);
|
||||
data.setData(list);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,441 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.entity.dto.MajorJointsDTO;
|
||||
import cn.unizk.entity.po.DiaRecord;
|
||||
import cn.unizk.entity.po.MobileAppUser;
|
||||
import cn.unizk.entity.vo.EightMajorJointsVO;
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.entity.vo.SpeakVO;
|
||||
import cn.unizk.exception.ServiceException;
|
||||
import cn.unizk.mapper.DiaRecordMapper;
|
||||
import cn.unizk.mapper.MobileAppUserMapper;
|
||||
import cn.unizk.utils.JkSecurityUtil;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2026/8/10 10:56
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet/rating")
|
||||
public class RatingController {
|
||||
|
||||
@Resource
|
||||
private MobileAppUserMapper mobileAppUserMapper;
|
||||
@Resource
|
||||
private DiaRecordMapper diaRecordMapper;
|
||||
|
||||
private static final Map<Integer, MajorJointsDTO> JOINTS_DTO_MAP1;
|
||||
private static final Map<Integer, MajorJointsDTO> JOINTS_DTO_MAP2;
|
||||
private static final Map<Integer,MajorJointsDTO> WAN_ZHOU_MAP;
|
||||
private static final Map<Integer,MajorJointsDTO> YAO_MAP;
|
||||
|
||||
|
||||
|
||||
static {
|
||||
JOINTS_DTO_MAP1 = new HashMap<>();
|
||||
MajorJointsDTO dto = new MajorJointsDTO();
|
||||
Map<Integer,String> questionMap1 = new HashMap<>();
|
||||
questionMap1.put(1,"1.肩膀前面锁骨下面凹窝处会不会闷痛、按压疼?");
|
||||
questionMap1.put(2,"2.抬手向前举胳膊、抱重物时,肩膀前侧扯着刺痛吗?");
|
||||
questionMap1.put(3,"3.胳膊向后背、穿脱套头衫时,肩膀前面牵拉难受吗?");
|
||||
dto.setTitle("肩前侧锁骨下方");
|
||||
dto.setReport("肩膀前侧肌腱劳损、肩关节前侧滑膜发炎,长期抬手干活、抱重物诱发");
|
||||
dto.setMap(questionMap1);
|
||||
JOINTS_DTO_MAP1.put(1,dto);
|
||||
MajorJointsDTO dto2 = new MajorJointsDTO();
|
||||
dto2.setTitle("肩顶端凸起骨头");
|
||||
dto2.setReport("肩峰滑囊炎、肩袖上方肌腱磨损,长期抬手、侧睡压肩引发");
|
||||
Map<Integer,String> questionMap2 = new HashMap<>();
|
||||
questionMap2.put(1,"1.肩膀最顶端那块骨头,一按就酸胀疼吗?");
|
||||
questionMap2.put(2,"2.胳膊侧平举、举过头顶时,肩膀顶刺痛卡住吗?");
|
||||
questionMap2.put(3,"3.侧卧压着肩膀睡觉,第二天肩顶疼痛感明显加重吗?");
|
||||
dto2.setMap(questionMap2);
|
||||
JOINTS_DTO_MAP1.put(2,dto2);
|
||||
MajorJointsDTO dto3 = new MajorJointsDTO();
|
||||
dto3.setTitle("肩膀外侧三角肌整块");
|
||||
dto3.setReport("肩部外侧肌肉劳损、肩袖外侧轻微损伤,单侧负重、长期外展发力导致");
|
||||
Map<Integer,String> questionMap3 = new HashMap<>();
|
||||
questionMap3.put(1,"1.肩膀外侧一大块肌肉经常发酸发沉吗?");
|
||||
questionMap3.put(2,"2.向外抬胳膊、拎手提东西,外侧牵拉酸痛吗?");
|
||||
questionMap3.put(3,"运动干活后,肩膀外侧发胀,抬胳膊无力吗?");
|
||||
dto3.setMap(questionMap3);
|
||||
JOINTS_DTO_MAP1.put(3,dto3);
|
||||
|
||||
MajorJointsDTO dto4 = new MajorJointsDTO();
|
||||
dto4.setTitle("肩膀后侧肩胛骨");
|
||||
dto4.setReport("肩后筋膜僵硬、肩关节后侧韧带劳损,含胸驼背、后背内旋动作诱发");
|
||||
Map<Integer,String> questionMap4 = new HashMap<>();
|
||||
questionMap4.put(1,"后背肩膀骨头边缘隐隐拉扯酸胀吗?");
|
||||
questionMap4.put(2,"手往后背、反手抓后背腰带,肩膀后侧刺痛吗?");
|
||||
questionMap4.put(3,"含胸久坐、低头玩手机,肩后发紧僵硬疼吗?");
|
||||
dto4.setMap(questionMap4);
|
||||
JOINTS_DTO_MAP1.put(4,dto4);
|
||||
|
||||
MajorJointsDTO dto5 = new MajorJointsDTO();
|
||||
dto5.setTitle("肩胛骨内侧缝");
|
||||
dto5.setReport("肩胛内侧筋膜劳损、菱形肌紧张,长期久坐低头、圆肩驼背造成");
|
||||
Map<Integer,String> questionMap5 = new HashMap<>();
|
||||
questionMap5.put(1,"1.后背两块肩胛骨中间、靠近脖子那条缝酸胀疼吗?");
|
||||
questionMap5.put(2,"久坐伏案、低头看手机,肩缝发沉像压了重物吗?");
|
||||
questionMap5.put(3,"胳膊向前环抱、含胸,肩内侧牵扯刺痛吗?");
|
||||
dto5.setMap(questionMap5);
|
||||
JOINTS_DTO_MAP1.put(5,dto5);
|
||||
|
||||
MajorJointsDTO dto6 = new MajorJointsDTO();
|
||||
dto6.setTitle("腋下肩胛内侧区");
|
||||
dto6.setReport("肩峰撞击、长头腱炎症、肩胛下肌损伤");
|
||||
Map<Integer,String> questionMap6 = new HashMap<>();
|
||||
questionMap6.put(1,"后背手腋下深处疼吗?");
|
||||
questionMap6.put(2,"屈肘内旋用力腋下酸胀?");
|
||||
questionMap6.put(3,"侧卧夹臂睡觉会不会闷痛?");
|
||||
dto6.setMap(questionMap6);
|
||||
JOINTS_DTO_MAP1.put(6,dto6);
|
||||
}
|
||||
|
||||
//手指
|
||||
static {
|
||||
JOINTS_DTO_MAP2 = new HashMap<>();
|
||||
MajorJointsDTO dto = new MajorJointsDTO();
|
||||
Map<Integer,String> questionMap1 = new HashMap<>();
|
||||
questionMap1.put(1,"大拇指整根手指、指关节、根部位置,按压有没有酸胀、刺痛、发硬的感觉?");
|
||||
questionMap1.put(2,"频繁划手机、捏东西、开门锁、捏筷子发力时,大拇指会不会扯着疼?");
|
||||
questionMap1.put(3,"大拇指弯曲、伸直的时候,有没有卡顿、发僵、活动不顺畅的情况?");
|
||||
dto.setTitle("拇指区");
|
||||
dto.setReport("拇指腱鞘劳损、拇指关节疲劳、拇指肌腱卡压");
|
||||
dto.setMap(questionMap1);
|
||||
JOINTS_DTO_MAP2.put(1,dto);
|
||||
MajorJointsDTO dto2 = new MajorJointsDTO();
|
||||
dto2.setTitle("食指区");
|
||||
dto2.setReport("食指关节劳损、食指腱鞘轻微发炎、指关节筋膜紧张");
|
||||
Map<Integer,String> questionMap2 = new HashMap<>();
|
||||
questionMap2.put(1,"食指整根手指、各个关节按压有没有酸痛、隐痛、刺痛感?");
|
||||
questionMap2.put(2,"打字、写字、点屏幕、捏取细小物品时,食指发力会不会牵扯疼痛?");
|
||||
questionMap2.put(3,"食指用力弯曲、伸直、单独抬起时,有没有僵硬、扯痛的感觉?");
|
||||
dto2.setMap(questionMap2);
|
||||
JOINTS_DTO_MAP2.put(2,dto2);
|
||||
MajorJointsDTO dto3 = new MajorJointsDTO();
|
||||
dto3.setTitle("中指区");
|
||||
dto3.setReport("中指肌腱劳损、指关节压力性疲劳、腱鞘紧张");
|
||||
Map<Integer,String> questionMap3 = new HashMap<>();
|
||||
questionMap3.put(1,"中指各关节、手指整条位置按压,有没有酸胀、压痛的情况?");
|
||||
questionMap3.put(2,"握拳发力、拎东西、写字按压、干活用力时,中指会不会牵扯疼?");
|
||||
questionMap3.put(3,"中指弯曲伸直、大幅度活动时,有没有发紧、卡顿、不舒服的感觉?");
|
||||
dto3.setMap(questionMap3);
|
||||
JOINTS_DTO_MAP2.put(3,dto3);
|
||||
|
||||
MajorJointsDTO dto4 = new MajorJointsDTO();
|
||||
dto4.setTitle("无名指区");
|
||||
dto4.setReport("无名指关节劳损、腱鞘循环不畅、手指筋膜紧张");
|
||||
Map<Integer,String> questionMap4 = new HashMap<>();
|
||||
questionMap4.put(1,"无名指整条手指、关节位置按压,有没有隐隐酸痛、发胀的感觉?");
|
||||
questionMap4.put(2,"握拳、抓握物品、抬手发力时,无名指会不会跟着牵扯隐痛?");
|
||||
questionMap4.put(3,"手指并拢、分开活动时,无名指有没有发紧、活动受限、轻微刺痛?");
|
||||
dto4.setMap(questionMap4);
|
||||
JOINTS_DTO_MAP2.put(4,dto4);
|
||||
|
||||
MajorJointsDTO dto5 = new MajorJointsDTO();
|
||||
dto5.setTitle("小指区");
|
||||
dto5.setReport("小指腱鞘劳损、小指关节牵拉损伤、末梢循环不畅");
|
||||
Map<Integer,String> questionMap5 = new HashMap<>();
|
||||
questionMap5.put(1,"小拇指整条手指、关节按压,有没有酸痛、刺痛、发麻发木的感觉?");
|
||||
questionMap5.put(2,"撑手、趴桌子、手部偏向小指侧用力时,小拇指会不会扯着疼?");
|
||||
questionMap5.put(3,"小指弯曲伸直、单独活动时,有没有僵硬、不灵活、牵扯不适?");
|
||||
dto5.setMap(questionMap5);
|
||||
JOINTS_DTO_MAP2.put(5,dto5);
|
||||
|
||||
MajorJointsDTO dto6 = new MajorJointsDTO();
|
||||
dto6.setTitle("屈肌总腱鞘区");
|
||||
dto6.setReport("手部总腱鞘劳损、掌心筋膜紧张、手指屈肌疲劳,多由双手长期重复抓握、持续发力、受凉僵硬导致,是多手指整体劳损的核心区域");
|
||||
Map<Integer,String> questionMap6 = new HashMap<>();
|
||||
questionMap6.put(1,"手指根部、掌心上方整片位置,按压有没有发紧、发胀、闷痛的感觉?");
|
||||
questionMap6.put(2," 用力握拳、持续抓东西、反复屈伸所有手指时,整片区域会不会牵扯疼?");
|
||||
questionMap6.put(3,"长时间握鼠标、玩手机、干活后,掌心手指根部会不会发硬、发僵?");
|
||||
dto6.setMap(questionMap6);
|
||||
JOINTS_DTO_MAP2.put(6,dto6);
|
||||
}
|
||||
|
||||
//腕肘
|
||||
static {
|
||||
WAN_ZHOU_MAP = new HashMap<>();
|
||||
MajorJointsDTO dto = new MajorJointsDTO();
|
||||
Map<Integer,String> questionMap1 = new HashMap<>();
|
||||
questionMap1.put(1,"手肘外侧突出的小骨头,一按就酸痛吗?");
|
||||
questionMap1.put(2,"拧毛巾、拎重物、拿水杯发力时,外侧骨头扯着刺痛吗?");
|
||||
questionMap1.put(3,"长时间打字、拖地、反复抬手,手肘外侧发酸发沉吗?");
|
||||
dto.setTitle("手肘外侧骨头凸起");
|
||||
dto.setReport("手肘外侧肌腱劳损、网球肘,反复抓握、拧转发力诱发");
|
||||
dto.setMap(questionMap1);
|
||||
WAN_ZHOU_MAP.put(1,dto);
|
||||
MajorJointsDTO dto2 = new MajorJointsDTO();
|
||||
dto2.setTitle("手肘内侧骨头凸起");
|
||||
dto2.setReport("手肘内侧肌腱发炎、高尔夫肘,长期屈肘抓握、支撑发力导致");
|
||||
Map<Integer,String> questionMap2 = new HashMap<>();
|
||||
questionMap2.put(1,"手肘内侧凸起骨头按压闷痛吗?");
|
||||
questionMap2.put(2,"用力攥拳头、屈肘搬东西,手肘内侧牵扯疼吗?");
|
||||
questionMap2.put(3,"长期屈肘玩手机、趴着撑胳膊,内侧酸胀加重吗?");
|
||||
dto2.setMap(questionMap2);
|
||||
WAN_ZHOU_MAP.put(2,dto2);
|
||||
MajorJointsDTO dto3 = new MajorJointsDTO();
|
||||
dto3.setTitle("手肘后侧鹰嘴骨头");
|
||||
dto3.setReport("肘后滑囊发炎、胳膊后侧肌腱劳损,长期支撑、完全伸肘发力诱发");
|
||||
Map<Integer,String> questionMap3 = new HashMap<>();
|
||||
questionMap3.put(1,"1.手肘后面凸起那块骨头,撑桌面按压疼吗?");
|
||||
questionMap3.put(2,"2.完全伸直、用力向后顶东西,肘后刺痛吗?");
|
||||
questionMap3.put(3,"3.长期趴着睡觉、硬桌子撑手肘,后侧发胀红肿吗?");
|
||||
dto3.setMap(questionMap3);
|
||||
WAN_ZHOU_MAP.put(3,dto3);
|
||||
|
||||
MajorJointsDTO dto4 = new MajorJointsDTO();
|
||||
dto4.setTitle("手腕外侧");
|
||||
dto4.setReport("拇指腱鞘发炎、手腕外侧肌腱劳损,频繁用大拇指发力造成");
|
||||
Map<Integer,String> questionMap4 = new HashMap<>();
|
||||
questionMap4.put(1,"1.手腕靠近大拇指的凸起骨头按压酸胀吗?");
|
||||
questionMap4.put(2,"拧瓶盖、抱小孩、反复划手机,这个位置扯着疼吗?");
|
||||
questionMap4.put(3,"3.大拇指用力张开、握拳发力,手腕外侧刺痛吗?");
|
||||
dto4.setMap(questionMap4);
|
||||
WAN_ZHOU_MAP.put(4,dto4);
|
||||
|
||||
MajorJointsDTO dto5 = new MajorJointsDTO();
|
||||
dto5.setTitle("手腕掌心内侧正中");
|
||||
dto5.setReport("腕管受压、手腕内侧筋膜劳损,长期弯曲手腕、持续抓握诱发");
|
||||
Map<Integer,String> questionMap5 = new HashMap<>();
|
||||
questionMap5.put(1,".手掌根手腕内侧窝窝发闷胀痛吗?");
|
||||
questionMap5.put(2,"2.长时间屈腕玩手机、握鼠标,手指发麻连带手腕疼吗?");
|
||||
questionMap5.put(3,"3.睡觉手腕弯着,早上醒来手指僵硬、发麻吗?");
|
||||
dto5.setMap(questionMap5);
|
||||
WAN_ZHOU_MAP.put(5,dto5);
|
||||
|
||||
MajorJointsDTO dto6 = new MajorJointsDTO();
|
||||
dto6.setTitle("手腕内侧");
|
||||
dto6.setReport("手腕侧边韧带劳损、尺骨茎突磨损,手腕偏斜负重、撑地发力导致");
|
||||
Map<Integer,String> questionMap6 = new HashMap<>();
|
||||
questionMap6.put(1,"1.手腕靠近小拇指这边骨头按压疼吗?");
|
||||
questionMap6.put(2,"2.手掌往小指方向歪、撑地起身,手腕侧边刺痛吗?");
|
||||
// questionMap6.put(3,"侧卧夹臂睡觉会不会闷痛?");
|
||||
dto6.setMap(questionMap6);
|
||||
WAN_ZHOU_MAP.put(6,dto6);
|
||||
|
||||
MajorJointsDTO dto7 = new MajorJointsDTO();
|
||||
dto7.setTitle("手腕掌心中间整片");
|
||||
dto7.setReport("手指屈肌腱劳损、掌心筋膜紧张,长期重复抓握、受凉诱发");
|
||||
Map<Integer,String> qu7 = new HashMap<>();
|
||||
qu7.put(1,"手腕掌心连接手指的整片位置发紧酸胀吗?");
|
||||
qu7.put(2,"2.用力握拳、反复屈伸手指,手腕掌心牵扯疼吗?");
|
||||
qu7.put(3,"冷水洗手、受凉后,握拳僵硬疼痛感加重吗?");
|
||||
dto7.setMap(qu7);
|
||||
WAN_ZHOU_MAP.put(7,dto7);
|
||||
}
|
||||
|
||||
//腰
|
||||
static {
|
||||
YAO_MAP = new HashMap<>();
|
||||
MajorJointsDTO dto = new MajorJointsDTO();
|
||||
Map<Integer,String> questionMap1 = new HashMap<>();
|
||||
questionMap1.put(1,"肋骨下方、后腰上方这块经常发酸发胀吗?");
|
||||
questionMap1.put(2,"2.长时间低头久坐、弯腰干活之后,这里疼得更明显吗?");
|
||||
questionMap1.put(3,"3.挺直腰、向后舒展后腰时,这块有拉扯难受的感觉吗?");
|
||||
dto.setTitle("上腰段");
|
||||
dto.setReport("腰背筋膜上段、后腰浅层肌肉劳损,长期驼背、受凉、扭腰引发代偿酸痛");
|
||||
dto.setMap(questionMap1);
|
||||
YAO_MAP.put(1,dto);
|
||||
MajorJointsDTO dto2 = new MajorJointsDTO();
|
||||
dto2.setTitle("中下腰椎");
|
||||
dto2.setReport("腰肌劳损、腰椎关节错位、轻度腰间盘膨出");
|
||||
Map<Integer,String> questionMap2 = new HashMap<>();
|
||||
questionMap2.put(1,"1.腰带对应的后腰位置持续发酸、发疼吗?");
|
||||
questionMap2.put(2,"2.弯腰捡东西、久坐刚站起来的一瞬间,后腰会刺痛吗?");
|
||||
questionMap2.put(3,"3.用手按压后腰骨头两边,肌肉发硬、一按就疼吗?");
|
||||
dto2.setMap(questionMap2);
|
||||
YAO_MAP.put(2,dto2);
|
||||
MajorJointsDTO dto3 = new MajorJointsDTO();
|
||||
dto3.setTitle("腰骶结合处");
|
||||
dto3.setReport("腰底韧带劳损、腰五骶一椎间盘不适,翘腿、拖地、骨盆前倾诱发疼痛");
|
||||
Map<Integer,String> questionMap3 = new HashMap<>();
|
||||
questionMap3.put(1,"1.腰最底下、屁股上方凹进去的地方疼吗?");
|
||||
questionMap3.put(2,"久坐、躺床上翻身的时候,这块扯着牵拉疼吗?");
|
||||
questionMap3.put(3,"走路久了腰底部发沉,还连带屁股一起酸胀吗?");
|
||||
dto3.setMap(questionMap3);
|
||||
YAO_MAP.put(3,dto3);
|
||||
|
||||
MajorJointsDTO dto4 = new MajorJointsDTO();
|
||||
dto4.setTitle("腰椎棘突正中");
|
||||
dto4.setReport("后腰中间韧带发炎、长期弓背塌腰造成韧带劳损");
|
||||
Map<Integer,String> questionMap4 = new HashMap<>();
|
||||
questionMap4.put(1,"1.后腰正中间这条骨头,用手按压有痛感吗?");
|
||||
questionMap4.put(2,"长时间弯腰,或是刻意向后仰腰时,骨头缝刺痛吗?");
|
||||
questionMap4.put(3,"3.睡硬床平躺,后腰中间被硌到后难受加重吗?");
|
||||
dto4.setMap(questionMap4);
|
||||
YAO_MAP.put(4,dto4);
|
||||
|
||||
MajorJointsDTO dto5 = new MajorJointsDTO();
|
||||
dto5.setTitle("腰侧方");
|
||||
dto5.setReport("腰侧肌肉痉挛、歪坐、高低腿导致单侧腰部代偿劳损");
|
||||
Map<Integer,String> questionMap5 = new HashMap<>();
|
||||
questionMap5.put(1,"1.左右两侧腰窝经常拉扯酸胀吗?");
|
||||
questionMap5.put(2,"单侧侧身弯腰、单手提重物时,一边腰扯着疼吗?");
|
||||
questionMap5.put(3,"3.长期侧躺睡觉,受压一侧腰部僵硬酸痛吗?");
|
||||
dto5.setMap(questionMap5);
|
||||
YAO_MAP.put(5,dto5);
|
||||
|
||||
MajorJointsDTO dto6 = new MajorJointsDTO();
|
||||
dto6.setTitle(" 髋前侧腹股沟");
|
||||
dto6.setReport("大腿根胯部肌肉紧张、髋关节前侧滑膜发炎,久蹲、爬坡诱发疼痛");
|
||||
Map<Integer,String> questionMap6 = new HashMap<>();
|
||||
questionMap6.put(1,"大腿根里面凹陷处闷闷胀痛吗?");
|
||||
questionMap6.put(2,"2.深蹲、抬腿、久坐起身时,大腿根扯着刺痛吗?");
|
||||
questionMap6.put(3,"3.做弓步向前压腿,胯骨前面牵拉难受吗?");
|
||||
dto6.setMap(questionMap6);
|
||||
YAO_MAP.put(6,dto6);
|
||||
|
||||
MajorJointsDTO dto7 = new MajorJointsDTO();
|
||||
dto7.setTitle("髋外侧大转子");
|
||||
dto7.setReport("胯外侧滑囊发炎、臀部外侧肌肉劳损,长期侧睡、走路外八引发");
|
||||
Map<Integer,String> questionMap7 = new HashMap<>();
|
||||
questionMap7.put(1,"胯外侧突出的那块骨头,轻轻按压就疼吗?");
|
||||
questionMap7.put(2,"2.侧躺压住胯骨时,刺痛感会明显加重吗?");
|
||||
questionMap7.put(3,"走路、上下台阶,胯外侧酸胀还放射到大腿吗?");
|
||||
dto7.setMap(questionMap7);
|
||||
YAO_MAP.put(7,dto7);
|
||||
|
||||
MajorJointsDTO dto8 = new MajorJointsDTO();
|
||||
dto8.setTitle("髋后侧臀深处");
|
||||
dto8.setReport("臀部深层肌肉痉挛、坐骨神经受刺激,久坐盘腿诱发不适");
|
||||
Map<Integer,String> questionMap8 = new HashMap<>();
|
||||
questionMap8.put(1,"1.屁股里面深处隐隐胀痛吗?");
|
||||
questionMap8.put(2,"2.久坐、跷二郎腿之后,屁股深处一条筋扯着大腿后侧发麻疼吗?");
|
||||
questionMap8.put(3,"3.拉伸臀部的时候,深层有明显牵拉痛感吗?");
|
||||
dto8.setMap(questionMap8);
|
||||
YAO_MAP.put(8,dto8);
|
||||
|
||||
}
|
||||
|
||||
@PostMapping("/score")
|
||||
public ResultData<String> score(HttpServletRequest request,@RequestBody List<SpeakVO> vos){
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (Objects.isNull(currentUser)){
|
||||
throw new ServiceException(401,"登录已过期");
|
||||
}
|
||||
List<SpeakVO> collect = vos.stream().filter(vo -> vo.getNo() == 3).collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(collect)){
|
||||
throw new ServiceException("数据错误");
|
||||
}
|
||||
SpeakVO speakVO = collect.get(0);
|
||||
String join = String.join(",", speakVO.getOptions());
|
||||
MobileAppUser appUser = mobileAppUserMapper.selectById(currentUser.getId());
|
||||
appUser.setTherapy(join);
|
||||
mobileAppUserMapper.updateById(appUser);
|
||||
return ResultData.success();
|
||||
}
|
||||
|
||||
@PostMapping("/save4SRating")
|
||||
public ResultData save4S(HttpServletRequest request,@RequestBody MobileAppUser user){
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (Objects.isNull(currentUser)){
|
||||
throw new ServiceException(401,"登录已过期");
|
||||
}
|
||||
MobileAppUser appUser = mobileAppUserMapper.selectById(currentUser.getId());
|
||||
appUser.setFoursRating(user.getFoursRating());
|
||||
appUser.setEvaluationResult(user.getEvaluationResult());
|
||||
mobileAppUserMapper.updateById(appUser);
|
||||
return ResultData.success();
|
||||
}
|
||||
|
||||
@GetMapping("/getRating")
|
||||
public ResultData<MobileAppUser> getRating(HttpServletRequest request){
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (Objects.isNull(currentUser)){
|
||||
throw new ServiceException(401,"登录已过期");
|
||||
}
|
||||
MobileAppUser appUser = mobileAppUserMapper.selectById(currentUser.getId());
|
||||
ResultData<MobileAppUser> data = new ResultData<>();
|
||||
data.setData(appUser);
|
||||
data.setCode(200);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
private Map<Integer, JSONObject> scoreMap(){
|
||||
Map<Integer, JSONObject> map = new HashMap<>();
|
||||
JSONObject one = new JSONObject();
|
||||
one.put("A",2);
|
||||
one.put("B",8);
|
||||
one.put("C",12);
|
||||
map.put(1,one);
|
||||
JSONObject two = new JSONObject();
|
||||
two.put("A",0);
|
||||
two.put("B",4);
|
||||
two.put("C",15);
|
||||
map.put(2,two);
|
||||
|
||||
JSONObject three = new JSONObject();
|
||||
three.put("A",0);
|
||||
three.put("B",4);
|
||||
three.put("C",15);
|
||||
three.put("D",0);
|
||||
three.put("E",0);
|
||||
map.put(2,three);
|
||||
return map;
|
||||
}
|
||||
|
||||
@PostMapping("/eightMajorJoints")
|
||||
public ResultData eightMajorJoints(HttpServletRequest request,@RequestBody EightMajorJointsVO vo){
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (Objects.isNull(currentUser)){
|
||||
throw new ServiceException(401,"登录已过期");
|
||||
}
|
||||
List<DiaRecord> records = new ArrayList<>();
|
||||
String s = RandomStringUtils.randomNumeric(16);
|
||||
MajorJointsDTO dto = JOINTS_DTO_MAP1.get(vo.getArea());
|
||||
Map<Integer, String> map = dto.getMap();
|
||||
List<EightMajorJointsVO.Joints> joints = vo.getJoints();
|
||||
joints.forEach(j -> {
|
||||
DiaRecord diaRecord = new DiaRecord();
|
||||
diaRecord.setPart(vo.getPart());
|
||||
diaRecord.setArea(dto.getTitle());
|
||||
diaRecord.setQuestion(map.get(j.getNumber()));
|
||||
diaRecord.setBatchNumber(s);
|
||||
diaRecord.setResponse(j.getPatientResponse());
|
||||
diaRecord.setAppUserId(currentUser.getId());
|
||||
records.add(diaRecord);
|
||||
});
|
||||
diaRecordMapper.insert(records);
|
||||
return ResultData.success();
|
||||
}
|
||||
|
||||
@PostMapping("/getReport")
|
||||
public ResultData<String> getReport(@RequestBody EightMajorJointsVO vo){
|
||||
ResultData<String> data = new ResultData<>();
|
||||
data.setCode(200);
|
||||
switch (vo.getPart()){
|
||||
case "肩关节":
|
||||
MajorJointsDTO dto = JOINTS_DTO_MAP1.get(vo.getArea());
|
||||
data.setData(dto.getReport());
|
||||
return data;
|
||||
case "腱鞘指关节":
|
||||
MajorJointsDTO dto1 = JOINTS_DTO_MAP2.get(vo.getArea());
|
||||
data.setData(dto1.getReport());
|
||||
return data;
|
||||
case "腕肘关节":
|
||||
MajorJointsDTO dto2 = WAN_ZHOU_MAP.get(vo.getArea());
|
||||
data.setData(dto2.getReport());
|
||||
return data;
|
||||
case "腰髋关节":
|
||||
MajorJointsDTO dto3 = YAO_MAP.get(vo.getArea());
|
||||
data.setData(dto3.getReport());
|
||||
return data;
|
||||
}
|
||||
return ResultData.success();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.entity.po.RunConsultation;
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.exception.ServiceException;
|
||||
import cn.unizk.mapper.RunConsultationMapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2026/7/15 11:02
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet/running")
|
||||
public class RunningController {
|
||||
|
||||
@Resource
|
||||
private RunConsultationMapper runConsultationMapper;
|
||||
|
||||
@GetMapping("/getRunConsults")
|
||||
public Page<RunConsultation> getRunConsult(@RequestParam("currentPage") Integer currentPage,
|
||||
@RequestParam("pageSize") Integer pageSize) {
|
||||
|
||||
Page<RunConsultation> page = new Page<>(currentPage, pageSize);
|
||||
return runConsultationMapper.selectPage(page, null);
|
||||
}
|
||||
|
||||
@PostMapping("/getRunConsultByIds")
|
||||
public RunConsultation getRunConsultByIds(@RequestBody List<Integer> ids) {
|
||||
if (CollectionUtils.isEmpty(ids)) {
|
||||
throw new ServiceException("参数ids不能为空");
|
||||
}
|
||||
List<RunConsultation> runConsultations = runConsultationMapper.selectByIds(ids);
|
||||
RunConsultation consultation = new RunConsultation();
|
||||
String lesion = runConsultations.stream().map(RunConsultation::getLesion).distinct().collect(Collectors.joining(";"));
|
||||
consultation.setLesion(lesion);
|
||||
String conclusion = runConsultations.stream().map(RunConsultation::getConclusion).distinct().collect(Collectors.joining("\n"));
|
||||
consultation.setConclusion(conclusion);
|
||||
List<RunConsultation> distinctConsult = runConsultations.stream()
|
||||
.collect(Collectors.collectingAndThen(
|
||||
Collectors.toMap(
|
||||
RunConsultation::getLesion,
|
||||
Function.identity(),
|
||||
(existing, replacement) -> existing,
|
||||
LinkedHashMap::new
|
||||
),
|
||||
map -> new ArrayList<>(map.values())
|
||||
));
|
||||
String plan = distinctConsult.stream().map(RunConsultation::getPlan).distinct().collect(Collectors.joining("\n"));
|
||||
consultation.setPlan(plan);
|
||||
return consultation;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.entity.po.SysDict;
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.service.SysDictService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/9/3 11:30
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet/dict")
|
||||
public class SysDictController {
|
||||
|
||||
@Resource
|
||||
private SysDictService sysDictService;
|
||||
|
||||
@GetMapping("/getDictByType")
|
||||
public List<SysDict> getDictByType(@RequestParam("type") String type){
|
||||
return sysDictService.list(new LambdaQueryWrapper<SysDict>()
|
||||
.eq(SysDict::getDictType,type)
|
||||
.eq(SysDict::getStatus,"display"));
|
||||
}
|
||||
|
||||
@GetMapping("/getDictType")
|
||||
public List<String> getDictType(){
|
||||
return sysDictService.list().stream().map(SysDict::getDictType)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/*@GetMapping("/getGrfScanPrice")
|
||||
public ResultData getGrfScanPrice(){
|
||||
SysDict sysDict = sysDictService.getById(27);
|
||||
ResultData<String> data = new ResultData<>();
|
||||
data.setCode(200);
|
||||
data.setData(sysDict.getDictValue());
|
||||
return data;
|
||||
}*/
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.entity.po.PhysioThirteenArea;
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.mapper.PhysioThirteenAreaMapper;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2026/9/2 16:53
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet/test")
|
||||
public class TestController {
|
||||
|
||||
@Resource
|
||||
private PhysioThirteenAreaMapper physioThirteenAreaMapper;
|
||||
|
||||
@PostMapping("/add13Area")
|
||||
public ResultData add13Area(@RequestBody List<PhysioThirteenArea> areas){
|
||||
physioThirteenAreaMapper.insert(areas);
|
||||
return ResultData.success();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
String s = "1.减少膝关节扭转发力、深度负重深蹲,减少半月板挤压扭转,适度减负休养。2.强化膝关节周边大腿肌群,依靠肌肉力量分担关节内部压力。3.控制体重,降低膝关节整体负重,运动循序渐进,不突然加大运动量。4.膝关节整体做好保暖,寒凉会加重关节间隙酸胀感受。5.养护以膝关节周边肌群疏导为主,禁止直接大力按压关节缝隙。";
|
||||
List<String> num = Lists.newArrayList("2","3","4","5");
|
||||
StringBuilder sb = new StringBuilder(s);
|
||||
for (String n : num) {
|
||||
int i = sb.indexOf(n);
|
||||
sb.insert(i,"\\n");
|
||||
}
|
||||
System.out.println(sb.toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.entity.po.MobileAppUser;
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.exception.BusinessException;
|
||||
import cn.unizk.exception.ServiceException;
|
||||
import cn.unizk.pay.dto.BasePayResponse;
|
||||
import cn.unizk.pay.dto.CoursePayParam;
|
||||
import cn.unizk.pay.dto.HGJPayParam;
|
||||
import cn.unizk.pay.dto.PayBaseRequest;
|
||||
import cn.unizk.utils.HttpUtil;
|
||||
import cn.unizk.utils.JkSecurityUtil;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.gson.Gson;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2026/7/27 10:40
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet/wechat")
|
||||
@Slf4j
|
||||
public class WechatPayController {
|
||||
|
||||
@Value("${payIp}")
|
||||
private String payIp;
|
||||
|
||||
@PostMapping("/pay")
|
||||
public ResultData pay(HttpServletRequest request,@RequestBody PayBaseRequest param){
|
||||
if (StringUtils.isBlank(param.getOpenid())){
|
||||
throw new ServiceException("openid呢???");
|
||||
}
|
||||
param.setStep(2);
|
||||
// String ip = "http://192.168.0.6:8083";
|
||||
String url = payIp + "/mobileApp/hf/pay";
|
||||
log.info("url===={}",url);
|
||||
Map<String,String> headers = new HashMap<>();
|
||||
headers.put("mobile-t",param.getAppToken());
|
||||
// PayBaseRequest requestType = createRequestType(param);
|
||||
JSONObject from = JSONObject.from(param);
|
||||
from.put("sceneCode",param.getSceneCode());
|
||||
String s = HttpUtil.doPostJson(url, headers, from);
|
||||
Gson gson = new Gson();
|
||||
ResultData data = gson.fromJson(s, ResultData.class);
|
||||
if (data == null || data.getCode() != 200){
|
||||
throw new ServiceException("微信支付下单失败");
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,279 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.config.JkProperties;
|
||||
import cn.unizk.constant.WxConstant;
|
||||
import cn.unizk.entity.po.*;
|
||||
import cn.unizk.entity.vo.MobileAppUserVO;
|
||||
import cn.unizk.entity.vo.OneClickVO;
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.exception.ServiceException;
|
||||
import cn.unizk.mapper.BusinessChannelMapper;
|
||||
import cn.unizk.mapper.MobileAppUserMapper;
|
||||
import cn.unizk.mapper.YnzkSystemDeviceMapper;
|
||||
import cn.unizk.service.*;
|
||||
import cn.unizk.utils.*;
|
||||
import cn.unizk.wxPay.service.WxPayOrderService;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/7/9 16:25
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet")
|
||||
@Slf4j
|
||||
public class WxAppletLoginController {
|
||||
|
||||
@Resource
|
||||
private WxAppletLoginService appletLoginService;
|
||||
@Resource
|
||||
private WxAuthService wxAuthService;
|
||||
@Resource
|
||||
private MobileAppUserMapper mobileAppUserMapper;
|
||||
@Value("${spring.profiles.active}")
|
||||
private String active;
|
||||
@Resource
|
||||
private JkProperties jkProperties;
|
||||
@Autowired
|
||||
@Qualifier("kryoRedisTemplate")
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
/* @Resource
|
||||
private WxPayOrderService wxPayOrderService;*/
|
||||
@Resource
|
||||
private DeviceService deviceService;
|
||||
@Resource
|
||||
private YnzkSystemDeviceMapper ynzkSystemDeviceMapper;
|
||||
@Resource
|
||||
private BusinessChannelMapper businessChannelMapper;
|
||||
@Resource
|
||||
private SysDictService dictService;
|
||||
|
||||
@GetMapping("/login")
|
||||
public JSONObject login(@RequestParam("code") String code) {
|
||||
return appletLoginService.appletLogin(code);
|
||||
}
|
||||
|
||||
@PostMapping("/editWxUser")
|
||||
public int editUser(@RequestBody MobileAppUser wxUser) {
|
||||
MobileAppUser user = new MobileAppUser();
|
||||
user.setNickname(wxUser.getNickname());
|
||||
user.setAvatar(wxUser.getAvatar());
|
||||
LambdaUpdateWrapper<MobileAppUser> wrapper = new LambdaUpdateWrapper<>();
|
||||
wrapper.eq(MobileAppUser::getId, wxUser.getId());
|
||||
return mobileAppUserMapper.update(user, wrapper);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/sendPhoneCode")
|
||||
public ResultData sendPhoneCode(@RequestParam("phoneNumber") String phoneNumber) {
|
||||
if ("prod".equals(active)){
|
||||
String code = RandomStringUtils.randomNumeric(6);
|
||||
log.info("手机验证码:{}",code);
|
||||
try {
|
||||
String s = SendSmsUtil.sendPhoneCode(phoneNumber, code);
|
||||
JSONObject res = JSONObject.parseObject(s);
|
||||
Integer statusCode = res.getInteger("statusCode");
|
||||
if (statusCode != null && statusCode == 200) {
|
||||
redisTemplate.opsForValue().set(phoneNumber, code, 300, TimeUnit.SECONDS);
|
||||
return ResultData.success();
|
||||
}
|
||||
return ResultData.failure(500, "验证码发送失败");
|
||||
} catch (ExecutionException | InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
throw new ServiceException("验证码发送失败");
|
||||
}
|
||||
}else {
|
||||
redisTemplate.opsForValue().set(phoneNumber, "888888", 300, TimeUnit.SECONDS);
|
||||
return ResultData.success();
|
||||
}
|
||||
}
|
||||
|
||||
/* @PostMapping("/jkLogin")
|
||||
public MobileAppUserVO JKLogin(@RequestParam("openid") String openid) {
|
||||
MobileAppUser wxUser = mobileAppUserMapper.selectOne(new LambdaQueryWrapper<MobileAppUser>().eq(MobileAppUser::getOpenid, openid));
|
||||
if (Objects.isNull(wxUser)) {
|
||||
throw new ServiceException("登录失败!");
|
||||
}
|
||||
MobileAppUserVO wxUserVO = new MobileAppUserVO();
|
||||
BeanUtils.copyProperties(wxUser, wxUserVO);
|
||||
String token = JwtUtil.generateToken(wxUser.getId().toString());
|
||||
redisTemplate.opsForValue().set(WxConstant.CACHE_TOKEN_KEY + wxUser.getId(), wxUser, jkProperties.getTokenExpireTime(), TimeUnit.MINUTES);
|
||||
wxUserVO.setToken(token);
|
||||
return wxUserVO;
|
||||
}*/
|
||||
|
||||
@PostMapping("/loginByPhone")
|
||||
public MobileAppUserVO bindPhoneNumber(@RequestParam("phoneNumber") String phoneNumber, @RequestParam("code") String code,
|
||||
@RequestParam("openid") String openid) {
|
||||
|
||||
if ("prod".equals(active)){
|
||||
validatePhoneCode(phoneNumber, code);
|
||||
}
|
||||
MobileAppUser appUser = mobileAppUserMapper.selectOne(new LambdaQueryWrapper<MobileAppUser>().eq(MobileAppUser::getPhoneNumber, phoneNumber));
|
||||
if (Objects.isNull(appUser)){
|
||||
appUser = new MobileAppUser();
|
||||
appUser.setOpenid(openid);
|
||||
appUser.setPhoneNumber(phoneNumber);
|
||||
mobileAppUserMapper.insert(appUser);
|
||||
}else {
|
||||
appUser.setOpenid(openid);
|
||||
mobileAppUserMapper.updateById(appUser);
|
||||
}
|
||||
String token = JwtUtil.generateToken(phoneNumber);
|
||||
MobileAppUserVO mobileAppUserVO = new MobileAppUserVO();
|
||||
BeanUtils.copyProperties(appUser, mobileAppUserVO);
|
||||
mobileAppUserVO.setToken(token);
|
||||
redisTemplate.opsForValue().set(WxConstant.CACHE_TOKEN_KEY + phoneNumber, appUser, jkProperties.getTokenExpireTime(), TimeUnit.DAYS);
|
||||
return mobileAppUserVO;
|
||||
}
|
||||
|
||||
@PostMapping("/oneClickLogin")
|
||||
public MobileAppUser oneClick(@RequestBody OneClickVO vo){
|
||||
String accessToken = wxAuthService.getAccessToken();
|
||||
String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken;
|
||||
JSONObject jsonObject = JSONObject.from(vo);
|
||||
try {
|
||||
String s = HttpUtil.doPostJson(url, null, jsonObject);
|
||||
log.info("一键登录接口返回:{}",s);
|
||||
JSONObject res = JSONObject.parseObject(s);
|
||||
Integer errcode = res.getInteger("errcode");
|
||||
|
||||
if(errcode != 0 && errcode != 42001){
|
||||
throw new ServiceException("登录失败!请稍后重试");
|
||||
}
|
||||
if (errcode == 42001){
|
||||
redisTemplate.delete(WxConstant.WX_ACCESS_TOKEN);
|
||||
accessToken = wxAuthService.getAccessToken();
|
||||
url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken;
|
||||
String msg = HttpUtil.doPostJson(url, null, jsonObject);
|
||||
res = JSONObject.parseObject(msg);
|
||||
Integer code = res.getInteger("errcode");
|
||||
if (code != 0){
|
||||
throw new ServiceException("登录失败!请稍后重试");
|
||||
}
|
||||
}
|
||||
JSONObject phone_info = res.getJSONObject("phone_info");
|
||||
String phoneNumber = phone_info.getString("phoneNumber");
|
||||
log.info("获取到的用户手机号:{}",phoneNumber);
|
||||
MobileAppUser user = mobileAppUserMapper.selectOne(new LambdaQueryWrapper<MobileAppUser>().eq(MobileAppUser::getPhoneNumber, phoneNumber));
|
||||
if (Objects.isNull(user)){
|
||||
user = new MobileAppUser();
|
||||
user.setOpenid(vo.getOpenid());
|
||||
user.setPhoneNumber(phoneNumber);
|
||||
user.setCreateTime(LocalDateTime.now());
|
||||
mobileAppUserMapper.insert(user);
|
||||
}else {
|
||||
user.setOpenid(vo.getOpenid());
|
||||
mobileAppUserMapper.updateById(user);
|
||||
}
|
||||
String token = JwtUtil.generateToken(phoneNumber);
|
||||
MobileAppUserVO mobileAppUserVO = new MobileAppUserVO();
|
||||
BeanUtils.copyProperties(user, mobileAppUserVO);
|
||||
mobileAppUserVO.setToken(token);
|
||||
redisTemplate.opsForValue().set(WxConstant.CACHE_TOKEN_KEY + phoneNumber, user, jkProperties.getTokenExpireTime(), TimeUnit.DAYS);
|
||||
return mobileAppUserVO;
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
throw new ServiceException("登录失败!请稍后重试");
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/getAppletQrCode")
|
||||
public void getAppletQrCode(HttpServletResponse response){
|
||||
String accessToken = wxAuthService.getAccessToken();
|
||||
String url = String.format("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s",accessToken);
|
||||
log.info("url={}",url);
|
||||
JSONObject jsonBody = JSONObject.of();
|
||||
jsonBody.put("scene","apple=1");
|
||||
jsonBody.put("check_path",false);
|
||||
jsonBody.put("env_version","trial");
|
||||
byte[] bytes = HttpUtil.postRtnBytes(url, null, jsonBody);
|
||||
if (bytes == null || bytes.length == 0){
|
||||
ServletUtils.renderString(response,"qrcode res is empty");
|
||||
return;
|
||||
}
|
||||
// response.setContentType("image/jpeg");
|
||||
response.setContentLength(bytes.length);
|
||||
try (OutputStream os = response.getOutputStream()) {
|
||||
os.write(bytes);
|
||||
os.flush();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/logout")
|
||||
public ResultData logout(HttpServletRequest request){
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (Objects.isNull(currentUser)){
|
||||
return ResultData.success();
|
||||
}
|
||||
redisTemplate.delete(WxConstant.CACHE_TOKEN_KEY + currentUser.getPhoneNumber());
|
||||
return ResultData.success();
|
||||
}
|
||||
|
||||
@GetMapping("/getCurrentUser")
|
||||
public MobileAppUser getCurrentUser(HttpServletRequest request) {
|
||||
return JkSecurityUtil.getCurrentUser(request);
|
||||
}
|
||||
|
||||
private void validatePhoneCode(String phone, String code) {
|
||||
String cacheCode = (String) redisTemplate.opsForValue().get(phone);
|
||||
if (StringUtils.isBlank(cacheCode) || !cacheCode.equals(code)) {
|
||||
throw new ServiceException("验证码错误");
|
||||
}
|
||||
redisTemplate.delete(phone);
|
||||
}
|
||||
|
||||
// @GetMapping("/test")
|
||||
public boolean test() {
|
||||
List<YnzkSystemDevice> ynzkSystemDevices = ynzkSystemDeviceMapper.selectList(null);
|
||||
List<Device> deviceList = new ArrayList<>();
|
||||
ynzkSystemDevices.forEach(s -> {
|
||||
Device device = new Device();
|
||||
device.setMuid(s.getMuid());
|
||||
device.setDeviceId(s.getSerial());
|
||||
deviceList.add(device);
|
||||
});
|
||||
return deviceService.saveBatch(deviceList);
|
||||
}
|
||||
|
||||
@GetMapping("/test/one")
|
||||
public String testOne(SysDict dict){
|
||||
if (Objects.isNull(dict) || dict.getDictCode() == null){
|
||||
return "fail";
|
||||
}
|
||||
boolean b = dictService.updateById(dict);
|
||||
return b ? "success" : "fail";
|
||||
}
|
||||
|
||||
@GetMapping("/modifyDict")
|
||||
public void modifyDict(SysDict dict){
|
||||
dictService.updateById(dict);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.entity.po.Device;
|
||||
import cn.unizk.entity.vo.UniPage;
|
||||
import cn.unizk.service.DeviceService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/8/30 16:31
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet/device")
|
||||
public class WxDeviceController {
|
||||
|
||||
@Resource
|
||||
private DeviceService deviceService;
|
||||
|
||||
@GetMapping("/list")
|
||||
public Page<Device> list(UniPage uniPage, @RequestParam("storeId") Integer storeId){
|
||||
Page<Device> page = new Page<>();
|
||||
page.setCurrent(uniPage.getCurrentPage());
|
||||
page.setSize(uniPage.getPageSize());
|
||||
return deviceService.page(page,new LambdaQueryWrapper<Device>().eq(Device::getStatus,"1").eq(Device::getStoreId,storeId));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.constant.WxConstant;
|
||||
import cn.unizk.entity.po.*;
|
||||
import cn.unizk.entity.vo.*;
|
||||
import cn.unizk.enums.OrderAfterSaleStatus;
|
||||
import cn.unizk.enums.OrderStatus;
|
||||
import cn.unizk.exception.ServiceException;
|
||||
import cn.unizk.mapper.*;
|
||||
import cn.unizk.service.*;
|
||||
import cn.unizk.utils.BeanCopyUtils;
|
||||
import cn.unizk.utils.JkSecurityUtil;
|
||||
import cn.unizk.utils.JwtUtil;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/8/30 11:36
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet/order")
|
||||
public class WxOrderController {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("kryoRedisTemplate")
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
@Resource
|
||||
private MobileOrderMapper mobileOrderMapper;
|
||||
@Resource
|
||||
private ComboService comboService;
|
||||
@Resource
|
||||
private JkProductService productService;
|
||||
@Resource
|
||||
private JkStoreService storeService;
|
||||
@Resource
|
||||
private MobileAppUserMapper mobileAppUserMapper;
|
||||
@Resource
|
||||
private JkPhysioService physioService;
|
||||
@Resource
|
||||
private MobileOrderItemMapper mobileOrderItemMapper;
|
||||
@Resource
|
||||
private OrderReviewMapper reviewMapper;
|
||||
@Resource
|
||||
private CourseMapper courseMapper;
|
||||
|
||||
@PostMapping("/deleteInvalidOrder")
|
||||
public ResultData deleteInvalidOrder(@RequestParam("orderId") String orderId, HttpServletRequest request) {
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request.getHeader(WxConstant.APPLET_LOGIN_SIGN));
|
||||
if (Objects.isNull(currentUser)) {
|
||||
throw new ServiceException(401, "无权访问");
|
||||
}
|
||||
MobileOrder one = mobileOrderMapper.selectOne(new LambdaQueryWrapper<MobileOrder>()
|
||||
.eq(MobileOrder::getOrderId, orderId)
|
||||
.eq(MobileOrder::getMobileUserId, currentUser.getId()));
|
||||
if (Objects.isNull(one)) {
|
||||
throw new ServiceException("您无权限删除");
|
||||
}
|
||||
mobileOrderMapper.deleteById(orderId);
|
||||
return ResultData.success();
|
||||
}
|
||||
|
||||
@GetMapping("/getPersonOrders")
|
||||
public Page<MobileOrderVO> getPersonOrders(HttpServletRequest request, UniPage uniPage, @RequestParam(value = "orderStatus", required = false) String orderStatus) {
|
||||
boolean afterSale = false;
|
||||
if ("request_refund,refunded".equals(orderStatus)) {
|
||||
orderStatus = "";
|
||||
afterSale = true;
|
||||
}
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (Objects.isNull(currentUser)) {
|
||||
return null;
|
||||
}
|
||||
List<String> orderStatusList = null;
|
||||
if (StringUtils.isNotBlank(orderStatus) && orderStatus.contains(",")) {
|
||||
String[] split = orderStatus.split(",");
|
||||
orderStatusList = Arrays.asList(split);
|
||||
} else if (StringUtils.isNotBlank(orderStatus)) {
|
||||
orderStatusList = new ArrayList<>();
|
||||
orderStatusList.add(orderStatus);
|
||||
}
|
||||
Page<MobileOrder> page = new Page<>();
|
||||
page.setSize(uniPage.getPageSize());
|
||||
page.setCurrent(uniPage.getCurrentPage());
|
||||
// ArrayList<String> strings = Lists.newArrayList("unpaid", "not_shipped", "shipped", "to_be_evaluate");
|
||||
Page<MobileOrder> orderPage = mobileOrderMapper.selectPage(page, new LambdaQueryWrapper<MobileOrder>()
|
||||
.eq(MobileOrder::getMobileUserId, currentUser.getId())
|
||||
.in(CollectionUtils.isNotEmpty(orderStatusList), MobileOrder::getStatus, orderStatusList)
|
||||
.eq(!afterSale && StringUtils.isNotBlank(orderStatus), MobileOrder::getAfterSaleStatus, 0)
|
||||
.ne(afterSale, MobileOrder::getAfterSaleStatus, 0)
|
||||
.orderByDesc(MobileOrder::getCreateTime)
|
||||
/*.in(WxOrder::getStatus,strings)*/);
|
||||
List<MobileOrder> records = orderPage.getRecords();
|
||||
/*List<WxOrder> collect = records.stream().filter(o -> {
|
||||
return strings.contains(o.getStatus());
|
||||
}).collect(Collectors.toList());*/
|
||||
List<MobileOrderVO> vos = new ArrayList<>();
|
||||
for (MobileOrder order : records) {
|
||||
MobileOrderVO vo = new MobileOrderVO();
|
||||
BeanUtils.copyProperties(order, vo);
|
||||
/*if (order.getAfterSaleStatus() != 0){
|
||||
vo.setStatus(OrderAfterSaleStatus.getValueByKey(order.getAfterSaleStatus()));
|
||||
}*/
|
||||
List<MobileOrderItem> wxOrderItems = mobileOrderItemMapper.selectList(new LambdaQueryWrapper<MobileOrderItem>().eq(MobileOrderItem::getMobileOrderId, order.getOrderId()));
|
||||
Collection<MobileOrderItemVO> wxOrderItemVOS = BeanCopyUtils.copyArrays(wxOrderItems, MobileOrderItemVO::new);
|
||||
if (CollectionUtils.isEmpty(wxOrderItemVOS)) {
|
||||
vos.add(vo);
|
||||
continue;
|
||||
}
|
||||
for (MobileOrderItemVO wxOrderItemVO : wxOrderItemVOS) {
|
||||
if (wxOrderItemVO.getProductId() != null) {
|
||||
JkProduct product = productService.getById(wxOrderItemVO.getProductId());
|
||||
if (product != null){
|
||||
wxOrderItemVO.setProductName(product.getProductName());
|
||||
wxOrderItemVO.setImage(product.getProductImage());
|
||||
}
|
||||
} else if (wxOrderItemVO.getComboId() != null) {
|
||||
Combo combo = comboService.getById(wxOrderItemVO.getComboId());
|
||||
if (combo != null){
|
||||
wxOrderItemVO.setProductName(combo.getComboName());
|
||||
wxOrderItemVO.setImage(combo.getImage());
|
||||
}
|
||||
}
|
||||
}
|
||||
vo.setOrderItemVOS((List<MobileOrderItemVO>) wxOrderItemVOS);
|
||||
vos.add(vo);
|
||||
}
|
||||
Page<MobileOrderVO> voPage = new Page<>();
|
||||
voPage.setTotal(orderPage.getTotal());
|
||||
voPage.setSize(orderPage.getSize());
|
||||
voPage.setCurrent(orderPage.getCurrent());
|
||||
voPage.setRecords(vos);
|
||||
return voPage;
|
||||
}
|
||||
|
||||
@GetMapping("/getSelfOneOrder")
|
||||
public MobileOrderDetailVO getSelfOneOrder(@RequestParam("orderId") String orderId, HttpServletRequest request) {
|
||||
MobileOrder order = mobileOrderMapper.selectById(orderId);
|
||||
if (Objects.isNull(order)) {
|
||||
return new MobileOrderDetailVO();
|
||||
}
|
||||
MobileOrderDetailVO vo = new MobileOrderDetailVO();
|
||||
BeanUtils.copyProperties(order, vo);
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (Objects.isNull(currentUser) || !currentUser.getId().equals(order.getMobileUserId())) {
|
||||
throw new ServiceException(401, "无权限访问");
|
||||
}
|
||||
if (order.getStoreId() != null) {
|
||||
JkStore jkStore = storeService.getById(order.getStoreId());
|
||||
vo.setJkStore(jkStore);
|
||||
}
|
||||
if (order.getPhysioId() != null) {
|
||||
JkPhysio jkPhysio = physioService.getById(order.getPhysioId());
|
||||
vo.setJkPhysio(jkPhysio);
|
||||
}
|
||||
if (order.getProductId() != null){
|
||||
JkProduct jkProduct = productService.getById(order.getProductId());
|
||||
vo.setProductName(jkProduct.getProductName());
|
||||
}
|
||||
if (order.getComboId() != null){
|
||||
Combo combo = comboService.getById(order.getComboId());
|
||||
vo.setProductName(combo.getComboName());
|
||||
}
|
||||
if (order.getCourseId() != null){
|
||||
Course course = courseMapper.selectById(order.getCourseId());
|
||||
vo.setProductName(course.getTitle());
|
||||
}
|
||||
List<MobileOrderItem> wxOrderItems = mobileOrderItemMapper.selectList(new LambdaQueryWrapper<MobileOrderItem>().eq(MobileOrderItem::getMobileOrderId, order.getOrderId()));
|
||||
if (CollectionUtils.isNotEmpty(wxOrderItems)) {
|
||||
Collection<MobileOrderItemVO> wxOrderItemVOS = BeanCopyUtils.copyArrays(wxOrderItems, MobileOrderItemVO::new);
|
||||
for (MobileOrderItemVO itemVO : wxOrderItemVOS) {
|
||||
if (itemVO.getProductId() != null) {
|
||||
JkProduct product = productService.getById(itemVO.getProductId());
|
||||
itemVO.setProductName(product.getProductName());
|
||||
itemVO.setImage(product.getProductImage());
|
||||
} else if (itemVO.getComboId() != null) {
|
||||
Combo combo = comboService.getById(itemVO.getComboId());
|
||||
itemVO.setImage(combo.getImage());
|
||||
itemVO.setProductName(combo.getComboName());
|
||||
}
|
||||
}
|
||||
vo.setOrderItemVOS((List<MobileOrderItemVO>) wxOrderItemVOS);
|
||||
}
|
||||
MobileAppUser user = mobileAppUserMapper.selectOne(new LambdaQueryWrapper<MobileAppUser>().eq(MobileAppUser::getId, order.getMobileUserId()));
|
||||
vo.setMobileAppUser(user);
|
||||
return vo;
|
||||
}
|
||||
|
||||
@GetMapping("/getSortSum")
|
||||
public JSONObject getSum(HttpServletRequest request) {
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
JSONObject of = JSONObject.of();
|
||||
List<MobileOrder> list = mobileOrderMapper.selectList(new LambdaQueryWrapper<MobileOrder>().eq(MobileOrder::getMobileUserId, currentUser.getId()));
|
||||
List<MobileOrder> noAfterSales = list.stream().filter(o -> o.getAfterSaleStatus().equals(0)).collect(Collectors.toList());
|
||||
long unpaid = noAfterSales.stream().filter(o -> OrderStatus.unpaid.name().equals(o.getStatus())).count();
|
||||
of.put("待付款", unpaid);
|
||||
long daifahuo = noAfterSales.stream().filter(o -> OrderStatus.not_shipped.name().equals(o.getStatus())).count();
|
||||
of.put("待发货", daifahuo);
|
||||
long daishouhuo = noAfterSales.stream().filter(o -> (OrderStatus.shipped.name().equals(o.getStatus()) || OrderStatus.unverified.name().equals(o.getStatus()))).count();
|
||||
of.put("待收货/使用", daishouhuo);
|
||||
long daipingjia = noAfterSales.stream().filter(o -> (OrderStatus.received.name().equals(o.getStatus()) || OrderStatus.verified.name().equals(o.getStatus()))).count();
|
||||
of.put("待评价", daipingjia);
|
||||
ArrayList<Integer> integers = Lists.newArrayList(0, 5, 6, 7);
|
||||
long tuikuan = list.stream().filter(o -> !integers.contains(o.getAfterSaleStatus())).count();
|
||||
of.put("退款", tuikuan);
|
||||
return of;
|
||||
}
|
||||
|
||||
@PostMapping("/comment")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResultData comment(@Validated @RequestBody OrderReview review){
|
||||
MobileOrder wxOrder = mobileOrderMapper.selectById(review.getOrderId());
|
||||
if (Objects.isNull(wxOrder)){
|
||||
throw new ServiceException("无此订单");
|
||||
}
|
||||
MobileAppUser wxUser = mobileAppUserMapper.selectOne(new LambdaQueryWrapper<MobileAppUser>().eq(MobileAppUser::getId, wxOrder.getMobileUserId()));
|
||||
if (Objects.isNull(wxUser)){
|
||||
throw new ServiceException("数据出现异常");
|
||||
}
|
||||
wxUser.setPoints(wxUser.getPoints() + 1);
|
||||
mobileAppUserMapper.updateById(wxUser);
|
||||
reviewMapper.insert(review);
|
||||
wxOrder.setStatus(OrderStatus.commented.name());
|
||||
mobileOrderMapper.updateById(wxOrder);
|
||||
return ResultData.success();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.config.WxProperties;
|
||||
import cn.unizk.constant.WxConstant;
|
||||
import cn.unizk.entity.po.MobileAppUser;
|
||||
import cn.unizk.entity.vo.MobileOrderVO;
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.exception.ServiceException;
|
||||
import cn.unizk.service.PayService;
|
||||
import cn.unizk.utils.JkSecurityUtil;
|
||||
import cn.unizk.wxPay.vo.WxPlaceOrderResVO;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/8/28 18:17
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet/wxPay")
|
||||
@Slf4j
|
||||
public class WxPayController {
|
||||
|
||||
@Resource(name = "wx")
|
||||
private PayService payService;
|
||||
@Resource
|
||||
private WxProperties wxProperties;
|
||||
|
||||
|
||||
@PostMapping("/placeOrder")
|
||||
public WxPlaceOrderResVO placeOrder(@RequestBody MobileOrderVO orderVO, HttpServletRequest request){
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request.getHeader(WxConstant.APPLET_LOGIN_SIGN));
|
||||
if (Objects.isNull(currentUser) || !currentUser.getId().equals(orderVO.getMobileUserId())){
|
||||
throw new ServiceException(403,"无权访问该资源");
|
||||
}
|
||||
return payService.wxPlaceOrder(orderVO);
|
||||
}
|
||||
|
||||
@PostMapping("/paySuccessCallBack")
|
||||
public ResultData callback(@RequestBody JSONObject body, HttpServletRequest request){
|
||||
|
||||
payService.wxPaySuccessHandler(request,body);
|
||||
return ResultData.success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,348 @@
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.config.JkProperties;
|
||||
import cn.unizk.constant.WxConstant;
|
||||
import cn.unizk.entity.po.*;
|
||||
import cn.unizk.entity.vo.ReportReqVO;
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.enums.OrderStatus;
|
||||
import cn.unizk.exception.ServiceException;
|
||||
import cn.unizk.mapper.*;
|
||||
import cn.unizk.service.JkPhysioService;
|
||||
import cn.unizk.service.UserAddressService;
|
||||
import cn.unizk.service.WxUserService;
|
||||
import cn.unizk.utils.JkSecurityUtil;
|
||||
import cn.unizk.utils.QRcodeUtil;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.time.Clock;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/10/13 18:38
|
||||
* @Version 1.0
|
||||
**/
|
||||
@RestController
|
||||
@RequestMapping("/applet/user")
|
||||
@Slf4j
|
||||
public class WxUserController {
|
||||
|
||||
@Resource
|
||||
private MobileAppUserMapper mobileAppUserMapper;
|
||||
@Resource
|
||||
private MobileUserAddressMapper mobileUserAddressMapper;
|
||||
@Resource
|
||||
private MobileOrderMapper mobileOrderMapper;
|
||||
@Resource
|
||||
private SysDictMapper sysDictMapper;
|
||||
@Resource
|
||||
private GrfPjMapper grfPjMapper;
|
||||
@Resource
|
||||
private MobileAppUserAccountMapper mobileAppUserAccountMapper;
|
||||
@Resource
|
||||
private RechargePackageMapper rechargePackageMapper;
|
||||
@Resource
|
||||
private JkPhysioService jkPhysioService;
|
||||
@Autowired
|
||||
@Qualifier("kryoRedisTemplate")
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
@Resource
|
||||
private JkProperties jkProperties;
|
||||
@Resource
|
||||
private UserFreeTrialInfoMapper userFreeTrialInfoMapper;
|
||||
|
||||
|
||||
@GetMapping("/freeTrialQRcode")
|
||||
public void freeTrial(HttpServletResponse response,HttpServletRequest request){
|
||||
log.info("获取二维码");
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (Objects.isNull(currentUser)){
|
||||
throw new ServiceException(401,"登录已过期");
|
||||
}
|
||||
String url = "hello,userId=" + currentUser.getId();
|
||||
QRcodeUtil.generateQrcode(response,url,null);
|
||||
}
|
||||
|
||||
@GetMapping("/checkFreeTrial")
|
||||
public ResultData<JSONObject> checkFree(HttpServletRequest request){
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
UserFreeTrialInfo userFreeTrialInfo = userFreeTrialInfoMapper.selectOne(new LambdaQueryWrapper<UserFreeTrialInfo>()
|
||||
.eq(UserFreeTrialInfo::getUserId, currentUser.getId()));
|
||||
MobileAppUser user = mobileAppUserMapper.selectById(currentUser.getId());
|
||||
ResultData<JSONObject> resultData = new ResultData<>();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
resultData.setCode(200);
|
||||
if (Objects.isNull(userFreeTrialInfo)){
|
||||
jsonObject.put("flag",0);
|
||||
}else {
|
||||
jsonObject.put("flag",1);
|
||||
}
|
||||
jsonObject.put("firstTrial",user.getFreeTrial());
|
||||
resultData.setData(jsonObject);
|
||||
return resultData;
|
||||
}
|
||||
|
||||
@PostMapping("/saveFreeTrialInfo")
|
||||
public ResultData saveFreeTrialInfo(HttpServletRequest request,@RequestBody UserFreeTrialInfo info){
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
UserFreeTrialInfo userFreeTrialInfo = userFreeTrialInfoMapper.selectOne(new LambdaQueryWrapper<UserFreeTrialInfo>()
|
||||
.eq(UserFreeTrialInfo::getUserId, currentUser.getId()));
|
||||
if (Objects.nonNull(userFreeTrialInfo)){
|
||||
throw new ServiceException("用户已存在数据");
|
||||
}
|
||||
info.setUserId(currentUser.getId());
|
||||
info.setCreateTime(LocalDateTime.now());
|
||||
userFreeTrialInfoMapper.insert(info);
|
||||
return ResultData.success();
|
||||
}
|
||||
|
||||
@PostMapping("/editUserInfo")
|
||||
public ResultData editUserInfo(@RequestBody MobileAppUser user){
|
||||
mobileAppUserMapper.updateById(user);
|
||||
return ResultData.success();
|
||||
}
|
||||
|
||||
@GetMapping("/getUserIdType")
|
||||
public ResultData<Integer> getUserIdType(HttpServletRequest request){
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (Objects.isNull(currentUser)){
|
||||
throw new ServiceException(401,"登录已过期");
|
||||
}
|
||||
JkPhysio one = jkPhysioService.getOne(new LambdaQueryWrapper<JkPhysio>().eq(JkPhysio::getPhysioTel, currentUser.getPhoneNumber()));
|
||||
ResultData<Integer> data = new ResultData<>();
|
||||
data.setCode(200);
|
||||
if (Objects.isNull(one)){
|
||||
data.setData(0);
|
||||
}else {
|
||||
data.setData(1);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/switchIdType")
|
||||
public ResultData switchIdType(HttpServletRequest request,@RequestParam("type") String type){
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (Objects.isNull(currentUser)){
|
||||
throw new ServiceException(401,"登录已过期");
|
||||
}
|
||||
if (!type.equals("C") && !type.equals("P")){
|
||||
throw new ServiceException("未知的身份类型");
|
||||
}
|
||||
currentUser.setUserType(type);
|
||||
mobileAppUserMapper.updateById(currentUser);
|
||||
redisTemplate.delete(WxConstant.CACHE_TOKEN_KEY + currentUser.getPhoneNumber());
|
||||
redisTemplate.opsForValue().set(WxConstant.CACHE_TOKEN_KEY + currentUser.getPhoneNumber(), currentUser, jkProperties.getTokenExpireTime(), TimeUnit.DAYS);
|
||||
return ResultData.success();
|
||||
}
|
||||
|
||||
@PostMapping("/rememberDia")
|
||||
public ResultData<Integer> rememberDia(HttpServletRequest request, @Validated @RequestBody ReportReqVO vo) {
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (Objects.isNull(currentUser)) {
|
||||
throw new ServiceException(401, "登录已过期");
|
||||
}
|
||||
MobileAppUser user = new MobileAppUser();
|
||||
user.setId(currentUser.getId());
|
||||
user.setSymptom(vo.getReport());
|
||||
user.setAge(vo.getAge());
|
||||
user.setHeight(vo.getHeight());
|
||||
user.setWeight(vo.getWeight());
|
||||
user.setGender(vo.getGender());
|
||||
// user.setTemplateId(vo.getTemplateId());
|
||||
user.setPainNumber(vo.getPainNumber());
|
||||
mobileAppUserMapper.updateById(user);
|
||||
List<String> integers = Lists.newArrayList("1", "2", "4", "5", "7", "8", "10", "11", "12", "13");
|
||||
boolean b = false;
|
||||
int t = 2;
|
||||
if (vo.getPainNumber().contains(",")) {
|
||||
List<String> ids = Arrays.asList(vo.getPainNumber().split(","));
|
||||
for (String id : ids) {
|
||||
if (!integers.contains(id)) {
|
||||
b = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!b) {
|
||||
if ("000".equals(vo.getCode1()) && "000".equals(vo.getCode2())) {
|
||||
t = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!integers.contains(vo.getPainNumber())) {
|
||||
b = true;
|
||||
} else {
|
||||
if ("000".equals(vo.getCode1()) && "000".equals(vo.getCode2())) {
|
||||
t = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
ResultData<Integer> data = new ResultData<>();
|
||||
data.setCode(200);
|
||||
data.setData(t);
|
||||
return data;
|
||||
}
|
||||
|
||||
@GetMapping("/addresses")
|
||||
public List<MobileUserAddress> addresses(HttpServletRequest request) {
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (Objects.isNull(currentUser)) {
|
||||
throw new ServiceException(401, "登录已过期");
|
||||
}
|
||||
return mobileUserAddressMapper.selectList(new LambdaQueryWrapper<MobileUserAddress>()
|
||||
.eq(MobileUserAddress::getMobileUserId, currentUser.getId()));
|
||||
}
|
||||
|
||||
@PostMapping("/addOrUpdateAddress")
|
||||
public int addOrUpdateAddress(@RequestBody MobileUserAddress address, HttpServletRequest request) {
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (currentUser == null) {
|
||||
throw new ServiceException(401, "登陆已过期");
|
||||
}
|
||||
if (!currentUser.getId().equals(address.getMobileUserId())) {
|
||||
throw new ServiceException(403, "无权访问");
|
||||
}
|
||||
List<MobileUserAddress> wxUserAddresses = mobileUserAddressMapper.selectList(null);
|
||||
if (CollectionUtils.isEmpty(wxUserAddresses)) {
|
||||
address.setDefaultAddr(0);
|
||||
}
|
||||
if (address.getAddressId() == null && address.getDefaultAddr() == 0) {
|
||||
MobileUserAddress one = mobileUserAddressMapper.selectOne(new LambdaQueryWrapper<MobileUserAddress>().eq(MobileUserAddress::getDefaultAddr, 0));
|
||||
if (Objects.nonNull(one)) {
|
||||
one.setDefaultAddr(1);
|
||||
mobileUserAddressMapper.updateById(one);
|
||||
}
|
||||
}
|
||||
if (address.getAddressId() != null && address.getDefaultAddr() == 0) {
|
||||
MobileUserAddress userAddress = mobileUserAddressMapper.selectById(address.getAddressId());
|
||||
if (Objects.isNull(userAddress)) {
|
||||
throw new ServiceException("no this address");
|
||||
}
|
||||
if (userAddress.getDefaultAddr() != 0) {
|
||||
MobileUserAddress one = mobileUserAddressMapper.selectOne(new LambdaQueryWrapper<MobileUserAddress>().eq(MobileUserAddress::getDefaultAddr, 0));
|
||||
if (Objects.nonNull(one)) {
|
||||
one.setDefaultAddr(1);
|
||||
mobileUserAddressMapper.updateById(one);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (address.getAddressId() == null) {
|
||||
address.setCreateTime(LocalDateTime.now(Clock.systemDefaultZone()));
|
||||
} else {
|
||||
address.setUpdateTime(LocalDateTime.now(Clock.systemDefaultZone()));
|
||||
}
|
||||
mobileUserAddressMapper.insertOrUpdate(address);
|
||||
return address.getAddressId();
|
||||
}
|
||||
|
||||
@PostMapping("/deleteAddr")
|
||||
public int deleteAddr(@RequestParam("addressId") Integer addressId, HttpServletRequest request) {
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (currentUser == null) {
|
||||
throw new ServiceException(401, "登陆已过期");
|
||||
}
|
||||
MobileUserAddress userAddress = mobileUserAddressMapper.selectById(addressId);
|
||||
if (Objects.isNull(userAddress)) {
|
||||
throw new ServiceException("地址不存在");
|
||||
}
|
||||
if (!currentUser.getId().equals(userAddress.getMobileUserId())) {
|
||||
throw new ServiceException(403, "无权访问");
|
||||
}
|
||||
return mobileUserAddressMapper.deleteById(addressId);
|
||||
}
|
||||
|
||||
@PostMapping("/applyRefund")
|
||||
public int applyRefund(@RequestBody MobileOrder order, HttpServletRequest request) {
|
||||
MobileOrder mobileOrder = mobileOrderMapper.selectById(order.getOrderId());
|
||||
if (Objects.isNull(mobileOrder)) {
|
||||
throw new ServiceException("查无此单");
|
||||
}
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (currentUser == null || !currentUser.getId().equals(mobileOrder.getMobileUserId())) {
|
||||
throw new ServiceException("无权访问");
|
||||
}
|
||||
// wxOrder.setStatus(OrderStatus.request_refund.name());
|
||||
mobileOrder.setApplyRefundTime(LocalDateTime.now());
|
||||
mobileOrder.setRefundReason(order.getRefundReason());
|
||||
mobileOrder.setRefundTrackingNumber(order.getRefundTrackingNumber());
|
||||
mobileOrder.setAfterSaleStatus(order.getAfterSaleStatus());
|
||||
return mobileOrderMapper.updateById(mobileOrder);
|
||||
}
|
||||
|
||||
@PostMapping("/refundReason")
|
||||
public int refundReason(@RequestParam("orderId") String orderId, @RequestParam("reason") String reason, HttpServletRequest request) {
|
||||
MobileOrder mobileOrder = mobileOrderMapper.selectById(orderId);
|
||||
if (Objects.isNull(mobileOrder)) {
|
||||
throw new ServiceException("无此订单");
|
||||
}
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
if (currentUser == null || !currentUser.getId().equals(mobileOrder.getMobileUserId())) {
|
||||
throw new ServiceException("无权访问");
|
||||
}
|
||||
mobileOrder.setRefundReason(reason);
|
||||
return mobileOrderMapper.updateById(mobileOrder);
|
||||
}
|
||||
|
||||
@GetMapping("/getGrfScanPrice")
|
||||
public ResultData getGrfScanPrice(HttpServletRequest request, @RequestParam(value = "id", required = false) Integer id) {
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
List<MobileOrder> wxOrders = mobileOrderMapper.selectList(new LambdaQueryWrapper<MobileOrder>()
|
||||
.eq(MobileOrder::getMobileUserId, currentUser.getId())
|
||||
.eq(MobileOrder::getStatus, OrderStatus.paid.name())
|
||||
.eq(MobileOrder::getOrderType, 1));
|
||||
ResultData<String> data = new ResultData<>();
|
||||
if (CollectionUtils.isEmpty(wxOrders)) {
|
||||
data.setCode(200);
|
||||
SysDict sysDict = sysDictMapper.selectOne(new LambdaQueryWrapper<SysDict>().eq(SysDict::getDictType, "grf"));
|
||||
data.setData(Objects.nonNull(sysDict) ? sysDict.getDictValue() : "99");
|
||||
return data;
|
||||
} else {
|
||||
if (id == null) {
|
||||
throw new ServiceException("您不是首次体验用户!");
|
||||
}
|
||||
GrfPj grfPj = grfPjMapper.selectById(id);
|
||||
data.setCode(200);
|
||||
data.setData(grfPj.getPrice().toString());
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/getGrfPrice")
|
||||
public List<GrfPj> list() {
|
||||
return grfPjMapper.selectList(null);
|
||||
}
|
||||
|
||||
@GetMapping("/getAccountBalance")
|
||||
public MobileAppUserAccount account(HttpServletRequest request) {
|
||||
MobileAppUser currentUser = JkSecurityUtil.getCurrentUser(request);
|
||||
MobileAppUserAccount account = mobileAppUserAccountMapper.selectOne(new LambdaQueryWrapper<MobileAppUserAccount>().eq(MobileAppUserAccount::getMobileUserId, currentUser.getId()));
|
||||
if (account == null) {
|
||||
return new MobileAppUserAccount();
|
||||
}
|
||||
return account;
|
||||
}
|
||||
|
||||
@GetMapping("/getVipRechargePackage")
|
||||
public List<RechargePackage> rechargePackages() {
|
||||
return rechargePackageMapper.selectList(null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
package cn.unizk.controller;
|
||||
|
||||
import cn.unizk.constant.WxConstant;
|
||||
import cn.unizk.entity.po.WxUser;
|
||||
import cn.unizk.entity.vo.CallbackResponse;
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.exception.ServiceException;
|
||||
import cn.unizk.mapper.WxOrderMapper;
|
||||
import cn.unizk.utils.JkSecurityUtil;
|
||||
import cn.unizk.wxPay.vo.WxOrderVO;
|
||||
import cn.unizk.wxPay.vo.WxPlaceOrderResVO;
|
||||
import cn.unizk.xunfupay.dto.AddFzAccountDTO;
|
||||
import cn.unizk.xunfupay.dto.PaySuccessCallbackDTO;
|
||||
import cn.unizk.xunfupay.dto.QueryOrderTradeDetailResponse;
|
||||
import cn.unizk.xunfupay.service.XunFuPayService;
|
||||
import cn.unizk.xunfupay.util.FileUploadUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
|
||||
*/
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/9/22 16:35
|
||||
* @Version 1.0
|
||||
**//*
|
||||
|
||||
@RestController
|
||||
@Slf4j
|
||||
@RequestMapping("/applet/xunfuPay")
|
||||
public class XunFuPayController {
|
||||
|
||||
@Resource
|
||||
private XunFuPayService xunFuPayService;
|
||||
@Resource
|
||||
private WxOrderMapper orderMapper;
|
||||
|
||||
*/
|
||||
/**
|
||||
* 绑定微信小程序appid
|
||||
* @return
|
||||
*//*
|
||||
|
||||
@PostMapping("/bindWxAppid")
|
||||
public boolean bindWxAppid(){
|
||||
return xunFuPayService.bindWxAppID();
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* 开通分账功能
|
||||
* @return
|
||||
*//*
|
||||
|
||||
@PostMapping("/activateFz")
|
||||
public boolean activateFz(){
|
||||
return xunFuPayService.activateFz();
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* 添加分账接收方账户
|
||||
* @param dto
|
||||
* @return
|
||||
*//*
|
||||
|
||||
@PostMapping("/addFzAccount")
|
||||
public ResultData addFzAccount(@RequestBody AddFzAccountDTO dto,@RequestParam("storeId") Integer storeId){
|
||||
return xunFuPayService.addFzAccount(dto,storeId);
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* idCardFront-法人身份证正面(人面),
|
||||
* idCardBack-法人身份证反面(国徽面),
|
||||
* personWithIdCard-法人手持身份证,
|
||||
* bankCard-结算银行卡照片(对私上送),
|
||||
* license-营业执照,
|
||||
* openAccountLicenses-开户许可证(对公上送)
|
||||
* @return url
|
||||
*//*
|
||||
|
||||
@PostMapping("/uploadFile/{fileType}")
|
||||
public String getUploadToken(@RequestParam("file")MultipartFile file, @PathVariable("fileType") String fileType){
|
||||
String filename = file.getOriginalFilename();
|
||||
if (StringUtils.isBlank(filename) || !filename.contains(".")){
|
||||
throw new ServiceException("文件类型不正确");
|
||||
}
|
||||
String name = filename.substring(filename.lastIndexOf("/") + 1);
|
||||
try {
|
||||
return FileUploadUtil.autoUploadFile(file.getInputStream(),name,fileType);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return "file upload failure";
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* 分账接收方签约
|
||||
* @return
|
||||
* @throws NoSuchAlgorithmException
|
||||
*//*
|
||||
|
||||
@PostMapping("/qianyue")
|
||||
public String qianyue() throws NoSuchAlgorithmException {
|
||||
return xunFuPayService.qianyue();
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* 下单
|
||||
* @param vo
|
||||
* @param request
|
||||
* @return
|
||||
*//*
|
||||
|
||||
@PostMapping("/placeOrder")
|
||||
public WxPlaceOrderResVO placeOrder(@RequestBody WxOrderVO vo, HttpServletRequest request){
|
||||
WxUser currentUser = JkSecurityUtil.getCurrentUser(request.getHeader(WxConstant.APPLET_LOGIN_SIGN));
|
||||
if (Objects.isNull(currentUser) || !currentUser.getOpenid().equals(vo.getOpenid())){
|
||||
throw new ServiceException(403,"无权访问该资源");
|
||||
}
|
||||
return xunFuPayService.xunfuPlaceOrder(vo);
|
||||
}
|
||||
|
||||
@PostMapping("/callback")
|
||||
public CallbackResponse callback(@RequestBody PaySuccessCallbackDTO dto){
|
||||
log.info("环迅支付成功回调返回参数:{}",dto.toString());
|
||||
try {
|
||||
QueryOrderTradeDetailResponse queryOrderTradeDetailResponse = xunFuPayService.queryOrderTradeDetailResponse(dto.getOrderNo());
|
||||
String settleAmount = queryOrderTradeDetailResponse.getSettleAmount();
|
||||
String orderNo = queryOrderTradeDetailResponse.getOrderNo();
|
||||
boolean b = xunFuPayService.applyFz(orderNo, settleAmount);
|
||||
log.info("订单{}分账是否成功:{}",orderNo,b);
|
||||
//修改订单支付状态
|
||||
orderMapper.updateStatusToPaid(orderNo);
|
||||
return new CallbackResponse("1");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
return new CallbackResponse("1");
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,45 @@
|
||||
package cn.unizk.filter;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.annotation.WebFilter;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/9/13 17:01
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Slf4j
|
||||
public class JkCorsFilter implements Filter {
|
||||
@Override
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
||||
HttpServletResponse response = (HttpServletResponse) servletResponse;
|
||||
HttpServletRequest request = (HttpServletRequest) servletRequest;
|
||||
log.info("进入jkcorsfilter过滤器");
|
||||
// 允许任何域名(生产环境请换成具体域名)
|
||||
response.setHeader("Access-Control-Allow-Origin", "http://369.peaktcm.com:9000");
|
||||
|
||||
// 允许带自定义请求头
|
||||
response.setHeader("Access-Control-Allow-Headers", "Content-Type,token");
|
||||
|
||||
response.setHeader("Access-Control-Expose-Headers", "Authorization");
|
||||
|
||||
// 允许浏览器携带 cookie
|
||||
response.setHeader("Access-Control-Allow-Credentials", "true");
|
||||
|
||||
// 允许的 HTTP 方法
|
||||
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
|
||||
|
||||
// 关键:预检请求直接返回 200,其他正常放行
|
||||
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
|
||||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
return; // 预检结束
|
||||
}
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package cn.unizk.huifupay.config.properties;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/9/28 16:49
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "huifu")
|
||||
public class HuiFuProperties {
|
||||
|
||||
private String huifuId;
|
||||
|
||||
private String payApi;
|
||||
|
||||
private String refundApi;
|
||||
|
||||
private String publicKey;
|
||||
|
||||
private String privateKey;
|
||||
|
||||
private String notifyUrl;
|
||||
|
||||
private String productId;
|
||||
|
||||
private String configureAppletCallbackUrl;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package cn.unizk.huifupay.config.properties;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2026/3/11 10:43
|
||||
* @Version 1.0
|
||||
**/
|
||||
@ConfigurationProperties(prefix = "huifu-vendor")
|
||||
@Component
|
||||
@Getter
|
||||
@Setter
|
||||
public class HuiFuVendorProperties {
|
||||
|
||||
private String sysId;
|
||||
|
||||
private String huifuId;
|
||||
|
||||
private String publicKey;
|
||||
|
||||
private String privateKey;
|
||||
|
||||
private String productId;
|
||||
|
||||
private String notifyUrl;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package cn.unizk.huifupay.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/9/29 13:35
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Data
|
||||
public class HuifuBaseResponse {
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package cn.unizk.huifupay.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2026/4/30 10:34
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Data
|
||||
public class HuifuPlaceOrderParamBaseDTO<T> {
|
||||
private String openid;
|
||||
|
||||
private Integer userId;
|
||||
private String goodsDesc;
|
||||
private String placeOrderAmount;
|
||||
private T t;
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
package cn.unizk.huifupay.service;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.unizk.config.WxProperties;
|
||||
import cn.unizk.entity.po.JkStore;
|
||||
import cn.unizk.entity.po.MobileOrder;
|
||||
import cn.unizk.entity.po.MobileOrderItem;
|
||||
import cn.unizk.entity.vo.MobileOrderItemVO;
|
||||
import cn.unizk.entity.vo.MobileOrderVO;
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.enums.OrderStatus;
|
||||
import cn.unizk.exception.ServiceException;
|
||||
import cn.unizk.huifupay.config.properties.HuiFuProperties;
|
||||
import cn.unizk.huifupay.utils.HuifuSignUtil;
|
||||
import cn.unizk.mapper.JkStoreMapper;
|
||||
import cn.unizk.mapper.MobileOrderItemMapper;
|
||||
import cn.unizk.mapper.MobileOrderMapper;
|
||||
import cn.unizk.service.PayService;
|
||||
import cn.unizk.utils.BeanCopyUtils;
|
||||
import cn.unizk.utils.HttpUtil;
|
||||
import cn.unizk.wxPay.service.WxPayOrderService;
|
||||
import cn.unizk.wxPay.vo.WxPlaceOrderResVO;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.DecimalFormat;
|
||||
import java.time.Clock;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/9/28 16:28
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Service("huifu")
|
||||
@Slf4j
|
||||
public class HuiFuPayService implements PayService {
|
||||
|
||||
@Resource
|
||||
private WxProperties wxProperties;
|
||||
@Resource
|
||||
private HuiFuProperties huiFuProperties;
|
||||
@Resource
|
||||
private MobileOrderMapper mobileOrderMapper;
|
||||
/*@Resource
|
||||
private WxOrderCloseScheduler wxOrderCloseScheduler;*/
|
||||
@Resource
|
||||
private WxPayOrderService wxPayOrderService;
|
||||
@Resource
|
||||
private MobileOrderItemMapper mobileOrderItemMapper;
|
||||
@Resource
|
||||
private JkStoreMapper jkStoreMapper;
|
||||
|
||||
|
||||
/**
|
||||
* 防重复支付,前端防抖处理加随机uuid传给后端,调下单接口返回成功后变换uuid,
|
||||
* 后端根据uuid+redission分布式锁+双重检查锁处理
|
||||
* @param orderVO
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public WxPlaceOrderResVO wxPlaceOrder(MobileOrderVO orderVO) {
|
||||
// String orderId = IdUtil.getSnowflakeNextIdStr();
|
||||
String outTradeNo = RandomStringUtils.randomNumeric(30);
|
||||
List<MobileOrderItemVO> orderItemVOS = orderVO.getOrderItemVOS();
|
||||
if (CollectionUtils.isEmpty(orderItemVOS)){
|
||||
throw new ServiceException("参数错误");
|
||||
}
|
||||
boolean b = orderItemVOS.stream()
|
||||
.map(MobileOrderItemVO::getStoreId)
|
||||
.distinct()
|
||||
.count() == 1;
|
||||
Map<String,Object> params = new HashMap<>();
|
||||
params.put("sys_id",huiFuProperties.getHuifuId());
|
||||
params.put("product_id","EDUSTD");
|
||||
JSONObject data = JSONObject.of();
|
||||
data.put("req_date", DateUtil.format(new Date(),"yyyyMMdd"));
|
||||
data.put("req_seq_id",outTradeNo);
|
||||
data.put("huifu_id",huiFuProperties.getHuifuId());
|
||||
data.put("goods_desc",orderVO.getDescription());
|
||||
data.put("trade_type","T_MINIAPP");
|
||||
String sumPrice = new DecimalFormat("0.00").format(orderVO.getTotalPrice());
|
||||
data.put("trans_amt",sumPrice);
|
||||
DateTime dateTime = DateUtil.offsetMinute(new Date(), +5);
|
||||
String yyyyMMddHHmmss = DateUtil.format(dateTime, "yyyyMMddHHmmss");
|
||||
data.put("time_expire",yyyyMMddHHmmss);
|
||||
JSONObject wx_data = JSONObject.of();
|
||||
wx_data.put("sub_appid",wxProperties.getAppid());
|
||||
wx_data.put("sub_openid",orderVO.getOpenid());
|
||||
data.put("wx_data",wx_data.toString());
|
||||
data.put("fee_flag",2);
|
||||
//分账对象
|
||||
JSONObject acct_split_bunch = JSONObject.of();
|
||||
JSONArray array = new JSONArray();
|
||||
if (b){
|
||||
JSONObject acct_infos2 = new JSONObject();
|
||||
JkStore jkStore = jkStoreMapper.selectById(orderVO.getOrderItemVOS().get(0).getStoreId());
|
||||
if (Objects.isNull(jkStore)){
|
||||
log.info("门店不存在,门店id:{},不参与分账",orderVO.getOrderItemVOS().get(0).getStoreId());
|
||||
}else {
|
||||
if (StringUtils.isBlank(jkStore.getHuifuId()) || jkStore.getProfitSharingPercentage() == null){
|
||||
throw new ServiceException(String.format("门店:%s的汇付id或分账比为空",jkStore.getStoreName()));
|
||||
}
|
||||
acct_infos2.put("huifu_id",jkStore.getHuifuId());
|
||||
// acct_infos2.put("huifu_id","6666000179598737");
|
||||
// acct_infos2.put("acct_id","755980768110008");
|
||||
//分账比例
|
||||
log.info("子商户分账比例为:{}",jkStore.getProfitSharingPercentage().toString());
|
||||
acct_infos2.put("percentage_div",jkStore.getProfitSharingPercentage().toString());
|
||||
array.add(acct_infos2);
|
||||
|
||||
JSONObject parent_acct_infos = new JSONObject();
|
||||
parent_acct_infos.put("huifu_id",huiFuProperties.getHuifuId());
|
||||
BigDecimal b100 = new BigDecimal("100.00");
|
||||
BigDecimal surplusPercent = b100.subtract(jkStore.getProfitSharingPercentage());
|
||||
log.info("主商户分账比例为:{}",surplusPercent);
|
||||
parent_acct_infos.put("percentage_div",surplusPercent.toString());
|
||||
array.add(parent_acct_infos);
|
||||
}
|
||||
}else {
|
||||
double percent = 0.00;
|
||||
for (MobileOrderItemVO itemVO : orderItemVOS) {
|
||||
JkStore jkStore = jkStoreMapper.selectById(itemVO.getStoreId());
|
||||
if (Objects.isNull(jkStore)){
|
||||
throw new ServiceException(String.format("门店不存在,门店ID:%d",orderItemVOS.get(0).getStoreId()));
|
||||
}
|
||||
if (StringUtils.isBlank(jkStore.getHuifuId()) || jkStore.getProfitSharingPercentage() == null){
|
||||
throw new ServiceException(String.format("门店:%s的汇付id或分账比为空",jkStore.getStoreName()));
|
||||
}
|
||||
JSONObject acct_infos2 = new JSONObject();
|
||||
acct_infos2.put("huifu_id",jkStore.getHuifuId());
|
||||
double singleProductPercent = (itemVO.getPrice().doubleValue() / orderVO.getTotalPrice().doubleValue()) * jkStore.getProfitSharingPercentage().doubleValue();
|
||||
acct_infos2.put("percentage_div",singleProductPercent);
|
||||
percent += singleProductPercent;
|
||||
array.add(acct_infos2);
|
||||
}
|
||||
double surplusPercent = 100.00 - percent;
|
||||
JSONObject parent_acct_infos = new JSONObject();
|
||||
parent_acct_infos.put("huifu_id",huiFuProperties.getHuifuId());
|
||||
parent_acct_infos.put("percentage_div",String.valueOf(surplusPercent));
|
||||
array.add(parent_acct_infos);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(array)){
|
||||
acct_split_bunch.put("acct_infos",array);
|
||||
acct_split_bunch.put("percentage_flag","Y");
|
||||
data.put("acct_split_bunch",acct_split_bunch.toString());
|
||||
}
|
||||
data.put("notify_url",huiFuProperties.getNotifyUrl());
|
||||
TreeMap treeMap = JSONObject.parseObject(data.toString(), TreeMap.class);
|
||||
JSONObject signBody = new JSONObject(treeMap);
|
||||
// String s = Base64.getEncoder().encodeToString(huiFuProperties.getPrivateKey().getBytes(StandardCharsets.UTF_8));
|
||||
String sign = HuifuSignUtil.sign(signBody.toString(), huiFuProperties.getPrivateKey());
|
||||
params.put("sign",sign);
|
||||
params.put("data",data);
|
||||
log.info("下单请求参数:{}",params);
|
||||
String res = HttpUtil.doPostJson(huiFuProperties.getPayApi(), null, new JSONObject(params));
|
||||
log.info("汇付下单返回:{}",res);
|
||||
JSONObject response = JSONObject.parseObject(res);
|
||||
if (response == null){
|
||||
throw new ServiceException("下单失败");
|
||||
}
|
||||
JSONObject responseData = response.getJSONObject("data");
|
||||
String resp_code = responseData.getString("resp_code");
|
||||
String hf_seq_id = responseData.getString("hf_seq_id");
|
||||
if ("00000100".equals(resp_code)){
|
||||
log.info("订单:{}下单成功",outTradeNo);
|
||||
//生成订单
|
||||
|
||||
if (b){
|
||||
String orderId = IdUtil.getSnowflakeNextIdStr();
|
||||
MobileOrder wxOrder = new MobileOrder();
|
||||
BeanUtils.copyProperties(orderVO, wxOrder);
|
||||
wxOrder.setOutTradeNo(outTradeNo);
|
||||
wxOrder.setTotalPrice(orderVO.getTotalPrice());
|
||||
wxOrder.setStatus(OrderStatus.unpaid.name());
|
||||
wxOrder.setOrderId(orderId);
|
||||
wxOrder.setStoreId(orderItemVOS.get(0).getStoreId());
|
||||
wxOrder.setDeviceId(orderVO.getDeviceId());
|
||||
wxOrder.setPhysioId(orderVO.getPhysioId());
|
||||
wxOrder.setComboId(orderItemVOS.get(0).getComboId());
|
||||
/*wxOrder.setProductId(orderVO.getProductId());
|
||||
wxOrder.setComboId(orderVO.getComboId());*/
|
||||
wxOrder.setCreateTime(LocalDateTime.now(Clock.systemDefaultZone()));
|
||||
wxOrder.setRecipientPhone(orderVO.getRecipientPhone());
|
||||
wxOrder.setRecipientName(orderVO.getRecipientName());
|
||||
wxOrder.setReceivingAddress(orderVO.getReceivingAddress());
|
||||
wxOrder.setHfSeqId(hf_seq_id);
|
||||
mobileOrderMapper.insert(wxOrder);
|
||||
Collection<MobileOrderItem> orderItems = BeanCopyUtils.copyArrays(orderItemVOS, MobileOrderItem::new);
|
||||
orderItems.forEach(item -> item.setMobileOrderId(orderId));
|
||||
mobileOrderItemMapper.insert(orderItems);
|
||||
}else {
|
||||
List<Integer> storeIds = orderItemVOS.stream().map(MobileOrderItemVO::getStoreId).distinct().collect(Collectors.toList());
|
||||
Map<Integer,String> map = new HashMap<>();
|
||||
for (Integer storeId : storeIds) {
|
||||
String orderId = IdUtil.getSnowflakeNextIdStr();
|
||||
map.put(storeId,orderId);
|
||||
MobileOrder wxOrder = new MobileOrder();
|
||||
wxOrder.setOrderId(orderId);
|
||||
wxOrder.setOutTradeNo(outTradeNo);
|
||||
BigDecimal total = orderItemVOS.stream()
|
||||
.filter(vo -> storeId.equals(vo.getStoreId()))
|
||||
.map(MobileOrderItemVO::getPrice)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
wxOrder.setTotalPrice(total);
|
||||
wxOrder.setStatus(OrderStatus.unpaid.name());
|
||||
wxOrder.setStoreId(storeId);
|
||||
wxOrder.setCreateTime(LocalDateTime.now(Clock.systemDefaultZone()));
|
||||
wxOrder.setRecipientName(orderVO.getRecipientName());
|
||||
wxOrder.setRecipientPhone(orderVO.getRecipientPhone());
|
||||
wxOrder.setReceivingAddress(orderVO.getReceivingAddress());
|
||||
wxOrder.setHfSeqId(hf_seq_id);
|
||||
mobileOrderMapper.insert(wxOrder);
|
||||
}
|
||||
for (MobileOrderItemVO itemVO : orderItemVOS) {
|
||||
String orderId = map.get(itemVO.getStoreId());
|
||||
MobileOrderItem orderItem = new MobileOrderItem();
|
||||
BeanUtils.copyProperties(itemVO,orderItem);
|
||||
orderItem.setMobileOrderId(orderId);
|
||||
mobileOrderItemMapper.insert(orderItem);
|
||||
}
|
||||
}
|
||||
/*//将订单添加到关闭订单延迟队列
|
||||
wxOrderCloseScheduler.addCloseWxOrderTask(orderId, wxProperties.getPlaceOrder().getExpireTime() * 60 * 1000);
|
||||
//开启轮询查询订单支付状态
|
||||
try {
|
||||
wxPayOrderService.startPayStatusQuery(orderId);
|
||||
}catch (Exception e){
|
||||
log.error("开启订单支付状态轮询查询异常",e);
|
||||
}*/
|
||||
WxPlaceOrderResVO placeOrderResVO = new WxPlaceOrderResVO();
|
||||
String pay_info = responseData.getString("pay_info");
|
||||
JSONObject payInfo = JSONObject.parseObject(pay_info);
|
||||
placeOrderResVO.setTimestamp(payInfo.getString("timeStamp"));
|
||||
placeOrderResVO.setNonceStr(payInfo.getString("nonceStr"));
|
||||
placeOrderResVO.setSignType(payInfo.getString("signType"));
|
||||
// placeOrderResVO.setOrderId(orderId);
|
||||
placeOrderResVO.setPaySign(payInfo.getString("paySign"));
|
||||
placeOrderResVO.setPrepayId(payInfo.getString("package").split("=")[1]);
|
||||
return placeOrderResVO;
|
||||
}
|
||||
throw new ServiceException("下单失败");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ResultData wxPaySuccessHandler(HttpServletRequest request, JSONObject body) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String configureApplet() {
|
||||
JSONObject params = JSONObject.of();
|
||||
params.put("sys_id",huiFuProperties.getHuifuId());
|
||||
params.put("product_id",huiFuProperties.getProductId());
|
||||
JSONObject data = JSONObject.of();
|
||||
String reqSeqId = DateUtil.format(new Date(),"yyyyMMddHHmmss") + RandomStringUtils.randomNumeric(18);
|
||||
data.put("req_seq_id",reqSeqId);
|
||||
data.put("req_date",DateUtil.format(new Date(),"yyyyMMdd"));
|
||||
data.put("huifu_id",huiFuProperties.getHuifuId());
|
||||
data.put("fee_type","02");
|
||||
data.put("wx_applet_app_id",wxProperties.getAppid());
|
||||
data.put("wx_applet_secret",wxProperties.getSecret());
|
||||
data.put("async_return_url",huiFuProperties.getConfigureAppletCallbackUrl());
|
||||
params.put("data",data);
|
||||
String sign = HuifuSignUtil.sign(data, huiFuProperties.getPrivateKey());
|
||||
String url = "https://api.huifu.com/v2/merchant/busi/config";
|
||||
params.put("sign",sign);
|
||||
log.info("params={}",params);
|
||||
String res = HttpUtil.doPostJson(url, null, params);
|
||||
log.info("汇付微信商户配置小程序appid返回:{}",res);
|
||||
return "success";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,439 @@
|
||||
package cn.unizk.huifupay.service;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.unizk.config.WxProperties;
|
||||
import cn.unizk.entity.dto.CashOutDTO;
|
||||
import cn.unizk.entity.dto.CashOutResponse;
|
||||
import cn.unizk.entity.po.*;
|
||||
import cn.unizk.entity.vo.CourseVO;
|
||||
import cn.unizk.entity.vo.PayCourseVO;
|
||||
import cn.unizk.enums.OrderStatus;
|
||||
import cn.unizk.exception.ServiceException;
|
||||
import cn.unizk.huifupay.config.properties.HuiFuVendorProperties;
|
||||
import cn.unizk.huifupay.dto.HuifuPlaceOrderParamBaseDTO;
|
||||
import cn.unizk.huifupay.utils.HuifuSignUtil;
|
||||
import cn.unizk.huifupay.vo.DeviceScanPayVO;
|
||||
import cn.unizk.huifupay.vo.RechargeVO;
|
||||
import cn.unizk.mapper.*;
|
||||
import cn.unizk.utils.HttpUtil;
|
||||
import cn.unizk.utils.HuifuUtil;
|
||||
import cn.unizk.utils.JkSecurityUtil;
|
||||
import cn.unizk.wxPay.vo.WxPlaceOrderResVO;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2026/3/11 10:53
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class HuiFuVendorPayService {
|
||||
|
||||
@Resource
|
||||
private HuiFuVendorProperties vendorProperties;
|
||||
@Resource
|
||||
private WxProperties wxProperties;
|
||||
@Resource
|
||||
private MobileOrderMapper mobileOrderMapper;
|
||||
@Resource
|
||||
private JkStoreMapper jkStoreMapper;
|
||||
@Resource
|
||||
private DeviceMapper deviceMapper;
|
||||
@Resource
|
||||
private CashOutRecordMapper cashOutRecordMapper;
|
||||
@Resource
|
||||
private CourseMapper courseMapper;
|
||||
@Resource
|
||||
private WxVipRechargeMapper vipRechargeMapper;
|
||||
|
||||
private static final String PAY_API = "https://api.huifu.com/v3/trade/payment/jspay";
|
||||
private static final String YUE_PAY_API = "https://api.huifu.com/v2/trade/acctpayment/pay";
|
||||
private static final String COMMON_PARAM = "commonParam";
|
||||
private static final String AMOUNT = "amount";
|
||||
private static final String REQ_SEQ_ID = "req_seq_id";
|
||||
|
||||
/**
|
||||
* 聚合正扫,扫码付费
|
||||
*
|
||||
* @param vo
|
||||
* @return
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public WxPlaceOrderResVO vendorPay(DeviceScanPayVO vo) {
|
||||
if (StringUtils.isBlank(vo.getDeviceId())){
|
||||
throw new ServiceException("deviceId cannot be empty");
|
||||
}
|
||||
Device device = deviceMapper.selectById(vo.getDeviceId());
|
||||
if (Objects.isNull(device) || device.getStoreId() == null){
|
||||
throw new ServiceException("设备不存在或设备未与门店绑定");
|
||||
}
|
||||
JSONObject data = JSONObject.of();
|
||||
String now = DateUtil.format(new Date(), "yyyyMMdd");
|
||||
data.put("req_date", now);
|
||||
String snowId = IdUtil.getSnowflakeNextIdStr();
|
||||
String reqSeqId = HuifuUtil.getReqSeqId();
|
||||
data.put("req_seq_id", reqSeqId);
|
||||
data.put("huifu_id", vendorProperties.getHuifuId());
|
||||
data.put("goods_desc", vo.getGoodsDesc());
|
||||
data.put("trade_type", "T_MINIAPP");
|
||||
BigDecimal bd = new BigDecimal(vo.getAmount());
|
||||
bd = bd.setScale(2, RoundingMode.DOWN);
|
||||
data.put("trans_amt", bd.toString());
|
||||
JSONObject wx_data = JSONObject.of();
|
||||
wx_data.put("sub_appid", wxProperties.getAppid());
|
||||
wx_data.put("sub_openid", vo.getOpenid());
|
||||
data.put("wx_data", wx_data.toString());
|
||||
data.put("fee_flag", 2);
|
||||
data.put("notify_url", vendorProperties.getNotifyUrl());
|
||||
String sign = HuifuSignUtil.sign(data, vendorProperties.getPrivateKey());
|
||||
JSONObject commonParams = JSONObject.of();
|
||||
commonParams.put("sys_id", vendorProperties.getSysId());
|
||||
commonParams.put("product_id", vendorProperties.getProductId());
|
||||
commonParams.put("sign", sign);
|
||||
commonParams.put("data", data);
|
||||
log.info("commonParams={}", commonParams);
|
||||
String res = HttpUtil.doPostJson(PAY_API, null, commonParams);
|
||||
log.info("汇付下单返回:{}", res);
|
||||
JSONObject response = JSONObject.parseObject(res);
|
||||
if (response == null) {
|
||||
throw new ServiceException("下单失败");
|
||||
}
|
||||
JSONObject responseData = response.getJSONObject("data");
|
||||
String resp_code = responseData.getString("resp_code");
|
||||
String hf_seq_id = responseData.getString("hf_seq_id");
|
||||
if ("00000100".equals(resp_code) || "00000000".equals(resp_code)) {
|
||||
log.info("订单:{}下单成功", snowId);
|
||||
MobileOrder wxOrder = new MobileOrder();
|
||||
wxOrder.setOrderId(snowId);
|
||||
wxOrder.setOutTradeNo(reqSeqId);
|
||||
wxOrder.setTotalPrice(bd);
|
||||
// wxOrder.setOpenid(vo.getOpenid());
|
||||
wxOrder.setMobileUserId(vo.getUserId());
|
||||
wxOrder.setStatus(OrderStatus.unpaid.name());
|
||||
wxOrder.setDeviceId(vo.getDeviceId());
|
||||
wxOrder.setDescription(vo.getGoodsDesc());
|
||||
wxOrder.setDeliveryWay("自提");
|
||||
wxOrder.setCreateTime(LocalDateTime.now());
|
||||
wxOrder.setOrderType(1);
|
||||
mobileOrderMapper.insert(wxOrder);
|
||||
|
||||
WxPlaceOrderResVO placeOrderResVO = new WxPlaceOrderResVO();
|
||||
String pay_info = responseData.getString("pay_info");
|
||||
JSONObject payInfo = JSONObject.parseObject(pay_info);
|
||||
placeOrderResVO.setTimestamp(payInfo.getString("timeStamp"));
|
||||
placeOrderResVO.setNonceStr(payInfo.getString("nonceStr"));
|
||||
placeOrderResVO.setSignType(payInfo.getString("signType"));
|
||||
// placeOrderResVO.setOrderId(orderId);
|
||||
placeOrderResVO.setPaySign(payInfo.getString("paySign"));
|
||||
placeOrderResVO.setPrepayId(payInfo.getString("package").split("=")[1]);
|
||||
return placeOrderResVO;
|
||||
}
|
||||
throw new ServiceException("下单失败");
|
||||
}
|
||||
|
||||
private JSONObject createPlaceOrderParams(HuifuPlaceOrderParamBaseDTO dto){
|
||||
JSONObject data = JSONObject.of();
|
||||
String now = DateUtil.format(new Date(), "yyyyMMdd");
|
||||
data.put("req_date", now);
|
||||
// String snowId = IdUtil.getSnowflakeNextIdStr();
|
||||
String reqSeqId = HuifuUtil.getReqSeqId();
|
||||
data.put("req_seq_id", reqSeqId);
|
||||
data.put("huifu_id", vendorProperties.getHuifuId());
|
||||
data.put("goods_desc", dto.getGoodsDesc());
|
||||
data.put("trade_type", "T_MINIAPP");
|
||||
BigDecimal bd = new BigDecimal(dto.getPlaceOrderAmount());
|
||||
bd = bd.setScale(2, RoundingMode.DOWN);
|
||||
data.put("trans_amt", bd.toString());
|
||||
JSONObject wx_data = JSONObject.of();
|
||||
wx_data.put("sub_appid", wxProperties.getAppid());
|
||||
wx_data.put("sub_openid", dto.getOpenid());
|
||||
data.put("wx_data", wx_data.toString());
|
||||
data.put("fee_flag", 2);
|
||||
data.put("notify_url", vendorProperties.getNotifyUrl());
|
||||
String sign = HuifuSignUtil.sign(data, vendorProperties.getPrivateKey());
|
||||
JSONObject commonParams = JSONObject.of();
|
||||
commonParams.put("sys_id", vendorProperties.getSysId());
|
||||
commonParams.put("product_id", vendorProperties.getProductId());
|
||||
commonParams.put("sign", sign);
|
||||
commonParams.put("data", data);
|
||||
JSONObject of = JSONObject.of();
|
||||
of.put(COMMON_PARAM,commonParams);
|
||||
of.put(AMOUNT,bd);
|
||||
of.put(REQ_SEQ_ID,reqSeqId);
|
||||
return of;
|
||||
}
|
||||
|
||||
public WxPlaceOrderResVO recharge(RechargeVO vo){
|
||||
JSONObject data = JSONObject.of();
|
||||
String now = DateUtil.format(new Date(), "yyyyMMdd");
|
||||
data.put("req_date", now);
|
||||
String snowId = IdUtil.getSnowflakeNextIdStr();
|
||||
String reqSeqId = HuifuUtil.getReqSeqId();
|
||||
data.put("req_seq_id", reqSeqId);
|
||||
data.put("huifu_id", vendorProperties.getHuifuId());
|
||||
data.put("goods_desc", "会员充值");
|
||||
data.put("trade_type", "T_MINIAPP");
|
||||
BigDecimal bd = new BigDecimal(vo.getRechargePrice());
|
||||
bd = bd.setScale(2, RoundingMode.DOWN);
|
||||
data.put("trans_amt", bd.toString());
|
||||
JSONObject wx_data = JSONObject.of();
|
||||
wx_data.put("sub_appid", wxProperties.getAppid());
|
||||
wx_data.put("sub_openid", vo.getOpenid());
|
||||
data.put("wx_data", wx_data.toString());
|
||||
data.put("fee_flag", 2);
|
||||
data.put("notify_url", vendorProperties.getNotifyUrl());
|
||||
String sign = HuifuSignUtil.sign(data, vendorProperties.getPrivateKey());
|
||||
JSONObject commonParams = JSONObject.of();
|
||||
commonParams.put("sys_id", vendorProperties.getSysId());
|
||||
commonParams.put("product_id", vendorProperties.getProductId());
|
||||
commonParams.put("sign", sign);
|
||||
commonParams.put("data", data);
|
||||
log.info("commonParams={}", commonParams);
|
||||
String res = HttpUtil.doPostJson(PAY_API, null, commonParams);
|
||||
log.info("汇付下单返回:{}", res);
|
||||
JSONObject response = JSONObject.parseObject(res);
|
||||
if (response == null) {
|
||||
throw new ServiceException("下单失败");
|
||||
}
|
||||
JSONObject responseData = response.getJSONObject("data");
|
||||
String resp_code = responseData.getString("resp_code");
|
||||
if ("00000100".equals(resp_code) || "00000000".equals(resp_code)) {
|
||||
log.info("订单:{}下单成功", snowId);
|
||||
MobileOrder wxOrder = new MobileOrder();
|
||||
wxOrder.setOrderId(snowId);
|
||||
wxOrder.setOutTradeNo(reqSeqId);
|
||||
wxOrder.setTotalPrice(bd);
|
||||
// wxOrder.setOpenid(vo.getOpenid());
|
||||
wxOrder.setMobileUserId(vo.getUserId());
|
||||
wxOrder.setStatus(OrderStatus.unpaid.name());
|
||||
// wxOrder.setDeviceId(vo.getDeviceId());
|
||||
wxOrder.setDescription("会员充值");
|
||||
wxOrder.setDeliveryWay("自提");
|
||||
wxOrder.setCreateTime(LocalDateTime.now());
|
||||
wxOrder.setOrderType(4);
|
||||
mobileOrderMapper.insert(wxOrder);
|
||||
|
||||
WxVipRecharge vipRecharge = new WxVipRecharge();
|
||||
vipRecharge.setOpenid(vo.getOpenid());
|
||||
vipRecharge.setOrderId(snowId);
|
||||
vipRecharge.setRechargeAmount(bd);
|
||||
BigDecimal giftAmount = new BigDecimal(vo.getGiftAmount());
|
||||
BigDecimal decimalGift = giftAmount.setScale(2, RoundingMode.DOWN);
|
||||
vipRecharge.setPresentAmount(decimalGift);
|
||||
vipRecharge.setPayStatus(0);
|
||||
vipRecharge.setCreateTime(LocalDateTime.now());
|
||||
vipRechargeMapper.insert(vipRecharge);
|
||||
|
||||
WxPlaceOrderResVO placeOrderResVO = new WxPlaceOrderResVO();
|
||||
String pay_info = responseData.getString("pay_info");
|
||||
JSONObject payInfo = JSONObject.parseObject(pay_info);
|
||||
placeOrderResVO.setTimestamp(payInfo.getString("timeStamp"));
|
||||
placeOrderResVO.setNonceStr(payInfo.getString("nonceStr"));
|
||||
placeOrderResVO.setSignType(payInfo.getString("signType"));
|
||||
// placeOrderResVO.setOrderId(orderId);
|
||||
placeOrderResVO.setPaySign(payInfo.getString("paySign"));
|
||||
placeOrderResVO.setPrepayId(payInfo.getString("package").split("=")[1]);
|
||||
return placeOrderResVO;
|
||||
}
|
||||
throw new ServiceException("会员充值下单失败");
|
||||
}
|
||||
|
||||
public WxPlaceOrderResVO activeMembership(HuifuPlaceOrderParamBaseDTO dto){
|
||||
JSONObject jsonObject = createPlaceOrderParams(dto);
|
||||
JSONObject placeOrderParams = (JSONObject) jsonObject.get(COMMON_PARAM);
|
||||
String reqSeqId = jsonObject.getString(REQ_SEQ_ID);
|
||||
BigDecimal bd = (BigDecimal) jsonObject.get(AMOUNT);
|
||||
String res = HttpUtil.doPostJson(PAY_API, null, placeOrderParams);
|
||||
log.info("汇付下单返回:{}", res);
|
||||
JSONObject response = JSONObject.parseObject(res);
|
||||
if (response == null) {
|
||||
throw new ServiceException("下单失败");
|
||||
}
|
||||
JSONObject responseData = response.getJSONObject("data");
|
||||
String resp_code = responseData.getString("resp_code");
|
||||
if ("00000100".equals(resp_code) || "00000000".equals(resp_code)) {
|
||||
String snowId = IdUtil.getSnowflakeNextIdStr();
|
||||
log.info("订单:{}下单成功", snowId);
|
||||
MobileOrder wxOrder = new MobileOrder();
|
||||
wxOrder.setOrderId(snowId);
|
||||
wxOrder.setOutTradeNo(reqSeqId);
|
||||
wxOrder.setTotalPrice(bd);
|
||||
// wxOrder.setOpenid(dto.getOpenid());
|
||||
wxOrder.setMobileUserId(dto.getUserId());
|
||||
wxOrder.setStatus(OrderStatus.unpaid.name());
|
||||
// wxOrder.setDeviceId(vo.getDeviceId());
|
||||
wxOrder.setDescription(dto.getGoodsDesc());
|
||||
wxOrder.setDeliveryWay("自提");
|
||||
wxOrder.setCreateTime(LocalDateTime.now());
|
||||
wxOrder.setOrderType(6);
|
||||
mobileOrderMapper.insert(wxOrder);
|
||||
|
||||
WxPlaceOrderResVO placeOrderResVO = new WxPlaceOrderResVO();
|
||||
String pay_info = responseData.getString("pay_info");
|
||||
JSONObject payInfo = JSONObject.parseObject(pay_info);
|
||||
placeOrderResVO.setTimestamp(payInfo.getString("timeStamp"));
|
||||
placeOrderResVO.setNonceStr(payInfo.getString("nonceStr"));
|
||||
placeOrderResVO.setSignType(payInfo.getString("signType"));
|
||||
// placeOrderResVO.setOrderId(orderId);
|
||||
placeOrderResVO.setPaySign(payInfo.getString("paySign"));
|
||||
placeOrderResVO.setPrepayId(payInfo.getString("package").split("=")[1]);
|
||||
return placeOrderResVO;
|
||||
}
|
||||
throw new ServiceException("开通会员下单失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 门店提现接口
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
public CashOutResponse profitSharingPay(CashOutDTO dto) {
|
||||
JSONObject data = JSONObject.of();
|
||||
String snowId = IdUtil.getSnowflakeNextIdStr();
|
||||
data.put("req_seq_id", snowId);
|
||||
String now = DateUtil.format(new Date(), "yyyyMMdd");
|
||||
data.put("req_date", now);
|
||||
data.put("out_huifu_id", vendorProperties.getHuifuId());
|
||||
BigDecimal bd = new BigDecimal(dto.getAmount());
|
||||
bd = bd.setScale(2, RoundingMode.DOWN);
|
||||
data.put("ord_amt", bd.toString());
|
||||
JkStore jkStore = jkStoreMapper.selectById(dto.getStoreId());
|
||||
if (Objects.isNull(jkStore)) {
|
||||
return new CashOutResponse(500,String.format("门店ID【%d】不存在",dto.getStoreId()));
|
||||
}
|
||||
JSONObject acct_split_bunch = JSONObject.of();
|
||||
JSONArray acct_infos = new JSONArray();
|
||||
JSONObject accInfo = new JSONObject();
|
||||
accInfo.put("div_amt",bd.toString());
|
||||
accInfo.put("huifu_id", jkStore.getHuifuId());
|
||||
// accInfo.put("percentage_div", jkStore.getProfitSharingPercentage().toString());
|
||||
acct_infos.add(accInfo);
|
||||
/*JSONObject master_acct = new JSONObject();
|
||||
BigDecimal b100 = new BigDecimal("100.00");
|
||||
BigDecimal surplusPercent = b100.subtract(jkStore.getProfitSharingPercentage());
|
||||
log.info("主商户分账比例为:{}", surplusPercent);
|
||||
master_acct.put("huifu_id", vendorProperties.getHuifuId());
|
||||
master_acct.put("percentage_div", surplusPercent.toString());
|
||||
acct_infos.add(master_acct);*/
|
||||
acct_split_bunch.put("acct_infos", acct_infos);
|
||||
acct_split_bunch.put("percentage_flag", "Y");
|
||||
data.put("acct_split_bunch", acct_split_bunch);
|
||||
String sign = HuifuSignUtil.sign(data, vendorProperties.getPrivateKey());
|
||||
JSONObject commonParams = new JSONObject();
|
||||
commonParams.put("sys_id", vendorProperties.getSysId());
|
||||
commonParams.put("product_id", vendorProperties.getProductId());
|
||||
commonParams.put("sign", sign);
|
||||
commonParams.put("data", data);
|
||||
log.info("参数:{}", commonParams);
|
||||
String res = HttpUtil.doPostJson(YUE_PAY_API, null, commonParams);
|
||||
log.info("余额支付接口返回数据:{}", res);
|
||||
JSONObject response = JSONObject.parseObject(res);
|
||||
if (response == null) {
|
||||
return new CashOutResponse(300,"提现失败!");
|
||||
}
|
||||
JSONObject responseData = response.getJSONObject("data");
|
||||
String resp_code = responseData.getString("resp_code");
|
||||
String req_seq_id = responseData.getString("req_seq_id");
|
||||
String req_date = responseData.getString("req_date");
|
||||
String out_huifu_id = responseData.getString("out_huifu_id");
|
||||
String ord_amt = responseData.getString("ord_amt");
|
||||
if ("00000000".equals(resp_code)) {
|
||||
log.info("提现成功", snowId);
|
||||
CashOutRecord cashOutRecord = new CashOutRecord();
|
||||
cashOutRecord.setAmount(bd);
|
||||
cashOutRecord.setOutHuifuId(vendorProperties.getHuifuId());
|
||||
cashOutRecord.setStoreId(dto.getStoreId());
|
||||
cashOutRecord.setCreateTime(LocalDateTime.now());
|
||||
cashOutRecordMapper.insert(cashOutRecord);
|
||||
}
|
||||
throw new ServiceException(String.format("余额支付接口返回状态码:%s,提现失败!",resp_code));
|
||||
}
|
||||
|
||||
public WxPlaceOrderResVO coursePay(PayCourseVO vo){
|
||||
Course course = courseMapper.selectById(vo.getCourseId());
|
||||
if (Objects.isNull(course)){
|
||||
throw new ServiceException("course is not exist");
|
||||
}
|
||||
int compare = course.getPrice().compareTo(new BigDecimal(vo.getPrice()));
|
||||
if (compare != 0){
|
||||
throw new ServiceException("课程价格错误!");
|
||||
}
|
||||
JSONObject data = JSONObject.of();
|
||||
String now = DateUtil.format(new Date(), "yyyyMMdd");
|
||||
data.put("req_date", now);
|
||||
String snowId = IdUtil.getSnowflakeNextIdStr();
|
||||
String reqSeqId = HuifuUtil.getReqSeqId();
|
||||
data.put("req_seq_id", reqSeqId);
|
||||
data.put("huifu_id", vendorProperties.getHuifuId());
|
||||
data.put("goods_desc", "视频课程购买");
|
||||
data.put("trade_type", "T_MINIAPP");
|
||||
BigDecimal bd = new BigDecimal(vo.getPrice());
|
||||
bd = bd.setScale(2, RoundingMode.DOWN);
|
||||
data.put("trans_amt", bd.toString());
|
||||
JSONObject wx_data = JSONObject.of();
|
||||
wx_data.put("sub_appid", wxProperties.getAppid());
|
||||
wx_data.put("sub_openid", vo.getOpenid());
|
||||
data.put("wx_data", wx_data.toString());
|
||||
data.put("fee_flag", 2);
|
||||
data.put("notify_url", vendorProperties.getNotifyUrl());
|
||||
String sign = HuifuSignUtil.sign(data, vendorProperties.getPrivateKey());
|
||||
JSONObject commonParams = JSONObject.of();
|
||||
commonParams.put("sys_id", vendorProperties.getSysId());
|
||||
commonParams.put("product_id", vendorProperties.getProductId());
|
||||
commonParams.put("sign", sign);
|
||||
commonParams.put("data", data);
|
||||
log.info("commonParams={}", commonParams);
|
||||
String res = HttpUtil.doPostJson(PAY_API, null, commonParams);
|
||||
log.info("课程购买下单返回:{}", res);
|
||||
JSONObject response = JSONObject.parseObject(res);
|
||||
if (response == null) {
|
||||
throw new ServiceException("课程购买下单失败");
|
||||
}
|
||||
JSONObject responseData = response.getJSONObject("data");
|
||||
String resp_code = responseData.getString("resp_code");
|
||||
if ("00000100".equals(resp_code) || "00000000".equals(resp_code)){
|
||||
log.info("购买课程下单成功,orderId:{}",snowId);
|
||||
MobileOrder wxOrder = new MobileOrder();
|
||||
wxOrder.setOrderId(snowId);
|
||||
wxOrder.setOutTradeNo(reqSeqId);
|
||||
wxOrder.setTotalPrice(bd);
|
||||
wxOrder.setCourseId(vo.getCourseId());
|
||||
// wxOrder.setOpenid(vo.getOpenid());
|
||||
wxOrder.setMobileUserId(vo.getUserId());
|
||||
wxOrder.setStatus(OrderStatus.unpaid.name());
|
||||
wxOrder.setDescription("视频课程购买");
|
||||
wxOrder.setDeliveryWay("自提");
|
||||
wxOrder.setCreateTime(LocalDateTime.now());
|
||||
wxOrder.setOrderType(3);
|
||||
mobileOrderMapper.insert(wxOrder);
|
||||
|
||||
WxPlaceOrderResVO placeOrderResVO = new WxPlaceOrderResVO();
|
||||
String pay_info = responseData.getString("pay_info");
|
||||
JSONObject payInfo = JSONObject.parseObject(pay_info);
|
||||
placeOrderResVO.setTimestamp(payInfo.getString("timeStamp"));
|
||||
placeOrderResVO.setNonceStr(payInfo.getString("nonceStr"));
|
||||
placeOrderResVO.setSignType(payInfo.getString("signType"));
|
||||
// placeOrderResVO.setOrderId(orderId);
|
||||
placeOrderResVO.setPaySign(payInfo.getString("paySign"));
|
||||
placeOrderResVO.setPrepayId(payInfo.getString("package").split("=")[1]);
|
||||
return placeOrderResVO;
|
||||
}
|
||||
throw new ServiceException("课程购买下单失败!");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package cn.unizk.huifupay.utils;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/9/29 15:02
|
||||
* @Version 1.0
|
||||
**/
|
||||
public class HfUtil {
|
||||
|
||||
public static String getReqSeqId(){
|
||||
return DateUtil.format(new Date(),"yyyyMMddHHmmss") + RandomStringUtils.randomNumeric(18);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package cn.unizk.huifupay.utils;
|
||||
|
||||
import cn.unizk.exception.ServiceException;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.Signature;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.util.Base64;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/9/29 10:53
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Slf4j
|
||||
public class HuifuSignUtil {
|
||||
|
||||
/**
|
||||
* RSA私钥签名:签名方式SHA256WithRSA
|
||||
* @param data 待签名字符串
|
||||
* @param privateKeyBase64 私钥(Base64编码)
|
||||
* @return 签名byte[]
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public static String sign(String data, String privateKeyBase64) {
|
||||
// Base64 --> Key
|
||||
try {
|
||||
byte[] bytes = Base64.getDecoder().decode(privateKeyBase64);
|
||||
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
|
||||
KeyFactory keyFactory;
|
||||
keyFactory = KeyFactory.getInstance("RSA");
|
||||
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
|
||||
// Sign
|
||||
Signature signature = Signature.getInstance("SHA256WithRSA");
|
||||
signature.initSign(privateKey);
|
||||
signature.update(data.getBytes(StandardCharsets.UTF_8));
|
||||
return Base64.getEncoder().encodeToString(signature.sign());
|
||||
} catch (Exception e) {
|
||||
log.error("签名异常",e);
|
||||
throw new ServiceException("签名异常");
|
||||
}
|
||||
}
|
||||
|
||||
public static String sign(JSONObject object, String privateKeyStr) {
|
||||
TreeMap treeMap = JSONObject.parseObject(object.toString(), TreeMap.class);
|
||||
JSONObject signBody = new JSONObject(treeMap);
|
||||
// Base64 --> Key
|
||||
try {
|
||||
byte[] bytes = Base64.getDecoder().decode(privateKeyStr);
|
||||
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
|
||||
KeyFactory keyFactory;
|
||||
keyFactory = KeyFactory.getInstance("RSA");
|
||||
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
|
||||
// Sign
|
||||
Signature signature = Signature.getInstance("SHA256WithRSA");
|
||||
signature.initSign(privateKey);
|
||||
signature.update(signBody.toString().getBytes(StandardCharsets.UTF_8));
|
||||
return Base64.getEncoder().encodeToString(signature.sign());
|
||||
} catch (Exception e) {
|
||||
log.error("签名异常",e);
|
||||
throw new ServiceException("签名异常");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package cn.unizk.huifupay.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2026/3/11 10:56
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Data
|
||||
public class DeviceScanPayVO {
|
||||
|
||||
private String deviceId;
|
||||
|
||||
private String amount;
|
||||
|
||||
private String goodsDesc;
|
||||
|
||||
private Integer userId;
|
||||
|
||||
private String openid;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package cn.unizk.huifupay.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2026/4/17 14:02
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Data
|
||||
public class RechargeVO {
|
||||
|
||||
private String openid;
|
||||
private Integer userId;
|
||||
private String rechargePrice;
|
||||
private String giftAmount;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package cn.unizk.huifupay.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2026/6/17 15:49
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Data
|
||||
public class ReportTypeVO {
|
||||
|
||||
private String code1;
|
||||
|
||||
private String code2;
|
||||
|
||||
private Integer result;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package cn.unizk.interceptor;
|
||||
|
||||
import cn.unizk.constant.WxConstant;
|
||||
import cn.unizk.entity.po.MobileAppUser;
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.utils.JwtUtil;
|
||||
import cn.unizk.utils.ServletUtils;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
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 javax.servlet.http.HttpSession;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/8/21 14:46
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Component
|
||||
public class AppletLoginInterceptor implements HandlerInterceptor {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("kryoRedisTemplate")
|
||||
private RedisTemplate redisTemplate;
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
String token = request.getHeader(WxConstant.APPLET_LOGIN_SIGN);
|
||||
if (StringUtils.isBlank(token)){
|
||||
toRes(response,400);
|
||||
return false;
|
||||
}
|
||||
String phoneNumber = JwtUtil.parsePlaintext(token);
|
||||
MobileAppUser wxUser = (MobileAppUser) redisTemplate.opsForValue().get(WxConstant.CACHE_TOKEN_KEY + phoneNumber);
|
||||
if (Objects.isNull(wxUser)){
|
||||
toRes(response,401);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void toRes(HttpServletResponse response,Integer statusCode){
|
||||
ResultData data = new ResultData();
|
||||
data.setCode(statusCode);
|
||||
data.setMessage("Authentication failed");
|
||||
ServletUtils.renderString(response, JSONObject.toJSONString(data));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package cn.unizk.mapper;
|
||||
|
||||
import cn.unizk.entity.po.Combo;
|
||||
|
||||
public interface ComboMapper extends UniBaseMapper<Combo> {
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package cn.unizk.mapper;
|
||||
|
||||
import cn.unizk.entity.po.Conversation;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
|
||||
|
||||
public interface ConversationMapper {
|
||||
|
||||
|
||||
|
||||
void insertConversation(Conversation conversation);
|
||||
|
||||
void updateConversation(Conversation conversation);
|
||||
|
||||
Conversation selectBySessionId(String sessionId);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package cn.unizk.mapper;
|
||||
|
||||
import cn.unizk.entity.po.Device;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/8/30 17:06
|
||||
* @Version 1.0
|
||||
**/
|
||||
public interface DeviceMapper extends UniBaseMapper<Device> {
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package cn.unizk.mapper;
|
||||
|
||||
import cn.unizk.entity.po.SysFile;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/10/9 17:21
|
||||
* @Version 1.0
|
||||
**/
|
||||
public interface FileMapper extends UniBaseMapper<SysFile> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.unizk.mapper;
|
||||
|
||||
import cn.unizk.entity.po.JkPhysio;
|
||||
|
||||
public interface JkPhysioMapper extends UniBaseMapper<JkPhysio> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.unizk.mapper;
|
||||
|
||||
import cn.unizk.entity.po.JkProduct;
|
||||
|
||||
public interface JkProductMapper extends UniBaseMapper<JkProduct> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package cn.unizk.mapper;
|
||||
|
||||
import cn.unizk.entity.po.JkStore;
|
||||
|
||||
public interface JkStoreMapper extends UniBaseMapper<JkStore> {
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package cn.unizk.mapper;
|
||||
|
||||
import cn.unizk.entity.po.Message;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public interface MessageMapper {
|
||||
|
||||
|
||||
void insertMessage(Message message);
|
||||
|
||||
void updateMessage(Message message);
|
||||
|
||||
List<Message> selectBySessionIdList(String sessionId);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package cn.unizk.mapper;
|
||||
|
||||
import cn.unizk.entity.po.ProductCarousel;
|
||||
|
||||
public interface ProductCarouselMapper extends UniBaseMapper<ProductCarousel> {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package cn.unizk.mapper;
|
||||
|
||||
import cn.unizk.entity.po.Question;
|
||||
|
||||
public interface QuestionMapper extends UniBaseMapper<Question> {
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package cn.unizk.mapper;
|
||||
|
||||
import cn.unizk.entity.po.SysDict;
|
||||
|
||||
public interface SysDictMapper extends UniBaseMapper<SysDict> {
|
||||
|
||||
int deleteByPrimaryKey(Integer dictCode);
|
||||
|
||||
int insertSelective(SysDict record);
|
||||
|
||||
SysDict selectByPrimaryKey(Integer dictCode);
|
||||
|
||||
int updateByPrimaryKeySelective(SysDict record);
|
||||
|
||||
int updateByPrimaryKey(SysDict record);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package cn.unizk.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
public interface UniBaseMapper<T> extends BaseMapper<T> {
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
package cn.unizk.mapper;
|
||||
|
||||
import cn.unizk.entity.po.WxOrder;
|
||||
import cn.unizk.entity.vo.OrderReqVO;
|
||||
import cn.unizk.entity.vo.WxOrderVO;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
public interface WxOrderMapper extends UniBaseMapper<WxOrder> {
|
||||
|
||||
Integer updateStatusToPaid(@Param("orderId") String orderId);
|
||||
|
||||
Integer updateStatusToCanceled(@Param("orderId") String orderId);
|
||||
|
||||
Page<WxOrderVO> selectOrders(Page<WxOrderVO> page, @Param("vo") OrderReqVO vo);
|
||||
|
||||
WxOrder selectOrderByIdAndPhone(@Param("orderId") String orderId,@Param("phone") String phone);
|
||||
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
package cn.unizk.mapper;
|
||||
|
||||
import cn.unizk.entity.po.WxUser;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
public interface WxUserMapper extends UniBaseMapper<WxUser> {
|
||||
|
||||
Integer bindPhone(@Param("phoneNumber") String phoneNumber,@Param("openid") String openid);
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,9 @@
|
||||
package cn.unizk.mapper;
|
||||
|
||||
import cn.unizk.entity.po.WxUserSession;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
public interface WxUserSessionMapper extends UniBaseMapper<WxUserSession> {
|
||||
|
||||
Long selectMaxSessionId(@Param("openid") String openid);
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package cn.unizk.scheduler;
|
||||
|
||||
import cn.unizk.entity.po.Chapter;
|
||||
import cn.unizk.entity.po.MobileUserVideoProgress;
|
||||
import cn.unizk.mapper.ChapterMapper;
|
||||
import cn.unizk.mapper.MobileUserVideoProgressMapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.data.redis.core.HashOperations;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2026/3/27 15:44
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class VideoProgressScheduler {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("kryoRedisTemplate")
|
||||
private RedisTemplate redisTemplate;
|
||||
|
||||
@Resource
|
||||
private MobileUserVideoProgressMapper mobileUserVideoProgressMapper;
|
||||
@Resource
|
||||
private ChapterMapper chapterMapper;
|
||||
|
||||
// @Scheduled(cron = "0 0/1 * * * ?") // 每10分钟执行一次
|
||||
public void flushProgressToMySQL() {
|
||||
String pattern = "video:progress:batch:*";
|
||||
|
||||
Set<String> keys = redisTemplate.keys(pattern);
|
||||
|
||||
if (keys == null || keys.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (String key : keys) {
|
||||
try {
|
||||
// 2. 获取数据
|
||||
HashOperations<String, String, Object> ops = redisTemplate.opsForHash();
|
||||
Object currentTimeObj = ops.get(key, "lastPosition");
|
||||
Object durationObj = ops.get(key, "spentTime");
|
||||
|
||||
if (currentTimeObj == null || durationObj == null) continue;
|
||||
|
||||
int currentTime = Integer.parseInt(currentTimeObj.toString());
|
||||
int spentTime = Integer.parseInt(durationObj.toString());
|
||||
|
||||
// 3. 解析 Key 获取 UserID 和 VideoID
|
||||
// key format: video:progress:batch:{userId}:{videoId}
|
||||
String[] parts = key.split(":");
|
||||
if (parts.length < 5) continue;
|
||||
Integer userId = Integer.valueOf(parts[3]);
|
||||
Integer chapterId = Integer.valueOf(parts[4]);
|
||||
|
||||
MobileUserVideoProgress videoProgress = mobileUserVideoProgressMapper.selectOne(new LambdaQueryWrapper<MobileUserVideoProgress>()
|
||||
.eq(MobileUserVideoProgress::getChapterId, chapterId)
|
||||
.eq(MobileUserVideoProgress::getMobileUserId, userId));
|
||||
if (Objects.isNull(videoProgress)){
|
||||
MobileUserVideoProgress progress = new MobileUserVideoProgress();
|
||||
progress.setChapterId(chapterId);
|
||||
progress.setMobileUserId(userId);
|
||||
progress.setSpentTime(spentTime);
|
||||
progress.setLastPosition(currentTime);
|
||||
progress.setUpdateTime(LocalDateTime.now());
|
||||
Chapter chapter = chapterMapper.selectById(chapterId);
|
||||
Integer p = (currentTime * 100) / chapter.getVideoDuration();
|
||||
progress.setProgress(p);
|
||||
mobileUserVideoProgressMapper.insert(progress);
|
||||
}else {
|
||||
videoProgress.setSpentTime(spentTime);
|
||||
if (currentTime > videoProgress.getLastPosition()){
|
||||
videoProgress.setLastPosition(currentTime);
|
||||
Chapter chapter = chapterMapper.selectById(chapterId);
|
||||
Integer p = (currentTime * 100) / chapter.getVideoDuration();
|
||||
videoProgress.setProgress(p);
|
||||
}
|
||||
videoProgress.setUpdateTime(LocalDateTime.now());
|
||||
mobileUserVideoProgressMapper.updateById(videoProgress);
|
||||
}
|
||||
|
||||
// 5. 写入成功后,删除 Redis Key (防止重复计算)
|
||||
redisTemplate.delete(key);
|
||||
|
||||
log.info("Flushed progress: userId={}, videoId={}, duration={}", userId, chapterId, spentTime);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Flush progress failed for key: {}", key, e);
|
||||
// 注意:这里不要删除 Key,让它留在 Redis 里,下次定时任务再试,或者依靠过期时间自动清理
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
package cn.unizk.scheduler;
|
||||
|
||||
import cn.unizk.config.WxProperties;
|
||||
import cn.unizk.constant.WxConstant;
|
||||
import cn.unizk.entity.po.WxOrder;
|
||||
import cn.unizk.exception.ServiceException;
|
||||
import cn.unizk.mapper.WxOrderMapper;
|
||||
import cn.unizk.service.PayService;
|
||||
import cn.unizk.utils.HttpUtil;
|
||||
import cn.unizk.wxPay.utils.WxSignatureUtil;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.wechat.pay.java.core.http.HttpMethod;
|
||||
import com.wechat.pay.java.core.util.NonceUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
*/
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/9/1 11:46
|
||||
* @Version 1.0
|
||||
**//*
|
||||
|
||||
@Component
|
||||
@SuppressWarnings("unchecked")
|
||||
@Slf4j
|
||||
public class WxOrderCloseScheduler {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("kryoRedisTemplate")
|
||||
private RedisTemplate redisTemplate;
|
||||
@Resource
|
||||
private WxOrderMapper wxOrderMapper;
|
||||
@Resource
|
||||
private WxProperties wxProperties;
|
||||
@Value("${spring.profiles.active}")
|
||||
private String active;
|
||||
|
||||
|
||||
private static final String DELAY_QUEUE_KEY = "wxorder:close:delay";
|
||||
|
||||
|
||||
public void addCloseWxOrderTask(String orderId,long delayMillis){
|
||||
redisTemplate.opsForZSet().add(DELAY_QUEUE_KEY,orderId,System.currentTimeMillis() + delayMillis);
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* 每10s执行一次
|
||||
*//*
|
||||
|
||||
// @Scheduled(fixedRate = 10000)
|
||||
public void processCloseWxOrderTasks(){
|
||||
long now = System.currentTimeMillis();
|
||||
Set<String> expireOrderIds = redisTemplate.opsForZSet().rangeByScore(DELAY_QUEUE_KEY,0,now,0,50);
|
||||
if (CollectionUtils.isEmpty(expireOrderIds)){
|
||||
return;
|
||||
}
|
||||
for (String expireOrderId : expireOrderIds) {
|
||||
try {
|
||||
closeOrder(expireOrderId);
|
||||
redisTemplate.opsForZSet().remove(DELAY_QUEUE_KEY,expireOrderId);
|
||||
}catch (Exception e){
|
||||
log.error("关闭订单失败,orderId: {}", expireOrderId, e);
|
||||
//将失败任务记录到死信队列中,再添加一个定时任务去消费死信队列中的记录
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void closeOrder(String orderId) {
|
||||
WxOrder order = wxOrderMapper.selectById(orderId);
|
||||
if (Objects.isNull(order) || !order.getStatus().equals("unpaid")){
|
||||
log.info("wxorderclosescheduler--->订单已被关闭或已支付,{}",orderId);
|
||||
return;
|
||||
}
|
||||
String authorization;
|
||||
String nonce = NonceUtil.createNonce(32);
|
||||
String closeOrderUrl = wxProperties.getPay().getCloseOrderApi().replace("{out_trade_no}", orderId);
|
||||
String finalCloseOrderUrl = wxProperties.getPay().getDomain() + closeOrderUrl;
|
||||
try {
|
||||
WxSignatureUtil.setEnv(active);
|
||||
authorization = WxSignatureUtil.getAuthorization(wxProperties.getPay().getMchid(),wxProperties.getPay().getSerialNo(),
|
||||
nonce, HttpMethod.POST.name(),finalCloseOrderUrl,
|
||||
JSONObject.toJSONString(JSONObject.of("mchid",wxProperties.getPay().getMchid())));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new ServiceException("微信关闭订单生成签名失败");
|
||||
}
|
||||
Map<String,String> headers = new HashMap<>();
|
||||
headers.put("Authorization", WxConstant.authorization_type + authorization);
|
||||
headers.put("Accept","application/json");
|
||||
headers.put("Content-Type","application/json");
|
||||
JSONObject resp = HttpUtil.postJsonCarryStatusCode(finalCloseOrderUrl, headers, JSONObject.of("mchid", wxProperties.getPay().getMchid()));
|
||||
int code = (int) resp.get(HttpUtil.STATUS_CODE);
|
||||
if (code >= 200 && code < 300){
|
||||
//对响应进行签名验证,参考WXPayUtility工具类。https://pay.weixin.qq.com/doc/v3/merchant/4014931831
|
||||
|
||||
//修改数据库订单状态为已关闭
|
||||
WxOrder wxOrder = new WxOrder();
|
||||
wxOrder.setOrderId(orderId);
|
||||
wxOrder.setStatus("canceled");
|
||||
wxOrderMapper.updateById(wxOrder);
|
||||
log.info("关闭订单{}成功",orderId);
|
||||
}else {
|
||||
log.info("关闭订单失败,orderId={},微信关闭订单API返回:{}",orderId,resp);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,18 @@
|
||||
package cn.unizk.service;
|
||||
|
||||
import cn.unizk.entity.vo.ReplyVo;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface AIAdviceService{
|
||||
ReplyVo reply (ReplyVo vo);
|
||||
|
||||
|
||||
ReplyVo saveConversation(List<Map<String, List<String>>> conversation,String openid);
|
||||
|
||||
|
||||
|
||||
JSONObject getTreatmentPlan(String sessionId);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.unizk.service;
|
||||
|
||||
import cn.unizk.entity.po.Combo;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface ComboService extends IService<Combo> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.unizk.service;
|
||||
|
||||
import cn.unizk.entity.po.Device;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface DeviceService extends IService<Device> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.unizk.service;
|
||||
|
||||
import cn.unizk.entity.po.SysFile;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface FileService extends IService<SysFile> {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package cn.unizk.service;
|
||||
|
||||
public interface IAiService {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.unizk.service;
|
||||
|
||||
import cn.unizk.entity.po.JkPhysio;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface JkPhysioService extends IService<JkPhysio> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.unizk.service;
|
||||
|
||||
import cn.unizk.entity.po.JkProduct;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface JkProductService extends IService<JkProduct> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.unizk.service;
|
||||
|
||||
import cn.unizk.entity.po.JkStore;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface JkStoreService extends IService<JkStore> {
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package cn.unizk.service;
|
||||
|
||||
import cn.unizk.entity.vo.MobileOrderVO;
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.wxPay.vo.WxPlaceOrderResVO;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
public interface PayService {
|
||||
|
||||
WxPlaceOrderResVO wxPlaceOrder(MobileOrderVO orderVO);
|
||||
|
||||
ResultData wxPaySuccessHandler(HttpServletRequest request, JSONObject body);
|
||||
|
||||
default String configureApplet(){
|
||||
return "success";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.unizk.service;
|
||||
|
||||
import cn.unizk.entity.po.ProductCarousel;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface ProductCarouselService extends IService<ProductCarousel> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.unizk.service;
|
||||
|
||||
import cn.unizk.entity.po.Question;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface QuestionService extends IService<Question> {
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package cn.unizk.service;
|
||||
|
||||
import cn.unizk.entity.po.SysDict;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/9/3 11:22
|
||||
* @Version 1.0
|
||||
**/
|
||||
public interface SysDictService extends IService<SysDict> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.unizk.service;
|
||||
|
||||
import cn.unizk.entity.po.MobileUserAddress;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface UserAddressService extends IService<MobileUserAddress> {
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
package cn.unizk.service;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import okhttp3.HttpUrl;
|
||||
import org.java_websocket.WebSocket;
|
||||
import org.java_websocket.client.WebSocketClient;
|
||||
import org.java_websocket.handshake.ServerHandshake;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.*;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/11/21 14:29
|
||||
* @Version 1.0
|
||||
**/
|
||||
public class WebTtsWsService {
|
||||
// 地址与鉴权信息
|
||||
public static final String hostUrl = "https://tts-api.xfyun.cn/v2/tts";
|
||||
// 均到控制台-语音合成页面获取
|
||||
public static final String APPID = "3fa7b7a0";
|
||||
public static final String APISecret = "N2Q5Y2NiOTZmNThhODZjYTgxMjg1NjA4";
|
||||
public static final String APIKey = "da390c58ef0f2ad8424c3dccc6d458c7";
|
||||
// 合成文本
|
||||
public static String text = "欢迎来到讯飞开放平台";
|
||||
// 合成文本编码格式
|
||||
public static final String TTE = "UTF8"; // 小语种必须使用UNICODE编码作为值
|
||||
// 发音人参数。到控制台-我的应用-语音合成-添加试用或购买发音人,添加后即显示该发音人参数值,若试用未添加的发音人会报错11200
|
||||
public static final String VCN = "x4_yezi";
|
||||
// 合成文件存储地址以及名称
|
||||
public static final String OUTPUT_FILE_PATH = "D:\\code\\temp\\" + System.currentTimeMillis() + ".mp3";
|
||||
// json
|
||||
public static final Gson gson = new Gson();
|
||||
public static volatile boolean wsCloseFlag = false;
|
||||
|
||||
/*public static void main(String[] args) throws Exception {
|
||||
String wsUrl = getAuthUrl(hostUrl, APIKey, APISecret).replace("https://", "wss://");
|
||||
OutputStream outputStream = new FileOutputStream(OUTPUT_FILE_PATH);
|
||||
websocketWork(wsUrl, outputStream);
|
||||
}*/
|
||||
|
||||
public static void tts(String text,String filePath,CountDownLatch latch) throws Exception {
|
||||
WebTtsWsService.text = text;
|
||||
OutputStream outputStream = new FileOutputStream(filePath);
|
||||
String wsUrl = getAuthUrl(hostUrl, APIKey, APISecret).replace("https://", "wss://");
|
||||
websocketWork(wsUrl,outputStream,latch);
|
||||
}
|
||||
|
||||
|
||||
// Websocket方法
|
||||
private static void websocketWork(String wsUrl, OutputStream outputStream,CountDownLatch latch) {
|
||||
try {
|
||||
URI uri = new URI(wsUrl);
|
||||
WebSocketClient webSocketClient = new WebSocketClient(uri) {
|
||||
@Override
|
||||
public void onOpen(ServerHandshake serverHandshake) {
|
||||
System.out.println("ws建立连接成功...");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(String text) {
|
||||
// System.out.println("本次转换的内容是:"+ text);
|
||||
JsonParse myJsonParse = gson.fromJson(text, JsonParse.class);
|
||||
if (myJsonParse.code != 0) {
|
||||
System.out.println("发生错误,错误码为:" + myJsonParse.code);
|
||||
System.out.println("本次请求的sid为:" + myJsonParse.sid);
|
||||
}
|
||||
if (myJsonParse.data != null) {
|
||||
try {
|
||||
byte[] textBase64Decode = Base64.getDecoder().decode(myJsonParse.data.audio);
|
||||
outputStream.write(textBase64Decode);
|
||||
outputStream.flush();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (myJsonParse.data.status == 2) {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println("本次请求的sid==>" + myJsonParse.sid);
|
||||
System.out.println("合成成功,文件保存路径为==>" + OUTPUT_FILE_PATH);
|
||||
// 可以关闭连接,释放资源
|
||||
wsCloseFlag = true;
|
||||
latch.countDown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(int i, String s, boolean b) {
|
||||
System.out.println("ws链接已关闭,本次请求完成...");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception e) {
|
||||
System.out.println("发生错误 " + e.getMessage());
|
||||
}
|
||||
};
|
||||
// 建立连接
|
||||
webSocketClient.connect();
|
||||
while (!webSocketClient.getReadyState().equals(WebSocket.READYSTATE.OPEN)) {
|
||||
//System.out.println("正在连接...");
|
||||
Thread.sleep(100);
|
||||
}
|
||||
MyThread webSocketThread = new MyThread(webSocketClient);
|
||||
webSocketThread.start();
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 线程来发送音频与参数
|
||||
static class MyThread extends Thread {
|
||||
WebSocketClient webSocketClient;
|
||||
|
||||
public MyThread(WebSocketClient webSocketClient) {
|
||||
this.webSocketClient = webSocketClient;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
System.out.println("多线程发送文字内容------");
|
||||
wsCloseFlag = false;
|
||||
String requestJson;//请求参数json串
|
||||
try {
|
||||
requestJson = "{\n" +
|
||||
" \"common\": {\n" +
|
||||
" \"app_id\": \"" + APPID + "\"\n" +
|
||||
" },\n" +
|
||||
" \"business\": {\n" +
|
||||
" \"aue\": \"lame\",\n" +
|
||||
" \"sfl\": 1,\n" +
|
||||
" \"tte\": \"" + TTE + "\",\n" +
|
||||
" \"ent\": \"intp65\",\n" +
|
||||
" \"vcn\": \"" + VCN + "\",\n" +
|
||||
" \"pitch\": 50,\n" +
|
||||
" \"speed\": 39\n" +
|
||||
" },\n" +
|
||||
" \"data\": {\n" +
|
||||
" \"status\": 2,\n" +
|
||||
" \"text\": \"" + Base64.getEncoder().encodeToString(text.getBytes(StandardCharsets.UTF_8)) + "\"\n" +
|
||||
//" \"text\": \"" + Base64.getEncoder().encodeToString(TEXT.getBytes("UTF-16LE")) + "\"\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
webSocketClient.send(requestJson);
|
||||
// 等待服务端返回完毕后关闭
|
||||
while (!wsCloseFlag) {
|
||||
Thread.sleep(200);
|
||||
}
|
||||
webSocketClient.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 鉴权方法
|
||||
public static String getAuthUrl(String hostUrl, String apiKey, String apiSecret) throws Exception {
|
||||
URL url = new URL(hostUrl);
|
||||
// 时间
|
||||
SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
|
||||
format.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||
String date = format.format(new Date());
|
||||
// 拼接
|
||||
String preStr = "host: " + url.getHost() + "\n" +
|
||||
"date: " + date + "\n" +
|
||||
"GET " + url.getPath() + " HTTP/1.1";
|
||||
//System.out.println(preStr);
|
||||
// SHA256加密
|
||||
Mac mac = Mac.getInstance("hmacsha256");
|
||||
SecretKeySpec spec = new SecretKeySpec(apiSecret.getBytes(StandardCharsets.UTF_8), "hmacsha256");
|
||||
mac.init(spec);
|
||||
byte[] hexDigits = mac.doFinal(preStr.getBytes(StandardCharsets.UTF_8));
|
||||
// Base64加密
|
||||
String sha = Base64.getEncoder().encodeToString(hexDigits);
|
||||
// 拼接
|
||||
String authorization = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", apiKey, "hmac-sha256", "host date request-line", sha);
|
||||
// 拼接地址
|
||||
HttpUrl httpUrl = Objects.requireNonNull(HttpUrl.parse("https://" + url.getHost() + url.getPath())).newBuilder().//
|
||||
addQueryParameter("authorization", Base64.getEncoder().encodeToString(authorization.getBytes(StandardCharsets.UTF_8))).//
|
||||
addQueryParameter("date", date).//
|
||||
addQueryParameter("host", url.getHost()).//
|
||||
build();
|
||||
|
||||
return httpUrl.toString();
|
||||
}
|
||||
|
||||
//返回的json结果拆解
|
||||
class JsonParse {
|
||||
int code;
|
||||
String sid;
|
||||
Data data;
|
||||
}
|
||||
|
||||
class Data {
|
||||
int status;
|
||||
String audio;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.unizk.service;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
|
||||
public interface WxAppletLoginService {
|
||||
JSONObject appletLogin(String code);
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package cn.unizk.service;
|
||||
|
||||
import cn.unizk.cache.LocalCache;
|
||||
import cn.unizk.constant.WxConstant;
|
||||
import cn.unizk.exception.ServiceException;
|
||||
import cn.unizk.utils.HttpUtil;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/7/9 13:41
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class WxAuthService {
|
||||
@Value("${wx.appid}")
|
||||
private String appid;
|
||||
@Value("${wx.secret}")
|
||||
private String secret;
|
||||
@Autowired
|
||||
@Qualifier("kryoRedisTemplate")
|
||||
private RedisTemplate redisTemplate;
|
||||
|
||||
private void refreshToken(){
|
||||
Map<String,String> params = new HashMap<>();
|
||||
params.put("grant_type","client_credential");
|
||||
params.put("appid",appid);
|
||||
params.put("secret",secret);
|
||||
String s = HttpUtil.doPost(WxConstant.GET_ACCESS_TOKEN_URL, null, params);
|
||||
log.info("wx获取access_token返回数据:{}",s);
|
||||
try {
|
||||
JSONObject getTokenRes = JSONObject.parseObject(s);
|
||||
String access_token = (String) getTokenRes.get("access_token");
|
||||
Integer expires_in = (Integer) getTokenRes.get("expires_in");
|
||||
long exp = System.currentTimeMillis()/1000 + expires_in;
|
||||
// LocalCache.setWxAccessTokenCache(access_token,exp);
|
||||
redisTemplate.opsForValue().set(WxConstant.WX_ACCESS_TOKEN,access_token,5400, TimeUnit.SECONDS);
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
throw new ServiceException("获取微信token失败");
|
||||
}
|
||||
}
|
||||
|
||||
public String getAccessToken(){
|
||||
String accessToken = (String) redisTemplate.opsForValue().get(WxConstant.WX_ACCESS_TOKEN);
|
||||
if (StringUtils.isBlank(accessToken)){
|
||||
refreshToken();
|
||||
accessToken = (String) redisTemplate.opsForValue().get(WxConstant.WX_ACCESS_TOKEN);
|
||||
}
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package cn.unizk.service;
|
||||
/*
|
||||
import cn.unizk.entity.po.WxOrder;
|
||||
import cn.unizk.entity.vo.OrderReqVO;
|
||||
import cn.unizk.entity.vo.UniPage;
|
||||
import cn.unizk.entity.vo.WxOrderVO;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface WxOrderService extends IService<WxOrder> {
|
||||
Page<WxOrderVO> orderList(UniPage<OrderReqVO> uniPage);
|
||||
|
||||
WxOrder getOrderByIdAndPhone(String orderId,String phone);
|
||||
}*/
|
||||
@@ -0,0 +1,10 @@
|
||||
package cn.unizk.service;
|
||||
|
||||
import cn.unizk.entity.po.MobileAppUser;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface WxUserService extends IService<MobileAppUser> {
|
||||
|
||||
void bindPhone(String phone,Integer openid);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package cn.unizk.service;
|
||||
|
||||
import cn.unizk.entity.po.WxUserSession;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface WxUserSessionService extends IService<WxUserSession> {
|
||||
Long findMaxSessionId(String openid);
|
||||
}
|
||||
@@ -0,0 +1,494 @@
|
||||
package cn.unizk.service.impl;
|
||||
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.unizk.entity.po.Conversation;
|
||||
import cn.unizk.entity.po.Message;
|
||||
import cn.unizk.entity.vo.ReplyVo;
|
||||
import cn.unizk.mapper.ConversationMapper;
|
||||
import cn.unizk.mapper.MessageMapper;
|
||||
import cn.unizk.service.AIAdviceService;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.client.HttpStatusCodeException;
|
||||
import org.springframework.web.client.RestClientException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @Author lj
|
||||
* @Date 2025/7/149 16:30
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Service
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@EnableTransactionManagement
|
||||
public class AIAdviceServiceImpl implements AIAdviceService {
|
||||
|
||||
private static final String DP_API_KEY = "sk-1338e30687cd47d3adda5ae9d903d319"; //刘杰
|
||||
// private static final String DP_API_URL = "https://api.deepseek.com";
|
||||
private static final String DP_API_URL = "https://api.deepseek.com/chat/completions";
|
||||
|
||||
private final RestTemplate restTemplate = new RestTemplate();
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
// 使用正确的模型名称
|
||||
// private static final String MODEL_NAME = "deepseek-reasoner"; // r1
|
||||
private static final String MODEL_NAME = "deepseek-chat"; // 多轮文档
|
||||
|
||||
private final ConversationMapper conversationMapper;
|
||||
|
||||
private final MessageMapper messageMapper;
|
||||
|
||||
|
||||
// 问题到描述短语的映射
|
||||
private static final Map<String, String> QUESTION_MAPPING = new HashMap<>();
|
||||
|
||||
// 疼痛位置到炎症名词的映射
|
||||
private static final Map<String, String> PAIN_LOCATION_MAPPING = new HashMap<>();
|
||||
|
||||
static {
|
||||
QUESTION_MAPPING.put("性别", "性别");
|
||||
QUESTION_MAPPING.put("年龄", "年龄");
|
||||
QUESTION_MAPPING.put("身高", "身高");
|
||||
QUESTION_MAPPING.put("体重", "体重");
|
||||
QUESTION_MAPPING.put("1.您膝关节疼痛的具体位置是哪里?", "膝关节疼痛的具体位置是");
|
||||
QUESTION_MAPPING.put("2.您的膝关节疼痛持续了多长时间?", "膝关节疼痛持续");
|
||||
QUESTION_MAPPING.put("3.您当前的膝关节疼痛程度如何?", "当前膝关节疼痛程度为");
|
||||
QUESTION_MAPPING.put("4.您的膝关节主要是哪种类型的疼痛?", "膝关节疼痛类型为");
|
||||
QUESTION_MAPPING.put("5.在哪些特定动作或姿势下您的膝关节疼痛会明显出现或加重?", "膝关节疼痛在以下情况加重:");
|
||||
QUESTION_MAPPING.put("6.您的膝关节疼痛是否会向其他部位扩散或放射?", "膝关节疼痛扩散情况:");
|
||||
QUESTION_MAPPING.put("7.您的膝关节还有哪些伴随症状?", "膝关节伴随症状:");
|
||||
QUESTION_MAPPING.put("8.您的膝关节在哪些活动方向上感到受限?", "膝关节活动受限方向:");
|
||||
QUESTION_MAPPING.put("9.您是否感觉膝关节不稳定?", "膝关节不稳定表现:");
|
||||
QUESTION_MAPPING.put("10.您认为导致您膝关节疼痛的主要原因是什么?", "导致膝关节疼痛的主要原因:");
|
||||
|
||||
// 初始化疼痛位置映射
|
||||
PAIN_LOCATION_MAPPING.put("位置1", "股四头肌肌腱炎");
|
||||
PAIN_LOCATION_MAPPING.put("位置2", "股内侧肌拉伤");
|
||||
PAIN_LOCATION_MAPPING.put("位置3", "股直肌肌腱炎髌上囊囊肿");
|
||||
PAIN_LOCATION_MAPPING.put("位置4", "膝关节外侧疼痛");
|
||||
PAIN_LOCATION_MAPPING.put("位置5", "髌骨外侧疼痛");
|
||||
PAIN_LOCATION_MAPPING.put("位置6", "髌骨综合征");
|
||||
PAIN_LOCATION_MAPPING.put("位置7", "髌骨内侧疼痛");
|
||||
PAIN_LOCATION_MAPPING.put("位置8", "膝关节内侧疼痛");
|
||||
PAIN_LOCATION_MAPPING.put("位置9", "半月板损伤");
|
||||
PAIN_LOCATION_MAPPING.put("位置10", "脂肪垫炎");
|
||||
PAIN_LOCATION_MAPPING.put("位置11", "髌腱炎");
|
||||
PAIN_LOCATION_MAPPING.put("位置12", "胫骨骨骺炎");
|
||||
PAIN_LOCATION_MAPPING.put("位置13", "鹅足滑囊炎");
|
||||
}
|
||||
|
||||
private static final String SYSTEM_PROMPT = "你是一位专业的膝关节医疗顾问,我会提供收集的用户信息,请你根据信息给出符合用户病情的诊断参考报告。"
|
||||
// + "报告内容包括:主诉、现病史、既往史、初步诊断、用药或治疗、饮食与运动、注意事项。要求详细、专业、只提供内容即可,不要多余的解释。";
|
||||
+ "报告内容包括:一、初步诊断 二、病因及机制分析(1.诊断结论 2.形成原因) 三、康复建议。要求详细、专业、只提供内容即可,不要多余的解释。";
|
||||
@Override
|
||||
public ReplyVo reply(ReplyVo vo) {
|
||||
//新
|
||||
return vo;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ReplyVo saveConversation(List<Map<String, List<String>>> conversation,String openid) {
|
||||
|
||||
ReplyVo vo = new ReplyVo();
|
||||
|
||||
if (validateParams(conversation, openid)) {
|
||||
vo.setContent("参数错误");
|
||||
return vo;
|
||||
}
|
||||
try {
|
||||
|
||||
// 1. 构建症状摘要
|
||||
String summary = buildSymptomSummary(conversation);
|
||||
// 2. 保存会话记录
|
||||
Conversation conversationInfo = saveConversationToDB(conversation, openid, summary);
|
||||
String sessionId = conversationInfo.getSessionId();
|
||||
|
||||
// 3. 构建AI请求消息
|
||||
// List<Map<String, String>> messageList = buildMessageList(summary);
|
||||
|
||||
// 4. 获取AI诊断报告
|
||||
// String response = getChatCompletion(messageList);
|
||||
|
||||
//25年 10-10日 第一版修改为不需要ai诊断,采用模板形式
|
||||
String response = "模板";
|
||||
// 5. 封装返回结果
|
||||
vo.setContent(response);
|
||||
vo.setSessionId(sessionId);
|
||||
|
||||
//将诊断回复存储到数据库
|
||||
conversationInfo.setAiDiagnosis(response);
|
||||
conversationMapper.updateConversation(conversationInfo);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("调用 DeepSeek API 失败", e);
|
||||
throw new RuntimeException("出现错误,AI助手暂时无法响应您的请求,请稍后再试。", e);
|
||||
}
|
||||
|
||||
return vo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject getTreatmentPlan(String sessionId){
|
||||
//获取sessionId
|
||||
// 1. 参数校验(使用具体异常而非空注释)
|
||||
if (StringUtils.isBlank(sessionId)) {
|
||||
throw new IllegalArgumentException("参数错误");
|
||||
}
|
||||
JSONObject plan = new JSONObject();
|
||||
JSONObject errorResponse = new JSONObject();
|
||||
try {
|
||||
//根据参数去查询
|
||||
Conversation conversation = conversationMapper.selectBySessionId(sessionId);
|
||||
String qaJson = conversation.getQaJson();
|
||||
//转为List<Map<String, String>> 来判断以及重组返回值
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
List<Map<String, String>> qaList = objectMapper.readValue(
|
||||
qaJson,
|
||||
new TypeReference<List<Map<String, String>>>() {}
|
||||
);
|
||||
|
||||
System.out.println(qaList);
|
||||
System.out.println(qaList);
|
||||
System.out.println(qaList);
|
||||
|
||||
plan.put("patientId", "P12345");
|
||||
} catch (Exception e) {
|
||||
|
||||
errorResponse.put("content", "出错了" + e.getMessage());
|
||||
// 9. 异常处理
|
||||
return errorResponse;
|
||||
}
|
||||
|
||||
return plan;
|
||||
}
|
||||
|
||||
|
||||
// --- 辅助方法 ---
|
||||
private boolean validateParams(List<Map<String, List<String>>> conversation, String openid) {
|
||||
return conversation == null || conversation.isEmpty() ||
|
||||
openid == null || openid.isEmpty();
|
||||
}
|
||||
|
||||
private String buildSymptomSummary(List<Map<String, List<String>>> conversation) {
|
||||
StringBuilder summary = new StringBuilder("患者");
|
||||
|
||||
for (Map<String, List<String>> item : conversation) {
|
||||
for (Map.Entry<String, List<String>> entry : item.entrySet()) {
|
||||
String question = entry.getKey();
|
||||
List<String> answers = entry.getValue();
|
||||
|
||||
// 获取预定义的描述短语
|
||||
String description = QUESTION_MAPPING.getOrDefault(question, question);
|
||||
|
||||
// 特殊处理疼痛位置
|
||||
if ("1.您膝关节疼痛的具体位置是哪里?".equals(question)) {
|
||||
String processedAnswer = replacePainLocations(answers);
|
||||
summary.append(description).append(processedAnswer).append(",");
|
||||
continue;
|
||||
}
|
||||
|
||||
// 处理多选答案,用"和"连接
|
||||
String answerStr;
|
||||
if (answers.size() == 1) {
|
||||
answerStr = answers.get(0);
|
||||
} else {
|
||||
answerStr = String.join("和", answers);
|
||||
}
|
||||
|
||||
summary.append(description).append(answerStr).append(",");
|
||||
}
|
||||
}
|
||||
|
||||
// 移除最后一个逗号
|
||||
if (summary.length() > 0) {
|
||||
summary.setLength(summary.length() - 1);
|
||||
}
|
||||
|
||||
return summary.toString();
|
||||
}
|
||||
|
||||
private Conversation saveConversationToDB(List<Map<String, List<String>>> conversation,
|
||||
String openid, String summary) {
|
||||
|
||||
|
||||
String sessionId = UUID.randomUUID().toString().replace("-", "");
|
||||
Conversation conversationInfo = new Conversation();
|
||||
conversationInfo.setSessionId(sessionId);
|
||||
conversationInfo.setUserId(openid);
|
||||
conversationInfo.setQaJson(conversation.toString());
|
||||
conversationInfo.setSymptomSummary(summary);
|
||||
conversationMapper.insertConversation(conversationInfo);
|
||||
return conversationInfo;
|
||||
}
|
||||
|
||||
|
||||
private List<Map<String, String>> buildMessageList(String summary) {
|
||||
List<Map<String, String>> messageList = new ArrayList<>();
|
||||
|
||||
// 系统消息
|
||||
messageList.add(createMessage("system", SYSTEM_PROMPT));
|
||||
// 用户消息
|
||||
messageList.add(createMessage("user", "信息:" + summary));
|
||||
|
||||
return messageList;
|
||||
}
|
||||
|
||||
|
||||
private Map<String, String> createMessage(String role, String content) {
|
||||
Map<String, String> message = new HashMap<>();
|
||||
message.put("role", role);
|
||||
message.put("content", content);
|
||||
return message;
|
||||
}
|
||||
|
||||
private String replacePainLocations(List<String> locations) {
|
||||
List<String> replacedLocations = new ArrayList<>();
|
||||
|
||||
for (String loc : locations) {
|
||||
String trimmedLoc = loc.trim();
|
||||
|
||||
// 检查是否是位置编码格式
|
||||
if (trimmedLoc.startsWith("位置")) {
|
||||
// 从映射表中获取医学名词,如果没有则返回原值
|
||||
String medicalTerm = PAIN_LOCATION_MAPPING.get(trimmedLoc);
|
||||
if (medicalTerm != null) {
|
||||
replacedLocations.add(medicalTerm);
|
||||
} else {
|
||||
replacedLocations.add(trimmedLoc);
|
||||
}
|
||||
} else {
|
||||
// 如果已经是医学名词,直接使用
|
||||
replacedLocations.add(trimmedLoc);
|
||||
}
|
||||
}
|
||||
|
||||
// 用顿号连接处理后的位置
|
||||
return String.join("、", replacedLocations);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// @Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ReplyVo reply000(ReplyVo vo) {
|
||||
try {
|
||||
// 使用实际的用户输入
|
||||
String userMessage = vo.getContent(); // 实际应该使用 vo 中的内容
|
||||
Integer sort = vo.getSort();
|
||||
|
||||
// 构造消息列表
|
||||
List<Map<String, String>> userMessageList = new ArrayList<>();
|
||||
|
||||
// 系统提示词
|
||||
Map<String, String> systemMessage = new HashMap<>();
|
||||
|
||||
String content ="你是一位专业的膝关节医疗顾问,我想打造一个智能化理疗问诊平台,通过动态流程引擎实现全自动问诊路径控制,确保在10分钟内高效完成从症状收集到初步诊断的全流程," +
|
||||
"同时支持基于患者实时回答的智能分支跳转,保障问诊过程的专业性与时效性。一期建设主要实现膝盖疼痛、损伤等顽疾的诊断治疗。我会提供给你用户的回复,你根据最新的回复判断下一次提问的问题," +
|
||||
"问题围绕这些维度展开:'主要症状','症状时长','伴随症状','损伤机制'" +
|
||||
"只提供给我问题本身即可,不要多余的回复,例如:用户:我头疼。AI:头疼多久了?额外要求:若该回复和诊断膝盖无关,请输出'无关'二字,不需要多余的解释。";
|
||||
// "2.若生成的问题为“膝盖疼痛位置”相关,则不输出问题,只回复'图片'二字,不需要多余的解释。" ;
|
||||
//在下列7个维度中,
|
||||
systemMessage.put("role", "system");
|
||||
systemMessage.put("content", content);
|
||||
userMessageList.add(systemMessage);
|
||||
|
||||
Message message = new Message();
|
||||
String sessionId = "";
|
||||
if(vo.getSort() == 1){
|
||||
//第一次会话 生成会话id
|
||||
sessionId = UUID.randomUUID().toString().replace("-", "");
|
||||
|
||||
Conversation conversation = new Conversation();
|
||||
conversation.setSessionId(sessionId);
|
||||
conversation.setUserId(vo.getOpenid());
|
||||
//存储到会话表数据 后面ai判断无关时 更新状态
|
||||
conversationMapper.insertConversation(conversation);
|
||||
//存储到对话信息表
|
||||
message.setSessionId(sessionId);
|
||||
message.setSort(sort);
|
||||
message.setAiMessage("请问有什么可以帮助你?");
|
||||
message.setUserMessage(vo.getContent());
|
||||
messageMapper.insertMessage(message);
|
||||
|
||||
}else {
|
||||
sessionId = vo.getSessionId();
|
||||
//查询最新的那条
|
||||
|
||||
|
||||
//查询数据库是否有数据 状态为1 的有效数据 2无效数据
|
||||
List<Message> messageList= messageMapper.selectBySessionIdList(sessionId);
|
||||
//将messageList 所有数据组合到userMessageList 中
|
||||
for (Message messageInfo : messageList) {
|
||||
// 处理AI消息(assistant角色)
|
||||
Map<String, String> assistantMsg = new HashMap<>();
|
||||
assistantMsg.put("role", "assistant");
|
||||
assistantMsg.put("content", messageInfo.getAiMessage()); // 使用Message对象的aiMessage字段
|
||||
userMessageList.add(assistantMsg);
|
||||
|
||||
// 处理用户消息(user角色)
|
||||
Map<String, String> userMsg = new HashMap<>();
|
||||
userMsg.put("role", "user");
|
||||
userMsg.put("content", messageInfo.getUserMessage()); // 使用Message对象的userMessage字段
|
||||
userMessageList.add(userMsg);
|
||||
}
|
||||
}
|
||||
|
||||
//组装多轮对话
|
||||
|
||||
|
||||
// 用户消息
|
||||
Map<String, String> userMessageMap = new HashMap<>();
|
||||
userMessageMap.put("role", "user");
|
||||
userMessageMap.put("content", "用户回复:"+userMessage);
|
||||
userMessageList.add(userMessageMap);
|
||||
|
||||
|
||||
// Map<String, String> userMessageMap1 = new HashMap<>();
|
||||
// userMessageMap1.put("role", "assistant");
|
||||
// userMessageMap1.put("content", "请问您的膝盖是否有疼痛或不适感");
|
||||
// userMessageList.add(userMessageMap1);
|
||||
//
|
||||
// Map<String, String> userMessageMap2 = new HashMap<>();
|
||||
// userMessageMap2.put("role", "user");
|
||||
// userMessageMap2.put("content", "涨得慌");
|
||||
// userMessageList.add(userMessageMap2);
|
||||
//
|
||||
// Map<String, String> userMessageMap3 = new HashMap<>();
|
||||
// userMessageMap3.put("role", "assistant");
|
||||
// userMessageMap3.put("content", "您的膝盖是否有肿胀或发红的现象?");
|
||||
// userMessageList.add(userMessageMap3);
|
||||
//
|
||||
// Map<String, String> userMessageMap4 = new HashMap<>();
|
||||
// userMessageMap4.put("role", "user");
|
||||
// userMessageMap4.put("content", "有");
|
||||
// userMessageList.add(userMessageMap4);
|
||||
//
|
||||
//
|
||||
// Map<String, String> userMessageMap5 = new HashMap<>();
|
||||
// userMessageMap5.put("role", "assistant");
|
||||
// userMessageMap5.put("content", "肿胀和发红的症状持续了多长时间?");
|
||||
// userMessageList.add(userMessageMap5);
|
||||
//
|
||||
// Map<String, String> userMessageMap6 = new HashMap<>();
|
||||
// userMessageMap6.put("role", "user");
|
||||
// userMessageMap6.put("content", "好几天咧");
|
||||
// userMessageList.add(userMessageMap6);
|
||||
|
||||
System.out.println(userMessageList);
|
||||
String response = getChatCompletion(userMessageList);
|
||||
|
||||
// //得到答案后存储 数据库
|
||||
Message nextMessage = new Message();
|
||||
Integer nextSort = sort+1; //sort +1
|
||||
if(("无关").equals(response)){
|
||||
// 状态为2 更新status
|
||||
// response =
|
||||
}else {
|
||||
nextMessage.setSessionId(sessionId);
|
||||
nextMessage.setSort(nextSort);
|
||||
|
||||
}
|
||||
|
||||
System.out.println("AI 回复: " + response);
|
||||
|
||||
// 将 AI 回复设置到返回对象
|
||||
vo.setContent(response);
|
||||
vo.setSort(nextSort);
|
||||
vo.setSessionId(sessionId);
|
||||
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("调用 DeepSeek API 失败", e);
|
||||
vo.setContent("很抱歉,AI助手暂时无法响应您的请求,请稍后再试。");
|
||||
throw new RuntimeException("出现错误,AI助手暂时无法响应您的请求,请稍后再试。", e);
|
||||
}
|
||||
return vo;
|
||||
}
|
||||
|
||||
public String getChatCompletion( List<Map<String, String>> userMessageList) throws Exception {
|
||||
// 设置请求头
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
headers.setBearerAuth(DP_API_KEY);
|
||||
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
|
||||
|
||||
|
||||
|
||||
// 构造请求体
|
||||
Map<String, Object> body = new HashMap<>();
|
||||
body.put("model", MODEL_NAME);
|
||||
body.put("messages", userMessageList);
|
||||
body.put("stream", false);
|
||||
body.put("max_tokens", 1024);
|
||||
|
||||
// 构造请求实体
|
||||
HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(body, headers);
|
||||
|
||||
try {
|
||||
// 发送请求
|
||||
ResponseEntity<String> response = restTemplate.exchange(
|
||||
DP_API_URL,
|
||||
HttpMethod.POST,
|
||||
requestEntity,
|
||||
String.class
|
||||
);
|
||||
|
||||
// 检查响应状态(处理非200状态码)
|
||||
if (response.getStatusCode() != HttpStatus.OK) {
|
||||
String errorMsg = "DeepSeek API 返回错误状态: " + response.getStatusCode();
|
||||
log.error(errorMsg);
|
||||
throw new Exception(errorMsg);
|
||||
}
|
||||
|
||||
// 解析响应
|
||||
Map<String, Object> result = objectMapper.readValue(response.getBody(), Map.class);
|
||||
List<Map<String, Object>> choices = (List<Map<String, Object>>) result.get("choices");
|
||||
Map<String, Object> message = (Map<String, Object>) choices.get(0).get("message");
|
||||
|
||||
return (String) message.get("content");
|
||||
|
||||
} catch (HttpStatusCodeException e) {
|
||||
// 捕获所有HTTP状态异常 (4xx/5xx)
|
||||
String errorMsg = String.format("DeepSeek API 错误: %d - %s",
|
||||
e.getStatusCode().value(), e.getResponseBodyAsString());
|
||||
log.error(errorMsg);
|
||||
throw new Exception(errorMsg, e);
|
||||
} catch (JsonProcessingException e) {
|
||||
// 捕获JSON解析异常
|
||||
String errorMsg = "响应JSON解析失败: " + e.getMessage();
|
||||
log.error(errorMsg);
|
||||
throw new Exception(errorMsg, e);
|
||||
} catch (ClassCastException | NullPointerException e) {
|
||||
// 捕获类型转换和空指针异常
|
||||
String errorMsg = "API响应格式异常: " + e.getMessage();
|
||||
log.error(errorMsg);
|
||||
throw new Exception(errorMsg, e);
|
||||
} catch (RestClientException e) {
|
||||
// 捕获其他RestTemplate异常(网络问题等)
|
||||
String errorMsg = "API请求失败: " + e.getMessage();
|
||||
log.error(errorMsg);
|
||||
throw new Exception(errorMsg, e);
|
||||
} catch (Exception e) {
|
||||
// 捕获所有其他未处理异常
|
||||
String errorMsg = "未知API错误: " + e.getMessage();
|
||||
log.error(errorMsg);
|
||||
throw new Exception(errorMsg, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package cn.unizk.service.impl;
|
||||
|
||||
import cn.unizk.entity.po.Combo;
|
||||
import cn.unizk.mapper.ComboMapper;
|
||||
import cn.unizk.service.ComboService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/8/30 17:23
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Service
|
||||
public class ComboServiceImpl extends ServiceImpl<ComboMapper, Combo> implements ComboService {
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package cn.unizk.service.impl;
|
||||
|
||||
import cn.unizk.entity.po.Device;
|
||||
import cn.unizk.mapper.DeviceMapper;
|
||||
import cn.unizk.service.DeviceService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/8/30 17:07
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Service
|
||||
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements DeviceService {
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package cn.unizk.service.impl;
|
||||
|
||||
import cn.unizk.entity.vo.ResultData;
|
||||
import cn.unizk.service.IAiService;
|
||||
import com.volcengine.ark.runtime.model.responses.constant.ResponsesConstants;
|
||||
import com.volcengine.ark.runtime.model.responses.content.InputContentItemText;
|
||||
import com.volcengine.ark.runtime.model.responses.content.OutputContentItemText;
|
||||
import com.volcengine.ark.runtime.model.responses.item.ItemEasyMessage;
|
||||
import com.volcengine.ark.runtime.model.responses.item.ItemOutputMessage;
|
||||
import com.volcengine.ark.runtime.model.responses.item.MessageContent;
|
||||
import com.volcengine.ark.runtime.model.responses.request.CreateResponsesRequest;
|
||||
import com.volcengine.ark.runtime.model.responses.request.ResponsesInput;
|
||||
import com.volcengine.ark.runtime.model.responses.response.ResponseObject;
|
||||
import com.volcengine.ark.runtime.service.ArkService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2026/5/12 16:36
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Service
|
||||
public class DoubaoServiceImpl implements IAiService {
|
||||
|
||||
public String drawConclusion(String input1,String input2){
|
||||
String apiKey = "ark-9da95e96-cffe-4e7d-afc5-771990873320-24c67";
|
||||
// 创建ArkService实例
|
||||
ArkService arkService = ArkService.builder().apiKey(apiKey).baseUrl("https://ark.cn-beijing.volces.com/api/v3").build();
|
||||
CreateResponsesRequest request = CreateResponsesRequest.builder()
|
||||
.model("doubao-seed-1-8-251228")
|
||||
.input(ResponsesInput.builder().addListItem(
|
||||
ItemEasyMessage.builder().role(ResponsesConstants.MESSAGE_ROLE_USER).content(
|
||||
MessageContent.builder()
|
||||
.addListItem(InputContentItemText.builder().text(input1).build())
|
||||
.addListItem(InputContentItemText.builder().text(input2).build())
|
||||
.build()
|
||||
).build()
|
||||
).build())
|
||||
.build();
|
||||
ResponseObject resp = arkService.createResponse(request);
|
||||
System.out.println(resp);
|
||||
String result = resp.getOutput().stream()
|
||||
.filter(item -> item instanceof ItemOutputMessage)
|
||||
.map(item -> (ItemOutputMessage) item)
|
||||
.flatMap(msg -> msg.getContent().stream())
|
||||
.filter(c -> c instanceof OutputContentItemText)
|
||||
.map(c -> ((OutputContentItemText) c).getText())
|
||||
.findFirst()
|
||||
.orElse("获取答案失败");
|
||||
System.out.println("result="+result);
|
||||
arkService.shutdownExecutor();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package cn.unizk.service.impl;
|
||||
|
||||
import cn.unizk.entity.po.SysFile;
|
||||
import cn.unizk.mapper.FileMapper;
|
||||
import cn.unizk.service.FileService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/10/9 17:20
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Service
|
||||
public class FileServiceImpl extends ServiceImpl<FileMapper, SysFile> implements FileService {
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package cn.unizk.service.impl;
|
||||
|
||||
import cn.unizk.entity.po.JkPhysio;
|
||||
import cn.unizk.mapper.JkPhysioMapper;
|
||||
import cn.unizk.service.JkPhysioService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/8/25 10:57
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class JkPhysioServiceImpl extends ServiceImpl<JkPhysioMapper, JkPhysio> implements JkPhysioService {
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package cn.unizk.service.impl;
|
||||
|
||||
import cn.unizk.entity.po.JkProduct;
|
||||
import cn.unizk.mapper.JkProductMapper;
|
||||
import cn.unizk.service.JkProductService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/8/25 11:00
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class JkProductServiceImpl extends ServiceImpl<JkProductMapper,JkProduct> implements JkProductService {
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package cn.unizk.service.impl;
|
||||
|
||||
import cn.unizk.entity.po.JkStore;
|
||||
import cn.unizk.mapper.JkStoreMapper;
|
||||
import cn.unizk.service.JkStoreService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/8/19 11:26
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class JkStoreServiceImpl extends ServiceImpl<JkStoreMapper, JkStore> implements JkStoreService {
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package cn.unizk.service.impl;
|
||||
|
||||
import cn.unizk.entity.po.ProductCarousel;
|
||||
import cn.unizk.mapper.ProductCarouselMapper;
|
||||
import cn.unizk.service.ProductCarouselService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @Author hao
|
||||
* @Date 2025/9/16 15:40
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Service
|
||||
public class ProductCarouselServiceImpl extends ServiceImpl<ProductCarouselMapper, ProductCarousel> implements ProductCarouselService {
|
||||
}
|
||||
Loaded 100 of 1456 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user