Browse Source

修复下单端系统派单

master
前端-胡立永 2 weeks ago
parent
commit
ecfa4d29f5
9 changed files with 520 additions and 10 deletions
  1. +448
    -0
      CatmDogd-Mall-Front-test/src/views/model/AppletOrder/detail.vue
  2. +1
    -0
      ruoyi-catdog/src/main/java/com/ruoyi/applet/service/impl/IMallOrderServiceImpl.java
  3. +4
    -0
      ruoyi-catdog/src/main/java/com/ruoyi/model/domain/AppletOrder.java
  4. +3
    -1
      ruoyi-catdog/src/main/java/com/ruoyi/model/mapper/AppletConfigMapper.java
  5. +3
    -0
      ruoyi-catdog/src/main/java/com/ruoyi/model/service/IAppletConfigService.java
  6. +16
    -0
      ruoyi-catdog/src/main/java/com/ruoyi/model/service/impl/AppletConfigServiceImpl.java
  7. +37
    -5
      ruoyi-catdog/src/main/java/com/ruoyi/model/service/impl/AppletOrderServiceImpl.java
  8. +1
    -1
      ruoyi-catdog/src/main/resources/mapper/model/AppletConfigMapper.xml
  9. +7
    -3
      ruoyi-catdog/src/main/resources/mapper/model/AppletOrderMapper.xml

+ 448
- 0
CatmDogd-Mall-Front-test/src/views/model/AppletOrder/detail.vue View File

@ -0,0 +1,448 @@
<template>
<div class="order_detail_wrapper">
<el-main v-loading="loading">
<el-card class="mt10">
<el-descriptions title="订单信息" :column="2" border label-class-name="my-label"
contentClassName="my-content">
<el-descriptions-item label="订单编号">{{ orderDetail.orderSn }}</el-descriptions-item>
<el-descriptions-item label="订单金额">{{ orderDetail.price }}</el-descriptions-item>
<el-descriptions-item label="订单详细地址">{{ orderDetail.address }}</el-descriptions-item>
</el-descriptions>
</el-card>
<el-card class="mt10">
<el-descriptions title="接单信息" :column="2" border label-class-name="my-label"
contentClassName="my-content">
<el-descriptions-item label="派单次数">{{ orderDetail.num }}</el-descriptions-item>
<el-descriptions-item label="接单时间">{{ parseTime(orderDetail.acceptTime, '') || '最终接单的时间' }}</el-descriptions-item>
<el-descriptions-item label="接单用时(h)">{{ orderDetail.whenTakOrders ? (orderDetail.whenTakOrders / 3600).toFixed(2) : '--' }}</el-descriptions-item>
<el-descriptions-item label="最终接单伴宠师">
<span style="color: #409eff;" v-if="orderDetail.userId && getAppUsersPhone(orderDetail.userId)">
{{ getAppUsersPhone(orderDetail.userId) }}
</span>
<span style="color: #f00;" v-else-if="orderDetail.userId">伴宠师已离职/已不是伴宠师</span>
</el-descriptions-item>
</el-descriptions>
</el-card>
<el-card class="mt10">
<el-descriptions title="开始派单记录" :column="2" border label-class-name="my-label"
contentClassName="my-content">
<el-descriptions-item label="开始派单的时间">{{ parseTime(orderDetail.createTime, '') || '' }}</el-descriptions-item>
<el-descriptions-item label="开始派单类型">
<dict-tag :options="dict.type.applet_order_type" :value="orderDetail.createType" />
</el-descriptions-item>
<el-descriptions-item label="开始派单指定伴宠师">
<span style="color: #409eff;" v-if="orderDetail.createUserIdJson">
{{ orderDetail.createUserIdJson }}
</span>
</el-descriptions-item>
<!-- <el-descriptions-item label="开始派单接单伴宠师">
<span style="color: #409eff;" v-if="orderDetail.createAcceptUserId">
{{ orderDetail.createAcceptUserId }}
</span>
</el-descriptions-item> -->
</el-descriptions>
</el-card>
<el-card class="mt10">
<el-descriptions title="最新派单记录" :column="2" border label-class-name="my-label"
contentClassName="my-content">
<el-descriptions-item label="最新派单的时间">{{ parseTime(orderDetail.newOrderTime, '') || '' }}</el-descriptions-item>
<el-descriptions-item label="最新派单类型">
<dict-tag :options="dict.type.applet_order_type" :value="orderDetail.type" />
</el-descriptions-item>
<el-descriptions-item label="最新派单指定伴宠师">
<span style="color: #409eff;" v-if="orderDetail.userIdJson">
{{ orderDetail.userIdJson }}
</span>
</el-descriptions-item>
<el-descriptions-item label="最新派单接单伴宠师">
<span style="color: #409eff;" v-if="orderDetail.userId && getAppUsersPhone(orderDetail.userId)">
{{ getAppUsersPhone(orderDetail.userId) }}
</span>
<span style="color: #f00;" v-else-if="orderDetail.userId">伴宠师已离职/已不是伴宠师</span>
</el-descriptions-item>
</el-descriptions>
</el-card>
<el-card class="mt10">
<div slot="header" class="clearfix">
<span style="font-size: 16px;font-weight: bold">服务项目及费用</span>
</div>
<div class="service-items">
<div v-for="(item, index) in serviceItems" :key="index" class="service-item">
<div class="service-item-header">
<div class="service-date">{{ item.day }}</div>
<div class="service-name">{{ item.itemsText.join('、') }}</div>
<div class="service-price">¥{{ item.price.toFixed(2) }}</div>
</div>
<div class="service-pets" v-if="item.pets && item.pets.length">
<div v-for="(pet, petIndex) in item.pets" :key="petIndex" class="pet-info">
<div class="pet-header">
<el-avatar :size="40" :src="pet.photo" icon="el-icon-user-solid"></el-avatar>
<span class="pet-name">{{ pet.name }}</span>
</div>
<div class="pet-services">
<div v-for="(service, serviceIndex) in pet.itemList" :key="serviceIndex"
class="service-detail">
<span class="service-detail-name">{{ service.productName }}</span>
<span class="service-detail-price">¥{{ service.salePrice.toFixed(2) }} × {{
service.quantity }}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</el-card>
<el-card class="mt10" v-if="dateFrequencyList.length > 0">
<div slot="header" style="font-size: 16px;font-weight: bold;">日订单列表</div>
<el-table :data="dateFrequencyList" v-loading="tableLoading" style="width: 100%">
<el-table-column label="服务日期" align="center" prop="serviceDate" />
<el-table-column label="接单伴宠师" align="center" prop="masterId">
<template slot-scope="scope">
<div style="display: flex; align-items: center; justify-content: center;">
<div style="margin-right: 10px;">
<el-avatar :size="40" :src="scope.row.master.userImage" icon="el-icon-user-solid"
style="background-color: #409EFF;">
</el-avatar>
</div>
<div style="display: flex; flex-direction: column; align-items: flex-start;">
<div style="font-weight: bold; margin-bottom: 2px;">
{{ scope.row.master.userName || '未分配' }}
</div>
<div style="font-size: 12px; color: #999;">
ID: {{ scope.row.masterId || '--' }}
</div>
</div>
</div>
</template>
</el-table-column>
<el-table-column label="宠物" align="center" prop="status">
<template slot-scope="scope">
<div style="display: flex; align-items: center; justify-content: center;"
v-for="(pet, index) in scope.row.pets" :key="index">
<div style="margin-right: 10px;">
<el-avatar :size="40" :src="pet.photo" icon="el-icon-user-solid"
style="background-color: #409EFF;">
</el-avatar>
</div>
<div style="display: flex; flex-direction: column; align-items: flex-start;">
<div style="margin-bottom: 2px;">
{{ pet.name }} | {{ pet.breed }} | {{ pet.bodyType }}
</div>
<div style="font-size: 12px; color: #999;">
{{pet.orderItemList.map(n => n.productName).join(',')}}
</div>
</div>
</div>
</template>
</el-table-column>
<el-table-column label="完成状态" align="center" prop="status">
<template slot-scope="scope">
<dict-tag :options="dict.type.order_check_status" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column label="完成时间" align="center" prop="completionTime" />
<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-full-screen"
@click="handleCheckin(scope.row)">打卡信息</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
</el-main>
<!-- 打卡弹窗 -->
<checkin-dialog v-model="checkinDialogVisible" :order-data="currentOrderData">
</checkin-dialog>
</div>
</template>
<script>
import { getAppletOrder, getAppletOrderDetail } from "@/api/model/AppletOrder";
import { listAppletOrderDateFrequency } from "@/api/model/appletOrderDateFrequency";
import { listAppUsers } from "@/api/model/AppUsers";
import CheckinDialog from "@/components/CheckinDialog.vue";
import dayjs from "dayjs";
export default {
name: "AppletOrderDetail",
dicts: ['applet_order_status', 'applet_order_type', 'order_check_status'],
components: {
CheckinDialog
},
data() {
return {
loading: false,
tableLoading: false,
orderDetail: {},
dateFrequencyList: [],
appUsersList: [],
active: 1,
checkinDialogVisible: false,
currentOrderData: {},
id: null,
serviceItems: [],
}
},
created() {
this.id = this.$route.query.id;
this.getDetail(this.id);
this.listAppUsers();
},
methods: {
getDetail() {
this.loading = true;
getAppletOrder(this.id).then(res => {
this.orderDetail = res.data;
this.getDateFrequencyList();
this.getOmsOrder();
if (this.orderDetail.status <= 3) {
this.active = this.orderDetail.status + 1;
} else {
this.active = 1;
}
this.loading = false;
});
},
getOmsOrder() {
getAppletOrderDetail(this.orderDetail.orderId).then(res => {
//==========================================
let data = res.data;
let items = []
//1
let days = [...new Set(data.orderServiceList.map(item => item.serviceDate))]
days.forEach(day => {
let price = 0;
let itemsText = []
//2
let dayItems = data.orderServiceList.filter(item => item.serviceDate === day)
//3
let pets = data.petVOList.filter(item => dayItems.some(dayItem => dayItem.petId === item.id))
//pets
pets = JSON.parse(JSON.stringify(pets))
//4
pets.forEach(pet => {
pet.serviceList = dayItems.filter(item => item.petId === pet.id)
let itemList = []
//5
pet.serviceList.forEach(item => {
itemList.push(...(data.orderItemList.filter(n => n.orderServiceId == item.id)))
})
//
itemList = itemList.reverse();
itemList.forEach(p => {
price += p.salePrice * p.quantity
itemsText = [...new Set([...itemsText, p.productName])]
})
pet.itemList = itemList
})
//6items
items.push({
price,
pets,
day,
itemsText,
})
})
//
items = items.sort((a, b) => dayjs(a.day).valueOf() - dayjs(b.day).valueOf())
items.forEach(n => {
n.day = dayjs(n.day).format('MM-DD')
})
console.log(items);
this.serviceItems = items;
//==========================================
});
},
getDateFrequencyList() {
this.tableLoading = true;
listAppletOrderDateFrequency({
orderId: this.orderDetail.orderId
}).then(response => {
this.dateFrequencyList = response.rows;
this.tableLoading = false;
});
},
listAppUsers() {
listAppUsers({
pageNum: 1,
pageSize: 99999999,
userBcs: 1,
}).then(response => {
this.appUsersList = response.rows;
});
},
getAppUsersPhone(userId) {
let data = this.appUsersList.find(item => item.userId == userId);
if (data) {
return data.userTelephone;
} else {
return '';
}
},
handleCheckin(row) {
this.currentOrderData = row;
this.checkinDialogVisible = true;
}
}
}
</script>
<style lang="scss" scoped>
.order_detail_wrapper {
>.el-card+.el-card {
margin-top: 1rem;
}
.el-form-item {
margin-bottom: 0;
.el-form-item__content,
.el-form-item__label {
line-height: 2;
}
}
}
.my-label {
width: 100px;
}
.my-content {
width: 400px;
}
.service-items {
padding: 0 20px;
display: flex;
flex-wrap: wrap;
gap: 20px;
.service-item {
padding: 20px;
min-width: 280px;
width: 30%;
background-color: #f9f9f9;
border-radius: 10px;
box-sizing: border-box;
&:last-child {
border-bottom: none;
}
.service-item-header {
display: flex;
align-items: center;
margin-bottom: 15px;
.service-date {
font-size: 16px;
color: #000;
margin-right: 10px;
min-width: 100px;
font-weight: 900;
}
.service-name {
flex: 1;
font-size: 14px;
color: #303133;
margin: 0 20px;
}
.service-price {
font-size: 16px;
font-weight: bold;
color: #303133;
min-width: 100px;
text-align: right;
}
}
.service-pets {
padding: 15px;
background-color: #F5F7FA;
border-radius: 4px;
.pet-info {
margin-bottom: 15px;
&:last-child {
margin-bottom: 0;
}
.pet-header {
display: flex;
align-items: center;
margin-bottom: 10px;
.pet-name {
margin-left: 10px;
font-size: 14px;
font-weight: bold;
color: #303133;
}
}
.pet-services {
padding-left: 50px;
.service-detail {
display: flex;
justify-content: space-between;
margin-bottom: 8px;
padding: 8px 0;
border-bottom: 1px dashed #E4E7ED;
&:last-child {
margin-bottom: 0;
border-bottom: none;
}
.service-detail-name {
font-size: 13px;
color: #606266;
}
.service-detail-price {
font-size: 13px;
color: #909399;
}
}
}
}
}
}
}
</style>

+ 1
- 0
ruoyi-catdog/src/main/java/com/ruoyi/applet/service/impl/IMallOrderServiceImpl.java View File

@ -94,6 +94,7 @@ public class IMallOrderServiceImpl implements IMallOrderService {
appletOrder.setType("1"); //指定人接单
//appletUserId 用json形式储存
appletOrder.setUserIdJson(""+appletUserId);
appletOrder.setStartUserIdJson(""+appletUserId);
appletOrder.setOrderTime(3); //设置为三分钟
appletOrder.setNum(1);
appletOrder.setStatus(0); //派单中


+ 4
- 0
ruoyi-catdog/src/main/java/com/ruoyi/model/domain/AppletOrder.java View File

@ -89,6 +89,10 @@ public class AppletOrder {
@Excel(name = "派单给的用户集合")
private String userIdJson;
/** 开始派单给的用户集合 多个用,隔开 */
@Excel(name = "开始派单给的用户集合")
private String startUserIdJson;
/** 关联宠物ID */
@Excel(name = "关联宠物ID")
private Integer petId;


+ 3
- 1
ruoyi-catdog/src/main/java/com/ruoyi/model/mapper/AppletConfigMapper.java View File

@ -1,6 +1,8 @@
package com.ruoyi.model.mapper;
import java.util.List;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.model.domain.AppletConfig;
import org.apache.ibatis.annotations.Param;
@ -10,7 +12,7 @@ import org.apache.ibatis.annotations.Param;
* @author ruoyi
* @date 2025-03-28
*/
public interface AppletConfigMapper
public interface AppletConfigMapper extends BaseMapper<AppletConfig>
{
/**
* 查询配置信息


+ 3
- 0
ruoyi-catdog/src/main/java/com/ruoyi/model/service/IAppletConfigService.java View File

@ -58,4 +58,7 @@ public interface IAppletConfigService
* @return 结果
*/
public int deleteAppletConfigById(Long id);
AppletConfig getByCode(String code);
}

+ 16
- 0
ruoyi-catdog/src/main/java/com/ruoyi/model/service/impl/AppletConfigServiceImpl.java View File

@ -1,6 +1,9 @@
package com.ruoyi.model.service.impl;
import java.util.List;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -99,4 +102,17 @@ public class AppletConfigServiceImpl implements IAppletConfigService
{
return appletConfigMapper.deleteAppletConfigById(id);
}
@Override
public AppletConfig getByCode(String code) {
List<AppletConfig> appletConfigs = appletConfigMapper.selectList(Wrappers.<AppletConfig>lambdaQuery()
.eq(AppletConfig::getParamCode, code));
if (appletConfigs.size() > 0){
return appletConfigs.get(0);
}else {
throw new ServiceException("配置缺失=" + code);
}
}
}

+ 37
- 5
ruoyi-catdog/src/main/java/com/ruoyi/model/service/impl/AppletOrderServiceImpl.java View File

@ -12,16 +12,14 @@ import com.ruoyi.applet.pojo.dto.filterQualifiedUsersVo;
import com.ruoyi.common.core.sms.AliyunSmsUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.model.domain.AppUsers;
import com.ruoyi.model.domain.AppletAddress;
import com.ruoyi.model.domain.AppletOutDate;
import com.ruoyi.model.domain.*;
import com.ruoyi.model.mapper.AppUsersMapper;
import com.ruoyi.model.service.IAppUsersService;
import com.ruoyi.model.service.IAppletConfigService;
import com.ruoyi.model.service.IAppletOutDateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.model.mapper.AppletOrderMapper;
import com.ruoyi.model.domain.AppletOrder;
import com.ruoyi.model.service.IAppletOrderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -41,6 +39,9 @@ public class AppletOrderServiceImpl extends ServiceImpl<AppletOrderMapper, Apple
@Autowired
private IAppUsersService appUsersService;
@Autowired
private IAppletConfigService appletConfigService;
private static final Logger log = LoggerFactory.getLogger(AppletOrderServiceImpl.class);
/**
@ -89,6 +90,7 @@ public class AppletOrderServiceImpl extends ServiceImpl<AppletOrderMapper, Apple
{
// appletOrder.setCreateTime(new Date());
appletOrder.setNoticeSystemFlag(0);
appletOrder.setNum(1);
int i = appletOrderMapper.insert(appletOrder);
noticePersonalByOrderIds(Collections.singletonList(appletOrder.getId()));
return i;
@ -105,8 +107,13 @@ public class AppletOrderServiceImpl extends ServiceImpl<AppletOrderMapper, Apple
{
// appletOrder.setUpdateTime(DateUtils.getNowDate());
AppletOrder one = lambdaQuery()
.eq(AppletOrder::getId, appletOrder.getId())
.one();
appletOrder.setNewOrderTime(LocalDateTime.now());
appletOrder.setNoticeSystemFlag(0);
appletOrder.setNum(one.getNum() == null ? 2 : one.getNum() + 1);
noticePersonalByOrderIds(Collections.singletonList(appletOrder.getId()));
@ -187,6 +194,7 @@ public class AppletOrderServiceImpl extends ServiceImpl<AppletOrderMapper, Apple
.set(AppletOrder::getUpdateTime, LocalDateTime.now())
.set(AppletOrder::getNoticeSystemFlag, 0)
.set(AppletOrder::getNewOrderTime, LocalDateTime.now())
.setSql("num = num + 1")
.update();
}
@ -254,9 +262,33 @@ public class AppletOrderServiceImpl extends ServiceImpl<AppletOrderMapper, Apple
.list();
if(timeoutOrders.size() > 0){
List<Long> idList = timeoutOrders.stream().map(n -> n.getId()).collect(Collectors.toList());
AppletConfig appletConfig = appletConfigService.getByCode("admin_phone_list");
String adminPhoneList = appletConfig.getParamValueText();
if (StringUtils.isNotEmpty(adminPhoneList)){
String orderId = "";
for (AppletOrder aLong : timeoutOrders) {
orderId += aLong.getOrderId();
}
if (orderId.length() > 30){
orderId = orderId.substring(28) + "...";
}
for (String phone : adminPhoneList.split(",")) {
AliyunSmsUtils.sendLongTimeNoOrderAccepted(phone, orderId);
}
}
//180分钟未接单修改订单状态
lambdaUpdate()
.in(AppletOrder::getId, timeoutOrders.stream().map(n -> n.getId()).collect(Collectors.toList()))
.in(AppletOrder::getId, idList)
.set(AppletOrder::getUpdateTime, LocalDateTime.now())
.set(AppletOrder::getNoticeSystemFlag, -1)//通知过管理员了
.update();


+ 1
- 1
ruoyi-catdog/src/main/resources/mapper/model/AppletConfigMapper.xml View File

@ -28,7 +28,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="selectAppletConfigList" parameterType="AppletConfig" resultMap="AppletConfigResult">
<include refid="selectAppletConfigVo"/>
<where>
<if test="paramValue != null and paramValue != ''"> and param_value = #{paramValue}</if>
<if test="paramValue != null and paramValue != ''"> and param_value like concat('%', #{paramValue}, '%')</if>
<if test="paramCode != null and paramCode != ''"> and param_code = #{paramCode}</if>
<if test="paramValueText != null and paramValueText != ''"> and param_value_text = #{paramValueText}</if>
<if test="paramValueImage != null and paramValueImage != ''"> and param_value_image = #{paramValueImage}</if>


+ 7
- 3
ruoyi-catdog/src/main/resources/mapper/model/AppletOrderMapper.xml View File

@ -28,12 +28,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="acceptTime" column="accept_time"/>
<result property="whenTakOrders" column="when_tak_orders"/>
<result property="noticeSystemFlag" column="notice_system_flag"/>
<result property="startUserIdJson" column="start_user_id_json"/>
</resultMap>
<sql id="selectAppletOrderVo">
select id, create_time, create_by, update_time, update_by, pay_time, status, price, address, type, reason, user_id,
pet_id,num,user_id_json,order_id,order_sn,order_time,companion_level,
longitude, latitude, create_type, new_order_time, accept_time, when_tak_orders,
longitude, latitude, create_type, new_order_time, accept_time, when_tak_orders, start_user_id_json
notice_system_flag
from applet_order
</sql>
@ -127,7 +128,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="newOrderTime != null">new_order_time,</if>
<if test="acceptTime != null">accept_time,</if>
<if test="whenTakOrders != null">when_tak_orders,</if>
<if test="whenTakOrders != null">notice_system_flag,</if>
<if test="noticeSystemFlag != null">notice_system_flag,</if>
<if test="startUserIdJson != null">start_user_id_json,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
@ -156,7 +158,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="newOrderTime != null">#{newOrderTime},</if>
<if test="acceptTime != null">#{acceptTime},</if>
<if test="whenTakOrders != null">#{whenTakOrders},</if>
<if test="whenTakOrders != null">#{noticeSystemFlag},</if>
<if test="noticeSystemFlag != null">#{noticeSystemFlag},</if>
<if test="startUserIdJson != null">#{start_user_id_json},</if>
</trim>
@ -191,6 +194,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="acceptTime != null"> accept_time = #{acceptTime},</if>
<if test="whenTakOrders != null"> when_tak_orders = #{whenTakOrders},</if>
<if test="noticeSystemFlag != null"> notice_system_flag = #{noticeSystemFlag},</if>
<if test="startUserIdJson != null"> start_user_id_json = #{startUserIdJson},</if>
</trim>
where id = #{id}
</update>


Loading…
Cancel
Save