feat: add core entities, controllers, services, and mappers across multi-module project

This commit is contained in:
zhangsz committed 2026-09-20 15:03:05 +08:00
commit 4335344af7
1456 files changed
+58308

No files matched your search

View File
Whitespace-only changes.
View File
Whitespace-only changes.
+116
View File
@@ -0,0 +1,116 @@
<?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>mobileApp</artifactId>
<name>mobileApp</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>cn.unizk</groupId>
<artifactId>common</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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>
<!-- 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>
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk18on -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</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,15 @@
package cn.unizk;
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 MobileApp {
public static void main(String[] args) {
SpringApplication.run(MobileApp.class,args);
}
}
@@ -0,0 +1,13 @@
package cn.unizk;
/**
* @Author hao
* @Date 2026/6/30 14:54
* @Version 1.0
**/
public class MobileAppConstant {
public static final String CACHE_TOKEN_PREFIX = "mobile-t:";
public static final String REQUEST_TOKEN_HEADER = "mobile-t";
}
@@ -0,0 +1,29 @@
package cn.unizk.config;
import cn.unizk.interceptor.MobileAppLoginInterceptor;
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 2026/6/30 11:21
* @Version 1.0
**/
@Configuration
public class ResourceConfig implements WebMvcConfigurer {
@Resource
private MobileAppLoginInterceptor loginInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor).addPathPatterns("/**")
.excludePathPatterns("/mobileApp/login/**",
"/hf/webhook/**",
"/test/**",
"/mobileApp/module/**");
}
}
@@ -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 2026/7/24 17:48
* @Version 1.0
**/
@ConfigurationProperties(prefix = "wx")
@Component
@Getter
@Setter
public class WxProperties {
private String appid;
private String secret;
}
@@ -0,0 +1,46 @@
package cn.unizk.controller;
import cn.unizk.MobileAppConstant;
import cn.unizk.entity.po.AppletModule;
import cn.unizk.entity.po.MobileAppUser;
import cn.unizk.mapper.AppletModuleMapper;
import cn.unizk.utils.MobileAppSecurityUtil;
import org.apache.commons.lang3.StringUtils;
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;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;
/**
* @Author hao
* @Date 2026/8/11 15:34
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp/module")
public class AppModuleController {
@Resource
private AppletModuleMapper appletModuleMapper;
@GetMapping("/getModule")
public List<AppletModule> getModule(HttpServletRequest request){
String token = request.getHeader(MobileAppConstant.REQUEST_TOKEN_HEADER);
if (StringUtils.isBlank(token)){
return appletModuleMapper.getModule("app","C");
}
MobileAppUser currentUser = MobileAppSecurityUtil.getCurrentUser(token);
if (Objects.isNull(currentUser)){
return appletModuleMapper.getModule("app","C");
}
String userType = currentUser.getUserType();
if (StringUtils.isBlank(userType)){
userType = "C";
}
return appletModuleMapper.getModule("app",userType);
}
}
@@ -0,0 +1,208 @@
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.MobileAppSecurityUtil;
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.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* @Author hao
* @Date 2026/7/1 11:32
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp/appointment")
@Slf4j
public class AppointmentController {
@Resource
private DailySchedulesMapper dailySchedulesMapper;
@Resource
private MobileUserMedicalVisitInfoMapper medicalVisitInfoMapper;
@Resource
private MobileAppointmentsMapper mobileAppointmentsMapper;
@Resource
private MobilePhysioMapper jkPhysioMapper;
@Resource
private MobileStoreMapper storeMapper;
@Resource
private TimeSlotsMapper timeSlotsMapper;
@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 = MobileAppSecurityUtil.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 mobileUserMedicalVisitInfo = medicalVisitInfoMapper.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(mobileUserMedicalVisitInfo.getName());
appointments.setPatientPhone(mobileUserMedicalVisitInfo.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);
return ResultData.success();
}
@PostMapping("/addOrUpdateMedicalVisitInfo")
public ResultData addMedicalVisitInfo(HttpServletRequest request, @RequestBody MobileUserMedicalVisitInfo info){
if (info.getId() == null){
MobileAppUser currentUser = MobileAppSecurityUtil.getCurrentUser(request);
List<MobileUserMedicalVisitInfo> mobileUserMedicalVisitInfos = medicalVisitInfoMapper.selectList(new LambdaQueryWrapper<MobileUserMedicalVisitInfo>().eq(MobileUserMedicalVisitInfo::getMobileUserId, currentUser
.getId()));
if (mobileUserMedicalVisitInfos.size() >= 3){
throw new ServiceException("最多只能添加3张就诊卡");
}
info.setMobileUserId(currentUser.getId());
info.setCreateTime(LocalDateTime.now());
medicalVisitInfoMapper.insert(info);
}else {
if (info.getItsDefault() == 1){
medicalVisitInfoMapper.update(new LambdaUpdateWrapper<MobileUserMedicalVisitInfo>().set(MobileUserMedicalVisitInfo::getItsDefault,0));
}
medicalVisitInfoMapper.updateById(info);
}
return ResultData.success();
}
@GetMapping("/getDefaultVisitInfo")
public ResultData getDefVisitInfo(HttpServletRequest request){
MobileAppUser currentUser = MobileAppSecurityUtil.getCurrentUser(request);
MobileUserMedicalVisitInfo mobileUserMedicalVisitInfo = medicalVisitInfoMapper.selectOne(new LambdaQueryWrapper<MobileUserMedicalVisitInfo>().eq(MobileUserMedicalVisitInfo::getMobileUserId, currentUser.getId()).eq(MobileUserMedicalVisitInfo::getItsDefault, 1));
ResultData<MobileUserMedicalVisitInfo> resultData = new ResultData<>();
if (Objects.nonNull(mobileUserMedicalVisitInfo)){
resultData.setData(mobileUserMedicalVisitInfo);
}else {
MobileUserMedicalVisitInfo visitInfo = medicalVisitInfoMapper.selectLatest(currentUser.getId());
resultData.setData(visitInfo);
}
resultData.setCode(200);
return resultData;
}
@DeleteMapping("/deleteVisitInfo")
public ResultData deleteVisitInfo(@RequestParam("id") Integer id){
medicalVisitInfoMapper.deleteById(id);
return ResultData.success();
}
@GetMapping("/getVisitInfo")
public ResultData getVisitInfo(HttpServletRequest request){
MobileAppUser currentUser = MobileAppSecurityUtil.getCurrentUser(request);
List<MobileUserMedicalVisitInfo> wxUserMedicalVisitInfos = medicalVisitInfoMapper.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 = MobileAppSecurityUtil.getCurrentUser(request);
if (Objects.isNull(currentUser)){
throw new ServiceException(401,"请重新登录");
}
Page<MobileAppointments> page = new Page<>(currentPage,pageSize);
Page<MobileAppointments> mobileAppointmentsPage = mobileAppointmentsMapper.selectPage(page, new LambdaQueryWrapper<MobileAppointments>().eq(MobileAppointments::getMobileUserId, currentUser.getId())
.orderByDesc(MobileAppointments::getCreatedAt));
List<MobileAppointments> appointments = mobileAppointmentsPage.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,97 @@
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.mapper.ComboMapper;
import cn.unizk.service.DeviceService;
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.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 javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* @Author hao
* @Date 2026/6/30 14:34
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp/combo")
@Slf4j
public class ComboController {
@Resource
private ComboMapper comboMapper;
@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 comboMapper.selectPage(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 comboMapper.selectPage(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 comboMapper.selectPage(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,187 @@
package cn.unizk.controller;
import cn.unizk.entity.po.*;
import cn.unizk.entity.vo.ChapterVO;
import cn.unizk.entity.vo.CourseVO;
import cn.unizk.entity.vo.ResultData;
import cn.unizk.entity.vo.VideoProgressVO;
import cn.unizk.exception.ServiceException;
import cn.unizk.mapper.*;
import cn.unizk.utils.BeanCopyUtils;
import cn.unizk.utils.MobileAppSecurityUtil;
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.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.stream.Collectors;
/**
* @Author hao
* @Date 2026/6/30 14:49
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp/course")
public class CourseStudyController {
@Resource
private CourseMapper courseMapper;
@Resource
private MobileUserHaveCourseMapper haveCourseMapper;
@Resource
private MobileUserVideoProgressMapper videoProgressMapper;
@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 = MobileAppSecurityUtil.getCurrentUser(request);
if (Objects.isNull(currentUser)) {
throw new ServiceException(401, "登录已过期,请重新登录");
}
List<MobileUserHaveCourse> userHaveCourses = haveCourseMapper.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 = videoProgressMapper.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 = "10") int pageSize,
@RequestParam("courseId") Integer courseId, HttpServletRequest request) {
/* MobileAppUser currentUser = MobileAppSecurityUtil.getCurrentUser(request);
if (Objects.isNull(currentUser)){
throw new ServiceException(401, "登录已过期,请重新登录");
}
MobileUserHaveCourse userHaveCourse = haveCourseMapper.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 = videoProgressMapper.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);*/
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 = MobileAppSecurityUtil.getCurrentUser(request);
if (Objects.isNull(currentUser)){
throw new ServiceException(401, "登录已过期,请重新登录");
}
MobileUserVideoProgress wxUserVideoProgress = videoProgressMapper.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());
Integer p = (videoProgressVO.getLastPosition() * 100) / chapter.getVideoDuration();
videoProgress.setProgress(p);
videoProgressMapper.insert(videoProgress);
}else {
wxUserVideoProgress.setSpentTime(videoProgressVO.getSpentTime());
if (videoProgressVO.getLastPosition() > wxUserVideoProgress.getLastPosition()){
wxUserVideoProgress.setLastPosition(videoProgressVO.getLastPosition());
Chapter chapter = chapterMapper.selectById(videoProgressVO.getChapterId());
Integer p = (videoProgressVO.getLastPosition() * 100) / chapter.getVideoDuration();
wxUserVideoProgress.setProgress(p);
}
videoProgressMapper.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();
}
}
@@ -0,0 +1,34 @@
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.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;
/**
* @Author hao
* @Date 2026/7/8 17:12
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp/device")
public class DeviceController {
@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,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.DoubaoService;
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/6/30 18:06
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp/doubao")
@Slf4j
public class DoubaoAIController {
@Resource
private DoubaoService 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,52 @@
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.mapper.FileMapper;
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 2026/7/1 17:01
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp/file")
public class FileController {
@Resource
private FileMapper fileMapper;
@Resource
private FileUploadService fileUploadService;
@GetMapping("/getById/{id}")
public SysFile getById(@PathVariable("id") Integer id){
return fileMapper.selectById(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.*;
import cn.unizk.entity.vo.GrfReportVO;
import cn.unizk.entity.vo.GrfdialogueVO;
import cn.unizk.entity.vo.ResultData;
import cn.unizk.mapper.AppointmentsMapper;
import cn.unizk.mapper.GolfCustInfoMapper;
import cn.unizk.mapper.MobileAppUserMapper;
import cn.unizk.mapper.MobileAppointmentsMapper;
import cn.unizk.service.DoubaoService;
import cn.unizk.utils.MobileAppSecurityUtil;
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/7/7 10:33
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp/golf")
@Slf4j
public class GolfController {
@Resource
private DoubaoService doubaoService;
@Resource
private GolfCustInfoMapper golfCustInfoMapper;
@Resource
private MobileAppUserMapper appUserMapper;
@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 = MobileAppSecurityUtil.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));
appUserMapper.updateById(user);
}).start();
return ResultData.success(vo);
}
@PostMapping("/evaluation")
public ResultData evaluation(@RequestBody Appointments 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,53 @@
package cn.unizk.controller;
import cn.hutool.core.util.IdUtil;
import cn.unizk.entity.po.MobileAppUser;
import cn.unizk.entity.po.MobileOrder;
import cn.unizk.entity.vo.ResultData;
import cn.unizk.exception.BusinessException;
import cn.unizk.pay.dto.BasePayResponse;
import cn.unizk.pay.dto.PayBaseRequest;
import cn.unizk.pay.enums.PayChannelEnum;
import cn.unizk.pay.service.HFPayService;
import cn.unizk.utils.MobileAppSecurityUtil;
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.Arrays;
import java.util.Map;
import java.util.Objects;
/**
* @Author hao
* @Date 2026/7/2 11:22
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp/hf")
public class HFPayController {
@Resource
private Map<String,HFPayService> payMap;
@PostMapping("/pay")
public <R extends BasePayResponse> R pay(HttpServletRequest request, @RequestBody PayBaseRequest param){
if (param.getPayChannel().equals(PayChannelEnum.WECHAT.name()) && param.getStep() == null){
param.setStep(1);
}
boolean b = Arrays.stream(PayChannelEnum.values()).anyMatch(e -> e.name().equals(param.getPayChannel()));
if (!b){
throw new BusinessException("不支持的支付渠道");
}
MobileAppUser currentUser = MobileAppSecurityUtil.getCurrentUser(request);
if (Objects.isNull(currentUser)){
throw new BusinessException(401,"登录已过期");
}
param.setMobileAppUserId(currentUser.getId());
HFPayService hfPayService = payMap.get(param.getPayChannel());
return (R) hfPayService.pay(param);
}
}
@@ -0,0 +1,151 @@
package cn.unizk.controller;
import cn.unizk.entity.po.*;
import cn.unizk.enums.OrderStatus;
import cn.unizk.enums.OrderTypeEnum;
import cn.unizk.mapper.*;
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.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.math.BigDecimal;
import java.net.URLDecoder;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
/**
* @Author hao
* @Date 2026/7/8 14:20
* @Version 1.0
**/
@RestController
@RequestMapping("/hf/webhook")
@Slf4j
public class HFPayWebhookController {
@Resource
private MobileOrderMapper mobileOrderMapper;
@Resource
private MobileStoreMapper mobileStoreMapper;
@Resource
private MobileAppUserAccountMapper mobileAppUserAccountMapper;
@Resource
private MobileUserHaveCourseMapper mobileUserHaveCourseMapper;
@RequestMapping("/callback")
public void 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> mobileOrders = mobileOrderMapper.selectList(new LambdaQueryWrapper<MobileOrder>()
.eq(MobileOrder::getOutTradeNo, req_seq_id));
if (CollectionUtils.isEmpty(mobileOrders)){
log.error("没有这个订单,订单out_trade_no:{}",req_seq_id);
return;
}
MobileOrder mobileOrder = mobileOrders.get(0);
if (Objects.isNull(mobileOrder)){
log.error("没有这个订单,订单out_trade_no:{}",req_seq_id);
return;
}
if (OrderStatus.paid.name().equals(mobileOrder.getStatus())){
return;
}
if ("S".equals(trans_stat)){
log.info("交易成功-------+++++++++");
if (mobileOrder.getOrderType() != null && mobileOrder.getOrderType().equals(OrderTypeEnum.SCAN_PAY.getCode())){
scanToPower(mobileOrder);
}else if (mobileOrder.getOrderType() != null && mobileOrder.getOrderType().equals(OrderTypeEnum.MEMBER_RECHARGE.getCode())){
recharge(mobileOrder);
}else if (mobileOrder.getOrderType() != null && mobileOrder.getOrderType().equals(OrderTypeEnum.COURSE_PAY.getCode())){
courseBuy(mobileOrder);
}else if (mobileOrder.getOrderType() != null && mobileOrder.getOrderType().equals(OrderTypeEnum.HGJ_PAY.getCode())){
hgjPay(mobileOrder);
}else if (mobileOrder.getOrderType() != null && mobileOrder.getOrderType().equals(OrderTypeEnum.GOLF_SERVICE_PAY.getCode())){
golfService(mobileOrder);
}else if (mobileOrder.getOrderType() != null && mobileOrder.getOrderType().equals(OrderTypeEnum.PRODUCT_PAY.getCode())){
productPay(mobileOrder);
}else if (mobileOrder.getOrderType() != null && mobileOrder.getOrderType().equals(OrderTypeEnum.SHOPPING_CART_PAY.getCode())){
shoppingCartPay(mobileOrders);
}
}
}catch (Exception e){
e.printStackTrace();
}
}
private void scanToPower(MobileOrder order){
order.setStatus(OrderStatus.paid.name());
JkStore jkStore = mobileStoreMapper.selectById(order.getDeviceId());
order.setStoreId(jkStore.getId());
order.setPayTime(LocalDateTime.now());
mobileOrderMapper.updateById(order);
}
private void recharge(MobileOrder order){
order.setStatus(OrderStatus.paid.name());
order.setPayTime(LocalDateTime.now());
MobileAppUserAccount mobileAppUserAccount = mobileAppUserAccountMapper.selectOne(new LambdaQueryWrapper<MobileAppUserAccount>()
.eq(MobileAppUserAccount::getMobileUserId, order.getMobileUserId()));
if (Objects.isNull(mobileAppUserAccount)){
MobileAppUserAccount account = new MobileAppUserAccount();
account.setMobileUserId(order.getMobileUserId());
account.setAccountBalance(order.getTotalPrice());
mobileAppUserAccountMapper.insert(account);
}else {
BigDecimal add = mobileAppUserAccount.getAccountBalance().add(order.getTotalPrice());
mobileAppUserAccount.setAccountBalance(add);
mobileAppUserAccountMapper.updateById(mobileAppUserAccount);
}
mobileOrderMapper.updateById(order);
}
private void courseBuy(MobileOrder order){
order.setStatus(OrderStatus.paid.name());
order.setPayTime(LocalDateTime.now());
MobileUserHaveCourse userHaveCourse = new MobileUserHaveCourse();
userHaveCourse.setBuyTime(LocalDateTime.now());
userHaveCourse.setCourseId(order.getCourseId());
userHaveCourse.setMobileUserId(order.getMobileUserId());
userHaveCourse.setStatus(1);
mobileUserHaveCourseMapper.insert(userHaveCourse);
mobileOrderMapper.updateById(order);
}
private void hgjPay(MobileOrder order){
order.setStatus(OrderStatus.paid.name());
order.setPayTime(LocalDateTime.now());
mobileOrderMapper.updateById(order);
}
private void golfService(MobileOrder order){
order.setStatus(OrderStatus.paid.name());
order.setPayTime(LocalDateTime.now());
mobileOrderMapper.updateById(order);
}
private void productPay(MobileOrder order){
order.setStatus(OrderStatus.paid.name());
order.setPayTime(LocalDateTime.now());
mobileOrderMapper.updateById(order);
}
private void shoppingCartPay(List<MobileOrder> mobileOrders){
for (MobileOrder order : mobileOrders) {
order.setPayTime(LocalDateTime.now());
order.setStatus(OrderStatus.paid.name());
}
mobileOrderMapper.updateById(mobileOrders);
}
}
@@ -0,0 +1,154 @@
package cn.unizk.controller;
import cn.unizk.entity.po.MobileAppUser;
import cn.unizk.entity.vo.MobileAppLoginRequestVO;
import cn.unizk.entity.vo.MobileAppUserVO;
import cn.unizk.entity.vo.ResultData;
import cn.unizk.exception.BusinessException;
import cn.unizk.service.UniCloudClient;
import cn.unizk.service.UserService;
import cn.unizk.utils.AESUtil;
import cn.unizk.utils.CaptchaGenerator;
import cn.unizk.utils.MobileJwtUtil;
import cn.unizk.utils.SendSmsUtil;
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.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.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
/**
* @Author hao
* @Date 2026/6/30 11:18
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp/login")
@Slf4j
public class LoginController {
@Resource
private UserService userService;
@Resource
private CaptchaGenerator captchaGenerator;
@Value("${spring.profiles.active}")
private String active;
@Autowired
@Qualifier("kryoRedisTemplate")
private RedisTemplate<String, Object> redisTemplate;
private static final String PLAIN_TEXT = "unizk.jkzy";
@PostMapping("/oneClick")
public ResultData loginByPhone(@RequestBody MobileAppLoginRequestVO vo) throws Exception {
String decrypt = AESUtil.decrypt(vo.getPlainText());
if (!PLAIN_TEXT.equals(decrypt)){
throw new BusinessException("密文错误");
}
// String phoneNumber = UniCloudClient.getPhoneNumber(vo.getAccessToken());
MobileAppUser appUser = userService.userLogin(vo.getPhoneNumber());
String token = MobileJwtUtil.generateToken(appUser.getPhoneNumber());
ResultData<MobileAppUserVO> resultData = new ResultData<>();
resultData.setCode(200);
MobileAppUserVO userVO = new MobileAppUserVO();
BeanUtils.copyProperties(appUser,userVO);
userVO.setToken(token);
resultData.setData(userVO);
return resultData;
}
@PostMapping("/loginByPhoneCode")
public ResultData<MobileAppUserVO> loginByPhoneCode(@RequestParam("phoneNumber") String phoneNumber,
@RequestParam("code") String code){
if ("prod".equals(active)){
String cacheCode = (String) redisTemplate.opsForValue().get(phoneNumber);
if (StringUtils.isBlank(cacheCode)){
throw new BusinessException("手机验证码已过期");
}
if (!cacheCode.equals(code)){
throw new BusinessException("验证码错误");
}
}
MobileAppUser appUser = userService.userLogin(phoneNumber);
String token = MobileJwtUtil.generateToken(appUser.getPhoneNumber());
ResultData<MobileAppUserVO> resultData = new ResultData<>();
resultData.setCode(200);
MobileAppUserVO userVO = new MobileAppUserVO();
BeanUtils.copyProperties(appUser,userVO);
userVO.setToken(token);
resultData.setData(userVO);
return resultData;
}
@PostMapping("/sendPhoneCode")
public ResultData sendPhoneCode(@RequestParam("phoneNumber") String phoneNumber,
@RequestParam("captcha") String captcha,
@RequestParam("uuid") String uuid){
captchaGenerator.verifyCaptcha(captcha,uuid);
if ("prod".equals(active)){
String phoneCode = RandomStringUtils.randomNumeric(6);
log.info("手机验证码:{}",phoneCode);
try {
String s = SendSmsUtil.sendPhoneCode(phoneNumber, phoneCode);
JSONObject res = JSONObject.parseObject(s);
Integer statusCode = res.getInteger("statusCode");
if (statusCode != null && statusCode == 200){
redisTemplate.opsForValue().set(phoneNumber,phoneCode,300, TimeUnit.SECONDS);
return ResultData.success();
}
return ResultData.failure(500,"验证码发送失败");
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
throw new BusinessException("验证码发送失败");
}
}else {
redisTemplate.opsForValue().set(phoneNumber,"888888",300, TimeUnit.SECONDS);
return ResultData.success();
}
}
@GetMapping("/getUuid")
public ResultData<String> getUuid(){
String uuid = RandomStringUtils.randomNumeric(16);
ResultData<String> data = new ResultData<>();
data.setCode(200);
data.setData(uuid);
return data;
}
@GetMapping("/getCaptcha")
public void getCaptcha(HttpServletResponse response,@RequestParam("uuid") String uuid){
BufferedImage bufferedImage = captchaGenerator.generateCaptcha(uuid);
ServletOutputStream outputStream = null;
try {
outputStream = response.getOutputStream();
ImageIO.write(bufferedImage,"jpg",outputStream);
} catch (IOException e) {
e.printStackTrace();
throw new BusinessException("图片验证码生成异常");
}finally {
if (outputStream != null){
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
@@ -0,0 +1,41 @@
package cn.unizk.controller;
import cn.unizk.MobileAppConstant;
import cn.unizk.entity.po.MobileAppUser;
import cn.unizk.entity.vo.ResultData;
import cn.unizk.utils.MobileAppSecurityUtil;
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.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects;
/**
* @Author hao
* @Date 2026/8/11 15:56
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp")
public class LogoutController {
@Autowired
@Qualifier("kryoRedisTemplate")
private RedisTemplate redisTemplate;
@GetMapping("/logout")
public ResultData logout(HttpServletRequest request){
MobileAppUser currentUser = MobileAppSecurityUtil.getCurrentUser(request);
if (Objects.isNull(currentUser)){
return ResultData.success();
}
redisTemplate.delete(MobileAppConstant.CACHE_TOKEN_PREFIX + currentUser.getPhoneNumber());
return ResultData.success();
}
}
@@ -0,0 +1,60 @@
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 15:50
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp/clinic")
public class MClinicWorkLogController {
@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,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 11:39
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp/inventory")
public class MInventoryController {
@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,329 @@
package cn.unizk.controller;
import cn.unizk.MobileAppConstant;
import cn.unizk.config.WxProperties;
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.BusinessException;
import cn.unizk.exception.ServiceException;
import cn.unizk.mapper.*;
import cn.unizk.utils.HttpUtil;
import cn.unizk.utils.MobileAppSecurityUtil;
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 java.time.Clock;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* @Author hao
* @Date 2026/7/1 17:23
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp/user")
@Slf4j
public class MobileAppUserController {
@Resource
private MobileAppUserMapper mobileAppUserMapper;
@Resource
private MobileUserAddressMapper mobileUserAddressMapper;
@Resource
private MobileOrderMapper orderMapper;
@Resource
private SysDictMapper sysDictMapper;
@Resource
private GrfPjMapper grfPjMapper;
@Resource
private MobileAppUserAccountMapper mobileAppUserAccountMapper;
@Resource
private RechargePackageMapper rechargePackageMapper;
@Resource
private WxProperties wxProperties;
@Resource
private MobilePhysioMapper mobilePhysioMapper;
@Autowired
@Qualifier("kryoRedisTemplate")
private RedisTemplate<String, Object> redisTemplate;
@PostMapping("/editUserInfo")
public ResultData editUserInfo(@RequestBody MobileAppUser user){
mobileAppUserMapper.updateById(user);
return ResultData.success();
}
@GetMapping("/getUserIdType")
public ResultData<Integer> getUserIdType(HttpServletRequest request){
MobileAppUser currentUser = MobileAppSecurityUtil.getCurrentUser(request);
if (Objects.isNull(currentUser)){
throw new ServiceException(401,"登录已过期");
}
JkPhysio one = mobilePhysioMapper.selectOne(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 = MobileAppSecurityUtil.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(MobileAppConstant.CACHE_TOKEN_PREFIX + currentUser.getPhoneNumber());
redisTemplate.opsForValue().set(MobileAppConstant.CACHE_TOKEN_PREFIX + currentUser.getPhoneNumber(), currentUser, 90, TimeUnit.DAYS);
return ResultData.success();
}
@GetMapping("/getCurrentUser")
public MobileAppUser getCurrentUser(HttpServletRequest request){
return MobileAppSecurityUtil.getCurrentUser(request);
}
@PostMapping("/rememberDia")
public ResultData<Integer> rememberDia(HttpServletRequest request, @Validated @RequestBody ReportReqVO vo){
/*MobileAppUser currentUser = MobileAppSecurityUtil.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.setTemplateId(vo.getTemplateId());
user.setPainNumber(vo.getPainNumber());
mobileAppUserMapper.updateById(user);*/
List<String> integers = Lists.newArrayList("1", "2", "4", "8");
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 = MobileAppSecurityUtil.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 = MobileAppSecurityUtil.getCurrentUser(request);
if (currentUser == null){
throw new ServiceException(401,"登陆已过期");
}
address.setMobileUserId(currentUser.getId());
/*if (!currentUser.getId().equals(address.getMobileUserId())){
throw new ServiceException(403,"无权访问");
}*/
List<MobileUserAddress> userAddresses = mobileUserAddressMapper.selectList(null);
if (CollectionUtils.isEmpty(userAddresses)){
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 boolean deleteAddr(@RequestParam("addressId") Integer addressId,HttpServletRequest request){
MobileAppUser currentUser = MobileAppSecurityUtil.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) > 0;
}
@PostMapping("/applyRefund")
public boolean applyRefund(@RequestBody MobileOrder order, HttpServletRequest request){
MobileOrder mobileOrder = orderMapper.selectById(order.getOrderId());
if (Objects.isNull(mobileOrder)){
throw new ServiceException("查无此单");
}
MobileAppUser currentUser = MobileAppSecurityUtil.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());
mobileOrder.setStatus(OrderStatus.request_refund.name());
return orderMapper.updateById(mobileOrder) > 0;
}
@PostMapping("/refundReason")
public boolean refundReason(@RequestParam("orderId") String orderId,@RequestParam("reason") String reason,HttpServletRequest request){
MobileOrder mobileOrder = orderMapper.selectById(orderId);
if (Objects.isNull(mobileOrder)){
throw new ServiceException("无此订单");
}
MobileAppUser currentUser = MobileAppSecurityUtil.getCurrentUser(request);
if (currentUser == null || !currentUser.getId().equals(mobileOrder.getMobileUserId())){
throw new ServiceException("无权访问");
}
mobileOrder.setRefundReason(reason);
return orderMapper.updateById(mobileOrder) > 0;
}
@GetMapping("/getGrfScanPrice")
public ResultData getGrfScanPrice(HttpServletRequest request,@RequestParam(value = "id",required = false) Integer id){
MobileAppUser currentUser = MobileAppSecurityUtil.getCurrentUser(request);
List<MobileOrder> wxOrders = orderMapper.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("/getVipRechargePackage")
public List<RechargePackage> rechargePackages(){
return rechargePackageMapper.selectList(null);
}
@GetMapping("/getAccountBalance")
public MobileAppUserAccount account(HttpServletRequest request){
MobileAppUser currentUser = MobileAppSecurityUtil.getCurrentUser(request);
MobileAppUserAccount account = mobileAppUserAccountMapper.selectOne(new LambdaQueryWrapper<MobileAppUserAccount>().eq(MobileAppUserAccount::getMobileUserId, currentUser.getId()));
if (account == null){
return new MobileAppUserAccount();
}
return account;
}
@GetMapping("/getOpenid")
public ResultData<String> getOpenid(@RequestParam("code") String code){
log.info("小程序登录传参:{}",code);
Map<String,String> params = new HashMap<>();
params.put("appid",wxProperties.getAppid());
params.put("secret",wxProperties.getSecret());
params.put("js_code",code);
params.put("grant_type","authorization_code");
try {
String s = HttpUtil.doGet("https://api.weixin.qq.com/sns/jscode2session", null, params);
log.info("小程序登录返回:{}", s);
JSONObject loginResp = JSONObject.parseObject(s);
if (loginResp.containsKey("errcode")) {
throw new ServiceException("小程序登录失败");
}
String session_key = (String) loginResp.get("session_key");
String openid = (String) loginResp.get("openid");
log.info("sessionKey={};openid={}", session_key, openid);
ResultData<String> resultData = new ResultData<>();
resultData.setCode(200);
resultData.setData(openid);
return resultData;
}catch (Exception e){
throw new BusinessException("获取openid失败");
}
}
}
@@ -0,0 +1,37 @@
package cn.unizk.controller;
import cn.unizk.entity.po.SysDict;
import cn.unizk.entity.vo.ResultData;
import cn.unizk.mapper.SysDictMapper;
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/7/1 16:55
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp/member")
public class MobileMemberController {
@Resource
private SysDictMapper sysDictMapper;
@GetMapping("/getCost")
public ResultData getCost(){
SysDict activeMember = sysDictMapper.selectOne(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,257 @@
package cn.unizk.controller;
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.JkProductService;
import cn.unizk.utils.BeanCopyUtils;
import cn.unizk.utils.MobileAppSecurityUtil;
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.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 2026/7/8 14:43
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp/order")
public class MobileOrderController {
@Resource
private MobileOrderMapper mobileOrderMapper;
@Resource
private MobileOrderItemMapper mobileOrderItemMapper;
@Resource
private JkProductService productService;
@Resource
private ComboMapper comboMapper;
@Resource
private MobileStoreMapper mobileStoreMapper;
@Resource
private PhysioMapper physioMapper;
@Resource
private MobileAppUserMapper mobileAppUserMapper;
@Resource
private CourseMapper courseMapper;
@Resource
private OrderReviewMapper reviewMapper;
@GetMapping("/getOrderById")
public ResultData<MobileOrder> getOrderById(@RequestParam("orderId") String orderId){
return ResultData.success(mobileOrderMapper.selectById(orderId));
}
@GetMapping("/getSortSum")
public JSONObject getSum(HttpServletRequest request) {
MobileAppUser currentUser = MobileAppSecurityUtil.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("/deleteInvalidOrder")
public ResultData deleteInvalidOrder(@RequestParam("orderId") String orderId, HttpServletRequest request) {
MobileAppUser currentUser = MobileAppSecurityUtil.getCurrentUser(request);
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,refund_refusal".equals(orderStatus)) {
orderStatus = "";
afterSale = true;
}
MobileAppUser currentUser = MobileAppSecurityUtil.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()));
}*/
if (order.getProductId() != null){
JkProduct jkProduct = productService.getById(order.getProductId());
vo.setProductName(jkProduct.getProductName());
}
if (order.getComboId() != null){
Combo combo = comboMapper.selectById(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()));
Collection<MobileOrderItemVO> wxOrderItemVOS = BeanCopyUtils.copyArrays(wxOrderItems, MobileOrderItemVO::new);
if (CollectionUtils.isEmpty(wxOrderItemVOS)) {
vos.add(vo);
continue;
}
for (MobileOrderItemVO wxOrderItemVO : wxOrderItemVOS) {
System.out.println(wxOrderItemVO.getStoreId());
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 = comboMapper.selectById(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 = MobileAppSecurityUtil.getCurrentUser(request);
if (Objects.isNull(currentUser) || !currentUser.getId().equals(order.getMobileUserId())) {
throw new ServiceException(401, "无权限访问");
}
if (order.getStoreId() != null) {
JkStore jkStore = mobileStoreMapper.selectById(order.getStoreId());
vo.setJkStore(jkStore);
}
if (order.getPhysioId() != null) {
JkPhysio jkPhysio = physioMapper.selectById(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 = comboMapper.selectById(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 = comboMapper.selectById(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;
}
@PostMapping("/comment")
@Transactional(rollbackFor = Exception.class)
public ResultData comment(@Validated @RequestBody OrderReview review){
MobileOrder mobileOrder = mobileOrderMapper.selectById(review.getOrderId());
if (Objects.isNull(mobileOrder)){
throw new ServiceException("无此订单");
}
MobileAppUser mobileAppUser = mobileAppUserMapper.selectOne(new LambdaQueryWrapper<MobileAppUser>().eq(MobileAppUser::getId, mobileOrder.getMobileUserId()));
if (Objects.isNull(mobileAppUser)){
throw new ServiceException("数据出现异常");
}
// mobileAppUser.setPoints(wxUser.getPoints() + 1);
// mobileAppUserMapper.updateById(mobileAppUser);
reviewMapper.insert(review);
mobileOrder.setStatus(OrderStatus.commented.name());
mobileOrderMapper.updateById(mobileOrder);
return ResultData.success();
}
}
@@ -0,0 +1,214 @@
package cn.unizk.controller;
import cn.unizk.entity.po.*;
import cn.unizk.entity.vo.*;
import cn.unizk.exception.ServiceException;
import cn.unizk.mapper.*;
import cn.unizk.pojo.vo.ReportTypeVO2;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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 2026/7/1 18:39
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp/physio")
public class MobilePhysioController {
@Resource
private PhysioMapper physioMapper;
@Resource
private ReportTemplateMapper reportTemplateMapper;
@Resource
private SubHealthDietaryRegulationMapper regulationMapper;
@Resource
private PhysioExamMapper examMapper;
@Resource
private ExamScoreMapper scoreMapper;
@GetMapping("/getPhysios")
public IPage<JkPhysio> getPhysios(@RequestParam("storeId") Integer storeId, UniPage uniPage) {
Page<JkPhysio> page = new Page<>();
page.setCurrent(uniPage.getCurrentPage());
return physioMapper.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 ReportTypeVO2 vo) {
String text = "<p>尊敬的客户您好!非常理解您正承受着膝关节疼痛带来的不适与困扰," +
"考虑到您目前关节疼痛症状较为严重,为了能精准对症缓解您的病痛," +
"我们现将您的相关情况转接至上一级专业接待机构。那边配备经验更丰富的护理人员与配" +
"套诊疗资源,会为您提供更全面、专业且细致优质的诊疗服务,请您稍作等候配合转接。</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;
}
}
@@ -0,0 +1,79 @@
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.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.Objects;
/**
* @Author hao
* @Date 2026/6/30 16:00
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp/product")
public class MobileProductController {
@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,74 @@
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.mapper.MobileStoreMapper;
import cn.unizk.mapper.SysDictMapper;
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;
/**
* @Author hao
* @Date 2026/7/1 11:03
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp/store")
@Slf4j
public class MobileStoreController {
@Resource
private MobileStoreMapper mobileStoreMapper;
@Resource
private SysDictMapper sysDictMapper;
@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 mobileStoreMapper.selectPage(page, wrapper);
}
@GetMapping("/getStoreById")
public JkStore getStoreById(@RequestParam("storeId") Integer storeId){
return mobileStoreMapper.selectById(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 = sysDictMapper.selectById(26);
ResultData<String> data = new ResultData<>();
data.setCode(200);
data.setData(sysDict.getDictValue());
return data;
}
}
@@ -0,0 +1,32 @@
package cn.unizk.controller;
import cn.unizk.entity.vo.ProvinceTreeVO;
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.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @Author hao
* @Date 2026/7/9 18:27
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp/address")
public class MobileUserAddrController {
@Autowired
@Qualifier("kryoRedisTemplate")
private RedisTemplate redisTemplate;
@GetMapping("/getCity")
public List<ProvinceTreeVO> getCity(){
List<ProvinceTreeVO> cityData = (List<ProvinceTreeVO>) redisTemplate.opsForValue().get("cityData");
return cityData;
}
}
@@ -0,0 +1,436 @@
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.MobileAppSecurityUtil;
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 14:45
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp/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 = MobileAppSecurityUtil.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 = MobileAppSecurityUtil.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 = MobileAppSecurityUtil.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(@RequestBody EightMajorJointsVO vo){
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());
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,49 @@
package cn.unizk.controller;
import cn.unizk.entity.po.RunConsultation;
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.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
/**
* @Author hao
* @Date 2026/7/15 15:49
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp/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);
String plan = runConsultations.stream().map(RunConsultation::getPlan).distinct().collect(Collectors.joining("\n"));
consultation.setPlan(plan);
return consultation;
}
}
@@ -0,0 +1,40 @@
package cn.unizk.controller;
import cn.unizk.entity.po.SysDict;
import cn.unizk.mapper.SysDictMapper;
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 2026/7/1 16:51
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp/dict")
public class SysDictController {
@Resource
private SysDictMapper sysDictMapper;
@GetMapping("/getDictByType")
public List<SysDict> getDictByType(@RequestParam("type") String type){
return sysDictMapper.selectList(new LambdaQueryWrapper<SysDict>()
.eq(SysDict::getDictType,type)
.eq(SysDict::getStatus,"display"));
}
@GetMapping("/getDictType")
public List<String> getDictType(){
return sysDictMapper.selectList(null).stream().map(SysDict::getDictType)
.distinct()
.collect(Collectors.toList());
}
}
@@ -0,0 +1,31 @@
package cn.unizk.controller;
import cn.unizk.entity.vo.ProvinceTreeVO;
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.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @Author hao
* @Date 2026/7/9 18:22
* @Version 1.0
**/
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
@Qualifier("kryoRedisTemplate")
private RedisTemplate redisTemplate;
@GetMapping("/")
public List<ProvinceTreeVO> getCity(){
List<ProvinceTreeVO> cityData = (List<ProvinceTreeVO>) redisTemplate.opsForValue().get("cityData");
return cityData;
}
}
@@ -0,0 +1,265 @@
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.DoubaoService;
import cn.unizk.utils.MobileAppSecurityUtil;
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.Map;
import java.util.Objects;
/**
* @Author hao
* @Date 2026/8/19 17:30
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp/consultation")
@Slf4j
public class UserConsultationRecordController {
@Resource
private UserConsultationRecordMapper consultationRecordMapper;
@Resource
private DoubaoService doubaoService;
@Resource
private TreatParameterMapper treatParameterMapper;
@Resource
private MobileAppUserMapper mobileAppUserMapper;
@Resource
private PhysioMapper physioMapper;
@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 = MobileAppSecurityUtil.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 = MobileAppSecurityUtil.getCurrentUser(request);
if (Objects.isNull(currentUser)){
throw new ServiceException(401,"登录已过期");
}
JkPhysio jkPhysio = physioMapper.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);
int month = DateUtil.month(new Date()) + 1;
int day = DateUtil.thisDayOfMonth();
String yyyy = DateUtil.format(new Date(), "yyyy");
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 = MobileAppSecurityUtil.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,500 @@
package cn.unizk.controller;
import cn.unizk.cache.LocalCache;
import cn.unizk.entity.po.*;
import cn.unizk.entity.vo.*;
import cn.unizk.exception.ServiceException;
import cn.unizk.mapper.DiagnosisTemplateMapper;
import cn.unizk.mapper.StoreAccountMapper;
import cn.unizk.mapper.SysDictMapper;
import cn.unizk.mapper.TreatParameterMapper;
import cn.unizk.service.QuestionService;
import cn.unizk.service.WebTtsWsService;
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 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.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 java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
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;
/**
* @Author hao
* @Date 2026/6/30 14:13
* @Version 1.0
**/
@RestController
@RequestMapping("/mobileApp/xf")
@Slf4j
public class XunFeiAiController {
@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 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 SysDictMapper sysDictMapper;
/* @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 = sysDictMapper.selectOne(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;
}
}
@@ -0,0 +1,66 @@
package cn.unizk.interceptor;
import cn.unizk.MobileAppConstant;
import cn.unizk.entity.po.MobileAppUser;
import cn.unizk.entity.vo.ResultData;
import cn.unizk.mapper.MobileAppUserMapper;
import cn.unizk.utils.MobileJwtUtil;
import cn.unizk.utils.ServletUtils;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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 org.springframework.web.servlet.ModelAndView;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;
/**
* @Author hao
* @Date 2026/6/30 11:24
* @Version 1.0
**/
@Component
public class MobileAppLoginInterceptor implements HandlerInterceptor {
@Autowired
@Qualifier("kryoRedisTemplate")
private RedisTemplate redisTemplate;
@Resource
private MobileAppUserMapper userMapper;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getHeader("mobile-t");
if (StringUtils.isBlank(token)){
toRes(response,401);
return false;
}
String phoneNumber = MobileJwtUtil.parsePlaintext(token);
MobileAppUser mobileAppUser = (MobileAppUser) redisTemplate.opsForValue().get(MobileAppConstant.CACHE_TOKEN_PREFIX + phoneNumber);
if (Objects.isNull(mobileAppUser)){
toRes(response,403);
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
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,7 @@
package cn.unizk.mapper;
import cn.unizk.entity.po.SysFile;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface FileMapper extends BaseMapper<SysFile> {
}
@@ -0,0 +1,7 @@
package cn.unizk.mapper;
import cn.unizk.entity.po.JkProduct;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface JkProductMapper extends BaseMapper<JkProduct> {
}
@@ -0,0 +1,7 @@
package cn.unizk.mapper;
import cn.unizk.entity.po.JkPhysio;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface MobilePhysioMapper extends BaseMapper<JkPhysio> {
}
@@ -0,0 +1,7 @@
package cn.unizk.mapper;
import cn.unizk.entity.po.JkStore;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface MobileStoreMapper extends BaseMapper<JkStore> {
}
@@ -0,0 +1,12 @@
package cn.unizk.mapper;
import cn.unizk.entity.po.JkPhysio;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Author hao
* @Date 2026/7/1 18:42
* @Version 1.0
**/
public interface PhysioMapper extends BaseMapper<JkPhysio> {
}
@@ -0,0 +1,7 @@
package cn.unizk.mapper;
import cn.unizk.entity.po.ProductCarousel;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface ProductCarouselMapper extends BaseMapper<ProductCarousel> {
}
@@ -0,0 +1,7 @@
package cn.unizk.mapper;
import cn.unizk.entity.po.Question;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface QuestionMapper extends BaseMapper<Question> {
}
@@ -0,0 +1,7 @@
package cn.unizk.mapper;
import cn.unizk.entity.po.SysDict;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface SysDictMapper extends BaseMapper<SysDict> {
}
@@ -0,0 +1,9 @@
package cn.unizk.pay;
import cn.unizk.pay.dto.BasePayResponse;
import cn.unizk.pay.dto.PayBaseRequest;
public interface PayStrategy<T extends PayBaseRequest> {
<R extends BasePayResponse> R pay(T param);
}
@@ -0,0 +1,32 @@
package cn.unizk.pay.enums;
public enum PayChannelEnum {
WECHAT("微信支付","T_MINIAPP"),
ALIPAY("支付宝支付","A_NATIVE");
private String description;
private String tradeType;
PayChannelEnum(){}
PayChannelEnum(String description,String tradeType){
this.description = description;
this.tradeType = tradeType;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getTradeType() {
return tradeType;
}
public void setTradeType(String tradeType) {
this.tradeType = tradeType;
}
}
@@ -0,0 +1,50 @@
package cn.unizk.pay.enums;
import cn.unizk.exception.BusinessException;
import cn.unizk.pay.handler.PaySceneHandler;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
@Getter
public enum PaySceneEnum {
HGJ_PAY("10000","好关节预约下单","hGJPayHandler"),
SHOPPING_CART_PAY("20000","购物车下单支付","shoppingCartPayHandler"),
RECHARGE_PAY("30000","充值支付","rechargePayHandler"),
SCAN_TO_POWER_ON_PAY("40000","扫码开机支付","scanToPowerOnHandler"),
GOLF_SERVICE_PAY("50000","高尔夫服务套餐支付","golfServicePayHandler"),
COURSE_PAY("60000","视频课程购买支付","coursePayHandler"),
ACTIVE_MEMBER_PAY("70000","开通会员","activeMemberPayHandler"),
PRODUCT_PAY("80000","商品购买","productPayHandler");
private String code;
private String description;
private String paySceneHandlerName;
PaySceneEnum(){}
PaySceneEnum(String code,String description){
this.code = code;
this.description = description;
}
PaySceneEnum(String code,String description,String paySceneHandlerName){
this.code = code;
this.description = description;
this.paySceneHandlerName = paySceneHandlerName;
}
public static String getHandlerNameByCode(String code){
if (StringUtils.isBlank(code)){
throw new BusinessException("code 不能为空");
}
for (PaySceneEnum sceneEnum : PaySceneEnum.values()) {
if (code.equals(sceneEnum.getCode())){
return sceneEnum.paySceneHandlerName;
}
}
throw new RuntimeException("无此类型的枚举");
}
}
@@ -0,0 +1,42 @@
package cn.unizk.pay.factory;
import cn.unizk.exception.BusinessException;
import cn.unizk.pay.enums.PaySceneEnum;
import cn.unizk.pay.handler.PaySceneHandler;
import cn.unizk.pay.handler.ScanToPowerOnHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @Author hao
* @Date 2026/7/2 17:23
* @Version 1.0
**/
@Component
@Slf4j
public class PaySceneFactory {
final private Map<String,PaySceneHandler> paySceneMap;
@Autowired
public PaySceneFactory(Map<String,PaySceneHandler> paySceneMap){
this.paySceneMap = paySceneMap;
}
public PaySceneHandler getPaySceneHandler(String sceneCode){
String handlerName = PaySceneEnum.getHandlerNameByCode(sceneCode);
List<String> codes = Arrays.stream(PaySceneEnum.values()).map(PaySceneEnum::getCode).collect(Collectors.toList());
if (!codes.contains(sceneCode)){
throw new BusinessException("No PaySceneHandler of this type exists");
}
return paySceneMap.get(handlerName);
}
}
@@ -0,0 +1,115 @@
package cn.unizk.pay.handler;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.unizk.entity.dto.PlaceOrderCommonDTO;
import cn.unizk.entity.po.MobileOrder;
import cn.unizk.enums.OrderStatus;
import cn.unizk.enums.OrderTypeEnum;
import cn.unizk.exception.BusinessException;
import cn.unizk.mapper.MobileOrderMapper;
import cn.unizk.pay.dto.ActiveMemberPayParam;
import cn.unizk.pay.dto.BasePayResponse;
import cn.unizk.pay.dto.PayBaseRequest;
import cn.unizk.pay.enums.PayChannelEnum;
import cn.unizk.pay.enums.PaySceneEnum;
import cn.unizk.properties.HuiFuVendorProperties;
import cn.unizk.utils.HFSignUtil;
import cn.unizk.utils.HttpUtil;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
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/7/9 15:59
* @Version 1.0
**/
@Component
@Slf4j
public class ActiveMemberPayHandler extends PaySceneHandler<ActiveMemberPayParam> {
@Resource
private HuiFuVendorProperties vendorProperties;
@Resource
private MobileOrderMapper mobileOrderMapper;
@Override
public <R extends BasePayResponse> R scenePay(ActiveMemberPayParam param) {
if (param.getPayChannel().equals(PayChannelEnum.WECHAT.name()) && param.getStep() == 1){
BasePayResponse basePayResponse = new BasePayResponse();
MobileOrder mobileOrder = new MobileOrder();
String snowflakeNextIdStr = IdUtil.getSnowflakeNextIdStr();
mobileOrder.setOrderId(snowflakeNextIdStr);
mobileOrder.setMobileUserId(param.getMobileAppUserId());
mobileOrder.setDescription(PaySceneEnum.ACTIVE_MEMBER_PAY.getDescription());
BigDecimal price = new BigDecimal(param.getActualPayPrice());
price = price.setScale(2, RoundingMode.DOWN);
mobileOrder.setTotalPrice(price);
mobileOrder.setStatus(OrderStatus.unpaid.name());
mobileOrder.setCreateTime(LocalDateTime.now());
mobileOrderMapper.insert(mobileOrder);
basePayResponse.setOrderId(snowflakeNextIdStr);
return (R) basePayResponse;
}
log.info("param={}",param);
String now = DateUtil.format(new Date(), "yyyyMMdd");
BigDecimal price = new BigDecimal(param.getActualPayPrice());
price = price.setScale(2, RoundingMode.DOWN);
PlaceOrderCommonDTO dto = new PlaceOrderCommonDTO();
dto.setPrice(price.toString());
dto.setReqDate(now);
String reqSeqId = HFSignUtil.getReqSeqId();
dto.setReqSeqId(reqSeqId);
dto.setDescribe(PaySceneEnum.ACTIVE_MEMBER_PAY.getDescription());
JSONObject commonParams = super.createCommonParams(param,dto);
String res = HttpUtil.doPostJson(vendorProperties.getPayApi(), null, commonParams);
log.info("汇付下单返回:{}", res);
JSONObject response = JSONObject.parseObject(res);
if (response == null) {
throw new BusinessException("下单失败");
}
JSONObject responseData = response.getJSONObject("data");
String resp_code = responseData.getString("resp_code");
if ("00000000".equals(resp_code) || "00000100".equals(resp_code)){
if (param.getPayChannel().equals(PayChannelEnum.ALIPAY.name())){
MobileOrder mobileOrder = new MobileOrder();
String snowflakeNextIdStr = IdUtil.getSnowflakeNextIdStr();
mobileOrder.setOrderId(snowflakeNextIdStr);
mobileOrder.setOutTradeNo(reqSeqId);
mobileOrder.setStatus(OrderStatus.unpaid.name());
mobileOrder.setOrderType(OrderTypeEnum.ACTIVE_MEMBER.getCode());
mobileOrder.setDescription(PaySceneEnum.ACTIVE_MEMBER_PAY.getDescription());
mobileOrder.setTotalPrice(price);
mobileOrder.setDeliveryWay("自提");
mobileOrder.setCreateTime(LocalDateTime.now());
mobileOrder.setMobileUserId(param.getMobileAppUserId());
mobileOrderMapper.insert(mobileOrder);
responseData.put("orderId",snowflakeNextIdStr);
}else if (param.getPayChannel().equals(PayChannelEnum.WECHAT.name()) && param.getStep() == 2){
MobileOrder mobileOrder = mobileOrderMapper.selectById(param.getOrderId());
if (Objects.isNull(mobileOrder)){
throw new BusinessException(String.format("orderId:%s不存在",param.getOrderId()));
}
mobileOrder.setOutTradeNo(reqSeqId);
mobileOrder.setMobileUserId(param.getMobileAppUserId());
mobileOrder.setOrderType(OrderTypeEnum.ACTIVE_MEMBER.getCode());
mobileOrderMapper.updateById(mobileOrder);
}
return super.createResponse(param.getPayChannel(),responseData);
}
throw new BusinessException("下单失败");
}
@Override
public PaySceneEnum getSceneEnum() {
return null;
}
}
@@ -0,0 +1,129 @@
package cn.unizk.pay.handler;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.unizk.entity.dto.PlaceOrderCommonDTO;
import cn.unizk.entity.po.MobileOrder;
import cn.unizk.entity.po.MobileOrderItem;
import cn.unizk.enums.OrderStatus;
import cn.unizk.enums.OrderTypeEnum;
import cn.unizk.exception.BusinessException;
import cn.unizk.mapper.MobileOrderItemMapper;
import cn.unizk.mapper.MobileOrderMapper;
import cn.unizk.pay.dto.BasePayResponse;
import cn.unizk.pay.dto.CoursePayParam;
import cn.unizk.pay.dto.PayBaseRequest;
import cn.unizk.pay.enums.PayChannelEnum;
import cn.unizk.pay.enums.PaySceneEnum;
import cn.unizk.properties.HuiFuVendorProperties;
import cn.unizk.utils.HFSignUtil;
import cn.unizk.utils.HttpUtil;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
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/7/7 17:01
* @Version 1.0
**/
@Component
@Slf4j
public class CoursePayHandler extends PaySceneHandler<CoursePayParam> {
@Resource
private HuiFuVendorProperties vendorProperties;
@Resource
private MobileOrderMapper mobileOrderMapper;
@Resource
private MobileOrderItemMapper mobileOrderItemMapper;
@Override
public <R extends BasePayResponse> R scenePay(CoursePayParam param) {
if (param.getPayChannel().equals(PayChannelEnum.WECHAT.name()) && param.getStep() == 1){
BasePayResponse basePayResponse = new BasePayResponse();
MobileOrder mobileOrder = new MobileOrder();
String snowflakeNextIdStr = IdUtil.getSnowflakeNextIdStr();
mobileOrder.setOrderId(snowflakeNextIdStr);
mobileOrder.setMobileUserId(param.getMobileAppUserId());
mobileOrder.setCourseId(param.getCourseId());
mobileOrder.setDescription(PaySceneEnum.COURSE_PAY.getDescription());
BigDecimal price = new BigDecimal(param.getActualPayPrice());
price = price.setScale(2, RoundingMode.DOWN);
mobileOrder.setTotalPrice(price);
mobileOrder.setStatus(OrderStatus.unpaid.name());
mobileOrder.setCreateTime(LocalDateTime.now());
mobileOrderMapper.insert(mobileOrder);
basePayResponse.setOrderId(snowflakeNextIdStr);
return (R) basePayResponse;
}
log.info("param={}",param);
String now = DateUtil.format(new Date(), "yyyyMMdd");
BigDecimal price = new BigDecimal(param.getActualPayPrice());
price = price.setScale(2, RoundingMode.DOWN);
PlaceOrderCommonDTO dto = new PlaceOrderCommonDTO();
dto.setPrice(price.toString());
dto.setReqDate(now);
String reqSeqId = HFSignUtil.getReqSeqId();
dto.setReqSeqId(reqSeqId);
dto.setDescribe(PaySceneEnum.COURSE_PAY.getDescription());
JSONObject commonParams = super.createCommonParams(param,dto);
String res = HttpUtil.doPostJson(vendorProperties.getPayApi(), null, commonParams);
log.info("汇付下单返回:{}", res);
JSONObject response = JSONObject.parseObject(res);
if (response == null) {
throw new BusinessException("下单失败");
}
JSONObject responseData = response.getJSONObject("data");
String resp_code = responseData.getString("resp_code");
String pay_info = responseData.getString("pay_info");
log.info("下单返回支付信息pay_info={}",pay_info);
if ("00000000".equals(resp_code) || "00000100".equals(resp_code)){
if (param.getPayChannel().equals(PayChannelEnum.ALIPAY.name())){
MobileOrder mobileOrder = new MobileOrder();
String snowflakeNextIdStr = IdUtil.getSnowflakeNextIdStr();
mobileOrder.setOrderId(snowflakeNextIdStr);
mobileOrder.setOutTradeNo(reqSeqId);
mobileOrder.setStatus(OrderStatus.unpaid.name());
mobileOrder.setOrderType(OrderTypeEnum.COURSE_PAY.getCode());
mobileOrder.setDescription(param.getGoodDesc());
mobileOrder.setCourseId(param.getCourseId());
mobileOrder.setTotalPrice(price);
mobileOrder.setDeliveryWay("自提");
mobileOrder.setCreateTime(LocalDateTime.now());
mobileOrder.setMobileUserId(param.getMobileAppUserId());
mobileOrderMapper.insert(mobileOrder);
/*MobileOrderItem mobileOrderItem = new MobileOrderItem();
mobileOrderItem.setMobileOrderId(mobileOrder.getOrderId());
mobileOrderItem.setQuantity(1);
mobileOrderItem.setPrice(price);
mobileOrderItem.setCourseId(param.getCourseId());
mobileOrderItemMapper.insert(mobileOrderItem);*/
responseData.put("orderId",snowflakeNextIdStr);
}else if (param.getPayChannel().equals(PayChannelEnum.WECHAT.name()) && param.getStep() == 2){
MobileOrder mobileOrder = mobileOrderMapper.selectById(param.getOrderId());
if (Objects.isNull(mobileOrder)){
throw new BusinessException(String.format("orderId:%s不存在",param.getOrderId()));
}
mobileOrder.setOutTradeNo(reqSeqId);
mobileOrder.setOrderType(OrderTypeEnum.COURSE_PAY.getCode());
mobileOrder.setMobileUserId(param.getMobileAppUserId());
mobileOrderMapper.updateById(mobileOrder);
}
return super.createResponse(param.getPayChannel(),responseData);
}
throw new BusinessException("下单失败");
}
@Override
public PaySceneEnum getSceneEnum() {
return null;
}
}
@@ -0,0 +1,113 @@
package cn.unizk.pay.handler;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.unizk.entity.dto.PlaceOrderCommonDTO;
import cn.unizk.entity.po.MobileOrder;
import cn.unizk.enums.OrderStatus;
import cn.unizk.enums.OrderTypeEnum;
import cn.unizk.exception.BusinessException;
import cn.unizk.mapper.MobileOrderMapper;
import cn.unizk.pay.dto.BasePayResponse;
import cn.unizk.pay.dto.GolfServicePayParam;
import cn.unizk.pay.enums.PayChannelEnum;
import cn.unizk.pay.enums.PaySceneEnum;
import cn.unizk.properties.HuiFuVendorProperties;
import cn.unizk.utils.HFSignUtil;
import cn.unizk.utils.HttpUtil;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
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/7/9 11:31
* @Version 1.0
**/
@Component
@Slf4j
public class GolfServicePayHandler extends PaySceneHandler<GolfServicePayParam> {
@Resource
private HuiFuVendorProperties vendorProperties;
@Resource
private MobileOrderMapper mobileOrderMapper;
@Override
public <R extends BasePayResponse> R scenePay(GolfServicePayParam param) {
if (param.getPayChannel().equals(PayChannelEnum.WECHAT.name()) && param.getStep() == 1){
BasePayResponse basePayResponse = new BasePayResponse();
MobileOrder mobileOrder = new MobileOrder();
String snowflakeNextIdStr = IdUtil.getSnowflakeNextIdStr();
mobileOrder.setOrderId(snowflakeNextIdStr);
mobileOrder.setMobileUserId(param.getMobileAppUserId());
mobileOrder.setDescription(param.getProjectName());
BigDecimal price = new BigDecimal(param.getActualPayPrice());
price = price.setScale(2, RoundingMode.DOWN);
mobileOrder.setTotalPrice(price);
mobileOrder.setStatus(OrderStatus.unpaid.name());
mobileOrder.setCreateTime(LocalDateTime.now());
mobileOrderMapper.insert(mobileOrder);
basePayResponse.setOrderId(snowflakeNextIdStr);
return (R) basePayResponse;
}
String now = DateUtil.format(new Date(), "yyyyMMdd");
BigDecimal price = new BigDecimal(param.getActualPayPrice());
price = price.setScale(2, RoundingMode.DOWN);
PlaceOrderCommonDTO dto = new PlaceOrderCommonDTO();
dto.setPrice(price.toString());
dto.setReqDate(now);
String reqSeqId = HFSignUtil.getReqSeqId();
dto.setReqSeqId(reqSeqId);
dto.setDescribe(PaySceneEnum.GOLF_SERVICE_PAY.getDescription());
JSONObject commonParams = super.createCommonParams(param,dto);
String res = HttpUtil.doPostJson(vendorProperties.getPayApi(), null, commonParams);
log.info("汇付下单返回:{}", res);
JSONObject response = JSONObject.parseObject(res);
if (response == null) {
throw new BusinessException("下单失败");
}
JSONObject responseData = response.getJSONObject("data");
String resp_code = responseData.getString("resp_code");
if ("00000000".equals(resp_code) || "00000100".equals(resp_code)){
if (param.getPayChannel().equals(PayChannelEnum.ALIPAY.name())){
MobileOrder mobileOrder = new MobileOrder();
String snowflakeNextIdStr = IdUtil.getSnowflakeNextIdStr();
mobileOrder.setOrderId(snowflakeNextIdStr);
mobileOrder.setOutTradeNo(reqSeqId);
mobileOrder.setStatus(OrderStatus.unpaid.name());
mobileOrder.setOrderType(OrderTypeEnum.GOLF_SERVICE_PAY.getCode());
mobileOrder.setDescription(param.getProjectName());
mobileOrder.setTotalPrice(price);
mobileOrder.setDeliveryWay("自提");
mobileOrder.setCreateTime(LocalDateTime.now());
mobileOrder.setMobileUserId(param.getMobileAppUserId());
mobileOrderMapper.insert(mobileOrder);
responseData.put("orderId",snowflakeNextIdStr);
}else if (param.getPayChannel().equals(PayChannelEnum.WECHAT.name()) && param.getStep() == 2){
MobileOrder mobileOrder = mobileOrderMapper.selectById(param.getOrderId());
if (Objects.isNull(mobileOrder)){
throw new BusinessException(String.format("orderId:%s不存在",param.getOrderId()));
}
mobileOrder.setOutTradeNo(reqSeqId);
mobileOrder.setMobileUserId(param.getMobileAppUserId());
mobileOrder.setOrderType(OrderTypeEnum.GOLF_SERVICE_PAY.getCode());
mobileOrderMapper.updateById(mobileOrder);
}
return super.createResponse(param.getPayChannel(),responseData);
}
throw new BusinessException("下单失败");
}
@Override
public PaySceneEnum getSceneEnum() {
return null;
}
}
@@ -0,0 +1,122 @@
package cn.unizk.pay.handler;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.unizk.entity.dto.PlaceOrderCommonDTO;
import cn.unizk.entity.po.MobileOrder;
import cn.unizk.enums.OrderStatus;
import cn.unizk.enums.OrderTypeEnum;
import cn.unizk.exception.BusinessException;
import cn.unizk.mapper.MobileOrderMapper;
import cn.unizk.pay.dto.BasePayResponse;
import cn.unizk.pay.dto.HGJPayParam;
import cn.unizk.pay.enums.PayChannelEnum;
import cn.unizk.pay.enums.PaySceneEnum;
import cn.unizk.properties.HuiFuVendorProperties;
import cn.unizk.utils.HFSignUtil;
import cn.unizk.utils.HttpUtil;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
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/7/9 10:34
* @Version 1.0
**/
@Component
@Slf4j
public class HGJPayHandler extends PaySceneHandler<HGJPayParam> {
@Resource
private HuiFuVendorProperties vendorProperties;
@Resource
private MobileOrderMapper mobileOrderMapper;
@Override
public <R extends BasePayResponse> R scenePay(HGJPayParam param) {
if (param.getPayChannel().equals(PayChannelEnum.WECHAT.name()) && param.getStep() == 1){
BasePayResponse basePayResponse = new BasePayResponse();
MobileOrder mobileOrder = new MobileOrder();
String snowflakeNextIdStr = IdUtil.getSnowflakeNextIdStr();
mobileOrder.setOrderId(snowflakeNextIdStr);
mobileOrder.setMobileUserId(param.getMobileAppUserId());
mobileOrder.setDeviceId(param.getDeviceId());
mobileOrder.setComboId(param.getComboId());
mobileOrder.setPhysioId(param.getPhysioId());
mobileOrder.setStoreId(param.getStoreId());
mobileOrder.setDescription(PaySceneEnum.HGJ_PAY.getDescription());
BigDecimal price = new BigDecimal(param.getActualPayPrice());
price = price.setScale(2, RoundingMode.DOWN);
mobileOrder.setTotalPrice(price);
mobileOrder.setStatus(OrderStatus.unpaid.name());
mobileOrder.setCreateTime(LocalDateTime.now());
mobileOrderMapper.insert(mobileOrder);
basePayResponse.setOrderId(snowflakeNextIdStr);
return (R) basePayResponse;
}
log.info("param={}",param);
String now = DateUtil.format(new Date(), "yyyyMMdd");
BigDecimal price = new BigDecimal(param.getActualPayPrice());
price = price.setScale(2, RoundingMode.DOWN);
PlaceOrderCommonDTO dto = new PlaceOrderCommonDTO();
dto.setPrice(price.toString());
dto.setReqDate(now);
String reqSeqId = HFSignUtil.getReqSeqId();
dto.setReqSeqId(reqSeqId);
dto.setDescribe(PaySceneEnum.HGJ_PAY.getDescription());
JSONObject commonParams = super.createCommonParams(param,dto);
String res = HttpUtil.doPostJson(vendorProperties.getPayApi(), null, commonParams);
log.info("汇付下单返回:{}", res);
JSONObject response = JSONObject.parseObject(res);
if (response == null) {
throw new BusinessException("下单失败");
}
JSONObject responseData = response.getJSONObject("data");
String resp_code = responseData.getString("resp_code");
if ("00000000".equals(resp_code) || "00000100".equals(resp_code)){
if (param.getPayChannel().equals(PayChannelEnum.ALIPAY.name())){
MobileOrder mobileOrder = new MobileOrder();
String snowflakeNextIdStr = IdUtil.getSnowflakeNextIdStr();
mobileOrder.setOrderId(snowflakeNextIdStr);
mobileOrder.setOutTradeNo(reqSeqId);
mobileOrder.setStatus(OrderStatus.unpaid.name());
mobileOrder.setOrderType(OrderTypeEnum.HGJ_PAY.getCode());
mobileOrder.setDescription(PaySceneEnum.HGJ_PAY.getDescription());
mobileOrder.setTotalPrice(price);
mobileOrder.setDeviceId(param.getDeviceId());
mobileOrder.setStoreId(param.getStoreId());
mobileOrder.setPhysioId(param.getPhysioId());
mobileOrder.setComboId(param.getComboId());
mobileOrder.setDeliveryWay("自提");
mobileOrder.setCreateTime(LocalDateTime.now());
mobileOrder.setMobileUserId(param.getMobileAppUserId());
mobileOrderMapper.insert(mobileOrder);
responseData.put("orderId",snowflakeNextIdStr);
}else if (param.getPayChannel().equals(PayChannelEnum.WECHAT.name()) && param.getStep() == 2){
MobileOrder mobileOrder = mobileOrderMapper.selectById(param.getOrderId());
if (Objects.isNull(mobileOrder)){
throw new BusinessException(String.format("orderId:%s不存在",param.getOrderId()));
}
mobileOrder.setOutTradeNo(reqSeqId);
mobileOrder.setMobileUserId(param.getMobileAppUserId());
mobileOrder.setOrderType(OrderTypeEnum.HGJ_PAY.getCode());
mobileOrderMapper.updateById(mobileOrder);
}
return super.createResponse(param.getPayChannel(),responseData);
}
throw new BusinessException("下单失败");
}
@Override
public PaySceneEnum getSceneEnum() {
return null;
}
}
@@ -0,0 +1,91 @@
package cn.unizk.pay.handler;
import cn.hutool.core.date.DateUtil;
import cn.unizk.config.WxProperties;
import cn.unizk.entity.dto.PlaceOrderCommonDTO;
import cn.unizk.exception.BusinessException;
import cn.unizk.pay.dto.AlipayResp;
import cn.unizk.pay.dto.BasePayResponse;
import cn.unizk.pay.dto.PayBaseRequest;
import cn.unizk.pay.dto.WechatPayResp;
import cn.unizk.pay.enums.PayChannelEnum;
import cn.unizk.pay.enums.PaySceneEnum;
import cn.unizk.properties.HuiFuVendorProperties;
import cn.unizk.utils.HFSignUtil;
import cn.unizk.utils.HttpUtil;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
@Slf4j
public abstract class PaySceneHandler<T extends PayBaseRequest> {
@Resource
private HuiFuVendorProperties vendorProperties;
@Resource
private WxProperties wxProperties;
public abstract <R extends BasePayResponse> R scenePay(T param);
public abstract PaySceneEnum getSceneEnum();
protected JSONObject createCommonParams(T param, PlaceOrderCommonDTO dto){
JSONObject data = new JSONObject();
data.put("req_date", dto.getReqDate());
data.put("req_seq_id",dto.getReqSeqId());
data.put("huifu_id",vendorProperties.getHuifuId());
data.put("goods_desc",dto.getDescribe());
String tradeType = PayChannelEnum.valueOf(param.getPayChannel()).getTradeType();
data.put("trade_type",tradeType);
if (PayChannelEnum.WECHAT.name().equals(param.getPayChannel())){
log.info("使用微信支付----使用微信支付");
JSONObject wxData = new JSONObject();
wxData.put("sub_appid",wxProperties.getAppid());
wxData.put("sub_openid",param.getOpenid());
data.put("wx_data",wxData);
}
data.put("trans_amt",dto.getPrice());
data.put("notify_url",vendorProperties.getNotifyUrl());
String sign = HFSignUtil.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);
return commonParams;
}
protected <R extends BasePayResponse> R createResponse(String payChannel,JSONObject object){
if (payChannel.equals(PayChannelEnum.WECHAT.name())){
JSONObject pay_info = object.getJSONObject("pay_info");
String orderId = object.getString("orderId");
WechatPayResp wechatPayResp = new WechatPayResp();
wechatPayResp.setOrderId(orderId);
String timeStamp = pay_info.getString("timeStamp");
wechatPayResp.setTimestamp(timeStamp);
String paySign = pay_info.getString("paySign");
wechatPayResp.setPaySign(paySign);
String aPackage = pay_info.getString("package").split("=")[1];
wechatPayResp.setPrepayId(aPackage);
String nonceStr = pay_info.getString("nonceStr");
wechatPayResp.setNonceStr(nonceStr);
return (R) wechatPayResp;
}
if (payChannel.equals(PayChannelEnum.ALIPAY.name())){
AlipayResp alipayResp = new AlipayResp();
String qrCode = object.getString("qr_code");
String orderId = object.getString("orderId");
alipayResp.setQrCode(qrCode);
alipayResp.setOrderId(orderId);
return (R) alipayResp;
}
throw new BusinessException("不支持的支付渠道!");
}
}
@@ -0,0 +1,145 @@
package cn.unizk.pay.handler;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.unizk.entity.dto.PlaceOrderCommonDTO;
import cn.unizk.entity.po.MobileOrder;
import cn.unizk.entity.po.MobileOrderItem;
import cn.unizk.entity.po.MobileUserAddress;
import cn.unizk.enums.OrderStatus;
import cn.unizk.enums.OrderTypeEnum;
import cn.unizk.exception.BusinessException;
import cn.unizk.mapper.MobileOrderItemMapper;
import cn.unizk.mapper.MobileOrderMapper;
import cn.unizk.mapper.MobileUserAddressMapper;
import cn.unizk.pay.dto.BasePayResponse;
import cn.unizk.pay.dto.ProductPayParam;
import cn.unizk.pay.enums.PayChannelEnum;
import cn.unizk.pay.enums.PaySceneEnum;
import cn.unizk.properties.HuiFuVendorProperties;
import cn.unizk.utils.HFSignUtil;
import cn.unizk.utils.HttpUtil;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
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/7/10 10:24
* @Version 1.0
**/
@Component
@Slf4j
public class ProductPayHandler extends PaySceneHandler<ProductPayParam> {
@Resource
private HuiFuVendorProperties vendorProperties;
@Resource
private MobileOrderMapper mobileOrderMapper;
@Resource
private MobileUserAddressMapper mobileUserAddressMapper;
@Resource
private MobileOrderItemMapper mobileOrderItemMapper;
@Override
public <R extends BasePayResponse> R scenePay(ProductPayParam param) {
if (param.getPayChannel().equals(PayChannelEnum.WECHAT.name()) && param.getStep() == 1){
BasePayResponse basePayResponse = new BasePayResponse();
MobileOrder mobileOrder = new MobileOrder();
String snowflakeNextIdStr = IdUtil.getSnowflakeNextIdStr();
mobileOrder.setOrderId(snowflakeNextIdStr);
mobileOrder.setMobileUserId(param.getMobileAppUserId());
mobileOrder.setProductId(param.getProductId());
mobileOrder.setComboId(param.getComboId());
mobileOrder.setDescription(PaySceneEnum.PRODUCT_PAY.getDescription());
BigDecimal price = new BigDecimal(param.getActualPayPrice());
price = price.setScale(2, RoundingMode.DOWN);
mobileOrder.setTotalPrice(price);
mobileOrder.setStatus(OrderStatus.unpaid.name());
mobileOrder.setCreateTime(LocalDateTime.now());
mobileOrderMapper.insert(mobileOrder);
basePayResponse.setOrderId(snowflakeNextIdStr);
return (R) basePayResponse;
}
log.info("param={}",param);
String now = DateUtil.format(new Date(), "yyyyMMdd");
BigDecimal price = new BigDecimal(param.getActualPayPrice());
price = price.setScale(2, RoundingMode.DOWN);
PlaceOrderCommonDTO dto = new PlaceOrderCommonDTO();
dto.setPrice(price.toString());
dto.setReqDate(now);
String reqSeqId = HFSignUtil.getReqSeqId();
dto.setReqSeqId(reqSeqId);
dto.setDescribe(PaySceneEnum.PRODUCT_PAY.getDescription());
JSONObject commonParams = super.createCommonParams(param,dto);
String res = HttpUtil.doPostJson(vendorProperties.getPayApi(), null, commonParams);
log.info("汇付下单返回:{}", res);
JSONObject response = JSONObject.parseObject(res);
if (response == null) {
throw new BusinessException("下单失败");
}
JSONObject responseData = response.getJSONObject("data");
String resp_code = responseData.getString("resp_code");
if ("00000000".equals(resp_code) || "00000100".equals(resp_code)){
if (param.getPayChannel().equals(PayChannelEnum.ALIPAY.name())){
MobileOrder mobileOrder = new MobileOrder();
String snowflakeNextIdStr = IdUtil.getSnowflakeNextIdStr();
mobileOrder.setOrderId(snowflakeNextIdStr);
mobileOrder.setOutTradeNo(reqSeqId);
mobileOrder.setProductId(param.getProductId());
mobileOrder.setComboId(param.getComboId());
mobileOrder.setDeliveryWay(param.getDeliveryWay());
MobileUserAddress mobileUserAddress = mobileUserAddressMapper.selectById(param.getAddressId());
if ("配送".equals(param.getDeliveryWay())){
if (Objects.isNull(mobileUserAddress)){
String msg = String.format("收货地址不存在!addressId: %d",param.getAddressId());
throw new BusinessException(msg);
}
mobileOrder.setRecipientPhone(mobileUserAddress.getPhone());
mobileOrder.setRecipientName(mobileUserAddress.getReceiverName());
mobileOrder.setReceivingAddress(mobileUserAddress.getAddress());
}
mobileOrder.setStatus(OrderStatus.unpaid.name());
mobileOrder.setOrderType(OrderTypeEnum.PRODUCT_PAY.getCode());
mobileOrder.setDescription(PaySceneEnum.PRODUCT_PAY.getDescription());
mobileOrder.setTotalPrice(price);
mobileOrder.setDeliveryWay("自提");
mobileOrder.setCreateTime(LocalDateTime.now());
mobileOrder.setMobileUserId(param.getMobileAppUserId());
mobileOrderMapper.insert(mobileOrder);
MobileOrderItem orderItem = new MobileOrderItem();
orderItem.setMobileOrderId(mobileOrder.getOrderId());
orderItem.setProductId(param.getProductId());
orderItem.setComboId(param.getComboId());
orderItem.setPrice(price);
orderItem.setQuantity(param.getQuantity());
mobileOrderItemMapper.insert(orderItem);
responseData.put("orderId",snowflakeNextIdStr);
}else if (param.getPayChannel().equals(PayChannelEnum.WECHAT.name()) && param.getStep() == 2){
MobileOrder mobileOrder = mobileOrderMapper.selectById(param.getOrderId());
if (Objects.isNull(mobileOrder)){
throw new BusinessException(String.format("orderId:%s不存在",param.getOrderId()));
}
mobileOrder.setOutTradeNo(reqSeqId);
mobileOrder.setMobileUserId(param.getMobileAppUserId());
mobileOrder.setOrderType(OrderTypeEnum.PRODUCT_PAY.getCode());
mobileOrderMapper.updateById(mobileOrder);
}
return super.createResponse(param.getPayChannel(),responseData);
}
throw new BusinessException("下单失败");
}
@Override
public PaySceneEnum getSceneEnum() {
return null;
}
}
@@ -0,0 +1,115 @@
package cn.unizk.pay.handler;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.unizk.entity.dto.PlaceOrderCommonDTO;
import cn.unizk.entity.po.MobileOrder;
import cn.unizk.enums.OrderStatus;
import cn.unizk.enums.OrderTypeEnum;
import cn.unizk.exception.BusinessException;
import cn.unizk.mapper.MobileOrderMapper;
import cn.unizk.pay.dto.BasePayResponse;
import cn.unizk.pay.dto.PayBaseRequest;
import cn.unizk.pay.dto.RechargePayParam;
import cn.unizk.pay.enums.PayChannelEnum;
import cn.unizk.pay.enums.PaySceneEnum;
import cn.unizk.properties.HuiFuVendorProperties;
import cn.unizk.utils.HFSignUtil;
import cn.unizk.utils.HttpUtil;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
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/7/7 16:04
* @Version 1.0
**/
@Component
@Slf4j
public class RechargePayHandler extends PaySceneHandler<RechargePayParam> {
@Resource
private HuiFuVendorProperties vendorProperties;
@Resource
private MobileOrderMapper mobileOrderMapper;
@Override
public <R extends BasePayResponse> R scenePay(RechargePayParam param) {
if (param.getPayChannel().equals(PayChannelEnum.WECHAT.name()) && param.getStep() == 1){
BasePayResponse basePayResponse = new BasePayResponse();
MobileOrder mobileOrder = new MobileOrder();
String snowflakeNextIdStr = IdUtil.getSnowflakeNextIdStr();
mobileOrder.setOrderId(snowflakeNextIdStr);
mobileOrder.setMobileUserId(param.getMobileAppUserId());
mobileOrder.setDescription(PaySceneEnum.RECHARGE_PAY.getDescription());
BigDecimal price = new BigDecimal(param.getActualPayPrice());
price = price.setScale(2, RoundingMode.DOWN);
mobileOrder.setTotalPrice(price);
mobileOrder.setStatus(OrderStatus.unpaid.name());
mobileOrder.setCreateTime(LocalDateTime.now());
mobileOrderMapper.insert(mobileOrder);
basePayResponse.setOrderId(snowflakeNextIdStr);
return (R) basePayResponse;
}
String now = DateUtil.format(new Date(), "yyyyMMdd");
BigDecimal price = new BigDecimal(param.getActualPayPrice());
price = price.setScale(2, RoundingMode.DOWN);
PlaceOrderCommonDTO dto = new PlaceOrderCommonDTO();
dto.setPrice(price.toString());
dto.setReqDate(now);
String reqSeqId = HFSignUtil.getReqSeqId();
dto.setReqSeqId(reqSeqId);
dto.setDescribe(PaySceneEnum.RECHARGE_PAY.getDescription());
JSONObject commonParams = super.createCommonParams(param,dto);
String res = HttpUtil.doPostJson(vendorProperties.getPayApi(), null, commonParams);
log.info("汇付下单返回:{}", res);
JSONObject response = JSONObject.parseObject(res);
if (response == null) {
throw new BusinessException("下单失败");
}
JSONObject responseData = response.getJSONObject("data");
String resp_code = responseData.getString("resp_code");
if ("00000000".equals(resp_code) || "00000100".equals(resp_code)){
if (param.getPayChannel().equals(PayChannelEnum.ALIPAY.name())){
MobileOrder mobileOrder = new MobileOrder();
String snowflakeNextIdStr = IdUtil.getSnowflakeNextIdStr();
mobileOrder.setOrderId(snowflakeNextIdStr);
mobileOrder.setOutTradeNo(reqSeqId);
mobileOrder.setStatus(OrderStatus.unpaid.name());
mobileOrder.setOrderType(OrderTypeEnum.MEMBER_RECHARGE.getCode());
mobileOrder.setDescription(PaySceneEnum.RECHARGE_PAY.getDescription());
mobileOrder.setTotalPrice(price);
mobileOrder.setDeliveryWay("自提");
mobileOrder.setCreateTime(LocalDateTime.now());
mobileOrder.setMobileUserId(param.getMobileAppUserId());
mobileOrderMapper.insert(mobileOrder);
responseData.put("orderId",snowflakeNextIdStr);
}else if (param.getPayChannel().equals(PayChannelEnum.WECHAT.name()) && param.getStep() == 2){
MobileOrder mobileOrder = mobileOrderMapper.selectById(param.getOrderId());
if (Objects.isNull(mobileOrder)){
throw new BusinessException(String.format("orderId:%s不存在",param.getOrderId()));
}
mobileOrder.setOutTradeNo(reqSeqId);
mobileOrder.setMobileUserId(param.getMobileAppUserId());
mobileOrder.setOrderType(OrderTypeEnum.MEMBER_RECHARGE.getCode());
mobileOrderMapper.updateById(mobileOrder);
}
return super.createResponse(param.getPayChannel(),responseData);
}
throw new BusinessException("下单失败");
}
@Override
public PaySceneEnum getSceneEnum() {
return null;
}
}
@@ -0,0 +1,117 @@
package cn.unizk.pay.handler;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.unizk.entity.dto.PlaceOrderCommonDTO;
import cn.unizk.entity.po.MobileOrder;
import cn.unizk.enums.OrderStatus;
import cn.unizk.enums.OrderTypeEnum;
import cn.unizk.exception.BusinessException;
import cn.unizk.mapper.MobileOrderMapper;
import cn.unizk.pay.dto.BasePayResponse;
import cn.unizk.pay.dto.PayBaseRequest;
import cn.unizk.pay.dto.ScanToPowerOnPayParam;
import cn.unizk.pay.enums.PayChannelEnum;
import cn.unizk.pay.enums.PaySceneEnum;
import cn.unizk.properties.HuiFuVendorProperties;
import cn.unizk.utils.HFSignUtil;
import cn.unizk.utils.HttpUtil;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
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/7/2 17:12
* @Version 1.0
**/
@Component
@Slf4j
public class ScanToPowerOnHandler extends PaySceneHandler<ScanToPowerOnPayParam> {
@Resource
private HuiFuVendorProperties vendorProperties;
@Resource
private MobileOrderMapper mobileOrderMapper;
@Override
public <R extends BasePayResponse> R scenePay(ScanToPowerOnPayParam param) {
if (param.getPayChannel().equals(PayChannelEnum.WECHAT.name()) && param.getStep() == 1){
BasePayResponse basePayResponse = new BasePayResponse();
MobileOrder mobileOrder = new MobileOrder();
String snowflakeNextIdStr = IdUtil.getSnowflakeNextIdStr();
mobileOrder.setOrderId(snowflakeNextIdStr);
mobileOrder.setMobileUserId(param.getMobileAppUserId());
mobileOrder.setDeviceId(param.getDeviceId());
mobileOrder.setDescription(PaySceneEnum.SCAN_TO_POWER_ON_PAY.getDescription());
BigDecimal price = new BigDecimal(param.getActualPayPrice());
price = price.setScale(2, RoundingMode.DOWN);
mobileOrder.setTotalPrice(price);
mobileOrder.setStatus(OrderStatus.unpaid.name());
mobileOrder.setCreateTime(LocalDateTime.now());
mobileOrderMapper.insert(mobileOrder);
basePayResponse.setOrderId(snowflakeNextIdStr);
return (R) basePayResponse;
}
log.info("param={}",param);
String now = DateUtil.format(new Date(), "yyyyMMdd");
BigDecimal price = new BigDecimal(param.getActualPayPrice());
price = price.setScale(2, RoundingMode.DOWN);
PlaceOrderCommonDTO dto = new PlaceOrderCommonDTO();
dto.setPrice(price.toString());
dto.setReqDate(now);
String reqSeqId = HFSignUtil.getReqSeqId();
dto.setReqSeqId(reqSeqId);
dto.setDescribe(PaySceneEnum.SCAN_TO_POWER_ON_PAY.getDescription());
JSONObject commonParams = super.createCommonParams(param,dto);
String res = HttpUtil.doPostJson(vendorProperties.getPayApi(), null, commonParams);
log.info("汇付下单返回:{}", res);
JSONObject response = JSONObject.parseObject(res);
if (response == null) {
throw new BusinessException("下单失败");
}
JSONObject responseData = response.getJSONObject("data");
String resp_code = responseData.getString("resp_code");
if ("00000000".equals(resp_code) || "00000100".equals(resp_code)){
if (param.getPayChannel().equals(PayChannelEnum.ALIPAY.name())){
MobileOrder mobileOrder = new MobileOrder();
String snowflakeNextIdStr = IdUtil.getSnowflakeNextIdStr();
mobileOrder.setOrderId(snowflakeNextIdStr);
mobileOrder.setOutTradeNo(reqSeqId);
mobileOrder.setStatus(OrderStatus.unpaid.name());
mobileOrder.setOrderType(OrderTypeEnum.SCAN_PAY.getCode());
mobileOrder.setDescription(PaySceneEnum.SCAN_TO_POWER_ON_PAY.getDescription());
mobileOrder.setTotalPrice(price);
mobileOrder.setDeviceId(param.getDeviceId());
mobileOrder.setDeliveryWay("自提");
mobileOrder.setCreateTime(LocalDateTime.now());
mobileOrder.setMobileUserId(param.getMobileAppUserId());
mobileOrderMapper.insert(mobileOrder);
responseData.put("orderId",snowflakeNextIdStr);
}else if (param.getPayChannel().equals(PayChannelEnum.WECHAT.name()) && param.getStep() == 2){
MobileOrder mobileOrder = mobileOrderMapper.selectById(param.getOrderId());
if (Objects.isNull(mobileOrder)){
throw new BusinessException(String.format("orderId:%s不存在",param.getOrderId()));
}
mobileOrder.setOutTradeNo(reqSeqId);
mobileOrder.setMobileUserId(param.getMobileAppUserId());
mobileOrder.setOrderType(OrderTypeEnum.SCAN_PAY.getCode());
mobileOrderMapper.updateById(mobileOrder);
}
return super.createResponse(param.getPayChannel(),responseData);
}
throw new BusinessException("下单失败");
}
@Override
public PaySceneEnum getSceneEnum() {
return PaySceneEnum.SCAN_TO_POWER_ON_PAY;
}
}
@@ -0,0 +1,162 @@
package cn.unizk.pay.handler;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.unizk.entity.dto.PlaceOrderCommonDTO;
import cn.unizk.entity.po.MobileOrder;
import cn.unizk.entity.po.MobileOrderItem;
import cn.unizk.entity.po.MobileUserAddress;
import cn.unizk.enums.OrderStatus;
import cn.unizk.enums.OrderTypeEnum;
import cn.unizk.exception.BusinessException;
import cn.unizk.mapper.MobileOrderItemMapper;
import cn.unizk.mapper.MobileOrderMapper;
import cn.unizk.mapper.MobileUserAddressMapper;
import cn.unizk.pay.dto.BasePayResponse;
import cn.unizk.pay.dto.CartPayParam;
import cn.unizk.pay.enums.PayChannelEnum;
import cn.unizk.pay.enums.PaySceneEnum;
import cn.unizk.properties.HuiFuVendorProperties;
import cn.unizk.utils.HFSignUtil;
import cn.unizk.utils.HttpUtil;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
* @Author hao
* @Date 2026/7/10 10:57
* @Version 1.0
**/
@Component
@Slf4j
public class ShoppingCartPayHandler extends PaySceneHandler<CartPayParam> {
@Resource
private HuiFuVendorProperties vendorProperties;
@Resource
private MobileOrderMapper mobileOrderMapper;
@Resource
private MobileOrderItemMapper mobileOrderItemMapper;
@Resource
private MobileUserAddressMapper mobileUserAddressMapper;
@Override
public <R extends BasePayResponse> R scenePay(CartPayParam param) {
if (param.getPayChannel().equals(PayChannelEnum.WECHAT.name()) && param.getStep() == 1){
BasePayResponse basePayResponse = new BasePayResponse();
MobileOrder mobileOrder = new MobileOrder();
String snowflakeNextIdStr = IdUtil.getSnowflakeNextIdStr();
mobileOrder.setOrderId(snowflakeNextIdStr);
mobileOrder.setMobileUserId(param.getMobileAppUserId());
mobileOrder.setDeliveryWay(param.getDeliveryWay());
MobileUserAddress mobileUserAddress = mobileUserAddressMapper.selectById(param.getAddressId());
if ("配送".equals(param.getDeliveryWay())) {
if (Objects.isNull(mobileUserAddress)) {
String msg = String.format("收货地址不存在!addressId: %d", param.getAddressId());
throw new BusinessException(msg);
}
mobileOrder.setRecipientPhone(mobileUserAddress.getPhone());
mobileOrder.setRecipientName(mobileUserAddress.getReceiverName());
mobileOrder.setReceivingAddress(mobileUserAddress.getAddress());
}
mobileOrder.setStatus(OrderStatus.unpaid.name());
mobileOrder.setOrderType(OrderTypeEnum.SHOPPING_CART_PAY.getCode());
mobileOrder.setDescription(PaySceneEnum.SHOPPING_CART_PAY.getDescription());
mobileOrder.setDeliveryWay("自提");
mobileOrder.setCreateTime(LocalDateTime.now());
mobileOrder.setMobileUserId(param.getMobileAppUserId());
BigDecimal price = new BigDecimal(param.getActualPayPrice());
price = price.setScale(2, RoundingMode.DOWN);
mobileOrder.setTotalPrice(price);
mobileOrder.setStatus(OrderStatus.unpaid.name());
mobileOrder.setCreateTime(LocalDateTime.now());
mobileOrderMapper.insert(mobileOrder);
basePayResponse.setOrderId(snowflakeNextIdStr);
return (R) basePayResponse;
}
log.info("param={}", param);
String now = DateUtil.format(new Date(), "yyyyMMdd");
BigDecimal price = new BigDecimal(param.getActualPayPrice());
price = price.setScale(2, RoundingMode.DOWN);
PlaceOrderCommonDTO dto = new PlaceOrderCommonDTO();
dto.setPrice(price.toString());
dto.setReqDate(now);
String reqSeqId = HFSignUtil.getReqSeqId();
dto.setReqSeqId(reqSeqId);
dto.setDescribe(PaySceneEnum.SHOPPING_CART_PAY.getDescription());
JSONObject commonParams = super.createCommonParams(param, dto);
String res = HttpUtil.doPostJson(vendorProperties.getPayApi(), null, commonParams);
log.info("汇付下单返回:{}", res);
JSONObject response = JSONObject.parseObject(res);
if (response == null) {
throw new BusinessException("下单失败");
}
JSONObject responseData = response.getJSONObject("data");
String resp_code = responseData.getString("resp_code");
if ("00000000".equals(resp_code) || "00000100".equals(resp_code)) {
if (param.getPayChannel().equals(PayChannelEnum.ALIPAY.name())){
MobileOrder mobileOrder = new MobileOrder();
String snowflakeNextIdStr = IdUtil.getSnowflakeNextIdStr();
mobileOrder.setOrderId(snowflakeNextIdStr);
mobileOrder.setOutTradeNo(reqSeqId);
mobileOrder.setDeliveryWay(param.getDeliveryWay());
MobileUserAddress mobileUserAddress = mobileUserAddressMapper.selectById(param.getAddressId());
if ("配送".equals(param.getDeliveryWay())) {
if (Objects.isNull(mobileUserAddress)) {
String msg = String.format("收货地址不存在!addressId: %d", param.getAddressId());
throw new BusinessException(msg);
}
mobileOrder.setRecipientPhone(mobileUserAddress.getPhone());
mobileOrder.setRecipientName(mobileUserAddress.getReceiverName());
mobileOrder.setReceivingAddress(mobileUserAddress.getAddress());
}
mobileOrder.setStatus(OrderStatus.unpaid.name());
mobileOrder.setOrderType(OrderTypeEnum.SHOPPING_CART_PAY.getCode());
mobileOrder.setDescription(PaySceneEnum.SHOPPING_CART_PAY.getDescription());
mobileOrder.setTotalPrice(price);
mobileOrder.setDeliveryWay("自提");
mobileOrder.setCreateTime(LocalDateTime.now());
mobileOrder.setMobileUserId(param.getMobileAppUserId());
mobileOrderMapper.insert(mobileOrder);
List<MobileOrderItem> items = param.getItems();
if (CollectionUtils.isEmpty(items)){
throw new BusinessException("购物车商品为空");
}
for (MobileOrderItem orderItem : items) {
orderItem.setMobileOrderId(mobileOrder.getOrderId());
}
mobileOrderItemMapper.insert(items);
responseData.put("orderId", snowflakeNextIdStr);
}else if (param.getPayChannel().equals(PayChannelEnum.WECHAT.name()) && param.getStep() == 2){
MobileOrder mobileOrder = mobileOrderMapper.selectById(param.getOrderId());
if (Objects.isNull(mobileOrder)){
throw new BusinessException(String.format("orderId:%s不存在",param.getOrderId()));
}
mobileOrder.setOutTradeNo(reqSeqId);
mobileOrder.setOrderType(OrderTypeEnum.SHOPPING_CART_PAY.getCode());
mobileOrder.setMobileUserId(param.getMobileAppUserId());
mobileOrderMapper.updateById(mobileOrder);
}
return super.createResponse(param.getPayChannel(), responseData);
}
throw new BusinessException("下单失败");
}
@Override
public PaySceneEnum getSceneEnum() {
return null;
}
}
@@ -0,0 +1,9 @@
package cn.unizk.pay.service;
import cn.unizk.pay.dto.BasePayResponse;
import cn.unizk.pay.dto.PayBaseRequest;
public interface HFPayService<T extends PayBaseRequest> {
<R extends BasePayResponse> R pay(T param);
}
@@ -0,0 +1,30 @@
package cn.unizk.pay.service.impl;
import cn.unizk.pay.dto.BasePayResponse;
import cn.unizk.pay.dto.PayBaseRequest;
import cn.unizk.pay.factory.PaySceneFactory;
import cn.unizk.pay.handler.PaySceneHandler;
import cn.unizk.pay.service.HFPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @Author hao
* @Date 2026/7/3 10:35
* @Version 1.0
**/
@Service("ALIPAY")
@Slf4j
public class AliPayService<T extends PayBaseRequest> implements HFPayService<T> {
@Resource
private PaySceneFactory paySceneFactory;
@Override
public <R extends BasePayResponse> R pay(T param) {
PaySceneHandler paySceneHandler = paySceneFactory.getPaySceneHandler(param.getSceneCode());
return (R) paySceneHandler.scenePay(param);
}
}
@@ -0,0 +1,28 @@
package cn.unizk.pay.service.impl;
import cn.unizk.pay.dto.BasePayResponse;
import cn.unizk.pay.dto.PayBaseRequest;
import cn.unizk.pay.factory.PaySceneFactory;
import cn.unizk.pay.handler.PaySceneHandler;
import cn.unizk.pay.service.HFPayService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @Author hao
* @Date 2026/7/2 17:01
* @Version 1.0
**/
@Service("WECHAT")
public class WechatPayService<T extends PayBaseRequest> implements HFPayService<T> {
@Resource
private PaySceneFactory sceneFactory;
@Override
public <R extends BasePayResponse> R pay(T param) {
PaySceneHandler paySceneHandler = sceneFactory.getPaySceneHandler(param.getSceneCode());
return (R) paySceneHandler.scenePay(param);
}
}
@@ -0,0 +1,18 @@
package cn.unizk.pojo.vo;
import lombok.Data;
/**
* @Author hao
* @Date 2026/7/1 18:43
* @Version 1.0
**/
@Data
public class ReportTypeVO2 {
private String code1;
private String code2;
private Integer result;
}
@@ -0,0 +1,34 @@
package cn.unizk.properties;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @Author hao
* @Date 2026/6/30 11:01
* @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,31 @@
package cn.unizk.properties;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @Author hao
* @Date 2026/6/30 11:07
* @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;
private String payApi;
}
@@ -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,52 @@
package cn.unizk.service;
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/6/30 18:08
* @Version 1.0
**/
@Service
public class DoubaoService {
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,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.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,13 @@
package cn.unizk.service;
/**
* @Author hao
* @Date 2026/6/30 11:48
* @Version 1.0
**/
public class UniCloudClient {
public static String getPhoneNumber(String accessToken){
return "1234567890";
}
}
@@ -0,0 +1,45 @@
package cn.unizk.service;
import cn.unizk.MobileAppConstant;
import cn.unizk.entity.po.MobileAppUser;
import cn.unizk.mapper.MobileAppUserMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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 javax.annotation.Resource;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
* @Author hao
* @Date 2026/6/30 11:51
* @Version 1.0
**/
@Service
public class UserService {
@Resource
private MobileAppUserMapper userMapper;
@Autowired
@Qualifier("kryoRedisTemplate")
private RedisTemplate redisTemplate;
@Value("${token.expireTime}")
private Long expireTime;
public MobileAppUser userLogin(String phoneNumber){
MobileAppUser mobileAppUser = userMapper.selectOne(new LambdaQueryWrapper<MobileAppUser>().eq(MobileAppUser::getPhoneNumber, phoneNumber));
if (Objects.isNull(mobileAppUser)){
MobileAppUser appUser = new MobileAppUser();
appUser.setPhoneNumber(phoneNumber);
userMapper.insert(appUser);
redisTemplate.opsForValue().set(MobileAppConstant.CACHE_TOKEN_PREFIX+phoneNumber,appUser,expireTime, TimeUnit.DAYS);
return appUser;
}
redisTemplate.opsForValue().set(MobileAppConstant.CACHE_TOKEN_PREFIX+mobileAppUser.getPhoneNumber(),mobileAppUser,expireTime,TimeUnit.DAYS);
return mobileAppUser;
}
}
@@ -0,0 +1,209 @@
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.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
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 2026/6/30 14:27
* @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,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 2026/6/30 14:38
* @Version 1.0
**/
@Service
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements DeviceService {
}
@@ -0,0 +1,16 @@
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 org.springframework.stereotype.Service;
/**
* @Author hao
* @Date 2026/6/30 16:03
* @Version 1.0
**/
@Service
public class JkProductServiceImpl extends ServiceImpl<JkProductMapper, JkProduct> implements JkProductService {
}
@@ -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 2026/6/30 16:10
* @Version 1.0
**/
@Service
public class ProductCarouselServiceImpl extends ServiceImpl<ProductCarouselMapper, ProductCarousel> implements ProductCarouselService {
}
@@ -0,0 +1,16 @@
package cn.unizk.service.impl;
import cn.unizk.entity.po.Question;
import cn.unizk.mapper.QuestionMapper;
import cn.unizk.service.QuestionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* @Author hao
* @Date 2026/6/30 14:18
* @Version 1.0
**/
@Service
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper,Question> implements QuestionService {
}
@@ -0,0 +1,76 @@
package cn.unizk.utils;
import cn.hutool.core.date.DateUtil;
import cn.unizk.exception.ServiceException;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
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.Date;
import java.util.TreeMap;
/**
* @Author hao
* @Date 2026/7/2 10:45
* @Version 1.0
**/
@Slf4j
public class HFSignUtil {
/**
* 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("签名异常");
}
}
public static String getReqSeqId(){
return DateUtil.format(new Date(),"yyyyMMddHHmmss") + RandomStringUtils.randomNumeric(18);
}
}
@@ -0,0 +1,52 @@
package cn.unizk.utils;
import cn.unizk.MobileAppConstant;
import cn.unizk.entity.po.MobileAppUser;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
/**
* @Author hao
* @Date 2026/6/30 14:52
* @Version 1.0
**/
@Component
public class MobileAppSecurityUtil {
@Resource(name = "kryoRedisTemplate")
private RedisTemplate kryoRedisTemplate;
private static MobileAppSecurityUtil instance;
@PostConstruct
private void init() {
instance = this;
}
private MobileAppSecurityUtil() {}
/**
* 静态方法,推荐的调用方式
*/
public static MobileAppUser getCurrentUser(String token) {
if (instance == null) {
throw new IllegalStateException("JkSecurityUtil 未初始化");
}
String phoneNumber = MobileJwtUtil.parsePlaintext(token);
return (MobileAppUser) instance.kryoRedisTemplate.opsForValue().get(MobileAppConstant.CACHE_TOKEN_PREFIX + phoneNumber);
}
public static MobileAppUser getCurrentUser(HttpServletRequest request){
if (instance == null) {
throw new IllegalStateException("JkSecurityUtil 未初始化");
}
String token = request.getHeader(MobileAppConstant.REQUEST_TOKEN_HEADER);
String phoneNumber = MobileJwtUtil.parsePlaintext(token);
return (MobileAppUser) instance.kryoRedisTemplate.opsForValue().get(MobileAppConstant.CACHE_TOKEN_PREFIX + phoneNumber);
}
}
@@ -0,0 +1,67 @@
package cn.unizk.utils;
import cn.unizk.exception.ServiceException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;
/**
* @Author hao
* @Date 2026/6/30 11:30
* @Version 1.0
**/
@Slf4j
public class MobileJwtUtil {
private static final long TTL = 30 * 24 * 60 * 60 * 1000L;
// private static final SecretKey key = Keys.secretKeyFor(SignatureAlgorithm.HS512);
private static final String secretKey = "F8YlTp0TlknHG2arQBTxHhZox7tRpbJYYH0vLDOHuH6K276X9ntadC9ZLv5FNOq6X5E4bgPRv2AumgjDav2Vi2WVW8M845E8EAyvEJGFietkXTnbbfhCGa70kUVA2cnD";
private static final SecretKey key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8));
private MobileJwtUtil() {}
/**
* 生成 token
* @param plaintext 明文
* @return token 字符串
*/
public static String generateToken(String plaintext) {
//使用自定义的secretKey,但长度必须大于512bit(64字节),否则会报错
// SecretKey key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8));
Date now = new Date();
return Jwts.builder()
.setSubject(plaintext) // 手机号放在 sub 字段
.setIssuedAt(now) // 签发时间
.setExpiration(new Date(now.getTime() + TTL))
.signWith(key, SignatureAlgorithm.HS512)
.compact();
}
/**
* 从 token 解析出手机号
* @param token token
* @return 手机号;如果 token 无效(过期、篡改、格式错误)返回 null
*/
public static String parsePlaintext(String token) {
try {
Claims body = Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(token)
.getBody();
return body.getSubject();
} catch (JwtException e) {
log.info("token解析失败");
throw new ServiceException(401,"token无效");
}
}
}
@@ -0,0 +1,80 @@
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
druid:
url: jdbc:mysql://139.9.2.195:3306/uni_ai_doctor?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true
username: unizk
password: Unizk@2025
redis:
port: 6379
host: 139.9.2.195
username:
password: Unizk@2025.Jkzy
database: 0
lettuce:
pool:
max-active: 8
max-idle: 6
min-idle: 2
max-wait: -1ms
shutdown-timeout: 360
timeout: 5000
huifu:
huifuId: 6666000179463008
payApi: https://api.huifu.com/v3/trade/payment/jspay
refundApi: https://api.huifu.com/v3/trade/payment/scanpay/refund
publicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3IcOEDMBOiHaa5dLsPWVVx+9yE/VEGjRSVZFUAospbCEhGDimE7UEL8ecXwbG9AN5k8yX+Ltj6zaeLIt3KgxbX5/4pnrOoPqFhtaoNuQrwl8/9/rkgGkoksH9e//mRan2+TjbHLKXWZKUduksaoWw4VehOx0nxE+wx7Bk7/VQAegnrDz4z/8zEd2Mcm51THceHJ5wVoMoXvo5e8nhUUAFJeHtlI5jxC85lK6kz2UNhGQ7Kutc7sBzK1U/mi29j/iStN3Z0fzND7+nRfgWPu4b0cKNnNwlIaGiabFTbpVZyV8LTg1BandmHJLNUUJyrc/s3W72VFUdp+BwgoERDcEwwIDAQAB
privateKey: MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDchw4QMwE6Idprl0uw9ZVXH73IT9UQaNFJVkVQCiylsISEYOKYTtQQvx5xfBsb0A3mTzJf4u2PrNp4si3cqDFtfn/imes6g+oWG1qg25CvCXz/3+uSAaSiSwf17/+ZFqfb5ONscspdZkpR26SxqhbDhV6E7HSfET7DHsGTv9VAB6CesPPjP/zMR3YxybnVMdx4cnnBWgyhe+jl7yeFRQAUl4e2UjmPELzmUrqTPZQ2EZDsq61zuwHMrVT+aLb2P+JK03dnR/M0Pv6dF+BY+7hvRwo2c3CUhoaJpsVNulVnJXwtODUFqd2Ycks1RQnKtz+zdbvZUVR2n4HCCgRENwTDAgMBAAECggEAbFWAaB7WVHt69G3fxi/uzF0Qe04UijojzhYueLJ22nKLtwhtaIsZDJ0G1JM2MgSUP3badVZig7lTngVSGFsb5QFGy8f3Ucip/3AypmEWg5ZyrLSQ4ioieYPIhl3/P3Jsxc58lrMRjK6KhgoTrx+yjRyAoWYTqGztWydJy05q8UekdbIn9K2Dq0294hHbarCjB3C/3SXX4xniEbDtVBTdjP81731gxnM2HJ98GDrvUf5MDrX4SdExvCYV0P0mU8uaRPK8ylWCmtsEuMxKupFUFePJNZdyG+P/RZs6CbgUgJyYUzKlOyeWH8KwQF1FLntipkIPlJ+uVkdwK2eDD6bzWQKBgQDylFiSnlFy0fwXSpWHDnDgukaLYxm2GNWaPyg0f2IqK/368o/Xu4TWOPuknR6ngeiJZz3SVA/kFeCz3+UxtDlbUheoSkkbo0cZg8PaKx875gE97oCHgRkaPS4l44kmu1ZwOMgfZDQPrLZMEbAfjqvMEa7ci5kXk1quOGeSJRIg3QKBgQDoumM2dZ+RxYxtxB2k1kJJIndZX3hhVyMfDIh5TwHHKNml1poa/s+aoT27BZgiM8snLR55xk4cQ59kr9Yic9Oa4seECsrAgP8mbB6eC/y7lRDZDFjJvHXl6a1ePo+hBlYarL83AUMIE1/SfZrdyM5yRmp3+cwHkKVpAQuiEXOSHwKBgEDkpn0ylR9eRU4FydKDbnbv3gdTz4EDS8EjvCGvIheeBSeo1AomQ/b673auAZFWE1sOn18w1b9yitYTw0B0shNX9rQyizQ1jcOpmC848fYYJaTntMKLKqf2Te4c3Ifb/devmPms2LCIx4u5/5+xjwvcfybIwX+pD80jkbFq8VqRAoGBAKulTKdN+XK6EOikTHjWzezCzuPL1i105yJvS/isnNMW/e+iZ+ahKN0TL0RQy/Pt31f1nxSRfeq6tUS9q2Gdq+QAfsaUbxWsDoN4GtzWWoC/YL20rYecyBfaUVPBMI3C7p6d6inXdGjwYSwOF7qb8Ce4Z641PpYVyOm5K6tM08BhAoGBALNkfH3ZPImRKN19bGcHAtrzoDMFAAQrhjyMr9aUpMGLoAjxh1U2pYbj1y0e03ArUT/TRzOXNbHuST82tDZEarVSF8RmU8DNUAHSI9dmtXPtgeKpG8TNyP5q3VnJEHdSRZVLb5pGfZuo3tegsHwZF/oCGK+GHD/fhmSFB04GPJon
notifyUrl: https://peaktcm.com/applet/huifuPay/callback
productId: EDUSTD
configureAppletCallbackUrl: https://peaktcm.com/applet/huifuPay/configureAppletCallback
huifu-vendor:
sysId: 6666000188069628
huifuId: 6666000188735389
publicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0uJDRMFj1xoQCJbReVaNdiqjL9vdKolMzWKe2vMhZwkBlgQMpaqtHqNKNCn3DPL/7ugPUNzj4PLr3PSR4DK+TBOOa3xRuKLt3s2x6wouVNpiRRglUzh5OgciXXYPPl7QGu2YlJZ9F7ikiaD7KG9PJI7oidbA7lQ4qMcIGlSBUF4l3TeoOpad0zLs41IRJJPIMKPf5Jj9HS/1Tggcn7f36h1l4JWpTRyfB8HyF66IHzA3mQa5yskUHf1LLuO0hxtIfy9Ua+xJYqEWD334xaMzauZQsLM98d1Pj7I1YRvzNohabpCJqO1wF6PDB3rqdLarAZagN/JhYIHHGXMBGfQZxwIDAQAB
privateKey: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDS4kNEwWPXGhAIltF5Vo12KqMv290qiUzNYp7a8yFnCQGWBAylqq0eo0o0KfcM8v/u6A9Q3OPg8uvc9JHgMr5ME45rfFG4ou3ezbHrCi5U2mJFGCVTOHk6ByJddg8+XtAa7ZiUln0XuKSJoPsob08kjuiJ1sDuVDioxwgaVIFQXiXdN6g6lp3TMuzjUhEkk8gwo9/kmP0dL/VOCByft/fqHWXglalNHJ8HwfIXrogfMDeZBrnKyRQd/Usu47SHG0h/L1Rr7ElioRYPffjFozNq5lCwsz3x3U+PsjVhG/M2iFpukImo7XAXo8MHeup0tqsBlqA38mFggccZcwEZ9BnHAgMBAAECggEABRZaQxVbQDwruNlSklfJL9mVeDkYm8cWKDpB1MxauO6ZsDHG0FROutd7mciNYi2WiP/mJrA9exbBI+JuhncS6ijqnaMxIYAktuRFb4MeXQOrrTkI5XoOSp0Tcie/9GQ7JvsmXCdJO0JEDeHpTS9qPFqKN5ELtHQprcCnbGMvf23KyqOFx71Sbe4JxDqV4j0MeJJ/ZEOnLHJAhJ/o/0Gw+2cAVBxOq/xDTiSzKQaR4Cy7h3HMlDXnBXlAwKLb7x/F6efFyBv3RGZjtTgt8G7319icRJUHyXa3JPk/UbKTHrZ3saCj0ByAPpCwSVx6uNxhVeEOFqi3VwtV8s4ClAJtUQKBgQDwEGA1Shr2klTnM1VN+R3YkgaG8QtkZQQG77vCR1q3uMPKpWUQOi/2wQs3SbTAr7ZX+8CHNb8M3KGVAEFR2PDEFok/LA0snFTwdL6dLkXkmOxmNyR2wmXIUimMBogQIc4bI11EpPoocbrzuJ3q48fDIAr7Hc4d/0HasEAQHvAdfwKBgQDg4gCr5M7atD4XdKqmNs5kltjw36EeSig2cajfQb7aARmHS+1F9cn1cpgTvqMBHxBZBx5cW1ETLTxDEq8/ONHHAtmgCVgrc0lgch+Dph1Nt4Jl/aNxxaZjLpLQtcHnFR4/7RGuJMUTAzAUcOer9XiCJskE2EVLrT53pE665Se3uQKBgFcXmc+7cszBicvW87u2BP3s/DE4gcmKXEun7ZYuDNtaTK3YEzIv6fa7UjZcpxbAqIaC7vYeqZEg+f30eb4X1kFNa71fXegxTx9tOzoK75BfamQq3S+4lvR12lzSgcpYeU2fJtcggyDpIcoJ0EDHIlHH7jPsPDrlwB52ksdGchZBAoGBAM49dvAuf6cD9o38aSTWzqJh1cPS1Ci7SfXkd0OJQEcfCxKSB6FJsVZxKhexljzJCG0dojKBbPFxYvsAf8gzi/BAJOYoq7vtlzXkdBKAng9QZT60Rtlosxfy9qKCjronG/70pGpZPoQZQFb+1PlXvpVejKzsy2CEGe4PukSdNLfBAoGATUJ7FGVmG2Ym8UHcP0bMeWwS7XROuiquliLtamWwpZTByZaLO1nK2FtC1oVj3il4Wox6/In1bBbdtqxmRmKcD9q1JExr1PHxXQTUbIoWb4GXNHq7h5kOhpra1uVRmNIewfJUYTCEzzHTrJe8dADBc7lGpsibwk174YD2343Aupw=
productId: PAYUN
notifyUrl: https://peaktcm.com:8083/hf/webhook/callback
payApi: https://api.huifu.com/v3/trade/payment/jspay
aliyun:
accessKeyId: LTAI5tBQGeqmhe6yhfqupaZD
accessKeySecret: YM2lsEtpjCLOF2kJGdsCBcwRHLX8aa
minio:
endpoint: http://139.9.2.195:8002
accessKey: YIh5PhIEHXEiJgPTlCSc
secretKey: 07becv7RNMI1wHyPPFtq3rlCPC6cyF0WrV5LNHYN
username: jkzy
password: jkzy@2025
nginxHost:
huaweiyun:
accessKey: HPUACMRQ2NKQNOXNCFNO
secretKey: KC3yEw7ARoL0oxcmXy7vE3hyMBPKjLsG1LCSQdYh
xf:
appid: 3fa7b7a0
long-sound:
keySecret: b44d730380dcfae02313dcea7101efc8
instant:
host: https://iat-api.xfyun.cn/v2/iat
APISecret: N2Q5Y2NiOTZmNThhODZjYTgxMjg1NjA4
apiKey: da390c58ef0f2ad8424c3dccc6d458c7
token:
expireTime: 30
wx:
appid: wx71e559ade446f09a
secret: 00b7f3cff0f4bde07daacd0dea7548c9
@@ -0,0 +1,80 @@
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
druid:
url: jdbc:mysql://139.9.2.195:3306/uni_ai_doctor?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true
username: unizk
password: Unizk@2025
redis:
port: 6379
host: localhost
username:
password: Unizk@2025.Jkzy
database: 0
lettuce:
pool:
max-active: 8
max-idle: 6
min-idle: 2
max-wait: -1ms
shutdown-timeout: 360
timeout: 5000
huifu:
huifuId: 6666000179463008
payApi: https://api.huifu.com/v3/trade/payment/jspay
refundApi: https://api.huifu.com/v3/trade/payment/scanpay/refund
publicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3IcOEDMBOiHaa5dLsPWVVx+9yE/VEGjRSVZFUAospbCEhGDimE7UEL8ecXwbG9AN5k8yX+Ltj6zaeLIt3KgxbX5/4pnrOoPqFhtaoNuQrwl8/9/rkgGkoksH9e//mRan2+TjbHLKXWZKUduksaoWw4VehOx0nxE+wx7Bk7/VQAegnrDz4z/8zEd2Mcm51THceHJ5wVoMoXvo5e8nhUUAFJeHtlI5jxC85lK6kz2UNhGQ7Kutc7sBzK1U/mi29j/iStN3Z0fzND7+nRfgWPu4b0cKNnNwlIaGiabFTbpVZyV8LTg1BandmHJLNUUJyrc/s3W72VFUdp+BwgoERDcEwwIDAQAB
privateKey: MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDchw4QMwE6Idprl0uw9ZVXH73IT9UQaNFJVkVQCiylsISEYOKYTtQQvx5xfBsb0A3mTzJf4u2PrNp4si3cqDFtfn/imes6g+oWG1qg25CvCXz/3+uSAaSiSwf17/+ZFqfb5ONscspdZkpR26SxqhbDhV6E7HSfET7DHsGTv9VAB6CesPPjP/zMR3YxybnVMdx4cnnBWgyhe+jl7yeFRQAUl4e2UjmPELzmUrqTPZQ2EZDsq61zuwHMrVT+aLb2P+JK03dnR/M0Pv6dF+BY+7hvRwo2c3CUhoaJpsVNulVnJXwtODUFqd2Ycks1RQnKtz+zdbvZUVR2n4HCCgRENwTDAgMBAAECggEAbFWAaB7WVHt69G3fxi/uzF0Qe04UijojzhYueLJ22nKLtwhtaIsZDJ0G1JM2MgSUP3badVZig7lTngVSGFsb5QFGy8f3Ucip/3AypmEWg5ZyrLSQ4ioieYPIhl3/P3Jsxc58lrMRjK6KhgoTrx+yjRyAoWYTqGztWydJy05q8UekdbIn9K2Dq0294hHbarCjB3C/3SXX4xniEbDtVBTdjP81731gxnM2HJ98GDrvUf5MDrX4SdExvCYV0P0mU8uaRPK8ylWCmtsEuMxKupFUFePJNZdyG+P/RZs6CbgUgJyYUzKlOyeWH8KwQF1FLntipkIPlJ+uVkdwK2eDD6bzWQKBgQDylFiSnlFy0fwXSpWHDnDgukaLYxm2GNWaPyg0f2IqK/368o/Xu4TWOPuknR6ngeiJZz3SVA/kFeCz3+UxtDlbUheoSkkbo0cZg8PaKx875gE97oCHgRkaPS4l44kmu1ZwOMgfZDQPrLZMEbAfjqvMEa7ci5kXk1quOGeSJRIg3QKBgQDoumM2dZ+RxYxtxB2k1kJJIndZX3hhVyMfDIh5TwHHKNml1poa/s+aoT27BZgiM8snLR55xk4cQ59kr9Yic9Oa4seECsrAgP8mbB6eC/y7lRDZDFjJvHXl6a1ePo+hBlYarL83AUMIE1/SfZrdyM5yRmp3+cwHkKVpAQuiEXOSHwKBgEDkpn0ylR9eRU4FydKDbnbv3gdTz4EDS8EjvCGvIheeBSeo1AomQ/b673auAZFWE1sOn18w1b9yitYTw0B0shNX9rQyizQ1jcOpmC848fYYJaTntMKLKqf2Te4c3Ifb/devmPms2LCIx4u5/5+xjwvcfybIwX+pD80jkbFq8VqRAoGBAKulTKdN+XK6EOikTHjWzezCzuPL1i105yJvS/isnNMW/e+iZ+ahKN0TL0RQy/Pt31f1nxSRfeq6tUS9q2Gdq+QAfsaUbxWsDoN4GtzWWoC/YL20rYecyBfaUVPBMI3C7p6d6inXdGjwYSwOF7qb8Ce4Z641PpYVyOm5K6tM08BhAoGBALNkfH3ZPImRKN19bGcHAtrzoDMFAAQrhjyMr9aUpMGLoAjxh1U2pYbj1y0e03ArUT/TRzOXNbHuST82tDZEarVSF8RmU8DNUAHSI9dmtXPtgeKpG8TNyP5q3VnJEHdSRZVLb5pGfZuo3tegsHwZF/oCGK+GHD/fhmSFB04GPJon
notifyUrl: https://peaktcm.com/applet/huifuPay/callback
productId: EDUSTD
configureAppletCallbackUrl: https://peaktcm.com/applet/huifuPay/configureAppletCallback
huifu-vendor:
sysId: 6666000188069628
huifuId: 6666000188735389
publicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0uJDRMFj1xoQCJbReVaNdiqjL9vdKolMzWKe2vMhZwkBlgQMpaqtHqNKNCn3DPL/7ugPUNzj4PLr3PSR4DK+TBOOa3xRuKLt3s2x6wouVNpiRRglUzh5OgciXXYPPl7QGu2YlJZ9F7ikiaD7KG9PJI7oidbA7lQ4qMcIGlSBUF4l3TeoOpad0zLs41IRJJPIMKPf5Jj9HS/1Tggcn7f36h1l4JWpTRyfB8HyF66IHzA3mQa5yskUHf1LLuO0hxtIfy9Ua+xJYqEWD334xaMzauZQsLM98d1Pj7I1YRvzNohabpCJqO1wF6PDB3rqdLarAZagN/JhYIHHGXMBGfQZxwIDAQAB
privateKey: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDS4kNEwWPXGhAIltF5Vo12KqMv290qiUzNYp7a8yFnCQGWBAylqq0eo0o0KfcM8v/u6A9Q3OPg8uvc9JHgMr5ME45rfFG4ou3ezbHrCi5U2mJFGCVTOHk6ByJddg8+XtAa7ZiUln0XuKSJoPsob08kjuiJ1sDuVDioxwgaVIFQXiXdN6g6lp3TMuzjUhEkk8gwo9/kmP0dL/VOCByft/fqHWXglalNHJ8HwfIXrogfMDeZBrnKyRQd/Usu47SHG0h/L1Rr7ElioRYPffjFozNq5lCwsz3x3U+PsjVhG/M2iFpukImo7XAXo8MHeup0tqsBlqA38mFggccZcwEZ9BnHAgMBAAECggEABRZaQxVbQDwruNlSklfJL9mVeDkYm8cWKDpB1MxauO6ZsDHG0FROutd7mciNYi2WiP/mJrA9exbBI+JuhncS6ijqnaMxIYAktuRFb4MeXQOrrTkI5XoOSp0Tcie/9GQ7JvsmXCdJO0JEDeHpTS9qPFqKN5ELtHQprcCnbGMvf23KyqOFx71Sbe4JxDqV4j0MeJJ/ZEOnLHJAhJ/o/0Gw+2cAVBxOq/xDTiSzKQaR4Cy7h3HMlDXnBXlAwKLb7x/F6efFyBv3RGZjtTgt8G7319icRJUHyXa3JPk/UbKTHrZ3saCj0ByAPpCwSVx6uNxhVeEOFqi3VwtV8s4ClAJtUQKBgQDwEGA1Shr2klTnM1VN+R3YkgaG8QtkZQQG77vCR1q3uMPKpWUQOi/2wQs3SbTAr7ZX+8CHNb8M3KGVAEFR2PDEFok/LA0snFTwdL6dLkXkmOxmNyR2wmXIUimMBogQIc4bI11EpPoocbrzuJ3q48fDIAr7Hc4d/0HasEAQHvAdfwKBgQDg4gCr5M7atD4XdKqmNs5kltjw36EeSig2cajfQb7aARmHS+1F9cn1cpgTvqMBHxBZBx5cW1ETLTxDEq8/ONHHAtmgCVgrc0lgch+Dph1Nt4Jl/aNxxaZjLpLQtcHnFR4/7RGuJMUTAzAUcOer9XiCJskE2EVLrT53pE665Se3uQKBgFcXmc+7cszBicvW87u2BP3s/DE4gcmKXEun7ZYuDNtaTK3YEzIv6fa7UjZcpxbAqIaC7vYeqZEg+f30eb4X1kFNa71fXegxTx9tOzoK75BfamQq3S+4lvR12lzSgcpYeU2fJtcggyDpIcoJ0EDHIlHH7jPsPDrlwB52ksdGchZBAoGBAM49dvAuf6cD9o38aSTWzqJh1cPS1Ci7SfXkd0OJQEcfCxKSB6FJsVZxKhexljzJCG0dojKBbPFxYvsAf8gzi/BAJOYoq7vtlzXkdBKAng9QZT60Rtlosxfy9qKCjronG/70pGpZPoQZQFb+1PlXvpVejKzsy2CEGe4PukSdNLfBAoGATUJ7FGVmG2Ym8UHcP0bMeWwS7XROuiquliLtamWwpZTByZaLO1nK2FtC1oVj3il4Wox6/In1bBbdtqxmRmKcD9q1JExr1PHxXQTUbIoWb4GXNHq7h5kOhpra1uVRmNIewfJUYTCEzzHTrJe8dADBc7lGpsibwk174YD2343Aupw=
productId: PAYUN
notifyUrl: http://139.9.2.195:8083/hf/webhook/callback
payApi: https://api.huifu.com/v3/trade/payment/jspay
aliyun:
accessKeyId: LTAI5tBQGeqmhe6yhfqupaZD
accessKeySecret: YM2lsEtpjCLOF2kJGdsCBcwRHLX8aa
minio:
endpoint: http://139.9.2.195:8002
accessKey: YIh5PhIEHXEiJgPTlCSc
secretKey: 07becv7RNMI1wHyPPFtq3rlCPC6cyF0WrV5LNHYN
username: jkzy
password: jkzy@2025
nginxHost:
huaweiyun:
accessKey: HPUACMRQ2NKQNOXNCFNO
secretKey: KC3yEw7ARoL0oxcmXy7vE3hyMBPKjLsG1LCSQdYh
xf:
appid: 3fa7b7a0
long-sound:
keySecret: b44d730380dcfae02313dcea7101efc8
instant:
host: https://iat-api.xfyun.cn/v2/iat
APISecret: N2Q5Y2NiOTZmNThhODZjYTgxMjg1NjA4
apiKey: da390c58ef0f2ad8424c3dccc6d458c7
token:
expireTime: 30
wx:
appid: wx71e559ade446f09a
secret: 00b7f3cff0f4bde07daacd0dea7548c9
@@ -0,0 +1,35 @@
spring:
application:
name: unizk-admin
profiles:
active: dev
servlet:
multipart:
enabled: true
max-file-size: 500MB
max-request-size: 1000MB
server:
port: 8083
tomcat:
max-swallow-size: 1000MB
connection-timeout: 600000
max-keep-alive-requests: 600000
max-connections: 600000
servlet:
session:
timeout: 30m
logging:
level:
cn.unizk.mapper: debug
org.springframework: warn
org.apache.ibatis.logging: debug
org.springframework.integration: INFO
# org.springframework.web.servlet.DispatcherServlet: DEBUG
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
@@ -0,0 +1,80 @@
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
druid:
url: jdbc:mysql://139.9.2.195:3306/uni_ai_doctor?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true
username: unizk
password: Unizk@2025
redis:
port: 6379
host: 139.9.2.195
username:
password: Unizk@2025.Jkzy
database: 0
lettuce:
pool:
max-active: 8
max-idle: 6
min-idle: 2
max-wait: -1ms
shutdown-timeout: 360
timeout: 5000
huifu:
huifuId: 6666000179463008
payApi: https://api.huifu.com/v3/trade/payment/jspay
refundApi: https://api.huifu.com/v3/trade/payment/scanpay/refund
publicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3IcOEDMBOiHaa5dLsPWVVx+9yE/VEGjRSVZFUAospbCEhGDimE7UEL8ecXwbG9AN5k8yX+Ltj6zaeLIt3KgxbX5/4pnrOoPqFhtaoNuQrwl8/9/rkgGkoksH9e//mRan2+TjbHLKXWZKUduksaoWw4VehOx0nxE+wx7Bk7/VQAegnrDz4z/8zEd2Mcm51THceHJ5wVoMoXvo5e8nhUUAFJeHtlI5jxC85lK6kz2UNhGQ7Kutc7sBzK1U/mi29j/iStN3Z0fzND7+nRfgWPu4b0cKNnNwlIaGiabFTbpVZyV8LTg1BandmHJLNUUJyrc/s3W72VFUdp+BwgoERDcEwwIDAQAB
privateKey: MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDchw4QMwE6Idprl0uw9ZVXH73IT9UQaNFJVkVQCiylsISEYOKYTtQQvx5xfBsb0A3mTzJf4u2PrNp4si3cqDFtfn/imes6g+oWG1qg25CvCXz/3+uSAaSiSwf17/+ZFqfb5ONscspdZkpR26SxqhbDhV6E7HSfET7DHsGTv9VAB6CesPPjP/zMR3YxybnVMdx4cnnBWgyhe+jl7yeFRQAUl4e2UjmPELzmUrqTPZQ2EZDsq61zuwHMrVT+aLb2P+JK03dnR/M0Pv6dF+BY+7hvRwo2c3CUhoaJpsVNulVnJXwtODUFqd2Ycks1RQnKtz+zdbvZUVR2n4HCCgRENwTDAgMBAAECggEAbFWAaB7WVHt69G3fxi/uzF0Qe04UijojzhYueLJ22nKLtwhtaIsZDJ0G1JM2MgSUP3badVZig7lTngVSGFsb5QFGy8f3Ucip/3AypmEWg5ZyrLSQ4ioieYPIhl3/P3Jsxc58lrMRjK6KhgoTrx+yjRyAoWYTqGztWydJy05q8UekdbIn9K2Dq0294hHbarCjB3C/3SXX4xniEbDtVBTdjP81731gxnM2HJ98GDrvUf5MDrX4SdExvCYV0P0mU8uaRPK8ylWCmtsEuMxKupFUFePJNZdyG+P/RZs6CbgUgJyYUzKlOyeWH8KwQF1FLntipkIPlJ+uVkdwK2eDD6bzWQKBgQDylFiSnlFy0fwXSpWHDnDgukaLYxm2GNWaPyg0f2IqK/368o/Xu4TWOPuknR6ngeiJZz3SVA/kFeCz3+UxtDlbUheoSkkbo0cZg8PaKx875gE97oCHgRkaPS4l44kmu1ZwOMgfZDQPrLZMEbAfjqvMEa7ci5kXk1quOGeSJRIg3QKBgQDoumM2dZ+RxYxtxB2k1kJJIndZX3hhVyMfDIh5TwHHKNml1poa/s+aoT27BZgiM8snLR55xk4cQ59kr9Yic9Oa4seECsrAgP8mbB6eC/y7lRDZDFjJvHXl6a1ePo+hBlYarL83AUMIE1/SfZrdyM5yRmp3+cwHkKVpAQuiEXOSHwKBgEDkpn0ylR9eRU4FydKDbnbv3gdTz4EDS8EjvCGvIheeBSeo1AomQ/b673auAZFWE1sOn18w1b9yitYTw0B0shNX9rQyizQ1jcOpmC848fYYJaTntMKLKqf2Te4c3Ifb/devmPms2LCIx4u5/5+xjwvcfybIwX+pD80jkbFq8VqRAoGBAKulTKdN+XK6EOikTHjWzezCzuPL1i105yJvS/isnNMW/e+iZ+ahKN0TL0RQy/Pt31f1nxSRfeq6tUS9q2Gdq+QAfsaUbxWsDoN4GtzWWoC/YL20rYecyBfaUVPBMI3C7p6d6inXdGjwYSwOF7qb8Ce4Z641PpYVyOm5K6tM08BhAoGBALNkfH3ZPImRKN19bGcHAtrzoDMFAAQrhjyMr9aUpMGLoAjxh1U2pYbj1y0e03ArUT/TRzOXNbHuST82tDZEarVSF8RmU8DNUAHSI9dmtXPtgeKpG8TNyP5q3VnJEHdSRZVLb5pGfZuo3tegsHwZF/oCGK+GHD/fhmSFB04GPJon
notifyUrl: https://peaktcm.com/applet/huifuPay/callback
productId: EDUSTD
configureAppletCallbackUrl: https://peaktcm.com/applet/huifuPay/configureAppletCallback
huifu-vendor:
sysId: 6666000188069628
huifuId: 6666000188735389
publicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0uJDRMFj1xoQCJbReVaNdiqjL9vdKolMzWKe2vMhZwkBlgQMpaqtHqNKNCn3DPL/7ugPUNzj4PLr3PSR4DK+TBOOa3xRuKLt3s2x6wouVNpiRRglUzh5OgciXXYPPl7QGu2YlJZ9F7ikiaD7KG9PJI7oidbA7lQ4qMcIGlSBUF4l3TeoOpad0zLs41IRJJPIMKPf5Jj9HS/1Tggcn7f36h1l4JWpTRyfB8HyF66IHzA3mQa5yskUHf1LLuO0hxtIfy9Ua+xJYqEWD334xaMzauZQsLM98d1Pj7I1YRvzNohabpCJqO1wF6PDB3rqdLarAZagN/JhYIHHGXMBGfQZxwIDAQAB
privateKey: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDS4kNEwWPXGhAIltF5Vo12KqMv290qiUzNYp7a8yFnCQGWBAylqq0eo0o0KfcM8v/u6A9Q3OPg8uvc9JHgMr5ME45rfFG4ou3ezbHrCi5U2mJFGCVTOHk6ByJddg8+XtAa7ZiUln0XuKSJoPsob08kjuiJ1sDuVDioxwgaVIFQXiXdN6g6lp3TMuzjUhEkk8gwo9/kmP0dL/VOCByft/fqHWXglalNHJ8HwfIXrogfMDeZBrnKyRQd/Usu47SHG0h/L1Rr7ElioRYPffjFozNq5lCwsz3x3U+PsjVhG/M2iFpukImo7XAXo8MHeup0tqsBlqA38mFggccZcwEZ9BnHAgMBAAECggEABRZaQxVbQDwruNlSklfJL9mVeDkYm8cWKDpB1MxauO6ZsDHG0FROutd7mciNYi2WiP/mJrA9exbBI+JuhncS6ijqnaMxIYAktuRFb4MeXQOrrTkI5XoOSp0Tcie/9GQ7JvsmXCdJO0JEDeHpTS9qPFqKN5ELtHQprcCnbGMvf23KyqOFx71Sbe4JxDqV4j0MeJJ/ZEOnLHJAhJ/o/0Gw+2cAVBxOq/xDTiSzKQaR4Cy7h3HMlDXnBXlAwKLb7x/F6efFyBv3RGZjtTgt8G7319icRJUHyXa3JPk/UbKTHrZ3saCj0ByAPpCwSVx6uNxhVeEOFqi3VwtV8s4ClAJtUQKBgQDwEGA1Shr2klTnM1VN+R3YkgaG8QtkZQQG77vCR1q3uMPKpWUQOi/2wQs3SbTAr7ZX+8CHNb8M3KGVAEFR2PDEFok/LA0snFTwdL6dLkXkmOxmNyR2wmXIUimMBogQIc4bI11EpPoocbrzuJ3q48fDIAr7Hc4d/0HasEAQHvAdfwKBgQDg4gCr5M7atD4XdKqmNs5kltjw36EeSig2cajfQb7aARmHS+1F9cn1cpgTvqMBHxBZBx5cW1ETLTxDEq8/ONHHAtmgCVgrc0lgch+Dph1Nt4Jl/aNxxaZjLpLQtcHnFR4/7RGuJMUTAzAUcOer9XiCJskE2EVLrT53pE665Se3uQKBgFcXmc+7cszBicvW87u2BP3s/DE4gcmKXEun7ZYuDNtaTK3YEzIv6fa7UjZcpxbAqIaC7vYeqZEg+f30eb4X1kFNa71fXegxTx9tOzoK75BfamQq3S+4lvR12lzSgcpYeU2fJtcggyDpIcoJ0EDHIlHH7jPsPDrlwB52ksdGchZBAoGBAM49dvAuf6cD9o38aSTWzqJh1cPS1Ci7SfXkd0OJQEcfCxKSB6FJsVZxKhexljzJCG0dojKBbPFxYvsAf8gzi/BAJOYoq7vtlzXkdBKAng9QZT60Rtlosxfy9qKCjronG/70pGpZPoQZQFb+1PlXvpVejKzsy2CEGe4PukSdNLfBAoGATUJ7FGVmG2Ym8UHcP0bMeWwS7XROuiquliLtamWwpZTByZaLO1nK2FtC1oVj3il4Wox6/In1bBbdtqxmRmKcD9q1JExr1PHxXQTUbIoWb4GXNHq7h5kOhpra1uVRmNIewfJUYTCEzzHTrJe8dADBc7lGpsibwk174YD2343Aupw=
productId: PAYUN
notifyUrl: https://peaktcm.com:8083/hf/webhook/callback
payApi: https://api.huifu.com/v3/trade/payment/jspay
aliyun:
accessKeyId: LTAI5tBQGeqmhe6yhfqupaZD
accessKeySecret: YM2lsEtpjCLOF2kJGdsCBcwRHLX8aa
minio:
endpoint: http://139.9.2.195:8002
accessKey: YIh5PhIEHXEiJgPTlCSc
secretKey: 07becv7RNMI1wHyPPFtq3rlCPC6cyF0WrV5LNHYN
username: jkzy
password: jkzy@2025
nginxHost:
huaweiyun:
accessKey: HPUACMRQ2NKQNOXNCFNO
secretKey: KC3yEw7ARoL0oxcmXy7vE3hyMBPKjLsG1LCSQdYh
xf:
appid: 3fa7b7a0
long-sound:
keySecret: b44d730380dcfae02313dcea7101efc8
instant:
host: https://iat-api.xfyun.cn/v2/iat
APISecret: N2Q5Y2NiOTZmNThhODZjYTgxMjg1NjA4
apiKey: da390c58ef0f2ad8424c3dccc6d458c7
token:
expireTime: 30
wx:
appid: wx71e559ade446f09a
secret: 00b7f3cff0f4bde07daacd0dea7548c9
@@ -0,0 +1,80 @@
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
druid:
url: jdbc:mysql://139.9.2.195:3306/uni_ai_doctor?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true
username: unizk
password: Unizk@2025
redis:
port: 6379
host: localhost
username:
password: Unizk@2025.Jkzy
database: 0
lettuce:
pool:
max-active: 8
max-idle: 6
min-idle: 2
max-wait: -1ms
shutdown-timeout: 360
timeout: 5000
huifu:
huifuId: 6666000179463008
payApi: https://api.huifu.com/v3/trade/payment/jspay
refundApi: https://api.huifu.com/v3/trade/payment/scanpay/refund
publicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3IcOEDMBOiHaa5dLsPWVVx+9yE/VEGjRSVZFUAospbCEhGDimE7UEL8ecXwbG9AN5k8yX+Ltj6zaeLIt3KgxbX5/4pnrOoPqFhtaoNuQrwl8/9/rkgGkoksH9e//mRan2+TjbHLKXWZKUduksaoWw4VehOx0nxE+wx7Bk7/VQAegnrDz4z/8zEd2Mcm51THceHJ5wVoMoXvo5e8nhUUAFJeHtlI5jxC85lK6kz2UNhGQ7Kutc7sBzK1U/mi29j/iStN3Z0fzND7+nRfgWPu4b0cKNnNwlIaGiabFTbpVZyV8LTg1BandmHJLNUUJyrc/s3W72VFUdp+BwgoERDcEwwIDAQAB
privateKey: MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDchw4QMwE6Idprl0uw9ZVXH73IT9UQaNFJVkVQCiylsISEYOKYTtQQvx5xfBsb0A3mTzJf4u2PrNp4si3cqDFtfn/imes6g+oWG1qg25CvCXz/3+uSAaSiSwf17/+ZFqfb5ONscspdZkpR26SxqhbDhV6E7HSfET7DHsGTv9VAB6CesPPjP/zMR3YxybnVMdx4cnnBWgyhe+jl7yeFRQAUl4e2UjmPELzmUrqTPZQ2EZDsq61zuwHMrVT+aLb2P+JK03dnR/M0Pv6dF+BY+7hvRwo2c3CUhoaJpsVNulVnJXwtODUFqd2Ycks1RQnKtz+zdbvZUVR2n4HCCgRENwTDAgMBAAECggEAbFWAaB7WVHt69G3fxi/uzF0Qe04UijojzhYueLJ22nKLtwhtaIsZDJ0G1JM2MgSUP3badVZig7lTngVSGFsb5QFGy8f3Ucip/3AypmEWg5ZyrLSQ4ioieYPIhl3/P3Jsxc58lrMRjK6KhgoTrx+yjRyAoWYTqGztWydJy05q8UekdbIn9K2Dq0294hHbarCjB3C/3SXX4xniEbDtVBTdjP81731gxnM2HJ98GDrvUf5MDrX4SdExvCYV0P0mU8uaRPK8ylWCmtsEuMxKupFUFePJNZdyG+P/RZs6CbgUgJyYUzKlOyeWH8KwQF1FLntipkIPlJ+uVkdwK2eDD6bzWQKBgQDylFiSnlFy0fwXSpWHDnDgukaLYxm2GNWaPyg0f2IqK/368o/Xu4TWOPuknR6ngeiJZz3SVA/kFeCz3+UxtDlbUheoSkkbo0cZg8PaKx875gE97oCHgRkaPS4l44kmu1ZwOMgfZDQPrLZMEbAfjqvMEa7ci5kXk1quOGeSJRIg3QKBgQDoumM2dZ+RxYxtxB2k1kJJIndZX3hhVyMfDIh5TwHHKNml1poa/s+aoT27BZgiM8snLR55xk4cQ59kr9Yic9Oa4seECsrAgP8mbB6eC/y7lRDZDFjJvHXl6a1ePo+hBlYarL83AUMIE1/SfZrdyM5yRmp3+cwHkKVpAQuiEXOSHwKBgEDkpn0ylR9eRU4FydKDbnbv3gdTz4EDS8EjvCGvIheeBSeo1AomQ/b673auAZFWE1sOn18w1b9yitYTw0B0shNX9rQyizQ1jcOpmC848fYYJaTntMKLKqf2Te4c3Ifb/devmPms2LCIx4u5/5+xjwvcfybIwX+pD80jkbFq8VqRAoGBAKulTKdN+XK6EOikTHjWzezCzuPL1i105yJvS/isnNMW/e+iZ+ahKN0TL0RQy/Pt31f1nxSRfeq6tUS9q2Gdq+QAfsaUbxWsDoN4GtzWWoC/YL20rYecyBfaUVPBMI3C7p6d6inXdGjwYSwOF7qb8Ce4Z641PpYVyOm5K6tM08BhAoGBALNkfH3ZPImRKN19bGcHAtrzoDMFAAQrhjyMr9aUpMGLoAjxh1U2pYbj1y0e03ArUT/TRzOXNbHuST82tDZEarVSF8RmU8DNUAHSI9dmtXPtgeKpG8TNyP5q3VnJEHdSRZVLb5pGfZuo3tegsHwZF/oCGK+GHD/fhmSFB04GPJon
notifyUrl: https://peaktcm.com/applet/huifuPay/callback
productId: EDUSTD
configureAppletCallbackUrl: https://peaktcm.com/applet/huifuPay/configureAppletCallback
huifu-vendor:
sysId: 6666000188069628
huifuId: 6666000188735389
publicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0uJDRMFj1xoQCJbReVaNdiqjL9vdKolMzWKe2vMhZwkBlgQMpaqtHqNKNCn3DPL/7ugPUNzj4PLr3PSR4DK+TBOOa3xRuKLt3s2x6wouVNpiRRglUzh5OgciXXYPPl7QGu2YlJZ9F7ikiaD7KG9PJI7oidbA7lQ4qMcIGlSBUF4l3TeoOpad0zLs41IRJJPIMKPf5Jj9HS/1Tggcn7f36h1l4JWpTRyfB8HyF66IHzA3mQa5yskUHf1LLuO0hxtIfy9Ua+xJYqEWD334xaMzauZQsLM98d1Pj7I1YRvzNohabpCJqO1wF6PDB3rqdLarAZagN/JhYIHHGXMBGfQZxwIDAQAB
privateKey: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDS4kNEwWPXGhAIltF5Vo12KqMv290qiUzNYp7a8yFnCQGWBAylqq0eo0o0KfcM8v/u6A9Q3OPg8uvc9JHgMr5ME45rfFG4ou3ezbHrCi5U2mJFGCVTOHk6ByJddg8+XtAa7ZiUln0XuKSJoPsob08kjuiJ1sDuVDioxwgaVIFQXiXdN6g6lp3TMuzjUhEkk8gwo9/kmP0dL/VOCByft/fqHWXglalNHJ8HwfIXrogfMDeZBrnKyRQd/Usu47SHG0h/L1Rr7ElioRYPffjFozNq5lCwsz3x3U+PsjVhG/M2iFpukImo7XAXo8MHeup0tqsBlqA38mFggccZcwEZ9BnHAgMBAAECggEABRZaQxVbQDwruNlSklfJL9mVeDkYm8cWKDpB1MxauO6ZsDHG0FROutd7mciNYi2WiP/mJrA9exbBI+JuhncS6ijqnaMxIYAktuRFb4MeXQOrrTkI5XoOSp0Tcie/9GQ7JvsmXCdJO0JEDeHpTS9qPFqKN5ELtHQprcCnbGMvf23KyqOFx71Sbe4JxDqV4j0MeJJ/ZEOnLHJAhJ/o/0Gw+2cAVBxOq/xDTiSzKQaR4Cy7h3HMlDXnBXlAwKLb7x/F6efFyBv3RGZjtTgt8G7319icRJUHyXa3JPk/UbKTHrZ3saCj0ByAPpCwSVx6uNxhVeEOFqi3VwtV8s4ClAJtUQKBgQDwEGA1Shr2klTnM1VN+R3YkgaG8QtkZQQG77vCR1q3uMPKpWUQOi/2wQs3SbTAr7ZX+8CHNb8M3KGVAEFR2PDEFok/LA0snFTwdL6dLkXkmOxmNyR2wmXIUimMBogQIc4bI11EpPoocbrzuJ3q48fDIAr7Hc4d/0HasEAQHvAdfwKBgQDg4gCr5M7atD4XdKqmNs5kltjw36EeSig2cajfQb7aARmHS+1F9cn1cpgTvqMBHxBZBx5cW1ETLTxDEq8/ONHHAtmgCVgrc0lgch+Dph1Nt4Jl/aNxxaZjLpLQtcHnFR4/7RGuJMUTAzAUcOer9XiCJskE2EVLrT53pE665Se3uQKBgFcXmc+7cszBicvW87u2BP3s/DE4gcmKXEun7ZYuDNtaTK3YEzIv6fa7UjZcpxbAqIaC7vYeqZEg+f30eb4X1kFNa71fXegxTx9tOzoK75BfamQq3S+4lvR12lzSgcpYeU2fJtcggyDpIcoJ0EDHIlHH7jPsPDrlwB52ksdGchZBAoGBAM49dvAuf6cD9o38aSTWzqJh1cPS1Ci7SfXkd0OJQEcfCxKSB6FJsVZxKhexljzJCG0dojKBbPFxYvsAf8gzi/BAJOYoq7vtlzXkdBKAng9QZT60Rtlosxfy9qKCjronG/70pGpZPoQZQFb+1PlXvpVejKzsy2CEGe4PukSdNLfBAoGATUJ7FGVmG2Ym8UHcP0bMeWwS7XROuiquliLtamWwpZTByZaLO1nK2FtC1oVj3il4Wox6/In1bBbdtqxmRmKcD9q1JExr1PHxXQTUbIoWb4GXNHq7h5kOhpra1uVRmNIewfJUYTCEzzHTrJe8dADBc7lGpsibwk174YD2343Aupw=
productId: PAYUN
notifyUrl: http://139.9.2.195:8083/hf/webhook/callback
payApi: https://api.huifu.com/v3/trade/payment/jspay
aliyun:
accessKeyId: LTAI5tBQGeqmhe6yhfqupaZD
accessKeySecret: YM2lsEtpjCLOF2kJGdsCBcwRHLX8aa
minio:
endpoint: http://139.9.2.195:8002
accessKey: YIh5PhIEHXEiJgPTlCSc
secretKey: 07becv7RNMI1wHyPPFtq3rlCPC6cyF0WrV5LNHYN
username: jkzy
password: jkzy@2025
nginxHost:
huaweiyun:
accessKey: HPUACMRQ2NKQNOXNCFNO
secretKey: KC3yEw7ARoL0oxcmXy7vE3hyMBPKjLsG1LCSQdYh
xf:
appid: 3fa7b7a0
long-sound:
keySecret: b44d730380dcfae02313dcea7101efc8
instant:
host: https://iat-api.xfyun.cn/v2/iat
APISecret: N2Q5Y2NiOTZmNThhODZjYTgxMjg1NjA4
apiKey: da390c58ef0f2ad8424c3dccc6d458c7
token:
expireTime: 30
wx:
appid: wx71e559ade446f09a
secret: 00b7f3cff0f4bde07daacd0dea7548c9
+35
View File
@@ -0,0 +1,35 @@
spring:
application:
name: unizk-admin
profiles:
active: dev
servlet:
multipart:
enabled: true
max-file-size: 500MB
max-request-size: 1000MB
server:
port: 8083
tomcat:
max-swallow-size: 1000MB
connection-timeout: 600000
max-keep-alive-requests: 600000
max-connections: 600000
servlet:
session:
timeout: 30m
logging:
level:
cn.unizk.mapper: debug
org.springframework: warn
org.apache.ibatis.logging: debug
org.springframework.integration: INFO
# org.springframework.web.servlet.DispatcherServlet: DEBUG
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
Binary file not shown.
Loaded 100 of 1456 files, more files were not shown because too many files have changed in this diff. Show more