202507171540

This commit is contained in:
张潘 2025-07-17 15:40:29 +08:00
parent 29bce55a07
commit 2c7e315e46
49 changed files with 5728 additions and 1300 deletions

View File

@ -158,3 +158,174 @@ return AppletControllerUtil.appletWarning("积分不足");
## 下一步工作
需要继续对剩余的方法进行统一响应格式处理,确保所有小程序接口都使用统一的响应格式。
# AppletController 接口说明
## 修改的接口
### `/api/paybefor/info/{id}` - 预支付记录查询和金额计算
**请求方式**: POST
**接口描述**: 根据预支付记录ID查询详情并根据传递的参数计算支付金额
**请求参数**:
- `id` (路径参数): 预支付记录ID
- `paytype` (可选): 支付方式1=微信支付2=余额支付3=组合支付默认为1
- `coupon_id` (可选): 优惠券ID
- `mtcode` (可选): 美团优惠码
**请求示例**:
```json
{
"paytype": 1,
"coupon_id": 123,
"mtcode": "MT123456"
}
```
**响应示例**:
**微信支付示例**:
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"id": 1,
"orderId": "ORDER20250101001",
"paycode": "PAY20250101001",
"allmoney": 100.00,
"finalAmount": 85.10,
"wxmoney": 85.10,
"yemoney": 0.00,
"membermoney": 5.00,
"shopmoney": 2.00,
"servicemoney": 3.00,
"couponmoney": 10.00,
"mtmoney": 9.90,
"type": 1,
"paytype": 1,
"usersBalance": 50.00,
"couponId": 123,
"mtcode": "MT123456",
"calculationDetail": {
"originalAmount": 100.00,
"memberDiscount": 5.00,
"serviceDiscount": 3.00,
"shopDiscount": 2.00,
"couponDiscount": 10.00,
"mtDiscount": 9.90,
"finalAmount": 85.10
}
}
}
```
**组合支付示例**用户余额30元实际应付85.10元):
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"id": 1,
"orderId": "ORDER20250101001",
"paycode": "PAY20250101001",
"allmoney": 100.00,
"finalAmount": 85.10,
"wxmoney": 55.10,
"yemoney": 30.00,
"membermoney": 5.00,
"shopmoney": 2.00,
"servicemoney": 3.00,
"couponmoney": 10.00,
"mtmoney": 9.90,
"type": 1,
"paytype": 3,
"usersBalance": 30.00,
"couponId": 123,
"mtcode": "MT123456",
"calculationDetail": {
"originalAmount": 100.00,
"memberDiscount": 5.00,
"serviceDiscount": 3.00,
"shopDiscount": 2.00,
"couponDiscount": 10.00,
"mtDiscount": 9.90,
"finalAmount": 85.10
}
}
}
```
**响应参数**:
- `id`: 预支付记录ID
- `orderId`: 订单ID
- `paycode`: 支付订单号
- `allmoney`: 原始总金额(固定不变,这是您最初存储的金额)
- `finalAmount`: 实际应付金额基于allmoney计算得出
- `wxmoney`: 微信支付金额
- `yemoney`: 余额支付金额
- `membermoney`: 会员优惠金额(固定不变)
- `shopmoney`: 购物金抵扣金额(固定不变)
- `servicemoney`: 服务金抵扣金额(固定不变)
- `couponmoney`: 优惠券金额(实时计算)
- `mtmoney`: 美团优惠金额(实时计算)
- `type`: 订单类型
- `paytype`: 支付方式
- `usersBalance`: 用户余额
- `couponId`: 优惠券ID
- `mtcode`: 美团优惠码
- `calculationDetail`: 计算明细
- `originalAmount`: 原始金额allmoney
- `memberDiscount`: 会员优惠
- `serviceDiscount`: 服务金抵扣
- `shopDiscount`: 购物金抵扣
- `couponDiscount`: 优惠券金额
- `mtDiscount`: 美团优惠
- `finalAmount`: 最终应付金额
**业务逻辑**:
1. 验证用户登录状态和权限
2. 获取 `allmoney`(原始总金额,固定不变)和固定优惠金额(会员优惠、服务金抵扣、购物金抵扣)
3. 根据优惠券ID查询优惠券信息并验证有效性计算优惠券优惠金额
4. 计算美团优惠金额每次调用生成2至15的随机整数
5. 基于 `allmoney` 减去所有优惠,计算实际应付金额:
```
实际应付金额 = allmoney - 会员优惠 - 服务金抵扣 - 购物金抵扣 - 优惠券金额 - 美团优惠
```
6. 根据支付方式计算各支付渠道金额:
- 微信支付:全部用微信支付
- 余额支付:验证余额是否足够,全部用余额支付
- 组合支付:
- 余额足够:全部用余额支付
- 余额不足:优先扣除用户所有余额,剩余部分用微信支付
- 无余额:全部用微信支付
7. 更新预支付记录到数据库(注意:`allmoney` 保持不变)
8. 返回计算后的支付信息,包含计算明细
**错误处理**:
- 用户未登录或token无效
- 预支付记录不存在
- 无权查看该预支付记录
- 优惠券无效或已被使用
- 优惠券不属于当前用户
- 优惠券已过期
- 订单金额未达到优惠券使用条件
- 余额不足
- 无效的支付方式
- 更新预支付记录失败
**注意事项**:
- `allmoney` 是您最初存储的总金额,永远不会改变,所有计算都基于这个金额
- 每次调用都会基于 `allmoney` 重新计算,确保前端能实时获取最新的支付信息
- 会员优惠、服务金抵扣、购物金抵扣金额在每次计算中保持不变
- 优惠券金额和美团优惠金额根据用户选择实时计算
- 美团优惠功能每次调用生成2至15的随机整数作为优惠金额用于测试
- 优惠券验证包括状态、归属权、过期时间、最低消费等
- 组合支付逻辑:
- 余额足够全部用余额支付wxmoney=0, yemoney=实际金额)
- 余额不足优先扣除用户所有余额剩余部分用微信支付wxmoney=差额, yemoney=用户余额)
- 无余额全部用微信支付wxmoney=实际金额, yemoney=0
- 所有金额计算都使用BigDecimal确保精度
- 返回的calculationDetail字段方便前端理解金额构成和计算过程
- 更新数据库时,`allmoney` 字段保持不变

View File

@ -360,43 +360,43 @@ public class AppleMemberController extends BaseController {
// ==================== 余额支付相关接口 ====================
/**
* 余额支付测试接口
*
* 测试用户余额支付功能
* 模拟购买99.99元商品的余额支付流程
*
* @param request HTTP请求对象需要包含token
* @return 支付结果
*/
@GetMapping("/balance/payment")
public AjaxResult apibalancepayment(HttpServletRequest request) {
try {
// 1. 验证用户登录状态
String token = request.getHeader("token");
Map<String, Object> userValidation = AppletLoginUtil.validateUserToken(token, usersService);
if (!(Boolean) userValidation.get("valid")) {
return AppletControllerUtil.appletWarning("用户未登录或token无效");
}
// 2. 获取用户信息
Users user = (Users) userValidation.get("user");
if (user == null) {
return AppletControllerUtil.appletWarning("用户信息获取失败");
}
// 3. 调用余额支付工具类
Map<String, Object> rmap = BalancePayUtil.processBalancePayment(
user.getId(),
new BigDecimal("99.99"),
"购买一般商品单价99.99");
return AppletControllerUtil.appletSuccess(rmap.get("message"));
} catch (Exception e) {
System.err.println("余额支付异常:" + e.getMessage());
return AppletControllerUtil.appletError("余额支付失败:" + e.getMessage());
}
}
// /**
// * 余额支付测试接口
// *
// * 测试用户余额支付功能
// * 模拟购买99.99元商品的余额支付流程
// *
// * @param request HTTP请求对象需要包含token
// * @return 支付结果
// */
// @GetMapping("/balance/payment")
// public AjaxResult apibalancepayment(HttpServletRequest request) {
// try {
// // 1. 验证用户登录状态
// String token = request.getHeader("token");
// Map<String, Object> userValidation = AppletLoginUtil.validateUserToken(token, usersService);
// if (!(Boolean) userValidation.get("valid")) {
// return AppletControllerUtil.appletWarning("用户未登录或token无效");
// }
//
// // 2. 获取用户信息
// Users user = (Users) userValidation.get("user");
// if (user == null) {
// return AppletControllerUtil.appletWarning("用户信息获取失败");
// }
//
//// // 3. 调用余额支付工具类
//// Map<String, Object> rmap = BalancePayUtil.processBalancePayment(
//// user.getId(),
//// new BigDecimal("99.99"),
//// "购买一般商品单价99.99");
//// return AppletControllerUtil.appletSuccess(rmap.get("message"));
//
// } catch (Exception e) {
// System.err.println("余额支付异常:" + e.getMessage());
// return AppletControllerUtil.appletError("余额支付失败:" + e.getMessage());
// }
// }
// ==================== 记录查询相关接口 ====================

View File

@ -11,6 +11,8 @@ import com.ruoyi.system.domain.AppleDoMain.OrderApple;
import com.ruoyi.system.domain.AppleDoMain.AddressApple;
import com.ruoyi.system.service.*;
import com.winnerlook.model.VoiceResponseResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@ -40,6 +42,8 @@ import com.ruoyi.system.domain.QuoteMaterial;
@RestController
public class AppletController extends BaseController {
private static final Logger logger = LoggerFactory.getLogger(AppletController.class);
@Autowired
private IServiceCateService serviceCateService;
@Autowired
@ -115,7 +119,8 @@ public class AppletController extends BaseController {
private IUserSecondaryCardService userSecondaryCardService;
@Autowired
private IUserGroupBuyingService userGroupBuyingService;
@Autowired
private IUsersPayBeforService usersPayBeforService;
@ -961,6 +966,7 @@ public class AppletController extends BaseController {
if (type != null && type == 2) {
UserSecondaryCard goods = userSecondaryCardService.selectUserSecondaryCardById(id);
Map<String, Object> map = new HashMap<>();
map.put("isyikoujia", 1);
map.put("id", goods.getId());
map.put("allsellnum", 10);
map.put("orderid", goods.getOrderid());
@ -1010,13 +1016,16 @@ public class AppletController extends BaseController {
//拼团独有数据
if (type == 1) {
// 拼团服务详情
goodsData.put("isyikoujia", 1);
goodsData.put("allsellnum", 10);
goodsData.put("isgroup", serviceGoodsData.getIsgroup());
goodsData.put("groupnum", serviceGoodsData.getGroupnum());
goodsData.put("groupprice", serviceGoodsData.getGroupprice());
List<Map<String, Object>> groupBuyingList = userGroupBuyingService.selectGroupBuyingGroupByProductAndOrder(Math.toIntExact(serviceGoodsData.getId()));
for (Map<String, Object> groupBuying : groupBuyingList) {
//还差几人成团
JSONArray groupBuyingArray = JSONArray.parseArray(groupBuying.get("name").toString());
// JSONArray groupBuyingArray =new JSONArray();
groupBuying.put("neednum", serviceGoodsData.getGroupnum() - groupBuyingArray.size());
groupBuying.put("image", AppletControllerUtil.parseImagesStringToArray(groupBuying.get("image").toString()));
//parseImagesStringToArray(goods.getImgs())
@ -1026,19 +1035,53 @@ public class AppletController extends BaseController {
}
//秒杀独有数据
if (type == 3) {
// 获取秒杀相关数据
long msdata = 0L;
try {
// 获取config_one配置中的秒杀结束时间
SiteConfig configQuery = new SiteConfig();
configQuery.setName("config_one");
List<SiteConfig> configList = siteConfigService.selectSiteConfigList(configQuery);
if (configList != null && !configList.isEmpty()) {
String configValue = configList.get(0).getValue();
if (configValue != null && !configValue.trim().isEmpty()) {
JSONObject configJson = JSONObject.parseObject(configValue);
String mstime = configJson.getString("mstime");
if (mstime != null && !mstime.trim().isEmpty()) {
// 解析秒杀结束时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date endTime = sdf.parse(mstime);
msdata = endTime.getTime(); // 返回结束时间的毫秒数
}
}
}
} catch (Exception e) {
// 解析异常时设置为0
msdata = 0L;
}
// 秒杀服务详情
goodsData.put("isyikoujia", 1);
goodsData.put("msdata", msdata);
goodsData.put("allsellnum", 10);
goodsData.put("isfixed", serviceGoodsData.getIsfixed());
goodsData.put("fixedprice", serviceGoodsData.getFixedprice());
}
//报价数据下师傅的报价详情
if (type == 3) {
if (type == 4) {
goodsData.put("isyikoujia", 2);
// 秒杀服务详情
// List<Map<String, Object>> quoteList = new List<Map<String, Object>>() ;
//
// goodsData.put("isfixed", serviceGoodsData.getIsfixed());
// goodsData.put("fixedprice", serviceGoodsData.getFixedprice());
}
}else{
goodsData.put("isyikoujia", 2);
}
return AppletControllerUtil.appletSuccess(goodsData);
}
@ -1667,7 +1710,6 @@ public class AppletController extends BaseController {
userInfo.put("status", user.getStatus() != null ? user.getStatus() : 1);
userInfo.put("tpd", 0); // 默认值
// userInfo.put("total_comm","0.00");
// userInfo.put("total_comm", user.getTotalComm().toString() != null ? user.getTotalComm().toString() : "0.00");
userInfo.put("total_integral", user.getTotalIntegral() != null ? user.getTotalIntegral() : 100);
userInfo.put("type", user.getType() != null ? user.getType().toString() : "1");
userInfo.put("worker_time", user.getWorkerTime());
@ -3130,30 +3172,52 @@ public class AppletController extends BaseController {
} else {
sku = null;
}
// 5. 查询商品信息并验证
// 5. 获取新增的三个参数ordertypefileDataremark
Long ordertype = null;
if (params.get("ordertype") != null) {
try {
ordertype = Long.valueOf(params.get("ordertype").toString());
} catch (NumberFormatException e) {
// 如果转换失败保持为null
ordertype = null;
}
}
String fileData = null;
if (params.get("fileData") != null) {
fileData = params.get("fileData").toString();
}
String remark = null;
if (params.get("remark") != null) {
remark = params.get("remark").toString();
}
// 6. 查询商品信息并验证
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(goodId);
if (serviceGoods == null) {
return AppletControllerUtil.appletWarning("商品不存在");
}
// 6. 验证商品状态
// 7. 验证商品状态
// if (serviceGoods.getStatus() == null || !serviceGoods.getStatus().equals(1L)) {
// return AppletControllerUtil.appletWarning("商品已下架或不可用");
// }
// 7. 检查商品库存如果有库存管理
// 8. 检查商品库存如果有库存管理
// if (serviceGoods.getStock() != null && serviceGoods.getStock() <= 0L) {
// return AppletControllerUtil.appletWarning("商品库存不足");
// }
// 8. 检查购物车中是否已存在该商品
// 9. 检查购物车中是否已存在该商品
GoodsCart existingCartItem = AppletControllerUtil.findExistingCartItem(user.getId(), goodId, sku, goodsCartService);
if (existingCartItem != null) {
// 如果已存在更新数量
return AppletControllerUtil.updateCartItemQuantity(existingCartItem, serviceGoods, goodsCartService);
// 如果已存在更新数量和新参数
return AppletControllerUtil.updateCartItemQuantity(existingCartItem, serviceGoods, goodsCartService, ordertype, fileData, remark);
} else {
// 如果不存在新增购物车记录
return AppletControllerUtil.addNewCartItem(user, serviceGoods, sku, goodsCartService);
return AppletControllerUtil.addNewCartItem(user, serviceGoods, sku, goodsCartService, ordertype, fileData, remark);
}
} catch (Exception e) {
@ -3161,6 +3225,94 @@ public class AppletController extends BaseController {
return AppletControllerUtil.appletError("添加购物车失败:" + e.getMessage());
}
}
/**
* 查询用户购物车数据按商品类型分为商城类和服务类不分页
*
* @param request HTTP请求对象
* @return { mallList: [...], serviceList: [...] }
* <p>
* 接口说明
* - 查询当前登录用户的全部购物车数据不分页
* - 根据商品的 type 字段分为商城类type=2和服务类type=1
* - 每个列表的封装方式参考 /api/cart/lst
* - 需要用户登录验证
* <p>
*/
@GetMapping("/api/cart/pluslst")
public AjaxResult getCartPlusList(HttpServletRequest request) {
try {
// 1. 验证用户登录状态
String token = request.getHeader("token");
Map<String, Object> userValidation = AppletLoginUtil.validateUserToken(token, usersService);
if (!(Boolean) userValidation.get("valid")) {
return AppletControllerUtil.appletUnauthorized();
}
// 2. 获取用户信息
Users user = (Users) userValidation.get("user");
if (user == null) {
return AppletControllerUtil.appletWarning("用户信息获取失败");
}
// 3. 查询全部购物车数据不分页
GoodsCart queryCart = new GoodsCart();
queryCart.setUid(user.getId());
List<GoodsCart> cartList = goodsCartService.selectGoodsCartList(queryCart);
// 4. 按商品类型分组
List<Map<String, Object>> goodsList = new ArrayList<>();
List<Map<String, Object>> serviceList = new ArrayList<>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (GoodsCart cart : cartList) {
Map<String, Object> cartData = new HashMap<>();
cartData.put("id", cart.getId());
cartData.put("uid", cart.getUid());
cartData.put("good_id", cart.getGoodId());
cartData.put("good_num", cart.getGoodNum());
if (cart.getSku() != null && !cart.getSku().isEmpty()) {
try {
cartData.put("sku", com.alibaba.fastjson2.JSONObject.parseObject(cart.getSku()));
} catch (Exception e) {
cartData.put("sku", cart.getSku());
}
} else {
cartData.put("sku", null);
}
cartData.put("ordertype", cart.getOrdertype());
cartData.put("fileData", cart.getFileData());
cartData.put("remark", cart.getReamk());
cartData.put("created_at", cart.getCreatedAt() != null ? sdf.format(cart.getCreatedAt()) : null);
cartData.put("updated_at", cart.getUpdatedAt() != null ? sdf.format(cart.getUpdatedAt()) : null);
// 查询商品详细信息
Map<String, Object> goodInfo = AppletControllerUtil.getGoodDetailForCart(cart.getGoodId(), serviceGoodsService);
cartData.put("good", goodInfo);
// 判断商品类型
Integer type = null;
if (goodInfo.get("type") != null) {
try {
type = Integer.valueOf(goodInfo.get("type").toString());
} catch (Exception ignore) {}
}
if (type != null && type == 2) {
goodsList.add(cartData);
} else {
// 默认都归为服务类type=1
serviceList.add(cartData);
}
}
// 5. 返回结构
Map<String, Object> result = new HashMap<>();
result.put("goodsList", goodsList);
result.put("serviceList", serviceList);
return AppletControllerUtil.appletSuccess(result);
} catch (Exception e) {
System.err.println("查询购物车plus列表异常" + e.getMessage());
return AppletControllerUtil.appletError("查询购物车plus列表失败" + e.getMessage());
}
}
/**
* 查询购物车列表接口
*
@ -6735,6 +6887,7 @@ public class AppletController extends BaseController {
map.put("icon", AppletControllerUtil.buildImageUrl(goods.getIcon()));
map.put("title", goods.getTitle());
map.put("price", goods.getPrice());
map.put("id", goods.getId());
map.put("groupprice", goods.getGroupprice());
map.put("groupnum", goods.getGroupnum());
resultList.add(map);
@ -6815,6 +6968,7 @@ public class AppletController extends BaseController {
List<Map<String, Object>> resultList = new ArrayList<>();
for (ServiceGoods goods : goodsList) {
Map<String, Object> map = new HashMap<>();
map.put("id", goods.getId());
map.put("icon", AppletControllerUtil.buildImageUrl(goods.getIcon()));
map.put("title", goods.getTitle());
map.put("price", goods.getPrice());
@ -6826,7 +6980,38 @@ public class AppletController extends BaseController {
TableDataInfo tableDataInfo = getDataTable(goodsList);
tableDataInfo.setRows(resultList); // 只返回精简字段
Map<String, Object> pageData = PageUtil.buildSimplePageResponse(tableDataInfo, page, limit);
return AppletControllerUtil.appletSuccess(pageData);
// 获取秒杀相关数据
long msdata = 0L;
try {
// 获取config_one配置中的秒杀结束时间
SiteConfig configQuery = new SiteConfig();
configQuery.setName("config_one");
List<SiteConfig> configList = siteConfigService.selectSiteConfigList(configQuery);
if (configList != null && !configList.isEmpty()) {
String configValue = configList.get(0).getValue();
if (configValue != null && !configValue.trim().isEmpty()) {
JSONObject configJson = JSONObject.parseObject(configValue);
String mstime = configJson.getString("mstime");
if (mstime != null && !mstime.trim().isEmpty()) {
// 解析秒杀结束时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date endTime = sdf.parse(mstime);
msdata = endTime.getTime(); // 返回结束时间的毫秒数
}
}
}
} catch (Exception e) {
// 解析异常时设置为0
msdata = 0L;
}
Map<String, Object> reData = new HashMap<>();
reData.put("listData", pageData);
reData.put("msdata", msdata);
return AppletControllerUtil.appletSuccess(reData);
}
//报价数据
@ -6846,6 +7031,7 @@ public class AppletController extends BaseController {
List<Map<String, Object>> resultList = new ArrayList<>();
for (ServiceGoods goods : goodsList) {
Map<String, Object> map = new HashMap<>();
map.put("id", goods.getId());
map.put("icon", AppletControllerUtil.buildImageUrl(goods.getIcon()));
map.put("title", goods.getTitle());
resultList.add(map);
@ -6863,7 +7049,273 @@ public class AppletController extends BaseController {
}
return null;
}
/**
* 根据ID查询预支付记录并计算支付金额
*
* @param id 预支付记录ID
* @param params 请求参数包含paytypecoupon_idmtcode
* @param request HTTP请求对象
* @return 预支付记录详情和计算后的支付金额
*/
@PostMapping("/api/paybefor/info/{id}")
public AjaxResult getPayBeforInfo(@PathVariable("id") String id, @RequestBody Map<String, Object> params, HttpServletRequest request) {
try {
// 1. 验证用户登录状态
String token = request.getHeader("token");
Map<String, Object> userValidation = AppletLoginUtil.validateUserToken(token, usersService);
if (!(Boolean) userValidation.get("valid")) {
return AppletControllerUtil.appletWarning("用户未登录或token无效");
}
Users user = (Users) userValidation.get("user");
if (user == null) {
return AppletControllerUtil.appletWarning("用户信息获取失败");
}
// 2. 参数验证
if (StringUtils.isBlank(id)) {
return AppletControllerUtil.appletWarning("预支付记录ID不能为空");
}
// 3. 获取请求参数
Integer paytype = params.get("paytype") != null ? Integer.parseInt(params.get("paytype").toString()) : 1;
Long couponId = params.get("coupon_id") != null ? Long.parseLong(params.get("coupon_id").toString()) : null;
String mtcode = params.get("mtcode") != null ? params.get("mtcode").toString() : null;
// 4. 查询预支付记录
UsersPayBefor payBefor = usersPayBeforService.selectUsersPayBeforByOrderId(id);
if (payBefor == null) {
return AppletControllerUtil.appletWarning("预支付记录不存在");
}
// 5. 验证记录归属权只能查看自己的记录
if (!payBefor.getUid().equals(user.getId())) {
return AppletControllerUtil.appletWarning("无权查看该预支付记录");
}
// 6. 获取原始总金额allmoney是固定的永远不会改变
BigDecimal originalAmount = payBefor.getAllmoney();
if (originalAmount == null) {
originalAmount = BigDecimal.ZERO;
}
// 获取会员优惠金额固定不变
BigDecimal memberMoney = payBefor.getMembermoney();
if (memberMoney == null) {
memberMoney = BigDecimal.ZERO;
}
// 获取服务金抵扣金额固定不变
BigDecimal serviceMoney = payBefor.getServicemoney();
if (serviceMoney == null) {
serviceMoney = BigDecimal.ZERO;
}
// 获取购物金抵扣金额固定不变
BigDecimal shopMoney = payBefor.getShopmoney();
if (shopMoney == null) {
shopMoney = BigDecimal.ZERO;
}
// 7. 计算优惠券金额每次重新计算
BigDecimal couponMoney = BigDecimal.ZERO;
if (couponId != null) {
CouponUser couponUser = couponUserService.selectCouponUserById(couponId);
if (couponUser != null && couponUser.getStatus() != null && couponUser.getStatus() == 1L) {
// 验证优惠券是否属于当前用户
if (!couponUser.getUid().equals(user.getId())) {
return AppletControllerUtil.appletWarning("优惠券不属于当前用户");
}
// 验证优惠券是否过期
if (couponUser.getLoseTime() != null && !"永久有效".equals(couponUser.getLoseTime())) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date loseTime = sdf.parse(couponUser.getLoseTime());
if (new Date().after(loseTime)) {
return AppletControllerUtil.appletWarning("优惠券已过期");
}
} catch (Exception e) {
logger.warn("解析优惠券过期时间失败: " + e.getMessage());
}
}
// 验证最低消费基于原始金额
if (couponUser.getMinPrice() != null && originalAmount.compareTo(BigDecimal.valueOf(couponUser.getMinPrice())) < 0) {
return AppletControllerUtil.appletWarning("订单金额未达到优惠券使用条件");
}
couponMoney = BigDecimal.valueOf(couponUser.getCouponPrice());
} else {
return AppletControllerUtil.appletWarning("优惠券无效或已被使用");
}
}
// 8. 计算美团优惠金额每次重新计算2至15的随机整数用于测试
BigDecimal mtMoney = BigDecimal.ZERO;
if (mtcode != null && !mtcode.trim().isEmpty()) {
// 生成2至15的随机整数
Random random = new Random();
int randomDiscount = random.nextInt(14) + 2; // 2到15的随机数
mtMoney = new BigDecimal(randomDiscount);
}
// 9. 计算实际应付金额基于allmoney减去所有优惠
BigDecimal actualAmount = originalAmount
.subtract(memberMoney) // 减去会员优惠
.subtract(serviceMoney) // 减去服务金抵扣
.subtract(shopMoney) // 减去购物金抵扣
.subtract(couponMoney) // 减去优惠券金额
.subtract(mtMoney); // 减去美团优惠
if (actualAmount.compareTo(BigDecimal.ZERO) < 0) {
actualAmount = BigDecimal.ZERO;
}
// 10. 根据支付方式计算各支付渠道金额
BigDecimal wxMoney = BigDecimal.ZERO;
BigDecimal yeMoney = BigDecimal.ZERO;
if (paytype == 1) {
// 微信支付
wxMoney = actualAmount;
yeMoney = BigDecimal.ZERO;
} else if (paytype == 2) {
// 余额支付
if (user.getBalance() != null && user.getBalance().compareTo(actualAmount) >= 0) {
wxMoney = BigDecimal.ZERO;
yeMoney = actualAmount;
} else {
// 13. 构建返回数据
Map<String, Object> result = new HashMap<>();
result.put("id", payBefor.getId());
result.put("orderId", payBefor.getOrderid());
result.put("paycode", payBefor.getPaycode());
result.put("allmoney", originalAmount); // 原始总金额固定不变这是您最初存储的金额
result.put("finalAmount", actualAmount); // 实际应付金额基于allmoney计算得出
result.put("wxmoney", wxMoney); // 微信支付金额
result.put("yemoney", yeMoney); // 余额支付金额
result.put("membermoney", memberMoney); // 会员优惠金额固定不变
result.put("shopmoney", shopMoney); // 购物金抵扣金额固定不变
result.put("servicemoney", serviceMoney); // 服务金抵扣金额固定不变
result.put("couponmoney", couponMoney); // 优惠券金额实时计算
result.put("mtmoney", mtMoney); // 美团优惠金额实时计算
result.put("type", payBefor.getType());
result.put("servicetype", payBefor.getServicetype());
result.put("paytype", paytype);
result.put("usersBalance", user.getBalance());
result.put("couponId", couponId);
result.put("mtcode", mtcode);
return AppletControllerUtil.appletSuccess(result);
}
} else if (paytype == 3) {
// 组合支付优先使用余额不足部分用微信支付
if (user.getBalance() != null && user.getBalance().compareTo(actualAmount) >= 0) {
// 余额足够全部用余额支付
wxMoney = BigDecimal.ZERO;
yeMoney = actualAmount;
} else if (user.getBalance() != null && user.getBalance().compareTo(BigDecimal.ZERO) > 0) {
// 余额不足优先扣除用户所有余额剩余部分用微信支付
yeMoney = user.getBalance();
wxMoney = actualAmount.subtract(yeMoney);
} else {
// 无余额全部微信支付
wxMoney = actualAmount;
yeMoney = BigDecimal.ZERO;
}
} else {
return AppletControllerUtil.appletWarning("无效的支付方式");
}
// 11. 更新预支付记录注意allmoney保持不变只更新其他字段
payBefor.setPaytype(Long.valueOf(paytype));
payBefor.setCouponid(couponId);
payBefor.setCouponmoney(couponMoney);
payBefor.setMtcode(mtcode);
payBefor.setMtmoney(mtMoney);
payBefor.setWxmoney(wxMoney);
payBefor.setYemoney(yeMoney);
// 注意allmoney保持不变这是原始总金额
int updateResult = usersPayBeforService.updateUsersPayBefor(payBefor);
if (updateResult <= 0) {
return AppletControllerUtil.appletWarning("更新预支付记录失败");
}
// 12. 构建支付公式
StringBuilder paymentFormula = new StringBuilder();
paymentFormula.append("总金额(").append(originalAmount).append(")");
// 添加各种优惠项
if (memberMoney.compareTo(BigDecimal.ZERO) > 0) {
paymentFormula.append("-会员优惠(").append(memberMoney).append(")");
}
if (serviceMoney.compareTo(BigDecimal.ZERO) > 0) {
paymentFormula.append("-服务金抵扣(").append(serviceMoney).append(")");
}
if (shopMoney.compareTo(BigDecimal.ZERO) > 0) {
paymentFormula.append("-购物金抵扣(").append(shopMoney).append(")");
}
if (couponMoney.compareTo(BigDecimal.ZERO) > 0) {
paymentFormula.append("-优惠券(").append(couponMoney).append(")");
}
if (mtMoney.compareTo(BigDecimal.ZERO) > 0) {
paymentFormula.append("-美团优惠(").append(mtMoney).append(")");
}
paymentFormula.append("=").append(actualAmount).append("=");
// 添加支付方式
if (wxMoney.compareTo(BigDecimal.ZERO) > 0 && yeMoney.compareTo(BigDecimal.ZERO) > 0) {
// 组合支付
paymentFormula.append("微信支付(").append(wxMoney).append(")+余额支付(").append(yeMoney).append(")");
} else if (wxMoney.compareTo(BigDecimal.ZERO) > 0) {
// 纯微信支付
paymentFormula.append("微信支付(").append(wxMoney).append(")");
} else if (yeMoney.compareTo(BigDecimal.ZERO) > 0) {
// 纯余额支付
paymentFormula.append("余额支付(").append(yeMoney).append(")");
}
// 13. 构建返回数据
Map<String, Object> result = new HashMap<>();
result.put("id", payBefor.getId());
result.put("orderId", payBefor.getOrderid());
result.put("paycode", payBefor.getPaycode());
result.put("allmoney", originalAmount); // 原始总金额固定不变这是您最初存储的金额
result.put("finalAmount", actualAmount); // 实际应付金额基于allmoney计算得出
result.put("wxmoney", wxMoney); // 微信支付金额
result.put("yemoney", yeMoney); // 余额支付金额
result.put("membermoney", memberMoney); // 会员优惠金额固定不变
result.put("shopmoney", shopMoney); // 购物金抵扣金额固定不变
result.put("servicemoney", serviceMoney); // 服务金抵扣金额固定不变
result.put("couponmoney", couponMoney); // 优惠券金额实时计算
result.put("mtmoney", mtMoney); // 美团优惠金额实时计算
result.put("type", payBefor.getType());
result.put("paytype", paytype);
result.put("usersBalance", user.getBalance());
result.put("couponId", couponId);
result.put("mtcode", mtcode);
result.put("servicetype", payBefor.getServicetype());
result.put("paymentFormula", paymentFormula.toString()); // 支付公式
// // 添加计算明细方便前端理解金额构成
// Map<String, Object> calculationDetail = new HashMap<>();
// calculationDetail.put("originalAmount", originalAmount);
// calculationDetail.put("memberDiscount", memberMoney);
// calculationDetail.put("serviceDiscount", serviceMoney);
// calculationDetail.put("shopDiscount", shopMoney);
// calculationDetail.put("couponDiscount", couponMoney);
// calculationDetail.put("mtDiscount", mtMoney);
// calculationDetail.put("finalAmount", actualAmount);
// result.put("calculationDetail", calculationDetail);
return AppletControllerUtil.appletSuccess(result);
} catch (Exception e) {
logger.error("查询预支付记录失败:", e);
return AppletControllerUtil.appletError("查询预支付记录失败:" + e.getMessage());
}
}
// /**
// * 获取次卡列表支持分页
// *

View File

@ -5,7 +5,9 @@ import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.ControllerUtil.BalancePayUtil;
import com.ruoyi.system.ControllerUtil.GenerateCustomCode;
import com.ruoyi.system.ControllerUtil.OrderUtil;
import com.ruoyi.system.ControllerUtil.WXsendMsgUtil;
import com.ruoyi.system.ControllerUtil.WechatPayUtil;
import com.ruoyi.system.domain.*;
@ -91,6 +93,13 @@ public class PayNotifyController extends BaseController {
@Autowired
private IUserGroupBuyingService userGroupBuyingService;
@Autowired
private IUsersPayBeforService usersPayBeforService;
@Autowired
private IUserUseSecondaryCardService userUseSecondaryCardService;
/**
* 商品支付回调接口
*
@ -258,6 +267,177 @@ public class PayNotifyController extends BaseController {
/**
* 拼团支付的回调接口
*
* @param request HTTP请求对象
* @return XML格式响应给微信服务器
*IUserGroupBuyingService userGroupBuyingService;
* 处理商品订单的支付成功回调
* 1. 验证支付签名
* 2. 更新商品订单支付状态
* 3. 更新订单支付时间和交易号
* 4. 处理库存扣减等业务逻辑
*/
@PostMapping(value = "/api/order/amount/paydata/notify")
public String apiorderamountpaydatanotify(HttpServletRequest request) {
try {
logger.info("收到商品支付回调通知,开始处理...");
// 1. 使用WechatPayUtil处理支付回调
Map<String, Object> notifyResult = wechatPayUtil.handlePayNotify(request);
// 2. 检查处理结果
boolean success = (Boolean) notifyResult.get("success");
String message = (String) notifyResult.get("message");
if (!success) {
logger.error("商品支付回调处理失败:{}", message);
return buildFailResponse("商品支付回调处理失败");
}
// 3. 获取支付信息
Map<String, Object> paymentInfo = (Map<String, Object>) notifyResult.get("paymentInfo");
String outTradeNo = (String) paymentInfo.get("outTradeNo");
String transactionId = (String) paymentInfo.get("transactionId");
String totalFee = (String) paymentInfo.get("totalFee");
UsersPayBefor usersPayBefor = usersPayBeforService.selectUsersPayBeforByOrderId(outTradeNo);
if (usersPayBefor!=null){
usersPayBefor.setStatus(2L);
usersPayBefor.setPaytime(new Date());
usersPayBefor.setPaycode(transactionId);
usersPayBeforService.updateUsersPayBefor(usersPayBefor);
}
Users users = null;
if (usersPayBefor != null) {
users = usersService.selectUsersById(usersPayBefor.getUid());
}
//订单回调处理拼团创建订单其他订单修改状态
OrderUtil.prepayCallback(usersPayBefor, users);
// //最后无论如何平台流水需要添加让平台看到流水和账目
PayMoneyLog payMoneyLog = new PayMoneyLog();
if (usersPayBefor != null) {
payMoneyLog.setOid(usersPayBefor.getId());
}
payMoneyLog.setOrderId(usersPayBefor.getOrderid());
payMoneyLog.setUid(usersPayBefor.getUid());
if (users != null) {
payMoneyLog.setUname(users.getName());
}
payMoneyLog.setPrice(usersPayBefor.getWxmoney());
payMoneyLog.setMark("订单支付");
payMoneyLog.setPayTime(new Date());
payMoneyLogService.insertPayMoneyLog(payMoneyLog);
//sendWechatMessage(users,outTradeNo);
logger.info("商品支付回调处理成功,订单号:{}", outTradeNo);
return buildSuccessResponse();
} catch (Exception e) {
logger.error("商品支付回调处理异常:", e);
return buildFailResponse("商品支付回调处理异常");
}
}
/**
* 拼团支付的回调接口
*
* @param request HTTP请求对象
* @return XML格式响应给微信服务器
*IUserGroupBuyingService userGroupBuyingService;
* 处理商品订单的支付成功回调
* 1. 验证支付签名
* 2. 更新商品订单支付状态
* 3. 更新订单支付时间和交易号
* 4. 处理库存扣减等业务逻辑
*/
@PostMapping(value = "/api/order/amount/paydata/zuhenotify")
public String apiorderamountpaydatazuhenotify(HttpServletRequest request) {
try {
logger.info("收到商品支付回调通知,开始处理...");
// 1. 使用WechatPayUtil处理支付回调
Map<String, Object> notifyResult = wechatPayUtil.handlePayNotify(request);
// 2. 检查处理结果
boolean success = (Boolean) notifyResult.get("success");
String message = (String) notifyResult.get("message");
if (!success) {
logger.error("商品支付回调处理失败:{}", message);
return buildFailResponse("商品支付回调处理失败");
}
// 3. 获取支付信息
Map<String, Object> paymentInfo = (Map<String, Object>) notifyResult.get("paymentInfo");
String outTradeNo = (String) paymentInfo.get("outTradeNo");
String transactionId = (String) paymentInfo.get("transactionId");
String totalFee = (String) paymentInfo.get("totalFee");
UsersPayBefor usersPayBefor = usersPayBeforService.selectUsersPayBeforByOrderId(outTradeNo);
// 组合支付微信支付回调后自动扣余额
if (usersPayBefor != null && usersPayBefor.getYemoney() != null && usersPayBefor.getYemoney().compareTo(BigDecimal.ZERO) > 0) {
Users user = usersService.selectUsersById(usersPayBefor.getUid());
Map<String, Object> balanceResult = BalancePayUtil.processBalancePayment(
user.getId(),
usersPayBefor.getYemoney(),
"订单组合支付-余额部分" + usersPayBefor.getYemoney() + "",
usersPayBefor.getOrderid()
);
if (balanceResult == null || !Boolean.TRUE.equals(balanceResult.get("success"))) {
OrderUtil.prepayCallback(usersPayBefor, user);
String errorMsg = balanceResult != null ? (String) balanceResult.get("message") : "余额支付失败";
logger.error("组合支付余额部分扣款失败:{}", errorMsg);
return buildFailResponse("组合支付余额部分扣款失败: " + errorMsg);
}
}
if (usersPayBefor!=null){
usersPayBefor.setStatus(2L);
usersPayBefor.setPaytime(new Date());
usersPayBefor.setPaycode(transactionId);
usersPayBeforService.updateUsersPayBefor(usersPayBefor);
}
Users users = null;
if (usersPayBefor != null) {
users = usersService.selectUsersById(usersPayBefor.getUid());
}
//订单回调处理拼团创建订单其他订单修改状态
OrderUtil.prepayCallback(usersPayBefor, users);
// //最后无论如何平台流水需要添加让平台看到流水和账目
PayMoneyLog payMoneyLog = new PayMoneyLog();
if (usersPayBefor != null) {
payMoneyLog.setOid(usersPayBefor.getId());
}
payMoneyLog.setOrderId(usersPayBefor.getOrderid());
payMoneyLog.setUid(usersPayBefor.getUid());
if (users != null) {
payMoneyLog.setUname(users.getName());
}
payMoneyLog.setPrice(usersPayBefor.getWxmoney());
payMoneyLog.setMark("订单支付");
payMoneyLog.setPayTime(new Date());
payMoneyLogService.insertPayMoneyLog(payMoneyLog);
//sendWechatMessage(users,outTradeNo);
logger.info("商品支付回调处理成功,订单号:{}", outTradeNo);
return buildSuccessResponse();
} catch (Exception e) {
logger.error("商品支付回调处理异常:", e);
return buildFailResponse("商品支付回调处理异常");
}
}
/**
@ -1347,4 +1527,57 @@ public class PayNotifyController extends BaseController {
return "商品";
}
}
/**
* 次卡微信支付回调接口
* @param request HTTP请求对象
* @return XML格式响应给微信服务器
* 逻辑
* 1. 验证支付签名
* 2. 查询次卡使用记录orderId
* 3. 修改为可用状态
*/
@PostMapping("/api/secondary/card/paydata/notify")
public String secondaryCardPayDataNotify(HttpServletRequest request) {
try {
logger.info("收到次卡微信支付回调通知,开始处理...");
// 1. 使用WechatPayUtil处理支付回调
Map<String, Object> notifyResult = wechatPayUtil.handlePayNotify(request);
// 2. 检查处理结果
boolean success = (Boolean) notifyResult.get("success");
String message = (String) notifyResult.get("message");
if (!success) {
logger.error("次卡支付回调处理失败:{}", message);
return buildFailResponse("次卡支付回调处理失败");
}
// 3. 获取支付信息
Map<String, Object> paymentInfo = (Map<String, Object>) notifyResult.get("paymentInfo");
String outTradeNo = (String) paymentInfo.get("outTradeNo"); // 订单号
String transactionId = (String) paymentInfo.get("transactionId");
String totalFee = (String) paymentInfo.get("totalFee");
// 4. 查询次卡使用记录
UserUseSecondaryCard useCard = userUseSecondaryCardService.selectUserUseSecondaryCardByorderId(outTradeNo);
if (useCard == null) {
logger.error("未找到次卡使用记录,订单号:{}", outTradeNo);
return buildFailResponse("未找到次卡使用记录");
}
// 5. 修改为可用状态假设status=1为可用
useCard.setStatus(1L);
useCard.setUpdatedAt(new Date());
useCard.setTransactionId(transactionId);
userUseSecondaryCardService.updateUserUseSecondaryCard(useCard);
logger.info("次卡支付回调处理成功,订单号:{}", outTradeNo);
return buildSuccessResponse();
} catch (Exception e) {
logger.error("次卡支付回调处理异常:", e);
return buildFailResponse("次卡支付回调处理异常");
}
}
}

View File

@ -0,0 +1,104 @@
package com.ruoyi.system.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.ShopAddress;
import com.ruoyi.system.service.IShopAddressService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* 店铺地址Controller
*
* @author ruoyi
* @date 2025-07-17
*/
@RestController
@RequestMapping("/system/address")
public class ShopAddressController extends BaseController
{
@Autowired
private IShopAddressService shopAddressService;
/**
* 查询店铺地址列表
*/
@PreAuthorize("@ss.hasPermi('system:address:list')")
@GetMapping("/list")
public TableDataInfo list(ShopAddress shopAddress)
{
startPage();
List<ShopAddress> list = shopAddressService.selectShopAddressList(shopAddress);
return getDataTable(list);
}
/**
* 导出店铺地址列表
*/
@PreAuthorize("@ss.hasPermi('system:address:export')")
@Log(title = "店铺地址", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, ShopAddress shopAddress)
{
List<ShopAddress> list = shopAddressService.selectShopAddressList(shopAddress);
ExcelUtil<ShopAddress> util = new ExcelUtil<ShopAddress>(ShopAddress.class);
util.exportExcel(response, list, "店铺地址数据");
}
/**
* 获取店铺地址详细信息
*/
@PreAuthorize("@ss.hasPermi('system:address:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
return success(shopAddressService.selectShopAddressById(id));
}
/**
* 新增店铺地址
*/
@PreAuthorize("@ss.hasPermi('system:address:add')")
@Log(title = "店铺地址", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody ShopAddress shopAddress)
{
return toAjax(shopAddressService.insertShopAddress(shopAddress));
}
/**
* 修改店铺地址
*/
@PreAuthorize("@ss.hasPermi('system:address:edit')")
@Log(title = "店铺地址", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody ShopAddress shopAddress)
{
return toAjax(shopAddressService.updateShopAddress(shopAddress));
}
/**
* 删除店铺地址
*/
@PreAuthorize("@ss.hasPermi('system:address:remove')")
@Log(title = "店铺地址", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
return toAjax(shopAddressService.deleteShopAddressByIds(ids));
}
}

View File

@ -7,7 +7,6 @@ import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.AppleDoMain.OrderApple;
import com.ruoyi.system.service.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
@ -1685,6 +1684,8 @@ public class AppletControllerUtil {
List<Map<String, Object>> resultList = new ArrayList<>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (CouponUser couponUser : couponUserList) {
Map<String, Object> couponData = new HashMap<>();
ServiceGoods serviceGoods = null;
@ -2779,7 +2780,7 @@ public class AppletControllerUtil {
}
/**
* 更新购物车商品数量
* 更新购物车商品数量向后兼容版本
*
* @param cartItem 购物车商品记录
* @param serviceGoods 商品信息
@ -2790,6 +2791,27 @@ public class AppletControllerUtil {
GoodsCart cartItem,
ServiceGoods serviceGoods,
IGoodsCartService goodsCartService) {
return updateCartItemQuantity(cartItem, serviceGoods, goodsCartService, null, null, null);
}
/**
* 更新购物车商品数量
*
* @param cartItem 购物车商品记录
* @param serviceGoods 商品信息
* @param goodsCartService 购物车服务
* @param ordertype 订单类别
* @param fileData 附件
* @param remark 备注
* @return 更新结果
*/
public static AjaxResult updateCartItemQuantity(
GoodsCart cartItem,
ServiceGoods serviceGoods,
IGoodsCartService goodsCartService,
Long ordertype,
String fileData,
String remark) {
try {
// 数量加1
Long newQuantity = (cartItem.getGoodNum() != null ? cartItem.getGoodNum() : 0L) + 1L;
@ -2803,6 +2825,9 @@ public class AppletControllerUtil {
GoodsCart updateCart = new GoodsCart();
updateCart.setId(cartItem.getId());
updateCart.setGoodNum(newQuantity);
updateCart.setOrdertype(ordertype);
updateCart.setFileData(fileData);
updateCart.setReamk(remark);
updateCart.setUpdatedAt(new Date());
int updateResult = goodsCartService.updateGoodsCart(updateCart);
@ -2819,7 +2844,7 @@ public class AppletControllerUtil {
}
/**
* 新增购物车商品记录
* 新增购物车商品记录向后兼容版本
*
* @param user 用户信息
* @param serviceGoods 商品信息
@ -2832,6 +2857,29 @@ public class AppletControllerUtil {
ServiceGoods serviceGoods,
String sku,
IGoodsCartService goodsCartService) {
return addNewCartItem(user, serviceGoods, sku, goodsCartService, null, null, null);
}
/**
* 新增购物车商品记录
*
* @param user 用户信息
* @param serviceGoods 商品信息
* @param sku 商品规格
* @param goodsCartService 购物车服务
* @param ordertype 订单类别
* @param fileData 附件
* @param remark 备注
* @return 添加结果
*/
public static AjaxResult addNewCartItem(
Users user,
ServiceGoods serviceGoods,
String sku,
IGoodsCartService goodsCartService,
Long ordertype,
String fileData,
String remark) {
try {
// 构建购物车记录
GoodsCart newCartItem = new GoodsCart();
@ -2839,6 +2887,9 @@ public class AppletControllerUtil {
newCartItem.setGoodId(serviceGoods.getId());
newCartItem.setSku(sku);
newCartItem.setGoodNum(1L); // 默认数量为1
newCartItem.setOrdertype(ordertype);
newCartItem.setFileData(fileData);
newCartItem.setReamk(remark);
newCartItem.setCreatedAt(new Date());
newCartItem.setUpdatedAt(new Date());
@ -3143,7 +3194,7 @@ public class AppletControllerUtil {
data.put("icon", buildImageUrl(goods.getIcon()));
data.put("sub_title", goods.getSubTitle());
data.put("info", goods.getInfo());
data.put("price", goods.getPrice() != null ? goods.getPrice().toString() : "0.00");
data.put("price_zn", goods.getPriceZn());
data.put("sales", goods.getSales() != null ? goods.getSales().intValue() : 0);
data.put("stock", goods.getStock() != null ? goods.getStock().intValue() : 0);
@ -3160,6 +3211,12 @@ public class AppletControllerUtil {
// 处理SKU数据
// data.put("sku", parseSkuStringToObject(goods.getSku()));
data.put("latitude", goods.getLatitude());
data.put("groupprice", goods.getGroupprice() != null ? goods.getGroupprice().toString() : "0.00");
data.put("fixedprice", goods.getFixedprice() != null ? goods.getFixedprice().toString() : "0.00");
data.put("price", goods.getPrice() != null ? goods.getPrice().toString() : "0.00");
data.put("longitude", goods.getLongitude());
data.put("type", goods.getType() != null ? goods.getType() : 2);
data.put("cate_id", goods.getCateId());
@ -3170,6 +3227,7 @@ public class AppletControllerUtil {
data.put("basic", parseBasicStringToArray(goods.getBasic()));
data.put("margin", goods.getMargin() != null ? goods.getMargin().toString() : null);
data.put("skill_ids", goods.getSkillIds());
data.put("servicetype", goods.getServicetype());
// 处理图片数组
data.put("imgs", parseImagesStringToArray(goods.getImgs()));
// 时间字段

View File

@ -93,7 +93,7 @@ public class BalancePayUtil {
* - afterBalance: 支付后余额
* - consumptionLogId: 消费记录ID
*/
public static Map<String, Object> processBalancePayment(Long userId, BigDecimal money, String remark) {
public static Map<String, Object> processBalancePayment(Long userId, BigDecimal money, String remark,String orderid) {
Map<String, Object> result = new HashMap<>();
try {
@ -163,6 +163,7 @@ public class BalancePayUtil {
consumptionLog.setConsumptiontype(1); // 1=余额支付消费
consumptionLog.setConsumptiontime(new Date());
consumptionLog.setConsumptionmoney(money);
consumptionLog.setOrderid(orderid);
consumptionLog.setReamk(remark);
consumptionLog.setBeformoney(currentBalance);
consumptionLog.setAftermoney(afterBalance);

View File

@ -4,19 +4,17 @@ import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.utils.AmapUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.system.domain.Order;
import com.ruoyi.system.domain.OrderLog;
import com.ruoyi.system.domain.UserAddress;
import com.ruoyi.system.domain.Users;
import com.ruoyi.system.service.IOrderLogService;
import com.ruoyi.system.service.IUserAddressService;
import com.ruoyi.system.service.IUsersService;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.service.*;
import org.springframework.stereotype.Controller;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
/**
* 服务订单Controller工具类
* 专注于订单编号生成状态验证和用户地址处理等核心功能
@ -25,6 +23,8 @@ import java.util.*;
public class OrderUtil {
private static IUsersService usersService = SpringUtils.getBean(IUsersService.class);
private static IOrderLogService orderLogService = SpringUtils.getBean(IOrderLogService.class);
private static IGoodsOrderService goodsOrderService = SpringUtils.getBean(IGoodsOrderService.class);
private static OrderLogHandler orderLogHandler = SpringUtils.getBean(OrderLogHandler.class);
// 订单编号生成相关常量
@ -338,4 +338,450 @@ public class OrderUtil {
}
}
}
/**
* 拼团订单创建参考AppleOrderController标准流程
* @param id 预支付记录ID
* @return 新创建的订单对象若未找到预支付记录则返回null
*/
public Order createGroupOrderByPayBeforId(Long id) {
IUsersPayBeforService usersPayBeforService = SpringUtils.getBean(IUsersPayBeforService.class);
IServiceGoodsService serviceGoodsService = SpringUtils.getBean(IServiceGoodsService.class);
IUserAddressService userAddressService = SpringUtils.getBean(IUserAddressService.class);
IOrderService orderService = SpringUtils.getBean(IOrderService.class);
IOrderLogService orderLogService = SpringUtils.getBean(IOrderLogService.class);
// 1. 查询预支付记录
UsersPayBefor payBefor = usersPayBeforService.selectUsersPayBeforById(id);
if (payBefor == null) {
return null; // 未找到预支付记录
}
// 2. 查询商品信息
Long productId = null;
try {
productId = Long.valueOf(payBefor.getSku()); // 假设sku字段存储商品ID
} catch (Exception e) {
// 若sku不是商品ID则尝试orderid等其它方式
}
if (productId == null) {
// 若无法获取商品ID直接返回
return null;
}
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(productId);
if (serviceGoods == null) {
return null;
}
// 3. 查询地址信息
UserAddress userAddress = null;
if (payBefor.getAddressid() != null) {
userAddress = userAddressService.selectUserAddressById(payBefor.getAddressid());
}
// GenerateCustomCode.
// 4. 生成订单号
//com.ruoyi.system.ControllerUtil.GenerateCustomCode GenerateCustomCode = null;
String orderId = payBefor.getOrderid() != null ? payBefor.getOrderid() : GenerateCustomCode.generCreateOrder("PT");
// 5. 创建订单
Order order = new Order();
order.setOdertype(4); // 拼团
order.setStatus(9L); // 状态9
order.setOrderId(orderId);
order.setUid(payBefor.getUid());
order.setNum(1L); // 默认1可根据业务调整
order.setProductId(serviceGoods.getId());
order.setProductName(serviceGoods.getTitle());
order.setSku(payBefor.getSku());
order.setTotalPrice(payBefor.getAllmoney());
order.setPayPrice(payBefor.getWxmoney());
order.setCreateTime(new Date());
order.setType(1); // 服务订单
order.setCreateType(1); // 用户自主下单
order.setUname(""); // 可补充用户名称
if (userAddress != null) {
order.setAddressId(userAddress.getId());
order.setName(userAddress.getName());
order.setPhone(userAddress.getPhone());
order.setAddress(userAddress.getAddressInfo());
}
// 可补充其它字段如拼团价优惠券备注等
// 6. 保存订单
orderService.insertOrder(order);
// 7. 添加订单日志
OrderLog orderLog = new OrderLog();
orderLog.setOid(order.getId());
orderLog.setOrderId(order.getOrderId());
orderLog.setTitle("拼团订单创建");
orderLog.setType(new BigDecimal("1.0"));
orderLog.setContent("拼团订单创建成功");
orderLog.setRemark("拼团订单自动创建");
orderLogService.insertOrderLog(orderLog);
return order;
}
/**
* 订单价格确认工具方法
* 根据服务IDSKU是否一口价和订单类型计算最终价格
*
* @param serviceId 服务ID
* @param sku SKU信息格式{"精细擦玻璃":"20㎡全屋精细擦窗","pic":"","price":"236","groupprice":"100","seckillprice":"99","stock":"1000"}
* @param type 订单类别 1=拼团 2=次卡 3=秒杀
* @return 计算后的价格如果计算失败返回null
*
* 使用示例
* // 一口价订单单规格
* BigDecimal price1 = OrderUtil.confirmOrderPrice(1L, null, 1, 1);
*
* // 一口价订单多规格
* String sku = "{\"精细擦玻璃\":\"20㎡全屋精细擦窗\",\"pic\":\"\",\"price\":\"236\",\"groupprice\":\"100\",\"seckillprice\":\"99\",\"stock\":\"1000\"}";
* BigDecimal price2 = OrderUtil.confirmOrderPrice(1L, sku, 1, 1);
*
* // 拼团订单单规格
* BigDecimal price3 = OrderUtil.confirmOrderPrice(1L, null, 2, 1);
*
* // 秒杀订单多规格
* BigDecimal price4 = OrderUtil.confirmOrderPrice(1L, sku, 2, 3);
*/
public static BigDecimal confirmOrderPrice(Long serviceId, String sku, Integer type) {
try {
// // 参数验证
// if (serviceId == null || isyikoujia == null || type == null) {
// return null;
// }
// 获取服务商品信息
IServiceGoodsService serviceGoodsService = SpringUtils.getBean(IServiceGoodsService.class);
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(serviceId);
if (serviceGoods == null) {
return null;
}
// 获取sku_type默认为单规格
Integer skuType = serviceGoods.getSkuType();
if (skuType == null) {
skuType = 1; // 默认为单规格
}
// // 如果是一口价
// if (isyikoujia == 1) {
// // 如果是多规格商品从SKU中获取price
// if (skuType == 2 && sku != null && !sku.trim().isEmpty()) {
// return handleMultiSkuPrice(sku, null); // 传入null表示获取基础价格
// }
// // 单规格商品直接返回商品的基础价格
// return serviceGoods.getPrice();
// }
// 如果不是一口价需要根据sku_type和订单类型判断
// 单规格商品 (sku_type = 1)
if (skuType == 1) {
return handleSingleSkuPrice(serviceGoods, type);
}
// 多规格商品 (sku_type = 2)
else if (skuType == 2) {
return handleMultiSkuPrice(sku, type);
}
return null;
} catch (Exception e) {
// 记录异常信息这里可以添加日志记录
System.err.println("订单价格确认失败: " + e.getMessage());
return null;
}
}
/**
* 处理单规格商品价格计算
*
* @param serviceGoods 服务商品对象
* @param type 订单类型 1=拼团 2=次卡 3=秒杀
* @return 计算后的价格
*/
private static BigDecimal handleSingleSkuPrice(ServiceGoods serviceGoods, Integer type) {
switch (type) {
case 1: // 拼团
return serviceGoods.getGroupprice();
case 3: // 秒杀
return serviceGoods.getFixedprice();
case 2: // 一口价
return serviceGoods.getPrice();
default:
return serviceGoods.getPrice(); // 默认返回基础价格
}
}
/**
* 处理多规格商品价格计算
*
* @param sku SKU信息JSON字符串
* @param type 订单类型 1=拼团 2=次卡 3=秒杀null表示获取基础价格
* @return 计算后的价格
*/
private static BigDecimal handleMultiSkuPrice(String sku, Integer type) {
try {
if (sku == null || sku.trim().isEmpty()) {
return null;
}
// 解析SKU JSON
JSONObject skuJson = JSONObject.parseObject(sku);
// 如果type为null获取基础价格
if (type == null) {
String priceStr = skuJson.getString("price");
return parsePrice(priceStr);
}
switch (type) {
case 1: // 拼团
String groupPriceStr = skuJson.getString("groupprice");
return parsePrice(groupPriceStr);
case 3: // 秒杀
String seckillPriceStr = skuJson.getString("seckillprice");
return parsePrice(seckillPriceStr);
case 2: // 一口价
String priceStr = skuJson.getString("price");
return parsePrice(priceStr);
default:
String defaultPriceStr = skuJson.getString("price");
return parsePrice(defaultPriceStr);
}
} catch (Exception e) {
System.err.println("解析多规格SKU价格失败: " + e.getMessage());
return null;
}
}
/**
* 解析价格字符串为BigDecimal
*
* @param priceStr 价格字符串
* @return BigDecimal价格解析失败返回null
*/
private static BigDecimal parsePrice(String priceStr) {
try {
if (priceStr == null || priceStr.trim().isEmpty()) {
return null;
}
return new BigDecimal(priceStr.trim());
} catch (NumberFormatException e) {
System.err.println("价格格式解析失败: " + priceStr);
return null;
}
}
/**
* 预支付回调处理方法
* @param payBefor 预支付记录
* @param user 用户实体
* @return 新建的订单对象仅拼团或处理结果Map
*/
public static Object prepayCallback(UsersPayBefor payBefor, Users user) {
if (payBefor == null || user == null) {
return null;
}
int type = payBefor.getType() != null ? payBefor.getType().intValue() : 0;
IOrderService orderService = SpringUtils.getBean(IOrderService.class);
// 拼团
if (payBefor.getServicetype()==2){
GoodsOrder gorder = new GoodsOrder();
gorder.setMainOrderId(payBefor.getOrderid());
List<GoodsOrder> orderslist =goodsOrderService.selectGoodsOrderList(gorder);
if (!orderslist.isEmpty()){
for (GoodsOrder goodsOrder : orderslist){
goodsOrder.setStatus(2L);
goodsOrder.setTransactionId(payBefor.getPaycode());
goodsOrderService.updateGoodsOrder(goodsOrder);
}
}
return payBefor.getOrderid();
}
if (type == 1) {
String ptorderid= payBefor.getOrderid();
//第一步创建订单状态为待成团
Order order = new Order();
order.setOdertype(1); // 拼团
order.setStatus(9L); // 9=待成团
order.setOrderId(ptorderid);
order.setUid(payBefor.getUid());
order.setNum(1L); // 默认1可根据业务调整
//order.setProductId(payBefor.getSku() != null ? Long.valueOf(payBefor.getSku()) : null); // 假设sku字段存储商品ID
order.setProductId(payBefor.getServiceid()); // 假设sku字段存储商品ID
IServiceGoodsService serviceGoodsService = SpringUtils.getBean(IServiceGoodsService.class);
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(payBefor.getServiceid());
// 商品名图片类型价格等
String productName = "";
if (serviceGoods != null) {
productName = serviceGoods.getTitle();
}
order.setProductName(productName);
order.setSku(payBefor.getSku());
order.setTotalPrice(payBefor.getAllmoney());
order.setPayPrice(payBefor.getWxmoney());
order.setCreateTime(new Date());
order.setType(1); // 服务订单
order.setCreateType(1); // 用户自主下单
order.setUname(user.getName());
// 预约时间
if (payBefor.getMaketime() != null && !payBefor.getMaketime().isEmpty()) {
String[] makeTimeArr = payBefor.getMaketime().split(" ");
if (makeTimeArr.length == 2) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = sdf.parse(makeTimeArr[0]);
order.setMakeTime(date.getTime() / 1000);
order.setMakeHour(makeTimeArr[1]);
} catch (Exception e) {
// 忽略解析异常
}
}
}
if (payBefor.getAddressid() != null) {
IUserAddressService userAddressService = SpringUtils.getBean(IUserAddressService.class);
UserAddress userAddress = userAddressService.selectUserAddressById(payBefor.getAddressid());
if (userAddress != null) {
order.setAddressId(userAddress.getId());
order.setName(userAddress.getName());
order.setPhone(userAddress.getPhone());
order.setAddress(userAddress.getAddressInfo());
}
}
// 可补充其它字段如拼团价优惠券备注等
orderService.insertOrder(order);
// 添加订单日志
IOrderLogService orderLogService = SpringUtils.getBean(IOrderLogService.class);
//IOrderService orderService = SpringUtils.getBean(IOrderService.class);
OrderLog orderLog = new OrderLog();
orderLog.setOid(order.getId());
orderLog.setOrderId(order.getOrderId());
orderLog.setTitle("订单生成");
orderLog.setType(new BigDecimal("1.0"));
JSONObject jsonObject = new JSONObject();
jsonObject.put("name", "订单创建成功,待成团");
orderLog.setContent(jsonObject.toJSONString());
orderLogService.insertOrderLog(orderLog);
//第二步修改拼团时候的状态
IUserGroupBuyingService userGroupBuyingService = SpringUtils.getBean(IUserGroupBuyingService.class);
UserGroupBuying userGroupBuying = userGroupBuyingService.selectUserGroupBuyingByptorderid(ptorderid);
if (userGroupBuying != null){
userGroupBuying.setStatus(1L);
userGroupBuying.setPaystatus(1L);
userGroupBuyingService.updateUserGroupBuying(userGroupBuying);
}
//第三步核验团数据如果满足条件都修改为待预约
UserGroupBuying userGroupBuyingData = new UserGroupBuying();
userGroupBuyingData.setOrderid(payBefor.getGrouporderid());
userGroupBuyingData.setPaystatus(1L);
List<UserGroupBuying> userGroupBuyingList = userGroupBuyingService.selectUserGroupBuyingList(userGroupBuyingData);
if (userGroupBuyingList.size() >= serviceGoods.getGroupnum()) {
for (UserGroupBuying groupBuying1 : userGroupBuyingList){
groupBuying1.setStatus(1L);
groupBuying1.setPaystatus(1L);
userGroupBuyingService.updateUserGroupBuying(groupBuying1);
Order orderdata = orderService.selectOrderByOrderId(groupBuying1.getPtorderid());
if (orderdata != null){
orderdata.setStatus(10L);//已成团待预约
orderService.updateOrder(orderdata);
}
}
}
return order;
} else { // 其他类型
// 只更新订单状态为待预约假设为1
if (payBefor.getOrderid() != null) {
if (type == 2){
IUserUseSecondaryCardService userUseSecondaryCardService = SpringUtils.getBean(IUserUseSecondaryCardService.class);
UserUseSecondaryCard userUseSecondaryCard = userUseSecondaryCardService.selectUserUseSecondaryCardByorderId(payBefor.getOrderid());
if (userUseSecondaryCard != null){
userUseSecondaryCard.setStatus(1L);
userUseSecondaryCardService.updateUserUseSecondaryCard(userUseSecondaryCard);
}
return userUseSecondaryCard;
}else{
Order order = orderService.selectOrderByOrderId(payBefor.getOrderid());
if (order != null) {
OrderLog orderLog = new OrderLog();
orderLog.setOid(order.getId());
orderLog.setOrderId(order.getOrderId());
orderLog.setTitle("订单支付");
orderLog.setType(new BigDecimal("1.1"));
JSONObject jsonObject = new JSONObject();
jsonObject.put("name", "订单支付成功,待派单");
orderLog.setContent(jsonObject.toJSONString());
orderLogService.insertOrderLog(orderLog);
order.setStatus(1L); // 1=待预约
orderService.updateOrder(order);
return order;
}
}
}
return null;
}
}
/**
* 核验拼团订单
* @param orderId 主订单号
* @param uid 用户ID
* @return 处理结果 true=拼团成功 false=未成团
*/
public static boolean verifyGroupOrder(String orderId, Long uid) {
IUserGroupBuyingService userGroupBuyingService = SpringUtils.getBean(IUserGroupBuyingService.class);
IServiceGoodsService serviceGoodsService = SpringUtils.getBean(IServiceGoodsService.class);
IOrderService orderService = SpringUtils.getBean(IOrderService.class);
// 1. 查询拼团记录
UserGroupBuying query = new UserGroupBuying();
query.setOrderid(orderId);
query.setUid(uid);
List<UserGroupBuying> groupList = userGroupBuyingService.selectUserGroupBuyingList(query);
if (groupList == null || groupList.isEmpty()) {
return false;
}
UserGroupBuying group = groupList.get(0);
// 2. 设置paystatus=1
group.setPaystatus(1L);
userGroupBuyingService.updateUserGroupBuying(group);
// 3. 查询服务详情
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(group.getProductId());
if (serviceGoods == null) {
return false;
}
Integer groupNum = serviceGoods.getGroupnum();
if (groupNum == null || groupNum <= 0) {
return false;
}
// 4. 统计已支付人数
UserGroupBuying paidQuery = new UserGroupBuying();
paidQuery.setOrderid(orderId);
paidQuery.setPaystatus(1L);
List<UserGroupBuying> paidList = userGroupBuyingService.selectUserGroupBuyingList(paidQuery);
int paidCount = paidList != null ? paidList.size() : 0;
// 5. 如果已支付人数达到拼团人数更新订单状态
if (paidCount >= groupNum) {
// 查询所有mainOrderId=orderId的订单
Order orderQuery = new Order();
orderQuery.setMainOrderId(orderId);
List<Order> orderList = orderService.selectOrderList(orderQuery);
if (orderList != null) {
for (Order o : orderList) {
o.setStatus(1L); // 1=待预约
orderService.updateOrder(o);
}
}
return true;
}
return false;
}
}

View File

@ -81,7 +81,7 @@ public class WechatPayUtil {
private static final String WECHAT_TRANSFER_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; // 企业付款
public static final String PAY_FH = "https://1571276c.r3.cpolar.top/";
public static final String PAY_FH = "https://c5ed8e7.r3.cpolar.top/";
/**
* 其他配置常量
*/

View File

@ -22,6 +22,9 @@ public class OrderApple extends BaseEntity {
private Long status;// 4
private String total_price;// "68.00"
private Integer type;// 1
private Integer odertype;// 1
private Integer reamk;// 1
private String fileData;
private Long uid;// : 302
@ -152,4 +155,20 @@ public class OrderApple extends BaseEntity {
public void setFileData(String fileData) {
this.fileData = fileData;
}
public Integer getOdertype() {
return odertype;
}
public void setOdertype(Integer odertype) {
this.odertype = odertype;
}
public Integer getReamk() {
return reamk;
}
public void setReamk(Integer reamk) {
this.reamk = reamk;
}
}

View File

@ -28,6 +28,15 @@ public class GoodsCart extends BaseEntity
@Excel(name = "商品id")
private Long goodId;
/** 商品id */
@Excel(name = "商品分类")
private Long goodstype;
/** 商品数量 */
@Excel(name = "商品数量")
private Long goodNum;
@ -36,6 +45,18 @@ public class GoodsCart extends BaseEntity
@Excel(name = "规格")
private String sku;
/** 规格 */
@Excel(name = "备注")
private String reamk;
/** 规格 */
@Excel(name = "附件")
private String fileData;
/** 规格 */
@Excel(name = "类别")
private Long ordertype;
/** $column.columnComment */
@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
private Date createdAt;
@ -114,6 +135,31 @@ public class GoodsCart extends BaseEntity
return updatedAt;
}
public String getReamk() {
return reamk;
}
public void setReamk(String reamk) {
this.reamk = reamk;
}
public String getFileData() {
return fileData;
}
public void setFileData(String fileData) {
this.fileData = fileData;
}
public Long getOrdertype() {
return ordertype;
}
public void setOrdertype(Long ordertype) {
this.ordertype = ordertype;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

View File

@ -89,7 +89,13 @@ public class GoodsOrder extends BaseEntity
@Excel(name = "优惠券id")
private Long couponId;
/** 支付金额 */
@Excel(name = "是否自提 1是 2不是")
private Long isself;
/** 支付金额 */
@Excel(name = "自提店铺地址id")
private Long shopadresssid;
/** 抵扣金额 */
@Excel(name = "抵扣金额")
@ -508,6 +514,23 @@ public class GoodsOrder extends BaseEntity
this.couponId = couponId;
}
public Long getIsself() {
return isself;
}
public void setIsself(Long isself) {
this.isself = isself;
}
public Long getShopadresssid() {
return shopadresssid;
}
public void setShopadresssid(Long shopadresssid) {
this.shopadresssid = shopadresssid;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

View File

@ -196,10 +196,12 @@ public class Order extends BaseEntity
/** 订单附件 */
@Excel(name = "订单附件")
private String fileData;
/** 录音文件 */
@Excel(name = "订单类别 1预约 2报价 3一口价 4拼团 5普通订单")
private int odertype;
private String reamk;
private OrderLog orderLog;
private String cartid;
private BigDecimal totalPriceMin;
private BigDecimal totalPriceMax;
private BigDecimal payPriceMin;
@ -848,6 +850,31 @@ public class Order extends BaseEntity
this.fileData = fileData;
}
public int getOdertype() {
return odertype;
}
public void setOdertype(int odertype) {
this.odertype = odertype;
}
public String getReamk() {
return reamk;
}
public void setReamk(String reamk) {
this.reamk = reamk;
}
public String getCartid() {
return cartid;
}
public void setCartid(String cartid) {
this.cartid = cartid;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

View File

@ -0,0 +1,186 @@
package com.ruoyi.system.domain;
import java.util.Date;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* 店铺地址对象 shop_address
*
* @author ruoyi
* @date 2025-07-17
*/
public class ShopAddress extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** $column.columnComment */
private Long id;
/** 店铺名称 */
@Excel(name = "店铺名称")
private String shopName;
/** 店铺地址 */
@Excel(name = "店铺地址")
private String shopAddress;
/** 联系电话 */
@Excel(name = "联系电话")
private String contactPhone;
/** 经度 */
@Excel(name = "经度")
private String longitude;
/** 纬度 */
@Excel(name = "纬度")
private String latitude;
/** 联系人 */
@Excel(name = "联系人")
private String contactPerson;
/** 地址状态 */
@Excel(name = " 地址状态")
private Long addressStatus;
/** $column.columnComment */
private Date createdAt;
/** $column.columnComment */
private Date updatedAt;
/** $column.columnComment */
private Date deletedAt;
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setShopName(String shopName)
{
this.shopName = shopName;
}
public String getShopName()
{
return shopName;
}
public void setShopAddress(String shopAddress)
{
this.shopAddress = shopAddress;
}
public String getShopAddress()
{
return shopAddress;
}
public void setContactPhone(String contactPhone)
{
this.contactPhone = contactPhone;
}
public String getContactPhone()
{
return contactPhone;
}
public void setLongitude(String longitude)
{
this.longitude = longitude;
}
public String getLongitude()
{
return longitude;
}
public void setLatitude(String latitude)
{
this.latitude = latitude;
}
public String getLatitude()
{
return latitude;
}
public void setContactPerson(String contactPerson)
{
this.contactPerson = contactPerson;
}
public String getContactPerson()
{
return contactPerson;
}
public void setAddressStatus(Long addressStatus)
{
this.addressStatus = addressStatus;
}
public Long getAddressStatus()
{
return addressStatus;
}
public void setCreatedAt(Date createdAt)
{
this.createdAt = createdAt;
}
public Date getCreatedAt()
{
return createdAt;
}
public void setUpdatedAt(Date updatedAt)
{
this.updatedAt = updatedAt;
}
public Date getUpdatedAt()
{
return updatedAt;
}
public void setDeletedAt(Date deletedAt)
{
this.deletedAt = deletedAt;
}
public Date getDeletedAt()
{
return deletedAt;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("shopName", getShopName())
.append("shopAddress", getShopAddress())
.append("contactPhone", getContactPhone())
.append("longitude", getLongitude())
.append("latitude", getLatitude())
.append("contactPerson", getContactPerson())
.append("addressStatus", getAddressStatus())
.append("createdAt", getCreatedAt())
.append("updatedAt", getUpdatedAt())
.append("deletedAt", getDeletedAt())
.toString();
}
}

View File

@ -53,6 +53,11 @@ public class UserGroupBuying extends BaseEntity
@Excel(name = "支付订单号")
private String transactionId;
/** 支付订单号 */
@Excel(name = "拼团订单号")
private String ptorderid;
/** 支付订单号 */
@Excel(name = "头像")
private String image;
@ -220,6 +225,14 @@ public class UserGroupBuying extends BaseEntity
this.paystatus = paystatus;
}
public String getPtorderid() {
return ptorderid;
}
public void setPtorderid(String ptorderid) {
this.ptorderid = ptorderid;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

View File

@ -74,6 +74,10 @@ public class UsersPayBefor extends BaseEntity
@Excel(name = "订类别 1=拼团 2=次卡 3=秒杀 4=报价 0=普通预约", readConverterExp = "必=填")
private Long type;
private Long serviceid;
/** 订单号码 */
@Excel(name = "订单号码")
private String orderid;
@ -91,6 +95,16 @@ public class UsersPayBefor extends BaseEntity
@Excel(name = "支付时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date paytime;
private Long servicetype;
private String sku;
private Long addressid;
private String maketime;
private String attachments;
private String grouporderid;
/** 支付订单号 */
@Excel(name = "支付订单号")
private String paycode;
@ -283,6 +297,64 @@ public class UsersPayBefor extends BaseEntity
this.allmoney = allmoney;
}
public String getAttachments() {
return attachments;
}
public void setAttachments(String attachments) {
this.attachments = attachments;
}
public String getMaketime() {
return maketime;
}
public void setMaketime(String maketime) {
this.maketime = maketime;
}
public Long getAddressid() {
return addressid;
}
public void setAddressid(Long addressid) {
this.addressid = addressid;
}
public String getSku() {
return sku;
}
public void setSku(String sku) {
this.sku = sku;
}
public String getGrouporderid() {
return grouporderid;
}
public void setGrouporderid(String grouporderid) {
this.grouporderid = grouporderid;
}
public Long getServiceid() {
return serviceid;
}
public void setServiceid(Long serviceid) {
this.serviceid = serviceid;
}
public Long getServicetype() {
return servicetype;
}
public void setServicetype(Long servicetype) {
this.servicetype = servicetype;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

View File

@ -0,0 +1,61 @@
package com.ruoyi.system.mapper;
import java.util.List;
import com.ruoyi.system.domain.ShopAddress;
/**
* 店铺地址Mapper接口
*
* @author ruoyi
* @date 2025-07-17
*/
public interface ShopAddressMapper
{
/**
* 查询店铺地址
*
* @param id 店铺地址主键
* @return 店铺地址
*/
public ShopAddress selectShopAddressById(Long id);
/**
* 查询店铺地址列表
*
* @param shopAddress 店铺地址
* @return 店铺地址集合
*/
public List<ShopAddress> selectShopAddressList(ShopAddress shopAddress);
/**
* 新增店铺地址
*
* @param shopAddress 店铺地址
* @return 结果
*/
public int insertShopAddress(ShopAddress shopAddress);
/**
* 修改店铺地址
*
* @param shopAddress 店铺地址
* @return 结果
*/
public int updateShopAddress(ShopAddress shopAddress);
/**
* 删除店铺地址
*
* @param id 店铺地址主键
* @return 结果
*/
public int deleteShopAddressById(Long id);
/**
* 批量删除店铺地址
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
public int deleteShopAddressByIds(Long[] ids);
}

View File

@ -22,6 +22,10 @@ public interface UserGroupBuyingMapper
*/
public UserGroupBuying selectUserGroupBuyingById(Long id);
public UserGroupBuying selectUserGroupBuyingByptorderid(String ptorderid);
/**
* 查询拼团专区管理列表
*

View File

@ -19,6 +19,11 @@ public interface UserUseSecondaryCardMapper
*/
public UserUseSecondaryCard selectUserUseSecondaryCardById(Long id);
public UserUseSecondaryCard selectUserUseSecondaryCardByorderId(String orderid);
/**
* 查询次卡使用列表
*

View File

@ -19,6 +19,11 @@ public interface UsersPayBeforMapper
*/
public UsersPayBefor selectUsersPayBeforById(Long id);
public UsersPayBefor selectUsersPayBeforByOrderId(String orderid);
/**
* 查询预支付列表
*

View File

@ -0,0 +1,61 @@
package com.ruoyi.system.service;
import java.util.List;
import com.ruoyi.system.domain.ShopAddress;
/**
* 店铺地址Service接口
*
* @author ruoyi
* @date 2025-07-17
*/
public interface IShopAddressService
{
/**
* 查询店铺地址
*
* @param id 店铺地址主键
* @return 店铺地址
*/
public ShopAddress selectShopAddressById(Long id);
/**
* 查询店铺地址列表
*
* @param shopAddress 店铺地址
* @return 店铺地址集合
*/
public List<ShopAddress> selectShopAddressList(ShopAddress shopAddress);
/**
* 新增店铺地址
*
* @param shopAddress 店铺地址
* @return 结果
*/
public int insertShopAddress(ShopAddress shopAddress);
/**
* 修改店铺地址
*
* @param shopAddress 店铺地址
* @return 结果
*/
public int updateShopAddress(ShopAddress shopAddress);
/**
* 批量删除店铺地址
*
* @param ids 需要删除的店铺地址主键集合
* @return 结果
*/
public int deleteShopAddressByIds(Long[] ids);
/**
* 删除店铺地址信息
*
* @param id 店铺地址主键
* @return 结果
*/
public int deleteShopAddressById(Long id);
}

View File

@ -21,6 +21,8 @@ public interface IUserGroupBuyingService
*/
public UserGroupBuying selectUserGroupBuyingById(Long id);
public UserGroupBuying selectUserGroupBuyingByptorderid(String ptorderid);
/**
* 查询拼团专区管理列表
*

View File

@ -19,6 +19,11 @@ public interface IUserUseSecondaryCardService
*/
public UserUseSecondaryCard selectUserUseSecondaryCardById(Long id);
public UserUseSecondaryCard selectUserUseSecondaryCardByorderId(String orderid);
/**
* 查询次卡使用列表
*

View File

@ -19,6 +19,10 @@ public interface IUsersPayBeforService
*/
public UsersPayBefor selectUsersPayBeforById(Long id);
public UsersPayBefor selectUsersPayBeforByOrderId(String orderid);
/**
* 查询预支付列表
*

View File

@ -0,0 +1,93 @@
package com.ruoyi.system.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.ShopAddressMapper;
import com.ruoyi.system.domain.ShopAddress;
import com.ruoyi.system.service.IShopAddressService;
/**
* 店铺地址Service业务层处理
*
* @author ruoyi
* @date 2025-07-17
*/
@Service
public class ShopAddressServiceImpl implements IShopAddressService
{
@Autowired
private ShopAddressMapper shopAddressMapper;
/**
* 查询店铺地址
*
* @param id 店铺地址主键
* @return 店铺地址
*/
@Override
public ShopAddress selectShopAddressById(Long id)
{
return shopAddressMapper.selectShopAddressById(id);
}
/**
* 查询店铺地址列表
*
* @param shopAddress 店铺地址
* @return 店铺地址
*/
@Override
public List<ShopAddress> selectShopAddressList(ShopAddress shopAddress)
{
return shopAddressMapper.selectShopAddressList(shopAddress);
}
/**
* 新增店铺地址
*
* @param shopAddress 店铺地址
* @return 结果
*/
@Override
public int insertShopAddress(ShopAddress shopAddress)
{
return shopAddressMapper.insertShopAddress(shopAddress);
}
/**
* 修改店铺地址
*
* @param shopAddress 店铺地址
* @return 结果
*/
@Override
public int updateShopAddress(ShopAddress shopAddress)
{
return shopAddressMapper.updateShopAddress(shopAddress);
}
/**
* 批量删除店铺地址
*
* @param ids 需要删除的店铺地址主键
* @return 结果
*/
@Override
public int deleteShopAddressByIds(Long[] ids)
{
return shopAddressMapper.deleteShopAddressByIds(ids);
}
/**
* 删除店铺地址信息
*
* @param id 店铺地址主键
* @return 结果
*/
@Override
public int deleteShopAddressById(Long id)
{
return shopAddressMapper.deleteShopAddressById(id);
}
}

View File

@ -69,6 +69,12 @@ public class UserGroupBuyingServiceImpl implements IUserGroupBuyingService
return userGroupBuyingMapper.updateUserGroupBuying(userGroupBuying);
}
public UserGroupBuying selectUserGroupBuyingByptorderid(String ptorderid) {
return userGroupBuyingMapper.selectUserGroupBuyingByptorderid(ptorderid);
}
/**
* 批量删除拼团专区管理
*

View File

@ -19,6 +19,13 @@ public class UserUseSecondaryCardServiceImpl implements IUserUseSecondaryCardSer
@Autowired
private UserUseSecondaryCardMapper userUseSecondaryCardMapper;
public UserUseSecondaryCard selectUserUseSecondaryCardByorderId(String orderid){
return userUseSecondaryCardMapper.selectUserUseSecondaryCardByorderId(orderid);
}
/**
* 查询次卡使用
*

View File

@ -31,6 +31,11 @@ public class UsersPayBeforServiceImpl implements IUsersPayBeforService
return usersPayBeforMapper.selectUsersPayBeforById(id);
}
public UsersPayBefor selectUsersPayBeforByOrderId(String orderid){
return usersPayBeforMapper.selectUsersPayBeforByOrderId(orderid);
}
/**
* 查询预支付列表
*

View File

@ -101,7 +101,7 @@ public class QiniuUploadUtil {
DefaultPutRet putRet = JSON.parseObject(response.bodyString(), DefaultPutRet.class);
// 返回完整的访问URL
return putRet.key;
return "https://" + config.getDomain() + "/" + putRet.key;
} catch (QiniuException ex) {
Response r = ex.response;

View File

@ -10,12 +10,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="goodId" column="good_id" />
<result property="goodNum" column="good_num" />
<result property="sku" column="sku" />
<result property="fileData" column="file_data" />
<result property="reamk" column="reamk" />
<result property="ordertype" column="ordertype" />
<result property="createdAt" column="created_at" />
<result property="updatedAt" column="updated_at" />
<result property="goodstype" column="goodstype" />
</resultMap>
<sql id="selectGoodsCartVo">
select id, uid, good_id, good_num, sku, created_at, updated_at from goods_cart
select id, uid, good_id, good_num, sku,goodstype,ordertype,reamk,file_data, created_at, updated_at from goods_cart
</sql>
<select id="selectGoodsCartList" parameterType="GoodsCart" resultMap="GoodsCartResult">
@ -23,10 +27,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<where>
<if test="uid != null "> and uid = #{uid}</if>
<if test="goodId != null "> and good_id = #{goodId}</if>
<if test="goodNum != null "> and good_num = #{goodNum}</if>
<if test="sku != null and sku != ''"> and sku = #{sku}</if>
<if test="createdAt != null "> and created_at = #{createdAt}</if>
<if test="updatedAt != null "> and updated_at = #{updatedAt}</if>
<if test="goodstype != null "> and goodstype = #{goodstype}</if>
</where>
order by id desc
</select>
@ -43,6 +44,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="goodId != null">good_id,</if>
<if test="goodNum != null">good_num,</if>
<if test="sku != null">sku,</if>
<if test="fileData != null">file_data,</if>
<if test="reamk != null">reamk,</if>
<if test="ordertype != null">ordertype,</if>
<if test="goodstype != null">goodstype,</if>
created_at,
updated_at
</trim>
@ -51,6 +56,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="goodId != null">#{goodId},</if>
<if test="goodNum != null">#{goodNum},</if>
<if test="sku != null">#{sku},</if>
<if test="fileData != null">#{fileData},</if>
<if test="reamk != null">#{reamk},</if>
<if test="ordertype != null">#{ordertype},</if>
<if test="goodstype != null">#{goodstype},</if>
NOW(),
NOW()
</trim>
@ -63,6 +72,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="goodId != null">good_id = #{goodId},</if>
<if test="goodNum != null">good_num = #{goodNum},</if>
<if test="sku != null">sku = #{sku},</if>
<if test="fileData != null">file_data = #{fileData},</if>
<if test="reamk != null">reamk = #{reamk},</if>
<if test="ordertype != null">ordertype = #{ordertype},</if>
<if test="goodstype != null">goodstype = #{goodstype},</if>
updated_at=NOW()
</trim>
where id = #{id}

View File

@ -34,10 +34,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="createdAt" column="created_at" />
<result property="updatedAt" column="updated_at" />
<result property="deletedAt" column="deleted_at" />
<result property="isself" column="isself" />
<result property="shopadresssid" column="shopadresssid" />
</resultMap>
<sql id="selectGoodsOrderVo">
select id, type, main_order_id, order_id, transaction_id, uid, product_id, name, phone, address, num, total_price, good_price, service_price, pay_price, deduction, postage, pay_time, status, delivery_id, delivery_num, send_time, mark, address_id, sku, created_at, updated_at, deleted_at from goods_order
select id, type, main_order_id, order_id, transaction_id,isself,coupon_id,shopadresssid, uid, product_id, name, phone, address, num, total_price, good_price, service_price, pay_price, deduction, postage, pay_time, status, delivery_id, delivery_num, send_time, mark, address_id, sku, created_at, updated_at, deleted_at from goods_order
</sql>
<select id="selectGoodsOrderList" parameterType="GoodsOrder" resultMap="GoodsOrderResult">
@ -111,6 +116,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="mark != null">mark,</if>
<if test="addressId != null">address_id,</if>
<if test="sku != null">sku,</if>
<if test="isself != null">isself,</if>
<if test="shopadresssid != null">shopadresssid,</if>
created_at,
updated_at
<if test="deletedAt != null">deleted_at,</if>
@ -142,6 +149,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="addressId != null">#{addressId},</if>
<if test="sku != null">#{sku},</if>
<if test="deletedAt != null">#{deletedAt},</if>
<if test="isself != null">#{isself},</if>
<if test="shopadresssid != null">#{shopadresssid},</if>
NOW(),
NOW()
@ -177,6 +186,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="addressId != null">address_id = #{addressId},</if>
<if test="sku != null">sku = #{sku},</if>
<if test="deletedAt != null">deleted_at = #{deletedAt},</if>
<if test="isself != null">isself = #{isself},</if>
<if test="shopadresssid != null">shopadresssid = #{shopadresssid},</if>
updated_at=NOW()
</trim>

View File

@ -20,6 +20,8 @@
<result property="makeTime" column="make_time"/>
<result property="makeHour" column="make_hour"/>
<result property="num" column="num"/>
<result property="cartid" column="cartid"/>
<result property="totalPrice" column="total_price"/>
<result property="goodPrice" column="good_price"/>
<result property="servicePrice" column="service_price"/>
@ -51,12 +53,18 @@
<result property="createdAt" column="created_at"/>
<result property="updatedAt" column="updated_at"/>
<result property="deletedAt" column="deleted_at"/>
<result property="odertype" column="odertype"/>
<result property="reamk" column="reamk"/>
</resultMap>
<resultMap type="OrderApple" id="OrderAppleResult">
<result property="created_at" column="deleted_at"/>
<result property="reamk" column="reamk"/>
<result property="id" column="id"/>
<result property="odertype" column="odertype"/>
<result property="is_comment" column="is_comment"/>
<result property="make_hour" column="make_hour"/>
<result property="make_time" column="make_time"/>
@ -66,6 +74,8 @@
<result property="order_id" column="order_id"/>
<result property="product_id" column="product_id"/>
<result property="sku" column="sku"/>
<result property="cartid" column="cartid"/>
<result property="status" column="status"/>
<result property="total_price" column="total_price"/>
<result property="type" column="type"/>
@ -82,12 +92,15 @@
create_type,
create_phone,
uid,
cartid,
odertype,
product_id,
name,
phone,
address,
make_time,
make_hour,
reamk,
num,
total_price,
good_price,
@ -185,6 +198,10 @@
<if test="workerId != null">
and worker_id = #{workerId}
</if>
<if test="cartid != null">
and cartid = #{cartid}
</if>
</where>
order by id desc
</select>
@ -344,6 +361,16 @@
<if test="fileData != null">
file_data,
</if>
<if test="odertype != null">
odertype,
</if>
<if test="reamk != null">
reamk,
</if>
<if test="cartid != null">
cartid,
</if>
created_at,
updated_at
</trim>
@ -480,6 +507,16 @@
<if test="fileData != null">
#{fileData},
</if>
<if test="odertype != null">
#{odertype},
</if>
<if test="reamk != null">
#{reamk},
</if>
<if test="cartid != null">
#{cartid},
</if>
NOW(),
NOW()
</trim>
@ -517,6 +554,10 @@
<if test="productId != null">
product_id = #{productId},
</if>
<if test="odertype != null">
odertype = #{odertype},
</if>
<if test="name != null and name != ''">
name = #{name},
</if>
@ -622,6 +663,12 @@
<if test="deletedAt != null">
deleted_at = #{deletedAt},
</if>
<if test="reamk != null">
reamk = #{reamk},
</if>
<if test="cartid != null">
cartid = #{cartid},
</if>
updated_at = NOW()
</trim>
where id = #{id}

View File

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.ShopAddressMapper">
<resultMap type="ShopAddress" id="ShopAddressResult">
<result property="id" column="id" />
<result property="shopName" column="shop_name" />
<result property="shopAddress" column="shop_address" />
<result property="contactPhone" column="contact_phone" />
<result property="longitude" column="longitude" />
<result property="latitude" column="latitude" />
<result property="contactPerson" column="contact_person" />
<result property="addressStatus" column="address_status" />
<result property="createdAt" column="created_at" />
<result property="updatedAt" column="updated_at" />
<result property="deletedAt" column="deleted_at" />
</resultMap>
<sql id="selectShopAddressVo">
select id, shop_name, shop_address, contact_phone, longitude, latitude, contact_person, address_status, created_at, updated_at, deleted_at from shop_address
</sql>
<select id="selectShopAddressList" parameterType="ShopAddress" resultMap="ShopAddressResult">
<include refid="selectShopAddressVo"/>
<where>
<if test="shopName != null and shopName != ''"> and shop_name like concat('%', #{shopName}, '%')</if>
<if test="shopAddress != null and shopAddress != ''"> and shop_address like concat('%', #{shopAddress}, '%')</if>
<if test="contactPhone != null and contactPhone != ''"> and contact_phone like concat('%', #{contactPhone}, '%')</if>
<if test="addressStatus != null "> and address_status = #{addressStatus}</if>
</where>
</select>
<select id="selectShopAddressById" parameterType="Long" resultMap="ShopAddressResult">
<include refid="selectShopAddressVo"/>
where id = #{id}
</select>
<insert id="insertShopAddress" parameterType="ShopAddress">
insert into shop_address
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">id,</if>
<if test="shopName != null">shop_name,</if>
<if test="shopAddress != null">shop_address,</if>
<if test="contactPhone != null">contact_phone,</if>
<if test="longitude != null">longitude,</if>
<if test="latitude != null">latitude,</if>
<if test="contactPerson != null">contact_person,</if>
<if test="addressStatus != null">address_status,</if>
<if test="createdAt != null">created_at,</if>
<if test="updatedAt != null">updated_at,</if>
<if test="deletedAt != null">deleted_at,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">#{id},</if>
<if test="shopName != null">#{shopName},</if>
<if test="shopAddress != null">#{shopAddress},</if>
<if test="contactPhone != null">#{contactPhone},</if>
<if test="longitude != null">#{longitude},</if>
<if test="latitude != null">#{latitude},</if>
<if test="contactPerson != null">#{contactPerson},</if>
<if test="addressStatus != null">#{addressStatus},</if>
<if test="createdAt != null">#{createdAt},</if>
<if test="updatedAt != null">#{updatedAt},</if>
<if test="deletedAt != null">#{deletedAt},</if>
</trim>
</insert>
<update id="updateShopAddress" parameterType="ShopAddress">
update shop_address
<trim prefix="SET" suffixOverrides=",">
<if test="shopName != null">shop_name = #{shopName},</if>
<if test="shopAddress != null">shop_address = #{shopAddress},</if>
<if test="contactPhone != null">contact_phone = #{contactPhone},</if>
<if test="longitude != null">longitude = #{longitude},</if>
<if test="latitude != null">latitude = #{latitude},</if>
<if test="contactPerson != null">contact_person = #{contactPerson},</if>
<if test="addressStatus != null">address_status = #{addressStatus},</if>
<if test="createdAt != null">created_at = #{createdAt},</if>
<if test="updatedAt != null">updated_at = #{updatedAt},</if>
<if test="deletedAt != null">deleted_at = #{deletedAt},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteShopAddressById" parameterType="Long">
delete from shop_address where id = #{id}
</delete>
<delete id="deleteShopAddressByIds" parameterType="String">
delete from shop_address where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

View File

@ -20,10 +20,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="productId" column="product_id" />
<result property="createdAt" column="created_at" />
<result property="updatedAt" column="updated_at" />
<result property="ptorderid" column="ptorderid" />
</resultMap>
<sql id="selectUserGroupBuyingVo">
select id, orderid, uid, money, status, deduction, paystatus,image,uname, paytime, transaction_id, paytype, product_id, created_at, updated_at from user_group_buying
select id, orderid, uid, money, status, ptorderid,deduction, paystatus,image,uname, paytime, transaction_id, paytype, product_id, created_at, updated_at from user_group_buying
</sql>
<select id="selectUserGroupBuyingList" parameterType="UserGroupBuying" resultMap="UserGroupBuyingResult">
@ -33,6 +35,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="status != null "> and status = #{status}</if>
<if test="uname != null and uname != ''"> and uname like concat('%', #{uname}, '%')</if>
<if test="paytype != null "> and paytype = #{paytype}</if>
<if test="ptorderid != null "> and ptorderid = #{ptorderid}</if>
<if test="paystatus != null "> and paystatus = #{paystatus}</if>
</where>
</select>
@ -41,6 +47,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where id = #{id}
</select>
<select id="selectUserGroupBuyingByptorderid" parameterType="String" resultMap="UserGroupBuyingResult">
<include refid="selectUserGroupBuyingVo"/>
where ptorderid = #{ptorderid}
</select>
<insert id="insertUserGroupBuying" parameterType="UserGroupBuying">
insert into user_group_buying
<trim prefix="(" suffix=")" suffixOverrides=",">
@ -57,6 +68,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="productId != null">product_id,</if>
<if test="image != null">image,</if>
<if test="paystatus != null">paystatus,</if>
<if test="ptorderid != null">ptorderid,</if>
created_at,
updated_at
@ -75,6 +87,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="productId != null">#{productId},</if>
<if test="image != null">#{image},</if>
<if test="paystatus != null">#{paystatus},</if>
<if test="ptorderid != null">#{ptorderid},</if>
NOW(),
NOW()
</trim>
@ -95,6 +109,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="paytype != null">paytype = #{paytype},</if>
<if test="productId != null">product_id = #{productId},</if>
<if test="paystatus != null">paystatus = #{paystatus},</if>
<if test="ptorderid != null">ptorderid = #{ptorderid},</if>
updated_at = NOW(),
</trim>
where id = #{id}

View File

@ -20,7 +20,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap>
<sql id="selectUserUseSecondaryCardVo">
select id, uid, carid, goodsids, num, usenum, orderid, introduction,transaction_id, paymoney, status, created_at, updated_at from user_use_secondary_card
select id, uid, carid, goodsids, num, usenum, orderid,transaction_id, paymoney, status, created_at, updated_at from user_use_secondary_card
</sql>
<select id="selectUserUseSecondaryCardList" parameterType="UserUseSecondaryCard" resultMap="UserUseSecondaryCardResult">
@ -28,15 +28,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<where>
<if test="uid != null "> and uid = #{uid}</if>
<if test="carid != null and carid != ''"> and carid = #{carid}</if>
<if test="goodsids != null and goodsids != ''"> and goodsids = #{goodsids}</if>
<if test="num != null "> and num = #{num}</if>
<if test="usenum != null "> and usenum = #{usenum}</if>
<if test="orderid != null and orderid != ''"> and orderid = #{orderid}</if>
<if test="transactionId != null and transactionId != ''"> and transaction_id = #{transactionId}</if>
<if test="paymoney != null "> and paymoney = #{paymoney}</if>
<if test="status != null "> and status = #{status}</if>
<if test="createdAt != null "> and created_at = #{createdAt}</if>
<if test="updatedAt != null "> and updated_at = #{updatedAt}</if>
</where>
</select>
@ -45,6 +42,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where id = #{id}
</select>
<select id="selectUserUseSecondaryCardByorderId" parameterType="String" resultMap="UserUseSecondaryCardResult">
<include refid="selectUserUseSecondaryCardVo"/>
where orderid = #{orderid}
</select>
<insert id="insertUserUseSecondaryCard" parameterType="UserUseSecondaryCard" useGeneratedKeys="true" keyProperty="id">
insert into user_use_secondary_card
<trim prefix="(" suffix=")" suffixOverrides=",">

View File

@ -18,6 +18,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="mtcode" column="mtcode" />
<result property="mtmoney" column="mtmoney" />
<result property="allmoney" column="allmoney" />
<result property="servicetype" column="servicetype" />
<result property="sku" column="sku" />
<result property="addressid" column="addressid" />
<result property="maketime" column="maketime" />
<result property="attachments" column="attachments" />
<result property="grouporderid" column="grouporderid" />
<result property="serviceid" column="serviceid" />
<result property="type" column="type" />
<result property="orderid" column="orderid" />
@ -28,7 +37,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap>
<sql id="selectUsersPayBeforVo">
select id, uid, paytype, wxmoney, yemoney, allmoney,membermoney, shopmoney, servicemoney, couponid, couponmoney, mtcode, mtmoney, type, orderid, oid, status, paytime, paycode from users_pay_befor
select id, uid, paytype,grouporderid, 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">
@ -51,6 +60,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="status != null "> and status = #{status}</if>
<if test="paytime != null "> and paytime = #{paytime}</if>
<if test="paycode != null and paycode != ''"> and paycode = #{paycode}</if>
</where>
</select>
@ -59,6 +71,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where id = #{id}
</select>
<select id="selectUsersPayBeforByOrderId" parameterType="String" resultMap="UsersPayBeforResult">
<include refid="selectUsersPayBeforVo"/>
where orderid = #{orderid} limit 1
</select>
<insert id="insertUsersPayBefor" parameterType="UsersPayBefor" useGeneratedKeys="true" keyProperty="id">
insert into users_pay_befor
<trim prefix="(" suffix=")" suffixOverrides=",">
@ -81,6 +99,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="paycode != null">paycode,</if>
<if test="allmoney != null">allmoney,</if>
<if test="sku != null">sku,</if>
<if test="addressid != null">addressid,</if>
<if test="maketime != null">maketime,</if>
<if test="attachments != null">attachments,</if>
<if test="grouporderid != null">grouporderid,</if>
<if test="serviceid != null">serviceid,</if>
<if test="servicetype != null">servicetype,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
@ -103,6 +130,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="paycode != null">#{paycode},</if>
<if test="allmoney != null">#{allmoney},</if>
<if test="sku != null">#{sku},</if>
<if test="addressid != null">#{addressid},</if>
<if test="maketime != null">#{maketime},</if>
<if test="attachments != null">#{attachments},</if>
<if test="grouporderid != null">#{grouporderid},</if>
<if test="serviceid != null">#{serviceid},</if>
<if test="servicetype != null">#{servicetype},</if>
</trim>
</insert>
@ -127,6 +162,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="paytime != null">paytime = #{paytime},</if>
<if test="paycode != null">paycode = #{paycode},</if>
<if test="allmoney != null">allmoney = #{allmoney},</if>
<if test="serviceid != null">serviceid = #{serviceid},</if>
<if test="sku != null">sku = #{sku},</if>
<if test="addressid != null">addressid = #{addressid},</if>
<if test="maketime != null">maketime = #{maketime},</if>
<if test="attachments != null">attachments = #{attachments},</if>
<if test="grouporderid != null">grouporderid = #{grouporderid},</if>
<if test="servicetype != null">servicetype = #{servicetype},</if>
</trim>
where id = #{id}

View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询店铺地址列表
export function listAddress(query) {
return request({
url: '/system/address/list',
method: 'get',
params: query
})
}
// 查询店铺地址详细
export function getAddress(id) {
return request({
url: '/system/address/' + id,
method: 'get'
})
}
// 新增店铺地址
export function addAddress(data) {
return request({
url: '/system/address',
method: 'post',
data: data
})
}
// 修改店铺地址
export function updateAddress(data) {
return request({
url: '/system/address',
method: 'put',
data: data
})
}
// 删除店铺地址
export function delAddress(id) {
return request({
url: '/system/address/' + id,
method: 'delete'
})
}

View File

@ -0,0 +1,298 @@
<template>
<div>
<el-card class="sku-main-card" shadow="never">
<SkuForm
:source-attribute="sourceAttribute"
:attribute.sync="attribute"
:sku.sync="sku"
:structure="structure"
ref="skuForm"
:theme="2"
>
<template #score="slotProps">
<div>
<el-rate v-model="slotProps.row.score" />
</div>
</template>
<template #pic="slotProps">
<div class="upimg">
<div class="imgs"> <image-upload v-model="slotProps.row.pic" :limit="1" :isShowTip="false" /></div>
</div>
</template>
</SkuForm>
</el-card>
</div>
</template>
<script>
import SkuForm from './skufrom.vue'
export default {
components:{
SkuForm
},
props:{
info:{
type:String,
}
},
watch:{
info:{
handler() {
this.init();
}
}
},
mounted(){
this.init();
},
data() {
return {
data:{},
sourceAttribute: [
],
attribute: [
],
sku: [
],
structure:[
{
name: 'pic',
type: 'slot',
label: '图片',
batch:false
},
{
name: 'price',
type: 'input',
label: '价格',
batch:false,
required: true
},
{
name: 'stock',
type: 'input',
label: '库存',
batch:false,
required: true
}
],
}
},
methods: {
parseInfoToSkuData(infoStr) {
let data;
try {
data = typeof infoStr === 'string' ? JSON.parse(infoStr) : infoStr;
} catch {
return {
sourceAttribute: [],
attribute: [],
sku: []
};
}
const attrs = data.attrs || {};
const attrArr = Object.keys(attrs).map(name => ({
name,
item: attrs[name]
}));
// sku
return {
sourceAttribute: JSON.parse(JSON.stringify(attrArr)),
attribute: JSON.parse(JSON.stringify(attrArr)),
sku: Array.isArray(data.sku) ? data.sku.map(item => {
const specNames = Object.keys(attrs);
const skuValue = specNames.map(name => item[name]).join(';');
return {
sku: skuValue,
...item
}
}) : []
};
},
init(){
if(this.info){
this.data=JSON.parse(this.info);
//
const parsed = this.parseInfoToSkuData(this.info);
this.sourceAttribute = parsed.sourceAttribute;
this.attribute = parsed.attribute;
this.sku = parsed.sku;
this.$refs.skuForm.init()
}
},
TodoData(){
// 1. attrs
const attrs = {};
//
this.$refs.skuForm.getArray().forEach(attr => {
if(attr.name && Array.isArray(attr.item)){
attrs[attr.name] = attr.item.map(r => r.name || r);
}
});
// 2. sku
//
const specNames = Object.keys(attrs);
// sku
const skuList = (this.sku || []).map(row => {
const result = {};
//
const _txt=row.sku.split(';');
_txt.forEach((name,index) => {
result[specNames[index]] = name;
})
//
this.structure.forEach(col => {
if(row[col.name] !== undefined) result[col.name] = row[col.name];
});
return result;
});
return {
type: 'many',
attrs,
sku: skuList
};
},
submit() {
let _IS=false
this.$refs.skuForm.validate(valid => {
if (valid) {
_IS=JSON.stringify(this.TodoData())
} else {
_IS=false
}
})
return _IS
},
add(){
this.sourceAttribute.push({
"name": "",
"item": [],
"input":""
})
this.attribute.push({
"name": "",
"item": []
})
this.$refs.skuForm.init()
this.generateSku()
},
itemAdd(row){
if(row.input){
row.item.push(row.input)
row.input = ""
}else{
this.$message.error("请输入内容")
}
},
generateSku() {
// SKU
this.sku = [];
//
let specs = this.sourceAttribute.map(attr => {
return {
name: attr.name,
items: attr.item
};
}).filter(spec => spec.name && spec.items.length > 0);
//
if (specs.length === 0) {
return;
}
//
const generateCombinations = (specs) => {
if (specs.length === 0) return [[]];
const [first, ...rest] = specs;
const combinations = generateCombinations(rest);
return first.items.flatMap(item =>
combinations.map(combination => [item, ...combination])
);
};
//
const combinations = generateCombinations(specs);
// SKU
this.sku = combinations.map(combination => {
const skuItem = {
specs: {},
price: 0,
stock: 0,
imageUrl: ''
};
//
specs.forEach((spec, index) => {
skuItem.specs[spec.name] = combination[index];
});
return skuItem;
});
// attribute
this.attribute = specs.map(spec => ({
name: spec.name,
item: spec.items
}));
},
itemDelete(row){
console.log(row)
this.sourceAttribute.splice(row.vmCount, 1);
this.attribute.splice(row.vmCount, )
this.$refs.skuForm.init()
this.generateSku()
}
}
}
</script>
<style scoped lang="scss">
.upimg {
display: inline-flex;
align-items: center;
::v-deep .el-upload--picture-card {
width: 60px !important;
height: 60px !important;
line-height: 66px !important;
}
::v-deep .el-upload-list--picture-card .el-upload-list__item {
width: 60px !important;
height: 60px !important;
line-height: 60px !important;
}
.imgs {
margin-right: 15px;
}
}
.sku-main-card {
margin: 24px 0 24px 0;
background: #f8fafd;
border-radius: 10px;
border: 1px solid #e6e8eb;
box-shadow: 0 2px 8px 0 rgba(0,0,0,0.03);
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,11 @@
<template #pic="slotProps">
<div class="upimg">
<div class="imgs"> <image-upload v-model="slotProps.row.pic" :limit="1" :isShowTip="false" /></div>
<div class="imgs">
<image-upload v-model="slotProps.row.pic" :isShowTip="false" :limit="1"/>
<!-- <image-upload v-model="slotProps.row.pic" :limit="1" :isShowTip="false" :fileSize="10" /> -->
</div>
</div>
</template>
</SkuForm>
@ -66,7 +70,9 @@ export default {
name: 'pic',
type: 'slot',
label: '图片',
batch:false
batch:false,
required: true
},
{
@ -77,6 +83,23 @@ export default {
required: true
},
{
name: 'groupprice',
type: 'input',
label: '拼团价',
batch:false,
required: true
},
{
name: 'seckillprice',
type: 'input',
label: '秒杀价',
batch:false,
required: true
},
{
name: 'stock',
type: 'input',
@ -102,8 +125,9 @@ export default {
};
}
const attrs = data.attrs || {};
const attrArr = Object.keys(attrs).map(name => ({
const attrArr = Object.keys(attrs).map((name,index) => ({
name,
desc:data.desc[index] || '',
item: attrs[name]
}));
// sku
@ -129,6 +153,7 @@ export default {
this.attribute = parsed.attribute;
this.sku = parsed.sku;
this.$refs.skuForm.init()
}
},
TodoData(){
@ -137,9 +162,11 @@ export default {
//
this.$refs.skuForm.getArray().forEach(attr => {
if(attr.name && Array.isArray(attr.item)){
attrs[attr.name] = attr.item.map(r => r.name || r);
}
});
console.log(this.$refs.skuForm.getArray())
// 2. sku
//
const specNames = Object.keys(attrs);
@ -160,10 +187,11 @@ export default {
});
return result;
});
console.log(attrs)
return {
type: 'many',
attrs,
desc:this.$refs.skuForm.getArray().map(r=>r.desc),
sku: skuList
};
},
@ -186,10 +214,12 @@ export default {
this.sourceAttribute.push({
"name": "",
"item": [],
// "desc": "",
"input":""
})
this.attribute.push({
"name": "",
// "desc": "",
"item": []
})
this.$refs.skuForm.init()
@ -211,6 +241,7 @@ export default {
let specs = this.sourceAttribute.map(attr => {
return {
name: attr.name,
// desc: attr.desc,
items: attr.item
};
}).filter(spec => spec.name && spec.items.length > 0);
@ -255,6 +286,7 @@ export default {
// attribute
this.attribute = specs.map(spec => ({
name: spec.name,
// desc: spec.desc,
item: spec.items
}));
},

View File

@ -47,6 +47,14 @@
@change="onAttributeNameChange(index, $event, item.name)"
>
</el-input>
<el-input
placeholder="请输入描述"
:value="item.desc"
style="width: 200px"
clearable
@change="onAttributeNameChange(index, $event, item.desc)"
>
</el-input>
</div>
<el-checkbox
v-for="(item2, index2) in item.item"
@ -75,16 +83,28 @@
</el-card>
</div>
<el-table v-else :data="myAttribute" :show-header="false" class="theme-2" border >
<el-table-column prop="name" :resizable="false" width="180px">
<el-table-column prop="name" :resizable="false" width="500px">
<template slot-scope="scope">
<el-input
placeholder="请输入内容"
v-model="scope.row.name"
style="width: 150px"
style="width: 300px"
clearable
@focus="onAttributeNameFocus(scope)"
@blur="onAttributeNameBlur(scope.$index, $event, scope)"
>
<template slot="prepend">名称</template>
</el-input>
<div></div>
<el-input
placeholder="请输入描述"
v-model="scope.row.desc"
style="width: 400px"
clearable
>
<template slot="prepend">描述</template>
</el-input>
</template>
</el-table-column>
@ -251,6 +271,10 @@
<el-button size="small" type="primary" class="batch-btn" @click="onBatchSet('price')">批量设置价格</el-button>
<el-input v-model="batchSetStock" size="small" placeholder="批量设置库存" class="batch-input" />
<el-button size="small" type="success" class="batch-btn" @click="onBatchSet('stock')">批量设置库存</el-button>
<el-input v-model="batchSetGroupPrice" size="small" placeholder="批量设置拼团价" class="batch-input" />
<el-button size="small" type="primary" class="batch-btn" @click="onBatchSet('groupprice')">批量设置拼团价</el-button>
<el-input v-model="batchSetSeckillPrice" size="small" placeholder="批量设置秒杀价" class="batch-input" />
<el-button size="small" type="primary" class="batch-btn" @click="onBatchSet('seckillprice')">批量设置秒杀价</el-button>
</div>
</el-card>
<div class="sku-divider"></div>
@ -341,6 +365,8 @@ export default {
form: {
skuData: [],
},
batchSetGroupPrice: '',
batchSetSeckillPrice: '',
batch: {},
attributeNameMap: {},
batchSetPrice: '',
@ -397,6 +423,7 @@ export default {
this.myAttribute.forEach((v1) => {
const obj = {
name: v1.name,
desc: v1.desc,
item: [],
};
v1.item.forEach((v2) => {
@ -418,6 +445,7 @@ export default {
this.myAttribute.forEach((attr, idx) => {
if (!Object.prototype.hasOwnProperty.call(attr, '_oldName')) {
this.$set(this.myAttribute[idx], '_oldName', attr.name);
this.$set(this.myAttribute[idx], '_oldDesc', attr.desc);
}
});
if (!this.isInit) {
@ -557,6 +585,7 @@ export default {
this.myAttribute.push({
name: this.inputname.trim(),
desc:"",
item: [],
canAddAttribute: true,
addAttribute: "",
@ -582,12 +611,14 @@ export default {
? v.canAddAttribute
: true,
addAttribute: "",
desc: v.desc,
item: [],
};
v.item.forEach((itemName) => {
temp.item.push({
name: itemName,
checked: false,
desc: v.desc,
});
});
myAttribute.push(temp);
@ -607,6 +638,7 @@ export default {
) {
myAttrVal.item.push({
name: attrName,
desc: attr.desc,
checked: true,
});
}
@ -738,18 +770,24 @@ export default {
v.price = this.batchSetPrice;
});
this.batchSetPrice = '';
} else if (type === 'stock' && this.batchSetStock !== '') {
}
if (type === 'stock' && this.batchSetStock !== '') {
this.form.skuData.forEach((v) => {
v.stock = this.batchSetStock;
});
this.batchSetStock = '';
} else if (this.batch[type] != "") {
}
if (type === 'groupprice' && this.batchSetGroupPrice !== '') {
this.form.skuData.forEach((v) => {
v[type] = this.batch[type];
v.groupprice = this.batchSetGroupPrice;
});
this.batch[type] = "";
//
this.validateFieldByColumns([type], () => {});
this.batchSetGroupPrice = '';
}
if (type === 'seckillprice' && this.batchSetSeckillPrice !== '') {
this.form.skuData.forEach((v) => {
v.seckillprice = this.batchSetSeckillPrice;
});
this.batchSetSeckillPrice = '';
}
},
// structure validate callback
@ -866,8 +904,10 @@ export default {
this.myAttribute[index].name = newName;
this.$set(this.myAttribute[index], '_oldName', newName);
this.$forceUpdate();
},
},
}
}
};
</script>

View File

@ -43,7 +43,7 @@ import BeautyWrapper from '@/components/BeautyWrapper'
import UserSelect from '@/components/UserSelect'
import sku from '@/components/Sku/sku'
import shopSku from '@/components/ShopSku/sku'
// 全局方法挂载
Vue.prototype.getDicts = getDicts
Vue.prototype.getConfigKey = getConfigKey
@ -66,6 +66,7 @@ Vue.component('ImagePreview', ImagePreview)
Vue.component('BeautyWrapper', BeautyWrapper)
Vue.component('UserSelect', UserSelect)
Vue.component('Sku', sku)
Vue.component('ShopSku', shopSku)
Vue.use(directive)
Vue.use(plugins)

View File

@ -284,7 +284,7 @@
</el-form-item> -->
</div>
<div v-else>
<Sku :info="form.sku" ref="skuRef"></Sku>
<ShopSku :info="form.sku" ref="skuRef"></ShopSku>
</div>
</el-tab-pane>

View File

@ -221,11 +221,20 @@
<dict-tag :options="dict.type.order_status" :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column label="订单类别" align="center" prop="odertype">
<template slot-scope="scope">
<dict-tag :options="dict.type.order_ordertype" :value="scope.row.odertype"/>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createdAt" width="120">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createdAt, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="通话记录" align="center" width="100">
<template slot-scope="scope">
<div class="record-box" @click="showRecordDetails(scope.row, 'call')">
@ -1153,7 +1162,7 @@ import EditInfo from './components/EditInfo'
export default {
name: "Order",
dicts: ['order_status'],
dicts: ['order_status','order_ordertype'],
components: {
CallRecord,
AudioRecord,

View File

@ -243,7 +243,7 @@
</template>
</el-table-column>
<el-table-column label="秒杀价格" align="center" prop="fixedprice" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right">
<template slot-scope="scope">
<el-button
size="mini"
@ -463,7 +463,7 @@
<el-form-item label="下单类型" prop="servicetype">
<el-radio-group v-model="form.servicetype">
<el-radio-group v-model="form.servicetype" @change="handleServiceTypeChange">
<el-radio
v-for="dict in dict.type.servicetype"
:key="dict.value"
@ -473,13 +473,14 @@
</el-form-item>
<el-form-item label="是否可拼团" prop="isgroup">
<el-radio-group v-model="form.isgroup">
<el-radio-group v-model="form.isgroup" :disabled="disableGroupAndFixed">
<el-radio
v-for="dict in dict.type.fixed"
:key="dict.value"
:label="parseInt(dict.value)"
>{{dict.label}}</el-radio>
</el-radio-group>
<div v-if="disableGroupAndFixed" style="color:#999;font-size:12px;">仅一口价可设置拼团</div>
</el-form-item>
<el-form-item label="拼团价" prop="groupprice" v-if="form.isgroup === 1">
<el-input-number v-model="form.groupprice" :min="0" :step="0.01" :precision="2" placeholder="请输入拼团价" style="width: 200px" />
@ -531,13 +532,14 @@
</el-select>
</el-form-item>
<el-form-item label="是否为秒杀" prop="isfixed">
<el-radio-group v-model="form.isfixed">
<el-radio-group v-model="form.isfixed" :disabled="disableGroupAndFixed">
<el-radio
v-for="dict in dict.type.fixed"
:key="dict.value"
:label="parseInt(dict.value)"
>{{dict.label}}</el-radio>
</el-radio-group>
<div v-if="disableGroupAndFixed" style="color:#999;font-size:12px;">仅一口价可设置秒杀</div>
</el-form-item>
<el-form-item label="秒杀价格" prop="fixedprice" v-if="form.isfixed === 1">
<el-input-number v-model="form.fixedprice" :min="0" :step="0.01" :precision="2" placeholder="请输入秒杀价格" style="width: 200px"/>
@ -849,6 +851,7 @@ export default {
showBasicInput: false,
newBasicTag: '',
saveTimeout: null, //
disableGroupAndFixed: false, //
}
},
created() {
@ -1045,6 +1048,7 @@ export default {
this.open = true
this.title = "添加服务内容"
this.handleServiceTypeChange(this.form.servicetype);
},
getSiteSkillList(){
@ -1288,6 +1292,7 @@ export default {
this.open = true
this.title = "修改服务内容"
this.handleServiceTypeChange(this.form.servicetype);
}).catch(error => {
console.error('编辑数据加载失败:', error);
this.$message.error('编辑数据加载失败,请重试');
@ -2057,6 +2062,16 @@ export default {
}
})
},
handleServiceTypeChange(value) {
// 1=2=3=
if (value === 1 || value === 2) {
this.form.isgroup = 2; //
this.form.isfixed = 2; //
this.disableGroupAndFixed = true;
} else {
this.disableGroupAndFixed = false;
}
},
}
}
</script>

View File

@ -12,6 +12,16 @@
<el-form-item label="抢单结束时间">
<el-time-picker v-model="baseForm.endTime" placeholder="选择时间" format="HH:mm" value-format="HH:mm" style="width: 150px" />
</el-form-item>
<el-form-item label="秒杀结束时间">
<el-date-picker
v-model="baseForm.mstime"
type="datetime"
placeholder="选择秒杀结束时间"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
style="width: 300px"
/>
</el-form-item>
<el-form-item label="质保金扣除比例">
<el-input-number v-model="baseForm.marginRate" :min="0" :max="100" />
<span style="margin-left: 8px">%</span>
@ -598,6 +608,7 @@ export default {
phone: '',
startTime: '',
endTime: '',
mstime: '',
marginRate: 10,
consumption: 0,
servicefee: 0,
@ -690,6 +701,7 @@ export default {
phone: configOneObj.phone || '',
startTime: configOneObj.loot_start || '',
endTime: configOneObj.loot_end || '',
mstime: configOneObj.mstime || '',
marginRate: configOneObj.margin || 10,
consumption: configOneObj.consumption || 0,
servicefee: configOneObj.servicefee || 0,
@ -810,6 +822,8 @@ export default {
},
resetBase() {
this.$refs.baseForm && this.$refs.baseForm.resetFields && this.$refs.baseForm.resetFields()
// mstime
this.baseForm.mstime = ''
},
handleQrChange(file) {
//
@ -883,6 +897,7 @@ export default {
phone: this.baseForm.phone,
loot_start: this.baseForm.startTime,
loot_end: this.baseForm.endTime,
mstime: this.baseForm.mstime,
margin: this.baseForm.marginRate,
consumption: this.baseForm.consumption,
servicefee: this.baseForm.servicefee,

View File

@ -0,0 +1,318 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="店铺名称" prop="shopName">
<el-input
v-model="queryParams.shopName"
placeholder="请输入店铺名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="店铺地址" prop="shopAddress">
<el-input
v-model="queryParams.shopAddress"
placeholder="请输入店铺地址"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="联系电话" prop="contactPhone">
<el-input
v-model="queryParams.contactPhone"
placeholder="请输入联系电话"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label=" 地址状态" prop="addressStatus">
<el-select v-model="queryParams.addressStatus" placeholder="请选择 地址状态" clearable>
<el-option
v-for="dict in dict.type.shopadress_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['system:address:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['system:address:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:address:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['system:address:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="addressList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="${comment}" align="center" prop="id" />
<el-table-column label="店铺名称" align="center" prop="shopName" />
<el-table-column label="店铺地址" align="center" prop="shopAddress" />
<el-table-column label="联系电话" align="center" prop="contactPhone" />
<el-table-column label="经度" align="center" prop="longitude" />
<el-table-column label="纬度" align="center" prop="latitude" />
<el-table-column label="联系人" align="center" prop="contactPerson" />
<el-table-column label=" 地址状态" align="center" prop="addressStatus">
<template slot-scope="scope">
<dict-tag :options="dict.type.shopadress_status" :value="scope.row.addressStatus"/>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['system:address:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:address:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改店铺地址对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="店铺名称" prop="shopName">
<el-input v-model="form.shopName" placeholder="请输入店铺名称" />
</el-form-item>
<el-form-item label="店铺地址" prop="shopAddress">
<el-input v-model="form.shopAddress" placeholder="请输入店铺地址" />
</el-form-item>
<el-form-item label="联系电话" prop="contactPhone">
<el-input v-model="form.contactPhone" placeholder="请输入联系电话" />
</el-form-item>
<el-form-item label="经度" prop="longitude">
<el-input v-model="form.longitude" placeholder="请输入经度" />
</el-form-item>
<el-form-item label="纬度" prop="latitude">
<el-input v-model="form.latitude" placeholder="请输入纬度" />
</el-form-item>
<el-form-item label="联系人" prop="contactPerson">
<el-input v-model="form.contactPerson" placeholder="请输入联系人" />
</el-form-item>
<el-form-item label=" 地址状态" prop="addressStatus">
<el-radio-group v-model="form.addressStatus">
<el-radio
v-for="dict in dict.type.shopadress_status"
:key="dict.value"
:label="parseInt(dict.value)"
>{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listAddress, getAddress, delAddress, addAddress, updateAddress } from "@/api/system/address"
export default {
name: "Address",
dicts: ['shopadress_status'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
addressList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
shopName: null,
shopAddress: null,
contactPhone: null,
addressStatus: null,
},
//
form: {},
//
rules: {
}
}
},
created() {
this.getList()
},
methods: {
/** 查询店铺地址列表 */
getList() {
this.loading = true
listAddress(this.queryParams).then(response => {
this.addressList = response.rows
this.total = response.total
this.loading = false
})
},
//
cancel() {
this.open = false
this.reset()
},
//
reset() {
this.form = {
id: null,
shopName: null,
shopAddress: null,
contactPhone: null,
longitude: null,
latitude: null,
contactPerson: null,
addressStatus: null,
createdAt: null,
updatedAt: null,
deletedAt: null
}
this.resetForm("form")
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm")
this.handleQuery()
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = "添加店铺地址"
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id = row.id || this.ids
getAddress(id).then(response => {
this.form = response.data
this.open = true
this.title = "修改店铺地址"
})
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateAddress(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
} else {
addAddress(this.form).then(response => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids
this.$modal.confirm('是否确认删除店铺地址编号为"' + ids + '"的数据项?').then(function() {
return delAddress(ids)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
},
/** 导出按钮操作 */
handleExport() {
this.download('system/address/export', {
...this.queryParams
}, `address_${new Date().getTime()}.xlsx`)
}
}
}
</script>