7-1 修复数据实时更新功能

This commit is contained in:
wsb1224 2026-07-01 10:05:30 +08:00
parent ec9f710572
commit e779f31493
8 changed files with 124 additions and 64 deletions

View File

@ -275,6 +275,13 @@ Page({
: "/api/orders/" + orderInfo.order_id + "/approve";
if (result === "pass") {
// 非自发订单审批通过时,工厂为必选,司机为可选
if (!isCancelFlow && orderInfo.order_status === "pending_approve" && !orderInfo.tracking_number) {
if (!that.data.selectedFactoryId) {
wx.showToast({ title: "请选择工厂", icon: "none" });
return;
}
}
// 通过:直接确认
var confirmMsg = isCancelFlow ? "确认同意取消此订单?" : "确认审批通过?";
wx.showModal({
@ -284,11 +291,9 @@ Page({
success: function (res) {
if (!res.confirm) return;
var payload = { approve_result: result, approve_opinion: "同意" };
// 如果是待审批状态且未自发附加工厂ID和司机ID
// 如果是待审批状态且未自发附加工厂ID,司机可选
if (!isCancelFlow && orderInfo.order_status === "pending_approve" && !orderInfo.tracking_number) {
if (that.data.selectedFactoryId) {
payload.factory_id = that.data.selectedFactoryId;
}
payload.factory_id = that.data.selectedFactoryId;
if (that.data.selectedDriverId) {
payload.driver_id = that.data.selectedDriverId;
}
@ -323,29 +328,34 @@ Page({
app.request({
url: targetUrl, method: "POST",
data: payload,
}).then(function () {
// 物流任务由后端审批接口统一创建,前端不再重复创建
}).then(function () {
if (payload.approve_result === "pass") {
// 从原始数据直接构建采购信息,避免 this.data 时序问题
var orderData = that.data.orderInfo;
var text = "";
if (orderData) {
var lines = [];
var isPickup = orderData.delivery_type === "自提";
// 非自提:复制收货信息
if (!isPickup) {
var contactParts = [orderData.customer_name, orderData.customer_mobile, orderData.customer_address].filter(function(v) { return v; });
if (contactParts.length) lines.push("收货信息:" + contactParts.join(" "));
}
// 客户需求
if (orderData.customer_demand) lines.push("客户需求: " + orderData.customer_demand);
text = lines.join("\n");
}
if (text) {
wx.setClipboardData({ data: text });
// 区分是否分配了司机factory_id 存在说明是非自发订单审批)
if (payload.factory_id && payload.driver_id) {
wx.showToast({ title: "审批通过,已下发工厂并分配司机", icon: "success" });
} else if (payload.factory_id) {
wx.showToast({ title: "审批通过,已下发工厂,待后续分配司机", icon: "success" });
} else {
wx.showToast({ title: "审批通过", icon: "success" });
// 自发订单或取消审批:复制采购信息
var orderData = that.data.orderInfo;
var text = "";
if (orderData) {
var lines = [];
var isPickup = orderData.delivery_type === "自提";
// 非自提:复制收货信息
if (!isPickup) {
var contactParts = [orderData.customer_name, orderData.customer_mobile, orderData.customer_address].filter(function(v) { return v; });
if (contactParts.length) lines.push("收货信息:" + contactParts.join(" "));
}
// 客户需求
if (orderData.customer_demand) lines.push("客户需求: " + orderData.customer_demand);
text = lines.join("\n");
}
if (text) {
wx.setClipboardData({ data: text });
} else {
wx.showToast({ title: "审批通过", icon: "success" });
}
}
} else {
wx.showToast({ title: "已退回", icon: "success" });
@ -417,10 +427,6 @@ Page({
wx.showToast({ title: "请选择工厂", icon: "none" });
return;
}
if (!that.data.selectedDriverId) {
wx.showToast({ title: "请选择司机", icon: "none" });
return;
}
that.setData({ actionLoading: true, message: "" });
app.request({
@ -428,21 +434,28 @@ Page({
method: "POST",
data: { target_status: "pending_factory", factory_id: that.data.selectedFactoryId },
}).then(function () {
return app.request({
url: "/api/logistics/tasks",
method: "POST",
data: {
order_id: orderInfo.order_id,
driver_id: Number(that.data.selectedDriverId),
pickup_address: orderInfo.factory_name || "",
delivery_address: orderInfo.customer_address || "",
pickup_content: orderInfo.customer_name ? orderInfo.customer_name + " 订单货物" : "",
quantity: 1,
factory_id: that.data.selectedFactoryId,
},
});
// 选了司机时一并创建物流任务,否则仅推进状态
if (that.data.selectedDriverId) {
return app.request({
url: "/api/logistics/tasks",
method: "POST",
data: {
order_id: orderInfo.order_id,
driver_id: Number(that.data.selectedDriverId),
pickup_address: orderInfo.factory_name || "",
delivery_address: orderInfo.customer_address || "",
pickup_content: orderInfo.customer_name ? orderInfo.customer_name + " 订单货物" : "",
quantity: 1,
factory_id: that.data.selectedFactoryId,
},
});
}
}).then(function () {
wx.showToast({ title: "已推进待工厂并分配司机", icon: "success" });
if (that.data.selectedDriverId) {
wx.showToast({ title: "已推进待工厂并分配司机", icon: "success" });
} else {
wx.showToast({ title: "已推进待工厂,待后续分配司机", icon: "success" });
}
return that.loadDetail();
}).catch(function (error) {
that.setData({ message: error.message || "操作失败" });

View File

@ -179,11 +179,11 @@
<text class="picker-arrow">▶</text>
</view>
</picker>
<view class="section-title" style="margin-top: 20rpx;">分配司机</view>
<view class="section-title" style="margin-top: 20rpx;">分配司机(可选)</view>
<view wx:if="{{!driverList.length}}" class="empty-hint">暂无可用司机</view>
<picker wx:else mode="selector" range="{{driverList}}" range-key="real_name" value="{{selectedDriverIndex}}" bindchange="onDriverChange">
<view class="picker-value">
{{selectedDriverIndex >= 0 ? driverList[selectedDriverIndex].real_name : '请选择司机'}}
{{selectedDriverIndex >= 0 ? driverList[selectedDriverIndex].real_name : '暂不分配,后续补选'}}
<text class="picker-arrow">▶</text>
</view>
</picker>

View File

@ -40,6 +40,11 @@ function connect() {
socketTask.onOpen(function () {
console.log("[WS] 连接成功");
isConnecting = false;
// 如果是重连成功,触发提醒事件让页面刷新数据
if (reconnectCount > 0) {
console.log("[WS] 重连成功,触发提醒事件刷新数据");
handleMessage({ type: "reconnected" });
}
reconnectCount = 0;
startHeartbeat();
});

View File

@ -47,6 +47,11 @@ class ReminderWebSocket {
console.log("[WebSocket] 连接成功");
this.connected = true;
this.reconnectAttempts = 0;
// 重连成功后,通知所有订阅者刷新数据
if (this.listeners.size > 0) {
console.log("[WebSocket] 重连成功,通知订阅者刷新数据");
this.notify(null);
}
};
this.ws.onmessage = (event) => {

View File

@ -173,7 +173,20 @@ onMounted(async () => {
// WebSocket
reminderWs.connect();
const unsubscribe = reminderWs.subscribe(() => loadDashboard());
onUnmounted(() => unsubscribe());
//
const handleVisibilityChange = () => {
if (document.visibilityState === 'visible') {
console.log('[工作台] 页面聚焦,刷新数据');
loadDashboard();
}
};
document.addEventListener('visibilitychange', handleVisibilityChange);
onUnmounted(() => {
unsubscribe();
document.removeEventListener('visibilitychange', handleVisibilityChange);
});
});
</script>

View File

@ -538,12 +538,12 @@
</select>
</div>
<!-- 分配司机选择非自发订单 -->
<!-- 分配司机选择非自发订单可选 -->
<div v-if="!detail.order.trackingNumber" class="approval-factory">
<label class="approval-label">分配司机</label>
<label class="approval-label">分配司机可选</label>
<div v-if="driverLoading" class="loading-hint">加载中...</div>
<select v-else v-model="selectedDriverId" class="approval-select">
<option :value="null">请选择司机</option>
<option :value="null">暂不分配后续补选</option>
<option v-for="d in driverList" :key="d.user_id" :value="d.user_id">
{{ d.real_name }} {{ d.mobile ? '(' + d.mobile + ')' : '' }}
</option>
@ -1687,28 +1687,34 @@ async function handleApprovalPass() {
toast.error('请选择下发工厂');
return;
}
if (!selectedDriverId.value) {
toast.error('请选择分配司机');
return;
}
detailActionBusy.value = true;
try {
await approveOrder(detail.orderId, {
const payload = {
approve_result: 'pass',
approve_opinion: '审批通过',
factory_id: selectedFactoryId.value,
driver_id: Number(selectedDriverId.value),
});
toast.success('审批通过,已下发工厂并分配司机');
};
//
if (selectedDriverId.value) {
payload.driver_id = Number(selectedDriverId.value);
}
await approveOrder(detail.orderId, payload);
if (selectedDriverId.value) {
toast.success('审批通过,已下发工厂并分配司机');
} else {
toast.success('审批通过,已下发工厂,待后续分配司机');
}
await loadDetail();
await handleSearch();
//
try {
const textData = await generateSupplierText(detail.orderId, selectedFactoryId.value);
supplierText.value = textData?.text_content || textData?.data?.text_content || JSON.stringify(textData, null, 2);
showSupplierTextModal.value = true;
} catch (textErr) {
console.error('生成供应商文本失败:', textErr);
//
if (selectedDriverId.value) {
try {
const textData = await generateSupplierText(detail.orderId, selectedFactoryId.value);
supplierText.value = textData?.text_content || textData?.data?.text_content || JSON.stringify(textData, null, 2);
showSupplierTextModal.value = true;
} catch (textErr) {
console.error('生成供应商文本失败:', textErr);
}
}
} catch (e) {
toast.error(e.message || '操作失败');

View File

@ -47,6 +47,11 @@ class ReminderWebSocket {
console.log("[WebSocket] 连接成功");
this.connected = true;
this.reconnectAttempts = 0;
// 重连成功后,通知所有订阅者刷新数据
if (this.listeners.size > 0) {
console.log("[WebSocket] 重连成功,通知订阅者刷新数据");
this.notify(null);
}
};
this.ws.onmessage = (event) => {

View File

@ -287,7 +287,20 @@ onMounted(async () => {
// WebSocket
reminderWs.connect();
const unsubscribe = reminderWs.subscribe(() => loadDashboard());
onUnmounted(() => unsubscribe());
//
const handleVisibilityChange = () => {
if (document.visibilityState === 'visible') {
console.log('[业务员工作台] 页面聚焦,刷新数据');
loadDashboard();
}
};
document.addEventListener('visibilitychange', handleVisibilityChange);
onUnmounted(() => {
unsubscribe();
document.removeEventListener('visibilitychange', handleVisibilityChange);
});
});
</script>