|
@@ -26,10 +26,11 @@
|
|
|
<el-tab-pane label="全部订单" name="" />
|
|
<el-tab-pane label="全部订单" name="" />
|
|
|
<el-tab-pane label="待派单" name="0" />
|
|
<el-tab-pane label="待派单" name="0" />
|
|
|
<el-tab-pane label="待接单" name="1" />
|
|
<el-tab-pane label="待接单" name="1" />
|
|
|
- <el-tab-pane label="服务中" name="2" />
|
|
|
|
|
- <el-tab-pane label="待商家确认" name="3" />
|
|
|
|
|
- <el-tab-pane label="已完成" name="4" />
|
|
|
|
|
- <el-tab-pane label="已取消" name="5" />
|
|
|
|
|
|
|
+ <el-tab-pane label="待服务" name="2" />
|
|
|
|
|
+ <el-tab-pane label="服务中" name="3" />
|
|
|
|
|
+ <el-tab-pane label="待商家确认" name="4" />
|
|
|
|
|
+ <el-tab-pane label="已完成" name="5" />
|
|
|
|
|
+ <el-tab-pane label="已取消" name="6" />
|
|
|
</el-tabs>
|
|
</el-tabs>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
@@ -119,11 +120,11 @@
|
|
|
<template #default="{ row }">
|
|
<template #default="{ row }">
|
|
|
<div class="op-cell">
|
|
<div class="op-cell">
|
|
|
<el-button link type="primary" size="small" @click="handleDetail(row)">详情</el-button>
|
|
<el-button link type="primary" size="small" @click="handleDetail(row)">详情</el-button>
|
|
|
- <el-button v-if="row.status === 0" link type="success" size="small" @click="openDispatchDialog(row)">派单</el-button>
|
|
|
|
|
- <el-button v-if="[1, 2].includes(row.status)" link type="warning" size="small" @click="openDispatchDialog(row)">重新派单</el-button>
|
|
|
|
|
|
|
+<!-- <el-button v-if="row.status === 0" link type="success" size="small" @click="openDispatchDialog(row)">派单</el-button>-->
|
|
|
|
|
+<!-- <el-button v-if="[1, 2, 3].includes(row.status)" link type="warning" size="small" @click="openDispatchDialog(row)">重新派单</el-button>-->
|
|
|
<el-button v-if="[0, 1].includes(row.status)" link type="danger" size="small" @click="handleCancel(row)">取消</el-button>
|
|
<el-button v-if="[0, 1].includes(row.status)" link type="danger" size="small" @click="handleCancel(row)">取消</el-button>
|
|
|
|
|
|
|
|
- <el-dropdown v-if="[2, 3, 4].includes(row.status)" trigger="click" @command="(cmd) => handleCommand(cmd, row)">
|
|
|
|
|
|
|
+ <el-dropdown v-if="[3, 4, 5].includes(row.status)" trigger="click" @command="(cmd) => handleCommand(cmd, row)">
|
|
|
<span class="el-dropdown-link">
|
|
<span class="el-dropdown-link">
|
|
|
更多<el-icon class="el-icon--right">
|
|
更多<el-icon class="el-icon--right">
|
|
|
<ArrowDown />
|
|
<ArrowDown />
|
|
@@ -131,8 +132,8 @@
|
|
|
</span>
|
|
</span>
|
|
|
<template #dropdown>
|
|
<template #dropdown>
|
|
|
<el-dropdown-menu>
|
|
<el-dropdown-menu>
|
|
|
- <el-dropdown-item v-if="row.status === 3" command="complete">确认完成</el-dropdown-item>
|
|
|
|
|
- <el-dropdown-item v-if="[3, 4].includes(row.status)" command="care_summary">护理小结</el-dropdown-item>
|
|
|
|
|
|
|
+ <el-dropdown-item v-if="row.status === 4" command="complete">确认完成</el-dropdown-item>
|
|
|
|
|
+ <el-dropdown-item v-if="[4, 5].includes(row.status)" command="care_summary">护理小结</el-dropdown-item>
|
|
|
<el-dropdown-item command="reward">奖惩</el-dropdown-item>
|
|
<el-dropdown-item command="reward">奖惩</el-dropdown-item>
|
|
|
<el-dropdown-item command="remark">备注</el-dropdown-item>
|
|
<el-dropdown-item command="remark">备注</el-dropdown-item>
|
|
|
</el-dropdown-menu>
|
|
</el-dropdown-menu>
|
|
@@ -177,7 +178,7 @@
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
|
-import { ref, reactive, onMounted, nextTick } from 'vue';
|
|
|
|
|
|
|
+import { ref, reactive, onMounted, nextTick, getCurrentInstance, toRefs } from 'vue';
|
|
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
|
|
import OrderDetailDrawer from './components/OrderDetailDrawer.vue';
|
|
import OrderDetailDrawer from './components/OrderDetailDrawer.vue';
|
|
|
import DispatchDialog from './components/DispatchDialog.vue';
|
|
import DispatchDialog from './components/DispatchDialog.vue';
|
|
@@ -185,10 +186,17 @@ import CareSummaryDrawer from './components/CareSummaryDrawer.vue';
|
|
|
import RewardDialog from './components/RewardDialog.vue';
|
|
import RewardDialog from './components/RewardDialog.vue';
|
|
|
import RemarkDialog from './components/RemarkDialog.vue';
|
|
import RemarkDialog from './components/RemarkDialog.vue';
|
|
|
import { listOnStore as listServiceOnStore } from '@/api/service/list/index';
|
|
import { listOnStore as listServiceOnStore } from '@/api/service/list/index';
|
|
|
-import { listSubOrder, dispatchSubOrder, getSubOrderInfo, cancelSubOrder, remarkSubOrder } from '@/api/order/subOrder/index';
|
|
|
|
|
|
|
+import { listSubOrder, dispatchSubOrder, getSubOrderInfo, cancelSubOrder, remarkSubOrder, confirmSubOrder, nursingSummarySubOrder } from '@/api/order/subOrder/index';
|
|
|
import { listOnStore as listAreaStationOnStore } from '@/api/system/areaStation';
|
|
import { listOnStore as listAreaStationOnStore } from '@/api/system/areaStation';
|
|
|
import { getStore } from '@/api/system/store';
|
|
import { getStore } from '@/api/system/store';
|
|
|
import { reward } from '@/api/fulfiller/pool';
|
|
import { reward } from '@/api/fulfiller/pool';
|
|
|
|
|
+import { getPet } from '@/api/archieves/pet';
|
|
|
|
|
+import { getCustomer } from '@/api/archieves/customer';
|
|
|
|
|
+
|
|
|
|
|
+const { proxy } = getCurrentInstance();
|
|
|
|
|
+const { sys_house_type, sys_entry_method } = toRefs(
|
|
|
|
|
+ proxy?.useDict('sys_house_type', 'sys_entry_method')
|
|
|
|
|
+);
|
|
|
|
|
|
|
|
const loading = ref(false);
|
|
const loading = ref(false);
|
|
|
|
|
|
|
@@ -333,12 +341,28 @@ const getServiceOrderTypeTag = (row) => {
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const getStatusName = (status) => {
|
|
const getStatusName = (status) => {
|
|
|
- const map = { 0: '待派单', 1: '待接单', 2: '服务中', 3: '待商家确认', 4: '已完成', 5: '已取消' };
|
|
|
|
|
|
|
+ const map = {
|
|
|
|
|
+ 0: '待派单',
|
|
|
|
|
+ 1: '待接单',
|
|
|
|
|
+ 2: '待服务',
|
|
|
|
|
+ 3: '服务中',
|
|
|
|
|
+ 4: '待商家确认',
|
|
|
|
|
+ 5: '已完成',
|
|
|
|
|
+ 6: '已取消'
|
|
|
|
|
+ };
|
|
|
return map[status] || '未知';
|
|
return map[status] || '未知';
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const getStatusClass = (status) => {
|
|
const getStatusClass = (status) => {
|
|
|
- const map = { 0: 'pending_dispatch', 1: 'pending_accept', 2: 'serving', 3: 'pending_confirm', 4: 'completed', 5: 'cancelled' };
|
|
|
|
|
|
|
+ const map = {
|
|
|
|
|
+ 0: 'pending_dispatch',
|
|
|
|
|
+ 1: 'pending_accept',
|
|
|
|
|
+ 2: 'pending_service',
|
|
|
|
|
+ 3: 'in_service',
|
|
|
|
|
+ 4: 'pending_confirm',
|
|
|
|
|
+ 5: 'completed',
|
|
|
|
|
+ 6: 'cancelled'
|
|
|
|
|
+ };
|
|
|
return map[status] || 'pending_dispatch';
|
|
return map[status] || 'pending_dispatch';
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -539,30 +563,78 @@ const handleDispatchSubmit = (payload) => {
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
// 护理小结
|
|
// 护理小结
|
|
|
-const openCareSummary = (row) => {
|
|
|
|
|
- careSummaryOrder.value = {
|
|
|
|
|
|
|
+const openCareSummary = async (row) => {
|
|
|
|
|
+ const orderData = {
|
|
|
...row,
|
|
...row,
|
|
|
- petAge: '3岁',
|
|
|
|
|
- petGender: 'male',
|
|
|
|
|
- petTags: ['易过敏', '胆小'],
|
|
|
|
|
- petWeight: '30 kg',
|
|
|
|
|
- petPersonality: '活泼,超级粘人,喜欢玩球',
|
|
|
|
|
- homeTime: '2023-01-01',
|
|
|
|
|
- houseType: '电梯',
|
|
|
|
|
- entryMethod: '密码开门',
|
|
|
|
|
- entryDetail: '密码: 123456 (仅限服务期间使用)',
|
|
|
|
|
- healthStatus: '健康',
|
|
|
|
|
- vaccineImg: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg',
|
|
|
|
|
- allergy: '海鲜'
|
|
|
|
|
|
|
+ careSummary: row.nursingSummary || undefined
|
|
|
};
|
|
};
|
|
|
|
|
+
|
|
|
|
|
+ // 获取宠物信息
|
|
|
|
|
+ const petId = row?.pet || row?.petId;
|
|
|
|
|
+ if (petId) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const petRes = await getPet(petId);
|
|
|
|
|
+ const pet = petRes?.data;
|
|
|
|
|
+ if (pet) {
|
|
|
|
|
+ orderData.petAge = pet.age ? `${pet.age}岁` : '未知';
|
|
|
|
|
+ orderData.petGender = pet.gender || 'male';
|
|
|
|
|
+ orderData.petTags = pet.tags || [];
|
|
|
|
|
+ orderData.petWeight = pet.weight ? `${pet.weight} kg` : '未知';
|
|
|
|
|
+ orderData.petPersonality = pet.personality || '未知';
|
|
|
|
|
+ orderData.healthStatus = pet.healthStatus || '未知';
|
|
|
|
|
+ orderData.vaccineImg = pet.vaccineImg || '';
|
|
|
|
|
+ orderData.allergy = pet.allergy || '无';
|
|
|
|
|
+ orderData.petBreed = pet.breed || '未知';
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch { }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取客户信息(宠物主人)
|
|
|
|
|
+ const customerId = row?.customer || row?.customerId;
|
|
|
|
|
+ if (customerId) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const customerRes = await getCustomer(customerId);
|
|
|
|
|
+ const customer = customerRes?.data;
|
|
|
|
|
+ if (customer) {
|
|
|
|
|
+ orderData.userName = customer.name || orderData.userName;
|
|
|
|
|
+ orderData.homeTime = customer.homeTime || '未知';
|
|
|
|
|
+
|
|
|
|
|
+ const houseTypeDict = sys_house_type.value?.find(d => d.value === customer.houseType);
|
|
|
|
|
+ orderData.houseType = houseTypeDict?.label || customer.houseType || '未知';
|
|
|
|
|
+
|
|
|
|
|
+ const entryMethodDict = sys_entry_method.value?.find(d => d.value === customer.entryMethod);
|
|
|
|
|
+ orderData.entryMethod = entryMethodDict?.label || customer.entryMethod || '未知';
|
|
|
|
|
+
|
|
|
|
|
+ orderData.entryDetail = customer.entryMethod === 'password'
|
|
|
|
|
+ ? (customer.entryPassword ? `密码: ${customer.entryPassword}` : '未设置密码')
|
|
|
|
|
+ : (customer.keyLocation || '未设置');
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch { }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ orderData.summaryTime = row.nursingSummaryTime || orderData.summaryTime;
|
|
|
|
|
+ careSummaryOrder.value = orderData;
|
|
|
careSummaryVisible.value = true;
|
|
careSummaryVisible.value = true;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-const saveCareSummary = (text) => {
|
|
|
|
|
- if (careSummaryOrder.value) {
|
|
|
|
|
- careSummaryOrder.value.careSummary = text;
|
|
|
|
|
|
|
+const saveCareSummary = async (text) => {
|
|
|
|
|
+ if (!careSummaryOrder.value?.id) {
|
|
|
|
|
+ ElMessage.warning('订单信息不存在');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ await nursingSummarySubOrder({
|
|
|
|
|
+ orderId: careSummaryOrder.value.id,
|
|
|
|
|
+ content: text
|
|
|
|
|
+ });
|
|
|
|
|
+ if (careSummaryOrder.value) {
|
|
|
|
|
+ careSummaryOrder.value.careSummary = text;
|
|
|
|
|
+ careSummaryOrder.value.nursingSummary = text;
|
|
|
|
|
+ }
|
|
|
ElMessage.success('护理小结已保存');
|
|
ElMessage.success('护理小结已保存');
|
|
|
handleSearch();
|
|
handleSearch();
|
|
|
|
|
+ } catch {
|
|
|
|
|
+ // Error handled by interceptor
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -642,9 +714,15 @@ const handleCommand = (cmd, row) => {
|
|
|
if (cmd === 'remark') openRemarkDialog(row);
|
|
if (cmd === 'remark') openRemarkDialog(row);
|
|
|
if (cmd === 'care_summary') openCareSummary(row);
|
|
if (cmd === 'care_summary') openCareSummary(row);
|
|
|
if (cmd === 'complete') {
|
|
if (cmd === 'complete') {
|
|
|
- ElMessageBox.confirm('确认将该订单手动标记为完成吗?', '提示', { type: 'warning' }).then(() => {
|
|
|
|
|
- row.status = 4;
|
|
|
|
|
- ElMessage.success('订单已标记完成');
|
|
|
|
|
|
|
+ ElMessageBox.confirm('确认将该订单手动标记为完成吗?', '提示', { type: 'warning' }).then(async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ await confirmSubOrder({ id: row.id });
|
|
|
|
|
+ row.status = 5;
|
|
|
|
|
+ ElMessage.success('订单已标记完成');
|
|
|
|
|
+ handleSearch();
|
|
|
|
|
+ } catch {
|
|
|
|
|
+ // Error handled by interceptor
|
|
|
|
|
+ }
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
if (cmd === 'delete') {
|
|
if (cmd === 'delete') {
|
|
@@ -791,8 +869,12 @@ const handleCommand = (cmd, row) => {
|
|
|
background-color: #e6a23c;
|
|
background-color: #e6a23c;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.status-dot.serving {
|
|
|
|
|
- background-color: #409eff;
|
|
|
|
|
|
|
+.status-dot.pending_service {
|
|
|
|
|
+ background-color: #49a3ff;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.status-dot.in_service {
|
|
|
|
|
+ background-color: #49a3ff;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.status-dot.pending_confirm {
|
|
.status-dot.pending_confirm {
|