From 5b76649a97e92e3f02cdbb71e871443524fd0348 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期二, 27 一月 2026 14:12:04 +0800
Subject: [PATCH] 销售台账增加发货列表和发货功能
---
src/api/salesManagement/salesLedger.js | 10
src/pages.json | 14
src/pages/sales/salesAccount/goOut.vue | 657 +++++++++++++++++++
src/pages/sales/salesAccount/index.vue | 386 +++++-----
src/pages/sales/salesAccount/out.vue | 407 +++++++++++
src/pages/procurementManagement/paymentLedger/detail.vue | 517 +++++++-------
6 files changed, 1,555 insertions(+), 436 deletions(-)
diff --git a/src/api/salesManagement/salesLedger.js b/src/api/salesManagement/salesLedger.js
index a6125f3..3297637 100644
--- a/src/api/salesManagement/salesLedger.js
+++ b/src/api/salesManagement/salesLedger.js
@@ -125,3 +125,13 @@
params: query
})
}
+
+
+// 鏂板鍙戣揣淇℃伅
+export function addShippingInfo(data) {
+ return request({
+ url: "/shippingInfo/add",
+ method: "post",
+ data,
+ });
+}
diff --git a/src/pages.json b/src/pages.json
index 09bebad..e93e39d 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -58,6 +58,20 @@
}
},
{
+ "path": "pages/sales/salesAccount/out",
+ "style": {
+ "navigationBarTitleText": "鍙戣揣鐘舵��",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/sales/salesAccount/goOut",
+ "style": {
+ "navigationBarTitleText": "鍙戣揣",
+ "navigationStyle": "custom"
+ }
+ },
+ {
"path": "pages/sales/salesAccount/detail",
"style": {
"navigationBarTitleText": "淇敼鍙拌处",
diff --git a/src/pages/procurementManagement/paymentLedger/detail.vue b/src/pages/procurementManagement/paymentLedger/detail.vue
index 915ee5d..00ccf8b 100644
--- a/src/pages/procurementManagement/paymentLedger/detail.vue
+++ b/src/pages/procurementManagement/paymentLedger/detail.vue
@@ -1,294 +1,305 @@
<template>
- <view class="receipt-payment-detail">
- <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="渚涘簲鍟嗗線鏉ヨ鎯�" @back="goBack" />
-
- <!-- 缁熻淇℃伅 -->
- <view class="summary-info" v-if="tableData.length > 0">
- <view class="summary-item">
- <text class="summary-label">鎬昏褰曟暟</text>
- <text class="summary-value">{{ tableData.length }}</text>
- </view>
- <view class="summary-item">
- <text class="summary-label">寮�绁ㄦ�婚噾棰�</text>
- <text class="summary-value">{{ formatAmount(invoiceTotal) }}</text>
- </view>
- <view class="summary-item">
- <text class="summary-label">鍥炴鎬婚噾棰�</text>
- <text class="summary-value highlight">{{ formatAmount(receiptTotal) }}</text>
- </view>
- <view class="summary-item">
- <text class="summary-label">搴旀敹鎬婚噾棰�</text>
- <text class="summary-value danger">{{ formatAmount(unReceiptTotal) }}</text>
- </view>
- </view>
-
- <!-- 鍥炴璁板綍鏄庣粏鍒楄〃 -->
- <view class="detail-list" v-if="tableData.length > 0">
- <view v-for="(item, index) in tableData" :key="index" class="detail-item">
- <view class="item-header">
- <view class="item-left">
- <view class="record-icon">
- <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
- </view>
- <text class="item-index">{{ index + 1 }}</text>
- </view>
- <view class="item-date">{{ item.happenTime }}</view>
- </view>
- <up-divider></up-divider>
- <view class="item-details">
- <view class="detail-row">
- <text class="detail-label">鍙戠エ閲戦(鍏�)</text>
- <text class="detail-value">{{ formatAmount(item.invoiceAmount) }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">浠樻閲戦(鍏�)</text>
- <text class="detail-value highlight">{{ formatAmount(item.currentPaymentAmount) }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">搴斾粯閲戦(鍏�)</text>
- <text class="detail-value danger">{{ formatAmount(item.payableAmount) }}</text>
- </view>
- </view>
- </view>
- </view>
- <view v-else class="no-data">
- <text>鏆傛棤鍥炴璁板綍</text>
- </view>
- </view>
+ <view class="receipt-payment-detail">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="渚涘簲鍟嗗線鏉ヨ鎯�"
+ @back="goBack" />
+ <!-- 缁熻淇℃伅 -->
+ <view class="summary-info"
+ v-if="tableData.length > 0">
+ <view class="summary-item">
+ <text class="summary-label">鎬昏褰曟暟</text>
+ <text class="summary-value">{{ tableData.length }}</text>
+ </view>
+ <view class="summary-item">
+ <text class="summary-label">寮�绁ㄦ�婚噾棰�</text>
+ <text class="summary-value">{{ formatAmount(invoiceTotal) }}</text>
+ </view>
+ <view class="summary-item">
+ <text class="summary-label">鍥炴鎬婚噾棰�</text>
+ <text class="summary-value highlight">{{ formatAmount(receiptTotal) }}</text>
+ </view>
+ <view class="summary-item">
+ <text class="summary-label">搴旀敹鎬婚噾棰�</text>
+ <text class="summary-value danger">{{ formatAmount(unReceiptTotal) }}</text>
+ </view>
+ </view>
+ <!-- 鍥炴璁板綍鏄庣粏鍒楄〃 -->
+ <view class="detail-list"
+ v-if="tableData.length > 0">
+ <view v-for="(item, index) in tableData"
+ :key="index"
+ class="detail-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="record-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-index">{{ index + 1 }}</text>
+ </view>
+ <view class="item-date">{{ item.happenTime }}</view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">鍙戠エ閲戦(鍏�)</text>
+ <text class="detail-value">{{ formatAmount(item.invoiceAmount) }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">浠樻閲戦(鍏�)</text>
+ <text class="detail-value highlight">{{ formatAmount(item.currentPaymentAmount) }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">搴斾粯閲戦(鍏�)</text>
+ <text class="detail-value danger">{{ formatAmount(item.payableAmount) }}</text>
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤鍥炴璁板綍</text>
+ </view>
+ </view>
</template>
<script setup>
-import { ref, computed, onMounted } from 'vue';
-import { onShow } from '@dcloudio/uni-app';
-import {paymentLedgerList, paymentRecordList} from "@/api/procurementManagement/paymentLedger";
+ import { ref, computed, onMounted } from "vue";
+ import { onShow } from "@dcloudio/uni-app";
+ import {
+ paymentLedgerList,
+ paymentRecordList,
+ } from "@/api/procurementManagement/paymentLedger";
-// 瀹㈡埛淇℃伅
-const supplierId = ref('');
+ // 瀹㈡埛淇℃伅
+ const supplierId = ref("");
-// 琛ㄦ牸鏁版嵁
-const tableData = ref([]);
+ // 琛ㄦ牸鏁版嵁
+ const tableData = ref([]);
-const invoiceTotal = computed(() => {
- return tableData.value.reduce((sum, item) => {
- return sum + (parseFloat(item.invoiceAmount) || 0);
- }, 0);
-});
+ const invoiceTotal = computed(() => {
+ return tableData.value.reduce((sum, item) => {
+ return sum + (parseFloat(item.invoiceAmount) || 0);
+ }, 0);
+ });
-const receiptTotal = computed(() => {
- return tableData.value.reduce((sum, item) => {
- return sum + (parseFloat(item.receiptAmount) || 0);
- }, 0);
-});
+ const receiptTotal = computed(() => {
+ return tableData.value.reduce((sum, item) => {
+ return sum + (parseFloat(item.receiptAmount) || 0);
+ }, 0);
+ });
-const unReceiptTotal = computed(() => {
- return tableData.value.reduce((sum, item) => {
- return sum + (parseFloat(item.unReceiptAmount) || 0);
- }, 0);
-});
+ const unReceiptTotal = computed(() => {
+ return tableData.value.reduce((sum, item) => {
+ return sum + (parseFloat(item.unReceiptAmount) || 0);
+ }, 0);
+ });
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
- uni.removeStorageSync('supplierId')
- uni.navigateBack();
-};
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.removeStorageSync("supplierId");
+ uni.navigateBack();
+ };
-// 鑾峰彇椤甸潰鍙傛暟
-const getPageParams = () => {
- // 浠庢湰鍦板瓨鍌ㄨ幏鍙栦緵搴斿晢ID
- const storedSupplierId = uni.getStorageSync('supplierId');
- if (storedSupplierId) {
- supplierId.value = storedSupplierId;
- }
-};
+ // 鑾峰彇椤甸潰鍙傛暟
+ const getPageParams = () => {
+ // 浠庢湰鍦板瓨鍌ㄨ幏鍙栦緵搴斿晢ID
+ const storedSupplierId = uni.getStorageSync("supplierId");
+ if (storedSupplierId) {
+ supplierId.value = storedSupplierId;
+ }
+ };
-// 鏌ヨ鍒楄〃
-const getList = () => {
- if (!supplierId.value) {
- uni.showToast({
- title: '瀹㈡埛淇℃伅缂哄け',
- icon: 'error'
- });
- return;
- }
- showLoadingToast('鍔犺浇涓�...')
- paymentRecordList(supplierId.value).then((res) => {
- tableData.value = res.data;
- closeToast()
- }).catch(() => {
- closeToast()
- uni.showToast({
- title: '鏌ヨ澶辫触',
- icon: 'error'
- });
- });
-};
+ // 鏌ヨ鍒楄〃
+ const getList = () => {
+ if (!supplierId.value) {
+ uni.showToast({
+ title: "瀹㈡埛淇℃伅缂哄け",
+ icon: "error",
+ });
+ return;
+ }
+ showLoadingToast("鍔犺浇涓�...");
+ paymentRecordList(supplierId.value)
+ .then(res => {
+ tableData.value = res.data;
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ uni.showToast({
+ title: "鏌ヨ澶辫触",
+ icon: "error",
+ });
+ });
+ };
-// 鏍煎紡鍖栭噾棰�
-const formatAmount = (amount) => {
- return amount ? parseFloat(amount).toFixed(2) : '0.00';
-};
+ // 鏍煎紡鍖栭噾棰�
+ const formatAmount = amount => {
+ return amount ? parseFloat(amount).toFixed(2) : "0.00";
+ };
-// 鏄剧ず鍔犺浇鎻愮ず
-const showLoadingToast = (message) => {
- uni.showLoading({
- title: message,
- mask: true
- });
-};
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
-// 鍏抽棴鎻愮ず
-const closeToast = () => {
- uni.hideLoading();
-};
+ // 鍏抽棴鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
-onMounted(() => {
- // 椤甸潰鍔犺浇鏃惰幏鍙栧弬鏁板苟鍒锋柊鍒楄〃
- getPageParams();
- getList();
-});
+ onMounted(() => {
+ // 椤甸潰鍔犺浇鏃惰幏鍙栧弬鏁板苟鍒锋柊鍒楄〃
+ getPageParams();
+ getList();
+ });
</script>
<style scoped lang="scss">
-.receipt-payment-detail {
- min-height: 100vh;
- background: #f8f9fa;
- position: relative;
-}
+ .receipt-payment-detail {
+ min-height: 100vh;
+ background: #f8f9fa;
+ position: relative;
+ }
-.u-divider {
- margin: 0 !important;
-}
+ .u-divider {
+ margin: 0 !important;
+ }
-.summary-info {
- background: #ffffff;
- margin: 20px 20px 0 20px;
- border-radius: 12px;
- padding: 16px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
-}
+ .summary-info {
+ background: #ffffff;
+ margin: 20px 20px 0 20px;
+ border-radius: 12px;
+ padding: 16px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+ }
-.summary-item {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 8px;
-
- &:last-child {
- margin-bottom: 0;
- }
-}
+ .summary-item {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 8px;
-.summary-label {
- font-size: 14px;
- color: #666;
-}
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
-.summary-value {
- font-size: 14px;
- color: #333;
- font-weight: 500;
-}
+ .summary-label {
+ font-size: 14px;
+ color: #666;
+ }
-.summary-value.highlight {
- color: #2979ff;
- font-weight: 600;
-}
+ .summary-value {
+ font-size: 14px;
+ color: #333;
+ font-weight: 500;
+ }
-.summary-value.danger {
- color: #ff4757;
- font-weight: 600;
-}
+ .summary-value.highlight {
+ color: #2979ff;
+ font-weight: 600;
+ }
-.detail-list {
- padding: 20px;
-}
+ .summary-value.danger {
+ color: #ff4757;
+ font-weight: 600;
+ }
-.detail-item {
- background: #ffffff;
- border-radius: 12px;
- margin-bottom: 16px;
- overflow: hidden;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
- padding: 0 16px;
-}
+ .detail-list {
+ padding: 20px;
+ }
-.item-header {
- padding: 10px 0;
- display: flex;
- align-items: center;
- justify-content: space-between;
-}
+ .detail-item {
+ background: #ffffff;
+ border-radius: 12px;
+ margin-bottom: 16px;
+ overflow: hidden;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+ padding: 0 16px;
+ }
-.item-left {
- display: flex;
- align-items: center;
- gap: 8px;
-}
+ .item-header {
+ padding: 10px 0;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
-.record-icon {
- width: 24px;
- height: 24px;
- background: #2979ff;
- border-radius: 4px;
- display: flex;
- align-items: center;
- justify-content: center;
-}
+ .item-left {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ }
-.item-index {
- font-size: 14px;
- color: #333;
- font-weight: 500;
-}
+ .record-icon {
+ width: 24px;
+ height: 24px;
+ background: #2979ff;
+ border-radius: 4px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
-.item-date {
- font-size: 12px;
- color: #666;
-}
+ .item-index {
+ font-size: 14px;
+ color: #333;
+ font-weight: 500;
+ }
-.item-details {
- padding: 16px 0;
-}
+ .item-date {
+ font-size: 12px;
+ color: #666;
+ }
-.detail-row {
- display: flex;
- align-items: flex-end;
- justify-content: space-between;
- margin-bottom: 8px;
-
- &:last-child {
- margin-bottom: 0;
- }
-}
+ .item-details {
+ padding: 16px 0;
+ }
-.detail-label {
- font-size: 12px;
- color: #777777;
- min-width: 60px;
-}
+ .detail-row {
+ display: flex;
+ align-items: flex-end;
+ justify-content: space-between;
+ margin-bottom: 8px;
-.detail-value {
- font-size: 12px;
- color: #000000;
- text-align: right;
- flex: 1;
- margin-left: 16px;
-}
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
-.detail-value.highlight {
- color: #2979ff;
- font-weight: 500;
-}
+ .detail-label {
+ font-size: 12px;
+ color: #777777;
+ min-width: 60px;
+ }
-.detail-value.danger {
- color: #ff4757;
- font-weight: 500;
-}
+ .detail-value {
+ font-size: 12px;
+ color: #000000;
+ text-align: right;
+ flex: 1;
+ margin-left: 16px;
+ }
-.no-data {
- padding: 40px 0;
- text-align: center;
- color: #999;
-}
+ .detail-value.highlight {
+ color: #2979ff;
+ font-weight: 500;
+ }
+
+ .detail-value.danger {
+ color: #ff4757;
+ font-weight: 500;
+ }
+
+ .no-data {
+ padding: 40px 0;
+ text-align: center;
+ color: #999;
+ }
</style>
diff --git a/src/pages/sales/salesAccount/goOut.vue b/src/pages/sales/salesAccount/goOut.vue
new file mode 100644
index 0000000..9980e5f
--- /dev/null
+++ b/src/pages/sales/salesAccount/goOut.vue
@@ -0,0 +1,657 @@
+<template>
+ <view class="account-detail">
+ <PageHeader title="鍙戣揣"
+ @back="goBack" />
+ <!-- 琛ㄥ崟鍖哄煙 -->
+ <u-form ref="formRef"
+ @submit="submitForm"
+ :rules="rules"
+ :model="form"
+ label-width="140rpx">
+ <u-form-item prop="typeValue"
+ label="鍙戣揣绫诲瀷"
+ required>
+ <u-input v-model="typeValue"
+ readonly
+ placeholder="璇烽�夋嫨鍙戣揣鏂瑰紡"
+ @click="showPicker = true" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="showPicker = true"></up-icon>
+ </template>
+ </u-form-item>
+ </u-form>
+ <!-- 閫夋嫨鍣ㄥ脊绐� -->
+ <up-action-sheet :show="showPicker"
+ :actions="productOptions"
+ title="鍙戣揣鏂瑰紡"
+ @select="onConfirm"
+ @close="showPicker = false" />
+ <!-- 瀹℃牳娴佺▼鍖哄煙 -->
+ <view class="approval-process">
+ <view class="approval-header">
+ <text class="approval-title">瀹℃牳娴佺▼</text>
+ <text class="approval-desc">姣忎釜姝ラ鍙兘閫夋嫨涓�涓鎵逛汉</text>
+ </view>
+ <view class="approval-steps">
+ <view v-for="(step, stepIndex) in approverNodes"
+ :key="stepIndex"
+ class="approval-step">
+ <view class="step-dot"></view>
+ <view class="step-title">
+ <text>瀹℃壒浜�</text>
+ </view>
+ <view class="approver-container">
+ <view v-if="step.nickName"
+ class="approver-item">
+ <view class="approver-avatar">
+ <text class="avatar-text">{{ step.nickName.charAt(0) }}</text>
+ <view class="status-dot"></view>
+ </view>
+ <view class="approver-info">
+ <text class="approver-name">{{ step.nickName }}</text>
+ </view>
+ <view class="delete-approver-btn"
+ @click="removeApprover(stepIndex)">脳</view>
+ </view>
+ <view v-else
+ class="add-approver-btn"
+ @click="addApprover(stepIndex)">
+ <view class="add-circle">+</view>
+ <text class="add-label">閫夋嫨瀹℃壒浜�</text>
+ </view>
+ </view>
+ <view class="step-line"
+ v-if="stepIndex < approverNodes.length - 1"></view>
+ <view class="delete-step-btn"
+ v-if="approverNodes.length > 1"
+ @click="removeApprovalStep(stepIndex)">鍒犻櫎鑺傜偣</view>
+ </view>
+ </view>
+ <view class="add-step-btn">
+ <u-button icon="plus"
+ plain
+ type="primary"
+ style="width: 100%"
+ @click="addApprovalStep">鏂板鑺傜偣</u-button>
+ </view>
+ </view>
+ <!-- 搴曢儴鎸夐挳 -->
+ <view class="footer-btns">
+ <u-button class="cancel-btn"
+ @click="goBack">鍙栨秷</u-button>
+ <u-button class="save-btn"
+ @click="submitForm">鍙戣揣</u-button>
+ </view>
+ </view>
+</template>
+
+<script setup>
+ import { ref, onMounted, onUnmounted, reactive, toRefs } from "vue";
+ import PageHeader from "@/components/PageHeader.vue";
+ import { addShippingInfo } from "@/api/salesManagement/salesLedger";
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
+ import { userListNoPageByTenantId } from "@/api/system/user";
+
+ const data = reactive({
+ form: {
+ approveTime: "",
+ approveId: "",
+ approveUser: "",
+ approveUserName: "",
+ approveDeptName: "",
+ approveDeptId: "",
+ approveReason: "",
+ checkResult: "",
+ tempFileIds: [],
+ approverList: [], // 鏂板瀛楁锛屽瓨鍌ㄦ墍鏈夎妭鐐圭殑瀹℃壒浜篿d
+ startDate: "",
+ endDate: "",
+ location: "",
+ price: "",
+ },
+ rules: {
+ typeValue: [{ required: false, message: "璇烽�夋嫨", trigger: "change" }],
+ },
+ });
+ const { form, rules } = toRefs(data);
+ const showPicker = ref(false);
+ const productOptions = ref([
+ {
+ value: "璐ц溅",
+ name: "璐ц溅",
+ },
+ {
+ value: "蹇��",
+ name: "蹇��",
+ },
+ ]);
+ const operationType = ref("");
+ const currentApproveStatus = ref("");
+ const approverNodes = ref([]);
+ const userList = ref([]);
+ const formRef = ref(null);
+ const approveType = ref(0);
+ const goOutData = ref({});
+ onMounted(async () => {
+ try {
+ userListNoPageByTenantId().then(res => {
+ userList.value = res.data;
+ });
+ // 浠庢湰鍦板瓨鍌ㄨ幏鍙栧彂璐ц鎯�
+ goOutData.value = JSON.parse(uni.getStorageSync("goOutData"));
+ console.log(goOutData.value, "goOutData.value");
+
+ // 鍒濆鍖栧鎵规祦绋嬭妭鐐癸紝榛樿涓�涓妭鐐�
+ approverNodes.value = [{ id: 1, userId: null }];
+
+ // 鐩戝惉鑱旂郴浜洪�夋嫨浜嬩欢
+ uni.$on("selectContact", handleSelectContact);
+ } catch (error) {
+ console.error("鑾峰彇澶辫触:", error);
+ }
+ });
+
+ onUnmounted(() => {
+ // 绉婚櫎浜嬩欢鐩戝惉
+ uni.$off("selectContact", handleSelectContact);
+ });
+ const typeValue = ref("璐ц溅");
+ const onConfirm = item => {
+ // 璁剧疆閫変腑鐨勯儴闂�
+ typeValue.value = item.name;
+ showPicker.value = false;
+ };
+
+ const goBack = () => {
+ // 娓呴櫎鏈湴瀛樺偍鐨勬暟鎹�
+ uni.removeStorageSync("operationType");
+ uni.removeStorageSync("invoiceLedgerEditRow");
+ uni.removeStorageSync("approveType");
+ uni.navigateBack();
+ };
+
+ const submitForm = () => {
+ // 妫�鏌ユ瘡涓鎵规楠ゆ槸鍚﹂兘鏈夊鎵逛汉
+ const hasEmptyStep = approverNodes.value.some(step => !step.nickName);
+ if (hasEmptyStep) {
+ showToast("璇蜂负姣忎釜瀹℃壒姝ラ閫夋嫨瀹℃壒浜�");
+ return;
+ }
+ formRef.value
+ .validate()
+ .then(valid => {
+ if (valid) {
+ // 琛ㄥ崟鏍¢獙閫氳繃锛屽彲浠ユ彁浜ゆ暟鎹�
+ // 鏀堕泦鎵�鏈夎妭鐐圭殑瀹℃壒浜篿d
+ console.log("approverNodes---", approverNodes.value);
+ const approveUserIds = approverNodes.value
+ .map(node => node.userId)
+ .join(",");
+ const params = {
+ salesLedgerId: goOutData.value.salesLedgerId,
+ salesLedgerProductId: goOutData.value.id,
+ type: typeValue.value,
+ approveUserIds,
+ };
+ console.log(params, "params");
+
+ addShippingInfo(params).then(res => {
+ showToast("鍙戣揣鎴愬姛");
+ setTimeout(() => {
+ goBack();
+ }, 500);
+ });
+ }
+ })
+ .catch(error => {
+ console.error("琛ㄥ崟鏍¢獙澶辫触:", error);
+ // 灏濊瘯鑾峰彇鍏蜂綋鐨勯敊璇瓧娈�
+ if (error && error.errors) {
+ const firstError = error.errors[0];
+ if (firstError) {
+ uni.showToast({
+ title: firstError.message || "琛ㄥ崟鏍¢獙澶辫触锛岃妫�鏌ュ繀濉」",
+ icon: "none",
+ });
+ return;
+ }
+ }
+ // 鏄剧ず閫氱敤閿欒淇℃伅
+ uni.showToast({
+ title: "琛ㄥ崟鏍¢獙澶辫触锛岃妫�鏌ュ繀濉」",
+ icon: "none",
+ });
+ });
+ };
+
+ // 澶勭悊鑱旂郴浜洪�夋嫨缁撴灉
+ const handleSelectContact = data => {
+ const { stepIndex, contact } = data;
+ // 灏嗛�変腑鐨勮仈绯讳汉璁剧疆涓哄搴斿鎵规楠ょ殑瀹℃壒浜�
+ approverNodes.value[stepIndex].userId = contact.userId;
+ approverNodes.value[stepIndex].nickName = contact.nickName;
+ };
+
+ const addApprover = stepIndex => {
+ // 璺宠浆鍒拌仈绯讳汉閫夋嫨椤甸潰
+ uni.setStorageSync("stepIndex", stepIndex);
+ uni.navigateTo({
+ url: "/pages/cooperativeOffice/collaborativeApproval/contactSelect",
+ });
+ };
+
+ const addApprovalStep = () => {
+ // 娣诲姞鏂扮殑瀹℃壒姝ラ
+ approverNodes.value.push({ userId: null, nickName: null });
+ };
+
+ const removeApprover = stepIndex => {
+ // 绉婚櫎瀹℃壒浜�
+ approverNodes.value[stepIndex].userId = null;
+ approverNodes.value[stepIndex].nickName = null;
+ };
+
+ const removeApprovalStep = stepIndex => {
+ // 纭繚鑷冲皯淇濈暀涓�涓鎵规楠�
+ if (approverNodes.value.length > 1) {
+ approverNodes.value.splice(stepIndex, 1);
+ } else {
+ uni.showToast({
+ title: "鑷冲皯闇�瑕佷竴涓鎵规楠�",
+ icon: "none",
+ });
+ }
+ };
+</script>
+
+<style scoped lang="scss">
+ @import "@/static/scss/form-common.scss";
+
+ .approval-process {
+ background: #fff;
+ margin: 16px;
+ border-radius: 16px;
+ padding: 16px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
+ }
+
+ .approval-header {
+ margin-bottom: 16px;
+ }
+
+ .approval-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #333;
+ display: block;
+ margin-bottom: 4px;
+ }
+
+ .approval-desc {
+ font-size: 12px;
+ color: #999;
+ }
+
+ /* 鏍峰紡澧炲己涓衡�滅畝娲佸皬鍦嗗湀椋庢牸鈥� */
+ .approval-steps {
+ padding-left: 22px;
+ position: relative;
+
+ &::before {
+ content: "";
+ position: absolute;
+ left: 11px;
+ top: 40px;
+ bottom: 40px;
+ width: 2px;
+ background: linear-gradient(
+ to bottom,
+ #e6f7ff 0%,
+ #bae7ff 50%,
+ #91d5ff 100%
+ );
+ border-radius: 1px;
+ }
+ }
+
+ .approval-step {
+ position: relative;
+ margin-bottom: 24px;
+
+ &::before {
+ content: "";
+ position: absolute;
+ left: -18px;
+ top: 14px; // 浠� 8px 璋冩暣涓� 14px锛屼笌鏂囧瓧涓績瀵归綈
+ width: 12px;
+ height: 12px;
+ background: #fff;
+ border: 3px solid #006cfb;
+ border-radius: 50%;
+ z-index: 2;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+ }
+ }
+
+ .step-title {
+ top: 12px;
+ margin-bottom: 12px;
+ position: relative;
+ margin-left: 6px;
+ }
+
+ .step-title text {
+ font-size: 14px;
+ color: #666;
+ background: #f0f0f0;
+ padding: 4px 12px;
+ border-radius: 12px;
+ position: relative;
+ line-height: 1.4; // 纭繚鏂囧瓧琛岄珮涓�鑷�
+ }
+
+ .approver-item {
+ display: flex;
+ align-items: center;
+ background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
+ border-radius: 16px;
+ padding: 16px;
+ gap: 12px;
+ position: relative;
+ border: 1px solid #e6f7ff;
+ box-shadow: 0 4px 12px rgba(0, 108, 251, 0.08);
+ transition: all 0.3s ease;
+ }
+
+ .approver-avatar {
+ width: 48px;
+ height: 48px;
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
+ }
+
+ .avatar-text {
+ color: #fff;
+ font-size: 18px;
+ font-weight: 600;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
+ }
+
+ .approver-info {
+ flex: 1;
+ position: relative;
+ }
+
+ .approver-name {
+ display: block;
+ font-size: 16px;
+ color: #333;
+ font-weight: 500;
+ position: relative;
+ }
+
+ .approver-dept {
+ font-size: 12px;
+ color: #999;
+ background: rgba(0, 108, 251, 0.05);
+ padding: 2px 8px;
+ border-radius: 8px;
+ display: inline-block;
+ position: relative;
+
+ &::before {
+ content: "";
+ position: absolute;
+ left: 4px;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 2px;
+ height: 2px;
+ background: #006cfb;
+ border-radius: 50%;
+ }
+ }
+
+ .delete-approver-btn {
+ font-size: 16px;
+ color: #ff4d4f;
+ background: linear-gradient(
+ 135deg,
+ rgba(255, 77, 79, 0.1) 0%,
+ rgba(255, 77, 79, 0.05) 100%
+ );
+ width: 28px;
+ height: 28px;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: all 0.3s ease;
+ position: relative;
+ }
+
+ .add-approver-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: linear-gradient(135deg, #f0f8ff 0%, #e6f7ff 100%);
+ border: 2px dashed #006cfb;
+ border-radius: 16px;
+ padding: 20px;
+ color: #006cfb;
+ font-size: 14px;
+ position: relative;
+ transition: all 0.3s ease;
+
+ &::before {
+ content: "";
+ position: absolute;
+ left: 50%;
+ top: 50%;
+ transform: translate(-50%, -50%);
+ width: 32px;
+ height: 32px;
+ border: 2px solid #006cfb;
+ border-radius: 50%;
+ opacity: 0;
+ transition: all 0.3s ease;
+ }
+ }
+
+ .delete-step-btn {
+ color: #ff4d4f;
+ font-size: 12px;
+ background: linear-gradient(
+ 135deg,
+ rgba(255, 77, 79, 0.1) 0%,
+ rgba(255, 77, 79, 0.05) 100%
+ );
+ padding: 6px 12px;
+ border-radius: 12px;
+ display: inline-block;
+ position: relative;
+ transition: all 0.3s ease;
+
+ &::before {
+ content: "";
+ position: absolute;
+ left: 6px;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 4px;
+ height: 4px;
+ background: #ff4d4f;
+ border-radius: 50%;
+ }
+ }
+
+ .step-line {
+ display: none; // 闅愯棌鍘熸潵鐨勭嚎鏉★紝浣跨敤浼厓绱犱唬鏇�
+ }
+
+ .add-step-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+ .footer-btns {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: #fff;
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ padding: 0.75rem 0;
+ box-shadow: 0 -0.125rem 0.5rem rgba(0, 0, 0, 0.05);
+ z-index: 1000;
+ }
+
+ .cancel-btn {
+ font-weight: 400;
+ font-size: 1rem;
+ color: #ffffff;
+ width: 6.375rem;
+ background: #c7c9cc;
+ box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
+
+ .save-btn {
+ font-weight: 400;
+ font-size: 1rem;
+ color: #ffffff;
+ width: 14rem;
+ background: linear-gradient(140deg, #00baff 0%, #006cfb 100%);
+ box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
+
+ // 鍔ㄧ敾瀹氫箟
+ @keyframes pulse {
+ 0% {
+ transform: scale(1);
+ opacity: 1;
+ }
+ 50% {
+ transform: scale(1.2);
+ opacity: 0.7;
+ }
+ 100% {
+ transform: scale(1);
+ opacity: 1;
+ }
+ }
+
+ @keyframes rotate {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+ }
+
+ @keyframes ripple {
+ 0% {
+ transform: translate(-50%, -50%) scale(0.8);
+ opacity: 1;
+ }
+ 100% {
+ transform: translate(-50%, -50%) scale(1.6);
+ opacity: 0;
+ }
+ }
+
+ /* 濡傛灉宸叉湁 .step-line锛岃繖閲屾洿绮惧噯瀹氫綅鍒板乏渚т笌灏忓渾鐐瑰榻� */
+ .step-line {
+ position: absolute;
+ left: 4px;
+ top: 48px;
+ width: 2px;
+ height: calc(100% - 48px);
+ background: #e5e7eb;
+ }
+
+ .approver-container {
+ display: flex;
+ align-items: center;
+ background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
+ border-radius: 16px;
+ gap: 12px;
+ padding: 10px 0;
+ background: transparent;
+ border: none;
+ box-shadow: none;
+ }
+
+ .approver-item {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ padding: 8px 10px;
+ background: transparent;
+ border: none;
+ box-shadow: none;
+ border-radius: 0;
+ }
+
+ .approver-avatar {
+ position: relative;
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ background: #f3f4f6;
+ border: 2px solid #e5e7eb;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ animation: none; /* 绂佺敤鏃嬭浆绛夊姩鐢伙紝鍥炲綊绠�娲� */
+ }
+
+ .avatar-text {
+ font-size: 14px;
+ color: #374151;
+ font-weight: 600;
+ }
+
+ .add-approver-btn {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ background: transparent;
+ border: none;
+ box-shadow: none;
+ padding: 0;
+ }
+
+ .add-approver-btn .add-circle {
+ width: 40px;
+ height: 40px;
+ border: 2px dashed #a0aec0;
+ border-radius: 50%;
+ color: #6b7280;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 22px;
+ line-height: 1;
+ }
+
+ .add-approver-btn .add-label {
+ color: #3b82f6;
+ font-size: 14px;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/sales/salesAccount/index.vue b/src/pages/sales/salesAccount/index.vue
index acc8783..d6a8646 100644
--- a/src/pages/sales/salesAccount/index.vue
+++ b/src/pages/sales/salesAccount/index.vue
@@ -1,196 +1,216 @@
<template>
- <view class="sales-account">
- <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="閿�鍞彴璐�" @back="goBack" />
-
- <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
- <view class="search-section">
- <view class="search-bar">
- <view class="search-input">
- <up-input
- class="search-text"
- placeholder="璇疯緭鍏ラ攢鍞悎鍚屽彿鎼滅储"
- v-model="salesContractNo"
- @change="getList"
- clearable
- />
- </view>
- <view class="filter-button" @click="getList">
- <up-icon name="search" size="24" color="#999"></up-icon>
- </view>
- </view>
- </view>
-
- <!-- 閿�鍞彴璐︾�戝竷娴� -->
- <view class="ledger-list" v-if="ledgerList.length > 0">
- <view v-for="(item, index) in ledgerList" :key="index">
- <view class="ledger-item" @click="handleInfo('edit', item)">
- <view class="item-header">
- <view class="item-left">
- <view class="document-icon">
- <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
- </view>
- <text class="item-id">{{ item.salesContractNo }}</text>
- </view>
- <!-- <view class="item-tag">-->
- <!-- <text class="tag-text">{{ item.recorder }}</text>-->
- <!-- </view>-->
- </view>
- <up-divider></up-divider>
-
- <view class="item-details">
- <view class="detail-row">
- <text class="detail-label">瀹㈡埛鍚嶇О</text>
- <text class="detail-value">{{ item.customerName }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">瀹㈡埛鍚堝悓鍙�</text>
- <text class="detail-value">{{ item.customerContractNo }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">涓氬姟鍛�</text>
- <text class="detail-value">{{ item.salesman }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">椤圭洰鍚嶇О</text>
- <text class="detail-value">{{ item.projectName }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">浠樻鏂瑰紡</text>
- <text class="detail-value">{{ item.paymentMethod }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鍚堝悓閲戦(鍏�)</text>
- <text class="detail-value highlight">{{ item.contractAmount }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">绛捐鏃ユ湡</text>
- <text class="detail-value">{{ item.executionDate }}</text>
- </view>
- <up-divider></up-divider>
- <view class="detail-info">
- <view class="detail-row">
- <text class="detail-label">褰曞叆浜�</text>
- <text class="detail-value">{{ item.entryPersonName }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">褰曞叆鏃ユ湡</text>
- <text class="detail-value">{{ item.entryDate }}</text>
- </view>
- </view>
- </view>
- </view>
- </view>
- </view>
- <view v-else class="no-data">
- <text>鏆傛棤閿�鍞彴璐︽暟鎹�</text>
- </view>
-
- <!-- 娴姩鎿嶄綔鎸夐挳 -->
- <view class="fab-button" @click="handleInfo('add')">
- <up-icon name="plus" size="24" color="#ffffff"></up-icon>
- </view>
- </view>
+ <view class="sales-account">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="閿�鍞彴璐�"
+ @back="goBack" />
+ <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
+ <view class="search-section">
+ <view class="search-bar">
+ <view class="search-input">
+ <up-input class="search-text"
+ placeholder="璇疯緭鍏ラ攢鍞悎鍚屽彿鎼滅储"
+ v-model="salesContractNo"
+ @change="getList"
+ clearable />
+ </view>
+ <view class="filter-button"
+ @click="getList">
+ <up-icon name="search"
+ size="24"
+ color="#999"></up-icon>
+ </view>
+ </view>
+ </view>
+ <!-- 閿�鍞彴璐︾�戝竷娴� -->
+ <view class="ledger-list"
+ v-if="ledgerList.length > 0">
+ <view v-for="(item, index) in ledgerList"
+ :key="index">
+ <view class="ledger-item"
+ @click="handleInfo('edit', item)">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="document-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">{{ item.salesContractNo }}</text>
+ </view>
+ <!-- <view class="item-tag">-->
+ <!-- <text class="tag-text">{{ item.recorder }}</text>-->
+ <!-- </view>-->
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">瀹㈡埛鍚嶇О</text>
+ <text class="detail-value">{{ item.customerName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">瀹㈡埛鍚堝悓鍙�</text>
+ <text class="detail-value">{{ item.customerContractNo }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">涓氬姟鍛�</text>
+ <text class="detail-value">{{ item.salesman }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">椤圭洰鍚嶇О</text>
+ <text class="detail-value">{{ item.projectName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">浠樻鏂瑰紡</text>
+ <text class="detail-value">{{ item.paymentMethod }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍚堝悓閲戦(鍏�)</text>
+ <text class="detail-value highlight">{{ item.contractAmount }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">绛捐鏃ユ湡</text>
+ <text class="detail-value">{{ item.executionDate }}</text>
+ </view>
+ <up-divider></up-divider>
+ <view class="detail-info">
+ <view class="detail-row">
+ <text class="detail-label">褰曞叆浜�</text>
+ <text class="detail-value">{{ item.entryPersonName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">褰曞叆鏃ユ湡</text>
+ <text class="detail-value">{{ item.entryDate }}</text>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <u-button class="detail-button"
+ size="small"
+ type="primary"
+ @click="openOut(item)">
+ 鍙戣揣鐘舵��
+ </u-button>
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤閿�鍞彴璐︽暟鎹�</text>
+ </view>
+ <!-- 娴姩鎿嶄綔鎸夐挳 -->
+ <view class="fab-button"
+ @click="handleInfo('add')">
+ <up-icon name="plus"
+ size="24"
+ color="#ffffff"></up-icon>
+ </view>
+ </view>
</template>
<script setup>
-import { ref } from 'vue';
-import { onShow } from '@dcloudio/uni-app';
-import {ledgerListPage} from "@/api/salesManagement/salesLedger";
-import useUserStore from "@/store/modules/user";
-import PageHeader from "@/components/PageHeader.vue";
-const userStore = useUserStore()
-const showLoadingToast = (message) => {
- uni.showLoading({
- title: message,
- mask: true
- })
-}
-const closeToast = () => {
- uni.hideLoading()
-}
+ import { ref } from "vue";
+ import { onShow } from "@dcloudio/uni-app";
+ import { ledgerListPage } from "@/api/salesManagement/salesLedger";
+ import useUserStore from "@/store/modules/user";
+ import PageHeader from "@/components/PageHeader.vue";
+ const userStore = useUserStore();
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
+ const closeToast = () => {
+ uni.hideLoading();
+ };
-// 鎼滅储鍏抽敭璇�
-const salesContractNo = ref('');
+ // 鎼滅储鍏抽敭璇�
+ const salesContractNo = ref("");
-// 閿�鍞彴璐︽暟鎹�
-const ledgerList = ref([]);
+ // 閿�鍞彴璐︽暟鎹�
+ const ledgerList = ref([]);
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
- uni.navigateBack();
-};
-// 鏌ヨ鍒楄〃
-const getList = () => {
- showLoadingToast('鍔犺浇涓�...')
- const page = {
- current: -1,
- size: -1
- }
- ledgerListPage({...page, salesContractNo: salesContractNo.value}).then((res) => {
- console.log('閿�鍞彴璐�----', res);
- ledgerList.value = res.records;
- closeToast()
- }).catch(() => {
- closeToast()
- });
-};
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ // 鏌ヨ鍒楄〃
+ const getList = () => {
+ showLoadingToast("鍔犺浇涓�...");
+ const page = {
+ current: -1,
+ size: -1,
+ };
+ ledgerListPage({ ...page, salesContractNo: salesContractNo.value })
+ .then(res => {
+ console.log("閿�鍞彴璐�----", res);
+ ledgerList.value = res.records;
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ });
+ };
+ const openOut = item => {
+ uni.setStorageSync("outData", JSON.stringify(item));
+ uni.navigateTo({
+ url: "/pages/sales/salesAccount/out",
+ });
+ };
+ // 澶勭悊鍙拌处淇℃伅鎿嶄綔锛堟煡鐪�/缂栬緫/鏂板锛�
+ const handleInfo = (type, row) => {
+ try {
+ // 璁剧疆鎿嶄綔绫诲瀷
+ uni.setStorageSync("operationType", type);
-// 澶勭悊鍙拌处淇℃伅鎿嶄綔锛堟煡鐪�/缂栬緫/鏂板锛�
-const handleInfo = (type, row) => {
- try {
- // 璁剧疆鎿嶄綔绫诲瀷
- uni.setStorageSync('operationType', type);
-
- // 濡傛灉鏄煡鐪嬫垨缂栬緫鎿嶄綔
- if (type !== 'add') {
- // 楠岃瘉琛屾暟鎹槸鍚﹀瓨鍦�
- if (!row) {
- uni.showToast({
- title: '鏁版嵁涓嶅瓨鍦�',
- icon: 'error'
- });
- return;
- }
-
- // 妫�鏌ユ潈闄愶細鍙湁褰曞叆浜烘墠鑳界紪杈�
- if (row.entryPerson != userStore.id) {
- // 闈炲綍鍏ヤ汉璺宠浆鍒板彧璇昏鎯呴〉闈�
- uni.setStorageSync('editData', JSON.stringify(row));
- uni.navigateTo({
- url: '/pages/sales/salesAccount/view'
- });
- return;
- }
-
- // 褰曞叆浜虹紪杈戯細瀛樺偍鏁版嵁骞惰烦杞埌缂栬緫椤甸潰
- uni.setStorageSync('editData', JSON.stringify(row));
- uni.navigateTo({
- url: '/pages/sales/salesAccount/detail'
- });
- return;
- }
-
- // 鏂板鎿嶄綔锛氱洿鎺ヨ烦杞埌缂栬緫椤甸潰
- uni.navigateTo({
- url: '/pages/sales/salesAccount/detail'
- });
-
- } catch (error) {
- console.error('澶勭悊鍙拌处淇℃伅鎿嶄綔澶辫触:', error);
- uni.showToast({
- title: '鎿嶄綔澶辫触锛岃閲嶈瘯',
- icon: 'error'
- });
- }
-};
+ // 濡傛灉鏄煡鐪嬫垨缂栬緫鎿嶄綔
+ if (type !== "add") {
+ // 楠岃瘉琛屾暟鎹槸鍚﹀瓨鍦�
+ if (!row) {
+ uni.showToast({
+ title: "鏁版嵁涓嶅瓨鍦�",
+ icon: "error",
+ });
+ return;
+ }
-onShow(() => {
- // 椤甸潰鏄剧ず鏃跺埛鏂板垪琛�
- getList();
-});
+ // 妫�鏌ユ潈闄愶細鍙湁褰曞叆浜烘墠鑳界紪杈�
+ if (row.entryPerson != userStore.id) {
+ // 闈炲綍鍏ヤ汉璺宠浆鍒板彧璇昏鎯呴〉闈�
+ uni.setStorageSync("editData", JSON.stringify(row));
+ uni.navigateTo({
+ url: "/pages/sales/salesAccount/view",
+ });
+ return;
+ }
+
+ // 褰曞叆浜虹紪杈戯細瀛樺偍鏁版嵁骞惰烦杞埌缂栬緫椤甸潰
+ uni.setStorageSync("editData", JSON.stringify(row));
+ uni.navigateTo({
+ url: "/pages/sales/salesAccount/detail",
+ });
+ return;
+ }
+
+ // 鏂板鎿嶄綔锛氱洿鎺ヨ烦杞埌缂栬緫椤甸潰
+ uni.navigateTo({
+ url: "/pages/sales/salesAccount/detail",
+ });
+ } catch (error) {
+ console.error("澶勭悊鍙拌处淇℃伅鎿嶄綔澶辫触:", error);
+ uni.showToast({
+ title: "鎿嶄綔澶辫触锛岃閲嶈瘯",
+ icon: "error",
+ });
+ }
+ };
+
+ onShow(() => {
+ // 椤甸潰鏄剧ず鏃跺埛鏂板垪琛�
+ getList();
+ });
</script>
<style scoped lang="scss">
-@import '@/styles/sales-common.scss';
+ @import "@/styles/sales-common.scss";
</style>
diff --git a/src/pages/sales/salesAccount/out.vue b/src/pages/sales/salesAccount/out.vue
new file mode 100644
index 0000000..d4fc5be
--- /dev/null
+++ b/src/pages/sales/salesAccount/out.vue
@@ -0,0 +1,407 @@
+<template>
+ <view class="receipt-payment-detail">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="鍙戣揣鐘舵��"
+ @back="goBack" />
+ <!-- 缁熻淇℃伅 -->
+ <view class="summary-info">
+ <view class="summary-item">
+ <text class="summary-label">瀹㈡埛鍚嶇О</text>
+ <text class="summary-value">{{ outData.customerName }}</text>
+ </view>
+ <view class="summary-item">
+ <text class="summary-label">鍚堝悓閲戦</text>
+ <text class="summary-value">{{ outData.contractAmount }}</text>
+ </view>
+ <view class="summary-item">
+ <text class="summary-label">绛捐鏃ユ湡</text>
+ <text class="summary-value">{{ outData.executionDate }}</text>
+ </view>
+ </view>
+ <!-- 鍥炴璁板綍鏄庣粏鍒楄〃 -->
+ <view class="detail-list"
+ v-if="tableData.length > 0">
+ <view v-for="(item, index) in tableData"
+ :key="index"
+ class="detail-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="record-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-index">{{ item.productCategory }}</text>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">浜у搧澶х被</text>
+ <text class="detail-value">{{ item.productCategory }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">瑙勬牸鍨嬪彿</text>
+ <text class="detail-value">{{ item.specificationModel }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍗曚綅</text>
+ <text class="detail-value">{{ item.unit }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">浜у搧鐘舵��</text>
+ <text v-if="item.approveStatus === 1"
+ class="detail-value highlight">鍏呰冻</text>
+ <text v-else
+ class="detail-value danger">涓嶈冻</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍙戣揣鐘舵��</text>
+ <u-tag size="mini"
+ :type="getShippingStatusType(item)">{{ getShippingStatusText(item) }}</u-tag>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">蹇�掑叕鍙�</text>
+ <text class="detail-value">{{ item.expressCompany }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">蹇�掑崟鍙�</text>
+ <text class="detail-value">{{ item.expressNumber }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍙戣揣杞︾墝</text>
+ <u-tag size="mini"
+ v-if="item.shippingCarNumber"
+ type="success">{{ item.shippingCarNumber }}</u-tag>
+ <u-tag v-else
+ size="mini"
+ type="info">-</u-tag>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍙戣揣鏃ユ湡</text>
+ <text class="detail-value">{{ item.shippingDate || '-' }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鏁伴噺</text>
+ <text class="detail-value">{{ item.quantity }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">绋庣巼锛�%锛�</text>
+ <text class="detail-value">{{ item.taxRate }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍚◣鍗曚环锛堝厓锛�</text>
+ <text class="detail-value">{{ item.taxInclusiveUnitPrice }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍚◣鎬讳环锛堝厓锛�</text>
+ <text class="detail-value">{{ item.taxInclusiveTotalPrice }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">涓嶅惈绋庢�讳环锛堝厓锛�</text>
+ <text class="detail-value">{{ item.taxExclusiveTotalPrice }}</text>
+ </view>
+ <up-divider></up-divider>
+ <u-button class="detail-button"
+ size="small"
+ type="primary"
+ :disabled="!canShip(item)"
+ @click="goout(item)">
+ 鍙戣揣
+ </u-button>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤鍥炴璁板綍</text>
+ </view>
+ </view>
+</template>
+
+<script setup>
+ import { ref, computed, onMounted } from "vue";
+ import { productList } from "@/api/salesManagement/salesLedger";
+
+ // 瀹㈡埛淇℃伅
+ const supplierId = ref("");
+
+ // 琛ㄦ牸鏁版嵁
+ const tableData = ref([]);
+
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.removeStorageSync("supplierId");
+ uni.navigateBack();
+ };
+ const getShippingStatusType = row => {
+ // 濡傛灉宸插彂璐э紙鏈夊彂璐ф棩鏈熸垨杞︾墝鍙凤級锛屾樉绀虹豢鑹�
+ if (row.shippingDate || row.shippingCarNumber) {
+ return "success";
+ }
+
+ // 鑾峰彇鍙戣揣鐘舵�佸瓧娈�
+ const status = row.shippingStatus;
+
+ // 濡傛灉鐘舵�佷负绌烘垨鏈畾涔夛紝榛樿涓虹伆鑹诧紙寰呭彂璐э級
+ if (status === null || status === undefined || status === "") {
+ return "info";
+ }
+
+ // 鐘舵�佹槸瀛楃涓�
+ const statusStr = String(status).trim();
+ const typeTextMap = {
+ 寰呭彂璐�: "info",
+ 寰呭鏍�: "info",
+ 瀹℃牳涓�: "warning",
+ 瀹℃牳鎷掔粷: "danger",
+ 瀹℃牳閫氳繃: "success",
+ 宸插彂璐�: "success",
+ };
+ return typeTextMap[statusStr] || "info";
+ };
+ const getShippingStatusText = row => {
+ // 濡傛灉宸插彂璐э紙鏈夊彂璐ф棩鏈熸垨杞︾墝鍙凤級锛屾樉绀�"宸插彂璐�"
+ if (row.shippingDate || row.shippingCarNumber) {
+ return "宸插彂璐�";
+ }
+
+ // 鑾峰彇鍙戣揣鐘舵�佸瓧娈�
+ const status = row.shippingStatus;
+
+ // 濡傛灉鐘舵�佷负绌烘垨鏈畾涔夛紝榛樿涓�"寰呭彂璐�"
+ if (status === null || status === undefined || status === "") {
+ return "寰呭彂璐�";
+ }
+
+ // 鐘舵�佹槸瀛楃涓�
+ const statusStr = String(status).trim();
+ const statusTextMap = {
+ 寰呭彂璐�: "寰呭彂璐�",
+ 寰呭鏍�: "寰呭鏍�",
+ 瀹℃牳涓�: "瀹℃牳涓�",
+ 瀹℃牳鎷掔粷: "瀹℃牳鎷掔粷",
+ 瀹℃牳閫氳繃: "瀹℃牳閫氳繃",
+ 宸插彂璐�: "宸插彂璐�",
+ };
+ return statusTextMap[statusStr] || "寰呭彂璐�";
+ };
+ // 鑾峰彇椤甸潰鍙傛暟
+ const getPageParams = () => {
+ // 浠庢湰鍦板瓨鍌ㄨ幏鍙栦緵搴斿晢ID
+ const storedSupplierId = uni.getStorageSync("supplierId");
+ if (storedSupplierId) {
+ supplierId.value = storedSupplierId;
+ }
+ };
+ const goout = item => {
+ uni.setStorageSync("goOutData", JSON.stringify(item));
+ uni.navigateTo({
+ url: "/pages/sales/salesAccount/goOut",
+ });
+ };
+
+ // 鏌ヨ鍒楄〃
+ const getList = () => {
+ showLoadingToast("鍔犺浇涓�...");
+ productList({
+ salesLedgerId: outData.value.id,
+ type: 1,
+ })
+ .then(res => {
+ tableData.value = res.data;
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ uni.showToast({
+ title: "鏌ヨ澶辫触",
+ icon: "error",
+ });
+ });
+ };
+ const canShip = row => {
+ // 浜у搧鐘舵�佸繀椤绘槸鍏呰冻锛坅pproveStatus === 1锛�
+ if (row.approveStatus !== 1) {
+ return false;
+ }
+
+ // 鑾峰彇鍙戣揣鐘舵��
+ const shippingStatus = row.shippingStatus;
+
+ // 濡傛灉宸插彂璐э紙鏈夊彂璐ф棩鏈熸垨杞︾墝鍙凤級锛屼笉鑳藉啀娆″彂璐�
+ if (row.shippingDate || row.shippingCarNumber) {
+ return false;
+ }
+
+ // 鍙戣揣鐘舵�佸繀椤绘槸"寰呭彂璐�"鎴�"瀹℃牳鎷掔粷"
+ const statusStr = shippingStatus ? String(shippingStatus).trim() : "";
+ return statusStr === "寰呭彂璐�" || statusStr === "瀹℃牳鎷掔粷";
+ };
+
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
+
+ // 鍏抽棴鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
+ const outData = ref({});
+
+ onMounted(() => {
+ // 椤甸潰鍔犺浇鏃惰幏鍙栧弬鏁板苟鍒锋柊鍒楄〃
+ getPageParams();
+ // 浠庢湰鍦板瓨鍌ㄨ幏鍙栧彂璐х姸鎬佹暟鎹�
+ outData.value = JSON.parse(uni.getStorageSync("outData"));
+ getList();
+ });
+</script>
+
+<style scoped lang="scss">
+ .receipt-payment-detail {
+ min-height: 100vh;
+ background: #f8f9fa;
+ position: relative;
+ }
+
+ .u-divider {
+ margin: 0 !important;
+ }
+
+ .summary-info {
+ background: #ffffff;
+ margin: 20px 20px 0 20px;
+ border-radius: 12px;
+ padding: 16px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+ }
+
+ .summary-item {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 8px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ .summary-label {
+ font-size: 14px;
+ color: #666;
+ }
+
+ .summary-value {
+ font-size: 14px;
+ color: #333;
+ font-weight: 500;
+ }
+
+ .summary-value.highlight {
+ color: #2979ff;
+ font-weight: 600;
+ }
+
+ .summary-value.danger {
+ color: #ff4757;
+ font-weight: 600;
+ }
+
+ .detail-list {
+ padding: 20px;
+ }
+
+ .detail-item {
+ background: #ffffff;
+ border-radius: 12px;
+ margin-bottom: 16px;
+ overflow: hidden;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+ padding: 0 16px;
+ }
+
+ .item-header {
+ padding: 10px 0;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+
+ .item-left {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ }
+
+ .record-icon {
+ width: 24px;
+ height: 24px;
+ background: #2979ff;
+ border-radius: 4px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+
+ .item-index {
+ font-size: 14px;
+ color: #333;
+ font-weight: 500;
+ }
+
+ .item-date {
+ font-size: 12px;
+ color: #666;
+ }
+
+ .item-details {
+ padding: 16px 0;
+ }
+
+ .detail-row {
+ display: flex;
+ align-items: flex-end;
+ justify-content: space-between;
+ margin-bottom: 8px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ .detail-label {
+ font-size: 12px;
+ color: #777777;
+ min-width: 60px;
+ }
+
+ .detail-value {
+ font-size: 12px;
+ color: #000000;
+ text-align: right;
+ flex: 1;
+ margin-left: 16px;
+ }
+
+ .detail-value.highlight {
+ color: #2979ff;
+ font-weight: 500;
+ }
+
+ .detail-value.danger {
+ color: #ff4757;
+ font-weight: 500;
+ }
+
+ .no-data {
+ padding: 40px 0;
+ text-align: center;
+ color: #999;
+ }
+</style>
--
Gitblit v1.9.3