202506251738

This commit is contained in:
张潘 2025-06-25 17:38:54 +08:00
parent 74257caefe
commit 44ca8c32d6
115 changed files with 1993 additions and 113210 deletions

View File

@ -3,6 +3,7 @@ package com.ruoyi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* 启动程序
@ -10,6 +11,7 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
* @author ruoyi
*/
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
@EnableScheduling
public class RuoYiApplication
{
public static void main(String[] args)

View File

@ -6,6 +6,7 @@ import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.system.ControllerUtil.*;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.AppleDoMain.OrderApple;
@ -25,6 +26,8 @@ import javax.servlet.http.HttpServletRequest;
import java.math.RoundingMode;
import java.text.DateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.text.SimpleDateFormat;
import java.util.stream.Collectors;
@ -3622,14 +3625,14 @@ public AjaxResult getSkillList(HttpServletRequest request) {
* @return 上传结果
* <p>
* 接口说明
* - 支持图片和文档文件上传
* - 支持图片和视频文件上传
* - 优先使用七牛云上传未启用时使用本地上传
* - 自动验证文件格式和大小
* - 无需用户登录验证public 接口
* <p>
* 支持的文件格式
* - 图片jpg, jpeg, png, gif, bmp, webp, svg
* - 文档doc, docx, xls, xlsx, ppt, pptx, txt, pdf
* - 视频mp4, avi, mov, wmv, flv, m4v, 3gp, rmvb, mkv
* <p>
* 返回格式
* {
@ -3649,16 +3652,16 @@ public AjaxResult uploadFile(@RequestParam("file") MultipartFile file, HttpServl
return AppletControllerUtil.appletWarning("上传文件不能为空");
}
// 2. 验证文件格式
// 2. 只允许图片和视频格式
String[] allowedTypes = {
// 图片格式
"jpg", "jpeg", "png", "gif", "bmp", "webp", "svg",
// 文档格式
"doc", "docx", "xls", "xlsx", "ppt", "pptx", "txt", "pdf"
// 视频格式
"mp4", "avi", "mov", "wmv", "flv", "m4v", "3gp", "rmvb", "mkv"
};
if (!QiniuUploadUtil.isValidFileType(file.getOriginalFilename(), allowedTypes)) {
return AppletControllerUtil.appletWarning("不支持的文件格式");
return AppletControllerUtil.appletWarning("只允许上传图片或视频文件");
}
// 3. 验证文件大小10MB
@ -4701,7 +4704,7 @@ public AjaxResult createServiceOrder(@RequestBody Map<String, Object> params, Ht
} else {
// 创建服务订单
String makeTime = orderParams.get("make_time") != null ? orderParams.get("make_time").toString() : "";
String fileData = orderParams.get("fileData") != null ? orderParams.get("fileData").toString() : "";
Order order = new Order();
order.setType(1); // 1:服务项目
order.setCreateType(1); // 1用户自主下单
@ -4710,6 +4713,7 @@ public AjaxResult createServiceOrder(@RequestBody Map<String, Object> params, Ht
order.setProductId(productId);
order.setProductName(serviceGoods.getTitle());
order.setName(userAddress.getName());
order.setFileData(fileData);
order.setPhone(userAddress.getPhone());
order.setAddress(userAddress.getAddressInfo());
order.setAddressId(addressId);
@ -5602,6 +5606,11 @@ public AjaxResult getWorkerOrderInfo(@PathVariable("id") Long id, HttpServletReq
data.put("phone_xx", order.getPhone()); // 可脱敏处理
data.put("user", user);
data.put("product", product);
if (order.getFileData() != null){
data.put("file_data", JSON.parseArray(order.getFileData()));
}else{
data.put("file_data", null);
}
data.put("log", logArr);
return AjaxResult.success(data);
} catch (Exception e) {
@ -7252,8 +7261,18 @@ public AjaxResult workerOrderEnd(@RequestBody Map<String, Object> params, HttpSe
moneyLog.setCr(Math.toIntExact(levelInfo != null ? levelInfo.getCr() : null));
moneyLog.setMergin(BigDecimal.ZERO);
moneyLog.setDoorPrice(price);
moneyLog.setCreatedAt(new Date());
moneyLog.setUpdatedAt(new Date());
moneyLog.setStatus(1);//锁单
moneyLog.setStatusType(0);//后台锁定
moneyLog.setBeginlook(new Date());
//7天锁单
LocalDateTime ldt = LocalDateTime.now().plusDays(7);
Date end = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
moneyLog.setEndlook(end);
moneyLog.setLookday(7);
moneyLog.setLookMoney(price);
// moneyLog.setCreatedAt(new Date());
// moneyLog.setUpdatedAt(new Date());
workerMoneyLogService.insertWorkerMoneyLog(moneyLog);
}
// 3.4 解绑虚拟号

View File

@ -17,6 +17,8 @@ import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@ -963,9 +965,19 @@ public class PayNotifyController extends BaseController {
moneyLog.setType(1); // 1=收入
moneyLog.setServicePrice(servicePrice);
moneyLog.setReductionPrice(reduction);
moneyLog.setCr(cr.multiply(new BigDecimal(100)).intValue()); // 百分比
int bfb=cr.multiply(new BigDecimal(100)).intValue();
moneyLog.setCr(bfb); // 百分比
moneyLog.setMergin(margin);
moneyLog.setDoorPrice(doorPrice);
moneyLog.setStatus(1);//锁单
moneyLog.setStatusType(0);//后台锁定
moneyLog.setBeginlook(new Date());
//7天锁单
LocalDateTime ldt = LocalDateTime.now().plusDays(7);
Date end = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
moneyLog.setEndlook(end);
moneyLog.setLookday(7);
moneyLog.setLookMoney(finalCommission);
workerMoneyLogService.insertWorkerMoneyLog(moneyLog);
logger.info("【分佣计算】插入师傅金额记录完成");

View File

@ -2,6 +2,17 @@ package com.ruoyi.system.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.ZoneId;
import java.util.Date;
import java.util.Map;
import java.math.BigDecimal;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.system.ControllerUtil.ScheduledTaskUtil;
import com.ruoyi.system.domain.Users;
import com.ruoyi.system.service.IUsersService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
@ -23,9 +34,9 @@ import com.ruoyi.common.core.page.TableDataInfo;
/**
* 师傅金额明细Controller
*
*
* @author ruoyi
* @date 2025-05-13
* @date 2025-06-25
*/
@RestController
@RequestMapping("/system/workerMoneyLog")
@ -34,6 +45,9 @@ public class WorkerMoneyLogController extends BaseController
@Autowired
private IWorkerMoneyLogService workerMoneyLogService;
@Autowired
private IUsersService usersService;
/**
* 查询师傅金额明细列表
*/
@ -41,8 +55,18 @@ public class WorkerMoneyLogController extends BaseController
@GetMapping("/list")
public TableDataInfo list(WorkerMoneyLog workerMoneyLog)
{
ScheduledTaskUtil taskUtil = SpringUtils.getBean(ScheduledTaskUtil.class);
taskUtil.healthCheck();
startPage();
List<WorkerMoneyLog> list = workerMoneyLogService.selectWorkerMoneyLogList(workerMoneyLog);
for(WorkerMoneyLog l: list){
Users users = usersService.selectUsersById(l.getWorkerId());
if (users != null){
l.setWorkerName(users.getName());
}
//list.get(i).setWorkerName(workerMoneyLogService.selectWorkerMoneyLogById(list.get(i).getId()).getWorkerName());
}
return getDataTable(list);
}
@ -96,9 +120,93 @@ public class WorkerMoneyLogController extends BaseController
*/
@PreAuthorize("@ss.hasPermi('system:workerMoneyLog:remove')")
@Log(title = "师傅金额明细", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Integer[] ids)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids)
{
return toAjax(workerMoneyLogService.deleteWorkerMoneyLogByIds(ids));
}
/**
* 批量锁住收益
* @param params {ids:[], lockType:'forever'|'timed', lockday:int}
* @return AjaxResult
*/
@PreAuthorize("@ss.hasPermi('system:workerMoneyLog:lock')")
@PostMapping("/lock")
public AjaxResult lockMoney(@RequestBody Map<String, Object> params) {
Object idsObj = params.get("ids");
if (idsObj == null) return AjaxResult.error("未选择数据");
List<Integer> ids = (List<Integer>) idsObj;
String lockType = (String) params.get("lockType");
Integer lockday = params.get("lockday") == null ? null : Integer.parseInt(params.get("lockday").toString());
Date now = new Date();
Date end = null;
if ("timed".equals(lockType) && lockday != null && lockday > 0) {
LocalDateTime ldt = LocalDateTime.now().plusDays(lockday);
end = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
}
for (Integer id : ids) {
WorkerMoneyLog log = workerMoneyLogService.selectWorkerMoneyLogById(id);
if (log == null) continue;
log.setStatus(1); // 锁定
log.setStatusType(1); // 后台锁定
log.setBeginlook(now);
if ("timed".equals(lockType) && end != null) {
log.setEndlook(end);
log.setLookday(lockday);
}
// else {
// // 永久锁住
//
// }
log.setLookMoney(log.getPrice());
workerMoneyLogService.updateWorkerMoneyLog(log);
if ("forever".equals(lockType)){
workerMoneyLogService.updateWorkerMoneyLogforever(log);
}
}
return AjaxResult.success("锁住收益成功");
}
/**
* 批量解锁收益
* @param params {ids:[]}
* @return AjaxResult
*/
@PreAuthorize("@ss.hasPermi('system:workerMoneyLog:unlock')")
@PostMapping("/unlock")
public AjaxResult unlockMoney(@RequestBody Map<String, Object> params) {
Object idsObj = params.get("ids");
if (idsObj == null) return AjaxResult.error("未选择数据");
List<Integer> ids = (List<Integer>) idsObj;
for (Integer id : ids) {
WorkerMoneyLog log = workerMoneyLogService.selectWorkerMoneyLogById(id);
if (log == null) continue;
log.setStatus(2); // 解锁
log.setLookMoney(BigDecimal.ZERO);
//log.setStatusType(null);
workerMoneyLogService.updateWorkerMoneyLog(log);
}
return AjaxResult.success("解锁收益成功");
}
/**
* 调整收益奖励/扣除
* @param params {id, amount, remark}
* @return AjaxResult
*/
@PreAuthorize("@ss.hasPermi('system:workerMoneyLog:adjust')")
@PostMapping("/adjust")
public AjaxResult adjustMoney(@RequestBody Map<String, Object> params) {
Integer id = params.get("id") instanceof Integer ? (Integer) params.get("id") : Integer.parseInt(params.get("id").toString());
WorkerMoneyLog log = workerMoneyLogService.selectWorkerMoneyLogById(id);
if (log == null) return AjaxResult.error("数据不存在");
if (log.getStatus() == null || log.getStatus() != 1) return AjaxResult.error("只能调整锁定状态的数据");
BigDecimal amount = new BigDecimal(params.get("amount").toString());
String remark = (String) params.get("remark");
log.setAdminUpPrice(amount);
log.setAdminUpReamk(remark);
workerMoneyLogService.updateWorkerMoneyLog(log);
return AjaxResult.success("调整收益成功");
}
}

View File

@ -1822,15 +1822,27 @@ public class AppletControllerUtil {
}
}
// 添加 tag 字段
String tag = "";
String tag = "优惠券";
if (coupons.getReceiveType() != null) {
String receiveType = String.valueOf(coupons.getReceiveType());
tag = switch (receiveType) {
case "1" -> "通用券";
case "2" -> "品类券";
case "3" -> "商品券";
default -> "优惠券";
};
if (receiveType.equals("1")) {
tag = "通用券";
}
if (receiveType.equals("2")) {
tag = "品类券";
}
if (receiveType.equals("3")) {
tag = "商品券";
}
// if (receiveType.equals("4")) {
// tag = "通用券";
// }
// tag = switch (receiveType) {
// case "1" -> "通用券";
// case "2" -> "品类券";
// case "3" -> "商品券";
// default -> "优惠券";
// };
}
couponData.put("suit_title", tag);
@ -2470,6 +2482,13 @@ public class AppletControllerUtil {
orderDetail.put("log_json", order.getLogJson());
orderDetail.put("json_status", order.getJsonStatus());
orderDetail.put("log_images", order.getLogImages());
// JSONArray jsonArray = new JSONArray();
if (order.getFileData() != null){
orderDetail.put("file_data", JSON.parseArray(order.getFileData()));
}else{
orderDetail.put("file_data", null);
}
// 4. 处理时间字段
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

View File

@ -5,8 +5,10 @@ import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.system.domain.Order;
import com.ruoyi.system.service.IOrderService;
import com.ruoyi.system.service.IWorkerMoneyLogService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@ -32,17 +34,22 @@ import java.util.concurrent.*;
* - 自动定时执行通过@Scheduled注解配置的定时任务会自动执行
* - 手动调用可直接调用相应的方法进行手动处理
* - 异步执行支持异步执行耗时任务不阻塞主线程
* - 项目启动时自动执行实现CommandLineRunner接口项目启动时自动调用run方法
*
* @author RuoYi
* @date 2024-01-01
*/
@Component
public class ScheduledTaskUtil {
public class ScheduledTaskUtil implements CommandLineRunner {
private static final Logger log = LoggerFactory.getLogger(ScheduledTaskUtil.class);
// 订单服务通过Spring工具类获取
private static IOrderService orderService;
// 订单服务通过Spring工具类获取
private static IWorkerMoneyLogService workerMoneyLogService;
// 线程池用于异步执行任务
private ThreadPoolExecutor executorService;
@ -91,8 +98,43 @@ public class ScheduledTaskUtil {
);
}
@Override
public void run(String... args) throws Exception {
log.info("项目启动,自动执行定时任务...");
handleDispatchTimeout();
checkOrderStatusTimeout();
cleanupSystemData();
healthCheck();
updateWorkerMoneyLook();
log.info("定时任务自动执行完成");
}
// ========================= 定时任务方法 =========================
/**
* 师傅收益7天定时冻结的解冻
* 每10分钟执行一次
*/
@Scheduled(fixedRate = 10 * 60 * 1000) // 每10分钟执行一次
public void updateWorkerMoneyLook() {
String taskName = "订单状态超时检查";
long startTime = System.currentTimeMillis();
try {
workerMoneyLogService=SpringUtils.getBean(IWorkerMoneyLogService.class);
workerMoneyLogService.updateWorkerMoneyLogStatusIfEndlookAfterNow();
} catch (Exception e) {
log.error("{}任务执行失败", taskName, e);
updateTaskStatistics(taskName, false, System.currentTimeMillis() - startTime);
}
}
/**
* 订单派单超时处理任务
* 每5分钟执行一次检查派单超过20分钟的订单
@ -106,30 +148,23 @@ public class ScheduledTaskUtil {
public void handleDispatchTimeout() {
String taskName = "订单派单超时处理";
long startTime = System.currentTimeMillis();
log.info("开始执行{}任务", taskName);
try {
log.info("开始执行{}任务", taskName);
// 获取派单超过20分钟的订单
List<Order> timeoutOrders = getDispatchTimeoutOrders();
if (timeoutOrders.isEmpty()) {
log.info("{}任务执行完成,无超时订单", taskName);
return;
}
log.info("发现{}个派单超时订单,开始处理", timeoutOrders.size());
// 异步处理超时订单
processTimeoutOrdersAsync(timeoutOrders);
// 更新任务统计
updateTaskStatistics(taskName, true, System.currentTimeMillis() - startTime);
} catch (Exception e) {
log.error("{}任务执行失败", taskName, e);
updateTaskStatistics(taskName, false, System.currentTimeMillis() - startTime);
}
log.info("{}任务执行完成,耗时{}毫秒", taskName, System.currentTimeMillis() - startTime);
}
/**
@ -208,6 +243,7 @@ public class ScheduledTaskUtil {
@Scheduled(fixedRate = 30 * 60 * 1000) // 每30分钟执行一次
public void healthCheck() {
String taskName = "系统健康检查";
log.info("开始执行{}任务", taskName);
long startTime = System.currentTimeMillis();
try {
@ -230,6 +266,18 @@ public class ScheduledTaskUtil {
}
}
/**
* 测试定时任务
* 每3秒执行一次打印测试信息
*
* 使用说明
* - 用于测试定时任务的执行情况
*/
@Scheduled(fixedRate = 3000) // 每3秒执行一次
public void testScheduledTask() {
log.info("测试定时任务执行中... 当前时间: {}", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
}
// ========================= 业务处理方法 =========================
/**

View File

@ -22,6 +22,7 @@ public class OrderApple extends BaseEntity {
private Long status;// 4
private String total_price;// "68.00"
private Integer type;// 1
private String fileData;
private Long uid;// : 302
public Long getUid() {
@ -143,4 +144,12 @@ public class OrderApple extends BaseEntity {
public void setCreated_at(Date created_at) {
this.created_at = created_at;
}
public String getFileData() {
return fileData;
}
public void setFileData(String fileData) {
this.fileData = fileData;
}
}

Some files were not shown because too many files have changed in this diff Show More