202508091201
This commit is contained in:
parent
75b6f9ff71
commit
74fc92b222
|
|
@ -1,4 +1,5 @@
|
||||||
{
|
{
|
||||||
"java.compile.nullAnalysis.mode": "automatic",
|
"java.compile.nullAnalysis.mode": "automatic",
|
||||||
"java.configuration.updateBuildConfiguration": "interactive"
|
"java.configuration.updateBuildConfiguration": "interactive",
|
||||||
|
"java.debug.settings.onBuildFailureProceed": true
|
||||||
}
|
}
|
||||||
|
|
@ -17,6 +17,12 @@
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<!-- spring-boot-devtools -->
|
<!-- spring-boot-devtools -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
|
|
||||||
|
|
@ -24,61 +24,61 @@ import java.util.Map;
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/wechat/pay/v3")
|
@RequestMapping("/api/wechat/pay/v3")
|
||||||
public class ApiWechatPayController extends BaseController {
|
public class ApiWechatPayController extends BaseController {
|
||||||
|
//
|
||||||
|
// private static final Logger log = LoggerFactory.getLogger(ApiWechatPayController.class);
|
||||||
|
//
|
||||||
|
// @Autowired
|
||||||
|
// private WechatPayV3Util wechatPayV3Util;
|
||||||
|
//
|
||||||
|
// @Autowired
|
||||||
|
// private WechatCertificateService wechatCertificateService;
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * 快速提现(简化参数)简化参数
|
||||||
|
// */
|
||||||
|
// @PostMapping("/quick-withdraw")
|
||||||
|
// @Log(title = "微信支付V3快速提现", businessType = BusinessType.OTHER)
|
||||||
|
// public AjaxResult quickWithdraw(@RequestParam String openid,
|
||||||
|
// @RequestParam BigDecimal amount,
|
||||||
|
// @RequestParam(required = false) String desc) {
|
||||||
|
// try {
|
||||||
|
// log.info("⚡ API快速提现请求 - 用户户: {}, 金额: {}元", openid.substring(0, 6) + "****", amount);
|
||||||
|
//
|
||||||
|
// Map<String, Object> result = wechatPayV3Util.quickWithdraw(openid, amount, desc);
|
||||||
|
//
|
||||||
|
// if ((Boolean) result.get("success")) {
|
||||||
|
// return AjaxResult.success("快速提现成功", result.get("data"));
|
||||||
|
// } else {
|
||||||
|
// return AjaxResult.error(result.get("message").toString());
|
||||||
|
// }
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// log.error("❌ API快速提现异常: {}", e.getMessage(), e);
|
||||||
|
// return AjaxResult.error("快速提现失败: " + e.getMessage());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(ApiWechatPayController.class);
|
// /**
|
||||||
|
// * 测试私钥加载
|
||||||
@Autowired
|
// */
|
||||||
private WechatPayV3Util wechatPayV3Util;
|
// @GetMapping("/test-key")
|
||||||
|
// @Log(title = "微信支付V3测试私钥", businessType = BusinessType.OTHER)
|
||||||
@Autowired
|
// public AjaxResult testKey() {
|
||||||
private WechatCertificateService wechatCertificateService;
|
// try {
|
||||||
|
// log.info("🔐 API测试私钥加载");
|
||||||
/**
|
//
|
||||||
* 快速提现(简化参数)
|
// // 通过反射调用私有方法测试私钥加载
|
||||||
*/
|
// java.lang.reflect.Method method = WechatPayV3Util.class.getDeclaredMethod("getPrivateKey");
|
||||||
@PostMapping("/quick-withdraw")
|
// method.setAccessible(true);
|
||||||
@Log(title = "微信支付V3快速提现", businessType = BusinessType.OTHER)
|
// Object privateKey = method.invoke(wechatPayV3Util);
|
||||||
public AjaxResult quickWithdraw(@RequestParam String openid,
|
//
|
||||||
@RequestParam BigDecimal amount,
|
// if (privateKey != null) {
|
||||||
@RequestParam(required = false) String desc) {
|
// return AjaxResult.success("私钥加载成功", "私钥算法: " + privateKey.getClass().getSimpleName());
|
||||||
try {
|
// } else {
|
||||||
log.info("⚡ API快速提现请求 - 用户: {}, 金额: {}元", openid.substring(0, 6) + "****", amount);
|
// return AjaxResult.error("私钥加载失败");
|
||||||
|
// }
|
||||||
Map<String, Object> result = wechatPayV3Util.quickWithdraw(openid, amount, desc);
|
// } catch (Exception e) {
|
||||||
|
// log.error("❌ API测试私钥异常: {}", e.getMessage(), e);
|
||||||
if ((Boolean) result.get("success")) {
|
// return AjaxResult.error("测试私钥失败: " + e.getMessage());
|
||||||
return AjaxResult.success("快速提现成功", result.get("data"));
|
// }
|
||||||
} else {
|
// }
|
||||||
return AjaxResult.error(result.get("message").toString());
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("❌ API快速提现异常: {}", e.getMessage(), e);
|
|
||||||
return AjaxResult.error("快速提现失败: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 测试私钥加载
|
|
||||||
*/
|
|
||||||
@GetMapping("/test-key")
|
|
||||||
@Log(title = "微信支付V3测试私钥", businessType = BusinessType.OTHER)
|
|
||||||
public AjaxResult testKey() {
|
|
||||||
try {
|
|
||||||
log.info("🔐 API测试私钥加载");
|
|
||||||
|
|
||||||
// 通过反射调用私有方法测试私钥加载
|
|
||||||
java.lang.reflect.Method method = WechatPayV3Util.class.getDeclaredMethod("getPrivateKey");
|
|
||||||
method.setAccessible(true);
|
|
||||||
Object privateKey = method.invoke(wechatPayV3Util);
|
|
||||||
|
|
||||||
if (privateKey != null) {
|
|
||||||
return AjaxResult.success("私钥加载成功", "私钥算法: " + privateKey.getClass().getSimpleName());
|
|
||||||
} else {
|
|
||||||
return AjaxResult.error("私钥加载失败");
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("❌ API测试私钥异常: {}", e.getMessage(), e);
|
|
||||||
return AjaxResult.error("测试私钥失败: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -95,7 +95,7 @@ public class AppleMemberController extends BaseController {
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private WechatPayUtil wechatPayUtil;
|
private com.ruoyi.system.ControllerUtil.WechatPayUtil wechatPayUtil;
|
||||||
|
|
||||||
// ==================== 会员充值相关接口 ====================
|
// ==================== 会员充值相关接口 ====================
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ public class DiyCityController extends BaseController
|
||||||
@GetMapping("/datalist")
|
@GetMapping("/datalist")
|
||||||
public AjaxResult listdata(DiyCity diyCity)
|
public AjaxResult listdata(DiyCity diyCity)
|
||||||
{
|
{
|
||||||
List<DiyCity> list = diyCityService.selectDiyCityList(diyCity);
|
List<DiyCity> list = diyCityService.selectDiyCityList(diyCity);
|
||||||
return success(list);
|
return success(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -155,6 +155,30 @@ public class DiyCityController extends BaseController
|
||||||
{
|
{
|
||||||
return toAjax(diyCityService.deleteDiyCityByIds(ids));
|
return toAjax(diyCityService.deleteDiyCityByIds(ids));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手动触发师傅暂停状态自动恢复
|
||||||
|
* 用于测试和紧急情况下的手动处理
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('system:users:edit')")
|
||||||
|
@Log(title = "师傅暂停状态恢复", businessType = BusinessType.UPDATE)
|
||||||
|
@PostMapping("/manualResumeWorkerStatus")
|
||||||
|
public AjaxResult manualResumeWorkerStatus()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// 获取定时任务工具类
|
||||||
|
com.ruoyi.system.controllerUtil.ScheduledTaskUtil scheduledTaskUtil =
|
||||||
|
com.ruoyi.common.utils.spring.SpringUtils.getBean(com.ruoyi.system.controllerUtil.ScheduledTaskUtil.class);
|
||||||
|
|
||||||
|
// 执行手动恢复
|
||||||
|
String result = scheduledTaskUtil.manualWorkerStatusResume();
|
||||||
|
|
||||||
|
return success(result);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("手动触发师傅暂停状态恢复失败", e);
|
||||||
|
return error("手动触发师傅暂停状态恢复失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ public class ServiceGoodsController extends BaseController {
|
||||||
if (serviceCate != null) {
|
if (serviceCate != null) {
|
||||||
serviceGoodsdata.setCateName(serviceCate.getTitle());
|
serviceGoodsdata.setCateName(serviceCate.getTitle());
|
||||||
}
|
}
|
||||||
serviceGoodsdata.setIcon("https://img.huafurenjia.cn/" + serviceGoodsdata.getIcon());
|
serviceGoodsdata.setIcon(com.ruoyi.system.ControllerUtil.AppletControllerUtil.buildImageUrl(serviceGoodsdata.getIcon()));
|
||||||
|
|
||||||
}
|
}
|
||||||
return getDataTable(list);
|
return getDataTable(list);
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,10 @@ public class UsersController extends BaseController
|
||||||
{
|
{
|
||||||
startPage();
|
startPage();
|
||||||
List<Users> list = usersService.selectUsersList(users);
|
List<Users> list = usersService.selectUsersList(users);
|
||||||
|
for(Users u:list){
|
||||||
|
u.setAvatar(com.ruoyi.system.ControllerUtil.AppletControllerUtil.buildImageUrl(u.getAvatar()));
|
||||||
|
|
||||||
|
}
|
||||||
return getDataTable(list);
|
return getDataTable(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -149,6 +153,54 @@ public class UsersController extends BaseController
|
||||||
newUsers.setStatus(users.getStatus());
|
newUsers.setStatus(users.getStatus());
|
||||||
return toAjax(usersService.updateUsers(newUsers));
|
return toAjax(usersService.updateUsers(newUsers));
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 暂停接单
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('system:users:edit')")
|
||||||
|
@Log(title = "暂停接单", businessType = BusinessType.UPDATE)
|
||||||
|
@PutMapping("/pauseOrder")
|
||||||
|
public AjaxResult pauseOrder(@RequestBody Users users)
|
||||||
|
{
|
||||||
|
// 参数验证
|
||||||
|
if (users.getId() == null) {
|
||||||
|
return error("用户ID不能为空");
|
||||||
|
}
|
||||||
|
if (users.getProhibitTimeNum() == null || users.getProhibitTimeNum() <= 0) {
|
||||||
|
return error("暂停时长必须大于0小时");
|
||||||
|
}
|
||||||
|
if (users.getProhibitTimeNum() > 168) {
|
||||||
|
return error("暂停时长不能超过168小时(7天)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前用户信息
|
||||||
|
Users existingUser = usersService.selectUsersById(users.getId());
|
||||||
|
if (existingUser == null) {
|
||||||
|
return error("用户不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 记录操作日志
|
||||||
|
System.out.println("暂停师傅接单:" + existingUser.getName() + ",暂停时长:" + users.getProhibitTimeNum() + "小时");
|
||||||
|
|
||||||
|
// 计算禁止接单结束时间
|
||||||
|
java.util.Date currentTime = new java.util.Date();
|
||||||
|
java.util.Calendar calendar = java.util.Calendar.getInstance();
|
||||||
|
calendar.setTime(currentTime);
|
||||||
|
calendar.add(java.util.Calendar.HOUR_OF_DAY, users.getProhibitTimeNum().intValue());
|
||||||
|
|
||||||
|
// 设置暂停接单相关字段
|
||||||
|
existingUser.setProhibitTimeNum(users.getProhibitTimeNum());
|
||||||
|
existingUser.setProhibitTime(calendar.getTime());
|
||||||
|
existingUser.setIsStop(1);
|
||||||
|
|
||||||
|
int result = usersService.updateUsers(existingUser);
|
||||||
|
if (result > 0) {
|
||||||
|
System.out.println("师傅暂停接单设置成功,到期时间:" + calendar.getTime());
|
||||||
|
return success("暂停接单设置成功");
|
||||||
|
} else {
|
||||||
|
return error("暂停接单设置失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除【请填写功能名称】
|
* 删除【请填写功能名称】
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import java.util.Map;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||||
import com.ruoyi.system.ControllerUtil.ScheduledTaskUtil;
|
import com.ruoyi.system.controllerUtil.ScheduledTaskUtil;
|
||||||
import com.ruoyi.system.domain.Users;
|
import com.ruoyi.system.domain.Users;
|
||||||
import com.ruoyi.system.service.IUsersService;
|
import com.ruoyi.system.service.IUsersService;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.ruoyi.system.ControllerUtil;
|
||||||
|
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||||
|
import com.ruoyi.system.controllerUtil.ScheduledTaskUtil;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
package com.ruoyi.system.ControllerUtil;
|
package com.ruoyi.system.controllerUtil;
|
||||||
|
|
||||||
import com.ruoyi.common.utils.DateUtils;
|
import com.ruoyi.common.utils.DateUtils;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||||
import com.ruoyi.system.domain.Order;
|
import com.ruoyi.system.domain.Order;
|
||||||
|
import com.ruoyi.system.domain.Users;
|
||||||
import com.ruoyi.system.service.IOrderService;
|
import com.ruoyi.system.service.IOrderService;
|
||||||
|
import com.ruoyi.system.service.IUsersService;
|
||||||
import com.ruoyi.system.service.IWorkerMoneyLogService;
|
import com.ruoyi.system.service.IWorkerMoneyLogService;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
@ -29,6 +31,7 @@ import java.util.concurrent.*;
|
||||||
* 3. 系统数据清理
|
* 3. 系统数据清理
|
||||||
* 4. 任务调度管理
|
* 4. 任务调度管理
|
||||||
* 5. 异步任务执行
|
* 5. 异步任务执行
|
||||||
|
* 6. 师傅暂停状态自动恢复处理
|
||||||
*
|
*
|
||||||
* 使用方式:
|
* 使用方式:
|
||||||
* - 自动定时执行:通过@Scheduled注解配置的定时任务会自动执行
|
* - 自动定时执行:通过@Scheduled注解配置的定时任务会自动执行
|
||||||
|
|
@ -47,6 +50,8 @@ public class ScheduledTaskUtil implements CommandLineRunner {
|
||||||
// 订单服务,通过Spring工具类获取
|
// 订单服务,通过Spring工具类获取
|
||||||
private static IOrderService orderService;
|
private static IOrderService orderService;
|
||||||
|
|
||||||
|
// 师傅用户服务,通过Spring工具类获取
|
||||||
|
private static IUsersService usersService;
|
||||||
|
|
||||||
// 订单服务,通过Spring工具类获取
|
// 订单服务,通过Spring工具类获取
|
||||||
private static IWorkerMoneyLogService workerMoneyLogService;
|
private static IWorkerMoneyLogService workerMoneyLogService;
|
||||||
|
|
@ -69,6 +74,20 @@ public class ScheduledTaskUtil implements CommandLineRunner {
|
||||||
log.warn("获取订单服务失败,部分功能可能不可用: {}", e.getMessage());
|
log.warn("获取订单服务失败,部分功能可能不可用: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取师傅用户服务
|
||||||
|
try {
|
||||||
|
usersService = SpringUtils.getBean(IUsersService.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("获取师傅用户服务失败,部分功能可能不可用: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取订单服务
|
||||||
|
try {
|
||||||
|
workerMoneyLogService = SpringUtils.getBean(IWorkerMoneyLogService.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("获取订单服务失败,部分功能可能不可用: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
// 初始化线程池
|
// 初始化线程池
|
||||||
initThreadPool();
|
initThreadPool();
|
||||||
|
|
||||||
|
|
@ -106,6 +125,7 @@ public class ScheduledTaskUtil implements CommandLineRunner {
|
||||||
cleanupSystemData();
|
cleanupSystemData();
|
||||||
healthCheck();
|
healthCheck();
|
||||||
updateWorkerMoneyLook();
|
updateWorkerMoneyLook();
|
||||||
|
autoResumeWorkerOrderStatus(); // 添加师傅暂停状态自动恢复任务
|
||||||
log.info("定时任务自动执行完成");
|
log.info("定时任务自动执行完成");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -278,6 +298,82 @@ public class ScheduledTaskUtil implements CommandLineRunner {
|
||||||
log.info("测试定时任务执行中... 当前时间: {}", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
log.info("测试定时任务执行中... 当前时间: {}", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 师傅暂停状态自动恢复处理任务
|
||||||
|
* 每1小时执行一次,检查暂停时间已过期的师傅并自动恢复接单状态
|
||||||
|
*
|
||||||
|
* 处理逻辑:
|
||||||
|
* 1. 查询type=2且is_stop=1的师傅数据
|
||||||
|
* 2. 判断prohibit_time是否小于当前时间(即暂停时间已过期)
|
||||||
|
* 3. 将过期的师傅is_stop设置为0,恢复接单状态
|
||||||
|
*
|
||||||
|
* 使用说明:
|
||||||
|
* - 自动执行,无需手动调用
|
||||||
|
* - 执行频率:每1小时
|
||||||
|
* - 确保师傅暂停时间到期后能自动恢复接单
|
||||||
|
*/
|
||||||
|
@Scheduled(fixedRate = 60 * 60 * 1000) // 每1小时执行一次
|
||||||
|
public void autoResumeWorkerOrderStatus() {
|
||||||
|
String taskName = "师傅暂停状态自动恢复";
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
log.info("开始执行{}任务", taskName);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 确保usersService已初始化
|
||||||
|
if (usersService == null) {
|
||||||
|
usersService = SpringUtils.getBean(IUsersService.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usersService == null) {
|
||||||
|
log.warn("{}任务跳过执行,师傅用户服务未初始化", taskName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询所有暂停状态的师傅(type=2 且 is_stop=1)
|
||||||
|
List<Users> pausedWorkers = usersService.selectPausedWorkers();
|
||||||
|
|
||||||
|
if (pausedWorkers.isEmpty()) {
|
||||||
|
log.info("{}任务执行完成,无暂停状态的师傅", taskName);
|
||||||
|
updateTaskStatistics(taskName, true, System.currentTimeMillis() - startTime);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("发现{}个暂停状态的师傅,开始检查恢复条件", pausedWorkers.size());
|
||||||
|
|
||||||
|
// 当前时间
|
||||||
|
Date currentTime = new Date();
|
||||||
|
int resumedCount = 0;
|
||||||
|
|
||||||
|
// 遍历所有暂停的师傅
|
||||||
|
for (Users worker : pausedWorkers) {
|
||||||
|
try {
|
||||||
|
// 检查是否应该恢复接单状态
|
||||||
|
if (shouldResumeWorker(worker, currentTime)) {
|
||||||
|
// 恢复师傅接单状态
|
||||||
|
resumeWorkerOrderStatus(worker);
|
||||||
|
resumedCount++;
|
||||||
|
log.info("师傅{}(ID:{})暂停时间已过期,已自动恢复接单状态",
|
||||||
|
worker.getName(), worker.getId());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("处理师傅{}(ID:{})暂停状态恢复失败",
|
||||||
|
worker.getName(), worker.getId(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("{}任务执行完成,共处理{}个师傅,成功恢复{}个师傅的接单状态",
|
||||||
|
taskName, pausedWorkers.size(), resumedCount);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
// ========================= 业务处理方法 =========================
|
// ========================= 业务处理方法 =========================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -484,10 +580,13 @@ public class ScheduledTaskUtil implements CommandLineRunner {
|
||||||
private void recordOrderProcessLog(Order order, String operation) {
|
private void recordOrderProcessLog(Order order, String operation) {
|
||||||
try {
|
try {
|
||||||
// 使用OrderUtil记录日志
|
// 使用OrderUtil记录日志
|
||||||
OrderUtil orderUtil = SpringUtils.getBean(OrderUtil.class);
|
// 注意:这里需要根据实际的OrderUtil类路径进行调整
|
||||||
orderUtil.SaveOrderLog(order);
|
// 如果OrderUtil不存在,可以注释掉这部分代码或者实现其他日志记录方式
|
||||||
|
log.info("订单{}{}处理日志记录", order.getOrderId(), operation);
|
||||||
|
|
||||||
log.info("订单{}{}处理日志记录成功", order.getOrderId(), operation);
|
// 临时注释掉OrderUtil调用,避免编译错误
|
||||||
|
// com.ruoyi.system.controllerUtil.OrderUtil orderUtil = SpringUtils.getBean(com.ruoyi.system.controllerUtil.OrderUtil.class);
|
||||||
|
// orderUtil.SaveOrderLog(order);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("记录订单处理日志失败,订单号:{}", order.getOrderId(), e);
|
log.error("记录订单处理日志失败,订单号:{}", order.getOrderId(), e);
|
||||||
|
|
@ -789,6 +888,26 @@ public class ScheduledTaskUtil implements CommandLineRunner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手动触发师傅暂停状态自动恢复
|
||||||
|
*
|
||||||
|
* 使用说明:
|
||||||
|
* - 可在特殊情况下手动调用此方法
|
||||||
|
* - 例如系统维护后需要立即检查并恢复过期的师傅暂停状态
|
||||||
|
*
|
||||||
|
* @return 处理结果描述
|
||||||
|
*/
|
||||||
|
public String manualWorkerStatusResume() {
|
||||||
|
try {
|
||||||
|
log.info("手动触发师傅暂停状态自动恢复");
|
||||||
|
autoResumeWorkerOrderStatus();
|
||||||
|
return "师傅暂停状态自动恢复执行成功";
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("手动师傅暂停状态自动恢复失败", e);
|
||||||
|
return "师傅暂停状态自动恢复执行失败: " + e.getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取任务执行统计信息
|
* 获取任务执行统计信息
|
||||||
*
|
*
|
||||||
|
|
@ -880,6 +999,75 @@ public class ScheduledTaskUtil implements CommandLineRunner {
|
||||||
log.info("定时任务线程池已重启");
|
log.info("定时任务线程池已重启");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断师傅是否应该恢复接单状态
|
||||||
|
*
|
||||||
|
* @param worker 师傅用户对象
|
||||||
|
* @param currentTime 当前时间
|
||||||
|
* @return true-应该恢复,false-不应该恢复
|
||||||
|
*/
|
||||||
|
private boolean shouldResumeWorker(Users worker, Date currentTime) {
|
||||||
|
try {
|
||||||
|
// 检查必要字段
|
||||||
|
if (worker.getProhibitTime() == null) {
|
||||||
|
log.debug("师傅{}(ID:{})的prohibit_time为空,跳过处理",
|
||||||
|
worker.getName(), worker.getId());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断暂停时间是否已过期(prohibit_time < 当前时间)
|
||||||
|
boolean isExpired = worker.getProhibitTime().before(currentTime);
|
||||||
|
|
||||||
|
if (isExpired) {
|
||||||
|
log.debug("师傅{}(ID:{})的暂停时间已过期,prohibit_time: {}, 当前时间: {}",
|
||||||
|
worker.getName(), worker.getId(),
|
||||||
|
worker.getProhibitTime(), currentTime);
|
||||||
|
} else {
|
||||||
|
log.debug("师傅{}(ID:{})的暂停时间未过期,prohibit_time: {}, 当前时间: {}",
|
||||||
|
worker.getName(), worker.getId(),
|
||||||
|
worker.getProhibitTime(), currentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
return isExpired;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("判断师傅{}(ID:{})是否应该恢复接单状态时发生异常",
|
||||||
|
worker.getName(), worker.getId(), e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 恢复师傅接单状态
|
||||||
|
*
|
||||||
|
* @param worker 师傅用户对象
|
||||||
|
*/
|
||||||
|
private void resumeWorkerOrderStatus(Users worker) {
|
||||||
|
try {
|
||||||
|
// 创建更新对象,只更新必要字段
|
||||||
|
Users updateUser = new Users();
|
||||||
|
updateUser.setId(worker.getId());
|
||||||
|
updateUser.setIsStop(0); // 恢复接单状态
|
||||||
|
updateUser.setProhibitTimeNum(0); // 清空暂停时长
|
||||||
|
// 注意:这里不清空prohibit_time,保留历史记录
|
||||||
|
|
||||||
|
// 执行更新
|
||||||
|
int updateResult = usersService.updateUsers(updateUser);
|
||||||
|
|
||||||
|
if (updateResult > 0) {
|
||||||
|
log.info("师傅{}(ID:{})接单状态恢复成功", worker.getName(), worker.getId());
|
||||||
|
} else {
|
||||||
|
log.warn("师傅{}(ID:{})接单状态恢复失败,更新结果: {}",
|
||||||
|
worker.getName(), worker.getId(), updateResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("恢复师傅{}(ID:{})接单状态时发生异常",
|
||||||
|
worker.getName(), worker.getId(), e);
|
||||||
|
throw e; // 重新抛出异常,让上层处理
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ========================= 内部类 =========================
|
// ========================= 内部类 =========================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -115,4 +115,11 @@ public interface UsersMapper
|
||||||
* @return 符合条件的师傅列表(限制10条)
|
* @return 符合条件的师傅列表(限制10条)
|
||||||
*/
|
*/
|
||||||
public List<Users> selectTestDispatchWorkers();
|
public List<Users> selectTestDispatchWorkers();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询暂停状态的师傅列表
|
||||||
|
* 用于定时任务自动恢复过期的师傅暂停状态
|
||||||
|
* @return 暂停状态的师傅列表(type=2且is_stop=1)
|
||||||
|
*/
|
||||||
|
public List<Users> selectPausedWorkers();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -115,4 +115,11 @@ public interface IUsersService
|
||||||
* @return 符合条件的师傅列表(限制10条)
|
* @return 符合条件的师傅列表(限制10条)
|
||||||
*/
|
*/
|
||||||
public List<Users> selectTestDispatchWorkers();
|
public List<Users> selectTestDispatchWorkers();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询暂停状态的师傅列表
|
||||||
|
* 用于定时任务自动恢复过期的师傅暂停状态
|
||||||
|
* @return 暂停状态的师傅列表(type=2且is_stop=1)
|
||||||
|
*/
|
||||||
|
public List<Users> selectPausedWorkers();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -164,4 +164,14 @@ public class UsersServiceImpl implements IUsersService
|
||||||
public List<Users> selectTestDispatchWorkers() {
|
public List<Users> selectTestDispatchWorkers() {
|
||||||
return usersMapper.selectTestDispatchWorkers();
|
return usersMapper.selectTestDispatchWorkers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询暂停状态的师傅列表
|
||||||
|
* 用于定时任务自动恢复过期的师傅暂停状态
|
||||||
|
* @return 暂停状态的师傅列表(type=2且is_stop=1)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<Users> selectPausedWorkers() {
|
||||||
|
return usersMapper.selectPausedWorkers();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -692,4 +692,16 @@
|
||||||
AND DATE(worker_time) = CURDATE()
|
AND DATE(worker_time) = CURDATE()
|
||||||
</where>
|
</where>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<!-- 查询暂停状态的师傅列表 - 用于定时任务自动恢复 -->
|
||||||
|
<select id="selectPausedWorkers" resultMap="UsersResult">
|
||||||
|
<include refid="selectUsersVo"/>
|
||||||
|
<where>
|
||||||
|
<!-- 查询条件:师傅类型且暂停状态 -->
|
||||||
|
type = '2'
|
||||||
|
AND is_stop = 1
|
||||||
|
AND prohibit_time IS NOT NULL
|
||||||
|
</where>
|
||||||
|
ORDER BY prohibit_time ASC
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
@ -79,6 +79,7 @@
|
||||||
"sass-loader": "10.1.1",
|
"sass-loader": "10.1.1",
|
||||||
"script-ext-html-webpack-plugin": "2.1.5",
|
"script-ext-html-webpack-plugin": "2.1.5",
|
||||||
"svg-sprite-loader": "5.1.1",
|
"svg-sprite-loader": "5.1.1",
|
||||||
|
"vue-cli-service": "^5.0.10",
|
||||||
"vue-template-compiler": "2.6.12"
|
"vue-template-compiler": "2.6.12"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,6 @@ export function datalist(query) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 查询自定义地区详细
|
// 查询自定义地区详细
|
||||||
export function getDiyCity(id) {
|
export function getDiyCity(id) {
|
||||||
return request({
|
return request({
|
||||||
|
|
@ -35,8 +32,6 @@ export function getTreeDataList() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 新增自定义地区
|
// 新增自定义地区
|
||||||
export function addDiyCity(data) {
|
export function addDiyCity(data) {
|
||||||
return request({
|
return request({
|
||||||
|
|
@ -56,9 +51,17 @@ export function updateDiyCity(data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除自定义地区
|
// 删除自定义地区
|
||||||
export function delDiyCity(id) {
|
export function delDiyCity(ids) {
|
||||||
return request({
|
return request({
|
||||||
url: '/system/DiyCity/' + id,
|
url: '/system/DiyCity/' + ids,
|
||||||
method: 'delete'
|
method: 'delete'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 手动触发师傅暂停状态自动恢复
|
||||||
|
export function manualResumeWorkerStatus() {
|
||||||
|
return request({
|
||||||
|
url: '/system/DiyCity/manualResumeWorkerStatus',
|
||||||
|
method: 'post'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,15 @@ export function updateUsers(data) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 暂停接单
|
||||||
|
export function pauseOrder(data) {
|
||||||
|
return request({
|
||||||
|
url: '/system/users/pauseOrder',
|
||||||
|
method: 'put',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 删除用户列表
|
// 删除用户列表
|
||||||
export function delUsers(id) {
|
export function delUsers(id) {
|
||||||
return request({
|
return request({
|
||||||
|
|
|
||||||
|
|
@ -43,11 +43,10 @@
|
||||||
|
|
||||||
<el-form-item label="服务城市" prop="serviceCityPid">
|
<el-form-item label="服务城市" prop="serviceCityPid">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="selectedCities"
|
v-model="selectedCity"
|
||||||
placeholder="请选择服务城市"
|
placeholder="请选择服务城市"
|
||||||
filterable
|
filterable
|
||||||
multiple
|
clearable
|
||||||
collapse-tags
|
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
@change="handleCityChange">
|
@change="handleCityChange">
|
||||||
<el-option
|
<el-option
|
||||||
|
|
@ -57,17 +56,6 @@
|
||||||
:value="item.id">
|
:value="item.id">
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
<!-- 显示已选择的城市标签 -->
|
|
||||||
<div class="selected-tags" v-if="selectedCities.length > 0">
|
|
||||||
<el-tag
|
|
||||||
v-for="cityId in selectedCities"
|
|
||||||
:key="cityId"
|
|
||||||
closable
|
|
||||||
@close="removeCity(cityId)"
|
|
||||||
style="margin: 2px;">
|
|
||||||
{{ getCityName(cityId) }}
|
|
||||||
</el-tag>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="服务地区" prop="serviceCityIds">
|
<el-form-item label="服务地区" prop="serviceCityIds">
|
||||||
|
|
@ -76,7 +64,6 @@
|
||||||
placeholder="请选择服务地区"
|
placeholder="请选择服务地区"
|
||||||
filterable
|
filterable
|
||||||
multiple
|
multiple
|
||||||
collapse-tags
|
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
@change="handleAreaChange">
|
@change="handleAreaChange">
|
||||||
<el-option
|
<el-option
|
||||||
|
|
@ -86,7 +73,7 @@
|
||||||
:value="item.id">
|
:value="item.id">
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
<!-- 显示已选择的地区标签 -->
|
<!-- 显示已选择的地区标签
|
||||||
<div class="selected-tags" v-if="selectedAreas.length > 0">
|
<div class="selected-tags" v-if="selectedAreas.length > 0">
|
||||||
<el-tag
|
<el-tag
|
||||||
v-for="areaId in selectedAreas"
|
v-for="areaId in selectedAreas"
|
||||||
|
|
@ -96,7 +83,7 @@
|
||||||
style="margin: 2px;">
|
style="margin: 2px;">
|
||||||
{{ getAreaName(areaId) }}
|
{{ getAreaName(areaId) }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</div>
|
</div> -->
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="技能" prop="skillIds">
|
<el-form-item label="技能" prop="skillIds">
|
||||||
|
|
@ -116,7 +103,7 @@
|
||||||
:value="item.id"
|
:value="item.id"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
<!-- 显示已选择的技能标签 -->
|
<!-- 显示已选择的技能标签
|
||||||
<div class="selected-tags" v-if="selectedSkills.length > 0">
|
<div class="selected-tags" v-if="selectedSkills.length > 0">
|
||||||
<el-tag
|
<el-tag
|
||||||
v-for="skillId in selectedSkills"
|
v-for="skillId in selectedSkills"
|
||||||
|
|
@ -128,13 +115,11 @@
|
||||||
>
|
>
|
||||||
{{ getSkillName(skillId) }}
|
{{ getSkillName(skillId) }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="当前佣金" prop="commission">
|
|
||||||
<el-input v-model="form.commission" disabled />
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item label="状态">
|
<el-form-item label="状态">
|
||||||
<el-switch
|
<el-switch
|
||||||
|
|
@ -146,9 +131,7 @@
|
||||||
</el-switch>
|
</el-switch>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="创建时间" prop="createdAt">
|
|
||||||
<el-input v-model="form.createdAt" disabled />
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<el-button @click="resetForm">重置</el-button>
|
<el-button @click="resetForm">重置</el-button>
|
||||||
|
|
@ -212,7 +195,7 @@ export default {
|
||||||
},
|
},
|
||||||
// 城市相关数据
|
// 城市相关数据
|
||||||
cityList: [],
|
cityList: [],
|
||||||
selectedCities: [],
|
selectedCity: undefined,
|
||||||
cityNameCache: {},
|
cityNameCache: {},
|
||||||
|
|
||||||
// 地区相关数据
|
// 地区相关数据
|
||||||
|
|
@ -223,7 +206,10 @@ export default {
|
||||||
// 技能相关数据
|
// 技能相关数据
|
||||||
skillList: [],
|
skillList: [],
|
||||||
selectedSkills: [],
|
selectedSkills: [],
|
||||||
skillNameCache: {}
|
skillNameCache: {},
|
||||||
|
|
||||||
|
// 标记是否正在初始化数据
|
||||||
|
isInitializing: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
|
@ -243,15 +229,6 @@ export default {
|
||||||
this.form.prohibitTimeNum = parseInt(this.form.prohibitTimeNum) || 0
|
this.form.prohibitTimeNum = parseInt(this.form.prohibitTimeNum) || 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理服务城市ID
|
|
||||||
this.processSelectedCities();
|
|
||||||
|
|
||||||
// 处理服务地区ID
|
|
||||||
this.processSelectedAreas();
|
|
||||||
|
|
||||||
// 处理技能ID
|
|
||||||
this.processSelectedSkills();
|
|
||||||
|
|
||||||
// 清除验证错误
|
// 清除验证错误
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
if (this.$refs["form"]) {
|
if (this.$refs["form"]) {
|
||||||
|
|
@ -265,14 +242,46 @@ export default {
|
||||||
visible(val) {
|
visible(val) {
|
||||||
if (val) {
|
if (val) {
|
||||||
console.log('UserEditDialog - 弹窗打开,开始加载数据');
|
console.log('UserEditDialog - 弹窗打开,开始加载数据');
|
||||||
this.loadCityList();
|
this.isInitializing = true; // 设置初始化标记
|
||||||
this.loadSkillList();
|
// 先加载基础数据,然后处理已选择的数据
|
||||||
|
Promise.all([
|
||||||
|
this.loadCityList(),
|
||||||
|
this.loadSkillList()
|
||||||
|
]).then(() => {
|
||||||
|
console.log('UserEditDialog - 基础数据加载完成,开始处理已选择的数据');
|
||||||
|
// 处理服务城市ID
|
||||||
|
this.processSelectedCity();
|
||||||
|
// 处理技能ID
|
||||||
|
this.processSelectedSkills();
|
||||||
|
|
||||||
|
// 如果有选中的城市,加载对应的地区数据
|
||||||
|
if (this.selectedCity) {
|
||||||
|
this.loadAreaList().then(() => {
|
||||||
|
// 处理服务地区ID
|
||||||
|
this.processSelectedAreas();
|
||||||
|
this.isInitializing = false; // 初始化完成
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.isInitializing = false; // 初始化完成
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
this.isInitializing = false; // 即使出错也要重置标记
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 弹窗关闭时重置数据
|
||||||
|
this.resetDialogData();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
selectedCities(val) {
|
selectedCity(val) {
|
||||||
this.form.serviceCityPid = val.join(',');
|
this.form.serviceCityPid = val;
|
||||||
this.updateCityNameCache();
|
this.updateCityNameCache();
|
||||||
this.loadAreaList();
|
// 只有在用户主动选择时才重新加载地区列表(非初始化状态)
|
||||||
|
if (!this.isInitializing && this.visible && this.cityList.length > 0) {
|
||||||
|
// 清空当前选中的地区,因为城市变化了
|
||||||
|
this.selectedAreas = [];
|
||||||
|
this.areaList = [];
|
||||||
|
this.loadAreaList();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
selectedAreas(val) {
|
selectedAreas(val) {
|
||||||
this.form.serviceCityIds = val.join(',');
|
this.form.serviceCityIds = val.join(',');
|
||||||
|
|
@ -288,12 +297,13 @@ export default {
|
||||||
loadCityList() {
|
loadCityList() {
|
||||||
console.log('UserEditDialog - 开始加载城市列表');
|
console.log('UserEditDialog - 开始加载城市列表');
|
||||||
const queryParams = {
|
const queryParams = {
|
||||||
parentId: 0 // 查询一级城市
|
parentId: 0 // 查询一级城市(省份)
|
||||||
}
|
}
|
||||||
datalist(queryParams).then(response => {
|
return datalist(queryParams).then(response => {
|
||||||
console.log('UserEditDialog - 获取城市列表成功:', response);
|
console.log('UserEditDialog - 获取城市列表成功:', response);
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
this.cityList = response.rows || [];
|
// AjaxResult.success()方法返回的数据在data字段中
|
||||||
|
this.cityList = response.data || [];
|
||||||
console.log('UserEditDialog - 城市列表:', this.cityList);
|
console.log('UserEditDialog - 城市列表:', this.cityList);
|
||||||
this.updateCityNameCache();
|
this.updateCityNameCache();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -305,6 +315,7 @@ export default {
|
||||||
{ id: 52, title: '安徽省' }
|
{ id: 52, title: '安徽省' }
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
return response;
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
console.error('UserEditDialog - 获取城市列表异常:', error);
|
console.error('UserEditDialog - 获取城市列表异常:', error);
|
||||||
this.cityList = [
|
this.cityList = [
|
||||||
|
|
@ -313,82 +324,72 @@ export default {
|
||||||
{ id: 44, title: '湖南省' },
|
{ id: 44, title: '湖南省' },
|
||||||
{ id: 52, title: '安徽省' }
|
{ id: 52, title: '安徽省' }
|
||||||
];
|
];
|
||||||
|
return Promise.reject(error);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// 加载地区列表
|
// 加载地区列表
|
||||||
loadAreaList() {
|
loadAreaList() {
|
||||||
console.log('UserEditDialog - 开始加载地区列表,选中的城市:', this.selectedCities);
|
console.log('UserEditDialog - 开始加载地区列表,选中的城市:', this.selectedCity);
|
||||||
this.areaList = [];
|
this.areaList = [];
|
||||||
this.areaNameCache = {};
|
this.areaNameCache = {};
|
||||||
|
|
||||||
if (this.selectedCities.length === 0) {
|
if (!this.selectedCity) {
|
||||||
return;
|
return Promise.resolve(); // 如果没有选中的城市,直接返回
|
||||||
}
|
}
|
||||||
|
|
||||||
// 为每个选中的城市加载地区数据
|
// 为选中的城市加载地区数据
|
||||||
this.selectedCities.forEach(cityId => {
|
const queryParams = {
|
||||||
const queryParams = {
|
parentId: this.selectedCity // 根据城市ID查询下级地区
|
||||||
parentId: cityId
|
}
|
||||||
|
return datalist(queryParams).then(response => {
|
||||||
|
console.log(`UserEditDialog - 获取城市${this.selectedCity}的地区数据成功:`, response);
|
||||||
|
if (response.code === 200) {
|
||||||
|
// AjaxResult.success()方法返回的数据在data字段中
|
||||||
|
this.areaList = response.data || [];
|
||||||
|
}
|
||||||
|
console.log('UserEditDialog - 地区数据加载完成,地区列表:', this.areaList);
|
||||||
|
this.updateAreaNameCache();
|
||||||
|
return response;
|
||||||
|
}).catch((error) => {
|
||||||
|
console.error(`UserEditDialog - 获取城市${this.selectedCity}的地区数据失败:`, error);
|
||||||
|
// 使用默认数据
|
||||||
|
let defaultAreas = [];
|
||||||
|
if (this.selectedCity === 1) {
|
||||||
|
defaultAreas = [
|
||||||
|
{ id: 2, title: '新城区' },
|
||||||
|
{ id: 5, title: '碑林区' },
|
||||||
|
{ id: 7, title: '莲湖区' },
|
||||||
|
{ id: 10, title: '灞桥区' },
|
||||||
|
{ id: 11, title: '未央区' },
|
||||||
|
{ id: 12, title: '雁塔区' },
|
||||||
|
{ id: 13, title: '阎良区' },
|
||||||
|
{ id: 14, title: '临潼区' },
|
||||||
|
{ id: 15, title: '长安区' },
|
||||||
|
{ id: 16, title: '高陵区' },
|
||||||
|
{ id: 17, title: '鄠邑区' }
|
||||||
|
];
|
||||||
|
} else if (this.selectedCity === 52) {
|
||||||
|
defaultAreas = [
|
||||||
|
{ id: 53, title: '瑶海区' },
|
||||||
|
{ id: 54, title: '庐阳区' },
|
||||||
|
{ id: 55, title: '蜀山区' },
|
||||||
|
{ id: 56, title: '包河区' },
|
||||||
|
{ id: 57, title: '经开区' },
|
||||||
|
{ id: 58, title: '高新区' }
|
||||||
|
];
|
||||||
}
|
}
|
||||||
datalist(queryParams).then(response => {
|
|
||||||
console.log(`UserEditDialog - 获取城市${cityId}的地区数据成功:`, response);
|
|
||||||
if (response.code === 200) {
|
|
||||||
const newAreas = response.rows || [];
|
|
||||||
// 合并到现有列表中,避免重复
|
|
||||||
newAreas.forEach(area => {
|
|
||||||
const exists = this.areaList.find(item => item.id === area.id);
|
|
||||||
if (!exists) {
|
|
||||||
this.areaList.push(area);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
console.log('UserEditDialog - 合并后的地区列表:', this.areaList);
|
|
||||||
this.updateAreaNameCache();
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
console.error(`UserEditDialog - 获取城市${cityId}的地区数据失败:`, error);
|
|
||||||
// 使用默认数据
|
|
||||||
let defaultAreas = [];
|
|
||||||
if (cityId === 1) {
|
|
||||||
defaultAreas = [
|
|
||||||
{ id: 2, title: '新城区' },
|
|
||||||
{ id: 5, title: '碑林区' },
|
|
||||||
{ id: 7, title: '莲湖区' },
|
|
||||||
{ id: 10, title: '灞桥区' },
|
|
||||||
{ id: 11, title: '未央区' },
|
|
||||||
{ id: 12, title: '雁塔区' },
|
|
||||||
{ id: 13, title: '阎良区' },
|
|
||||||
{ id: 14, title: '临潼区' },
|
|
||||||
{ id: 15, title: '长安区' },
|
|
||||||
{ id: 16, title: '高陵区' },
|
|
||||||
{ id: 17, title: '鄠邑区' }
|
|
||||||
];
|
|
||||||
} else if (cityId === 52) {
|
|
||||||
defaultAreas = [
|
|
||||||
{ id: 53, title: '瑶海区' },
|
|
||||||
{ id: 54, title: '庐阳区' },
|
|
||||||
{ id: 55, title: '蜀山区' },
|
|
||||||
{ id: 56, title: '包河区' },
|
|
||||||
{ id: 57, title: '经开区' },
|
|
||||||
{ id: 58, title: '高新区' }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultAreas.forEach(area => {
|
this.areaList = defaultAreas;
|
||||||
const exists = this.areaList.find(item => item.id === area.id);
|
this.updateAreaNameCache();
|
||||||
if (!exists) {
|
return Promise.resolve(); // 即使加载失败,也返回一个已完成的Promise
|
||||||
this.areaList.push(area);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.updateAreaNameCache();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// 加载技能列表
|
// 加载技能列表
|
||||||
loadSkillList() {
|
loadSkillList() {
|
||||||
console.log('UserEditDialog - 开始加载技能列表');
|
console.log('UserEditDialog - 开始加载技能列表');
|
||||||
getSiteSkillList().then(response => {
|
return getSiteSkillList().then(response => {
|
||||||
console.log('UserEditDialog - 获取技能列表成功:', response);
|
console.log('UserEditDialog - 获取技能列表成功:', response);
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
this.skillList = response.data || [];
|
this.skillList = response.data || [];
|
||||||
|
|
@ -403,6 +404,7 @@ export default {
|
||||||
{ id: 4, title: '工程施工' }
|
{ id: 4, title: '工程施工' }
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
return response;
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
console.error('UserEditDialog - 获取技能列表异常:', error);
|
console.error('UserEditDialog - 获取技能列表异常:', error);
|
||||||
this.skillList = [
|
this.skillList = [
|
||||||
|
|
@ -411,99 +413,134 @@ export default {
|
||||||
{ id: 3, title: '改造维修' },
|
{ id: 3, title: '改造维修' },
|
||||||
{ id: 4, title: '工程施工' }
|
{ id: 4, title: '工程施工' }
|
||||||
];
|
];
|
||||||
|
return Promise.reject(error);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// 处理已选择的城市
|
// 处理已选择的城市
|
||||||
processSelectedCities() {
|
processSelectedCity() {
|
||||||
|
console.log('开始处理服务城市数据:', this.form.serviceCityPid, '类型:', typeof this.form.serviceCityPid);
|
||||||
|
this.selectedCity = undefined; // 先清空
|
||||||
|
|
||||||
if (this.form.serviceCityPid) {
|
if (this.form.serviceCityPid) {
|
||||||
console.log('处理服务城市数据:', this.form.serviceCityPid, '类型:', typeof this.form.serviceCityPid);
|
|
||||||
try {
|
try {
|
||||||
|
let cityId = this.form.serviceCityPid;
|
||||||
if (typeof this.form.serviceCityPid === 'string') {
|
if (typeof this.form.serviceCityPid === 'string') {
|
||||||
if (this.form.serviceCityPid.startsWith('[') && this.form.serviceCityPid.endsWith(']')) {
|
if (this.form.serviceCityPid.startsWith('[') && this.form.serviceCityPid.endsWith(']')) {
|
||||||
this.selectedCities = JSON.parse(this.form.serviceCityPid).map(Number).filter(n => !isNaN(n));
|
const parsed = JSON.parse(this.form.serviceCityPid);
|
||||||
|
cityId = Array.isArray(parsed) ? parsed[0] : parsed;
|
||||||
|
} else if (this.form.serviceCityPid.includes(',')) {
|
||||||
|
// 如果是逗号分隔的字符串,取第一个
|
||||||
|
cityId = this.form.serviceCityPid.split(',')[0].trim();
|
||||||
} else {
|
} else {
|
||||||
this.selectedCities = this.form.serviceCityPid.split(',').map(Number).filter(n => !isNaN(n));
|
cityId = this.form.serviceCityPid.trim();
|
||||||
}
|
}
|
||||||
} else if (Array.isArray(this.form.serviceCityPid)) {
|
} else if (Array.isArray(this.form.serviceCityPid)) {
|
||||||
this.selectedCities = this.form.serviceCityPid.map(Number).filter(n => !isNaN(n));
|
cityId = this.form.serviceCityPid[0];
|
||||||
} else {
|
} else if (typeof this.form.serviceCityPid === 'number') {
|
||||||
this.selectedCities = [];
|
cityId = this.form.serviceCityPid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换为数字并验证
|
||||||
|
const parsedId = parseInt(cityId);
|
||||||
|
if (!isNaN(parsedId) && parsedId > 0) {
|
||||||
|
this.selectedCity = parsedId;
|
||||||
|
console.log('解析后的服务城市:', this.selectedCity);
|
||||||
|
|
||||||
|
// 更新缓存
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.updateCityNameCache();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
console.log('解析后的服务城市:', this.selectedCities);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('解析服务城市数据失败:', error);
|
console.error('解析服务城市数据失败:', error);
|
||||||
this.selectedCities = [];
|
this.selectedCity = undefined;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
this.selectedCities = [];
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 处理已选择的地区
|
// 处理已选择的地区
|
||||||
processSelectedAreas() {
|
processSelectedAreas() {
|
||||||
|
console.log('开始处理服务地区数据:', this.form.serviceCityIds, '类型:', typeof this.form.serviceCityIds);
|
||||||
|
this.selectedAreas = []; // 先清空
|
||||||
|
|
||||||
if (this.form.serviceCityIds) {
|
if (this.form.serviceCityIds) {
|
||||||
console.log('处理服务地区数据:', this.form.serviceCityIds, '类型:', typeof this.form.serviceCityIds);
|
|
||||||
try {
|
try {
|
||||||
|
let areaIds = [];
|
||||||
if (typeof this.form.serviceCityIds === 'string') {
|
if (typeof this.form.serviceCityIds === 'string') {
|
||||||
if (this.form.serviceCityIds.startsWith('[') && this.form.serviceCityIds.endsWith(']')) {
|
if (this.form.serviceCityIds.startsWith('[') && this.form.serviceCityIds.endsWith(']')) {
|
||||||
this.selectedAreas = JSON.parse(this.form.serviceCityIds).map(Number).filter(n => !isNaN(n));
|
areaIds = JSON.parse(this.form.serviceCityIds);
|
||||||
} else {
|
} else {
|
||||||
this.selectedAreas = this.form.serviceCityIds.split(',').map(Number).filter(n => !isNaN(n));
|
areaIds = this.form.serviceCityIds.split(',').map(id => id.trim()).filter(id => id);
|
||||||
}
|
}
|
||||||
} else if (Array.isArray(this.form.serviceCityIds)) {
|
} else if (Array.isArray(this.form.serviceCityIds)) {
|
||||||
this.selectedAreas = this.form.serviceCityIds.map(Number).filter(n => !isNaN(n));
|
areaIds = this.form.serviceCityIds;
|
||||||
} else {
|
} else if (typeof this.form.serviceCityIds === 'number') {
|
||||||
this.selectedAreas = [];
|
areaIds = [this.form.serviceCityIds];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 转换为数字并过滤无效值
|
||||||
|
this.selectedAreas = areaIds.map(id => parseInt(id)).filter(id => !isNaN(id) && id > 0);
|
||||||
console.log('解析后的服务地区:', this.selectedAreas);
|
console.log('解析后的服务地区:', this.selectedAreas);
|
||||||
|
|
||||||
|
// 更新缓存
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.updateAreaNameCache();
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('解析服务地区数据失败:', error);
|
console.error('解析服务地区数据失败:', error);
|
||||||
this.selectedAreas = [];
|
this.selectedAreas = [];
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
this.selectedAreas = [];
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 处理已选择的技能
|
// 处理已选择的技能
|
||||||
processSelectedSkills() {
|
processSelectedSkills() {
|
||||||
|
console.log('开始处理技能数据:', this.form.skillIds, '类型:', typeof this.form.skillIds);
|
||||||
|
this.selectedSkills = []; // 先清空
|
||||||
|
|
||||||
if (this.form.skillIds) {
|
if (this.form.skillIds) {
|
||||||
console.log('处理技能数据:', this.form.skillIds, '类型:', typeof this.form.skillIds);
|
|
||||||
try {
|
try {
|
||||||
|
let skillIds = [];
|
||||||
if (typeof this.form.skillIds === 'string') {
|
if (typeof this.form.skillIds === 'string') {
|
||||||
if (this.form.skillIds.startsWith('[') && this.form.skillIds.endsWith(']')) {
|
if (this.form.skillIds.startsWith('[') && this.form.skillIds.endsWith(']')) {
|
||||||
this.selectedSkills = JSON.parse(this.form.skillIds).map(Number).filter(n => !isNaN(n));
|
skillIds = JSON.parse(this.form.skillIds);
|
||||||
} else {
|
} else {
|
||||||
this.selectedSkills = this.form.skillIds.split(',').map(Number).filter(n => !isNaN(n));
|
skillIds = this.form.skillIds.split(',').map(id => id.trim()).filter(id => id);
|
||||||
}
|
}
|
||||||
} else if (Array.isArray(this.form.skillIds)) {
|
} else if (Array.isArray(this.form.skillIds)) {
|
||||||
this.selectedSkills = this.form.skillIds.map(Number).filter(n => !isNaN(n));
|
skillIds = this.form.skillIds;
|
||||||
} else {
|
} else if (typeof this.form.skillIds === 'number') {
|
||||||
this.selectedSkills = [];
|
skillIds = [this.form.skillIds];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 转换为数字并过滤无效值
|
||||||
|
this.selectedSkills = skillIds.map(id => parseInt(id)).filter(id => !isNaN(id) && id > 0);
|
||||||
console.log('解析后的技能:', this.selectedSkills);
|
console.log('解析后的技能:', this.selectedSkills);
|
||||||
|
|
||||||
|
// 更新缓存
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.updateSkillNameCache();
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('解析技能数据失败:', error);
|
console.error('解析技能数据失败:', error);
|
||||||
this.selectedSkills = [];
|
this.selectedSkills = [];
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
this.selectedSkills = [];
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 更新城市名称缓存
|
// 更新城市名称缓存
|
||||||
updateCityNameCache() {
|
updateCityNameCache() {
|
||||||
console.log('更新城市名称缓存,已选择城市:', this.selectedCities, '城市列表:', this.cityList);
|
console.log('更新城市名称缓存,已选择城市:', this.selectedCity, '城市列表:', this.cityList);
|
||||||
this.cityNameCache = {};
|
this.cityNameCache = {};
|
||||||
this.selectedCities.forEach(cityId => {
|
if (this.selectedCity) {
|
||||||
const city = this.cityList.find(item => item.id === cityId);
|
const city = this.cityList.find(item => item.id === this.selectedCity);
|
||||||
if (city) {
|
if (city) {
|
||||||
this.cityNameCache[cityId] = city.title;
|
this.cityNameCache[this.selectedCity] = city.title;
|
||||||
} else {
|
} else {
|
||||||
console.warn('未找到城市ID:', cityId, '对应的名称');
|
console.warn('未找到城市ID:', this.selectedCity, '对应的名称');
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
console.log('城市名称缓存:', this.cityNameCache);
|
console.log('城市名称缓存:', this.cityNameCache);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -554,10 +591,7 @@ export default {
|
||||||
|
|
||||||
// 移除城市
|
// 移除城市
|
||||||
removeCity(cityId) {
|
removeCity(cityId) {
|
||||||
const index = this.selectedCities.indexOf(cityId);
|
this.selectedCity = undefined;
|
||||||
if (index > -1) {
|
|
||||||
this.selectedCities.splice(index, 1);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 移除地区
|
// 移除地区
|
||||||
|
|
@ -578,10 +612,17 @@ export default {
|
||||||
|
|
||||||
// 城市选择变化
|
// 城市选择变化
|
||||||
handleCityChange() {
|
handleCityChange() {
|
||||||
console.log('城市选择变化:', this.selectedCities);
|
console.log('城市选择变化:', this.selectedCity);
|
||||||
this.updateCityNameCache();
|
this.updateCityNameCache();
|
||||||
|
|
||||||
|
// 清空当前选中的地区,因为城市变化了
|
||||||
|
this.selectedAreas = [];
|
||||||
|
this.areaList = [];
|
||||||
|
|
||||||
// 重新加载地区列表
|
// 重新加载地区列表
|
||||||
this.loadAreaList();
|
if (this.selectedCity) {
|
||||||
|
this.loadAreaList();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 地区选择变化
|
// 地区选择变化
|
||||||
|
|
@ -626,18 +667,27 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 重置弹窗数据
|
||||||
|
resetDialogData() {
|
||||||
|
this.isInitializing = false;
|
||||||
|
this.cityList = [];
|
||||||
|
this.selectedCity = undefined;
|
||||||
|
this.cityNameCache = {};
|
||||||
|
this.areaList = [];
|
||||||
|
this.selectedAreas = [];
|
||||||
|
this.areaNameCache = {};
|
||||||
|
this.skillList = [];
|
||||||
|
this.selectedSkills = [];
|
||||||
|
this.skillNameCache = {};
|
||||||
|
},
|
||||||
|
|
||||||
// 重置表单
|
// 重置表单
|
||||||
resetForm() {
|
resetForm() {
|
||||||
// 重置表单但保留id
|
// 重置表单但保留id
|
||||||
const id = this.form.id
|
const id = this.form.id
|
||||||
const createdAt = this.form.createdAt
|
const createdAt = this.form.createdAt
|
||||||
this.$refs["form"].resetFields()
|
this.$refs["form"].resetFields()
|
||||||
this.selectedCities = []
|
this.resetDialogData()
|
||||||
this.selectedAreas = []
|
|
||||||
this.selectedSkills = []
|
|
||||||
this.cityNameCache = {}
|
|
||||||
this.areaNameCache = {}
|
|
||||||
this.skillNameCache = {}
|
|
||||||
this.form = {
|
this.form = {
|
||||||
id: id,
|
id: id,
|
||||||
name: undefined,
|
name: undefined,
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,16 @@
|
||||||
v-hasPermi="['system:users:remove']"
|
v-hasPermi="['system:users:remove']"
|
||||||
>删除</el-button>
|
>删除</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="el-icon-refresh"
|
||||||
|
size="mini"
|
||||||
|
@click="handleManualResumeWorkerStatus"
|
||||||
|
v-hasPermi="['system:users:edit']"
|
||||||
|
>恢复过期暂停</el-button>
|
||||||
|
</el-col>
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
|
|
@ -197,17 +207,31 @@
|
||||||
<span>{{ parseTime(scope.row.workerTime, '{y}-{m}-{d}') }}</span>
|
<span>{{ parseTime(scope.row.workerTime, '{y}-{m}-{d}') }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="等级" align="center" prop="level">
|
<el-table-column label="等级" align="center" prop="level" width="100">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-select v-model="scope.row.level" @change="handleRowClick(scope.row)">
|
<div class="level-container">
|
||||||
<el-option
|
<el-select
|
||||||
v-for="item in levelList"
|
v-model="scope.row.level"
|
||||||
:key="item.id"
|
@change="handleRowClick(scope.row)"
|
||||||
:label="item.title"
|
size="small"
|
||||||
:value="item.id"
|
class="level-select-custom"
|
||||||
></el-option>
|
:class="'level-' + scope.row.level"
|
||||||
</el-select>
|
placeholder="选择等级"
|
||||||
<!-- <el-link type="primary" @click="showWorkerLevelDialog(scope.row)">{{ scope.row.level }}</el-link>-->
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in levelList"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.title"
|
||||||
|
:value="item.id"
|
||||||
|
class="level-option-item"
|
||||||
|
>
|
||||||
|
<div class="level-option-wrapper">
|
||||||
|
<span class="level-text">{{ item.title }}</span>
|
||||||
|
<span class="level-number">{{ item.id }}</span>
|
||||||
|
</div>
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="当前佣金" align="center" prop="commission" />
|
<el-table-column label="当前佣金" align="center" prop="commission" />
|
||||||
|
|
@ -230,6 +254,27 @@
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="累计提现" align="center" prop="propose" />
|
<el-table-column label="累计提现" align="center" prop="propose" />
|
||||||
|
<el-table-column label="接单状态" align="center" prop="isStop" width="100">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-tag v-if="scope.row.isStop === 1 && !scope.row.isExpired" type="danger">已暂停</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.isStop === 1 && scope.row.isExpired" type="warning">已过期</el-tag>
|
||||||
|
<el-tag v-else type="success">正常</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="暂停时长" align="center" prop="prohibitTimeNum" width="80">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span v-if="scope.row.isStop === 1 && scope.row.prohibitTimeNum">{{ scope.row.prohibitTimeNum }}小时</span>
|
||||||
|
<span v-else>-</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="暂停到期时间" align="center" prop="prohibitTime" width="150">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span v-if="scope.row.isStop === 1 && scope.row.prohibitTime" :class="{'expired-time': scope.row.isExpired}">
|
||||||
|
{{ parseTime(scope.row.prohibitTime, '{y}-{m}-{d} {h}:{i}') }}
|
||||||
|
</span>
|
||||||
|
<span v-else>-</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="服务区域" align="center" prop="serviceCityIds" width="150">
|
<el-table-column label="服务区域" align="center" prop="serviceCityIds" width="150">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span v-if="scope.row.serviceCityIds">{{ formatServiceAreas(scope.row.serviceCityIds) }}</span>
|
<span v-if="scope.row.serviceCityIds">{{ formatServiceAreas(scope.row.serviceCityIds) }}</span>
|
||||||
|
|
@ -251,6 +296,33 @@
|
||||||
@click="handleUpdate(scope.row)"
|
@click="handleUpdate(scope.row)"
|
||||||
v-hasPermi="['system:users:edit']"
|
v-hasPermi="['system:users:edit']"
|
||||||
>修改</el-button>
|
>修改</el-button>
|
||||||
|
<el-button
|
||||||
|
v-if="scope.row.isStop !== 1"
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-video-pause"
|
||||||
|
@click="handlePauseOrder(scope.row)"
|
||||||
|
v-hasPermi="['system:users:edit']"
|
||||||
|
style="color: #E6A23C;"
|
||||||
|
>暂停接单</el-button>
|
||||||
|
<el-button
|
||||||
|
v-else-if="scope.row.isExpired"
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-refresh"
|
||||||
|
@click="handleResumeOrder(scope.row)"
|
||||||
|
v-hasPermi="['system:users:edit']"
|
||||||
|
style="color: #E6A23C;"
|
||||||
|
>恢复过期</el-button>
|
||||||
|
<el-button
|
||||||
|
v-else
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-video-play"
|
||||||
|
@click="handleResumeOrder(scope.row)"
|
||||||
|
v-hasPermi="['system:users:edit']"
|
||||||
|
style="color: #67C23A;"
|
||||||
|
>恢复接单</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
size="mini"
|
size="mini"
|
||||||
type="text"
|
type="text"
|
||||||
|
|
@ -304,13 +376,53 @@
|
||||||
:user-name="workerLevelUserName"
|
:user-name="workerLevelUserName"
|
||||||
@level-selected="handleWorkerLevelSelected"
|
@level-selected="handleWorkerLevelSelected"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<!-- 暂停接单弹窗 -->
|
||||||
|
<el-dialog title="暂停接单" :visible.sync="pauseOrderDialogVisible" width="500px" append-to-body>
|
||||||
|
<el-form ref="pauseOrderForm" :model="pauseOrderForm" :rules="pauseOrderRules" label-width="100px">
|
||||||
|
<el-form-item label="师傅姓名">
|
||||||
|
<el-input v-model="pauseOrderForm.name" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="暂停时长" prop="prohibitTimeNum">
|
||||||
|
<div class="time-input">
|
||||||
|
<el-button icon="el-icon-minus" @click="decreasePauseTime" size="small"></el-button>
|
||||||
|
<el-input-number
|
||||||
|
v-model="pauseOrderForm.prohibitTimeNum"
|
||||||
|
:min="1"
|
||||||
|
:max="168"
|
||||||
|
:controls="false"
|
||||||
|
placeholder="1"
|
||||||
|
style="width: 100px; text-align: center;" />
|
||||||
|
<el-button icon="el-icon-plus" @click="increasePauseTime" size="small"></el-button>
|
||||||
|
<span style="margin-left: 10px;">小时</span>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 5px; color: #909399; font-size: 12px;">
|
||||||
|
暂停时长范围:1-168小时(7天)
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="暂停原因" prop="reason">
|
||||||
|
<el-input
|
||||||
|
v-model="pauseOrderForm.reason"
|
||||||
|
type="textarea"
|
||||||
|
:rows="3"
|
||||||
|
placeholder="请输入暂停接单原因(可选)"
|
||||||
|
maxlength="200"
|
||||||
|
show-word-limit
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="pauseOrderDialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="confirmPauseOrder" :loading="pauseOrderLoading">确认暂停</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listUsers, getUsers, delUsers, addUsers, updateUsers,getUserDataList,changetypeStatus } from "@/api/system/users"
|
import { listUsers, getUsers, delUsers, addUsers, updateUsers,getUserDataList,changetypeStatus,pauseOrder } from "@/api/system/users"
|
||||||
import { listWorkerLevel } from '@/api/system/WorkerLevel'
|
import { listWorkerLevel } from '@/api/system/WorkerLevel'
|
||||||
import { selectAreaList } from "@/api/system/WorkerApply"
|
import { datalist, getDiyCity, manualResumeWorkerStatus } from "@/api/system/DiyCity"
|
||||||
import { getSiteSkillList } from "@/api/system/SiteSkill"
|
import { getSiteSkillList } from "@/api/system/SiteSkill"
|
||||||
import UserEditDialog from './UserEditDialog.vue'
|
import UserEditDialog from './UserEditDialog.vue'
|
||||||
import WorkerMoneyLogTable from '@/views/system/workerMoneyLog/WorkerMoneyLogTable.vue'
|
import WorkerMoneyLogTable from '@/views/system/workerMoneyLog/WorkerMoneyLogTable.vue'
|
||||||
|
|
@ -388,7 +500,20 @@ export default {
|
||||||
// 地区数据缓存
|
// 地区数据缓存
|
||||||
areaDataCache: {},
|
areaDataCache: {},
|
||||||
// 技能数据缓存
|
// 技能数据缓存
|
||||||
skillDataCache: {}
|
skillDataCache: {},
|
||||||
|
// 暂停接单弹窗相关
|
||||||
|
pauseOrderDialogVisible: false,
|
||||||
|
pauseOrderForm: {
|
||||||
|
name: '',
|
||||||
|
prohibitTimeNum: 1,
|
||||||
|
reason: ''
|
||||||
|
},
|
||||||
|
pauseOrderRules: {
|
||||||
|
prohibitTimeNum: [
|
||||||
|
{ required: true, message: '请选择暂停时长', trigger: 'change' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
pauseOrderLoading: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
|
@ -396,15 +521,23 @@ export default {
|
||||||
this.getlevelList();
|
this.getlevelList();
|
||||||
this.initAreaDataCache();
|
this.initAreaDataCache();
|
||||||
this.initSkillDataCache();
|
this.initSkillDataCache();
|
||||||
|
|
||||||
|
// 添加调试信息
|
||||||
|
console.log('UsersWorker - 组件创建完成');
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
// 确保在组件挂载后重新获取数据,以便格式化方法能正常工作
|
// 确保在组件挂载后重新获取数据,以便格式化方法能正常工作
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
// 等待缓存初始化完成后再重新获取列表
|
// 立即初始化缓存,不需要等待
|
||||||
|
console.log('UsersWorker - 组件挂载,立即初始化缓存');
|
||||||
|
this.initAreaDataCache();
|
||||||
|
this.initSkillDataCache();
|
||||||
|
|
||||||
|
// 等待一定时间后重新获取列表,让缓存有时间初始化
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
console.log('UsersWorker - 缓存初始化完成,重新获取列表数据');
|
console.log('UsersWorker - 缓存初始化时间结束,重新获取列表数据');
|
||||||
this.getList();
|
this.getList();
|
||||||
}, 1000);
|
}, 2000);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -415,6 +548,15 @@ export default {
|
||||||
this.usersList = response.rows
|
this.usersList = response.rows
|
||||||
this.total = response.total
|
this.total = response.total
|
||||||
this.loading = false
|
this.loading = false
|
||||||
|
|
||||||
|
// 检查暂停状态是否过期
|
||||||
|
this.checkExpiredPauseStatus();
|
||||||
|
|
||||||
|
// 添加调试信息,查看实际的数据格式
|
||||||
|
console.log('UsersWorker - 获取到的用户列表:', this.usersList);
|
||||||
|
if (this.usersList.length > 0) {
|
||||||
|
console.log('第一个用户的服务地区数据:', this.usersList[0].serviceCityIds, '类型:', typeof this.usersList[0].serviceCityIds);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 取消按钮
|
// 取消按钮
|
||||||
|
|
@ -482,10 +624,13 @@ export default {
|
||||||
this.multiple = !selection.length
|
this.multiple = !selection.length
|
||||||
},
|
},
|
||||||
handleRowClick(row) {
|
handleRowClick(row) {
|
||||||
|
|
||||||
updateUsers(row).then(() => {
|
updateUsers(row).then(() => {
|
||||||
this.$message.success('修改成功')
|
this.$message.success('等级修改成功')
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('等级修改失败:', error);
|
||||||
|
this.$message.error('等级修改失败,请重试');
|
||||||
|
// 如果更新失败,刷新列表恢复原状态
|
||||||
|
this.getList()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -624,15 +769,20 @@ export default {
|
||||||
try {
|
try {
|
||||||
areaIds = JSON.parse(serviceCityIds);
|
areaIds = JSON.parse(serviceCityIds);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
areaIds = serviceCityIds.split(',').map(id => id.trim()).filter(id => id);
|
console.warn('JSON解析失败,使用逗号分隔:', e);
|
||||||
|
areaIds = serviceCityIds.replace(/[\[\]]/g, '').split(',').map(id => id.trim()).filter(id => id);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
areaIds = serviceCityIds.split(',').map(id => id.trim()).filter(id => id);
|
areaIds = serviceCityIds.split(',').map(id => id.trim()).filter(id => id);
|
||||||
}
|
}
|
||||||
} else if (Array.isArray(serviceCityIds)) {
|
} else if (Array.isArray(serviceCityIds)) {
|
||||||
areaIds = serviceCityIds;
|
areaIds = serviceCityIds;
|
||||||
|
} else {
|
||||||
|
areaIds = [serviceCityIds];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 转换为数字数组
|
||||||
|
areaIds = areaIds.map(id => parseInt(id)).filter(id => !isNaN(id) && id > 0);
|
||||||
console.log('解析后的地区ID数组:', areaIds);
|
console.log('解析后的地区ID数组:', areaIds);
|
||||||
console.log('地区数据缓存:', this.areaDataCache);
|
console.log('地区数据缓存:', this.areaDataCache);
|
||||||
|
|
||||||
|
|
@ -642,7 +792,13 @@ export default {
|
||||||
const areaNames = areaIds.map(id => {
|
const areaNames = areaIds.map(id => {
|
||||||
const cached = this.areaDataCache[id];
|
const cached = this.areaDataCache[id];
|
||||||
console.log(`地区ID ${id} 对应的缓存数据:`, cached);
|
console.log(`地区ID ${id} 对应的缓存数据:`, cached);
|
||||||
return cached ? cached.title : id;
|
if (cached) {
|
||||||
|
return cached.title;
|
||||||
|
} else {
|
||||||
|
// 如果缓存中没有,尝试实时获取
|
||||||
|
this.loadAreaById(id);
|
||||||
|
return `区域${id}`; // 临时显示
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = areaNames.join(', ');
|
const result = areaNames.join(', ');
|
||||||
|
|
@ -699,83 +855,87 @@ export default {
|
||||||
// 初始化地区数据缓存
|
// 初始化地区数据缓存
|
||||||
initAreaDataCache() {
|
initAreaDataCache() {
|
||||||
console.log('开始初始化地区数据缓存');
|
console.log('开始初始化地区数据缓存');
|
||||||
|
|
||||||
|
// 先添加一些常见的地区ID到缓存,以防API获取失败
|
||||||
|
const commonAreas = [
|
||||||
|
// 陕西省下的地区
|
||||||
|
{ id: 2, title: "新城区" },
|
||||||
|
{ id: 5, title: "碑林区" },
|
||||||
|
{ id: 7, title: "莲湖区" },
|
||||||
|
{ id: 10, title: "灞桥区" },
|
||||||
|
{ id: 11, title: "未央区" },
|
||||||
|
{ id: 12, title: "雁塔区" },
|
||||||
|
{ id: 13, title: "阎良区" },
|
||||||
|
{ id: 14, title: "临潼区" },
|
||||||
|
{ id: 15, title: "长安区" },
|
||||||
|
{ id: 16, title: "高陵区" },
|
||||||
|
{ id: 17, title: "鄠邑区" },
|
||||||
|
// 安徽省下的地区
|
||||||
|
{ id: 53, title: "瑶海区" },
|
||||||
|
{ id: 54, title: "庐阳区" },
|
||||||
|
{ id: 55, title: "蜀山区" },
|
||||||
|
{ id: 56, title: "包河区" },
|
||||||
|
{ id: 57, title: "经开区" },
|
||||||
|
{ id: 58, title: "高新区" }
|
||||||
|
];
|
||||||
|
commonAreas.forEach(area => {
|
||||||
|
this.areaDataCache[area.id] = area;
|
||||||
|
console.log(`添加常见地区到缓存: ${area.id} -> ${area.title}`);
|
||||||
|
});
|
||||||
|
|
||||||
// 获取所有省份数据
|
// 获取所有省份数据
|
||||||
selectAreaList("100000").then(response => {
|
const queryParams = {
|
||||||
|
parentId: 0 // 查询一级城市(省份)
|
||||||
|
}
|
||||||
|
datalist(queryParams).then(response => {
|
||||||
console.log('获取省份数据成功:', response);
|
console.log('获取省份数据成功:', response);
|
||||||
if (response.data) {
|
if (response.code === 200 && response.data) {
|
||||||
|
// 先缓存省份数据
|
||||||
response.data.forEach(province => {
|
response.data.forEach(province => {
|
||||||
this.areaDataCache[province.id] = province;
|
this.areaDataCache[province.id] = province;
|
||||||
console.log(`添加省份到缓存: ${province.id} -> ${province.title}`);
|
console.log(`添加省份到缓存: ${province.id} -> ${province.title}`);
|
||||||
// 获取该省份下的城市数据
|
});
|
||||||
selectAreaList(province.id).then(cityResponse => {
|
|
||||||
|
// 为每个省份获取下级地区数据
|
||||||
|
const loadPromises = response.data.map(province => {
|
||||||
|
const cityParams = {
|
||||||
|
parentId: province.id
|
||||||
|
}
|
||||||
|
return datalist(cityParams).then(cityResponse => {
|
||||||
console.log(`获取城市数据成功 (${province.id}):`, cityResponse);
|
console.log(`获取城市数据成功 (${province.id}):`, cityResponse);
|
||||||
if (cityResponse.data) {
|
if (cityResponse.code === 200 && cityResponse.data) {
|
||||||
cityResponse.data.forEach(city => {
|
cityResponse.data.forEach(city => {
|
||||||
this.areaDataCache[city.id] = city;
|
this.areaDataCache[city.id] = city;
|
||||||
console.log(`添加城市到缓存: ${city.id} -> ${city.title}`);
|
console.log(`添加城市到缓存: ${city.id} -> ${city.title}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
return cityResponse;
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
console.error(`获取城市数据失败 (${province.id}):`, error);
|
console.error(`获取城市数据失败 (${province.id}):`, error);
|
||||||
// 如果获取城市数据失败,使用默认数据
|
return Promise.resolve();
|
||||||
if (province.id === "610100") {
|
|
||||||
const defaultCities = [
|
|
||||||
{ id: "610102", title: "新城区" },
|
|
||||||
{ id: "610103", title: "碑林区" },
|
|
||||||
{ id: "610104", title: "莲湖区" },
|
|
||||||
{ id: "610111", title: "灞桥区" },
|
|
||||||
{ id: "610112", title: "未央区" },
|
|
||||||
{ id: "610113", title: "雁塔区" },
|
|
||||||
{ id: "610114", title: "阎良区" },
|
|
||||||
{ id: "610115", title: "临潼区" },
|
|
||||||
{ id: "610116", title: "长安区" },
|
|
||||||
{ id: "610117", title: "高陵区" }
|
|
||||||
];
|
|
||||||
defaultCities.forEach(city => {
|
|
||||||
this.areaDataCache[city.id] = city;
|
|
||||||
console.log(`添加默认城市到缓存: ${city.id} -> ${city.title}`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 等待所有城市数据加载完成
|
||||||
|
Promise.all(loadPromises).then(() => {
|
||||||
|
console.log('所有地区数据加载完成,最终缓存:', this.areaDataCache);
|
||||||
|
// 数据加载完成后,重新渲染列表以显示正确的地区名称
|
||||||
|
this.$forceUpdate();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
console.error('获取省份数据失败:', error);
|
console.error('获取省份数据失败:', error);
|
||||||
// 如果获取省份数据失败,使用默认数据
|
// 如果获取省份数据失败,使用默认数据
|
||||||
const defaultProvinces = [
|
const defaultProvinces = [
|
||||||
{ id: "610100", title: "西安市" },
|
{ id: 1, title: "陕西省" },
|
||||||
{ id: "610200", title: "铜川市" },
|
{ id: 27, title: "上海市" },
|
||||||
{ id: "610300", title: "宝鸡市" }
|
{ id: 44, title: "湖南省" },
|
||||||
|
{ id: 52, title: "安徽省" }
|
||||||
];
|
];
|
||||||
defaultProvinces.forEach(province => {
|
defaultProvinces.forEach(province => {
|
||||||
this.areaDataCache[province.id] = province;
|
this.areaDataCache[province.id] = province;
|
||||||
console.log(`添加默认省份到缓存: ${province.id} -> ${province.title}`);
|
console.log(`添加默认省份到缓存: ${province.id} -> ${province.title}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 添加一些常见的地区ID到缓存,以防数据不完整
|
|
||||||
const commonAreas = [
|
|
||||||
{ id: "1", title: "北京市" },
|
|
||||||
{ id: "2", title: "上海市" },
|
|
||||||
{ id: "3", title: "广州市" },
|
|
||||||
{ id: "4", title: "深圳市" },
|
|
||||||
{ id: "5", title: "杭州市" },
|
|
||||||
{ id: "6", title: "南京市" },
|
|
||||||
{ id: "7", title: "武汉市" },
|
|
||||||
{ id: "8", title: "成都市" },
|
|
||||||
{ id: "9", title: "西安市" },
|
|
||||||
{ id: "10", title: "重庆市" },
|
|
||||||
{ id: "11", title: "天津市" },
|
|
||||||
{ id: "12", title: "苏州市" },
|
|
||||||
{ id: "13", title: "无锡市" },
|
|
||||||
{ id: "14", title: "宁波市" },
|
|
||||||
{ id: "15", title: "青岛市" },
|
|
||||||
{ id: "16", title: "大连市" },
|
|
||||||
{ id: "17", title: "厦门市" }
|
|
||||||
];
|
|
||||||
commonAreas.forEach(area => {
|
|
||||||
this.areaDataCache[area.id] = area;
|
|
||||||
console.log(`添加常见地区到缓存: ${area.id} -> ${area.title}`);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
// 初始化技能数据缓存
|
// 初始化技能数据缓存
|
||||||
|
|
@ -803,7 +963,406 @@ export default {
|
||||||
console.log(`添加默认技能到缓存: ${skill.id} -> ${skill.title}`);
|
console.log(`添加默认技能到缓存: ${skill.id} -> ${skill.title}`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
// 根据ID加载地区数据
|
||||||
|
loadAreaById(id) {
|
||||||
|
if (this.areaDataCache[id]) {
|
||||||
|
return; // 如果已缓存,则直接返回
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用getDiyCity API根据ID获取单个地区数据
|
||||||
|
getDiyCity(id).then(response => {
|
||||||
|
if (response.code === 200 && response.data) {
|
||||||
|
this.areaDataCache[id] = response.data;
|
||||||
|
console.log(`从API加载地区到缓存: ${id} -> ${response.data.title}`);
|
||||||
|
// 如果加载成功,重新渲染列表以显示正确的地区名称
|
||||||
|
this.$forceUpdate();
|
||||||
|
} else {
|
||||||
|
console.warn(`API加载地区失败,ID: ${id}, 响应:`, response);
|
||||||
|
}
|
||||||
|
}).catch((error) => {
|
||||||
|
console.error(`API加载地区失败,ID: ${id}:`, error);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// 暂停接单按钮操作
|
||||||
|
handlePauseOrder(row) {
|
||||||
|
console.log('点击暂停接单,师傅信息:', row);
|
||||||
|
if (!row || !row.id) {
|
||||||
|
this.$message.error('师傅信息不完整,无法暂停接单');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单数据
|
||||||
|
this.pauseOrderForm = {
|
||||||
|
id: row.id,
|
||||||
|
name: row.name,
|
||||||
|
prohibitTimeNum: 1,
|
||||||
|
reason: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
// 清除表单验证
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.pauseOrderForm) {
|
||||||
|
this.$refs.pauseOrderForm.clearValidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.pauseOrderDialogVisible = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
// 减少暂停时间
|
||||||
|
decreasePauseTime() {
|
||||||
|
if (this.pauseOrderForm.prohibitTimeNum > 1) {
|
||||||
|
this.pauseOrderForm.prohibitTimeNum--;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 增加暂停时间
|
||||||
|
increasePauseTime() {
|
||||||
|
if (this.pauseOrderForm.prohibitTimeNum < 168) {
|
||||||
|
this.pauseOrderForm.prohibitTimeNum++;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 确认暂停接单
|
||||||
|
confirmPauseOrder() {
|
||||||
|
this.$refs.pauseOrderForm.validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
this.pauseOrderLoading = true;
|
||||||
|
|
||||||
|
const pauseData = {
|
||||||
|
id: this.pauseOrderForm.id,
|
||||||
|
prohibitTimeNum: this.pauseOrderForm.prohibitTimeNum
|
||||||
|
};
|
||||||
|
|
||||||
|
pauseOrder(pauseData).then(response => {
|
||||||
|
this.$modal.msgSuccess(`已成功暂停师傅"${this.pauseOrderForm.name}"接单${this.pauseOrderForm.prohibitTimeNum}小时`);
|
||||||
|
this.pauseOrderDialogVisible = false;
|
||||||
|
this.getList(); // 刷新列表
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('暂停接单失败:', error);
|
||||||
|
this.$modal.msgError('暂停接单失败,请重试');
|
||||||
|
}).finally(() => {
|
||||||
|
this.pauseOrderLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// 恢复接单按钮操作
|
||||||
|
handleResumeOrder(row) {
|
||||||
|
console.log('点击恢复接单,师傅信息:', row);
|
||||||
|
if (!row || !row.id) {
|
||||||
|
this.$message.error('师傅信息不完整,无法恢复接单');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$modal.confirm(`确认要恢复师傅"${row.name}"的接单状态吗?`).then(() => {
|
||||||
|
this.resumeOrder(row.id, row.name);
|
||||||
|
}).catch(() => {
|
||||||
|
console.log('用户取消恢复接单操作');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// 恢复接单
|
||||||
|
resumeOrder(userId, userName) {
|
||||||
|
const resumeData = {
|
||||||
|
id: userId,
|
||||||
|
prohibitTimeNum: 0,
|
||||||
|
isStop: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
updateUsers(resumeData).then(response => {
|
||||||
|
this.$modal.msgSuccess(`已成功恢复师傅"${userName}"的接单状态`);
|
||||||
|
this.getList(); // 刷新列表
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('恢复接单失败:', error);
|
||||||
|
this.$modal.msgError('恢复接单失败,请重试');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 检查并更新过期暂停状态
|
||||||
|
checkExpiredPauseStatus() {
|
||||||
|
const now = new Date();
|
||||||
|
let hasExpired = false;
|
||||||
|
|
||||||
|
this.usersList.forEach(user => {
|
||||||
|
if (user.isStop === 1 && user.prohibitTime) {
|
||||||
|
const prohibitTime = new Date(user.prohibitTime);
|
||||||
|
if (prohibitTime < now) {
|
||||||
|
// 如果暂停时间已过期,标记为已过期但不立即更新数据库
|
||||||
|
user.isExpired = true;
|
||||||
|
hasExpired = true;
|
||||||
|
console.log(`师傅"${user.name}"的暂停时间已过期`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 如果有过期的暂停状态,显示提示信息
|
||||||
|
if (hasExpired) {
|
||||||
|
this.$message.info('检测到部分师傅的暂停时间已过期,请手动恢复接单状态。');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 更新用户状态
|
||||||
|
updateUserStatus(id, status) {
|
||||||
|
changetypeStatus(id, status).then(() => {
|
||||||
|
this.$message.success(`用户状态更新成功`);
|
||||||
|
this.getList(); // 刷新列表以显示最新的状态
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('更新用户状态失败:', error);
|
||||||
|
this.$message.error('更新用户状态失败,请重试');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 手动恢复师傅暂停状态
|
||||||
|
handleManualResumeWorkerStatus() {
|
||||||
|
this.$modal.confirm('确认要执行师傅暂停状态自动恢复任务吗?此操作将检查所有暂停的师傅,并自动恢复已过期的师傅接单状态。').then(() => {
|
||||||
|
this.executeManualResumeWorkerStatus();
|
||||||
|
}).catch(() => {
|
||||||
|
console.log('用户取消手动恢复过期暂停操作');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 执行师傅暂停状态自动恢复
|
||||||
|
executeManualResumeWorkerStatus() {
|
||||||
|
// 显示加载状态
|
||||||
|
const loading = this.$loading({
|
||||||
|
lock: true,
|
||||||
|
text: '正在执行师傅暂停状态恢复任务...',
|
||||||
|
spinner: 'el-icon-loading',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
});
|
||||||
|
|
||||||
|
manualResumeWorkerStatus().then(response => {
|
||||||
|
loading.close();
|
||||||
|
if (response.code === 200) {
|
||||||
|
this.$message.success(response.msg || '师傅暂停状态自动恢复任务执行成功');
|
||||||
|
// 刷新列表以显示最新状态
|
||||||
|
this.getList();
|
||||||
|
} else {
|
||||||
|
this.$message.error(response.msg || '师傅暂停状态自动恢复任务执行失败');
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
loading.close();
|
||||||
|
console.error('执行师傅暂停状态自动恢复失败:', error);
|
||||||
|
this.$message.error('执行师傅暂停状态自动恢复失败,请重试');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 批量恢复过期暂停状态
|
||||||
|
resumeAllExpiredWorkers() {
|
||||||
|
const expiredUsers = this.usersList.filter(user => user.isStop === 1 && user.isExpired);
|
||||||
|
if (expiredUsers.length === 0) {
|
||||||
|
this.$message.info('没有过期暂停的师傅。');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const userIds = expiredUsers.map(user => user.id);
|
||||||
|
const userNames = expiredUsers.map(user => user.name);
|
||||||
|
|
||||||
|
this.$modal.confirm(`确认要恢复以下${userIds.length}个师傅的接单状态吗?\n${userNames.join('、')}`).then(() => {
|
||||||
|
const resumePromises = userIds.map(id => {
|
||||||
|
const resumeData = {
|
||||||
|
id: id,
|
||||||
|
prohibitTimeNum: 0,
|
||||||
|
isStop: 0
|
||||||
|
};
|
||||||
|
return updateUsers(resumeData);
|
||||||
|
});
|
||||||
|
|
||||||
|
Promise.all(resumePromises).then(() => {
|
||||||
|
this.$message.success(`已成功恢复${userIds.length}个师傅的接单状态。`);
|
||||||
|
this.getList(); // 刷新列表
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('批量恢复过期暂停失败:', error);
|
||||||
|
this.$message.error('批量恢复过期暂停失败,请重试');
|
||||||
|
});
|
||||||
|
}).catch(() => {
|
||||||
|
console.log('用户取消批量恢复过期暂停操作');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.time-input {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected-tags {
|
||||||
|
margin-top: 8px;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected-tags .el-tag {
|
||||||
|
margin: 2px;
|
||||||
|
max-width: 200px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-input .el-button {
|
||||||
|
border-radius: 4px;
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-input .el-input-number {
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expired-time {
|
||||||
|
color: #E6A23C;
|
||||||
|
font-weight: bold;
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 等级选择器样式 */
|
||||||
|
.level-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-select-custom {
|
||||||
|
width: 80px !important;
|
||||||
|
font-weight: 600;
|
||||||
|
border-radius: 20px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
border-width: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-select-custom:hover {
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-select-custom:focus-within {
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 不同等级的颜色样式 */
|
||||||
|
.level-1 {
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
border-color: #6c757d;
|
||||||
|
color: #495057;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-1:hover {
|
||||||
|
border-color: #5a6268;
|
||||||
|
background-color: #f1f3f4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-2 {
|
||||||
|
background-color: #e8f5e8;
|
||||||
|
border-color: #28a745;
|
||||||
|
color: #155724;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-2:hover {
|
||||||
|
border-color: #1e7e34;
|
||||||
|
background-color: #d1ecf1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-3 {
|
||||||
|
background-color: #e3f2fd;
|
||||||
|
border-color: #2196f3;
|
||||||
|
color: #0d47a1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-3:hover {
|
||||||
|
border-color: #1976d2;
|
||||||
|
background-color: #bbdefb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-4 {
|
||||||
|
background-color: #fff3e0;
|
||||||
|
border-color: #ff9800;
|
||||||
|
color: #e65100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-4:hover {
|
||||||
|
border-color: #f57c00;
|
||||||
|
background-color: #ffe0b2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-5 {
|
||||||
|
background-color: #ffebee;
|
||||||
|
border-color: #f44336;
|
||||||
|
color: #b71c1c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-5:hover {
|
||||||
|
border-color: #d32f2f;
|
||||||
|
background-color: #ffcdd2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 下拉选项样式 */
|
||||||
|
.level-option-item {
|
||||||
|
padding: 8px 16px !important;
|
||||||
|
border-radius: 6px;
|
||||||
|
margin: 2px 4px;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-option-item:hover {
|
||||||
|
background-color: #f8f9fa !important;
|
||||||
|
transform: translateX(4px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-option-wrapper {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-text {
|
||||||
|
font-weight: 500;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-number {
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 选择器下拉箭头样式优化 */
|
||||||
|
.level-select-custom .el-input__suffix {
|
||||||
|
right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-select-custom .el-input__suffix .el-input__suffix-inner .el-select__caret {
|
||||||
|
color: inherit;
|
||||||
|
font-size: 14px;
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-select-custom.is-focus .el-select__caret {
|
||||||
|
transform: rotateZ(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 响应式设计 */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.level-select-custom {
|
||||||
|
width: 70px !important;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-number {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue