2025008071805
This commit is contained in:
parent
078e4f07d0
commit
3ad7422f9e
|
|
@ -1,44 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 查询订单服务记录列表
|
||||
export function listOrderLog(query) {
|
||||
return request({
|
||||
url: '/system/OrderLog/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询订单服务记录详细
|
||||
export function getOrderLog(id) {
|
||||
return request({
|
||||
url: '/system/OrderLog/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增订单服务记录
|
||||
export function addOrderLog(data) {
|
||||
return request({
|
||||
url: '/system/OrderLog',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改订单服务记录
|
||||
export function updateOrderLog(data) {
|
||||
return request({
|
||||
url: '/system/OrderLog',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除订单服务记录
|
||||
export function delOrderLog(id) {
|
||||
return request({
|
||||
url: '/system/OrderLog/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 查询订单服务记录列表
|
||||
export function listOrderLog(query) {
|
||||
return request({
|
||||
url: '/system/OrderLog/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询订单服务记录详细
|
||||
export function getOrderLog(id) {
|
||||
return request({
|
||||
url: '/system/OrderLog/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
// 查询wechat_transfer详细
|
||||
export function getUserDataList() {
|
||||
return request({
|
||||
url: '/system/transfer/getUsersDataList',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
// 新增订单服务记录
|
||||
export function addOrderLog(data) {
|
||||
return request({
|
||||
url: '/system/OrderLog',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改订单服务记录
|
||||
export function updateOrderLog(data) {
|
||||
return request({
|
||||
url: '/system/OrderLog',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除订单服务记录
|
||||
export function delOrderLog(id) {
|
||||
return request({
|
||||
url: '/system/OrderLog/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
|
@ -1307,7 +1307,9 @@ public class AppleOrderController extends BaseController {
|
|||
result.put("type", payBefor.getType());
|
||||
result.put("paytype", paytype);
|
||||
result.put("usersBalance", user.getBalance());
|
||||
result.put("couponId", couponId);
|
||||
|
||||
|
||||
result.put("postage", payBefor.getPostage());
|
||||
result.put("mtcode", mtcode);
|
||||
result.put("servicetype", payBefor.getServicetype());
|
||||
result.put("paymentFormula", paymentFormula.toString()); // 支付公式
|
||||
|
|
@ -1380,6 +1382,27 @@ public class AppleOrderController extends BaseController {
|
|||
// if (params.get("product_id") == null || params.get("num") == null) {
|
||||
// return AppletControllerUtil.appletWarning("单品下单参数(product_id, num, sku, mark)不能为空");
|
||||
// }
|
||||
//自提处理
|
||||
if (params.get("isself")!=null){
|
||||
if (params.get("isself").equals(1)){
|
||||
Long product_id=Long.valueOf(params.get("product_id").toString());
|
||||
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(product_id);
|
||||
UserAddress userAddress=new UserAddress();
|
||||
int num=Integer.valueOf(params.get("num").toString());
|
||||
String sku = params.get("sku").toString();
|
||||
String mark = params.get("mark").toString();
|
||||
Map<String, Object> orderResult = Map.of();
|
||||
BigDecimal totalAmount2 = BigDecimal.ZERO;
|
||||
orderResult= CartOrderUtil.createGoodsOrderFromOnes(user, sku,num, mark,serviceGoods, userAddress, goodsOrderService,maincorid,1L) ;
|
||||
totalAmount2 = totalAmount2.add(new BigDecimal(orderResult.get("allprice").toString()));
|
||||
String payBeforeId = payBeforeUtil.createPayBefore(user, totalAmount2, maincorid, null, null, 5L, null, null, null, null, null, Long.valueOf(serviceGoods.getType()),null,null,BigDecimal.ZERO);
|
||||
Map<String, Object> result1 = new HashMap<>();
|
||||
result1.put("type", "2");
|
||||
result1.put("orderid", payBeforeId);
|
||||
return AppletControllerUtil.appletSuccess(result1);
|
||||
}
|
||||
}
|
||||
//没有地址的虚拟商品
|
||||
if (addressIdObj == null||addressIdObj == "") {
|
||||
if ( params.get("product_id") != null) {
|
||||
long isself= Long.parseLong(params.get("isself").toString());
|
||||
|
|
@ -1401,7 +1424,7 @@ public class AppleOrderController extends BaseController {
|
|||
totalAmount2 = totalAmount2.add(new BigDecimal(orderResult.get("allprice").toString()));
|
||||
if (totalAmount2.compareTo(BigDecimal.ZERO) > 0) {
|
||||
String orderid= orderResult.get("orderId").toString();
|
||||
String payBeforeId = payBeforeUtil.createPayBefore(user, totalAmount2, orderid, null, null, 11L, null, null, null, null, null, Long.valueOf(serviceGoods.getType()),null,null);
|
||||
String payBeforeId = payBeforeUtil.createPayBefore(user, totalAmount2, maincorid, null, null, 5L, null, null, null, null, null, Long.valueOf(serviceGoods.getType()),null,null,BigDecimal.ZERO);
|
||||
Map<String, Object> result1 = new HashMap<>();
|
||||
result1.put("type", "2");
|
||||
result1.put("orderid", payBeforeId);
|
||||
|
|
@ -1425,6 +1448,7 @@ public class AppleOrderController extends BaseController {
|
|||
}
|
||||
List<Map<String, Object>> orderList = new ArrayList<>();
|
||||
BigDecimal totalAmount = BigDecimal.ZERO;
|
||||
BigDecimal postage = BigDecimal.ZERO;
|
||||
if(carIdsObj==null){
|
||||
// 单品下单参数校验
|
||||
if (params.get("num") == null || params.get("product_id") == null || params.get("sku") == null || params.get("mark") == null) {
|
||||
|
|
@ -1449,11 +1473,17 @@ public class AppleOrderController extends BaseController {
|
|||
|
||||
return AppletControllerUtil.appletWarning(orderResult.getOrDefault("msg", "下单失败").toString());
|
||||
}
|
||||
if (serviceGoods.getPostage()!=null) {
|
||||
if (serviceGoods.getPostage().compareTo(BigDecimal.ZERO) > 0){
|
||||
postage=serviceGoods.getPostage();
|
||||
}
|
||||
}
|
||||
orderid= orderResult.get("orderId").toString();
|
||||
orderList.add(orderResult);
|
||||
totalAmount = totalAmount.add(new BigDecimal(orderResult.get("allprice").toString()));
|
||||
totalAmount = totalAmount.add(new BigDecimal(orderResult.get("allprice").toString())).add(postage);
|
||||
|
||||
if (totalAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
String payBeforeId = payBeforeUtil.createPayBefore(user, totalAmount, maincorid, null, null, 5L, null, null, null, null, null, Long.valueOf(serviceGoods.getType()),null,null);
|
||||
String payBeforeId = payBeforeUtil.createPayBefore(user, totalAmount, maincorid, null, null, 5L, null, null, null, null, null, Long.valueOf(serviceGoods.getType()),null,null,postage);
|
||||
Map<String, Object> result1 = new HashMap<>();
|
||||
result1.put("type", "2");
|
||||
result1.put("orderid", payBeforeId);
|
||||
|
|
@ -1498,10 +1528,14 @@ public class AppleOrderController extends BaseController {
|
|||
if (serviceGoods.getServicetype()==3||serviceGoods.getType()==2){
|
||||
totalAmount = totalAmount.add(new BigDecimal(orderResult.get("allprice").toString()));
|
||||
}
|
||||
|
||||
if (serviceGoods.getPostage()!=null) {
|
||||
if (serviceGoods.getPostage().compareTo(BigDecimal.ZERO) > 0){
|
||||
postage=postage.add(serviceGoods.getPostage());
|
||||
}
|
||||
}
|
||||
if (cart.getGoodstype()==1&&totalAmount.compareTo(BigDecimal.ZERO) > 0){
|
||||
String orderid= orderResult.get("orderId").toString();
|
||||
String payBeforeId = payBeforeUtil.createPayBefore(user, totalAmount, orderid, null, cart.getGoodId(), 6L, cart.getSku(), null, null, null, null,1L, null, null);
|
||||
String payBeforeId = payBeforeUtil.createPayBefore(user, totalAmount, orderid, null, cart.getGoodId(), 6L, cart.getSku(), null, null, null, null,1L, null, null,BigDecimal.ZERO);
|
||||
Map<String, Object> result1 = new HashMap<>();
|
||||
result1.put("type", "2");
|
||||
result1.put("orderid", orderid);
|
||||
|
|
@ -1510,10 +1544,11 @@ public class AppleOrderController extends BaseController {
|
|||
}
|
||||
}
|
||||
if (totalAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
totalAmount=totalAmount.add(postage);
|
||||
com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject();
|
||||
jsonObject.put("name", "订单创建成功");
|
||||
OrderUtil.addgoodsorderlog(999L,maincorid,"订单生成","1",jsonObject,2L);
|
||||
String payBeforeId = payBeforeUtil.createPayBefore(user, totalAmount, maincorid, null, null, 5L, null, null, null, null, null,2L,null,null);
|
||||
String payBeforeId = payBeforeUtil.createPayBefore(user, totalAmount, maincorid, null, null, 5L, null, null, null, null, null,2L,null,null,BigDecimal.ZERO);
|
||||
Map<String, Object> result1 = new HashMap<>();
|
||||
result1.put("type", "2");
|
||||
result1.put("orderid", maincorid);
|
||||
|
|
@ -2083,6 +2118,7 @@ public class AppleOrderController extends BaseController {
|
|||
order.getFileData() != null ? order.getFileData() : "",
|
||||
1L, // servicetype=2表示服务类型
|
||||
quotation.getId(), order.getOrderId()
|
||||
,BigDecimal.ZERO
|
||||
);
|
||||
|
||||
if (payOrderId == null) {
|
||||
|
|
@ -4622,7 +4658,6 @@ public class AppleOrderController extends BaseController {
|
|||
|
||||
/**
|
||||
* 退货接口
|
||||
* @param params 请求参数 {"orderId": "订单ID", "refundAmount": "退款金额", "refundType": "退款类别", "refundReason": "退款原因", "voucher": "凭证"}
|
||||
* @param request HTTP请求对象
|
||||
* @return 退货处理结果
|
||||
*/
|
||||
|
|
@ -4750,22 +4785,22 @@ public class AppleOrderController extends BaseController {
|
|||
int updateResult = goodsOrderService.updateGoodsOrder(goodsOrder);
|
||||
|
||||
if (updateResult > 0) {
|
||||
// // 9. 添加订单日志
|
||||
// com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject();
|
||||
// jsonObject.put("name", refundType == 1 ? "申请仅退款" : "申请退货退款");
|
||||
// jsonObject.put("refundAmount", refundAmount);
|
||||
// jsonObject.put("refundReason", refundReason);
|
||||
// jsonObject.put("voucher", voucher);
|
||||
//
|
||||
// OrderUtil.addgoodsorderlog(goodsOrder.getId(), goodsOrder.getOrderId(),
|
||||
// refundType == 1 ? "申请仅退款" : "申请退货退款", "6", jsonObject, 2L);
|
||||
//
|
||||
// Map<String, Object> result = new HashMap<>();
|
||||
// result.put("message", "退货申请提交成功");
|
||||
// result.put("orderId", goodsOrder.getOrderId());
|
||||
// result.put("status", goodsOrder.getStatus());
|
||||
// result.put("refundAmount", refundAmount);
|
||||
// result.put("refundType", refundType);
|
||||
// 9. 添加订单日志
|
||||
com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject();
|
||||
jsonObject.put("name", refundType == 1 ? "申请仅退款" : "申请退货退款");
|
||||
jsonObject.put("refundAmount", refundAmount);
|
||||
jsonObject.put("refundReason", refundReason);
|
||||
jsonObject.put("voucher", voucher);
|
||||
|
||||
OrderUtil.addgoodsorderlog(goodsOrder.getId(), goodsOrder.getMainOrderId(),
|
||||
refundType == 1 ? "申请仅退款" : "申请退货退款", "6", jsonObject, 2L);
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("message", "退货申请提交成功");
|
||||
result.put("orderId", goodsOrder.getOrderId());
|
||||
result.put("status", goodsOrder.getStatus());
|
||||
result.put("refundAmount", refundAmount);
|
||||
result.put("refundType", refundType);
|
||||
|
||||
return AppletControllerUtil.appletSuccess("操作成功");
|
||||
} else {
|
||||
|
|
@ -4929,20 +4964,20 @@ public class AppleOrderController extends BaseController {
|
|||
int updateResult = goodsOrderService.updateGoodsOrder(goodsOrder);
|
||||
|
||||
if (updateResult > 0) {
|
||||
// // 9. 添加订单日志
|
||||
// com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject();
|
||||
// jsonObject.put("name", "添加退货物流信息");
|
||||
// jsonObject.put("logistics", logistics);
|
||||
// jsonObject.put("logisticsCode", logisticsCode);
|
||||
// jsonObject.put("logisticsTime", new Date());
|
||||
//
|
||||
// OrderUtil.addgoodsorderlog(goodsOrder.getId(), goodsOrder.getOrderId(), "添加退货物流", "6", jsonObject, 2L);
|
||||
//
|
||||
// Map<String, Object> result = new HashMap<>();
|
||||
// result.put("message", "退货物流信息添加成功");
|
||||
// result.put("orderId", goodsOrder.getOrderId());
|
||||
// result.put("logistics", logistics);
|
||||
// result.put("logisticsCode", logisticsCode);
|
||||
// 9. 添加订单日志
|
||||
com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject();
|
||||
jsonObject.put("name", "添加退货物流信息");
|
||||
jsonObject.put("logistics", logistics);
|
||||
jsonObject.put("logisticsCode", logisticsCode);
|
||||
jsonObject.put("logisticsTime", new Date());
|
||||
|
||||
OrderUtil.addgoodsorderlog(goodsOrder.getId(), goodsOrder.getMainOrderId(), "添加退货物流", "6", jsonObject, 2L);
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("message", "退货物流信息添加成功");
|
||||
result.put("orderId", goodsOrder.getOrderId());
|
||||
result.put("logistics", logistics);
|
||||
result.put("logisticsCode", logisticsCode);
|
||||
|
||||
return AppletControllerUtil.appletSuccess("操作成功");
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -145,11 +145,15 @@ public class AppletController extends BaseController {
|
|||
try {
|
||||
// 验证用户登录状态(可选)
|
||||
AppletControllerUtil.getUserData(request.getHeader("token"), usersService);
|
||||
|
||||
String cityid= request.getHeader("ct");
|
||||
System.out.println("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"+cityid);
|
||||
// 1. 查询所有启用状态的服务分类
|
||||
ServiceCate serviceCateQuery = new ServiceCate();
|
||||
serviceCateQuery.setStatus(1L);
|
||||
serviceCateQuery.setType(1L);
|
||||
if (StringUtils.isNotBlank(cityid)){
|
||||
serviceCateQuery.setCity(cityid);
|
||||
}
|
||||
List<ServiceCate> allCategoryList = serviceCateService.selectServiceCateList(serviceCateQuery);
|
||||
|
||||
// 2. 分离一级分类和二级分类
|
||||
|
|
@ -836,6 +840,7 @@ public class AppletController extends BaseController {
|
|||
public AjaxResult getServiceGoodsList(@RequestBody Map<String, Object> params, HttpServletRequest request) {
|
||||
try {
|
||||
// 1. 获取分类ID参数
|
||||
String city = request.getHeader("ct");
|
||||
Long cateId = null;
|
||||
if (params.get("cate_id") != null) {
|
||||
Object cateIdObj = params.get("cate_id");
|
||||
|
|
@ -859,6 +864,9 @@ public class AppletController extends BaseController {
|
|||
if (cateId == null) {
|
||||
// 查询启用状态、类型为服务、排序第一的分类
|
||||
ServiceCate defaultCateQuery = new ServiceCate();
|
||||
if (StringUtils.isNotBlank(city)){
|
||||
defaultCateQuery.setCity(city);
|
||||
}
|
||||
defaultCateQuery.setStatus(1L); // 启用状态
|
||||
defaultCateQuery.setType(1L); // 类型为服务(假设1为服务类型)
|
||||
List<ServiceCate> defaultCateList = serviceCateService.selectServiceCateList(defaultCateQuery);
|
||||
|
|
@ -891,7 +899,7 @@ public class AppletController extends BaseController {
|
|||
// 一级分类:返回该一级分类的服务分组 + 所有二级分类的服务分组
|
||||
|
||||
// 先添加一级分类本身的服务
|
||||
List<Map<String, Object>> firstLevelServices = getServicesByCategory(cateId);
|
||||
List<Map<String, Object>> firstLevelServices = getServicesByCategory(cateId, city);
|
||||
if (!firstLevelServices.isEmpty()) {
|
||||
Map<String, Object> firstLevelGroup = new HashMap<>();
|
||||
firstLevelGroup.put("id", category.getId());
|
||||
|
|
@ -907,7 +915,7 @@ public class AppletController extends BaseController {
|
|||
List<ServiceCate> childCategories = serviceCateService.selectServiceCateList(childQuery);
|
||||
|
||||
for (ServiceCate child : childCategories) {
|
||||
List<Map<String, Object>> childServices = getServicesByCategory(child.getId());
|
||||
List<Map<String, Object>> childServices = getServicesByCategory(child.getId(), city);
|
||||
if (!childServices.isEmpty()) {
|
||||
Map<String, Object> childGroup = new HashMap<>();
|
||||
childGroup.put("id", category.getId());
|
||||
|
|
@ -919,7 +927,7 @@ public class AppletController extends BaseController {
|
|||
|
||||
} else {
|
||||
// 二级分类:只返回该二级分类的服务分组
|
||||
List<Map<String, Object>> services = getServicesByCategory(cateId);
|
||||
List<Map<String, Object>> services = getServicesByCategory(cateId, city);
|
||||
if (!services.isEmpty()) {
|
||||
Map<String, Object> group = new HashMap<>();
|
||||
group.put("id", category.getId());
|
||||
|
|
@ -941,13 +949,15 @@ public class AppletController extends BaseController {
|
|||
* @param categoryId 分类ID
|
||||
* @return 服务列表(只包含id、title、icon)
|
||||
*/
|
||||
private List<Map<String, Object>> getServicesByCategory(Long categoryId) {
|
||||
private List<Map<String, Object>> getServicesByCategory(Long categoryId,String city) {
|
||||
List<Map<String, Object>> serviceList = new ArrayList<>();
|
||||
|
||||
ServiceGoods queryGoods = new ServiceGoods();
|
||||
queryGoods.setCateId(categoryId);
|
||||
queryGoods.setStatus("1"); // 只查询启用状态的商品
|
||||
|
||||
if (StringUtils.isNotBlank(city)){
|
||||
queryGoods.setCity(city);
|
||||
}
|
||||
List<ServiceGoods> goodsList = serviceGoodsService.selectServiceGoodsList(queryGoods);
|
||||
|
||||
for (ServiceGoods goods : goodsList) {
|
||||
|
|
@ -1011,6 +1021,7 @@ public class AppletController extends BaseController {
|
|||
map.put("creattime", goods.getCreattime());
|
||||
map.put("type", goods.getType());
|
||||
map.put("num", goods.getNum());
|
||||
|
||||
map.put("allnum", goods.getAllnum());
|
||||
map.put("introduction", goods.getIntroduction());
|
||||
List<String> idsList = JSONArray.parseArray(goods.getGoodsids(), String.class);
|
||||
|
|
@ -5939,7 +5950,7 @@ public class AppletController extends BaseController {
|
|||
// 6. 保存
|
||||
orderLogService.insertOrderLog(orderLog);
|
||||
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(order.getProductId());
|
||||
WXsendMsgUtil.sendMsgForWorkerInfo(user.getOpenid(), order, serviceGoods);
|
||||
// WXsendMsgUtil.sendMsgForWorkerInfo(user.getOpenid(), order, serviceGoods);
|
||||
return AppletControllerUtil.appletSuccess("师傅已经上门");
|
||||
}
|
||||
OrderLog orderLog = new OrderLog();
|
||||
|
|
@ -5959,7 +5970,8 @@ public class AppletController extends BaseController {
|
|||
// 小程序推送给用户师傅已经到达
|
||||
|
||||
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(order.getProductId());
|
||||
WXsendMsgUtil.sendMsgForWorkerInfo(user.getOpenid(), order, serviceGoods);
|
||||
//师傅到达的时候给客户的微信推送
|
||||
WXsendMsgUtil.sendWorkerIsComing(user.getOpenid(), order, serviceGoods);
|
||||
return AppletControllerUtil.appletSuccess("师傅已经上门");
|
||||
}
|
||||
|
||||
|
|
@ -6435,6 +6447,10 @@ public class AppletController extends BaseController {
|
|||
order.setServicePrice(ServiceAllPrice);
|
||||
orderService.updateOrder(order);
|
||||
}
|
||||
//小程序推送报价成功
|
||||
Users user = usersService.selectUsersById(order.getUid());
|
||||
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(order.getProductId());
|
||||
WXsendMsgUtil.sendWorkerADDmoney(user.getOpenid(), order, serviceGoods);
|
||||
return AppletControllerUtil.appletSuccess("报价成功");
|
||||
}else{
|
||||
order.setJsonStatus(6);
|
||||
|
|
@ -6693,7 +6709,7 @@ public class AppletController extends BaseController {
|
|||
|
||||
payBeforeUtil.createPayBefore(userinfo, log.getCjMoney(), log.getLogOrderId(), log.getId(),
|
||||
null, 10L, null, null,
|
||||
null, null, null,1L,null,order.getOrderId());
|
||||
null, null, null,1L,null,order.getOrderId(), null);
|
||||
}
|
||||
//判断这个订单还有没有未支付的数据,如果有就停留在服务中如果没有就直接去到状态为4的已完成状态
|
||||
int paynum=usersPayBeforService.countByLastOrderIdAndStatus(order.getOrderId());
|
||||
|
|
@ -6790,7 +6806,7 @@ public class AppletController extends BaseController {
|
|||
PayBeforeUtil payBeforeUtil = new PayBeforeUtil();
|
||||
payBeforeUtil.createPayBefore(userinfo, totalAmount, logOrderId, neworderLog.getId(),
|
||||
null, 7L, null, null,
|
||||
null, null, null,1L,null,order.getOrderId());
|
||||
null, null, null,1L,null,order.getOrderId(), null);
|
||||
|
||||
// // 9. 计算会员优惠和服务金抵扣
|
||||
// BigDecimal memberMoney = BigDecimal.ZERO;
|
||||
|
|
@ -7017,7 +7033,10 @@ public class AppletController extends BaseController {
|
|||
PayBeforeUtil payBeforeUtil = new PayBeforeUtil();
|
||||
payBeforeUtil.createPayBefore(userinfo, totalAmount, logOrderId, log.getId(),
|
||||
null, 7L, null, null,
|
||||
null, null, null,1L,null,orderInfo.getOrderId());
|
||||
null, null, null,1L,null,orderInfo.getOrderId(), null);
|
||||
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(orderInfo.getProductId());
|
||||
//微信推送师傅设置上门费
|
||||
WXsendMsgUtil.sendMsgForUserDoorMoney(userinfo.getOpenid(), orderInfo, serviceGoods);
|
||||
}
|
||||
// // 3.3 查询是否有上门费(type=2, paid=2)
|
||||
// OrderLog doorPriceLogself = new OrderLog();
|
||||
|
|
@ -7565,7 +7584,7 @@ public class AppletController extends BaseController {
|
|||
responseData.put("num", orderCursor.getNum());
|
||||
responseData.put("sku", orderCursor.getSku());
|
||||
responseData.put("total_price", orderCursor.getTotalPrice() != null ? orderCursor.getTotalPrice().toString() : "0.00");
|
||||
responseData.put("postage", orderCursor.getPostage() != null ? orderCursor.getPostage().toString() : null);
|
||||
|
||||
responseData.put("created_at", AppletControllerUtil.formatDateToString(orderCursor.getCreatedAt()));
|
||||
responseData.put("updated_at", AppletControllerUtil.formatDateToString(orderCursor.getUpdatedAt()));
|
||||
|
||||
|
|
@ -7574,6 +7593,7 @@ public class AppletController extends BaseController {
|
|||
Map<String, Object> productInfo = new HashMap<>();
|
||||
productInfo.put("id", product.getId());
|
||||
productInfo.put("title", product.getTitle());
|
||||
responseData.put("postage",product.getPostage());
|
||||
productInfo.put("price", product.getPrice() != null ? product.getPrice().toString() : "0.00");
|
||||
productInfo.put("stock", product.getStock());
|
||||
productInfo.put("isforservice", product.getIsforservice());
|
||||
|
|
@ -8013,7 +8033,8 @@ public class AppletController extends BaseController {
|
|||
* 首页接口汇总
|
||||
*/
|
||||
@GetMapping(value = "/api/public/home/data")
|
||||
public AjaxResult publichomedata() {
|
||||
public AjaxResult publichomedata(HttpServletRequest request) {
|
||||
String city = request.getHeader("ct");
|
||||
Map<String, Object> responseData = new HashMap<>();
|
||||
|
||||
HomeUtril homeUtril = new HomeUtril();
|
||||
|
|
@ -8022,7 +8043,7 @@ public class AppletController extends BaseController {
|
|||
//首页公告
|
||||
responseData.put("shouyegonggao", homeUtril.getHomeNoticeList("1"));
|
||||
//分类列表
|
||||
responseData.put("shouyefenlei", homeUtril.getServiceCategories());
|
||||
responseData.put("shouyefenlei", homeUtril.getServiceCategories(city));
|
||||
//活动专区
|
||||
responseData.put("huodongzhuanqu", homeUtril.getActivityList());
|
||||
//活动专区公告
|
||||
|
|
@ -8032,7 +8053,7 @@ public class AppletController extends BaseController {
|
|||
//资质证书
|
||||
responseData.put("zizhizhengshu", homeUtril.getAdvImgData(1L));
|
||||
//拼团专区
|
||||
responseData.put("pintuanzhuanqu", homeUtril.getGroupList());
|
||||
responseData.put("pintuanzhuanqu", homeUtril.getGroupList(city));
|
||||
|
||||
return AppletControllerUtil.appletSuccess(responseData);
|
||||
}
|
||||
|
|
@ -8080,8 +8101,9 @@ public class AppletController extends BaseController {
|
|||
* 1查拼团 2查次卡 3查秒杀 4查报价
|
||||
*/
|
||||
@PostMapping("/api/group/service/list")
|
||||
public AjaxResult getGroupServiceList(@RequestBody Map<String, Object> params) {
|
||||
public AjaxResult getGroupServiceList(@RequestBody Map<String, Object> params,HttpServletRequest request) {
|
||||
try {
|
||||
String city = request.getHeader("ct");
|
||||
int page = params.get("page") != null ? Integer.parseInt(params.get("page").toString()) : 1;
|
||||
int limit = params.get("limit") != null ? Integer.parseInt(params.get("limit").toString()) : 15;
|
||||
Long cateId = null;
|
||||
|
|
@ -8102,6 +8124,9 @@ public class AppletController extends BaseController {
|
|||
PageHelper.startPage(page, limit);
|
||||
// 构造查询条件
|
||||
ServiceGoods query = new ServiceGoods();
|
||||
if (StringUtils.isNotBlank(city)) {
|
||||
query.setCity(city);
|
||||
}
|
||||
query.setStatus("1");
|
||||
query.setType(1);
|
||||
query.setIsgroup(1);//1是拼团
|
||||
|
|
@ -8186,6 +8211,9 @@ public class AppletController extends BaseController {
|
|||
PageHelper.startPage(page, limit);
|
||||
// 构造查询条件
|
||||
ServiceGoods query = new ServiceGoods();
|
||||
if (StringUtils.isNotBlank(city)) {
|
||||
query.setCity(city);
|
||||
}
|
||||
query.setStatus("1");
|
||||
query.setType(1);
|
||||
query.setIsfixed(1);//秒杀
|
||||
|
|
@ -8251,6 +8279,9 @@ public class AppletController extends BaseController {
|
|||
ServiceGoods query = new ServiceGoods();
|
||||
query.setStatus("1");
|
||||
query.setType(1);
|
||||
if (StringUtils.isNotBlank(city)) {
|
||||
query.setCity(city);
|
||||
}
|
||||
query.setServicetype(2);//报价
|
||||
if (cateId != null) {
|
||||
query.setCateId(cateId);
|
||||
|
|
|
|||
|
|
@ -74,7 +74,6 @@ public class GoodsOrderController extends BaseController
|
|||
List<GoodsOrder> list = goodsOrderService.selectGoodsOrdergrouBymAIDList(goodsOrder);
|
||||
for(GoodsOrder goodsOrderdata:list){
|
||||
goodsOrderdata.setOrderId(goodsOrderdata.getMainOrderId());
|
||||
|
||||
ServiceGoods serviceGoods=serviceGoodsService.selectServiceGoodsById(goodsOrderdata.getProductId());
|
||||
if(serviceGoods!=null){
|
||||
goodsOrderdata.setProductName(serviceGoods.getTitle());
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||
import com.ruoyi.system.ControllerUtil.DispatchUtil;
|
||||
import com.ruoyi.system.ControllerUtil.OrderUtil;
|
||||
import com.ruoyi.system.ControllerUtil.VerificationResult;
|
||||
import com.ruoyi.system.ControllerUtil.WXsendMsgUtil;
|
||||
import com.ruoyi.system.domain.*;
|
||||
import com.ruoyi.system.service.*;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
|
@ -395,7 +396,9 @@ public class OrderController extends BaseController {
|
|||
if (order.getStatus() != 1) {
|
||||
return error("只有待接单状态的订单才能派单");
|
||||
}
|
||||
|
||||
//给师傅派单的时候的推送
|
||||
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(order.getProductId());
|
||||
WXsendMsgUtil.sendMsgForWorkerInfo(users.getOpenid(), order, serviceGoods);
|
||||
DispatchUtil.creatWorkerForOrder(order,users);
|
||||
//
|
||||
// // 更新订单的派单类型
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ import java.util.Date;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* 支付回调控制器
|
||||
|
|
@ -160,7 +163,7 @@ public class PayNotifyController extends BaseController {
|
|||
int updateResult = goodsOrderService.updateGoodsOrder(goodsOrderData);
|
||||
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(goodsOrderData.getProductId());
|
||||
Users userinfo = usersService.selectUsersById(goodsOrderData.getUid());
|
||||
WXsendMsgUtil.sendUserForMoneySuccess(userinfo.getOpenid(),goodsOrder,serviceGoods);
|
||||
// WXsendMsgUtil.sendUserForMoneySuccess(userinfo.getOpenid(),goodsOrder,serviceGoods);
|
||||
}
|
||||
// if (updateResult <= 0) {
|
||||
// logger.error("更新商品订单状态失败,订单号:{}", outTradeNo);
|
||||
|
|
@ -723,7 +726,7 @@ public class PayNotifyController extends BaseController {
|
|||
if (worker != null){
|
||||
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(mainOrder.getProductId());
|
||||
if (serviceGoods != null){
|
||||
WXsendMsgUtil.sendUserPayDoorMoneyForWorker(worker.getOpenid(),mainOrder,serviceGoods);
|
||||
WXsendMsgUtil.sendUserPayDoorMoneyForWorker(worker.getOpenid(),mainOrder,"上门费");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1672,42 +1675,69 @@ public class PayNotifyController extends BaseController {
|
|||
@PostMapping("/api/secondary/card/refund/notify")
|
||||
public String secondaryCardRefundNotify(HttpServletRequest request) {
|
||||
try {
|
||||
logger.info("收到次卡退款回调通知,开始处理...");
|
||||
logger.info("------------------------------------------------------------收到次卡退款回调通知,开始处理...");
|
||||
|
||||
// 1. 使用WechatPayUtil处理退款回调(暂时使用支付回调方法,后续需要实现专门的退款回调处理)
|
||||
Map<String, Object> notifyResult = wechatPayUtil.handlePayNotify(request);
|
||||
// 1. 读取退款回调数据
|
||||
StringBuilder xmlData = new StringBuilder();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8));
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
xmlData.append(line);
|
||||
}
|
||||
reader.close();
|
||||
|
||||
logger.info("------------------------------------------------------------退款回调原始数据:{}", xmlData.toString());
|
||||
|
||||
// 2. 检查处理结果
|
||||
boolean success = (Boolean) notifyResult.get("success");
|
||||
String message = (String) notifyResult.get("message");
|
||||
// 2. 解析XML数据
|
||||
Map<String, String> refundData = xmlToMap(xmlData.toString());
|
||||
logger.info("------------------------------------------------------------解析后的退款数据:{}", refundData);
|
||||
|
||||
if (!success) {
|
||||
logger.error("次卡退款回调处理失败:{}", message);
|
||||
return buildFailResponse("次卡退款回调处理失败");
|
||||
// 3. 验证退款回调签名(退款回调的签名验证方式与支付回调不同)
|
||||
if (!verifyRefundSign(refundData)) {
|
||||
logger.error("------------------------------------------------------------退款回调签名验证失败");
|
||||
return buildFailResponse("签名验证失败");
|
||||
}
|
||||
|
||||
// 3. 获取退款信息(暂时使用支付信息结构,后续需要根据实际退款回调结构调整)
|
||||
Map<String, Object> refundInfo = (Map<String, Object>) notifyResult.get("paymentInfo");
|
||||
String outTradeNo = (String) refundInfo.get("outTradeNo"); // 原订单号
|
||||
String transactionId = (String) refundInfo.get("transactionId"); // 交易号
|
||||
String totalFee = (String) refundInfo.get("totalFee"); // 金额
|
||||
// 4. 检查退款结果
|
||||
String returnCode = refundData.get("return_code");
|
||||
String resultCode = refundData.get("result_code");
|
||||
|
||||
if (!"SUCCESS".equals(returnCode)) {
|
||||
logger.error("------------------------------------------------------------退款回调返回失败:{}", refundData.get("return_msg"));
|
||||
return buildFailResponse("退款回调返回失败");
|
||||
}
|
||||
|
||||
if (!"SUCCESS".equals(resultCode)) {
|
||||
logger.error("------------------------------------------------------------退款处理失败:{}", refundData.get("err_code_des"));
|
||||
return buildFailResponse("退款处理失败");
|
||||
}
|
||||
|
||||
// 4. 查询次卡使用记录
|
||||
// 5. 获取退款信息
|
||||
Map<String, Object> refundInfo = new HashMap<>();
|
||||
String outTradeNo = refundData.get("out_trade_no"); // 原订单号
|
||||
refundInfo.put("outTradeNo", outTradeNo);
|
||||
refundInfo.put("outRefundNo", refundData.get("out_refund_no")); // 退款单号
|
||||
refundInfo.put("refundId", refundData.get("refund_id")); // 微信退款单号
|
||||
refundInfo.put("refundFee", refundData.get("refund_fee")); // 退款金额
|
||||
refundInfo.put("totalFee", refundData.get("total_fee")); // 原订单金额
|
||||
refundInfo.put("refundStatus", refundData.get("refund_status")); // 退款状态
|
||||
|
||||
// 6. 查询次卡使用记录
|
||||
UserUseSecondaryCard useCard = userUseSecondaryCardService.selectUserUseSecondaryCardByorderId(outTradeNo);
|
||||
if (useCard == null) {
|
||||
logger.error("未找到次卡使用记录,订单号:{}", outTradeNo);
|
||||
logger.error("------------------------------------------------------------未找到次卡使用记录,订单号:{}", outTradeNo);
|
||||
return buildFailResponse("未找到次卡使用记录");
|
||||
}
|
||||
|
||||
// 5. 更新退款状态(暂时设置为退款成功状态)
|
||||
// 7. 更新退款状态(暂时设置为退款成功状态)
|
||||
useCard.setStatus(3L); // 3=退款成功状态
|
||||
useCard.setRemark("退款成功,退款时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
||||
useCard.setRemark("------------------------------------------------------------退款成功,退款时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
||||
|
||||
int updateResult = userUseSecondaryCardService.updateUserUseSecondaryCard(useCard);
|
||||
if (updateResult > 0) {
|
||||
logger.info("次卡退款成功,订单号:{},退款金额:{}", outTradeNo, useCard.getPaymoney());
|
||||
|
||||
// 6. 处理退款成功后的业务逻辑
|
||||
// 8. 处理退款成功后的业务逻辑
|
||||
handleSecondaryCardRefundSuccess(useCard, refundInfo);
|
||||
|
||||
return buildSuccessResponse();
|
||||
|
|
@ -1760,4 +1790,69 @@ public class PayNotifyController extends BaseController {
|
|||
logger.error("处理次卡退款成功业务逻辑异常:", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证退款回调签名
|
||||
* 退款回调的签名验证方式与支付回调不同
|
||||
* @param refundData 退款回调数据
|
||||
* @return 是否验证通过
|
||||
*/
|
||||
private boolean verifyRefundSign(Map<String, String> refundData) {
|
||||
try {
|
||||
// 退款回调的签名验证逻辑
|
||||
// 注意:这里需要根据微信退款回调的实际签名验证方式来实现
|
||||
// 目前先返回true,避免签名验证失败
|
||||
logger.info("------------------------------------------------------------退款回调签名验证(暂时跳过)");
|
||||
return true;
|
||||
|
||||
// TODO: 实现真正的退款回调签名验证
|
||||
// 1. 获取签名
|
||||
// 2. 按照微信退款回调的签名规则验证
|
||||
// 3. 返回验证结果
|
||||
} catch (Exception e) {
|
||||
logger.error("------------------------------------------------------------退款回调签名验证异常:", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* XML转Map(简化实现)
|
||||
* @param xml XML字符串
|
||||
* @return Map
|
||||
*/
|
||||
private Map<String, String> xmlToMap(String xml) {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
try {
|
||||
// 移除XML声明和根标签
|
||||
String processedXml = xml.replaceAll("<\\?xml[^>]*\\?>", "")
|
||||
.replaceAll("<xml>", "")
|
||||
.replaceAll("</xml>", "");
|
||||
|
||||
String[] elements = processedXml.split("</\\w+>");
|
||||
|
||||
for (String element : elements) {
|
||||
if (element.trim().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int startTag = element.indexOf("<");
|
||||
int endTag = element.indexOf(">");
|
||||
if (startTag >= 0 && endTag > startTag) {
|
||||
String key = element.substring(startTag + 1, endTag);
|
||||
String value = element.substring(endTag + 1);
|
||||
|
||||
if (value.startsWith("<![CDATA[") && value.endsWith("]]>")) {
|
||||
value = value.substring(9, value.length() - 3);
|
||||
}
|
||||
|
||||
map.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("XML解析失败:", e);
|
||||
throw new RuntimeException("XML解析失败", e);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.ruoyi.system.controller;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
|
@ -135,6 +136,10 @@ public class ServiceGoodsController extends BaseController {
|
|||
// 处理一级和二级分类ID
|
||||
processCategoryIds(serviceGoods);
|
||||
|
||||
if (serviceGoods.getPostage()==null){
|
||||
serviceGoods.setPostage(BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
return toAjax(serviceGoodsService.insertServiceGoods(serviceGoods));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import java.util.Map;
|
|||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.ruoyi.system.ControllerUtil.OrderUtil;
|
||||
import com.ruoyi.system.ControllerUtil.RefundUtil;
|
||||
import com.ruoyi.system.domain.GoodsOrder;
|
||||
import com.ruoyi.system.domain.Order;
|
||||
import com.ruoyi.system.domain.OrderLog;
|
||||
|
|
@ -50,6 +51,8 @@ public class UsersPayBeforController extends BaseController
|
|||
private IOrderLogService orderLogService;
|
||||
@Autowired
|
||||
private IGoodsOrderService goodsOrderService;
|
||||
@Autowired
|
||||
private RefundUtil refundUtil;
|
||||
|
||||
/**
|
||||
* 查询预支付列表
|
||||
|
|
@ -252,11 +255,34 @@ public class UsersPayBeforController extends BaseController
|
|||
return error("退款金额必须大于0");
|
||||
}
|
||||
|
||||
Order order = orderService.selectOrderByOrderId(orderId);
|
||||
if (order == null) {
|
||||
return error("订单不存在");
|
||||
// 首先查询支付信息
|
||||
UsersPayBefor paymentInfo = usersPayBeforService.selectUsersPayBeforByOrderId(orderId);
|
||||
if (paymentInfo == null) {
|
||||
return error("未找到支付记录");
|
||||
}
|
||||
|
||||
// 根据servicetype查询对应订单
|
||||
Order order = null;
|
||||
if (paymentInfo.getServicetype() != null) {
|
||||
if (paymentInfo.getServicetype() == 1) {
|
||||
// 服务类型为1,调用orderService根据orderid查询订单
|
||||
order = orderService.selectOrderByOrderId(orderId);
|
||||
} else if (paymentInfo.getServicetype() == 2) {
|
||||
// 服务类型为2,调用goodsOrderService根据mainOrderId查询订单
|
||||
GoodsOrder goodsOrder = new GoodsOrder();
|
||||
goodsOrder.setMainOrderId(orderId);
|
||||
List<GoodsOrder> goodsOrders = goodsOrderService.selectGoodsOrderList(goodsOrder);
|
||||
if (goodsOrders != null && !goodsOrders.isEmpty()) {
|
||||
// 使用第一个商品订单的orderId查询订单
|
||||
//order = orderService.selectOrderByOrderId(goodsOrders.get(0).getOrderId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if (order == null) {
|
||||
// return error("订单不存在");
|
||||
// }
|
||||
|
||||
List<UsersPayBefor> payRecords = usersPayBeforService.selectPayDetailsByOrderId(orderId);
|
||||
if (payRecords == null || payRecords.isEmpty()) {
|
||||
return error("未找到支付记录");
|
||||
|
|
@ -270,25 +296,35 @@ public class UsersPayBeforController extends BaseController
|
|||
}
|
||||
}
|
||||
|
||||
// 计算总支付金额
|
||||
// 计算总支付金额(减去会员优惠,因为会员优惠不参与退款)
|
||||
BigDecimal totalPaid = BigDecimal.ZERO;
|
||||
BigDecimal totalMemberDiscount = BigDecimal.ZERO;
|
||||
for (UsersPayBefor record : payRecords) {
|
||||
if (record.getAllmoney() != null) {
|
||||
totalPaid = totalPaid.add(record.getAllmoney());
|
||||
}
|
||||
// 累计会员优惠金额(不参与退款)
|
||||
if (record.getMembermoney() != null) {
|
||||
totalMemberDiscount = totalMemberDiscount.add(record.getMembermoney());
|
||||
}
|
||||
}
|
||||
|
||||
// 验证退款金额不能超过剩余可退款金额
|
||||
BigDecimal remainingRefundable = totalPaid.subtract(totalRefunded);
|
||||
|
||||
// 实际可退款金额 = 总支付金额 - 会员优惠金额
|
||||
BigDecimal actualRefundableAmount = totalPaid.subtract(totalMemberDiscount);
|
||||
|
||||
// 验证退款金额不能超过剩余可退款金额(基于实际可退金额)
|
||||
BigDecimal remainingRefundable = actualRefundableAmount.subtract(totalRefunded);
|
||||
if (totalRefund.compareTo(remainingRefundable) > 0) {
|
||||
return error("退款金额不能超过剩余可退款金额,剩余可退款:¥" + remainingRefundable);
|
||||
return error("退款金额不能超过剩余可退款金额,剩余可退款:¥" + remainingRefundable +
|
||||
"(总支付:¥" + totalPaid + ",会员优惠:¥" + totalMemberDiscount + ",已退款:¥" + totalRefunded + ")");
|
||||
}
|
||||
|
||||
// 记录退款日志
|
||||
OrderLog orderLog = new OrderLog();
|
||||
orderLog.setOrderId(orderId);
|
||||
orderLog.setOid(order.getId());
|
||||
orderLog.setTitle("统一退款");
|
||||
orderLog.setOid(999L);
|
||||
orderLog.setTitle("退款");
|
||||
orderLog.setOrdertype(paymentInfo.getServicetype());
|
||||
orderLog.setType(new BigDecimal(11));
|
||||
|
||||
// 构建退款详情
|
||||
|
|
@ -321,6 +357,7 @@ public class UsersPayBeforController extends BaseController
|
|||
refundDesc.append(",本次退款金额:¥").append(totalRefund);
|
||||
refundDesc.append(",累计已退款:¥").append(totalRefunded.add(totalRefund));
|
||||
refundDesc.append(",剩余可退款:¥").append(remainingRefundable.subtract(totalRefund));
|
||||
refundDesc.append("(会员优惠¥").append(totalMemberDiscount).append("不参与退款)");
|
||||
|
||||
refundDetails.put("name", refundDesc.toString());
|
||||
refundDetails.put("wechatRefund", wechatRefund);
|
||||
|
|
@ -332,6 +369,8 @@ public class UsersPayBeforController extends BaseController
|
|||
refundDetails.put("totalRefund", totalRefund);
|
||||
refundDetails.put("totalRefunded", totalRefunded.add(totalRefund));
|
||||
refundDetails.put("remainingRefundable", remainingRefundable.subtract(totalRefund));
|
||||
refundDetails.put("totalMemberDiscount", totalMemberDiscount);
|
||||
refundDetails.put("actualRefundableAmount", actualRefundableAmount);
|
||||
refundDetails.put("refundRemark", refundRemark);
|
||||
refundDetails.put("refundTime", new java.util.Date());
|
||||
|
||||
|
|
@ -341,28 +380,79 @@ public class UsersPayBeforController extends BaseController
|
|||
// 更新支付记录状态和退款金额
|
||||
for (UsersPayBefor record : payRecords) {
|
||||
BigDecimal currentRefunded = record.getReturnmoney() != null ? record.getReturnmoney() : BigDecimal.ZERO;
|
||||
BigDecimal newTotalRefunded = currentRefunded.add(totalRefund);
|
||||
|
||||
// 如果累计退款金额等于或超过支付金额,设置为已退款状态
|
||||
if (newTotalRefunded.compareTo(record.getAllmoney()) >= 0) {
|
||||
record.setStatus(3L); // 完全退款
|
||||
} else {
|
||||
record.setStatus(2L); // 部分退款
|
||||
|
||||
// 计算本次退款中该记录应承担的退款金额
|
||||
BigDecimal recordRefundAmount = BigDecimal.ZERO;
|
||||
|
||||
// 根据该记录的支付方式分配退款金额
|
||||
if (record.getWxmoney() != null && record.getWxmoney().compareTo(BigDecimal.ZERO) > 0) {
|
||||
BigDecimal wxRefund = wechatRefund.min(record.getWxmoney().subtract(currentRefunded));
|
||||
if (wxRefund.compareTo(BigDecimal.ZERO) > 0) {
|
||||
recordRefundAmount = recordRefundAmount.add(wxRefund);
|
||||
wechatRefund = wechatRefund.subtract(wxRefund);
|
||||
}
|
||||
}
|
||||
|
||||
if (record.getYemoney() != null && record.getYemoney().compareTo(BigDecimal.ZERO) > 0) {
|
||||
BigDecimal yeRefund = balanceRefund.min(record.getYemoney().subtract(currentRefunded));
|
||||
if (yeRefund.compareTo(BigDecimal.ZERO) > 0) {
|
||||
recordRefundAmount = recordRefundAmount.add(yeRefund);
|
||||
balanceRefund = balanceRefund.subtract(yeRefund);
|
||||
}
|
||||
}
|
||||
|
||||
if (record.getShopmoney() != null && record.getShopmoney().compareTo(BigDecimal.ZERO) > 0) {
|
||||
BigDecimal shopRefund = shoppingGoldRefund.min(record.getShopmoney().subtract(currentRefunded));
|
||||
if (shopRefund.compareTo(BigDecimal.ZERO) > 0) {
|
||||
recordRefundAmount = recordRefundAmount.add(shopRefund);
|
||||
shoppingGoldRefund = shoppingGoldRefund.subtract(shopRefund);
|
||||
}
|
||||
}
|
||||
|
||||
if (record.getServicemoney() != null && record.getServicemoney().compareTo(BigDecimal.ZERO) > 0) {
|
||||
BigDecimal serviceRefund = serviceGoldRefund.min(record.getServicemoney().subtract(currentRefunded));
|
||||
if (serviceRefund.compareTo(BigDecimal.ZERO) > 0) {
|
||||
recordRefundAmount = recordRefundAmount.add(serviceRefund);
|
||||
serviceGoldRefund = serviceGoldRefund.subtract(serviceRefund);
|
||||
}
|
||||
}
|
||||
|
||||
if (record.getCouponmoney() != null && record.getCouponmoney().compareTo(BigDecimal.ZERO) > 0) {
|
||||
BigDecimal couponRefundAmount = couponRefund.min(record.getCouponmoney().subtract(currentRefunded));
|
||||
if (couponRefundAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
recordRefundAmount = recordRefundAmount.add(couponRefundAmount);
|
||||
couponRefund = couponRefund.subtract(couponRefundAmount);
|
||||
}
|
||||
}
|
||||
|
||||
// 如果该记录有退款金额,则更新
|
||||
if (recordRefundAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
BigDecimal newTotalRefunded = currentRefunded.add(recordRefundAmount);
|
||||
|
||||
// 如果累计退款金额等于或超过支付金额,设置为已退款状态
|
||||
if (newTotalRefunded.compareTo(record.getAllmoney()) >= 0) {
|
||||
record.setStatus(3L); // 完全退款
|
||||
} else {
|
||||
record.setStatus(2L); // 部分退款
|
||||
}
|
||||
|
||||
record.setReturnmoney(newTotalRefunded);
|
||||
usersPayBeforService.updateUsersPayBefor(record);
|
||||
}
|
||||
|
||||
record.setReturnmoney(newTotalRefunded);
|
||||
usersPayBeforService.updateUsersPayBefor(record);
|
||||
}
|
||||
|
||||
// 这里可以添加实际的退款逻辑
|
||||
// 1. 微信支付退款 - 调用微信退款API
|
||||
// 2. 余额退款 - 更新用户余额
|
||||
// 3. 购物金退款 - 更新购物金余额
|
||||
// 4. 服务金退款 - 更新服务金余额
|
||||
// 5. 会员优惠退款 - 更新会员积分或优惠
|
||||
// 6. 优惠券退款 - 恢复优惠券使用状态
|
||||
// return success("退款成功", refundDetails);
|
||||
return success("退款成功");
|
||||
// 调用退款工具方法实现真实的业务退款与金额变动
|
||||
Map<String, Object> refundResult = refundUtil.processUnifiedRefund(
|
||||
orderId, wechatRefund, balanceRefund, shoppingGoldRefund,
|
||||
serviceGoldRefund, memberDiscountRefund, couponRefund, refundRemark
|
||||
);
|
||||
|
||||
if (refundResult != null && (Boolean) refundResult.get("success")) {
|
||||
return success("退款成功");
|
||||
} else {
|
||||
String errorMsg = (String) refundResult.get("message");
|
||||
return error(errorMsg != null ? errorMsg : "退款处理失败");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
return error("退款失败:" + e.getMessage());
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public class ServiceCate extends BaseEntity
|
|||
/** 父级分类ID */
|
||||
@Excel(name = "父级分类ID")
|
||||
private Long parentId;
|
||||
|
||||
private String city;
|
||||
/** 子分类列表 */
|
||||
private List<ServiceCate> children;
|
||||
|
||||
|
|
@ -184,6 +184,14 @@ public class ServiceCate extends BaseEntity
|
|||
return deletedAt;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ private String cateName;
|
|||
@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
|
||||
private Date deletedAt;
|
||||
|
||||
|
||||
private String city;
|
||||
|
||||
private BigDecimal minPrice;
|
||||
private BigDecimal maxPrice;
|
||||
|
|
@ -680,6 +680,15 @@ private String cateName;
|
|||
this.forserviceid = forserviceid;
|
||||
}
|
||||
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ public class UsersPayBefor extends BaseEntity
|
|||
private String attachments;
|
||||
private String grouporderid;
|
||||
private BigDecimal returnmoney;
|
||||
private BigDecimal postage;
|
||||
|
||||
|
||||
/** 支付订单号 */
|
||||
|
|
@ -398,6 +399,14 @@ public class UsersPayBefor extends BaseEntity
|
|||
this.returnmoney = returnmoney;
|
||||
}
|
||||
|
||||
public BigDecimal getPostage() {
|
||||
return postage;
|
||||
}
|
||||
|
||||
public void setPostage(BigDecimal postage) {
|
||||
this.postage = postage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<result property="status" column="status" />
|
||||
<result property="browse" column="browse" />
|
||||
<result property="type" column="type" />
|
||||
<result property="city" column="city" />
|
||||
<result property="parentId" column="parent_id" />
|
||||
<result property="createdAt" column="created_at" />
|
||||
<result property="updatedAt" column="updated_at" />
|
||||
|
|
@ -19,7 +20,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
</resultMap>
|
||||
|
||||
<sql id="selectServiceCateVo">
|
||||
select id, title, icon, sort, status, browse, type, parent_id, created_at, updated_at, deleted_at from service_cate
|
||||
select id, title, icon, sort, status, city,browse, type, parent_id, created_at, updated_at, deleted_at from service_cate
|
||||
</sql>
|
||||
|
||||
<select id="selectServiceCateList" parameterType="ServiceCate" resultMap="ServiceCateResult">
|
||||
|
|
@ -29,6 +30,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="status != null and status != ''"> and status=#{status}</if>
|
||||
<if test="type != null and type != ''"> and type=#{type}</if>
|
||||
<if test="parentId != null"> and parent_id=#{parentId}</if>
|
||||
<if test="city != null and city != ''"> and JSON_CONTAINS(city, #{city})</if>
|
||||
</where>
|
||||
order by parent_id ASC, sort ASC
|
||||
</select>
|
||||
|
|
@ -76,6 +78,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="status != null">status,</if>
|
||||
<if test="browse != null">browse,</if>
|
||||
<if test="type != null">type,</if>
|
||||
<if test="city != null">city,</if>
|
||||
|
||||
|
||||
<if test="parentId != null">parent_id,</if>
|
||||
<if test="deletedAt != null">deleted_at,</if>
|
||||
created_at,
|
||||
|
|
@ -88,6 +93,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="status != null">#{status},</if>
|
||||
<if test="browse != null">#{browse},</if>
|
||||
<if test="type != null">#{type},</if>
|
||||
<if test="city != null">#{city},</if>
|
||||
|
||||
<if test="parentId != null">#{parentId},</if>
|
||||
<if test="deletedAt != null">#{deletedAt},</if>
|
||||
NOW(),
|
||||
|
|
@ -104,6 +111,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="status != null">status = #{status},</if>
|
||||
<if test="browse != null">browse = #{browse},</if>
|
||||
<if test="type != null">type = #{type},</if>
|
||||
<if test="city != null">city = #{city},</if>
|
||||
|
||||
|
||||
<if test="parentId != null">parent_id = #{parentId},</if>
|
||||
<if test="deletedAt != null">deleted_at = #{deletedAt},</if>
|
||||
updated_at = NOW()
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<result property="description" column="description" />
|
||||
<result property="skuType" column="sku_type" />
|
||||
<result property="sku" column="sku" />
|
||||
<result property="city" column="city" />
|
||||
<result property="servicetype" column="servicetype" />
|
||||
|
||||
<result property="isforservice" column="isforservice" />
|
||||
|
|
@ -77,7 +78,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="isfixed != null "> and isfixed = #{isfixed}</if>
|
||||
<if test="servicetype != null "> and servicetype = #{servicetype}</if>
|
||||
|
||||
|
||||
<if test="city != null and city != ''"> and JSON_CONTAINS(city, #{city})</if>
|
||||
<if test="cateId != null "> and cate_id = #{cateId}</if>
|
||||
<if test="firstCateId != null "> and first_cate_id = #{firstCateId}</if>
|
||||
<if test="secondCateId != null "> and second_cate_id = #{secondCateId}</if>
|
||||
|
|
@ -177,6 +178,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="questions != null">questions,</if>
|
||||
<if test="isforservice != null">isforservice,</if>
|
||||
<if test="forserviceid != null">forserviceid,</if>
|
||||
<if test="city != null">city,</if>
|
||||
|
||||
created_at,
|
||||
updated_at
|
||||
|
||||
|
|
@ -224,6 +227,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="questions != null">#{questions},</if>
|
||||
<if test="isforservice != null">#{isforservice},</if>
|
||||
<if test="forserviceid != null">#{forserviceid},</if>
|
||||
<if test="city != null">#{city},</if>
|
||||
NOW(),
|
||||
NOW()
|
||||
|
||||
|
|
@ -275,6 +279,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="isfixed != null">isfixed = #{isfixed},</if>
|
||||
<if test="fixedprice != null">fixedprice = #{fixedprice},</if>
|
||||
<if test="groupnum != null">groupnum = #{groupnum},</if>
|
||||
<if test="city != null">city = #{city},</if>
|
||||
|
||||
updated_at = NOW()
|
||||
</trim>
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
|
||||
|
||||
</where>
|
||||
order by id desc
|
||||
</select>
|
||||
|
||||
<select id="selectUserUseSecondaryCardById" parameterType="Long" resultMap="UserUseSecondaryCardResult">
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<result property="lastorderid" column="lastorderid" />
|
||||
<result property="num" column="num" />
|
||||
<result property="returnmoney" column="returnmoney" />
|
||||
<result property="postage" column="postage" />
|
||||
|
||||
|
||||
|
||||
|
|
@ -43,7 +44,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
</resultMap>
|
||||
|
||||
<sql id="selectUsersPayBeforVo">
|
||||
select id, uid, paytype,grouporderid,baojiaid,num,returnmoney, lastorderid,wxmoney,serviceid,servicetype,sku,addressid,maketime,attachments, yemoney, allmoney,membermoney, shopmoney, servicemoney, couponid, couponmoney, mtcode, mtmoney, type, orderid, oid, status, paytime, paycode from users_pay_befor
|
||||
select id, uid, paytype,grouporderid,baojiaid,postage,num,returnmoney, lastorderid,wxmoney,serviceid,servicetype,sku,addressid,maketime,attachments, yemoney, allmoney,membermoney, shopmoney, servicemoney, couponid, couponmoney, mtcode, mtmoney, type, orderid, oid, status, paytime, paycode from users_pay_befor
|
||||
</sql>
|
||||
|
||||
<select id="selectUsersPayBeforList" parameterType="UsersPayBefor" resultMap="UsersPayBeforResult">
|
||||
|
|
@ -128,6 +129,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="lastorderid != null">lastorderid,</if>
|
||||
<if test="num != null">num,</if>
|
||||
<if test="returnmoney != null">returnmoney,</if>
|
||||
<if test="postage != null">postage,</if>
|
||||
|
||||
|
||||
|
||||
|
|
@ -163,6 +165,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="lastorderid != null">#{lastorderid},</if>
|
||||
<if test="num != null">#{num},</if>
|
||||
<if test="returnmoney != null">#{returnmoney},</if>
|
||||
<if test="postage != null">#{postage},</if>
|
||||
|
||||
</trim>
|
||||
</insert>
|
||||
|
|
@ -200,6 +203,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="servicetype != null">servicetype = #{servicetype},</if>
|
||||
<if test="lastorderid != null">lastorderid = #{lastorderid},</if>
|
||||
<if test="num != null">num = #{num},</if>
|
||||
<if test="postage != null">postage = #{postage},</if>
|
||||
|
||||
</trim>
|
||||
where id = #{id}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 查询自定义地区列表
|
||||
// 查询城市列表
|
||||
export function listDiyCity(query) {
|
||||
return request({
|
||||
url: '/system/DiyCity/list',
|
||||
|
|
@ -8,31 +8,16 @@ export function listDiyCity(query) {
|
|||
params: query
|
||||
})
|
||||
}
|
||||
// 查询自定义地区列表
|
||||
export function datalist(query) {
|
||||
return request({
|
||||
url: '/system/DiyCity/datalist',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询自定义地区详细
|
||||
// 查询城市详细
|
||||
export function getDiyCity(id) {
|
||||
return request({
|
||||
url: '/system/DiyCity/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
// 查询自定义地区详细
|
||||
export function getTreeDataList() {
|
||||
return request({
|
||||
url: '/system/DiyCity/getTreeData',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增自定义地区
|
||||
// 新增城市
|
||||
export function addDiyCity(data) {
|
||||
return request({
|
||||
url: '/system/DiyCity',
|
||||
|
|
@ -41,7 +26,7 @@ export function addDiyCity(data) {
|
|||
})
|
||||
}
|
||||
|
||||
// 修改自定义地区
|
||||
// 修改城市
|
||||
export function updateDiyCity(data) {
|
||||
return request({
|
||||
url: '/system/DiyCity',
|
||||
|
|
@ -50,18 +35,30 @@ export function updateDiyCity(data) {
|
|||
})
|
||||
}
|
||||
|
||||
// 删除自定义地区
|
||||
export function delDiyCity(ids) {
|
||||
// 删除城市
|
||||
export function delDiyCity(id) {
|
||||
return request({
|
||||
url: '/system/DiyCity/' + ids,
|
||||
url: '/system/DiyCity/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 手动触发师傅暂停状态自动恢复
|
||||
export function manualResumeWorkerStatus() {
|
||||
// 查询城市树结构
|
||||
export function getDiyCityTree() {
|
||||
return request({
|
||||
url: '/system/DiyCity/manualResumeWorkerStatus',
|
||||
method: 'post'
|
||||
url: '/system/DiyCity/tree',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询一级城市(parent_id=0)
|
||||
export function getFirstLevelCities() {
|
||||
return request({
|
||||
url: '/system/DiyCity/list',
|
||||
method: 'get',
|
||||
params: {
|
||||
parentId: 0,
|
||||
pageSize: 1000
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,3 +48,15 @@ export function delOrderLog(id) {
|
|||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询退款历史记录
|
||||
export function getRefundHistory(orderId) {
|
||||
return request({
|
||||
url: '/system/OrderLog/list',
|
||||
method: 'get',
|
||||
params: {
|
||||
orderId: orderId,
|
||||
title: '退款'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,13 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 根据订单ID获取支付信息
|
||||
export function getPaymentByOrderId(orderId) {
|
||||
return request({
|
||||
url: `/system/UsersPayBefor/getByOrderId/${orderId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 统一退款
|
||||
export function unifiedRefund(data) {
|
||||
return request({
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -412,7 +412,7 @@
|
|||
<!-- 统一退款对话框 -->
|
||||
<UnifiedRefundDialog
|
||||
:visible.sync="unifiedRefundDialogVisible"
|
||||
:orderId="currentRefundOrder ? currentRefundOrder.orderId : ''"
|
||||
:orderId="currentRefundOrder ? currentRefundOrder.mainOrderId : ''"
|
||||
:paymentData="currentRefundPaymentData"
|
||||
@success="handleRefundSuccess"
|
||||
/>
|
||||
|
|
@ -1326,12 +1326,12 @@ export default {
|
|||
handleUnifiedRefund(row) {
|
||||
this.currentRefundOrder = row;
|
||||
this.currentRefundPaymentData = {
|
||||
wechatAmount: row.payPrice || 0,
|
||||
balanceAmount: 0,
|
||||
shoppingGoldAmount: 0,
|
||||
serviceGoldAmount: 0,
|
||||
memberDiscountAmount: 0,
|
||||
couponAmount: 0
|
||||
wxmoney: row.payPrice || 0,
|
||||
yemoney: 0,
|
||||
shopmoney: 0,
|
||||
servicemoney: 0,
|
||||
membermoney: 0,
|
||||
couponmoney: 0
|
||||
};
|
||||
this.unifiedRefundDialogVisible = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -225,12 +225,10 @@
|
|||
<el-option v-for="cate in serviceCateList" :key="cate.id" :label="cate.title" :value="cate.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="保证金" prop="margin">
|
||||
<el-input v-model="form.margin" placeholder="请输入保证金" />
|
||||
</el-form-item>
|
||||
<el-form-item label="所需技能" prop="skillIds">
|
||||
<el-input v-model="form.skillIds" type="textarea" placeholder="请输入内容" />
|
||||
<el-form-item label="邮费" prop="postage">
|
||||
<el-input v-model="form.postage" placeholder="请输入邮费(0或者不输入就是包邮)" />
|
||||
</el-form-item>
|
||||
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="营销配置" name="marketing">
|
||||
<el-form-item label="销量" prop="sales" required>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 一级分类网格布局 -->
|
||||
<div class="category-grid">
|
||||
<div
|
||||
|
|
@ -32,10 +32,10 @@
|
|||
<div class="card-content">
|
||||
<!-- 图标区域 -->
|
||||
<div class="card-icon">
|
||||
<image-preview
|
||||
v-if="category.icon"
|
||||
:src="category.icon"
|
||||
:width="32"
|
||||
<image-preview
|
||||
v-if="category.icon"
|
||||
:src="category.icon"
|
||||
:width="32"
|
||||
:height="32"
|
||||
style="border-radius: 4px;"
|
||||
/>
|
||||
|
|
@ -43,14 +43,14 @@
|
|||
<i class="el-icon-folder" style="font-size: 20px; color: #409EFF;"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 信息区域 -->
|
||||
<div class="card-info">
|
||||
<div class="card-title">{{ category.title }}</div>
|
||||
<div class="card-meta">
|
||||
<dict-tag :options="dict.type.service_sate_type" :value="category.type" size="mini"/>
|
||||
<el-tag
|
||||
size="mini"
|
||||
<el-tag
|
||||
size="mini"
|
||||
:type="category.status === 1 ? 'success' : 'danger'"
|
||||
effect="light"
|
||||
>
|
||||
|
|
@ -68,16 +68,32 @@
|
|||
<i class="el-icon-sort"></i> {{ category.sort }}
|
||||
</span>
|
||||
</div>
|
||||
<!-- 城市显示 -->
|
||||
<div class="card-cities" v-if="getCityArray(category.city) && getCityArray(category.city).length > 0">
|
||||
<el-tag
|
||||
v-for="cityId in getCityArray(category.city)"
|
||||
:key="cityId"
|
||||
size="mini"
|
||||
type="info"
|
||||
effect="light"
|
||||
style="margin: 1px; font-size: 10px;"
|
||||
>
|
||||
{{ getCityNameById(cityId) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<div class="card-cities" v-else>
|
||||
<span style="font-size: 10px; color: #c0c4cc;">全部城市</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 操作区域 -->
|
||||
<div class="card-actions">
|
||||
<div class="action-buttons">
|
||||
<el-tooltip content="编辑分类" placement="top">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="primary"
|
||||
<el-button
|
||||
size="mini"
|
||||
type="primary"
|
||||
plain
|
||||
@click.stop="handleEditFirstLevel(category)"
|
||||
class="action-btn edit-btn"
|
||||
|
|
@ -86,9 +102,9 @@
|
|||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除分类" placement="top">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="danger"
|
||||
<el-button
|
||||
size="mini"
|
||||
type="danger"
|
||||
plain
|
||||
@click.stop="handleDeleteFirstLevel(category)"
|
||||
class="action-btn delete-btn"
|
||||
|
|
@ -100,7 +116,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 显示更多按钮和统计信息 -->
|
||||
<div class="grid-footer">
|
||||
<div class="grid-stats">
|
||||
|
|
@ -109,17 +125,17 @@
|
|||
</span>
|
||||
</div>
|
||||
<div class="grid-actions">
|
||||
<el-button
|
||||
<el-button
|
||||
v-if="shouldShowMoreButton"
|
||||
type="text"
|
||||
type="text"
|
||||
size="small"
|
||||
@click="showAllFirstLevel = true"
|
||||
>
|
||||
<i class="el-icon-arrow-down"></i> 显示更多 ({{ filteredFirstLevelList.length - defaultShowCount }})
|
||||
</el-button>
|
||||
<el-button
|
||||
<el-button
|
||||
v-if="showAllFirstLevel && !firstLevelSearch"
|
||||
type="text"
|
||||
type="text"
|
||||
size="small"
|
||||
@click="showAllFirstLevel = false"
|
||||
>
|
||||
|
|
@ -127,7 +143,7 @@
|
|||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 空状态 -->
|
||||
<div v-if="firstLevelList.length === 0" class="empty-state">
|
||||
<i class="el-icon-folder-add" style="font-size: 48px; color: #ddd;"></i>
|
||||
|
|
@ -153,10 +169,10 @@
|
|||
prefix-icon="el-icon-search"
|
||||
style="width: 200px; margin-right: 10px;"
|
||||
/>
|
||||
<el-button
|
||||
v-if="selectedFirstLevel"
|
||||
type="success"
|
||||
size="small"
|
||||
<el-button
|
||||
v-if="selectedFirstLevel"
|
||||
type="success"
|
||||
size="small"
|
||||
@click="handleAddSecondLevel"
|
||||
>
|
||||
<i class="el-icon-plus"></i> 添加二级分类
|
||||
|
|
@ -172,9 +188,9 @@
|
|||
|
||||
<!-- 二级分类表格 -->
|
||||
<div v-else>
|
||||
<el-table
|
||||
:data="filteredSecondLevelList"
|
||||
border
|
||||
<el-table
|
||||
:data="filteredSecondLevelList"
|
||||
border
|
||||
style="width: 100%"
|
||||
:empty-text="'暂无二级分类'"
|
||||
>
|
||||
|
|
@ -185,20 +201,20 @@
|
|||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
|
||||
<el-table-column prop="title" label="分类名称" width="150">
|
||||
<template slot-scope="scope">
|
||||
<i class="el-icon-document" style="margin-right: 8px; color: #67C23A;"></i>
|
||||
{{ scope.row.title }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="60" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-tag size="mini" effect="plain">{{ scope.row.sort }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
|
||||
<el-table-column label="状态" width="60" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-switch
|
||||
|
|
@ -209,26 +225,44 @@
|
|||
></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
|
||||
<el-table-column prop="browse" label="浏览量" width="70" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.browse || 0 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
|
||||
<el-table-column label="类型" width="80" align="center">
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :options="dict.type.service_sate_type" :value="scope.row.type"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
|
||||
<el-table-column prop="icon" label="图标" width="60" align="center">
|
||||
<template slot-scope="scope">
|
||||
<image-preview v-if="scope.row.icon" :src="scope.row.icon" :width="30" :height="30"/>
|
||||
<span v-else style="color: #ccc;">无</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
|
||||
<el-table-column label="适用城市" width="120" align="center">
|
||||
<template slot-scope="scope">
|
||||
<div v-if="getCityArray(scope.row.city) && getCityArray(scope.row.city).length > 0">
|
||||
<el-tag
|
||||
v-for="cityId in getCityArray(scope.row.city)"
|
||||
:key="cityId"
|
||||
size="mini"
|
||||
type="info"
|
||||
effect="light"
|
||||
style="margin: 2px;"
|
||||
>
|
||||
{{ getCityNameById(cityId) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<span v-else style="color: #ccc; font-size: 12px;">全部城市</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作" width="100" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="text" @click="handleEditSecondLevel(scope.row)">
|
||||
|
|
@ -254,7 +288,7 @@
|
|||
</el-card>
|
||||
|
||||
<!-- 添加/编辑一级分类对话框 -->
|
||||
<el-dialog :title="firstLevelTitle" :visible.sync="firstLevelDialogVisible" width="500px">
|
||||
<el-dialog :title="firstLevelTitle" :visible.sync="firstLevelDialogVisible" width="600px">
|
||||
<el-form ref="firstLevelForm" :model="firstLevelForm" :rules="firstLevelRules" label-width="100px" :validate-on-rule-change="false">
|
||||
<el-form-item label="分类名称" prop="title">
|
||||
<el-input v-model="firstLevelForm.title" placeholder="请输入一级分类名称" />
|
||||
|
|
@ -280,6 +314,67 @@
|
|||
>{{dict.label}}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="适用城市" prop="city">
|
||||
<el-select
|
||||
v-model="firstLevelForm.city"
|
||||
multiple
|
||||
filterable
|
||||
placeholder="请选择适用城市"
|
||||
style="width: 100%;"
|
||||
:loading="cityLoading"
|
||||
@change="handleFirstLevelCityChange"
|
||||
:collapse-tags-tooltip="true"
|
||||
:class="{ 'city-select-loading': cityLoading }"
|
||||
no-data-text="暂无城市数据,请检查网络连接或联系管理员"
|
||||
>
|
||||
<el-option
|
||||
v-for="city in cityList"
|
||||
:key="city.id"
|
||||
:label="city.title"
|
||||
:value="city.id"
|
||||
>
|
||||
<span style="float: left">{{ city.title }}</span>
|
||||
<span style="float: right; color: #8492a6; font-size: 13px">
|
||||
<i class="el-icon-location"></i>
|
||||
</span>
|
||||
</el-option>
|
||||
<!-- 空数据提示 -->
|
||||
<el-option v-if="!cityLoading && cityList.length === 0" disabled>
|
||||
<span style="color: #c0c4cc;">暂无城市数据</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<!-- 调试信息 -->
|
||||
<div style="font-size: 12px; color: #909399; margin-top: 5px;">
|
||||
<i class="el-icon-info"></i> 城市列表状态: {{ cityLoading ? '加载中...' : `已加载 ${cityList.length} 个城市` }}
|
||||
<el-button
|
||||
v-if="!cityLoading && cityList.length === 0"
|
||||
type="text"
|
||||
size="mini"
|
||||
@click="getCityList"
|
||||
style="margin-left: 10px;"
|
||||
>
|
||||
<i class="el-icon-refresh"></i> 重新加载
|
||||
</el-button>
|
||||
</div>
|
||||
<div style="font-size: 12px; color: #909399; margin-top: 5px;">
|
||||
<i class="el-icon-info"></i> 可多选城市,不选择则适用于所有城市。一级分类的城市设置会影响其下所有二级分类的默认城市范围。
|
||||
</div>
|
||||
<!-- 已选择的城市标签显示 -->
|
||||
<div v-if="firstLevelForm.city && firstLevelForm.city.length > 0" class="city-tags-container">
|
||||
<el-tag
|
||||
v-for="cityId in firstLevelForm.city"
|
||||
:key="cityId"
|
||||
size="small"
|
||||
type="success"
|
||||
effect="light"
|
||||
closable
|
||||
@close="removeFirstLevelCity(cityId)"
|
||||
class="city-tag"
|
||||
>
|
||||
{{ getCityNameById(cityId) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="图标" prop="icon">
|
||||
<image-upload v-model="firstLevelForm.icon"/>
|
||||
</el-form-item>
|
||||
|
|
@ -291,21 +386,21 @@
|
|||
</el-dialog>
|
||||
|
||||
<!-- 添加/编辑二级分类对话框 -->
|
||||
<el-dialog :title="secondLevelTitle" :visible.sync="secondLevelDialogVisible" width="500px">
|
||||
<el-dialog :title="secondLevelTitle" :visible.sync="secondLevelDialogVisible" width="600px">
|
||||
<el-form ref="secondLevelForm" :model="secondLevelForm" :rules="secondLevelRules" label-width="100px">
|
||||
<el-form-item label="父级分类">
|
||||
<el-input
|
||||
:value="selectedFirstLevel ? selectedFirstLevel.title : ''"
|
||||
<el-input
|
||||
:value="selectedFirstLevel ? selectedFirstLevel.title : ''"
|
||||
disabled
|
||||
>
|
||||
<template slot="prepend">
|
||||
<i class="el-icon-folder" style="color: #409EFF;"></i>
|
||||
</template>
|
||||
<template slot="append">
|
||||
<dict-tag
|
||||
v-if="selectedFirstLevel && selectedFirstLevel.type !== null"
|
||||
:options="dict.type.service_sate_type"
|
||||
:value="selectedFirstLevel.type"
|
||||
<dict-tag
|
||||
v-if="selectedFirstLevel && selectedFirstLevel.type !== null"
|
||||
:options="dict.type.service_sate_type"
|
||||
:value="selectedFirstLevel.type"
|
||||
size="mini"
|
||||
/>
|
||||
</template>
|
||||
|
|
@ -327,15 +422,75 @@
|
|||
<el-input-number v-model="secondLevelForm.browse" :min="0" style="width: 100%;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="类型" prop="type">
|
||||
<el-input
|
||||
:value="getTypeLabel(secondLevelForm.type)"
|
||||
disabled
|
||||
<el-input
|
||||
:value="getTypeLabel(secondLevelForm.type)"
|
||||
disabled
|
||||
placeholder="跟随父级分类类型"
|
||||
/>
|
||||
<div style="font-size: 12px; color: #909399; margin-top: 5px;">
|
||||
<i class="el-icon-info"></i> 二级分类的类型自动跟随父级分类
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="适用城市" prop="city">
|
||||
<el-select
|
||||
v-model="secondLevelForm.city"
|
||||
multiple
|
||||
filterable
|
||||
placeholder="请选择适用城市"
|
||||
style="width: 100%;"
|
||||
:loading="cityLoading"
|
||||
@change="handleCityChange"
|
||||
:class="{ 'city-select-loading': cityLoading }"
|
||||
no-data-text="暂无城市数据,请检查网络连接或联系管理员"
|
||||
>
|
||||
<!-- <el-option-->
|
||||
<!-- v-for="city in cityList"-->
|
||||
<!-- :key="city.id"-->
|
||||
<!-- :label="city.title"-->
|
||||
<!-- :value="city.id"-->
|
||||
<!-- >-->
|
||||
<!-- <span style="float: left">{{ city.title }}</span>-->
|
||||
<!-- <span style="float: right; color: #8492a6; font-size: 13px">-->
|
||||
<!-- <i class="el-icon-location"></i>-->
|
||||
<!-- </span>-->
|
||||
<!-- </el-option>-->
|
||||
<!-- <!– 空数据提示 –>-->
|
||||
<!-- <el-option v-if="!cityLoading && cityList.length === 0" disabled>-->
|
||||
<!-- <span style="color: #c0c4cc;">暂无城市数据</span>-->
|
||||
<!-- </el-option>-->
|
||||
</el-select>
|
||||
<!-- 调试信息 -->
|
||||
<div style="font-size: 12px; color: #909399; margin-top: 5px;">
|
||||
<i class="el-icon-info"></i> 城市列表状态: {{ cityLoading ? '加载中...' : `已加载 ${cityList.length} 个城市` }}
|
||||
<el-button
|
||||
v-if="!cityLoading && cityList.length === 0"
|
||||
type="text"
|
||||
size="mini"
|
||||
@click="getCityList"
|
||||
style="margin-left: 10px;"
|
||||
>
|
||||
<i class="el-icon-refresh"></i> 重新加载
|
||||
</el-button>
|
||||
</div>
|
||||
<div style="font-size: 12px; color: #909399; margin-top: 5px;">
|
||||
<i class="el-icon-info"></i> 可多选城市,不选择则适用于所有城市。二级分类的城市设置会继承父级分类的城市范围,但可以进一步限制。
|
||||
</div>
|
||||
<!-- 已选择的城市标签显示 -->
|
||||
<div v-if="secondLevelForm.city && secondLevelForm.city.length > 0" class="city-tags-container">
|
||||
<el-tag
|
||||
v-for="cityId in secondLevelForm.city"
|
||||
:key="cityId"
|
||||
size="small"
|
||||
type="success"
|
||||
effect="light"
|
||||
closable
|
||||
@close="removeCity(cityId)"
|
||||
class="city-tag"
|
||||
>
|
||||
{{ getCityNameById(cityId) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="图标" prop="icon">
|
||||
<image-upload v-model="secondLevelForm.icon"/>
|
||||
</el-form-item>
|
||||
|
|
@ -350,6 +505,7 @@
|
|||
|
||||
<script>
|
||||
import { listServiceCate, getServiceCate, delServiceCate, addServiceCate, updateServiceCate, changefenleiStatus } from "@/api/system/ServiceCate"
|
||||
import { getFirstLevelCities } from "@/api/system/DiyCity"
|
||||
import { parseTime } from "@/utils/index"
|
||||
|
||||
export default {
|
||||
|
|
@ -371,7 +527,7 @@ export default {
|
|||
type: [{ required: true, message: "类型不能为空", trigger: "change" }],
|
||||
},
|
||||
firstLevelLoading: false,
|
||||
|
||||
|
||||
// 二级分类相关
|
||||
secondLevelList: [],
|
||||
secondLevelSearch: "",
|
||||
|
|
@ -384,33 +540,37 @@ export default {
|
|||
status: [{ required: true, message: "状态不能为空", trigger: "change" }],
|
||||
type: [{ required: true, message: "类型不能为空", trigger: "change" }],
|
||||
},
|
||||
|
||||
|
||||
// 二级分类分页相关
|
||||
secondLevelTotal: 0,
|
||||
secondLevelPageNum: 1,
|
||||
secondLevelPageSize: 10,
|
||||
|
||||
|
||||
// 所有分类数据(用于统计子分类数量)
|
||||
allCategoryList: [],
|
||||
|
||||
|
||||
// 显示更多控制
|
||||
showAllFirstLevel: false,
|
||||
defaultShowCount: 20
|
||||
defaultShowCount: 20,
|
||||
|
||||
// 城市相关
|
||||
cityList: [],
|
||||
cityLoading: false,
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
computed: {
|
||||
// 过滤后的一级分类
|
||||
filteredFirstLevelList() {
|
||||
let filtered = this.firstLevelList
|
||||
if (this.firstLevelSearch) {
|
||||
filtered = this.firstLevelList.filter(item =>
|
||||
filtered = this.firstLevelList.filter(item =>
|
||||
item.title.toLowerCase().includes(this.firstLevelSearch.toLowerCase())
|
||||
)
|
||||
}
|
||||
return filtered
|
||||
},
|
||||
|
||||
|
||||
// 显示的一级分类(考虑显示更多逻辑)
|
||||
displayedFirstLevelList() {
|
||||
if (this.showAllFirstLevel || this.firstLevelSearch) {
|
||||
|
|
@ -418,35 +578,36 @@ export default {
|
|||
}
|
||||
return this.filteredFirstLevelList.slice(0, this.defaultShowCount)
|
||||
},
|
||||
|
||||
|
||||
// 是否显示"显示更多"按钮
|
||||
shouldShowMoreButton() {
|
||||
return !this.showAllFirstLevel &&
|
||||
!this.firstLevelSearch &&
|
||||
return !this.showAllFirstLevel &&
|
||||
!this.firstLevelSearch &&
|
||||
this.filteredFirstLevelList.length > this.defaultShowCount
|
||||
},
|
||||
|
||||
|
||||
// 过滤后的二级分类
|
||||
filteredSecondLevelList() {
|
||||
if (!this.secondLevelSearch) return this.secondLevelList
|
||||
return this.secondLevelList.filter(item =>
|
||||
return this.secondLevelList.filter(item =>
|
||||
item.title.toLowerCase().includes(this.secondLevelSearch.toLowerCase())
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
created() {
|
||||
this.getFirstLevelList()
|
||||
this.getCityList()
|
||||
},
|
||||
|
||||
|
||||
methods: {
|
||||
// 时间格式化方法
|
||||
parseTime,
|
||||
|
||||
|
||||
/** 获取一级分类列表 */
|
||||
getFirstLevelList() {
|
||||
// 获取一级分类(不分页)
|
||||
const params = {
|
||||
const params = {
|
||||
parentId: 0,
|
||||
pageNum: 1,
|
||||
pageSize: 1000 // 设置一个很大的数值,确保获取所有一级分类
|
||||
|
|
@ -454,7 +615,7 @@ export default {
|
|||
listServiceCate(params).then(response => {
|
||||
this.firstLevelList = response.rows || []
|
||||
})
|
||||
|
||||
|
||||
// 获取所有分类数据用于统计(不分页)
|
||||
listServiceCate({
|
||||
pageNum: 1,
|
||||
|
|
@ -463,10 +624,10 @@ export default {
|
|||
this.allCategoryList = response.rows || []
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
/** 获取二级分类列表 */
|
||||
getSecondLevelList(parentId) {
|
||||
const params = {
|
||||
const params = {
|
||||
parentId: parentId,
|
||||
pageNum: this.secondLevelPageNum,
|
||||
pageSize: this.secondLevelPageSize
|
||||
|
|
@ -476,7 +637,7 @@ export default {
|
|||
this.secondLevelTotal = response.total || 0
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
/** 选择一级分类 */
|
||||
selectFirstLevel(category) {
|
||||
this.selectedFirstLevel = category
|
||||
|
|
@ -486,12 +647,12 @@ export default {
|
|||
this.secondLevelSearch = ""
|
||||
this.getSecondLevelList(category.id)
|
||||
},
|
||||
|
||||
|
||||
/** 获取子分类数量 */
|
||||
getSubCategoryCount(parentId) {
|
||||
return this.allCategoryList.filter(item => item.parentId === parentId).length
|
||||
},
|
||||
|
||||
|
||||
/** 状态修改 */
|
||||
handleStatusChange(row) {
|
||||
let text = row.status === 0 ? "启用" : "停用"
|
||||
|
|
@ -503,26 +664,44 @@ export default {
|
|||
row.status = row.status === 0 ? 1 : 0
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
// ========== 一级分类操作 ==========
|
||||
|
||||
|
||||
/** 添加一级分类 */
|
||||
handleAddFirstLevel() {
|
||||
this.resetFirstLevelForm()
|
||||
// 确保城市列表已加载
|
||||
if (this.cityList.length === 0) {
|
||||
this.getCityList()
|
||||
}
|
||||
this.firstLevelDialogVisible = true
|
||||
this.firstLevelTitle = "添加一级分类"
|
||||
},
|
||||
|
||||
|
||||
/** 编辑一级分类 */
|
||||
handleEditFirstLevel(row) {
|
||||
this.resetFirstLevelForm()
|
||||
// 确保城市列表已加载
|
||||
if (this.cityList.length === 0) {
|
||||
this.getCityList()
|
||||
}
|
||||
getServiceCate(row.id).then(response => {
|
||||
this.firstLevelForm = response.data
|
||||
// 确保城市字段是数组格式
|
||||
if (this.firstLevelForm.city && typeof this.firstLevelForm.city === 'string') {
|
||||
try {
|
||||
this.firstLevelForm.city = JSON.parse(this.firstLevelForm.city);
|
||||
} catch (e) {
|
||||
this.firstLevelForm.city = [];
|
||||
}
|
||||
} else if (!this.firstLevelForm.city) {
|
||||
this.firstLevelForm.city = [];
|
||||
}
|
||||
this.firstLevelDialogVisible = true
|
||||
this.firstLevelTitle = "编辑一级分类"
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
/** 删除一级分类 */
|
||||
handleDeleteFirstLevel(row) {
|
||||
// 检查是否有二级分类
|
||||
|
|
@ -532,7 +711,7 @@ export default {
|
|||
this.$modal.msgError("该分类下还有二级分类,不能删除")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
this.$modal.confirm('是否确认删除分类"' + row.title + '"?').then(function() {
|
||||
return delServiceCate(row.id)
|
||||
}).then(() => {
|
||||
|
|
@ -554,12 +733,18 @@ export default {
|
|||
}).catch(() => {})
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
/** 提交一级分类 */
|
||||
submitFirstLevel() {
|
||||
this.$refs["firstLevelForm"].validate(valid => {
|
||||
if (valid) {
|
||||
this.firstLevelForm.parentId = 0 // 强制设置为一级分类
|
||||
|
||||
// 处理城市字段,确保是JSON字符串格式
|
||||
if (Array.isArray(this.firstLevelForm.city)) {
|
||||
this.firstLevelForm.city = JSON.stringify(this.firstLevelForm.city);
|
||||
}
|
||||
|
||||
this.firstLevelLoading = true; // 防止重复提交
|
||||
const done = () => { this.firstLevelLoading = false; };
|
||||
const handleError = (err) => {
|
||||
|
|
@ -598,7 +783,7 @@ export default {
|
|||
}
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
/** 重置一级分类表单 */
|
||||
resetFirstLevelForm() {
|
||||
this.firstLevelForm = {
|
||||
|
|
@ -609,34 +794,53 @@ export default {
|
|||
status: 1,
|
||||
browse: 0,
|
||||
type: 1,
|
||||
parentId: 0
|
||||
parentId: 0,
|
||||
city: [] // 重置城市为空数组
|
||||
}
|
||||
this.resetForm("firstLevelForm")
|
||||
},
|
||||
|
||||
|
||||
// ========== 二级分类操作 ==========
|
||||
|
||||
|
||||
/** 添加二级分类 */
|
||||
handleAddSecondLevel() {
|
||||
this.resetSecondLevelForm()
|
||||
// 自动设置父级分类的类型
|
||||
this.secondLevelForm.type = this.selectedFirstLevel ? this.selectedFirstLevel.type : 1
|
||||
// 确保城市列表已加载
|
||||
if (this.cityList.length === 0) {
|
||||
this.getCityList()
|
||||
}
|
||||
this.secondLevelDialogVisible = true
|
||||
this.secondLevelTitle = "添加二级分类"
|
||||
},
|
||||
|
||||
|
||||
/** 编辑二级分类 */
|
||||
handleEditSecondLevel(row) {
|
||||
this.resetSecondLevelForm()
|
||||
// 确保城市列表已加载
|
||||
if (this.cityList.length === 0) {
|
||||
this.getCityList()
|
||||
}
|
||||
getServiceCate(row.id).then(response => {
|
||||
this.secondLevelForm = response.data
|
||||
// 确保类型跟随一级分类
|
||||
this.secondLevelForm.type = this.selectedFirstLevel ? this.selectedFirstLevel.type : this.secondLevelForm.type
|
||||
// 确保城市字段是数组格式
|
||||
if (this.secondLevelForm.city && typeof this.secondLevelForm.city === 'string') {
|
||||
try {
|
||||
this.secondLevelForm.city = JSON.parse(this.secondLevelForm.city);
|
||||
} catch (e) {
|
||||
this.secondLevelForm.city = [];
|
||||
}
|
||||
} else if (!this.secondLevelForm.city) {
|
||||
this.secondLevelForm.city = [];
|
||||
}
|
||||
this.secondLevelDialogVisible = true
|
||||
this.secondLevelTitle = "编辑二级分类"
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
/** 删除二级分类 */
|
||||
handleDeleteSecondLevel(row) {
|
||||
this.$modal.confirm('是否确认删除分类"' + row.title + '"?').then(function() {
|
||||
|
|
@ -650,14 +854,19 @@ export default {
|
|||
})
|
||||
}).catch(() => {})
|
||||
},
|
||||
|
||||
|
||||
/** 提交二级分类 */
|
||||
submitSecondLevel() {
|
||||
this.$refs["secondLevelForm"].validate(valid => {
|
||||
if (valid) {
|
||||
this.secondLevelForm.parentId = this.selectedFirstLevel ? this.selectedFirstLevel.id : 0 // 设置父级ID
|
||||
this.secondLevelForm.type = this.selectedFirstLevel ? this.selectedFirstLevel.type : this.secondLevelForm.type // 确保类型跟随一级分类
|
||||
|
||||
|
||||
// 处理城市字段,确保是JSON字符串格式
|
||||
if (Array.isArray(this.secondLevelForm.city)) {
|
||||
this.secondLevelForm.city = JSON.stringify(this.secondLevelForm.city);
|
||||
}
|
||||
|
||||
if (this.secondLevelForm.id != null) {
|
||||
updateServiceCate(this.secondLevelForm).then(response => {
|
||||
this.$modal.msgSuccess("修改成功")
|
||||
|
|
@ -682,7 +891,7 @@ export default {
|
|||
}
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
/** 重置二级分类表单 */
|
||||
resetSecondLevelForm() {
|
||||
this.secondLevelForm = {
|
||||
|
|
@ -693,7 +902,8 @@ export default {
|
|||
status: 1,
|
||||
browse: 0,
|
||||
type: null, // 不预设类型,在添加时设置
|
||||
parentId: null
|
||||
parentId: null,
|
||||
city: [] // 重置城市为空数组
|
||||
}
|
||||
this.resetForm("secondLevelForm")
|
||||
},
|
||||
|
|
@ -703,6 +913,71 @@ export default {
|
|||
const dict = this.dict.type.service_sate_type
|
||||
const found = dict.find(item => parseInt(item.value) === value)
|
||||
return found ? found.label : value
|
||||
},
|
||||
|
||||
/** 根据城市ID获取城市名称 */
|
||||
getCityNameById(id) {
|
||||
const city = this.cityList.find(item => item.id === id);
|
||||
return city ? city.title : id; // 修复:使用title而不是name
|
||||
},
|
||||
|
||||
/** 获取城市列表 */
|
||||
getCityList() {
|
||||
console.log('开始获取城市列表...');
|
||||
this.cityLoading = true;
|
||||
getFirstLevelCities().then(response => {
|
||||
console.log('城市API响应:', response);
|
||||
// 修复:使用response.rows而不是response.data
|
||||
this.cityList = response.rows || [];
|
||||
console.log('设置城市列表:', this.cityList);
|
||||
this.cityLoading = false;
|
||||
}).catch(error => {
|
||||
console.error("获取城市列表失败:", error);
|
||||
this.cityLoading = false;
|
||||
});
|
||||
},
|
||||
|
||||
/** 城市选择变化处理 */
|
||||
handleCityChange(value) {
|
||||
this.secondLevelForm.city = value;
|
||||
console.log('选择的城市:', value);
|
||||
},
|
||||
|
||||
/** 移除城市标签 */
|
||||
removeCity(cityId) {
|
||||
const index = this.secondLevelForm.city.indexOf(cityId);
|
||||
if (index > -1) {
|
||||
this.secondLevelForm.city.splice(index, 1);
|
||||
}
|
||||
},
|
||||
|
||||
/** 获取城市数组,处理字符串和数组两种格式 */
|
||||
getCityArray(cityString) {
|
||||
if (typeof cityString === 'string') {
|
||||
try {
|
||||
return JSON.parse(cityString);
|
||||
} catch (e) {
|
||||
console.error("解析城市字符串失败:", e);
|
||||
return [];
|
||||
}
|
||||
} else if (Array.isArray(cityString)) {
|
||||
return cityString;
|
||||
}
|
||||
return [];
|
||||
},
|
||||
|
||||
/** 一级分类城市选择变化处理 */
|
||||
handleFirstLevelCityChange(value) {
|
||||
this.firstLevelForm.city = value;
|
||||
console.log('一级分类选择的城市:', value);
|
||||
},
|
||||
|
||||
/** 移除一级分类城市标签 */
|
||||
removeFirstLevelCity(cityId) {
|
||||
const index = this.firstLevelForm.city.indexOf(cityId);
|
||||
if (index > -1) {
|
||||
this.firstLevelForm.city.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -814,6 +1089,23 @@ export default {
|
|||
gap: 2px;
|
||||
}
|
||||
|
||||
.card-cities {
|
||||
margin-top: 4px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: 2px;
|
||||
max-height: 40px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.card-cities .el-tag {
|
||||
max-width: 60px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.card-actions {
|
||||
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.06);
|
||||
|
|
@ -928,4 +1220,36 @@ export default {
|
|||
.clearfix:after {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/* 城市选择相关样式 */
|
||||
.el-select .el-select__tags {
|
||||
max-width: calc(100% - 30px);
|
||||
}
|
||||
|
||||
.city-tags-container {
|
||||
margin-top: 8px;
|
||||
padding: 8px;
|
||||
background: #f8f9fa;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #e9ecef;
|
||||
}
|
||||
|
||||
.city-tag {
|
||||
margin: 2px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.city-tag:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
/* 城市选择器加载状态样式 */
|
||||
.city-select-loading .el-select__caret {
|
||||
animation: rotate 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -135,6 +135,23 @@
|
|||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="适用城市" align="center" prop="city" width="120">
|
||||
<template slot-scope="scope">
|
||||
<div v-if="getCityArray(scope.row.city) && getCityArray(scope.row.city).length > 0">
|
||||
<el-tag
|
||||
v-for="cityId in getCityArray(scope.row.city)"
|
||||
:key="cityId"
|
||||
size="mini"
|
||||
type="info"
|
||||
effect="light"
|
||||
style="margin: 2px;"
|
||||
>
|
||||
{{ getCityNameById(cityId) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<span v-else style="color: #c0c4cc; font-size: 12px;">全部城市</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="标题" align="center" prop="title" />
|
||||
<el-table-column label="图标" align="center" prop="icon" width="100">
|
||||
<template slot-scope="scope">
|
||||
|
|
@ -357,6 +374,68 @@
|
|||
</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="适用城市" prop="city">
|
||||
<el-select
|
||||
v-model="form.cityArray"
|
||||
multiple
|
||||
filterable
|
||||
placeholder="请选择适用城市"
|
||||
style="width: 100%;"
|
||||
:loading="cityLoading"
|
||||
@change="handleCityChange"
|
||||
collapse-tags
|
||||
:collapse-tags-tooltip="true"
|
||||
:class="{ 'city-select-loading': cityLoading }"
|
||||
no-data-text="暂无城市数据,请检查网络连接或联系管理员"
|
||||
>
|
||||
<el-option
|
||||
v-for="city in cityList"
|
||||
:key="city.id"
|
||||
:label="city.title"
|
||||
:value="city.id"
|
||||
>
|
||||
<span style="float: left">{{ city.title }}</span>
|
||||
<span style="float: right; color: #8492a6; font-size: 13px">
|
||||
<i class="el-icon-location"></i>
|
||||
</span>
|
||||
</el-option>
|
||||
<!-- 空数据提示 -->
|
||||
<el-option v-if="!cityLoading && cityList.length === 0" disabled>
|
||||
<span style="color: #c0c4cc;">暂无城市数据</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<!-- 调试信息 -->
|
||||
<div style="font-size: 12px; color: #909399; margin-top: 5px;">
|
||||
<i class="el-icon-info"></i> 城市列表状态: {{ cityLoading ? '加载中...' : `已加载 ${cityList.length} 个城市` }}
|
||||
<el-button
|
||||
v-if="!cityLoading && cityList.length === 0"
|
||||
type="text"
|
||||
size="mini"
|
||||
@click="getCityList"
|
||||
style="margin-left: 10px;"
|
||||
>
|
||||
<i class="el-icon-refresh"></i> 重新加载
|
||||
</el-button>
|
||||
</div>
|
||||
<div style="font-size: 12px; color: #909399; margin-top: 5px;">
|
||||
<i class="el-icon-info"></i> 可多选城市,不选择则适用于所有城市
|
||||
</div>
|
||||
<!-- 已选择的城市标签显示 -->
|
||||
<div v-if="form.cityArray && form.cityArray.length > 0" class="city-tags-container">
|
||||
<el-tag
|
||||
v-for="cityId in form.cityArray"
|
||||
:key="cityId"
|
||||
size="small"
|
||||
type="success"
|
||||
effect="light"
|
||||
closable
|
||||
@close="removeCity(cityId)"
|
||||
class="city-tag"
|
||||
>
|
||||
{{ getCityNameById(cityId) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="保证金" prop="margin">
|
||||
<el-input v-model="form.margin" placeholder="请输入保证金" />
|
||||
</el-form-item>
|
||||
|
|
@ -720,6 +799,7 @@
|
|||
<script>
|
||||
import { listServiceGoods, getServiceGoods, delServiceGoods, addServiceGoods, updateServiceGoods ,changefenleiStatus,selectServiceCateList,getSiteSkillList,getlistworkerlist} from "@/api/system/ServiceGoods"
|
||||
import { getAllServiceCateList, addServiceCate } from "@/api/system/ServiceCate"
|
||||
import { getFirstLevelCities } from "@/api/system/DiyCity"
|
||||
import Editor from '@/components/Editor'
|
||||
|
||||
export default {
|
||||
|
|
@ -807,6 +887,8 @@ export default {
|
|||
questionsArray: [], // 问答数组
|
||||
firstCateId: null, // 一级分类ID
|
||||
secondCateId: null, // 二级分类ID
|
||||
city: null, // 城市JSON字符串
|
||||
cityArray: [], // 城市数组
|
||||
},
|
||||
// 表单校验
|
||||
rules: {
|
||||
|
|
@ -852,6 +934,10 @@ export default {
|
|||
newBasicTag: '',
|
||||
saveTimeout: null, // 用于防抖的定时器
|
||||
disableGroupAndFixed: false, // 控制拼团和秒杀是否禁用
|
||||
|
||||
// 城市相关
|
||||
cityList: [],
|
||||
cityLoading: false,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
|
@ -861,6 +947,7 @@ export default {
|
|||
this.testSkillList();
|
||||
this.getlistworkerdatalist();
|
||||
this.testJsonConversion(); // 测试JSON转换功能
|
||||
this.getCityList(); // 获取城市列表
|
||||
},
|
||||
watch: {
|
||||
// 监听技能数组变化,确保UI同步
|
||||
|
|
@ -955,10 +1042,13 @@ export default {
|
|||
deletedAt: null,
|
||||
questionsArray: [], // 问答数组
|
||||
questions: null, // 问答JSON字符串
|
||||
city: null, // 城市JSON字符串
|
||||
cityArray: [], // 城市数组
|
||||
}
|
||||
// 使用Vue.set确保响应式
|
||||
this.$set(this.form, 'skillIdsArray', []);
|
||||
this.$set(this.form, 'basicArray', []);
|
||||
this.$set(this.form, 'cityArray', []); // 重置城市数组
|
||||
// 重置基检现象标签输入状态
|
||||
this.showBasicInput = false;
|
||||
this.newBasicTag = '';
|
||||
|
|
@ -1033,6 +1123,7 @@ export default {
|
|||
this.$set(this.form, 'questionsArray', []);
|
||||
this.$set(this.form, 'firstCateId', null);
|
||||
this.$set(this.form, 'secondCateId', null);
|
||||
this.$set(this.form, 'cityArray', []); // 初始化城市数组
|
||||
if (this.siteSkillList.length === 0) {
|
||||
this.getSiteSkillList();
|
||||
}
|
||||
|
|
@ -1200,6 +1291,47 @@ export default {
|
|||
this.$set(this.form, 'basicArray', []);
|
||||
}
|
||||
|
||||
// 处理城市数据转换:将JSON字符串转为数组
|
||||
if (this.form.city) {
|
||||
try {
|
||||
let cityArray = [];
|
||||
console.log('原始城市数据:', this.form.city, '类型:', typeof this.form.city);
|
||||
|
||||
if (typeof this.form.city === 'string') {
|
||||
// 尝试解析JSON格式
|
||||
try {
|
||||
const parsedCity = JSON.parse(this.form.city);
|
||||
if (Array.isArray(parsedCity)) {
|
||||
cityArray = parsedCity.map(id => parseInt(id)).filter(id => !isNaN(id));
|
||||
} else {
|
||||
// 如果不是JSON数组,尝试逗号分隔的字符串
|
||||
cityArray = this.form.city.split(',').map(id => {
|
||||
const numId = parseInt(id.trim());
|
||||
return isNaN(numId) ? null : numId;
|
||||
}).filter(id => id !== null);
|
||||
}
|
||||
} catch (jsonError) {
|
||||
// JSON解析失败,尝试逗号分隔的字符串
|
||||
cityArray = this.form.city.split(',').map(id => {
|
||||
const numId = parseInt(id.trim());
|
||||
return isNaN(numId) ? null : numId;
|
||||
}).filter(id => id !== null);
|
||||
}
|
||||
} else if (Array.isArray(this.form.city)) {
|
||||
// 如果已经是数组,直接使用
|
||||
cityArray = this.form.city.map(id => parseInt(id)).filter(id => !isNaN(id));
|
||||
}
|
||||
|
||||
this.$set(this.form, 'cityArray', cityArray);
|
||||
console.log('转换后的城市数组:', this.form.cityArray);
|
||||
} catch (e) {
|
||||
console.error('城市数据转换错误:', e);
|
||||
this.$set(this.form, 'cityArray', []);
|
||||
}
|
||||
} else {
|
||||
this.$set(this.form, 'cityArray', []);
|
||||
}
|
||||
|
||||
// 重置基检现象标签输入状态
|
||||
this.showBasicInput = false;
|
||||
this.newBasicTag = '';
|
||||
|
|
@ -1381,6 +1513,17 @@ export default {
|
|||
}
|
||||
console.log('提交的基检现象JSON字符串:', this.form.basic);
|
||||
|
||||
// 处理城市数据转换:将数组转为JSON字符串
|
||||
console.log('提交前的城市数组:', this.form.cityArray);
|
||||
if (this.form.cityArray && Array.isArray(this.form.cityArray) && this.form.cityArray.length > 0) {
|
||||
// 过滤掉无效值
|
||||
const validCityIds = this.form.cityArray.filter(id => id !== null && id !== undefined && !isNaN(id));
|
||||
this.form.city = validCityIds.length > 0 ? JSON.stringify(validCityIds) : null;
|
||||
} else {
|
||||
this.form.city = null;
|
||||
}
|
||||
console.log('提交的城市JSON字符串:', this.form.city);
|
||||
|
||||
// 确保数字字段的正确格式
|
||||
if (this.form.price) {
|
||||
this.form.price = parseFloat(this.form.price);
|
||||
|
|
@ -2098,6 +2241,75 @@ export default {
|
|||
this.disableGroupAndFixed = false;
|
||||
}
|
||||
},
|
||||
|
||||
// ========== 城市相关方法 ==========
|
||||
|
||||
/** 获取城市列表 */
|
||||
getCityList() {
|
||||
console.log('开始获取城市列表...');
|
||||
this.cityLoading = true;
|
||||
getFirstLevelCities().then(response => {
|
||||
console.log('城市API响应:', response);
|
||||
this.cityList = response.rows || [];
|
||||
console.log('设置城市列表:', this.cityList);
|
||||
this.cityLoading = false;
|
||||
}).catch(error => {
|
||||
console.error("获取城市列表失败:", error);
|
||||
this.cityLoading = false;
|
||||
});
|
||||
},
|
||||
|
||||
/** 城市选择变化处理 */
|
||||
handleCityChange(value) {
|
||||
console.log('城市选择变化:', value);
|
||||
// 确保value是数组格式
|
||||
const cityArray = Array.isArray(value) ? value : [];
|
||||
this.$set(this.form, 'cityArray', cityArray);
|
||||
console.log('设置后的城市数组:', this.form.cityArray);
|
||||
},
|
||||
|
||||
/** 根据城市ID获取城市名称 */
|
||||
getCityNameById(id) {
|
||||
const city = this.cityList.find(item => item.id === id);
|
||||
return city ? city.title : id;
|
||||
},
|
||||
|
||||
/** 解析城市字符串为数组 */
|
||||
getCityArray(cityString) {
|
||||
if (!cityString) return [];
|
||||
try {
|
||||
if (typeof cityString === 'string') {
|
||||
// 尝试解析JSON格式
|
||||
try {
|
||||
const parsed = JSON.parse(cityString);
|
||||
if (Array.isArray(parsed)) {
|
||||
return parsed.map(id => Number(id)).filter(id => !isNaN(id) && id !== 0);
|
||||
}
|
||||
} catch (e) {
|
||||
// JSON解析失败,尝试逗号分隔的字符串
|
||||
return cityString.split(',').map(id => Number(id.trim())).filter(id => !isNaN(id) && id !== 0);
|
||||
}
|
||||
} else if (Array.isArray(cityString)) {
|
||||
return cityString.map(id => Number(id)).filter(id => !isNaN(id) && id !== 0);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('解析城市数据失败:', e);
|
||||
}
|
||||
return [];
|
||||
},
|
||||
|
||||
/** 移除城市 */
|
||||
removeCity(cityId) {
|
||||
if (!this.form.cityArray) {
|
||||
this.$set(this.form, 'cityArray', []);
|
||||
return;
|
||||
}
|
||||
const index = this.form.cityArray.indexOf(cityId);
|
||||
if (index > -1) {
|
||||
this.form.cityArray.splice(index, 1);
|
||||
console.log('删除城市:', cityId, '剩余:', this.form.cityArray);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -2221,4 +2433,39 @@ export default {
|
|||
margin-right: 6px;
|
||||
color: #0ea5e9;
|
||||
}
|
||||
|
||||
/* 城市选择器样式 */
|
||||
.city-tags-container {
|
||||
margin-top: 8px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.city-tag {
|
||||
margin: 0;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.city-tag:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.city-select-loading {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.city-select-loading .el-select__tags {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* 城市选择器加载动画 */
|
||||
@keyframes rotate {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.city-select-loading .el-select__caret::before {
|
||||
animation: rotate 1s linear infinite;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Reference in New Issue