From 025e46e11cb2962fd7692adfa401333758cc779b Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 02 九月 2025 14:00:34 +0800
Subject: [PATCH] 修改组件

---
 src/pages/sales/salesAccount/detail.vue |  898 +++++++++++++++++++++++++++--------------------------------
 1 files changed, 407 insertions(+), 491 deletions(-)

diff --git a/src/pages/sales/salesAccount/detail.vue b/src/pages/sales/salesAccount/detail.vue
index 0260179..60efb0e 100644
--- a/src/pages/sales/salesAccount/detail.vue
+++ b/src/pages/sales/salesAccount/detail.vue
@@ -4,110 +4,120 @@
 		<PageHeader title="鍙拌处璇︽儏" @back="goBack" />
 
          <!-- 琛ㄥ崟鍖哄煙 -->
-		<u-form @submit="onSubmit" label-width="110" input-align="right" style="margin-top: 10px" error-message-align="right">
-			<u-form-item label="閿�鍞悎鍚屽彿" prop="salesContractNo" border-bottom>
-				<u-input v-model="form.salesContractNo" placeholder="鑷姩鐢熸垚" disabled />
-			</u-form-item>
-			<u-form-item
+		<up-form @submit="onSubmit" label-width="110" ref="formRef" :rules="rules" :model="form">
+
+			<up-form-item label="閿�鍞悎鍚屽彿" prop="salesContractNo" >
+				<up-input v-model="form.salesContractNo" placeholder="鑷姩鐢熸垚" disabled />
+			</up-form-item>
+			<up-form-item
 				label="涓氬姟鍛�"
 				prop="salesman"
 				required
-				border-bottom
+				@click="showPicker = true"
 			>
-				<u-input
+				<up-input
 					v-model="form.salesman"
-					readonly
-					placeholder="鐐瑰嚮閫夋嫨涓氬姟鍛�"
+					readonly=""
 					@click="showPicker = true"
+					placeholder="鐐瑰嚮閫夋嫨涓氬姟鍛�"
 				/>
-			</u-form-item>
-			<u-form-item label="瀹㈡埛鍚堝悓鍙�" prop="customerContractNo" required border-bottom>
-				<u-input
+				<template #right>
+					<up-icon
+						name="arrow-right"
+						@click="showPicker = true"
+					></up-icon>
+				</template>
+			</up-form-item>
+			<up-form-item label="瀹㈡埛鍚堝悓鍙�" prop="customerContractNo" required >
+				<up-input
 					v-model="form.customerContractNo"
 					placeholder="璇疯緭鍏ュ鎴峰悎鍚屽彿"
 				/>
-			</u-form-item>
-			<u-form-item
+			</up-form-item>
+			<up-form-item
 				label="瀹㈡埛鍚嶇О"
 				prop="customerName"
 				required
-				border-bottom
 			>
-				<u-input
+				<up-input
 					v-model="form.customerName"
 					readonly
 					placeholder="鐐瑰嚮閫夋嫨瀹㈡埛"
 					@click="showCustomerPicker = true"
 				/>
-			</u-form-item>
-			<u-form-item label="椤圭洰鍚嶇О" prop="projectName" required border-bottom>
-				<u-input v-model="form.projectName" placeholder="璇疯緭鍏ラ」鐩悕绉�" />
-			</u-form-item>
-			<u-form-item
+				<template #right>
+					<up-icon
+						name="arrow-right"
+						@click="showCustomerPicker = true"
+					></up-icon>
+				</template>
+			</up-form-item>
+			<up-form-item label="椤圭洰鍚嶇О" prop="projectName" required >
+				<up-input v-model="form.projectName" placeholder="璇疯緭鍏ラ」鐩悕绉�" />
+			</up-form-item>
+			<up-form-item
 				label="绛捐鏃ユ湡"
 				prop="executionDate"
 				required
-				border-bottom
 			>
-				<u-input
+				<up-input
 					v-model="form.executionDate"
 					readonly
 					placeholder="鐐瑰嚮閫夋嫨鏃堕棿"
 					@click="showDatePicker = true"
 				/>
-			</u-form-item>
-			<u-popup v-model="showDatePicker" mode="bottom">
-				<u-datetime-picker
+				<template #right>
+					<up-icon
+						name="arrow-right"
+						@click="showDatePicker = true"
+					></up-icon>
+				</template>
+			</up-form-item>
+			<up-form-item label="浠樻鏂瑰紡" prop="paymentMethod" >
+				<up-input v-model="form.paymentMethod" placeholder="璇疯緭鍏ヤ粯娆炬柟寮�" />
+			</up-form-item>
+			<up-form-item label="褰曞叆浜�" prop="entryPersonName" >
+				<up-input v-model="form.entryPersonName" placeholder="璇疯緭鍏�" disabled />
+			</up-form-item>
+			<up-form-item label="褰曞叆鏃ユ湡" prop="entryDate" >
+				<up-input v-model="form.entryDate" placeholder="璇疯緭鍏�" disabled />
+			</up-form-item>
+			<!-- 涓氬姟鍛橀�夋嫨 -->
+			<up-action-sheet
+				:show="showPicker"
+				:actions="userActionList"
+				title="閫夋嫨涓氬姟鍛�"
+				@select="onSalesmanSelect"
+				@close="showPicker = false"
+			/>
+			
+			<!-- 鏃ユ湡閫夋嫨 -->
+			<up-popup :show="showDatePicker" mode="bottom" @close="showDatePicker = false">
+				<up-datetime-picker
+					:show="true"
 					v-model="pickerDateValue"
 					@confirm="onDateConfirm"
 					@cancel="showDatePicker = false"
+					mode="date"
 				/>
-			</u-popup>
-			<u-form-item label="浠樻鏂瑰紡" prop="paymentMethod" border-bottom>
-				<u-input v-model="form.paymentMethod" placeholder="璇疯緭鍏ヤ粯娆炬柟寮�" />
-			</u-form-item>
-			<u-form-item label="褰曞叆浜�" prop="entryPersonName" border-bottom>
-				<u-input v-model="form.entryPersonName" placeholder="璇疯緭鍏�" disabled />
-			</u-form-item>
-			<u-form-item label="褰曞叆鏃ユ湡" prop="entryDate" border-bottom>
-				<u-input v-model="form.entryDate" placeholder="璇疯緭鍏�" disabled />
-			</u-form-item>
-			<!-- 涓氬姟鍛橀�夋嫨寮圭獥 -->
-			<u-popup v-model="showPicker" mode="bottom">
-				<view class="picker-header">
-					<view class="picker-cancel" @click="showPicker = false">鍙栨秷</view>
-					<view class="picker-title">閫夋嫨涓氬姟鍛�</view>
-					<view class="picker-confirm" @click="confirmSalesman">纭畾</view>
-				</view>
-				<u-picker
-					:columns="userList"
-					v-model="pickerValue"
-					@change="onPickerChange"
-				/>
-			</u-popup>
-			
-			<!-- 瀹㈡埛閫夋嫨寮圭獥 -->
-			<u-popup v-model="showCustomerPicker" mode="bottom">
-				<view class="picker-header">
-					<view class="picker-cancel" @click="showCustomerPicker = false">鍙栨秷</view>
-					<view class="picker-title">閫夋嫨瀹㈡埛</view>
-					<view class="picker-confirm" @click="confirmCustomer">纭畾</view>
-				</view>
-				<u-picker
-					:columns="customerOption"
-					v-model="pickerCustomerValue"
-					@change="onCustomerPickerChange"
-				/>
-			</u-popup>
+			</up-popup>
+			<!-- 瀹㈡埛閫夋嫨 -->
+			<up-action-sheet 
+				:show="showCustomerPicker"
+				:actions="customerActionList"
+				title="閫夋嫨瀹㈡埛"
+				@select="onCustomerSelect"
+				@close="showCustomerPicker = false"
+			/>
 			
 			<!-- 浜у搧澶х被閫夋嫨鍣� -->
-			<u-popup v-model="showCategoryPicker" mode="bottom">
+			<up-popup :show="showCategoryPicker" mode="bottom">
 				<!-- 澶撮儴鎸夐挳鍖哄煙 -->
 				<view class="popup-header">
 					<view @click="showCategoryPicker = false" class="cancelButton">鍙栨秷</view>
 					<view @click="confirmCategorySelection" class="confirmButton">纭畾</view>
 				</view>
-				<up-tree
+				<u-tree
 					:data="productOptions"
 					:props="defaultProps"
 					show-checkbox
@@ -115,200 +125,225 @@
 					check-strictly
 					@check-change="onCategoryConfirm"
 				/>
-			</u-popup>
+			</up-popup>
 			
 			<!-- 瑙勬牸鍨嬪彿閫夋嫨鍣� -->
-			<u-popup v-model="showSpecificationPicker" mode="bottom">
-				<u-picker
-					:columns="modelOptions"
-					v-model="pickerSpecificationValue"
-					@confirm="onSpecificationConfirm"
-					@cancel="showSpecificationPicker = false"
-				/>
-			</u-popup>
+			<up-action-sheet
+				:show="showSpecificationPicker"
+				:actions="specificationActionList"
+				title="閫夋嫨瑙勬牸鍨嬪彿"
+				@select="onSpecificationSelect"
+				@close="showSpecificationPicker = false"
+			/>
 			
 			<!-- 绋庣巼閫夋嫨鍣� -->
-			<u-popup v-model="showTaxRatePicker" mode="bottom">
-				<u-picker
-					:columns="taxRateOptions"
-					v-model="pickerTaxRateValue"
-					@confirm="onTaxRateConfirm"
-					@cancel="showTaxRatePicker = false"
-				/>
-			</u-popup>
+			<up-action-sheet
+				:show="showTaxRatePicker"
+				:actions="taxRateActionList"
+				title="閫夋嫨绋庣巼"
+				@select="onTaxRateSelect"
+				@close="showTaxRatePicker = false"
+			/>
 			
 			<!-- 鍙戠エ绫诲瀷閫夋嫨鍣� -->
-			<u-popup v-model="showInvoiceTypePicker" mode="bottom">
-				<u-picker
-					:columns="invoiceTypeOptions"
-					v-model="pickerInvoiceTypeValue"
-					@confirm="onInvoiceTypeConfirm"
-					@cancel="showInvoiceTypePicker = false"
-				/>
-			</u-popup>
+			<up-action-sheet
+				:show="showInvoiceTypePicker"
+				:actions="invoiceTypeActionList"
+				title="閫夋嫨鍙戠エ绫诲瀷"
+				@select="onInvoiceTypeSelect"
+				@close="showInvoiceTypePicker = false"
+			/>
 			<!-- 浜у搧淇℃伅 -->
 			<view class="product-section">
 				<view class="section-header">
-					<text class="section-title">浜у搧淇℃伅</text>
-					<u-button type="primary" size="small" @click="addProduct" class="add-btn" v-if="operationType !== 'view'">
-						<u-icon name="plus" size="14" />
-						鏂板
-					</u-button>
+					<view>
+						<text class="section-title">浜у搧淇℃伅</text>
+					</view>
+					<view>
+						<up-button type="primary" size="small" @click="addProduct" class="add-btn" v-if="operationType !== 'view'">
+							鏂板
+						</up-button>
+					</view>
 				</view>
 				<view class="product-card" v-for="(product, idx) in productData" :key="idx">
 					<!-- 浜у搧绫� -->
 					<view class="product-header">
 						<view class="product-title">
-							<u-icon name="file-text" color="#2979ff" size="15" />
+							<view class="document-icon">
+								<up-icon name="file-text" size="16" color="#ffffff"></up-icon>
+							</view>
 							<text class="product-productCategory">浜у搧 {{ idx + 1 }}</text>
 						</view>
 						<!-- 鎿嶄綔鎸夐挳 -->
 						<view class="product-actions" v-if="operationType !== 'view'">
-							<u-button type="error" size="mini" @click="removeProduct(idx)" class="del-btn">
-								<u-icon name="trash" size="12" />
+							<up-button type="error" size="mini" @click="removeProduct(idx)" class="del-btn">
 								鍒犻櫎
-							</u-button>
+							</up-button>
 						</view>
 					</view>
 					
 					<!-- 浜у搧淇℃伅琛ㄥ崟 -->
 					<view class="product-form">
 						<!-- 浜у搧澶х被 -->
-						<u-form-item
+						<up-form-item
 							label="浜у搧澶х被"
 							prop="productCategory"
 							required
-							border-bottom
+							:rules="productRules"
 						>
-							<u-input
+							<up-input
 								v-model="product.productCategory"
 								readonly
 								placeholder="璇烽�夋嫨"
 								@click="openCategoryPicker(idx)"
 							/>
-						</u-form-item>
+							<template #right>
+								<up-icon
+									name="arrow-right"
+									@click="showCategoryPicker = true"
+								></up-icon>
+							</template>
+						</up-form-item>
 						
 						<!-- 瑙勬牸鍨嬪彿 -->
-						<u-form-item
+						<up-form-item
 							label="瑙勬牸鍨嬪彿"
 							prop="specificationModel"
 							required
-							border-bottom
+							:rules="productRules"
 						>
-							<u-input
+							<up-input
 								v-model="product.specificationModel"
 								readonly
 								placeholder="璇烽�夋嫨"
 								@click="openSpecificationPicker(idx)"
 							/>
-						</u-form-item>
+							<template #right>
+								<up-icon
+									name="arrow-right"
+									@click="showSpecificationPicker = true"
+								></up-icon>
+							</template>
+						</up-form-item>
 						
 						<!-- 鍗曚綅 -->
-						<u-form-item
+						<up-form-item
 							label="鍗曚綅"
 							prop="unit"
 							required
-							border-bottom
+							:rules="productRules"
 						>
-							<u-input
+							<up-input
 								v-model="product.unit"
 								placeholder="璇疯緭鍏�"
 							/>
-						</u-form-item>
+						</up-form-item>
 						
 						<!-- 绋庣巼 -->
-						<u-form-item
+						<up-form-item
 							label="绋庣巼(%)"
 							prop="taxRate"
 							required
-							border-bottom
+							:rules="productRules"
 						>
-							<u-input
+							<up-input
 								v-model="product.taxRate"
 								readonly
 								placeholder="璇烽�夋嫨"
 								@click="openTaxRatePicker(idx)"
 							/>
-						</u-form-item>
+							<template #right>
+								<up-icon
+									name="arrow-right"
+									@click="showTaxRatePicker = true"
+								></up-icon>
+							</template>
+						</up-form-item>
 						
 						<!-- 鍚◣鍗曚环 -->
-						<u-form-item
+						<up-form-item
 							label="鍚◣鍗曚环(鍏�)"
 							prop="taxInclusiveUnitPrice"
 							required
-							border-bottom
+							:rules="productRules"
 						>
-							<u-input
+							<up-input
 								v-model="product.taxInclusiveUnitPrice"
 								type="number"
 								placeholder="璇疯緭鍏�"
 								@blur="formatTaxPrice(idx)"
 							/>
-						</u-form-item>
+						</up-form-item>
 						
 						<!-- 鏁伴噺 -->
-						<u-form-item
+						<up-form-item
 							label="鏁伴噺"
 							prop="quantity"
 							required
-							border-bottom
+							:rules="productRules"
 						>
-							<u-input
+							<up-input
 								v-model="product.quantity"
 								type="number"
 								placeholder="璇疯緭鍏�"
 								@blur="formatAmount(idx)"
 							/>
-						</u-form-item>
+						</up-form-item>
 						
 						<!-- 鍚◣鎬讳环 -->
-						<u-form-item
+						<up-form-item
 							label="鍚◣鎬讳环(鍏�)"
 							prop="taxInclusiveTotalPrice"
 							required
-							border-bottom
+							:rules="productRules"
 						>
-							<u-input
+							<up-input
 								v-model="product.taxInclusiveTotalPrice"
 								type="number"
 								placeholder="璇疯緭鍏�"
 								@blur="formatTaxTotal(idx)"
 							/>
-						</u-form-item>
+						</up-form-item>
 						
 						<!-- 涓嶅惈绋庢�讳环 -->
-						<u-form-item
+						<up-form-item
 							label="涓嶅惈绋庢�讳环(鍏�)"
 							prop="taxExclusiveTotalPrice"
 							required
-							border-bottom
+							:rules="productRules"
 						>
-							<u-input
+							<up-input
 								v-model="product.taxExclusiveTotalPrice"
 								type="number"
 								placeholder="璇疯緭鍏�"
 								@blur="formatNoTaxTotal(idx)"
 							/>
-						</u-form-item>
+						</up-form-item>
 						
 						<!-- 鍙戠エ绫诲瀷 -->
-						<u-form-item
+						<up-form-item
 							label="鍙戠エ绫诲瀷"
 							prop="invoiceType"
 							required
-							border-bottom
+							:rules="productRules"
 						>
-							<u-input
+							<up-input
 								v-model="product.invoiceType"
 								readonly
 								placeholder="璇烽�夋嫨"
 								@click="openInvoiceTypePicker(idx)"
 							/>
-						</u-form-item>
+							<template #right>
+								<up-icon
+									name="arrow-right"
+									@click="showInvoiceTypePicker = true"
+								></up-icon>
+							</template>
+						</up-form-item>
 					</view>
 				</view>
 			</view>
-		</u-form>
+		</up-form>
 		
 		<!-- 浣跨敤鍏叡搴曢儴鎸夐挳缁勪欢 -->
 		<FooterButtons
@@ -322,8 +357,9 @@
 </template>
 
 <script setup>
-import {onMounted, ref} from 'vue';
+import {onMounted, ref, computed} from 'vue';
 import {userListNoPage} from "@/api/system/user";
+import { formatDateToYMD } from '@/utils/ruoyi'
 import {
 	addOrUpdateSalesLedger,
 	addOrUpdateSalesLedgerProduct,
@@ -340,6 +376,7 @@
 // 鑾峰彇椤甸潰鍙傛暟
 const operationType = ref('');
 const editData = ref(null);
+const formRef = ref(null);
 
 const userStore = useUserStore()
 const form = ref({
@@ -355,14 +392,80 @@
 	entryPersonName: '',
 	entryDate: '',
 });
-const pickerValue = ref(['']);
-const pickerDateValue = ref([]);
 const showPicker = ref(false);
 const showDatePicker = ref(false);
-const pickerCustomerValue = ref(['']);
+const pickerDateValue = ref(Date.now());
 const showCustomerPicker = ref(false);
 const userList = ref([]);
 const customerOption = ref([]);
+const userActionList = computed(() => {
+	return userList.value.map(user => ({
+		name: user.text,
+		value: user.value
+	}))
+})
+const formatter = (type, value) => {
+	if (type === 'year') {
+		return `${value}`;
+	}
+	if (type === 'month') {
+		return `${value}`;
+	}
+	if (type === 'day') {
+		return `${value}`;
+	}
+	return value;
+};
+const customerActionList = computed(() => {
+	return customerOption.value.map(customer => ({
+		name: customer.text,
+		value: customer.value
+	}))
+})
+
+// 鏃ユ湡閫夋嫨鍒楄〃宸茬Щ闄わ紝鏀圭敤 up-datetime-picker
+
+// 浜у搧澶х被閫夋嫨鍒楄〃
+const categoryActionList = computed(() => {
+	const flattenCategories = (categories, result = []) => {
+		categories.forEach(category => {
+			result.push({
+				name: category.label,
+				value: category.id
+			})
+			if (category.children && category.children.length > 0) {
+				flattenCategories(category.children, result)
+			}
+		})
+		return result
+	}
+	return flattenCategories(productOptions.value)
+})
+
+// 瑙勬牸鍨嬪彿閫夋嫨鍒楄〃
+const specificationActionList = computed(() => {
+	return modelOptions.value.map(model => ({
+		name: model.text,
+		value: model.value,
+		unit: model.unit
+	}))
+})
+
+// 绋庣巼閫夋嫨鍒楄〃
+const taxRateActionList = computed(() => {
+	return taxRateOptions.value.map(rate => ({
+		name: rate.text,
+		value: rate.value
+	}))
+})
+
+// 鍙戠エ绫诲瀷閫夋嫨鍒楄〃
+const invoiceTypeActionList = computed(() => {
+	return invoiceTypeOptions.value.map(type => ({
+		name: type.text,
+		value: type.value
+	}))
+})
 const productData = ref([]);
 
 // 閫夋嫨鍣ㄧ浉鍏冲彉閲�
@@ -370,16 +473,9 @@
 const showSpecificationPicker = ref(false);
 const showTaxRatePicker = ref(false);
 const showInvoiceTypePicker = ref(false);
-const pickerCategoryValue = ref(['']);
-const pickerSpecificationValue = ref(['']);
-const pickerTaxRateValue = ref(['']);
-const pickerInvoiceTypeValue = ref(['']);
+// 閫夋嫨鍣ㄦ樉绀虹姸鎬佸彉閲忓凡鍦ㄤ笂闈㈠畾涔�
 
-// 涓存椂瀛樺偍閫夋嫨鍣ㄩ�変腑鐨勫��
-const tempSalesmanValue = ref('');
-const tempCustomerValue = ref('');
-const selectedSalesman = ref(null);
-const selectedCustomer = ref(null);
+// 涓存椂鍙橀噺宸蹭笉鍐嶉渶瑕�
 const currentProductIndex = ref(0);
 
 // 閫夐」鏁版嵁
@@ -405,6 +501,60 @@
   { text: '澧炰笓绁�', value: '澧炰笓绁�' },
 ]);
 
+// 琛ㄥ崟鏍¢獙瑙勫垯
+const rules = {
+	salesman: [
+		{ required: true, message: '璇烽�夋嫨涓氬姟鍛�', trigger: 'blur' }
+	],
+	customerContractNo: [
+		{ required: true, message: '璇疯緭鍏ュ鎴峰悎鍚屽彿', trigger: 'blur' }
+	],
+	customerName: [
+		{ required: true, message: '璇烽�夋嫨瀹㈡埛鍚嶇О', trigger: 'blur' }
+	],
+	projectName: [
+		{ required: true, message: '璇疯緭鍏ラ」鐩悕绉�', trigger: 'blur' }
+	],
+	executionDate: [
+		{ required: true, message: '璇烽�夋嫨绛捐鏃ユ湡', trigger: 'blur' }
+	]
+};
+
+// 浜у搧淇℃伅鏍¢獙瑙勫垯
+const productRules = {
+	productCategory: [
+		{ required: true, message: '璇烽�夋嫨浜у搧澶х被', trigger: 'blur' }
+	],
+	specificationModel: [
+		{ required: true, message: '璇烽�夋嫨瑙勬牸鍨嬪彿', trigger: 'blur' }
+	],
+	unit: [
+		{ required: true, message: '璇疯緭鍏ュ崟浣�', trigger: 'blur' }
+	],
+	taxRate: [
+		{ required: true, message: '璇烽�夋嫨绋庣巼', trigger: 'blur' }
+	],
+	taxInclusiveUnitPrice: [
+		{ required: true, message: '璇疯緭鍏ュ惈绋庡崟浠�', trigger: 'blur' },
+		{ type: 'number', min: 0, message: '鍚◣鍗曚环蹇呴』澶т簬0', trigger: 'blur' }
+	],
+	quantity: [
+		{ required: true, message: '璇疯緭鍏ユ暟閲�', trigger: 'blur' },
+		{ type: 'number', min: 0, message: '鏁伴噺蹇呴』澶т簬0', trigger: 'blur' }
+	],
+	taxInclusiveTotalPrice: [
+		{ required: true, message: '璇疯緭鍏ュ惈绋庢�讳环', trigger: 'blur' },
+		{ type: 'number', min: 0, message: '鍚◣鎬讳环蹇呴』澶т簬0', trigger: 'blur' }
+	],
+	taxExclusiveTotalPrice: [
+		{ required: true, message: '璇疯緭鍏ヤ笉鍚◣鎬讳环', trigger: 'blur' },
+		{ type: 'number', min: 0, message: '涓嶅惈绋庢�讳环蹇呴』澶т簬0', trigger: 'blur' }
+	],
+	invoiceType: [
+		{ required: true, message: '璇烽�夋嫨鍙戠エ绫诲瀷', trigger: 'blur' }
+	]
+};
+
 const addProduct = () => {
 	if (productData.value === null) {
 		productData.value = []
@@ -422,65 +572,25 @@
     invoiceType: ''
   });
 };
-// 涓氬姟鍛橀�夋嫨鍣ㄥ彉鍖栦簨浠�
-const onPickerChange = ({ selectedValues, selectedOptions }) => {
-	selectedSalesman.value = selectedOptions[0];
-	tempSalesmanValue.value = {
-		text: selectedOptions[0]?.text,
-		value: selectedOptions[0]?.value
-	};
-};
+// 涓氬姟鍛橀�夋嫨浜嬩欢
+const onSalesmanSelect = (item) => {
+	form.value.salesman = item.name
+}
 
-// 纭閫夋嫨涓氬姟鍛�
-const confirmSalesman = () => {
-	if (selectedSalesman.value) {
-		form.value.salesman = selectedSalesman.value.text;
-		pickerValue.value = [selectedSalesman.value.value];
-	}
-	showPicker.value = false;
-};
-
-// 瀹㈡埛閫夋嫨鍣ㄥ彉鍖栦簨浠�
-const onCustomerPickerChange = ({ selectedValues, selectedOptions }) => {
-	selectedCustomer.value = selectedOptions[0];
-	tempCustomerValue.value = {
-		text: selectedOptions[0]?.text,
-		value: selectedOptions[0]?.value
-	};
-};
-
-// 纭閫夋嫨瀹㈡埛
-const confirmCustomer = () => {
-	if (selectedCustomer.value) {
-		form.value.customerName = selectedCustomer.value.text;
-		form.value.customerId = selectedCustomer.value.value;
-		pickerCustomerValue.value = [selectedCustomer.value.value];
-	}
-	showCustomerPicker.value = false;
-};
-
-// 淇敼鍘熸湁鐨勭‘璁ゆ柟娉曪紙淇濇寔鍏煎鎬э級
-const onConfirm = ({ selectedValues, selectedOptions }) => {
-	if (selectedOptions && selectedOptions[0]) {
-		form.value.salesman = selectedOptions[0].text;
-		pickerValue.value = [selectedValues[0]];
-	}
-	showPicker.value = false;
-};
-
-const onCustomerConfirm = ({ selectedValues, selectedOptions }) => {
-	if (selectedOptions && selectedOptions[0]) {
-		form.value.customerName = selectedOptions[0].text;
-		form.value.customerId = selectedOptions[0].value;
-		pickerCustomerValue.value = [selectedValues[0]];
-	}
-	showCustomerPicker.value = false;
-};
-const onDateConfirm = ({ selectedValues }) => {
-	form.value.executionDate = selectedValues.join('-');
-	pickerDateValue.value = selectedValues;
+// 鏃ユ湡纭浜嬩欢
+const onDateConfirm = (e) => {
+	form.value.executionDate = formatDateToYMD(e.value)
+	pickerDateValue.value = formatDateToYMD(e.value)
 	showDatePicker.value = false;
-};
+}
+
+// 瀹㈡埛閫夋嫨浜嬩欢
+const onCustomerSelect = (item) => {
+	form.value.customerName = item.name
+	form.value.customerId = item.value
+}
+
+// 鍘熸湁鐨勭‘璁ゆ柟娉曞凡琚柊鐨刟ction-sheet閫夋嫨鏂规硶鏇夸唬
 const removeProduct = (idx) => {
 	productData.value.splice(idx, 1);
 };
@@ -524,7 +634,6 @@
 		selectedCategoryNode.value = null;
 		productData.value[currentProductIndex.value].specificationModel = ''
 		productData.value[currentProductIndex.value].productModelId = ''
-		productData.value[currentProductIndex.value].pickerSpecificationValue = ['']
 		getModels(id)
 	}
 	showCategoryPicker.value = false;
@@ -539,39 +648,27 @@
 		}));
 	});
 };
-// 閫夋嫨瑙勬牸鍨嬪彿
-const onSpecificationConfirm = ({ selectedValues, selectedOptions }) => {
-	productData.value[currentProductIndex.value].specificationModel = selectedOptions[0]?.text;
-	productData.value[currentProductIndex.value].productModelId = selectedOptions[0]?.value;
-	productData.value[currentProductIndex.value].unit = selectedOptions[0]?.unit;
-  pickerSpecificationValue.value = [selectedValues[0]];
-  showSpecificationPicker.value = false;
-};
-// 閫夋嫨绋庣巼
-const onTaxRateConfirm = ({ selectedValues, selectedOptions }) => {
-	productData.value[currentProductIndex.value].taxRate = selectedOptions[0]?.value;
-  pickerTaxRateValue.value = [selectedValues[0]];
-  showTaxRatePicker.value = false;
-	// if (isCalculating.value) return;
-	const inclusiveTotalPrice = parseFloat(productData.value[currentProductIndex.value].taxInclusiveTotalPrice);
-	const taxRate = parseFloat(productData.value[currentProductIndex.value].taxRate);
-	if (!inclusiveTotalPrice || !taxRate) {
-		return;
+// 瑙勬牸鍨嬪彿閫夋嫨浜嬩欢
+const onSpecificationSelect = (item) => {
+	productData.value[currentProductIndex.value].specificationModel = item.name
+	productData.value[currentProductIndex.value].productModelId = item.value
+	productData.value[currentProductIndex.value].unit = item.unit
+}
+// 绋庣巼閫夋嫨浜嬩欢
+const onTaxRateSelect = (item) => {
+	productData.value[currentProductIndex.value].taxRate = item.value
+	// 閲嶆柊璁$畻涓嶅惈绋庢�讳环
+	const inclusiveTotalPrice = parseFloat(productData.value[currentProductIndex.value].taxInclusiveTotalPrice)
+	const taxRate = parseFloat(item.value)
+	if (inclusiveTotalPrice && taxRate) {
+		productData.value[currentProductIndex.value].taxExclusiveTotalPrice =
+			calculateTaxExclusiveTotalPrice(inclusiveTotalPrice, taxRate)
 	}
-	// isCalculating.value = true;
-	// 璁$畻涓嶅惈绋庢�讳环
-	productData.value[currentProductIndex.value].taxExclusiveTotalPrice =
-		calculateTaxExclusiveTotalPrice(
-			inclusiveTotalPrice,
-			taxRate
-		);
-	// isCalculating.value = false;
 };
 
-const onInvoiceTypeConfirm = ({ selectedValues, selectedOptions }) => {
-	productData.value[currentProductIndex.value].invoiceType = selectedOptions[0]?.text;
-  pickerInvoiceTypeValue.value = [selectedValues[0]];
-  showInvoiceTypePicker.value = false;
+// 鍙戠エ绫诲瀷閫夋嫨浜嬩欢
+const onInvoiceTypeSelect = (item) => {
+	productData.value[currentProductIndex.value].invoiceType = item.name
 };
 
 // 鏍煎紡鍖栧嚱鏁� - 鍥哄畾涓や綅灏忔暟
@@ -698,16 +795,36 @@
 	uni.removeStorageSync('editData');
 	uni.navigateBack();
 };
-const onSubmit = () => {
-	if (productData.value !== null && productData.value.length > 0) {
-		form.value.productData = JSON.parse(JSON.stringify(productData.value));
-	} else {
+const onSubmit = async () => {
+	// 棣栧厛鏍¢獙鍩烘湰琛ㄥ崟
+	const formValid = await formRef.value.validate().catch(() => false);
+	if (!formValid) {
+		return;
+	}
+	
+	// 鏍¢獙浜у搧淇℃伅
+	if (!productData.value || productData.value.length === 0) {
 		uni.showToast({
 			title: '璇锋坊鍔犱骇鍝佷俊鎭�',
 			icon: 'none'
 		});
-		return
+		return;
 	}
+	
+	// 妫�鏌ユ瘡涓骇鍝佹槸鍚﹀~鍐欏畬鏁�
+	for (let i = 0; i < productData.value.length; i++) {
+		const errors = validateProduct(productData.value[i], i);
+		if (errors.length > 0) {
+			uni.showToast({
+				title: errors[0],
+				icon: 'none'
+			});
+			return;
+		}
+	}
+	
+	// 琛ㄥ崟鏍¢獙閫氳繃锛屾彁浜ゆ暟鎹�
+	form.value.productData = JSON.parse(JSON.stringify(productData.value));
 	form.value.type = 1;
 	addOrUpdateSalesLedger(form.value).then((res) => {
 		uni.showToast({
@@ -726,7 +843,8 @@
 	const month = String(today.getMonth() + 1).padStart(2, '0')
 	const day = String(today.getDate()).padStart(2, '0')
 	form.value.entryDate = `${year}-${month}-${day}`
-	pickerDateValue.value = [year.toString(), month.toString(), day.toString()]
+	// 璁剧疆鏃ユ湡閫夋嫨鍣ㄩ粯璁ゅ�间负浠婂ぉ
+	pickerDateValue.value = `${year}-${month}-${day}`
 }
 // 濉厖琛ㄥ崟鏁版嵁锛堢紪杈戞ā寮忥級
 const fillFormData = () => {
@@ -748,47 +866,30 @@
   form.value.entryDate = editData.value.entryDate || '';
   form.value.id = editData.value.id || '';
   form.value.customerId = editData.value.customerId || '';
-	
-  // 璁剧疆涓氬姟鍛橀�夋嫨鍣ㄧ殑鍊�
-  if (editData.value.salesman) {
-    const salesmanIndex = userList.value.findIndex(user => user.text === editData.value.salesman);
-    if (salesmanIndex !== -1) {
-      pickerValue.value = [userList.value[salesmanIndex].value];
-    }
-  }
-  
-  // 璁剧疆瀹㈡埛閫夋嫨鍣ㄧ殑鍊�
-  if (editData.value.customerName) {
-    const customerIndex = customerOption.value.findIndex(customer => customer.text === editData.value.customerName);
-    if (customerIndex !== -1) {
-      pickerCustomerValue.value = [customerOption.value[customerIndex].value]
-    }
-  }
   
   // 璁剧疆鏃ユ湡閫夋嫨鍣ㄧ殑鍊�
   if (editData.value.executionDate) {
-		pickerDateValue.value = editData.value.executionDate.split('-').map(num => parseInt(num, 10))
-		console.log(pickerDateValue.value)
+		pickerDateValue.value = editData.value.executionDate
 	}
 };
 const getUserList = () => {
 	userListNoPage().then((res) => {
-		// 纭繚鏁版嵁鏍煎紡姝g‘
-		userList.value = [res.data.map(user => ({
+		// 绉婚櫎澶氫綑鐨勬暟缁勫寘瑁�
+		userList.value = res.data.map(user => ({
 			text: user.nickName,
 			value: user.nickName
-		}))];
+		}));
 	})
-}
+};
 const getCustomerList = () => {
 	customerList().then((res) => {
-		// 纭繚鏁版嵁鏍煎紡姝g‘
-		customerOption.value = [res.map(item => ({
+		// 绉婚櫎澶氫綑鐨勬暟缁勫寘瑁�
+		customerOption.value = res.map(item => ({
 			text: item.customerName,
 			value: item.id
-		}))];
+		}));
 	})
-}
+};
 const convertIdToValue = (data) => {
 	// 濡傛灉浼犲叆鐨勪笉鏄暟缁勶紝鍒欒繑鍥炵┖鏁扮粍
 	if (!Array.isArray(data)) {
@@ -814,6 +915,41 @@
 		productOptions.value = convertIdToValue(res);
 	});
 };
+// 鍗曚釜浜у搧琛ㄥ崟楠岃瘉鍑芥暟
+const validateProduct = (product, index) => {
+	const errors = [];
+	
+	if (!product.productCategory) {
+		errors.push(`浜у搧${index + 1}锛氳閫夋嫨浜у搧澶х被`);
+	}
+	if (!product.specificationModel) {
+		errors.push(`浜у搧${index + 1}锛氳閫夋嫨瑙勬牸鍨嬪彿`);
+	}
+	if (!product.unit) {
+		errors.push(`浜у搧${index + 1}锛氳杈撳叆鍗曚綅`);
+	}
+	if (!product.taxRate) {
+		errors.push(`浜у搧${index + 1}锛氳閫夋嫨绋庣巼`);
+	}
+	if (!product.taxInclusiveUnitPrice || parseFloat(product.taxInclusiveUnitPrice) <= 0) {
+		errors.push(`浜у搧${index + 1}锛氳杈撳叆鏈夋晥鐨勫惈绋庡崟浠穈);
+	}
+	if (!product.quantity || parseFloat(product.quantity) <= 0) {
+		errors.push(`浜у搧${index + 1}锛氳杈撳叆鏈夋晥鐨勬暟閲廯);
+	}
+	if (!product.taxInclusiveTotalPrice || parseFloat(product.taxInclusiveTotalPrice) <= 0) {
+		errors.push(`浜у搧${index + 1}锛氳杈撳叆鏈夋晥鐨勫惈绋庢�讳环`);
+	}
+	if (!product.taxExclusiveTotalPrice || parseFloat(product.taxExclusiveTotalPrice) <= 0) {
+		errors.push(`浜у搧${index + 1}锛氳杈撳叆鏈夋晥鐨勪笉鍚◣鎬讳环`);
+	}
+	if (!product.invoiceType) {
+		errors.push(`浜у搧${index + 1}锛氳閫夋嫨鍙戠エ绫诲瀷`);
+	}
+	
+	return errors;
+};
+
 onMounted(() => {
 	// 鑾峰彇椤甸潰鍙傛暟
 	operationType.value = uni.getStorageSync('operationType') || '';
@@ -848,226 +984,6 @@
 });
 </script>
 
-<style scoped lang="scss">
-.account-detail {
-  min-height: 100vh;
-  background: #f8f9fa;
-  padding-bottom: 5rem;
-}
-
-.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;
-	/* 鍏煎 iOS 鍒樻捣/鐏靛姩宀涘畨鍏ㄥ尯 */
-	padding-top: env(safe-area-inset-top);
-}
-
-.title {
-  flex: 1;
-  text-align: center;
-  font-size: 1.125rem;
-  font-weight: 600;
-  color: #333;
-}
-
-.form-section {
-	margin-top: 1rem;
-}
-.van-field {
-	height: 3.4rem;
-}
-.van-cell {
-	align-items: center;
-}
-.product-section {
-  background: #fff;
-	margin-top: 1rem;
-  padding: 1rem;
-  box-shadow: 0 0.125rem 0.5rem rgba(0,0,0,0.04);
-}
-
-.section-header {
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-  margin-bottom: 1rem;
-}
-
-.section-title {
-  font-size: 1rem;
-  font-weight: 600;
-  color: #333;
-}
-
-.product-card {
-	background: #FFFFFF;
-	box-shadow: 0 0 1.25rem 0 rgba(0,57,117,0.08);
-	border-radius: 0.5rem 0.5rem 0.5rem 0.5rem;
-  padding: 1rem 0.5rem 0 0.5rem;
-  position: relative;
-}
-
-.product-header {
-  display: flex;
-  align-items: center;
-	justify-content: space-between;
-  padding: 0 0.5rem 0.75rem 0.5rem;
-  border-bottom: 0.0625rem solid #e8e8e8;
-}
-
-.product-productCategory {
-  margin-left: 0.5rem;
-  font-size: 0.875rem;
-  font-weight: 500;
-  color: #333;
-}
-
-.info-grid {
-  display: grid;
-  grid-template-columns: 1fr 1fr;
-  gap: 0.75rem;
-  margin-bottom: 1rem;
-}
-
-.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-form {
-  margin-bottom: 1rem;
-}
-
-.popup-header {
-	display: flex;
-	justify-content: space-between;
-	align-items: center;
-	padding: 1rem;
-	background: #fff;
-	position: sticky;
-	top: 0;
-	z-index: 10;
-}
-
-.cancelButton {
-	color: #969799
-}
-
-.confirmButton {
-	color: #1989FA
-}
-
-.u-tree {
-	height: 13rem;
-}
-
-/* 绉婚櫎 input 杈规鐨勬牱寮� */
-:deep(.u-input) {
-  border: none !important;
-  box-shadow: none !important;
-  background: transparent !important;
-}
-
-:deep(.u-input__content) {
-  border: none !important;
-  box-shadow: none !important;
-  background: transparent !important;
-}
-
-:deep(.u-input__content__field-wrapper) {
-  border: none !important;
-  box-shadow: none !important;
-  background: transparent !important;
-}
-
-:deep(.u-input__content__field-wrapper__field) {
-  border: none !important;
-  box-shadow: none !important;
-  background: transparent !important;
-  outline: none !important;
-}
-
-/* 绉婚櫎 textarea 杈规鐨勬牱寮� */
-:deep(.u-textarea) {
-  border: none !important;
-  box-shadow: none !important;
-  background: transparent !important;
-}
-
-:deep(.u-textarea__content) {
-  border: none !important;
-  box-shadow: none !important;
-  background: transparent !important;
-}
-
-:deep(.u-textarea__content__field) {
-  border: none !important;
-  box-shadow: none !important;
-  background: transparent !important;
-  outline: none !important;
-}
-
-/* 绉婚櫎 form-item 鐨勮竟妗� */
-:deep(.u-form-item) {
-  border: none !important;
-}
-
-:deep(.u-form-item__body) {
-  border: none !important;
-}
-
-/* 淇濇寔鍒嗗壊绾挎牱寮� */
-:deep(.u-form-item--border-bottom) {
-  border-bottom: 1px solid #ebeef5 !important;
-}
-
-/* 閫夋嫨鍣ㄥご閮ㄦ牱寮� */
-.picker-header {
-	display: flex;
-	justify-content: space-between;
-	align-items: center;
-	padding: 15px 20px;
-	background: #fff;
-	border-bottom: 1px solid #ebeef5;
-}
-
-.picker-cancel {
-	color: #909399;
-	font-size: 16px;
-}
-
-.picker-title {
-	color: #303133;
-	font-size: 16px;
-	font-weight: 500;
-}
-
-.picker-confirm {
-	color: #2979ff;
-	font-size: 16px;
-}
+<style lang="scss">
+@import '@/static/scss/form-common.scss';
 </style>

--
Gitblit v1.9.3