<template>
|
<view class="account-view">
|
<!-- 使用通用页面头部组件 -->
|
<PageHeader title="台账详情"
|
@back="goBack" />
|
<!-- 基本信息展示 -->
|
<view class="info-section">
|
<view class="section-title">基本信息</view>
|
<view class="info-grid">
|
<view class="info-item">
|
<text class="info-label">销售合同号</text>
|
<text class="info-value">{{ form.salesContractNo }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">客户名称</text>
|
<text class="info-value">{{ form.customerName }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">业务员</text>
|
<text class="info-value">{{ form.salesman }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">项目名称</text>
|
<text class="info-value">{{ form.projectName }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">签订日期</text>
|
<text class="info-value">{{ form.executionDate }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">年份</text>
|
<text class="info-value">{{ form.year || "-" }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">付款方式</text>
|
<text class="info-value">{{ dictLabel(form.paymentMethod) }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">交货日期</text>
|
<text class="info-value">{{ form.deliveryDate || "-" }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">签单单位</text>
|
<text class="info-value">{{ deptName(form.signingUnitId) }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">办事处</text>
|
<text class="info-value">{{ deptName(form.officeId) }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">组负责人</text>
|
<text class="info-value">{{ userName(form.groupLeaderId) }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">是否开发票</text>
|
<text class="info-value">{{ form.isInvoice === 1 ? "是" : "否" }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">是否中标</text>
|
<text class="info-value">{{ form.isBid === 1 ? "是" : "否" }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">{{ form.isBid === 1 ? "中标价" : "未中标原因" }}</text>
|
<text class="info-value">
|
{{ form.isBid === 1 ? form.bidPrice ?? "-" : form.unbidReason || "-" }}
|
</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">合同原件约定回传日期</text>
|
<text class="info-value">{{ form.contractOriginalReturnDate || "-" }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">录入人</text>
|
<text class="info-value">{{ form.entryPersonName }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">录入日期</text>
|
<text class="info-value">{{ form.entryDate }}</text>
|
</view>
|
<view v-if="form.remarks"
|
class="info-item remarks-item">
|
<text class="info-label">备注</text>
|
<text class="info-value">{{ form.remarks }}</text>
|
</view>
|
</view>
|
</view>
|
<!-- 产品信息展示 -->
|
<view class="product-section"
|
v-if="productData && productData.length > 0">
|
<view class="section-title">产品信息</view>
|
<view class="product-card"
|
v-for="(product, idx) in productData"
|
:key="idx">
|
<view class="product-header">
|
<view class="product-title">
|
<!-- 替换 van-icon 为 u-icon -->
|
<u-icon name="file-text"
|
color="#2979ff"
|
size="15" />
|
<text class="product-productCategory">产品 {{ idx + 1 }}</text>
|
</view>
|
</view>
|
<view class="product-info">
|
<view class="info-grid">
|
<view class="info-item">
|
<text class="info-label">产品大类</text>
|
<text class="info-value">{{ product.productCategory }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">规格型号</text>
|
<text class="info-value">{{ product.specificationModel }}</text>
|
</view>
|
<!-- <view class="info-item">
|
<text class="info-label">绑定机器</text>
|
<text class="info-value">{{ product.speculativeTradingName }}</text>
|
</view> -->
|
<view class="info-item">
|
<text class="info-label">单位</text>
|
<text class="info-value">{{ product.unit }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">税率(%)</text>
|
<text class="info-value">{{ product.taxRate }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">含税单价(元)</text>
|
<text class="info-value highlight">{{ product.taxInclusiveUnitPrice }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">数量</text>
|
<text class="info-value highlight">{{ product.quantity }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">含税总价(元)</text>
|
<text class="info-value highlight">{{ product.taxInclusiveTotalPrice }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">不含税总价(元)</text>
|
<text class="info-value highlight">{{ product.taxExclusiveTotalPrice }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">发票类型</text>
|
<text class="info-value">{{ product.invoiceType }}</text>
|
</view>
|
</view>
|
</view>
|
</view>
|
</view>
|
<view v-else
|
class="no-product">
|
<text>暂无产品信息</text>
|
</view>
|
<!-- 需求五.4:签约金额 = 含税单价 × 数量,按产品行汇总(对齐管理端 summarizeMainTable) -->
|
<view v-if="productData.length > 0"
|
class="product-summary">
|
<view class="summary-row">
|
<text class="summary-label">签约金额合计(元)</text>
|
<text class="summary-value highlight">{{ productTotals.taxInclusive }}</text>
|
</view>
|
<view class="summary-row">
|
<text class="summary-label">不含税总价合计(元)</text>
|
<text class="summary-value">{{ productTotals.taxExclusive }}</text>
|
</view>
|
</view>
|
</view>
|
</template>
|
|
<script setup>
|
import { computed, onMounted, ref } from "vue";
|
import { getSalesLedgerWithProducts } from "@/api/salesManagement/salesLedger";
|
import { getDept } from "@/api/collaborativeApproval/approvalProcess";
|
import { userListNoPageByTenantId } from "@/api/system/user";
|
import { useDict } from "@/utils/dict";
|
import PageHeader from "@/components/PageHeader.vue";
|
|
const { checkout_payment } = useDict("checkout_payment");
|
|
// 获取页面参数
|
const editData = ref(null);
|
|
const form = ref({
|
id: "",
|
salesContractNo: "",
|
customerId: "",
|
customerName: "",
|
projectName: "",
|
executionDate: "",
|
paymentMethod: "",
|
entryPerson: "",
|
entryPersonName: "",
|
entryDate: "",
|
salesman: "",
|
});
|
|
// 产品数据
|
const productData = ref([]);
|
const deptOptions = ref([]);
|
const userOptions = ref([]);
|
|
const dictLabel = value => {
|
if (value === undefined || value === null || value === "") return "-";
|
const matched = (checkout_payment.value || []).find(
|
item => String(item.value) === String(value)
|
);
|
return matched ? matched.label : String(value);
|
};
|
|
// 后端只存 id,只读页需要自己反查部门 / 员工名称
|
const deptName = id =>
|
deptOptions.value.find(item => String(item.value) === String(id))?.name ||
|
"-";
|
const userName = id =>
|
userOptions.value.find(item => String(item.value) === String(id))?.name ||
|
"-";
|
|
const productTotals = computed(() => {
|
const sumBy = key =>
|
(productData.value || [])
|
.reduce((sum, row) => sum + (Number(row?.[key]) || 0), 0)
|
.toFixed(2);
|
return {
|
taxInclusive: sumBy("taxInclusiveTotalPrice"),
|
taxExclusive: sumBy("taxExclusiveTotalPrice"),
|
};
|
});
|
|
// 返回上一页
|
const goBack = () => {
|
// 清理本地存储的数据
|
uni.removeStorageSync("editData");
|
uni.navigateBack();
|
};
|
|
// 填充表单数据
|
const fillFormData = () => {
|
if (!editData.value) return;
|
|
// 获取完整的产品信息
|
getSalesLedgerWithProducts({ id: editData.value.id, type: 1 }).then(res => {
|
productData.value = res.productData || [];
|
form.value = { ...res };
|
});
|
};
|
|
const loadOrgOptions = async () => {
|
const [depts, users] = await Promise.all([
|
getDept().catch(() => ({})),
|
userListNoPageByTenantId().catch(() => ({})),
|
]);
|
deptOptions.value = (depts?.data || []).map(item => ({
|
name: item.deptName,
|
value: item.deptId,
|
}));
|
const rows = users?.data || [];
|
userOptions.value = (Array.isArray(rows) ? rows : []).map(item => ({
|
name: item.nickName || item.userName || `用户${item.userId}`,
|
value: item.userId,
|
}));
|
};
|
|
onMounted(() => {
|
loadOrgOptions();
|
// 获取编辑数据并填充表单
|
const editDataStr = uni.getStorageSync("editData");
|
if (editDataStr) {
|
try {
|
editData.value = JSON.parse(editDataStr);
|
// 使用 nextTick 确保数据加载完成后再填充
|
setTimeout(() => {
|
fillFormData();
|
}, 100);
|
} catch (error) {
|
console.error("解析编辑数据失败:", error);
|
}
|
}
|
});
|
</script>
|
|
<style scoped lang="scss">
|
.account-view {
|
min-height: 100vh;
|
background: #f8f9fa;
|
padding-bottom: 2rem;
|
}
|
|
.header {
|
display: flex;
|
align-items: center;
|
background: #fff;
|
padding: 1rem 1.25rem;
|
border-bottom: 0.0625rem solid #f0f0f0;
|
position: sticky;
|
top: 0;
|
z-index: 100;
|
}
|
|
.title {
|
flex: 1;
|
text-align: center;
|
font-size: 1.125rem;
|
font-weight: 600;
|
color: #333;
|
}
|
|
.info-section {
|
background: #fff;
|
margin: 1rem;
|
padding: 1rem;
|
border-radius: 0.5rem;
|
box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.04);
|
}
|
|
.product-section {
|
background: #fff;
|
margin: 1rem;
|
padding: 1rem;
|
border-radius: 0.5rem;
|
box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.04);
|
}
|
|
.section-title {
|
font-size: 1rem;
|
font-weight: 600;
|
color: #333;
|
margin-bottom: 1rem;
|
padding-bottom: 0.5rem;
|
border-bottom: 0.0625rem solid #e8e8e8;
|
}
|
|
.info-grid {
|
display: grid;
|
grid-template-columns: 1fr 1fr;
|
gap: 0.75rem;
|
}
|
|
.info-item {
|
display: flex;
|
flex-direction: column;
|
gap: 0.25rem;
|
}
|
|
.info-label {
|
font-size: 0.75rem;
|
color: #666;
|
font-weight: 400;
|
}
|
|
.info-value {
|
font-size: 0.875rem;
|
color: #333;
|
font-weight: 500;
|
}
|
|
.info-value.highlight {
|
color: #2979ff;
|
font-weight: 600;
|
}
|
|
.product-card {
|
background: #f8f9fa;
|
border-radius: 0.5rem;
|
padding: 1rem;
|
margin-bottom: 1rem;
|
border: 0.0625rem solid #e8e8e8;
|
}
|
|
.product-header {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
margin-bottom: 1rem;
|
padding-bottom: 0.5rem;
|
border-bottom: 0.0625rem solid #e8e8e8;
|
}
|
|
.product-title {
|
display: flex;
|
align-items: center;
|
gap: 0.5rem;
|
}
|
|
.product-productCategory {
|
font-size: 0.875rem;
|
font-weight: 500;
|
color: #333;
|
}
|
|
.product-info .info-grid {
|
grid-template-columns: 1fr 1fr;
|
gap: 0.5rem;
|
}
|
|
.no-product {
|
text-align: center;
|
padding: 2rem;
|
color: #999;
|
font-size: 0.875rem;
|
}
|
|
.remarks-item {
|
grid-column: 1 / -1;
|
}
|
|
.product-summary {
|
background: #fff;
|
margin: 1rem;
|
padding: 1rem;
|
border-radius: 0.5rem;
|
box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.04);
|
display: flex;
|
flex-direction: column;
|
gap: 0.75rem;
|
}
|
|
.summary-row {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
}
|
|
.summary-label {
|
font-size: 0.8125rem;
|
color: #666;
|
}
|
|
.summary-value {
|
font-size: 0.875rem;
|
font-weight: 600;
|
color: #333;
|
}
|
|
.summary-value.highlight {
|
color: #2979ff;
|
}
|
</style>
|