427 lines
16 KiB
Java
427 lines
16 KiB
Java
package com.example.caseData.service;
|
||
|
||
import cn.hutool.crypto.SecureUtil;
|
||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||
import com.example.caseData.dao.BasicHospitalDao;
|
||
import com.example.caseData.dao.CaseClinicalDoctorDao;
|
||
import com.example.caseData.dao.CaseClinicalRecordScoreDao;
|
||
import com.example.caseData.dao.UserDao;
|
||
import com.example.caseData.dto.publicDto.LoginDto;
|
||
import com.example.caseData.exception.BusinessException;
|
||
import com.example.caseData.extend.aliyun.Oss;
|
||
import com.example.caseData.extend.app.Hospital.GetHospitalByUuidResponse;
|
||
import com.example.caseData.extend.app.Hospital.Hospital;
|
||
import com.example.caseData.extend.app.Score.Score;
|
||
import com.example.caseData.extend.app.UserInfo.GetUserInfoResponse;
|
||
import com.example.caseData.extend.app.UserInfo.UserInfo;
|
||
import com.example.caseData.model.*;
|
||
import com.example.caseData.request.UserRequest.ReportUserScoreRequest;
|
||
import com.example.caseData.utils.JwtUtil;
|
||
import com.example.caseData.utils.Replace;
|
||
import com.example.caseData.utils.StringToInt;
|
||
import jakarta.annotation.Resource;
|
||
import lombok.extern.slf4j.Slf4j;
|
||
import org.springframework.stereotype.Service;
|
||
import org.springframework.transaction.annotation.Transactional;
|
||
import java.io.ByteArrayOutputStream;
|
||
import java.io.InputStream;
|
||
import java.net.HttpURLConnection;
|
||
import java.net.URL;
|
||
import java.time.LocalDateTime;
|
||
import java.time.format.DateTimeFormatter;
|
||
import java.util.Random;
|
||
|
||
import java.io.InputStream;
|
||
import java.net.HttpURLConnection;
|
||
import java.net.URL;
|
||
import java.time.LocalDate;
|
||
import java.time.LocalDateTime;
|
||
import java.time.format.DateTimeFormatter;
|
||
import java.util.List;
|
||
import java.util.Objects;
|
||
import java.util.Random;
|
||
|
||
import static com.baomidou.mybatisplus.extension.toolkit.Db.save;
|
||
|
||
@Slf4j
|
||
@Service
|
||
public class UserService {
|
||
@Resource
|
||
private UserDao userDao;
|
||
|
||
@Resource
|
||
private UserInfo userInfo;
|
||
|
||
@Resource
|
||
private BasicHospitalDao basicHospitalDao;
|
||
|
||
@Resource
|
||
private CaseClinicalDoctorDao caseClinicalDoctorDao;
|
||
|
||
@Resource
|
||
private CaseClinicalRecordScoreDao caseClinicalRecordScoreDao;
|
||
|
||
@Resource
|
||
private Hospital hospital;
|
||
|
||
@Resource
|
||
private JwtUtil jwtUtil;
|
||
|
||
@Resource
|
||
private Score score;
|
||
|
||
/**
|
||
* 用户登陆-手机号
|
||
* @return UserModel
|
||
*/
|
||
@Transactional
|
||
public LoginDto UserLoginWithMobile(String phone) throws BusinessException {
|
||
// 获取app用户数据
|
||
GetUserInfoResponse result = userInfo.getUserInfoByMobile(phone);
|
||
UserModel user = GetAppUserInfo(result);
|
||
|
||
// 生成jwt
|
||
String token = jwtUtil.createToken(String.valueOf(user.getUserId()));
|
||
|
||
// 获取对应医生数据
|
||
LambdaQueryWrapper<CaseClinicalDoctorModel> caseClinicalDoctorWrapper = new LambdaQueryWrapper<>();
|
||
caseClinicalDoctorWrapper.eq(CaseClinicalDoctorModel::getDoctorIden, user.getUserIden());
|
||
CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectOne(caseClinicalDoctorWrapper);
|
||
|
||
// 处理返回值
|
||
LoginDto g = new LoginDto();
|
||
g.setUserId(String.valueOf(user.getUserId()));
|
||
g.setUserName(user.getUserName());
|
||
g.setAvatar(Replace.addOssDomain(user.getAvatar()));
|
||
g.setToken(token);
|
||
|
||
if (caseClinicalDoctor != null) {
|
||
g.setDoctorId(String.valueOf(caseClinicalDoctor.getDoctorId()));
|
||
}
|
||
return g;
|
||
}
|
||
|
||
/**
|
||
* 用户登陆-app
|
||
* @param appToken 1
|
||
*/
|
||
@Transactional
|
||
public LoginDto UserLoginWithApp(String appToken) throws BusinessException {
|
||
GetUserInfoResponse result = userInfo.getUserInfoByToken(appToken);
|
||
UserModel user = GetAppUserInfo(result);
|
||
|
||
// 生成jwt
|
||
String token = jwtUtil.createToken(String.valueOf(user.getUserId()));
|
||
|
||
// 获取对应医生数据
|
||
LambdaQueryWrapper<CaseClinicalDoctorModel> caseClinicalDoctorWrapper = new LambdaQueryWrapper<>();
|
||
caseClinicalDoctorWrapper.eq(CaseClinicalDoctorModel::getDoctorIden, user.getUserIden());
|
||
CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectOne(caseClinicalDoctorWrapper);
|
||
|
||
// 处理返回值
|
||
LoginDto g = new LoginDto();
|
||
g.setUserId(String.valueOf(user.getUserId()));
|
||
g.setUserName(user.getUserName());
|
||
g.setAvatar(Replace.addOssDomain(user.getAvatar()));
|
||
g.setToken(token);
|
||
|
||
if (caseClinicalDoctor != null) {
|
||
g.setDoctorId(String.valueOf(caseClinicalDoctor.getDoctorId()));
|
||
}
|
||
return g;
|
||
}
|
||
|
||
/**
|
||
* 获取app用户数据
|
||
* @return UserModel
|
||
*/
|
||
public UserModel GetAppUserInfo(GetUserInfoResponse r) throws BusinessException {
|
||
GetUserInfoResponse.ResponsData data = r.getData();
|
||
|
||
// 查询数据库用户信息
|
||
LambdaQueryWrapper<UserModel> userModelWrapper = new LambdaQueryWrapper<>();
|
||
userModelWrapper.eq(UserModel::getUserIden, r.getData().getUuid());
|
||
UserModel user = userDao.selectOne(userModelWrapper);
|
||
if (user == null){
|
||
// 构造 UserModel 对象
|
||
user = new UserModel();
|
||
user.setUserIden(data.getUuid());
|
||
user.setUserName(data.getRealname());
|
||
user.setUserMobile(data.getMobile());
|
||
user.setMobileEncryption(SecureUtil.md5(data.getMobile()));
|
||
user.setStatus(1);
|
||
user.setRegisterSource(2);
|
||
user.setOpenId("");
|
||
user.setUnionId("");
|
||
user.setSex(0);
|
||
if (data.getPhoto() != null) {
|
||
String ossPath = UserService.handleUserImage(data.getImg_host() + data.getPhoto());
|
||
user.setAvatar(ossPath);
|
||
}else{
|
||
user.setAvatar("");
|
||
}
|
||
|
||
user.setDepartmentName(data.getOfficeName());
|
||
user.setTitle(StringToInt.DoctorTitleToInt(data.getPositionName()));
|
||
user.setAddress(data.getProvName());
|
||
int res = userDao.insert(user);
|
||
if (res <= 0){
|
||
throw new BusinessException("操作失败");
|
||
}
|
||
}else{
|
||
if (!Objects.equals(user.getUserName(), data.getRealname())){
|
||
user.setUserName(data.getRealname());
|
||
}
|
||
|
||
if (!Objects.equals(user.getUserMobile(), data.getMobile())){
|
||
user.setUserMobile(data.getMobile());
|
||
user.setMobileEncryption(SecureUtil.md5(data.getMobile()));
|
||
}
|
||
|
||
if (!Objects.equals(user.getTitle(), StringToInt.DoctorTitleToInt(data.getPositionName()))){
|
||
user.setTitle(StringToInt.DoctorTitleToInt(data.getPositionName()));
|
||
}
|
||
|
||
if (!Objects.equals(user.getDepartmentName(), data.getOfficeName())){
|
||
user.setDepartmentName(data.getOfficeName());
|
||
}
|
||
|
||
if (!Objects.equals(user.getAddress(), data.getProvName())){
|
||
user.setAddress(data.getProvName());
|
||
}
|
||
|
||
if (data.getPhoto() != null) {
|
||
try {
|
||
String ossPath = UserService.handleUserImage(data.getImg_host() + data.getPhoto());
|
||
user.setAvatar(ossPath);
|
||
}catch (Exception e){
|
||
// 不处理
|
||
}
|
||
}
|
||
|
||
userDao.updateById(user);
|
||
}
|
||
|
||
// 获取app医院数据
|
||
BasicHospitalModel basicHospital = GetAppHospital(data.getHospitalUuid());
|
||
|
||
// 修改用户所属医院
|
||
if (!Objects.equals(user.getHospitalId(), basicHospital.getHospitalId())){
|
||
user.setHospitalId(basicHospital.getHospitalId());
|
||
userDao.updateById(user);
|
||
}
|
||
|
||
// 获取对应医生数据
|
||
LambdaQueryWrapper<CaseClinicalDoctorModel> caseClinicalDoctorWrapper = new LambdaQueryWrapper<>();
|
||
caseClinicalDoctorWrapper.eq(CaseClinicalDoctorModel::getDoctorIden, user.getUserIden());
|
||
CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectOne(caseClinicalDoctorWrapper);
|
||
if (caseClinicalDoctor == null){
|
||
// 二次匹配:通过姓名-医院获取医生信息
|
||
caseClinicalDoctorWrapper = new LambdaQueryWrapper<>();
|
||
caseClinicalDoctorWrapper.eq(CaseClinicalDoctorModel::getDoctorId, user.getUserName());
|
||
caseClinicalDoctorWrapper.eq(CaseClinicalDoctorModel::getHospitalId, basicHospital.getHospitalId());
|
||
caseClinicalDoctor = caseClinicalDoctorDao.selectOne(caseClinicalDoctorWrapper);
|
||
}
|
||
|
||
if (caseClinicalDoctor == null){
|
||
CaseClinicalDoctorModel c = new CaseClinicalDoctorModel();
|
||
c.setDoctorName(user.getUserName());
|
||
c.setDoctorIden(user.getUserIden());
|
||
c.setHospitalId(user.getHospitalId());
|
||
c.setAvatar(user.getAvatar());
|
||
int res = caseClinicalDoctorDao.insert(c);
|
||
if (res <= 0){
|
||
throw new BusinessException("操作失败");
|
||
}
|
||
}else{
|
||
if (!Objects.equals(caseClinicalDoctor.getDoctorName(), data.getRealname())){
|
||
caseClinicalDoctor.setDoctorName(data.getRealname());
|
||
}
|
||
|
||
if (!Objects.equals(basicHospital.getHospitalId(), caseClinicalDoctor.getHospitalId())){
|
||
caseClinicalDoctor.setHospitalId(basicHospital.getHospitalId());
|
||
}
|
||
|
||
if (!Objects.equals(user.getAvatar(), caseClinicalDoctor.getAvatar())){
|
||
caseClinicalDoctor.setAvatar(user.getAvatar());
|
||
}
|
||
|
||
caseClinicalDoctorDao.updateById(caseClinicalDoctor);
|
||
}
|
||
|
||
return user;
|
||
}
|
||
|
||
/**
|
||
* 获取app医院数据
|
||
* @param hospitalIden app医院唯一标识
|
||
* @return BasicHospitalModel
|
||
*/
|
||
public BasicHospitalModel GetAppHospital(String hospitalIden) throws BusinessException {
|
||
// 查询数据库医院信息
|
||
LambdaQueryWrapper<BasicHospitalModel> basicHospitalWrapper = new LambdaQueryWrapper<>();
|
||
basicHospitalWrapper.eq(BasicHospitalModel::getHospitalIden, hospitalIden);
|
||
BasicHospitalModel basicHospital = basicHospitalDao.selectOne(basicHospitalWrapper);
|
||
if (basicHospital == null){
|
||
// 请求接口获取数据
|
||
GetHospitalByUuidResponse result = hospital.getHospitalByUuid(hospitalIden);
|
||
GetHospitalByUuidResponse.GetHospitalByUuidData data = result.getData();
|
||
|
||
// 构造 UserModel 对象
|
||
basicHospital = new BasicHospitalModel();
|
||
basicHospital.setHospitalIden(hospitalIden);
|
||
basicHospital.setHospitalName(data.getName());
|
||
basicHospital.setSource(2);
|
||
basicHospital.setHospitalLevel(data.getLevel());
|
||
basicHospital.setDoctorNumber(data.getExpert_num());
|
||
basicHospital.setProvince(data.getProv_name());
|
||
save(basicHospital);
|
||
}
|
||
|
||
return basicHospital;
|
||
}
|
||
|
||
/**
|
||
* 获取临床医生数据
|
||
* @return UserModel
|
||
*/
|
||
public CaseClinicalDoctorModel GetCaseClinicalDoctor(GetUserInfoResponse r) throws BusinessException {
|
||
GetUserInfoResponse.ResponsData data = r.getData();
|
||
|
||
// 获取app医院数据
|
||
BasicHospitalModel basicHospital = GetAppHospital(data.getHospitalUuid());
|
||
|
||
// 获取对应医生数据
|
||
LambdaQueryWrapper<CaseClinicalDoctorModel> caseClinicalDoctorWrapper = new LambdaQueryWrapper<>();
|
||
caseClinicalDoctorWrapper.eq(CaseClinicalDoctorModel::getDoctorIden, data.getUuid());
|
||
CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectOne(caseClinicalDoctorWrapper);
|
||
if (caseClinicalDoctor == null){
|
||
caseClinicalDoctor = new CaseClinicalDoctorModel();
|
||
caseClinicalDoctor.setDoctorName(data.getRealname());
|
||
caseClinicalDoctor.setDoctorIden(data.getUuid());
|
||
caseClinicalDoctor.setHospitalId(basicHospital.getHospitalId());
|
||
caseClinicalDoctor.setAvatar(data.getPhoto());
|
||
int res = caseClinicalDoctorDao.insert(caseClinicalDoctor);
|
||
if (res <= 0){
|
||
throw new BusinessException("操作失败");
|
||
}
|
||
}else{
|
||
if (!Objects.equals(caseClinicalDoctor.getDoctorName(), data.getRealname())){
|
||
caseClinicalDoctor.setDoctorName(data.getRealname());
|
||
}
|
||
|
||
if (!Objects.equals(basicHospital.getHospitalId(), caseClinicalDoctor.getHospitalId())){
|
||
caseClinicalDoctor.setHospitalId(basicHospital.getHospitalId());
|
||
}
|
||
|
||
caseClinicalDoctorDao.updateById(caseClinicalDoctor);
|
||
}
|
||
|
||
return caseClinicalDoctor;
|
||
}
|
||
|
||
// 发放积分
|
||
public boolean ReportUserScore(String id,Integer type,String userId) throws BusinessException{
|
||
// 获取积分发放记录
|
||
// 获取今天的日期,并设置时间为 00:00:00
|
||
LocalDateTime startOfToday = LocalDate.now().atStartOfDay(); // 例如:2025-07-30 00:00:00
|
||
|
||
QueryWrapper<CaseClinicalRecordScoreModel> queryWrapper = new QueryWrapper<>();
|
||
queryWrapper.eq("user_id", userId)
|
||
.ge("created_at", startOfToday) // created_at >= 今天 00:00:00
|
||
.orderByDesc("created_at"); // 最新的在前
|
||
List<CaseClinicalRecordScoreModel> caseClinicalRecordScores = caseClinicalRecordScoreDao.selectList(queryWrapper);
|
||
if (caseClinicalRecordScores.size() > 3){
|
||
return true;
|
||
}
|
||
|
||
// 获取用户数据
|
||
UserModel user = userDao.selectById(userId);
|
||
if (user == null){
|
||
throw new BusinessException("积分");
|
||
}
|
||
|
||
// 发放积分
|
||
score.ReportUserScore(user.getUserIden(),5,"病例库-病例互动");
|
||
|
||
// 添加打赏记录
|
||
CaseClinicalRecordScoreModel data = new CaseClinicalRecordScoreModel();
|
||
data.setUserId(Long.valueOf(userId));
|
||
data.setScore(5);
|
||
data.setId(Long.valueOf(id));
|
||
data.setUserName(user.getUserName());
|
||
data.setNodeName("病例库-病例互动");
|
||
data.setType(type);
|
||
data.setScoreType(5);
|
||
caseClinicalRecordScoreDao.insert(data);
|
||
|
||
|
||
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* 处理用户头像:下载远程头像并上传至 OSS
|
||
*
|
||
* @param wxAvatarUrl 微信头像地址
|
||
* @return OSS 路径(以 / 开头),如 /user/avatar/202507301530123456.png
|
||
*/
|
||
public static String handleUserImage(String wxAvatarUrl) {
|
||
if (wxAvatarUrl == null || wxAvatarUrl.isEmpty()) {
|
||
return null;
|
||
}
|
||
|
||
HttpURLConnection conn = null;
|
||
try {
|
||
// 1. 下载远程图片
|
||
URL url = new URL(wxAvatarUrl);
|
||
conn = (HttpURLConnection) url.openConnection();
|
||
conn.setConnectTimeout(5000);
|
||
conn.setReadTimeout(10000);
|
||
conn.setRequestMethod("GET");
|
||
|
||
if (conn.getResponseCode() != 200) {
|
||
throw new BusinessException("图片处理失败");
|
||
}
|
||
|
||
try (InputStream input = conn.getInputStream();
|
||
ByteArrayOutputStream output = new ByteArrayOutputStream()) {
|
||
|
||
byte[] buffer = new byte[4096];
|
||
int len;
|
||
while ((len = input.read(buffer)) != -1) {
|
||
output.write(buffer, 0, len);
|
||
}
|
||
|
||
byte[] imageBytes = output.toByteArray();
|
||
if (imageBytes.length == 0) {
|
||
throw new BusinessException("图片处理失败");
|
||
}
|
||
|
||
// 2. 生成 OSS 路径
|
||
String dateTimeStr = LocalDateTime.now()
|
||
.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
|
||
int randomSuffix = new Random().nextInt(9000) + 1000;
|
||
String ossPath = "dev/static/images/" + dateTimeStr + randomSuffix + ".png";
|
||
|
||
// 3. 上传 OSS
|
||
boolean success = Oss.putObject(ossPath, imageBytes);
|
||
if (!success) {
|
||
throw new BusinessException("图片处理失败");
|
||
}
|
||
|
||
return "/" + ossPath;
|
||
}
|
||
|
||
} catch (Exception e) {
|
||
// 头像处理失败
|
||
System.out.println(e.getMessage());
|
||
return "";
|
||
} finally {
|
||
if (conn != null) {
|
||
conn.disconnect();
|
||
}
|
||
}
|
||
}
|
||
} |