Browse Source

新物料增加

wuhb 3 months ago
parent
commit
74d607d772

+ 36 - 0
api/apply/index.uts

@@ -93,3 +93,39 @@ export const getPurchaseApplyById = (applyId: string): Promise<any> => {
 		method: 'GET'
 	})
 }
+
+/**
+ * 新增物料
+ * @param data 物料数据
+ * @returns 
+ */
+export const addMaterial = (data: UTSJSONObject | null): Promise<any> => {
+	return request({
+		url: '/mes/md/mditem',
+		method: 'POST',
+		data: data
+	})
+}
+
+/**
+ * 删除采购申请
+ * @param applyId 申请ID
+ * @returns 
+ */
+export const deletePurchaseApply = (applyId: string): Promise<any> => {
+	return request({
+		url: `/mes/wm/purchaseApply/${applyId}`,
+		method: 'DELETE'
+	})
+}
+
+/**
+ * 获取单位列表
+ * @returns 
+ */
+export const getMeasureList = (): Promise<any> => {
+	return request({
+		url: '/mes/md/unitmeasure/selectall',
+		method: 'GET'
+	})
+}

+ 1 - 1
pages.json

@@ -155,7 +155,7 @@
 			}
 		},
 		{
-			"path": "pages/apply/outStockList",
+			"path": "pages/out/index",
 			"style": {
 				"navigationBarTitleText": "出库单列表",
 				"navigationStyle": "custom"

+ 38 - 2
pages/apply/applyInfo.uvue

@@ -66,6 +66,7 @@
 
         <!-- 底部按钮 -->
         <view v-if="applyStatus != null && applyStatus.trim() == 'PREPARE'" class="bottom-buttons">
+            <button class="delete-btn" @click="handleDelete">删除</button>
             <button class="confirm-btn" @click="handleConfirm">确认申请</button>
         </view>
     </view>
@@ -73,7 +74,7 @@
 
 <script setup lang="uts">
     import { ref, computed } from 'vue'
-    import { getPurchaseApplyById, confirmPurchaseApply } from '../../api/apply/index'
+    import { getPurchaseApplyById, confirmPurchaseApply, deletePurchaseApply } from '../../api/apply/index'
 
     const applyId = ref<string>("")
     const applyCode = ref<string>("")
@@ -183,6 +184,27 @@
         })
     }
 
+    const handleDelete = (): void => {
+        uni.showModal({
+            title: '提示',
+            content: '确定要删除该申请单吗?',
+            success: (res) => {
+                if (res.confirm) {
+                    deletePurchaseApply(applyId.value).then((res: any) => {
+                        uni.showToast({ title: '删除成功', icon: 'success' })
+                        setTimeout(() => {
+                            uni.navigateBack()
+                        }, 1500)
+                    }).catch((e) => {
+                        const error = e as UTSError
+                        const errMsg = error?.message
+                        uni.showToast({ title: errMsg.toString(), icon: 'none' })
+                    })
+                }
+            }
+        })
+    }
+
     onLoad((options: any) => {
 		const params = options as UTSJSONObject
         if (params != null && params['id'] != null) {
@@ -378,10 +400,24 @@
         padding: 20rpx 30rpx;
         background-color: #ffffff;
         border-top: 1rpx solid #e5e5e5;
+        flex-direction: row;
+        justify-content: space-between;
+    }
+
+    .delete-btn {
+        flex: 1;
+        height: 80rpx;
+        background-color: #ff4d4f;
+        color: #ffffff;
+        font-size: 28rpx;
+        font-weight: 600;
+        border-radius: 20rpx;
+        border: none;
+        margin-right: 20rpx;
     }
 
     .confirm-btn {
-        width: 100%;
+        flex: 1;
         height: 80rpx;
         background-color: #007aff;
         color: #ffffff;

+ 404 - 45
pages/apply/applyNew.uvue

@@ -6,7 +6,7 @@
 			<view class="search-bar">
 			    <view class="search-box">
 			        <image class="search-icon" src="/static/images/workbench/list/1.png" mode="aspectFit"></image>
-			        <input class="search-input" type="text" placeholder="请输入关键字查询" v-model="keyword" @confirm="handleSearch" confirm-type="search" />
+			        <input class="search-input" type="text" placeholder="请输入关键字查询" v-model="keyword" @input="handleSearch" />
 			        <view v-if="keyword.length > 0" class="clear-btn" @tap="clearKeyword">
 			        	<text class="clear-btn-text">×</text>
 			        </view>
@@ -32,20 +32,24 @@
 		</view>
 		<view class="section">
 				<view class="section-header">
-				    <view class="section-indicator"></view>
-				    <text class="section-title">物料列表</text>
+				    <view class="section-header-left">
+				    	<view class="section-indicator"></view>
+				    	<text class="section-title">物料列表</text>
+				    </view>
+				    <view class="add-material-btn" @click="showAddMaterialModal = true">
+				        <text class="add-material-text">新物料</text>
+				    </view>
 				</view>
 				<view class="material-list">
 					<view 
 						v-for="(item, index) in dataList" 
 						:key="item.itemId + '_' + page" 
 						class="list-item"
-						@click="handleItemClick(item, index)"
 					>
 						<view class="item-header">
 						    <view class="item-info">
 								<view class="item-name-row">
-									<text class="item-name">{{ getItemName(item) }}</text>
+									<text class="item-name" :class="{'status-0': getAuditStatus(item) == 0, 'status-2': getAuditStatus(item) == 3}">{{ getItemName(item) }}</text>
 									<text class="item-measure">{{ getMeasureName(item) }}</text>
 								</view>
 								<text class="item-sub-title">{{ getItemTypeName(item) }}</text>
@@ -53,6 +57,9 @@
 						    <view v-if="item.isSelected" class="added-btn">
 						        <text class="added-icon">已选</text>
 						    </view>
+						    <view v-else-if="isItemDisabled(item)" class="add-btn disabled">
+						        <text class="add-icon">+</text>
+						    </view>
 						    <view v-else class="add-btn" @click.stop="addToSelected(item)">
 						        <text class="add-icon">+</text>
 						    </view>
@@ -72,8 +79,10 @@
 			</view>
 			<view class="section">
 				<view class="section-header">
-				    <view class="section-indicator"></view>
-				    <text class="section-title">已选列表</text>
+				    <view class="section-header-left">
+				    	<view class="section-indicator"></view>
+				    	<text class="section-title">已选列表</text>
+				    </view>
 				</view>
 				<view class="selected-list">
 					<view v-if="selectedItems.length === 0" class="empty-tip">
@@ -116,15 +125,78 @@
 				<button class="confirm-btn" @click="confirmApplication">确认申请</button>
 			</view>
 		</view>
+		
+		<!-- 新增物料弹窗 -->
+		<view v-if="showAddMaterialModal" class="picker-modal">
+		    <view class="modal-mask" @click="showAddMaterialModal = false"></view>
+		    <view class="modal-content">
+		        <view class="modal-header">
+		            <text class="modal-title">新增物料</text>
+		            <text class="modal-close" @click="showAddMaterialModal = false">取消</text>
+		        </view>
+				<view class="form-item-input">
+				    <text class="label-picker">物料名称</text>
+				    <view class="view-input-picker">
+				        <input class="input-picker" type="text" placeholder="请输入物料名称" v-model="newMaterial.itemName" />
+				    </view>
+				</view>
+				<view class="form-item-input">
+				    <text class="label-picker">规格型号</text>
+				    <view class="view-input-picker">
+				        <input class="input-picker" type="text" placeholder="请输入规格型号" v-model="newMaterial.specification" />
+				    </view>
+				</view>
+				<view class="form-item-input">
+				    <text class="label-picker">单位</text>
+				    <view class="view-input-picker measure-input-row">
+				        <input class="input-picker" type="text" placeholder="请输入或选择单位" v-model="newMaterial.measureName" />
+				        <view class="pick-btn" @click="showMeasurePicker = true">
+				        	<text class="pick-btn-text">选择</text>
+				        </view>
+				    </view>
+				</view>
+				<view class="form-item-btn">
+					<button class="btn-primary" @click="handleAddMaterial">
+						保存
+					</button>
+				</view>
+		    </view>
+		</view>
+		
+		<!-- 单位选择弹窗 -->
+		<view v-if="showMeasurePicker" class="picker-modal">
+		    <view class="modal-mask" @click="showMeasurePicker = false"></view>
+		    <view class="modal-content">
+		        <view class="modal-header">
+		            <text class="modal-title">选择单位</text>
+		            <text class="modal-close" @click="showMeasurePicker = false">取消</text>
+		        </view>
+				<scroll-view class="measure-list" :scroll-y="true">
+					<view 
+						v-for="(item, index) in measureList" 
+						:key="index" 
+						class="measure-item"
+						@click="selectMeasure(item)"
+					>
+						<text class="measure-name">{{ item['measureName'] }}</text>
+					</view>
+					<view v-if="measureList.length === 0" class="empty-tip">
+						<text class="empty-tip-text">暂无单位数据</text>
+					</view>
+				</scroll-view>
+		    </view>
+		</view>
 	</view>
 </template>
 
 <script setup lang="uts">
 	import { ref, computed, onBeforeUnmount, onMounted } from 'vue'
-	import { getItemTypeListByParentId, getItemList, savePurchaseApply, confirmPurchaseApply } from '../../api/apply/index'
+import { getItemTypeListByParentId, getItemList, savePurchaseApply, confirmPurchaseApply, addMaterial, getMeasureList } from '../../api/apply/index'
+
+let searchTimer: number | null = null
 	
 	type CategoryItem = { id: string; name: string; code: string }
-	type Item = { itemId: string; itemName: string; itemTypeName: string; measureName: string; isSelected?: boolean }
+	type Item = { itemId: string; itemName: string; itemTypeName: string; measureName: string; isSelected?: boolean; auditStatus?: number }
 	type SelectedItem = { itemId: string; itemName: string; itemTypeName: string; measureName: string; qty: string }
 	
 	const keyword = ref<string>("")
@@ -145,8 +217,44 @@
 	const categories = ref<CategoryItem[]>([])
 	
 	const dealLoad = ref<boolean>(false) 
-	let currentStatus = ref<string>('')
-	const isSearching = ref<boolean>(false)
+let currentStatus = ref<string>('')
+const isSearching = ref<boolean>(false)
+
+// 新增物料相关
+const showAddMaterialModal = ref<boolean>(false)
+const showMeasurePicker = ref<boolean>(false)
+const measureList = ref<UTSJSONObject[]>([])
+
+type NewMaterial = {
+	itemName: string
+	specification: string
+	measureName: string
+}
+const newMaterial = ref<NewMaterial>({
+    itemName: '',
+    specification: '',
+    measureName: ''
+})
+
+// 加载单位列表
+const loadMeasureList = (): void => {
+	getMeasureList().then((res: any) => {
+		const data = res as UTSJSONObject
+		const list = data['data']
+		if (list != null) {
+			measureList.value = list as UTSJSONObject[]
+		}
+	}).catch(() => {
+		measureList.value = []
+	})
+}
+
+// 选择单位
+const selectMeasure = (item: UTSJSONObject): void => {
+	const measureName = item['measureName'] != null ? item['measureName'].toString() : ''
+	newMaterial.value.measureName = measureName
+	showMeasurePicker.value = false
+}
 	
 	// 获取当前选中的分类code
 	const getCurrentCategoryCode = (): string => {
@@ -172,12 +280,22 @@
 					const selectedIds = selectedItems.value.map((s: SelectedItem) => s.itemId)
 					listData.forEach((item: UTSJSONObject) => {
 						const itemId = item['itemId'] != null ? item['itemId'].toString() : ''
+						let auditStatus = -1
+						const auditStatusVal = item['auditStatus']
+						if (auditStatusVal != null) {
+							if (typeof auditStatusVal === 'number') {
+								auditStatus = auditStatusVal as number
+							} else {
+								auditStatus = parseInt(auditStatusVal.toString())
+							}
+						}
 						const it: Item = {
 							itemId: itemId,
 							itemName: item['itemName'] != null ? item['itemName'].toString() : '',
 							itemTypeName: item['itemTypeName'] != null ? item['itemTypeName'].toString() : '',
 							measureName: item['measureName'] != null ? item['measureName'].toString() : '',
-							isSelected: selectedIds.includes(itemId)
+							isSelected: selectedIds.includes(itemId),
+							auditStatus: auditStatus
 						}
 						arr.push(it)
 					})
@@ -256,6 +374,11 @@
 	const addToSelected = (item: any | null): void => {
 		if (item == null) return
 		const mdItem = item as Item
+		// 检查审核状态
+		if (mdItem.auditStatus != null && mdItem.auditStatus === 2) {
+			uni.showToast({ title: '该物料已禁用,无法添加', icon: 'none' })
+			return
+		}
 		// 检查是否已存在
 		const exists = selectedItems.value.find((s: SelectedItem) => s.itemId === mdItem.itemId)
 		if (exists != null) {
@@ -277,7 +400,7 @@
 		}
 	}
 	
-	// 删除已选物料
+	// 删除已选
 	const removeSelected = (index: number): void => {
 		const removedItem = selectedItems.value[index]
 		selectedItems.value.splice(index, 1)
@@ -322,6 +445,19 @@
 	    return mdItem.measureName
 	}
 	
+	const getAuditStatus = (item: any | null): number => {
+	    if (item == null) return -1
+	    const mdItem = item as Item
+	    return mdItem.auditStatus != null ? mdItem.auditStatus : -1
+	}
+	
+	const isItemDisabled = (item: any | null): boolean => {
+	    if (item == null) return false
+	    const mdItem = item as Item
+	    const status = mdItem.auditStatus != null ? mdItem.auditStatus : -1
+	    return status == 3
+	}
+	
 	// 检查物料是否已被选择
 	const isItemSelected = (item: any | null): boolean => {
 	    if (item == null) return false
@@ -330,8 +466,14 @@
 	}
 
 	const handleSearch = (): void => {
-	    page.value = 1
-	    loadItems()
+		const timer = searchTimer
+		if (timer != null) {
+			clearTimeout(timer)
+		}
+		searchTimer = setTimeout(() => {
+			page.value = 1
+			loadItems()
+		}, 300)
 	}
 	
 	const clearKeyword = (): void => {
@@ -447,16 +589,61 @@
 			uni.showToast({ title: errMsg.toString(), icon: 'none' })
 		})
 	}
-	onMounted(() => {
-		loadCategories()
-	// 获取页面参数,判断是否从index.uvue跳转过来
-		const pages = getCurrentPages()
-		const currentPage = pages[pages.length - 1]
-		const options = currentPage.options
-		if (options != null && options.from == 'index') {
-			fromIndexPage.value = true
-		}
-	})
+	// 处理新增物料
+const handleAddMaterial = async (): Promise<void> => {
+	// 验证输入
+	if (newMaterial.value.itemName.length == 0) {
+		uni.showToast({ title: '请输入物料名称', icon: 'none' })
+		return
+	}
+	if (newMaterial.value.measureName.length == 0) {
+		uni.showToast({ title: '请输入单位', icon: 'none' })
+		return
+	}
+	
+	try {
+		// 构建物料数据
+		const materialData = new UTSJSONObject()
+		materialData['itemShortName'] = newMaterial.value.itemName
+		materialData['itemName'] = newMaterial.value.itemName + "("+newMaterial.value.specification+")"
+		materialData['specification'] = newMaterial.value.specification
+		materialData['measureName'] = newMaterial.value.measureName
+		materialData['auditStatus'] = 0 // 审核状态为0
+		
+		// 调用接口保存物料
+		await addMaterial(materialData)
+		
+		// 保存成功
+		uni.showToast({ title: '物料新增成功', icon: 'success' })
+		
+		// 关闭弹窗
+		showAddMaterialModal.value = false
+		
+		// 清空表单
+		newMaterial.value = {
+			itemName: '',
+			specification: '',
+			measureName: ''
+		} as NewMaterial
+		
+		// 重新加载物料列表
+		loadItems()
+	} catch (e: any) {
+		uni.showToast({ title: e.message ?? '物料新增失败', icon: 'none' })
+	}
+}
+
+onMounted(() => {
+	loadCategories()
+	loadMeasureList()
+// 获取页面参数,判断是否从index.uvue跳转过来
+	const pages = getCurrentPages()
+	const currentPage = pages[pages.length - 1]
+	const options = currentPage.options
+	if (options != null && options.from == 'index') {
+		fromIndexPage.value = true
+	}
+})
 </script>
 
 <style lang="scss">
@@ -480,11 +667,29 @@
 	    background: #ffffff;
 	    border-radius: 16rpx;
 	
-	    &-header {
-	        flex-direction: row;
-	        align-items: center;
-	        padding: 30rpx 10rpx 20rpx;
-	    }
+		.section-header {
+			flex-direction: row;
+			align-items: center;
+			justify-content: space-between;
+			padding: 30rpx 10rpx 20rpx;
+		}
+		
+		.section-header-left {
+			flex-direction: row;
+			align-items: center;
+		}
+				    
+		.add-material-btn {
+			padding: 8rpx 16rpx;
+			background-color: #007aff;
+			border-radius: 8rpx;
+		}
+		
+		.add-material-text {
+			color: #ffffff;
+			font-size: 24rpx;
+			font-weight: bold;
+		}
 	
 	    &-indicator {
 	        width: 6rpx;
@@ -606,7 +811,15 @@
 		    font-size: 28rpx;
 		    color: #333333;
 		    font-weight: bold;
+		
+		&.status-0 {
+			color: #ff4d4f;
+		}
+		
+		&.status-2 {
+			color: #999999;
 		}
+	}
 	.item-name-row {
 			flex-direction: row;
 			align-items: center;
@@ -632,14 +845,13 @@
 	        height: 44rpx;
 	        border-radius: 22rpx;
 	        background-color: #165DFF;
+			color: #FFFFFF;
 	        align-items: center;
 	        justify-content: center;
 	    }
 	
-	.add-icon {
-	        color: #FFFFFF;
-	        font-size: 28rpx;
-	        font-weight: bold;
+	.add-btn.disabled {
+	        background-color: #cccccc;
 	    }
 	    
 	.added-btn {
@@ -837,16 +1049,163 @@
 	}
 
 	.confirm-btn {
-		flex: 1;
-		height: 80rpx;
-		background-color: #007aff;
-		color: #ffffff;
-		font-size: 28rpx;
-		font-weight: 600;
-		border-radius: 20rpx;
-		margin-left: 10rpx;
-		border: none;
-		box-shadow: 0 2rpx 8rpx rgba(0, 122, 255, 0.3);
-	}
+			flex: 1;
+			height: 80rpx;
+			background-color: #007aff;
+			color: #ffffff;
+			font-size: 28rpx;
+			font-weight: 600;
+			border-radius: 20rpx;
+			margin-left: 10rpx;
+			border: none;
+			box-shadow: 0 2rpx 8rpx rgba(0, 122, 255, 0.3);
+		}
+
+		/* 新增物料弹窗样式 */
+		.picker-modal {
+			position: fixed;
+			top: 0;
+			left: 0;
+			right: 0;
+			bottom: 0;
+			z-index: 1000;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+		}
+
+		.modal-mask {
+			position: absolute;
+			top: 0;
+			left: 0;
+			right: 0;
+			bottom: 0;
+			background-color: rgba(0, 0, 0, 0.5);
+		}
+
+		.modal-content {
+			position: relative;
+			width: 90%;
+			// max-width: 500rpx;
+			background-color: #ffffff;
+			border-radius: 16rpx;
+			padding: 30rpx;
+			box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.15);
+		}
+
+		.modal-header {
+			display: flex;
+			flex-direction: row;
+			justify-content: space-between;
+			align-items: center;
+			margin-bottom: 30rpx;
+			padding-bottom: 20rpx;
+			border-bottom: 1rpx solid #e5e5e5;
+		}
+
+		.modal-title {
+			font-size: 32rpx;
+			font-weight: bold;
+			color: #333333;
+		}
+
+		.modal-close {
+			font-size: 28rpx;
+			color: #999999;
+			padding: 8rpx 16rpx;
+			border-radius: 8rpx;
+			background-color: #f5f5f5;
+		}
+
+		.form-item-input {
+			display: flex;
+			flex-direction: column;
+			margin-bottom: 24rpx;
+		}
+
+		.label-picker {
+			font-size: 28rpx;
+			color: #333333;
+			margin-bottom: 12rpx;
+			font-weight: 500;
+		}
+
+		.view-input-picker {
+			position: relative;
+			width: 100%;
+		}
+
+		.input-picker {
+			width: 100%;
+			height: 80rpx;
+			padding: 0 24rpx;
+			background-color: #f5f5f5;
+			border-radius: 12rpx;
+			font-size: 28rpx;
+			color: #333333;
+			border: 1rpx solid #e5e5e5;
+		}
+
+		.input-picker:focus {
+			outline: none;
+			border-color: #007aff;
+			background-color: #ffffff;
+		}
 
+		.form-item-btn {
+			margin-top: 30rpx;
+			display: flex;
+			justify-content: center;
+		}
+
+		.btn-primary {
+			width: 100%;
+			height: 80rpx;
+			background-color: #007aff;
+			color: #ffffff;
+			font-size: 28rpx;
+			font-weight: 600;
+			border-radius: 12rpx;
+			border: none;
+			box-shadow: 0 2rpx 8rpx rgba(0, 122, 255, 0.3);
+		}
+		.add-icon{
+			color: #ffffff;
+		}
+		
+		.measure-list {
+			max-height: 500rpx;
+			overflow-y: auto;
+		}
+		
+		.measure-item {
+			padding: 24rpx;
+			border-bottom: 1rpx solid #f0f0f0;
+		}
+		
+		.measure-name {
+			font-size: 28rpx;
+			color: #333333;
+		}
+		
+		.measure-input-row {
+			flex-direction: row;
+			align-items: center;
+		}
+		
+		.measure-input-row .input-picker {
+			flex: 1;
+			margin-right: 16rpx;
+		}
+		
+		.pick-btn {
+			padding: 16rpx 24rpx;
+			background-color: #007aff;
+			border-radius: 8rpx;
+		}
+		
+		.pick-btn-text {
+			color: #ffffff;
+			font-size: 26rpx;
+		}
 </style>

+ 9 - 3
pages/apply/index.uvue

@@ -6,7 +6,7 @@
             <view class="search-bar">
                 <view class="search-box">
                     <image class="search-icon" src="/static/images/workbench/list/1.png" mode="aspectFit"></image>
-                    <input class="search-input" type="text" placeholder="请输入申请单号查询" v-model="keyword" @confirm="handleSearch" />
+                    <input class="search-input" type="text" placeholder="请输入申请单号查询" v-model="keyword" @input="handleSearch" />
                     <view v-if="keyword.length > 0" class="clear-btn" @tap="clearKeyword">
                     	<text class="clear-btn-text">×</text>
                     </view>
@@ -109,6 +109,7 @@
     // 列表数据
     const dataList = ref<any[]>([])
     const keyword = ref<string>("")
+    let searchTimer: number | null = null
     const currentStatus = ref<string>("")
     const page = ref<number>(1)
     const pageSize: number = 10
@@ -238,8 +239,13 @@
 
     // 搜索
     const handleSearch = (): void => {
-        const searchKeyword = keyword.value != null ? keyword.value : ''
-        loadData(true)
+		const timer = searchTimer
+		if (timer != null) {
+			clearTimeout(timer)
+		}
+		searchTimer = setTimeout(() => {
+			loadData(true)
+		}, 300)
     }
 
     // 清空搜索关键字

+ 1 - 1
pages/index/index.uvue

@@ -68,7 +68,7 @@
             title: '出库单',
             bgImage: '/static/images/workbench/2.png',
             icon: '',
-            path: '/pages/apply/outStockList',
+            path: '/pages/out/index',
 			badge: 2
         },
         {

+ 10 - 3
pages/item/index.uvue

@@ -9,7 +9,7 @@
 		        <view class="search-bar">
 		            <view class="search-box">
 		                <image class="search-icon" src="/static/images/workbench/list/1.png" mode="aspectFit"></image>
-		                <input class="search-input" type="text" placeholder="请输入关键字查询" v-model="keyword" @confirm="handleSearch" />
+			                <input class="search-input" type="text" placeholder="请输入关键字查询" v-model="keyword" @input="handleSearch" />
 		                <view v-if="keyword.length > 0" class="clear-btn" @tap="clearKeyword">
 		                	<text class="clear-btn-text">×</text>
 		                </view>
@@ -78,6 +78,7 @@
     // 列表数据
     const dataList = ref<any[]>([])
     const keyword = ref<string>("")
+    let searchTimer: number | null = null
     const page = ref<number>(1)
     const pageSize: number = 10
     const hasMore = ref<boolean>(true)
@@ -251,8 +252,14 @@
 
     // 搜索
     const handleSearch = (): void => {
-        page.value = 1
-        loadData(true)
+		const timer = searchTimer
+		if (timer != null) {
+			clearTimeout(timer)
+		}
+		searchTimer = setTimeout(() => {
+			page.value = 1
+			loadData(true)
+		}, 300)
     }
 
     // 清空搜索关键字

+ 0 - 0
pages/apply/outStockList.uvue → pages/out/index.uvue