Jelajahi Sumber

增加待领取

wuhb 1 bulan lalu
induk
melakukan
231a2c50b4

+ 18 - 1
api/apply/index.uts

@@ -66,9 +66,11 @@ export const confirmPurchaseApply = (data: UTSJSONObject | null): Promise<any> =
  * @param pageSize 每页数量
  * @param keyword 关键字
  * @param status 状态
+ * @param userId 用户ID
+ * @param pendingReceive 是否待领取筛选
  * @returns 
  */
-export const getPurchaseApplyList = (pageNum: number, pageSize: number, keyword: string, status: string | null, userId: string): Promise<any> => {
+export const getPurchaseApplyList = (pageNum: number, pageSize: number, keyword: string, status: string | null, userId: string, pendingReceive: boolean): Promise<any> => {
 	let url = `/mes/wm/purchaseApply/list?pageNum=${pageNum}&pageSize=${pageSize}&createBy=${userId}`
 	if (keyword != null && keyword.length > 0) {
 		url += `&applyCode=${encodeURIComponent(keyword)}`
@@ -76,6 +78,9 @@ export const getPurchaseApplyList = (pageNum: number, pageSize: number, keyword:
 	if (status != null && status.length > 0) {
 		url += `&status=${encodeURIComponent(status)}`
 	}
+	if (pendingReceive != null && pendingReceive === true) {
+		url += `&pendingReceive=true`
+	}
 	return request({
 		url: url,
 		method: 'GET'
@@ -141,3 +146,15 @@ export const deleteMaterial = (itemId: string): Promise<any> => {
 		method: 'DELETE'
 	})
 }
+
+/**
+ * 获取物料申请待领取数量
+ * @param userId 用户ID
+ * @returns 
+ */
+export const getPendingReceiveApplyCount = (userId: string): Promise<any> => {
+	return request({
+		url: `/mes/wm/purchaseApply/countPendingReceive?createBy=${userId}`,
+		method: 'GET'
+	})
+}

+ 13 - 0
components/custom-tabbar/custom-tabbar.uvue

@@ -163,6 +163,16 @@
             url: item.pagePath
         })
     }
+	// 监听登录状态变化
+	const onAuthStateChange = (res: UTSJSONObject): void => {
+	    if (res != null && res['isLoggedIn'] === false) {
+	        stopRefreshTimer()
+	    } else if (res != null && res['isLoggedIn'] === true) {
+	        // 重新登录后重新启动timer
+	        startRefreshTimer()
+	        getUnreadMessageCount()
+	    }
+	}
 
     // 组件挂载时
     onMounted(() => {
@@ -172,6 +182,8 @@
         startRefreshTimer()
         // 监听未读消息数量更新事件
         uni.$on('updateUnreadCount', getUnreadMessageCount)
+        // 监听登录状态变化,清除timer
+        uni.$on('onAuthStateChange', onAuthStateChange)
     })
 
     // 组件卸载时
@@ -180,6 +192,7 @@
         stopRefreshTimer()
         // 移除事件监听
         uni.$off('updateUnreadCount', getUnreadMessageCount)
+        uni.$off('onAuthStateChange', onAuthStateChange)
     })
 </script>
 

+ 2 - 0
composables/useAuth.uts

@@ -62,6 +62,8 @@ export const useAuth = (): AuthComposable => {
         clearAll()
         // 设置退出标志,防止自动登录
         uni.setStorageSync('isLogout', true)
+        // 触发登录状态变化事件
+        uni.$emit('onAuthStateChange', { isLoggedIn: false })
         // 跳转登录页
         uni.reLaunch({
             url: '/pages/login/index'

+ 121 - 14
pages/apply/index.uvue

@@ -17,7 +17,7 @@
             </view>
 
             <!-- 状态标签 -->
-            <view class="status-tabs">
+            <scroll-view class="status-tabs" scroll-x="true">
                 <view 
                     class="status-tab" 
                     :class="{ 'active': currentStatus === '' }" 
@@ -25,6 +25,13 @@
                 >
                     <text class="status-tab-text" :class="{ 'active-text': currentStatus === '' }">全部</text>
                 </view>
+				<view
+				    class="status-tab status-pending-receive" 
+				    :class="{ 'active': currentStatus === 'PENDING_RECEIVE' }" 
+				    @tap="handleStatusChange('PENDING_RECEIVE')"
+				>
+				    <text class="status-tab-text" :class="{ 'active-text': currentStatus === 'PENDING_RECEIVE' }">待领取</text>
+				</view>
                 <view 
                     class="status-tab" 
                     :class="{ 'active': currentStatus === 'PREPARE' }" 
@@ -53,7 +60,7 @@
                 >
                     <text class="status-tab-text" :class="{ 'active-text': currentStatus === 'APPROVED' }">已审批</text>
                 </view>
-            </view>
+            </scroll-view>
         </view>
 
         <!-- 列表内容 -->
@@ -86,12 +93,22 @@
                             </view>
                             <view class="info-row">
                                 <view class="info-item">
-                                    <text class="info-label">已完成</text>
-                                    <text class="info-value success">{{ getFinishedCount(item) }}</text>
+                                    <text class="info-label">待审核</text>
+                                    <text class="info-value warning">{{ getPendingAuditCount(item) }}</text>
+                                </view>
+                                <view class="info-item">
+                                    <text class="info-label">待领取</text>
+                                    <text class="info-value primary">{{ getPendingReceiveCount(item) }}</text>
+                                </view>
+                            </view>
+                            <view class="info-row">
+                                <view class="info-item">
+                                    <text class="info-label">待采购</text>
+                                    <text class="info-value warning">{{ getPendingPurchaseCount(item) }}</text>
                                 </view>
                                 <view class="info-item">
-                                    <text class="info-label">未完成</text>
-                                    <text class="info-value warning">{{ getUnfinishedCount(item) }}</text>
+                                    <text class="info-label">完成</text>
+                                    <text class="info-value success">{{ getFinishedCount(item) }}</text>
                                 </view>
                             </view>
                         </view>
@@ -104,7 +121,7 @@
 
 <script setup lang="uts">
     import { ref, onShow } from 'vue'
-    import { getPurchaseApplyList } from '../../api/apply/index'
+    import { getPurchaseApplyList, getPendingReceiveApplyCount } from '../../api/apply/index'
     import { getUserInfo } from '../../utils/storage'
 
     let currentUserId: string = ''
@@ -120,6 +137,19 @@
     const loading = ref<boolean>(false)
     const refreshing = ref<boolean>(false)
 	const showRight = ref<boolean>(false)
+    const pendingReceiveCount = ref<number>(0)
+
+    // 加载待领取数量
+    const loadPendingReceiveCount = (): void => {
+        if (currentUserId.length === 0) return
+        getPendingReceiveApplyCount(currentUserId).then((res: any) => {
+            const result = res as UTSJSONObject
+            const count = result['data']
+            pendingReceiveCount.value = count != null ? parseInt(count.toString()) : 0
+        }).catch((e) => {
+            console.error('加载待领取数量失败:', e)
+        })
+    }
 
     // 获取申请单号
     const getApplyCode = (item: any | null): string => {
@@ -178,11 +208,27 @@
         return val != null ? val.toString() : '0'
     }
 
-    // 获取未完成数量
-    const getUnfinishedCount = (item: any | null): string => {
+    // 获取待审核数量 (status=1)
+    const getPendingAuditCount = (item: any | null): string => {
+        if (item == null) return '0'
+        const jsonItem = item as UTSJSONObject
+        const val = jsonItem['pendingAuditCount']
+        return val != null ? val.toString() : '0'
+    }
+
+    // 获取待领取数量 (status=2 + status=4)
+    const getPendingReceiveCount = (item: any | null): string => {
         if (item == null) return '0'
         const jsonItem = item as UTSJSONObject
-        const val = jsonItem['unfinishedCount']
+        const val = jsonItem['pendingReceiveCount']
+        return val != null ? val.toString() : '0'
+    }
+
+    // 获取待采购数量 (status=3 + status=4)
+    const getPendingPurchaseCount = (item: any | null): string => {
+        if (item == null) return '0'
+        const jsonItem = item as UTSJSONObject
+        const val = jsonItem['pendingPurchaseCount']
         return val != null ? val.toString() : '0'
     }
 
@@ -198,11 +244,15 @@
             }
 
             const searchKeyword = keyword.value != null ? keyword.value : ''
-            const statusParam = currentStatus.value != null ? currentStatus.value : ''
-            const result = await getPurchaseApplyList(page.value, pageSize, searchKeyword, statusParam, currentUserId)
+            const isPendingReceive = currentStatus.value === 'PENDING_RECEIVE'
+            const statusParam = isPendingReceive ? '' : (currentStatus.value != null ? currentStatus.value : '')
+            console.log('loadData - statusParam:', statusParam, 'isPendingReceive:', isPendingReceive)
+            const result = await getPurchaseApplyList(page.value, pageSize, searchKeyword, statusParam, currentUserId, isPendingReceive)
+            console.log('getPurchaseApplyList result:', result)
             const resultObj = result as UTSJSONObject
             const rows = resultObj['rows']
             const total = resultObj['total'] as number
+            console.log('rows:', rows, 'total:', total)
 
             if (rows != null) {
                 const newData = rows as any[]
@@ -285,6 +335,7 @@
     // 页面显示时刷新列表
     onShow(() => {
         loadData(true)
+        loadPendingReceiveCount()
     })
 	
 	onMounted(() => {
@@ -315,6 +366,38 @@
         background-color: #ffffff;
     }
 
+    .pending-receive-bar {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        padding: 20rpx 30rpx;
+        background-color: #fff7e6;
+        border-left: 6rpx solid #fa8c16;
+        margin: 0 30rpx;
+        border-radius: 8rpx;
+    }
+
+    .pending-receive-label {
+        font-size: 28rpx;
+        color: #fa8c16;
+        font-weight: bold;
+    }
+
+    .pending-receive-count {
+        margin-left: 16rpx;
+        padding: 4rpx 16rpx;
+        background-color: #fa8c16;
+        color: #ffffff;
+        font-size: 24rpx;
+        border-radius: 20rpx;
+    }
+
+    .pending-receive-arrow {
+        margin-left: auto;
+        color: #999999;
+        font-size: 28rpx;
+    }
+
     .search-bar {
         padding: 20rpx 30rpx;
     }
@@ -324,12 +407,17 @@
         flex-direction: row;
         padding: 0rpx 30rpx 20rpx;
         background-color: #ffffff;
+        white-space: nowrap;
+        width: 100%;
     }
 
     .status-tab {
-        flex: 1;
-        padding: 16rpx 0;
+        display: inline-flex;
+        flex-direction: row;
+        align-items: center;
+        padding: 16rpx 24rpx;
         text-align: center;
+        position: relative;
         margin-right: 16rpx;
         border-radius: 8rpx;
         background-color: #f5f5f5;
@@ -354,6 +442,22 @@
                 font-weight: bold;
             }
         }
+
+        .tab-badge {
+            margin-left: 8rpx;
+            min-width: 32rpx;
+            height: 32rpx;
+            padding: 0 8rpx;
+            background-color: #ff3b30;
+            border-radius: 16rpx;
+            justify-content: center;
+            align-items: center;
+
+            .tab-badge-text {
+                font-size: 20rpx;
+                color: #ffffff;
+            }
+        }
     }
 
     .search-box {
@@ -501,6 +605,9 @@
                     &.warning {
                         color: #faad14;
                     }
+                    &.primary {
+                        color: #007aff;
+                    }
                 }
             }
         }

+ 27 - 2
pages/index/index.uvue

@@ -71,6 +71,7 @@
     import { ref, onMounted, onUnmounted } from 'vue'
     import { getUserInfo } from '../../utils/storage'
     import { getPendingReceiveLines, signReceiveLine, getProductSalseList } from '../../api/out/index'
+    import { getPendingReceiveApplyCount } from '../../api/apply/index'
     type QuickFunction = {
         id: number
         title: string
@@ -82,6 +83,7 @@
 	const receiveListData = ref<UTSJSONObject[]>([])
 	const receiveLoading = ref<boolean>(false)
 	let currentUserId: string = ''
+	let currentUserName: string = ''
 	let refreshTimer: number | null = null
 	let timerLock = false
 	
@@ -260,15 +262,34 @@ const loadReceiveList = (): void => {
 		}).catch((e) => {
 			console.error('加载出库单 badge 失败:', e)
 		})
-	}	
+	}
+	
+	// 加载物料申请待领取 badge 数量
+	const loadApplyBadge = (): void => {
+		if (currentUserName.length === 0) return
+		// 查询物料申请待领取数量
+		getPendingReceiveApplyCount(currentUserName).then((res: any) => {
+			const result = res as UTSJSONObject
+			const count = result['data']
+			// 更新快捷功能中的物料申请 badge
+			quickFunctions.value.forEach((functionItem) => {
+				if (functionItem.id === 1) {
+					functionItem.badge = count != null ? parseInt(count.toString()) : 0
+				}
+			})
+		}).catch((e) => {
+			console.error('加载物料申请 badge 失败:', e)
+		})
+	}
 	// 启动定时刷新
 	const startRefreshTimer = (): void => {
 	    stopRefreshTimer() // 先清除已有的定时器
 	    timerLock = true
 	    refreshTimer = setInterval(() => {
-	        if (currentUserId.length > 0) {
+	        if (currentUserId.length > 0 || currentUserName.length > 0) {
 				loadReceiveList()
 				loadOutstockBadge()
+				loadApplyBadge()
 			}
 		}, 5000) // 5秒刷新一次
 	}
@@ -279,11 +300,15 @@ const loadReceiveList = (): void => {
             const realName = userInfo['nickName'] as string | null
             userName.value = realName ?? '用户'
             const userId = userInfo['userId']
+            const userNameVal = userInfo['userName']
             currentUserId = userId != null ? userId.toString() : ''
+            currentUserName = userNameVal != null ? userNameVal.toString() : ''
             // 加载待签收列表
             loadReceiveList()
             // 加载出库单 badge 数量
             loadOutstockBadge()
+            // 加载物料申请 badge 数量
+            loadApplyBadge()
             // 启动定时刷新,每5秒刷新一次
             startRefreshTimer()
         }

+ 5 - 2
utils/request.uts

@@ -13,8 +13,8 @@ export type RequestConfig = {
 };
 
 // 基础 URL
-// const BASE_URL = "http://192.168.2.23:83";
-const BASE_URL = "http://192.168.189.43:83";
+const BASE_URL = "http://192.168.2.26:83";
+// const BASE_URL = "http://192.168.189.43:83";
 // const BASE_URL = "http://222.243.138.146:8150/prod-api" //测试服务器;
 // const BASE_URL = "http://222.243.138.146:880/prod-api" //正式服务器;
 
@@ -109,6 +109,9 @@ const handleLoginRedirect = (): void => {
         icon: "none",
     });
 
+    // 触发登录状态变化事件
+    uni.$emit('onAuthStateChange', { isLoggedIn: false });
+
     setTimeout(() => {
         uni.reLaunch({
             url: "/pages/login/index",