feat: 下发工厂页面极简化,点击即预览文案并一键复制下发
将原来的选订单→生成文案→确认下发三步流程,简化为点击订单卡片自动弹出文案预览面板, 一键复制到剪贴板并同步订单状态,减少经理操作步骤。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e163753cc5
commit
60194d8208
@ -1,11 +1,9 @@
|
||||
/**
|
||||
* 供应商文案页面
|
||||
* 职责:选择已审批的订单,生成供应商下单文案并确认下发。
|
||||
*/
|
||||
|
||||
var badgeColorMap = {
|
||||
approved: "badge-green", pending_factory: "badge-blue",
|
||||
pending_approve: "badge-orange", canceled: "badge-red", rejected: "badge-red",
|
||||
approved: "badge-green",
|
||||
pending_factory: "badge-blue",
|
||||
pending_approve: "badge-orange",
|
||||
canceled: "badge-red",
|
||||
rejected: "badge-red",
|
||||
};
|
||||
|
||||
Page({
|
||||
@ -15,16 +13,18 @@ Page({
|
||||
actionLoading: false,
|
||||
message: "",
|
||||
orderRows: [],
|
||||
selectedOrderId: null,
|
||||
selectedOrderNo: "",
|
||||
selectedSupplierId: null,
|
||||
showDrawer: false,
|
||||
currentOrderId: null,
|
||||
currentOrderNo: "",
|
||||
currentSupplierId: null,
|
||||
currentIsConfirmed: false,
|
||||
textContent: "",
|
||||
templateType: "default",
|
||||
},
|
||||
|
||||
onShow: function () {
|
||||
var app = getApp();
|
||||
this.setData({ statusBarHeight: app.globalData.statusBarHeight });
|
||||
this.setData({ statusBarHeight: app.globalData.statusBarHeight || 20 });
|
||||
this.loadOrders();
|
||||
},
|
||||
|
||||
@ -40,10 +40,12 @@ Page({
|
||||
results.forEach(function (data) {
|
||||
(data.list || []).forEach(function (item) {
|
||||
rows.push({
|
||||
orderId: item.order_id, orderNo: item.order_no,
|
||||
orderId: item.order_id,
|
||||
orderNo: item.order_no,
|
||||
customerName: item.customer_name,
|
||||
statusText: app.mapOrderStatus(item.order_status),
|
||||
badgeClass: badgeColorMap[item.order_status] || "badge-gray",
|
||||
isConfirmed: item.order_status === "pending_factory",
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -55,16 +57,45 @@ Page({
|
||||
});
|
||||
},
|
||||
|
||||
handleChooseOrder: function (event) {
|
||||
handleTapOrder: function (event) {
|
||||
var that = this;
|
||||
var id = event.currentTarget.dataset.id;
|
||||
var no = event.currentTarget.dataset.no;
|
||||
var confirmed = event.currentTarget.dataset.confirmed;
|
||||
var app = getApp();
|
||||
that.setData({ selectedOrderId: id, selectedOrderNo: no, selectedSupplierId: null, textContent: "", message: "" });
|
||||
that.setData({
|
||||
showDrawer: true,
|
||||
currentOrderId: id,
|
||||
currentOrderNo: no,
|
||||
currentIsConfirmed: !!confirmed,
|
||||
currentSupplierId: null,
|
||||
textContent: "",
|
||||
templateType: "default",
|
||||
message: "",
|
||||
actionLoading: true,
|
||||
});
|
||||
app.request({ url: "/api/orders/" + id, method: "GET" }).then(function (detail) {
|
||||
that.setData({ selectedSupplierId: detail.factory_id || null });
|
||||
var supplierId = detail.factory_id || null;
|
||||
that.setData({ currentSupplierId: supplierId });
|
||||
if (!supplierId) {
|
||||
that.setData({ textContent: "该订单未绑定工厂,无法生成文案", actionLoading: false });
|
||||
return;
|
||||
}
|
||||
if (confirmed) {
|
||||
that.setData({ textContent: "文案已下发,无需重复操作", actionLoading: false });
|
||||
return;
|
||||
}
|
||||
return app.request({
|
||||
url: "/api/orders/" + id + "/supplier-text",
|
||||
method: "POST",
|
||||
data: { supplier_id: Number(supplierId) },
|
||||
});
|
||||
}).then(function (data) {
|
||||
if (data) {
|
||||
that.setData({ textContent: data.text_content, templateType: data.template_type, actionLoading: false });
|
||||
}
|
||||
}).catch(function (error) {
|
||||
that.setData({ message: error.message || "加载订单详情失败" });
|
||||
that.setData({ textContent: "", actionLoading: false, message: error.message || "加载失败" });
|
||||
});
|
||||
},
|
||||
|
||||
@ -72,44 +103,51 @@ Page({
|
||||
this.setData({ textContent: event.detail.value });
|
||||
},
|
||||
|
||||
handleGenerateText: function () {
|
||||
handleCopyAndSend: function () {
|
||||
var that = this;
|
||||
if (!that.data.selectedOrderId) { that.setData({ message: "请先选择一笔订单" }); return; }
|
||||
if (!that.data.selectedSupplierId) { that.setData({ message: "当前订单未绑定工厂" }); return; }
|
||||
var app = getApp();
|
||||
that.setData({ actionLoading: true, message: "" });
|
||||
app.request({
|
||||
url: "/api/orders/" + that.data.selectedOrderId + "/supplier-text",
|
||||
method: "POST",
|
||||
data: { supplier_id: Number(that.data.selectedSupplierId) },
|
||||
}).then(function (data) {
|
||||
that.setData({ textContent: data.text_content, templateType: data.template_type, message: "文案已生成" });
|
||||
}).catch(function (error) {
|
||||
that.setData({ message: error.message || "生成文案失败" });
|
||||
}).finally(function () {
|
||||
that.setData({ actionLoading: false });
|
||||
if (!that.data.currentOrderId || !that.data.currentSupplierId) return;
|
||||
wx.showModal({
|
||||
title: "确认下发",
|
||||
content: "即将复制文案到剪贴板,并将订单 " + that.data.currentOrderNo + " 状态变更为待发厂。",
|
||||
confirmColor: "#2563eb",
|
||||
success: function (res) {
|
||||
if (!res.confirm) return;
|
||||
that._doConfirmAndCopy();
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
handleConfirmText: function () {
|
||||
_doConfirmAndCopy: function () {
|
||||
var that = this;
|
||||
if (!that.data.selectedOrderId) { that.setData({ message: "请先选择一笔订单" }); return; }
|
||||
if (!that.data.selectedSupplierId) { that.setData({ message: "当前订单未绑定工厂" }); return; }
|
||||
var app = getApp();
|
||||
that.setData({ actionLoading: true, message: "" });
|
||||
that.setData({ actionLoading: true });
|
||||
app.request({
|
||||
url: "/api/orders/" + that.data.selectedOrderId + "/supplier-text/confirm",
|
||||
url: "/api/orders/" + that.data.currentOrderId + "/supplier-text/confirm",
|
||||
method: "POST",
|
||||
data: { supplier_id: Number(that.data.selectedSupplierId), text_content: that.data.textContent, remark: "" },
|
||||
data: {
|
||||
supplier_id: Number(that.data.currentSupplierId),
|
||||
text_content: that.data.textContent,
|
||||
remark: "",
|
||||
},
|
||||
}).then(function () {
|
||||
that.setData({ message: "订单 " + that.data.selectedOrderNo + " 已确认下发" });
|
||||
wx.setClipboardData({
|
||||
data: that.data.textContent,
|
||||
success: function () {
|
||||
wx.showToast({ title: "已复制,请粘贴发送", icon: "none", duration: 2000 });
|
||||
},
|
||||
});
|
||||
that.setData({ showDrawer: false, actionLoading: false });
|
||||
that.loadOrders();
|
||||
}).catch(function (error) {
|
||||
that.setData({ message: error.message || "确认下发失败" });
|
||||
}).finally(function () {
|
||||
that.setData({ actionLoading: false });
|
||||
that.setData({ actionLoading: false, message: error.message || "下发失败" });
|
||||
});
|
||||
},
|
||||
|
||||
handleBack: function () { wx.navigateBack({ delta: 1 }); },
|
||||
handleCloseDrawer: function () {
|
||||
this.setData({ showDrawer: false });
|
||||
},
|
||||
|
||||
handleBack: function () {
|
||||
wx.navigateBack({ delta: 1 });
|
||||
},
|
||||
});
|
||||
|
||||
@ -2,44 +2,52 @@
|
||||
<view class="custom-header" style="padding-top: {{statusBarHeight}}px;">
|
||||
<view class="back-btn" bindtap="handleBack"><view class="back-arrow"></view></view>
|
||||
<view class="header-title">下发工厂文本</view>
|
||||
<view class="header-sub">选择订单后生成文案并确认下发</view>
|
||||
<view class="header-sub">选择订单查看文案并复制下发</view>
|
||||
</view>
|
||||
|
||||
<view wx:if="{{message}}" class="message card">{{message}}</view>
|
||||
|
||||
<view hidden="{{!loading}}" class="card empty-card">
|
||||
<view wx:if="{{loading}}" class="card empty-card">
|
||||
<view class="page-subtitle">正在加载...</view>
|
||||
</view>
|
||||
|
||||
<view wx:else class="card order-panel">
|
||||
<view class="section-title">待发厂订单</view>
|
||||
<view wx:if="{{!orderRows.length}}" class="empty-hint">暂无待发厂订单</view>
|
||||
<view wx:for="{{orderRows}}" wx:key="orderId" class="item-row"
|
||||
data-id="{{item.orderId}}" data-no="{{item.orderNo}}" bindtap="handleChooseOrder">
|
||||
<view class="row-main">
|
||||
<view class="row-left">
|
||||
<view class="row-title">{{item.orderNo}}</view>
|
||||
<view class="row-sub">客户:{{item.customerName}}</view>
|
||||
<view wx:elif="{{!orderRows.length}}" class="card empty-card">
|
||||
<view class="empty-title">暂无待发厂订单</view>
|
||||
<view class="page-subtitle">已审批通过的订单会出现在这里</view>
|
||||
</view>
|
||||
|
||||
<view wx:else class="order-list">
|
||||
<view wx:for="{{orderRows}}" wx:key="orderId" class="order-card card"
|
||||
data-id="{{item.orderId}}" data-no="{{item.orderNo}}" data-confirmed="{{item.isConfirmed}}"
|
||||
bindtap="handleTapOrder">
|
||||
<view class="order-card-main">
|
||||
<view class="order-card-left">
|
||||
<view class="order-card-no">{{item.orderNo}}</view>
|
||||
<view class="order-card-customer">客户:{{item.customerName}}</view>
|
||||
</view>
|
||||
<view class="badge {{item.badgeClass}}">{{item.statusText}}</view>
|
||||
<view wx:if="{{item.isConfirmed}}" class="badge badge-blue">已下发</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="card form-panel">
|
||||
<view class="selected">已选订单:{{selectedOrderNo || "未选择"}}</view>
|
||||
<view class="field-group">
|
||||
<view class="field-label">模板类型</view>
|
||||
<view class="field-value">{{templateType}}</view>
|
||||
<!-- 底部半屏面板 -->
|
||||
<view wx:if="{{showDrawer}}" class="drawer-mask" bindtap="handleCloseDrawer"></view>
|
||||
<view class="drawer {{showDrawer ? 'drawer-show' : ''}}">
|
||||
<view class="drawer-handle"></view>
|
||||
<view class="drawer-header">
|
||||
<view class="drawer-order-no">{{currentOrderNo}}</view>
|
||||
<view class="drawer-template">模板:{{templateType}}</view>
|
||||
</view>
|
||||
<view class="field-group">
|
||||
<view class="field-label">生成文案</view>
|
||||
<textarea class="textarea" placeholder="点击生成文案后可查看并编辑" value="{{textContent}}" bindinput="handleTextInput"></textarea>
|
||||
<view class="drawer-body">
|
||||
<textarea class="drawer-textarea {{currentIsConfirmed ? 'readonly' : ''}}"
|
||||
value="{{textContent}}" bindinput="handleTextInput"
|
||||
placeholder="文案内容" disabled="{{currentIsConfirmed}}" />
|
||||
</view>
|
||||
<view class="drawer-footer">
|
||||
<view wx:if="{{currentIsConfirmed}}" class="drawer-hint">文案已下发,无需重复操作</view>
|
||||
<button wx:else class="action-btn primary-btn" type="primary"
|
||||
loading="{{actionLoading}}" disabled="{{actionLoading}}"
|
||||
bindtap="handleCopyAndSend">复制并下发</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="actions-row">
|
||||
<button class="action-btn primary-btn" type="primary" loading="{{actionLoading}}" bindtap="handleGenerateText">生成文案</button>
|
||||
<button class="action-btn ghost-btn" loading="{{actionLoading}}" bindtap="handleConfirmText">确认下发</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@ -23,96 +23,35 @@
|
||||
margin-top: 6rpx;
|
||||
}
|
||||
|
||||
.order-panel,
|
||||
.form-panel {
|
||||
padding: 24rpx;
|
||||
.order-list {
|
||||
display: grid;
|
||||
gap: 14rpx;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #0f172a;
|
||||
.order-card {
|
||||
padding: 28rpx;
|
||||
}
|
||||
|
||||
.item-row {
|
||||
padding-top: 14rpx;
|
||||
border-top: 1rpx solid #f1f5f9;
|
||||
}
|
||||
|
||||
.row-main {
|
||||
.order-card-main {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.row-left {
|
||||
.order-card-left {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.row-title {
|
||||
.order-card-no {
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #0f172a;
|
||||
}
|
||||
|
||||
.row-sub {
|
||||
.order-card-customer {
|
||||
font-size: 24rpx;
|
||||
color: #64748b;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
|
||||
.selected {
|
||||
font-size: 26rpx;
|
||||
color: #475569;
|
||||
padding: 18rpx 20rpx;
|
||||
border-radius: 14rpx;
|
||||
background: #f8fbff;
|
||||
border: 1rpx solid #e5eaf1;
|
||||
}
|
||||
|
||||
.field-group {
|
||||
display: grid;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.field-label {
|
||||
font-size: 24rpx;
|
||||
color: #64748b;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.field-value {
|
||||
font-size: 28rpx;
|
||||
color: #0f172a;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.textarea {
|
||||
min-height: 180rpx;
|
||||
}
|
||||
|
||||
.actions-row {
|
||||
display: flex;
|
||||
gap: 16rpx;
|
||||
padding: 0 28rpx;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
flex: 1;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
font-size: 28rpx;
|
||||
border-radius: 18rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.ghost-btn {
|
||||
background: #ffffff;
|
||||
color: #475569;
|
||||
border: 1rpx solid #dbe3ee;
|
||||
margin-top: 6rpx;
|
||||
}
|
||||
|
||||
.empty-hint {
|
||||
@ -127,12 +66,100 @@
|
||||
padding: 20rpx 24rpx;
|
||||
}
|
||||
|
||||
.empty-card {
|
||||
padding: 40rpx 24rpx;
|
||||
text-align: center;
|
||||
/* 底部半屏面板 */
|
||||
.drawer-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
z-index: 90;
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
font-size: 26rpx;
|
||||
color: #64748b;
|
||||
.drawer {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: #ffffff;
|
||||
border-radius: 28rpx 28rpx 0 0;
|
||||
z-index: 100;
|
||||
transform: translateY(100%);
|
||||
transition: transform 0.3s ease;
|
||||
max-height: 80vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.drawer-show {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.drawer-handle {
|
||||
width: 64rpx;
|
||||
height: 8rpx;
|
||||
border-radius: 4rpx;
|
||||
background: #e2e8f0;
|
||||
margin: 16rpx auto 0;
|
||||
}
|
||||
|
||||
.drawer-header {
|
||||
padding: 20rpx 28rpx 0;
|
||||
}
|
||||
|
||||
.drawer-order-no {
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
color: #0f172a;
|
||||
}
|
||||
|
||||
.drawer-template {
|
||||
font-size: 24rpx;
|
||||
color: #64748b;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
|
||||
.drawer-body {
|
||||
padding: 20rpx 28rpx;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.drawer-textarea {
|
||||
width: 100%;
|
||||
min-height: 240rpx;
|
||||
box-sizing: border-box;
|
||||
border: 1rpx solid #e2e8f0;
|
||||
border-radius: 14rpx;
|
||||
padding: 20rpx;
|
||||
font-size: 26rpx;
|
||||
color: #0f172a;
|
||||
line-height: 1.6;
|
||||
background: #f8fbff;
|
||||
}
|
||||
|
||||
.drawer-textarea.readonly {
|
||||
color: #94a3b8;
|
||||
background: #f1f5f9;
|
||||
}
|
||||
|
||||
.drawer-footer {
|
||||
padding: 16rpx 28rpx 40rpx;
|
||||
}
|
||||
|
||||
.drawer-hint {
|
||||
text-align: center;
|
||||
color: #64748b;
|
||||
font-size: 26rpx;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
font-size: 28rpx;
|
||||
border-radius: 18rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
/** 订单状态与样式类名的映射 */
|
||||
var badgeColorMap = {
|
||||
approved: "badge-green",
|
||||
pending_factory: "badge-blue",
|
||||
@ -7,145 +6,148 @@ var badgeColorMap = {
|
||||
rejected: "badge-red",
|
||||
};
|
||||
|
||||
/**
|
||||
* 供应商文案页面
|
||||
* 职责:选择已审批的订单,生成供应商下单文案并确认下发。
|
||||
* 支持自动获取订单关联的工厂信息,生成和编辑文案内容后确认下发。
|
||||
*/
|
||||
Page({
|
||||
/** 页面数据 */
|
||||
data: {
|
||||
statusBarHeight: 20,
|
||||
loading: true,
|
||||
actionLoading: false,
|
||||
message: "",
|
||||
orderRows: [],
|
||||
selectedOrderId: null,
|
||||
selectedOrderNo: "",
|
||||
selectedSupplierId: null,
|
||||
showDrawer: false,
|
||||
currentOrderId: null,
|
||||
currentOrderNo: "",
|
||||
currentSupplierId: null,
|
||||
currentIsConfirmed: false,
|
||||
textContent: "",
|
||||
templateType: "default",
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面显示时加载可选择的订单列表(已审批和待发厂状态)
|
||||
*/
|
||||
onShow: function() {
|
||||
onShow: function () {
|
||||
var app = getApp();
|
||||
this.setData({ statusBarHeight: app.globalData.statusBarHeight || 20 });
|
||||
this.loadOrders();
|
||||
},
|
||||
|
||||
/**
|
||||
* 从后端并行加载已审批和待发厂的订单列表
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
loadOrders: function() {
|
||||
loadOrders: function () {
|
||||
var that = this;
|
||||
var app = getApp();
|
||||
that.setData({ loading: true, message: "" });
|
||||
Promise.all([
|
||||
app.request({ url: "/api/orders?order_status=approved&page_no=1&page_size=50", method: "GET" }),
|
||||
app.request({ url: "/api/orders?order_status=pending_factory&page_no=1&page_size=50", method: "GET" }),
|
||||
]).then(function(results) {
|
||||
]).then(function (results) {
|
||||
var rows = [];
|
||||
results.forEach(function(data) {
|
||||
(data.list || []).forEach(function(item) {
|
||||
results.forEach(function (data) {
|
||||
(data.list || []).forEach(function (item) {
|
||||
rows.push({
|
||||
orderId: item.order_id,
|
||||
orderNo: item.order_no,
|
||||
customerName: item.customer_name,
|
||||
statusText: app.mapOrderStatus(item.order_status),
|
||||
badgeClass: badgeColorMap[item.order_status] || "badge-gray",
|
||||
isConfirmed: item.order_status === "pending_factory",
|
||||
});
|
||||
});
|
||||
});
|
||||
that.setData({ orderRows: rows });
|
||||
}).catch(function(error) {
|
||||
}).catch(function (error) {
|
||||
that.setData({ message: error.message || "加载失败" });
|
||||
}).finally(function() {
|
||||
}).finally(function () {
|
||||
that.setData({ loading: false });
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 选择订单并获取其关联的工厂信息
|
||||
* @param {Object} event - 点击事件对象,通过 dataset.id/no 获取订单 ID 和编号
|
||||
*/
|
||||
handleChooseOrder: function(event) {
|
||||
handleTapOrder: function (event) {
|
||||
var that = this;
|
||||
var id = event.currentTarget.dataset.id;
|
||||
var no = event.currentTarget.dataset.no;
|
||||
var confirmed = event.currentTarget.dataset.confirmed;
|
||||
var app = getApp();
|
||||
that.setData({ selectedOrderId: id, selectedOrderNo: no, selectedSupplierId: null, textContent: "", message: "" });
|
||||
app.request({ url: "/api/orders/" + id, method: "GET" }).then(function(detail) {
|
||||
that.setData({ selectedSupplierId: detail.factory_id || null });
|
||||
}).catch(function(error) {
|
||||
that.setData({ message: error.message || "加载订单详情失败" });
|
||||
that.setData({
|
||||
showDrawer: true,
|
||||
currentOrderId: id,
|
||||
currentOrderNo: no,
|
||||
currentIsConfirmed: !!confirmed,
|
||||
currentSupplierId: null,
|
||||
textContent: "",
|
||||
templateType: "default",
|
||||
message: "",
|
||||
actionLoading: true,
|
||||
});
|
||||
app.request({ url: "/api/orders/" + id, method: "GET" }).then(function (detail) {
|
||||
var supplierId = detail.factory_id || null;
|
||||
that.setData({ currentSupplierId: supplierId });
|
||||
if (!supplierId) {
|
||||
that.setData({ textContent: "该订单未绑定工厂,无法生成文案", actionLoading: false });
|
||||
return;
|
||||
}
|
||||
if (confirmed) {
|
||||
that.setData({ textContent: "文案已下发,无需重复操作", actionLoading: false });
|
||||
return;
|
||||
}
|
||||
return app.request({
|
||||
url: "/api/orders/" + id + "/supplier-text",
|
||||
method: "POST",
|
||||
data: { supplier_id: Number(supplierId) },
|
||||
});
|
||||
}).then(function (data) {
|
||||
if (data) {
|
||||
that.setData({ textContent: data.text_content, templateType: data.template_type, actionLoading: false });
|
||||
}
|
||||
}).catch(function (error) {
|
||||
that.setData({ textContent: "", actionLoading: false, message: error.message || "加载失败" });
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 处理文案内容输入框值变化
|
||||
* @param {Object} event - 输入事件对象
|
||||
*/
|
||||
handleTextInput: function(event) {
|
||||
handleTextInput: function (event) {
|
||||
this.setData({ textContent: event.detail.value });
|
||||
},
|
||||
|
||||
/**
|
||||
* 调用后端接口生成供应商文案
|
||||
* 需要先选择订单且订单已绑定工厂
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
handleGenerateText: function() {
|
||||
handleCopyAndSend: function () {
|
||||
var that = this;
|
||||
if (!that.data.selectedOrderId) { that.setData({ message: "请先选择一笔订单" }); return; }
|
||||
if (!that.data.selectedSupplierId) { that.setData({ message: "当前订单未绑定工厂" }); return; }
|
||||
var app = getApp();
|
||||
that.setData({ actionLoading: true, message: "" });
|
||||
app.request({
|
||||
url: "/api/orders/" + that.data.selectedOrderId + "/supplier-text",
|
||||
method: "POST",
|
||||
data: { supplier_id: Number(that.data.selectedSupplierId) },
|
||||
}).then(function(data) {
|
||||
that.setData({ textContent: data.text_content, templateType: data.template_type, message: "文案已生成" });
|
||||
}).catch(function(error) {
|
||||
that.setData({ message: error.message || "生成文案失败" });
|
||||
}).finally(function() {
|
||||
that.setData({ actionLoading: false });
|
||||
if (!that.data.currentOrderId || !that.data.currentSupplierId) return;
|
||||
wx.showModal({
|
||||
title: "确认下发",
|
||||
content: "即将复制文案到剪贴板,并将订单 " + that.data.currentOrderNo + " 状态变更为待发厂。",
|
||||
confirmColor: "#2563eb",
|
||||
success: function (res) {
|
||||
if (!res.confirm) return;
|
||||
that._doConfirmAndCopy();
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 确认下发文案到供应商
|
||||
* 将文案内容提交到后端并更新订单状态为待发厂
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
handleConfirmText: function() {
|
||||
_doConfirmAndCopy: function () {
|
||||
var that = this;
|
||||
if (!that.data.selectedOrderId) { that.setData({ message: "请先选择一笔订单" }); return; }
|
||||
if (!that.data.selectedSupplierId) { that.setData({ message: "当前订单未绑定工厂" }); return; }
|
||||
var app = getApp();
|
||||
that.setData({ actionLoading: true, message: "" });
|
||||
that.setData({ actionLoading: true });
|
||||
app.request({
|
||||
url: "/api/orders/" + that.data.selectedOrderId + "/supplier-text/confirm",
|
||||
url: "/api/orders/" + that.data.currentOrderId + "/supplier-text/confirm",
|
||||
method: "POST",
|
||||
data: {
|
||||
supplier_id: Number(that.data.selectedSupplierId),
|
||||
supplier_id: Number(that.data.currentSupplierId),
|
||||
text_content: that.data.textContent,
|
||||
remark: "",
|
||||
},
|
||||
}).then(function() {
|
||||
that.setData({ message: "订单 " + that.data.selectedOrderNo + " 已确认下发" });
|
||||
}).then(function () {
|
||||
wx.setClipboardData({
|
||||
data: that.data.textContent,
|
||||
success: function () {
|
||||
wx.showToast({ title: "已复制,请粘贴发送", icon: "none", duration: 2000 });
|
||||
},
|
||||
});
|
||||
that.setData({ showDrawer: false, actionLoading: false });
|
||||
that.loadOrders();
|
||||
}).catch(function(error) {
|
||||
that.setData({ message: error.message || "确认下发失败" });
|
||||
}).finally(function() {
|
||||
that.setData({ actionLoading: false });
|
||||
}).catch(function (error) {
|
||||
that.setData({ actionLoading: false, message: error.message || "下发失败" });
|
||||
});
|
||||
},
|
||||
|
||||
/** 返回上一页 */
|
||||
handleBack: function() { wx.navigateBack({ delta: 1 }); },
|
||||
handleCloseDrawer: function () {
|
||||
this.setData({ showDrawer: false });
|
||||
},
|
||||
|
||||
handleBack: function () {
|
||||
wx.navigateBack({ delta: 1 });
|
||||
},
|
||||
});
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<view class="custom-header" style="padding-top: {{statusBarHeight}}px;">
|
||||
<view class="back-btn" bindtap="handleBack"><view class="back-arrow"></view></view>
|
||||
<view class="header-title">下发工厂文本</view>
|
||||
<view class="header-sub">选择订单后生成文案并确认下发</view>
|
||||
<view class="header-sub">选择订单查看文案并复制下发</view>
|
||||
</view>
|
||||
|
||||
<view wx:if="{{message}}" class="message card">{{message}}</view>
|
||||
@ -11,35 +11,43 @@
|
||||
<view class="page-subtitle">正在加载...</view>
|
||||
</view>
|
||||
|
||||
<view wx:else class="card order-panel">
|
||||
<view class="section-title">待发厂订单</view>
|
||||
<view wx:if="{{!orderRows.length}}" class="empty-hint">暂无待发厂订单</view>
|
||||
<view wx:for="{{orderRows}}" wx:key="orderId" class="item-row"
|
||||
data-id="{{item.orderId}}" data-no="{{item.orderNo}}" bindtap="handleChooseOrder">
|
||||
<view class="row-main">
|
||||
<view class="row-left">
|
||||
<view class="row-title">{{item.orderNo}}</view>
|
||||
<view class="row-sub">客户:{{item.customerName}}</view>
|
||||
<view wx:elif="{{!orderRows.length}}" class="card empty-card">
|
||||
<view class="empty-title">暂无待发厂订单</view>
|
||||
<view class="page-subtitle">已审批通过的订单会出现在这里</view>
|
||||
</view>
|
||||
|
||||
<view wx:else class="order-list">
|
||||
<view wx:for="{{orderRows}}" wx:key="orderId" class="order-card card"
|
||||
data-id="{{item.orderId}}" data-no="{{item.orderNo}}" data-confirmed="{{item.isConfirmed}}"
|
||||
bindtap="handleTapOrder">
|
||||
<view class="order-card-main">
|
||||
<view class="order-card-left">
|
||||
<view class="order-card-no">{{item.orderNo}}</view>
|
||||
<view class="order-card-customer">客户:{{item.customerName}}</view>
|
||||
</view>
|
||||
<view class="badge {{item.badgeClass}}">{{item.statusText}}</view>
|
||||
<view wx:if="{{item.isConfirmed}}" class="badge badge-blue">已下发</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="card form-panel">
|
||||
<view class="selected">已选订单:{{selectedOrderNo || "未选择"}}</view>
|
||||
<view class="field-group">
|
||||
<view class="field-label">模板类型</view>
|
||||
<view class="field-value">{{templateType}}</view>
|
||||
<!-- 底部半屏面板 -->
|
||||
<view wx:if="{{showDrawer}}" class="drawer-mask" bindtap="handleCloseDrawer"></view>
|
||||
<view class="drawer {{showDrawer ? 'drawer-show' : ''}}">
|
||||
<view class="drawer-handle"></view>
|
||||
<view class="drawer-header">
|
||||
<view class="drawer-order-no">{{currentOrderNo}}</view>
|
||||
<view class="drawer-template">模板:{{templateType}}</view>
|
||||
</view>
|
||||
<view class="field-group">
|
||||
<view class="field-label">生成文案</view>
|
||||
<textarea class="textarea" placeholder="点击生成文案后可查看并编辑" value="{{textContent}}" bindinput="handleTextInput"></textarea>
|
||||
<view class="drawer-body">
|
||||
<textarea class="drawer-textarea {{currentIsConfirmed ? 'readonly' : ''}}"
|
||||
value="{{textContent}}" bindinput="handleTextInput"
|
||||
placeholder="文案内容" disabled="{{currentIsConfirmed}}" />
|
||||
</view>
|
||||
<view class="drawer-footer">
|
||||
<view wx:if="{{currentIsConfirmed}}" class="drawer-hint">文案已下发,无需重复操作</view>
|
||||
<button wx:else class="action-btn primary-btn" type="primary"
|
||||
loading="{{actionLoading}}" disabled="{{actionLoading}}"
|
||||
bindtap="handleCopyAndSend">复制并下发</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="actions-row">
|
||||
<button class="action-btn primary-btn" type="primary" loading="{{actionLoading}}" bindtap="handleGenerateText">生成文案</button>
|
||||
<button class="action-btn ghost-btn" loading="{{actionLoading}}" bindtap="handleConfirmText">确认下发</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@ -23,96 +23,35 @@
|
||||
margin-top: 6rpx;
|
||||
}
|
||||
|
||||
.order-panel,
|
||||
.form-panel {
|
||||
padding: 24rpx;
|
||||
.order-list {
|
||||
display: grid;
|
||||
gap: 14rpx;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #0f172a;
|
||||
.order-card {
|
||||
padding: 28rpx;
|
||||
}
|
||||
|
||||
.item-row {
|
||||
padding-top: 14rpx;
|
||||
border-top: 1rpx solid #f1f5f9;
|
||||
}
|
||||
|
||||
.row-main {
|
||||
.order-card-main {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.row-left {
|
||||
.order-card-left {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.row-title {
|
||||
.order-card-no {
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #0f172a;
|
||||
}
|
||||
|
||||
.row-sub {
|
||||
.order-card-customer {
|
||||
font-size: 24rpx;
|
||||
color: #64748b;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
|
||||
.selected {
|
||||
font-size: 26rpx;
|
||||
color: #475569;
|
||||
padding: 18rpx 20rpx;
|
||||
border-radius: 14rpx;
|
||||
background: #f8fbff;
|
||||
border: 1rpx solid #e5eaf1;
|
||||
}
|
||||
|
||||
.field-group {
|
||||
display: grid;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.field-label {
|
||||
font-size: 24rpx;
|
||||
color: #64748b;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.field-value {
|
||||
font-size: 28rpx;
|
||||
color: #0f172a;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.textarea {
|
||||
min-height: 180rpx;
|
||||
}
|
||||
|
||||
.actions-row {
|
||||
display: flex;
|
||||
gap: 16rpx;
|
||||
padding: 0 28rpx;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
flex: 1;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
font-size: 28rpx;
|
||||
border-radius: 18rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.ghost-btn {
|
||||
background: #ffffff;
|
||||
color: #475569;
|
||||
border: 1rpx solid #dbe3ee;
|
||||
margin-top: 6rpx;
|
||||
}
|
||||
|
||||
.empty-hint {
|
||||
@ -127,12 +66,100 @@
|
||||
padding: 20rpx 24rpx;
|
||||
}
|
||||
|
||||
.empty-card {
|
||||
padding: 40rpx 24rpx;
|
||||
text-align: center;
|
||||
/* 底部半屏面板 */
|
||||
.drawer-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
z-index: 90;
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
font-size: 26rpx;
|
||||
color: #64748b;
|
||||
.drawer {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: #ffffff;
|
||||
border-radius: 28rpx 28rpx 0 0;
|
||||
z-index: 100;
|
||||
transform: translateY(100%);
|
||||
transition: transform 0.3s ease;
|
||||
max-height: 80vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.drawer-show {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.drawer-handle {
|
||||
width: 64rpx;
|
||||
height: 8rpx;
|
||||
border-radius: 4rpx;
|
||||
background: #e2e8f0;
|
||||
margin: 16rpx auto 0;
|
||||
}
|
||||
|
||||
.drawer-header {
|
||||
padding: 20rpx 28rpx 0;
|
||||
}
|
||||
|
||||
.drawer-order-no {
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
color: #0f172a;
|
||||
}
|
||||
|
||||
.drawer-template {
|
||||
font-size: 24rpx;
|
||||
color: #64748b;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
|
||||
.drawer-body {
|
||||
padding: 20rpx 28rpx;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.drawer-textarea {
|
||||
width: 100%;
|
||||
min-height: 240rpx;
|
||||
box-sizing: border-box;
|
||||
border: 1rpx solid #e2e8f0;
|
||||
border-radius: 14rpx;
|
||||
padding: 20rpx;
|
||||
font-size: 26rpx;
|
||||
color: #0f172a;
|
||||
line-height: 1.6;
|
||||
background: #f8fbff;
|
||||
}
|
||||
|
||||
.drawer-textarea.readonly {
|
||||
color: #94a3b8;
|
||||
background: #f1f5f9;
|
||||
}
|
||||
|
||||
.drawer-footer {
|
||||
padding: 16rpx 28rpx 40rpx;
|
||||
}
|
||||
|
||||
.drawer-hint {
|
||||
text-align: center;
|
||||
color: #64748b;
|
||||
font-size: 26rpx;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
font-size: 28rpx;
|
||||
border-radius: 18rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user