<template>
|
<view class="account-detail">
|
<PageHeader title="补充发货信息"
|
@back="goBack" />
|
<view class="form-container">
|
<up-form ref="formRef"
|
:model="form"
|
:rules="rules"
|
label-width="120"
|
input-align="right"
|
error-message-align="right">
|
<u-cell-group title="发货信息"
|
class="form-section">
|
<up-form-item label="发货类型"
|
prop="type"
|
required
|
border-bottom>
|
<FormPicker v-model="form.type"
|
type="select"
|
title="选择发货类型"
|
:options="typeOptions"
|
placeholder="请选择发货类型"
|
@change="onTypeChange" />
|
</up-form-item>
|
<up-form-item label="发货日期"
|
prop="shippingDate"
|
required
|
border-bottom>
|
<FormPicker v-model="form.shippingDate"
|
type="date"
|
placeholder="请选择发货日期" />
|
</up-form-item>
|
<up-form-item v-if="form.type === '货车'"
|
label="发货车牌号"
|
prop="shippingCarNumber"
|
required
|
border-bottom>
|
<up-input v-model="form.shippingCarNumber"
|
placeholder="请输入发货车牌号"
|
clearable />
|
</up-form-item>
|
<up-form-item v-if="form.type === '快递'"
|
label="快递公司"
|
prop="expressCompany"
|
required
|
border-bottom>
|
<up-input v-model="form.expressCompany"
|
placeholder="请输入快递公司"
|
clearable />
|
</up-form-item>
|
<up-form-item v-if="form.type === '快递'"
|
label="快递单号"
|
prop="expressNumber">
|
<up-input v-model="form.expressNumber"
|
placeholder="请输入快递单号"
|
clearable />
|
</up-form-item>
|
</u-cell-group>
|
|
<u-cell-group title="单据与归档"
|
class="form-section">
|
<up-form-item label="发货单据"
|
prop="shippingDocument"
|
border-bottom>
|
<up-input v-model="form.shippingDocument"
|
placeholder="请输入发货单据"
|
clearable />
|
</up-form-item>
|
<up-form-item label="是否对账"
|
prop="isReconciled"
|
border-bottom>
|
<up-switch v-model="form.isReconciled"
|
:active-value="1"
|
:inactive-value="0" />
|
</up-form-item>
|
<up-form-item v-if="form.isReconciled === 1"
|
label="对账单归档"
|
prop="statementArchivingStatus"
|
border-bottom>
|
<up-textarea v-model="form.statementArchivingStatus"
|
placeholder="请填写对账单归档情况"
|
auto-height
|
maxlength="200" />
|
</up-form-item>
|
<up-form-item label="是否结算"
|
prop="isSettled"
|
border-bottom>
|
<up-switch v-model="form.isSettled"
|
:active-value="1"
|
:inactive-value="0" />
|
</up-form-item>
|
<up-form-item v-if="form.isSettled === 1"
|
label="结算单归档"
|
prop="settlementArchivingStatus"
|
border-bottom>
|
<up-textarea v-model="form.settlementArchivingStatus"
|
placeholder="请填写结算单归档情况"
|
auto-height
|
maxlength="200" />
|
</up-form-item>
|
<up-form-item label="是否已开票"
|
prop="isInvoiced">
|
<up-switch v-model="form.isInvoiced"
|
:active-value="1"
|
:inactive-value="0" />
|
</up-form-item>
|
</u-cell-group>
|
|
<u-cell-group title="发货图片"
|
class="form-section">
|
<view class="upload-wrap">
|
<CommonUpload v-model="form.deliveryFiles"
|
accept="image"
|
:max-count="6" />
|
</view>
|
</u-cell-group>
|
</up-form>
|
|
<u-cell-group title="发货产品明细"
|
class="form-section">
|
<view v-if="products.length === 0"
|
class="empty-block">
|
<text>暂无产品明细</text>
|
</view>
|
<view v-for="(row, index) in products"
|
:key="index"
|
class="product-row">
|
<view class="detail-row">
|
<text class="detail-label">产品名称</text>
|
<text class="detail-value">{{ row.productName || "-" }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">规格型号</text>
|
<text class="detail-value">{{ row.specificationModel || "-" }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">批次号</text>
|
<text class="detail-value">{{ row.batchNo || "-" }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">发货数量</text>
|
<text class="detail-value">
|
{{ row.deliveryQuantity === "" ? "-" : row.deliveryQuantity }}{{ row.unit ? ` ${row.unit}` : "" }}
|
</text>
|
</view>
|
</view>
|
</u-cell-group>
|
</view>
|
|
<FooterButtons :loading="loading"
|
confirmText="保存"
|
@cancel="goBack"
|
@confirm="handleSubmit" />
|
</view>
|
</template>
|
|
<script setup>
|
import { ref } from "vue";
|
import { onLoad } from "@dcloudio/uni-app";
|
import PageHeader from "@/components/PageHeader.vue";
|
import FooterButtons from "@/components/FooterButtons.vue";
|
import FormPicker from "@/components/FormPicker.vue";
|
import CommonUpload from "@/components/CommonUpload.vue";
|
import { formatDateToYMD } from "@/utils/ruoyi";
|
import { loadDetailData } from "@/utils/detailCache";
|
import {
|
resolveDeliveryFiles,
|
resolveDeliveryProducts,
|
} from "@/utils/delivery";
|
import {
|
deductStock,
|
getDeliveryDetail,
|
} from "@/api/salesManagement/deliveryLedger";
|
|
const formRef = ref();
|
const loading = ref(false);
|
const deliveryId = ref("");
|
const products = ref([]);
|
|
const typeOptions = [
|
{ name: "货车", value: "货车" },
|
{ name: "快递", value: "快递" },
|
];
|
|
const form = ref({
|
id: undefined,
|
type: "",
|
shippingDate: "",
|
shippingCarNumber: "",
|
expressCompany: "",
|
expressNumber: "",
|
shippingDocument: "",
|
isReconciled: 0,
|
statementArchivingStatus: "",
|
isSettled: 0,
|
settlementArchivingStatus: "",
|
isInvoiced: 0,
|
deliveryFiles: [],
|
});
|
|
// 车牌与快递公司按发货类型二选一必填
|
const rules = {
|
type: [{ required: true, message: "请选择发货类型", trigger: "change" }],
|
shippingDate: [
|
{ required: true, message: "请选择发货日期", trigger: "change" },
|
],
|
};
|
|
const goBack = () => uni.navigateBack();
|
|
const onTypeChange = value => {
|
if (value === "货车") {
|
form.value.expressCompany = "";
|
form.value.expressNumber = "";
|
} else {
|
form.value.shippingCarNumber = "";
|
}
|
};
|
|
const loadDetail = async () => {
|
let data = null;
|
try {
|
data = await loadDetailData({
|
cacheKey: "deliveryDetail",
|
id: deliveryId.value,
|
fetcher: getDeliveryDetail,
|
});
|
} catch (error) {
|
data = null;
|
}
|
if (!data) {
|
uni.showToast({ title: "未找到发货信息", icon: "none" });
|
return;
|
}
|
|
form.value = {
|
id: data.id,
|
type: data.type || "",
|
shippingDate: (data.shippingDate || "").slice(0, 10),
|
shippingCarNumber: data.shippingCarNumber || "",
|
expressCompany: data.expressCompany || "",
|
expressNumber: data.expressNumber || "",
|
shippingDocument: data.shippingDocument || "",
|
isReconciled: data.isReconciled ?? 0,
|
statementArchivingStatus: data.statementArchivingStatus || "",
|
isSettled: data.isSettled ?? 0,
|
settlementArchivingStatus: data.settlementArchivingStatus || "",
|
isInvoiced: data.isInvoiced ?? 0,
|
deliveryFiles: resolveDeliveryFiles(data),
|
};
|
products.value = resolveDeliveryProducts(data);
|
};
|
|
const handleSubmit = async () => {
|
const valid = await formRef.value.validate().catch(() => false);
|
if (!valid) return;
|
|
if (form.value.type === "货车" && !form.value.shippingCarNumber) {
|
uni.showToast({ title: "请输入发货车牌号", icon: "none" });
|
return;
|
}
|
if (form.value.type === "快递" && !form.value.expressCompany) {
|
uni.showToast({ title: "请输入快递公司", icon: "none" });
|
return;
|
}
|
|
// 需求六:发货台账要求补充单据与对账/结算/开票情况。
|
// 参考实现(管理端)只提交前 7 个字段,这里按需求一并提交,
|
// 后端若未接收这几个字段会被忽略,不影响发货主流程。
|
const payload = {
|
id: form.value.id,
|
type: form.value.type,
|
shippingDate: form.value.shippingDate,
|
shippingCarNumber:
|
form.value.type === "货车" ? form.value.shippingCarNumber : "",
|
expressCompany:
|
form.value.type === "快递" ? form.value.expressCompany : "",
|
expressNumber: form.value.type === "快递" ? form.value.expressNumber : "",
|
storageBlobDTOs: (form.value.deliveryFiles || [])
|
.filter(file => file?.url)
|
.map(file => ({ url: file.url, name: file.name || "" })),
|
shippingDocument: form.value.shippingDocument,
|
isReconciled: form.value.isReconciled,
|
statementArchivingStatus:
|
form.value.isReconciled === 1
|
? form.value.statementArchivingStatus
|
: "",
|
isSettled: form.value.isSettled,
|
settlementArchivingStatus:
|
form.value.isSettled === 1 ? form.value.settlementArchivingStatus : "",
|
isInvoiced: form.value.isInvoiced,
|
};
|
|
loading.value = true;
|
deductStock(payload)
|
.then(() => {
|
uni.showToast({ title: "保存成功", icon: "success" });
|
setTimeout(() => uni.navigateBack(), 1200);
|
})
|
.catch(() => {
|
uni.showToast({ title: "保存失败", icon: "none" });
|
})
|
.finally(() => {
|
loading.value = false;
|
});
|
};
|
|
onLoad(options => {
|
if (options?.id) {
|
deliveryId.value = options.id;
|
form.value.id = options.id;
|
loadDetail();
|
} else {
|
form.value.shippingDate = formatDateToYMD(Date.now());
|
}
|
});
|
</script>
|
|
<style scoped lang="scss">
|
@import "@/static/scss/form-common.scss";
|
|
.account-detail {
|
min-height: 100vh;
|
background: #f8f9fa;
|
padding-bottom: 100px;
|
}
|
|
.form-container {
|
padding: 12px 12px 0;
|
}
|
|
.form-section {
|
margin-bottom: 12px;
|
border-radius: 12px;
|
overflow: hidden;
|
box-shadow: 0 2px 10px rgba(15, 35, 95, 0.05);
|
}
|
|
.upload-wrap {
|
padding: 12px;
|
}
|
|
.empty-block {
|
padding: 16px;
|
font-size: 14px;
|
color: #909399;
|
}
|
|
.product-row {
|
padding: 12px 16px;
|
border-bottom: 1px solid #f2f4f8;
|
}
|
|
.product-row:last-child {
|
border-bottom: none;
|
}
|
|
.detail-row {
|
display: flex;
|
align-items: flex-start;
|
justify-content: space-between;
|
padding: 4px 0;
|
}
|
|
.detail-label {
|
font-size: 13px;
|
color: #909399;
|
}
|
|
.detail-value {
|
font-size: 13px;
|
color: #333;
|
max-width: 70%;
|
text-align: right;
|
word-break: break-all;
|
}
|
|
:deep(.u-cell-group__title) {
|
padding: 14px 18px 10px !important;
|
font-size: 15px !important;
|
font-weight: 600 !important;
|
color: #22324d !important;
|
background: #f8fbff !important;
|
}
|
</style>
|