Kaynağa Gözat

feat:盘点

maliang 4 gün önce
ebeveyn
işleme
199ad41e72

+ 31 - 0
common/request/apis/inventoryTask.js

@@ -0,0 +1,31 @@
+//盘点任务列表
+export const taskStocktakingList = (
+  params,
+  config = { custom: { auth: true } }
+) => uni.$u.http.post(`/pda/taskStocktakingList`, params, config);
+//盘点任务详情
+export const taskStocktakingDetail = (
+  taskId,
+  config = { custom: { auth: true } }
+) => uni.$u.http.get(`/pda/taskStocktakingDetail/${taskId}`, config);
+//开始任务
+export const startTask = (taskId, config = { custom: { auth: true } }) =>
+  uni.$u.http.get(`/pda/startTask/${taskId}`, config);
+//负责人下拉列表
+export const creatorSpinnerList = (
+  taskId,
+  config = { custom: { auth: true } }
+) => uni.$u.http.get(`/pda/creatorSpinnerList/${taskId}`, config);
+//盘点任务详情-商品列表
+export const taskStocktakingItemList = (
+  params,
+  config = { custom: { auth: true } }
+) => uni.$u.http.post(`/pda/taskStocktakingItemList`, params, config);
+//提交盘点
+export const stocktaking = (params, config = { custom: { auth: true } }) =>
+  uni.$u.http.post(`/pda/stocktaking`, params, config);
+//获取商品类别树数据
+export const getMaterialCategoryTree = (
+  params,
+  config = { custom: { auth: true } }
+) => uni.$u.http.get(`/pda/getMaterialCategoryTree?id=`, { params }, config);

+ 132 - 127
pages.json

@@ -1,128 +1,133 @@
 {
-	"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
-		{
-			"path": "pages/index/index",
-			"style": {
-				"navigationBarTitleText": "首页"
-			},
-			"meta": {
-				"auth": false,
-				"sync": true,
-				"title": "推荐",
-				"group": "平台"
-			}
-		},
-		{
-			"path": "pages/login/login",
-			"style": {
-				"navigationBarTitleText": ""
-			}
-		},
-		{
-			"path": "pages/index/app-update",
-			"style": {
-				"navigationBarTitleText": ""
-			}
-		},
-		
-		{
-			"path": "pages/picking-task/index",
-			"style": {
-				"navigationBarTitleText": ""
-			}
-		},
-		{
-			"path": "pages/picking-task/delivery",
-			"style": {
-				"navigationBarTitleText": ""
-			}
-		},
-		{
-			"path": "pages/picking-task/detail",
-			"style": {
-				"navigationBarTitleText": ""
-			}
-		},
-		{
-			"path": "pages/index/notice-page",
-			"style": {
-				"navigationBarTitleText": ""
-			}
-		},
-		{
-			"path": "pages/inventory-inquiry/index",
-			"style": {
-				"navigationBarTitleText": ""
-			}
-		},
-		{
-			"path": "pages/goods/detail",
-			"style": {
-				"navigationBarTitleText": ""
-			}
-		},
-		{
-			"path": "pages/purchase/index",
-			"style": {
-				"navigationBarTitleText": ""
-			}
-		},
-		{
-			"path": "pages/purchase/put-storage",
-			"style": {
-				"navigationBarTitleText": ""
-			}
-		},
-		{
-			"path": "pages/purchase/detail",
-			"style": {
-				"navigationBarTitleText": ""
-			}
-		},
-		{
-			"path": "pages/check/index",
-			"style": {
-				"navigationBarTitleText": ""
-			}
-		},
-		{
-			"path" : "pages/inventory-task/taskDetail",
-			"style" : 
-			{
-				"navigationBarTitleText" : "",
-				"enablePullDownRefresh": true,
-				"onReachBottomDistance": 50,
-				"app-plus": {
-					"bounce": "none"
-				}
-			}
-		},
-		{
-			"path" : "pages/inventory-task/detail",
-			"style" : 
-			{
-				"navigationBarTitleText" : "",
-				"enablePullDownRefresh": true,
-				"onReachBottomDistance": 50,
-				"app-plus": {
-					"bounce": "none"
-				}
-			}
-		}
-	],
-	/* 分包预载配置 */
-	// "preloadRule": {
-	// 	"pages/index/index": {
-	// 		"network": "all",
-	// 		"packages": ["pages/account", "pages/app", "pages/user"]
-	// 	}
-	// },
-	"globalStyle": {
-		"navigationBarTextStyle": "black",
-		"navigationBarTitleText": "pda",
-		"navigationBarBackgroundColor": "#FAFAFC",
-		"backgroundColor": "#FAFAFC",
-		"navigationStyle": "custom"
-	},
-	"uniIdRouter": {}
-}
+  "pages": [
+    //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
+    {
+      "path": "pages/index/index",
+      "style": {
+        "navigationBarTitleText": "首页"
+      },
+      "meta": {
+        "auth": false,
+        "sync": true,
+        "title": "推荐",
+        "group": "平台"
+      }
+    },
+    {
+      "path": "pages/login/login",
+      "style": {
+        "navigationBarTitleText": ""
+      }
+    },
+    {
+      "path": "pages/index/app-update",
+      "style": {
+        "navigationBarTitleText": ""
+      }
+    },
+
+    {
+      "path": "pages/picking-task/index",
+      "style": {
+        "navigationBarTitleText": ""
+      }
+    },
+    {
+      "path": "pages/picking-task/delivery",
+      "style": {
+        "navigationBarTitleText": ""
+      }
+    },
+    {
+      "path": "pages/picking-task/detail",
+      "style": {
+        "navigationBarTitleText": ""
+      }
+    },
+    {
+      "path": "pages/index/notice-page",
+      "style": {
+        "navigationBarTitleText": ""
+      }
+    },
+    {
+      "path": "pages/inventory-inquiry/index",
+      "style": {
+        "navigationBarTitleText": ""
+      }
+    },
+    {
+      "path": "pages/goods/detail",
+      "style": {
+        "navigationBarTitleText": ""
+      }
+    },
+    {
+      "path": "pages/purchase/index",
+      "style": {
+        "navigationBarTitleText": ""
+      }
+    },
+    {
+      "path": "pages/purchase/put-storage",
+      "style": {
+        "navigationBarTitleText": ""
+      }
+    },
+    {
+      "path": "pages/purchase/detail",
+      "style": {
+        "navigationBarTitleText": ""
+      }
+    },
+    {
+      "path": "pages/inventory-task/index",
+      "style": {
+        "navigationBarTitleText": "",
+        "enablePullDownRefresh": true,
+        "onReachBottomDistance": 50,
+        "app-plus": {
+          "bounce": "none"
+        }
+      }
+    },
+    {
+      "path": "pages/inventory-task/taskDetail",
+      "style": {
+        "navigationBarTitleText": ""
+      }
+    },
+    {
+      "path": "pages/inventory-task/detail",
+      "style": {
+        "navigationBarTitleText": "",
+        "enablePullDownRefresh": true,
+        "onReachBottomDistance": 50,
+        "app-plus": {
+          "bounce": "none"
+        }
+      }
+    },
+    {
+      "path": "pages/inventory-task/inventoryDetail",
+      "style": {
+        "navigationBarTitleText": ""
+      }
+    }
+  ],
+  /* 分包预载配置 */
+  // "preloadRule": {
+  // 	"pages/index/index": {
+  // 		"network": "all",
+  // 		"packages": ["pages/account", "pages/app", "pages/user"]
+  // 	}
+  // },
+  "globalStyle": {
+    "navigationBarTextStyle": "black",
+    "navigationBarTitleText": "pda",
+    "navigationBarBackgroundColor": "#FAFAFC",
+    "backgroundColor": "#FAFAFC",
+    "navigationStyle": "custom"
+  },
+  "uniIdRouter": {}
+}

+ 0 - 156
pages/check/components/check-item.vue

@@ -1,156 +0,0 @@
-<template>
-	<view class="check-item">
-		<view class="header-box">
-			<view class="header-box-l">
-				<view class="header-box-name">2025年中心仓第三季度食品盘点</view>
-				<view>盘点单号:2024202244</view>
-			</view>
-			<view>
-				<view class="tips-box tips-red">待盘点</view>
-				<!-- <view class="tips-box tips-green">已盘点</view>
-				<view class="tips-box tips-hui">已取消</view>
-				<view class="tips-box tips-yellow">盘点中</view> -->
-			</view>
-		</view>
-		<view class="cont-box">
-			<view class="cont-item">
-				<view class="item-label">盘点仓库</view>
-				<view class="item-val">中心仓</view>
-			</view>
-			<view class="cont-item">
-				<view class="item-label">创建人</view>
-				<view class="item-val">刘双美</view>
-			</view>
-			<view class="cont-item">
-				<view class="item-label">盘点负责人</view>
-				<view class="item-val">刘双美</view>
-			</view>
-			<view class="cont-item">
-				<view class="item-label">货物种类</view>
-				<view class="item-val">20</view>
-			</view>
-			<view class="cont-item">
-				<view class="item-label">货物总量</view>
-				<view class="item-val">80件</view>
-			</view>
-			<view class="cont-item">
-				<view class="item-label">库位范围</view>
-				<view class="item-val">A区-B区</view>
-			</view>
-			<view class="cont-item">
-				<view class="item-label">创建时间</view>
-				<view class="item-val">2025-04-03</view>
-			</view>
-			<view class="cont-item">
-				<view class="item-label">盘点时间</view>
-				<view class="item-val">2025-04-03</view>
-			</view>
-			<view class="cont-item">
-				<view class="item-label">盘点人</view>
-				<view class="item-val">刘双美</view>
-			</view>
-		</view>
-	
-		<view class="btn-box">
-			<!-- <u-button class="detail-btn" type="primary" text="详情"></u-button> -->
-			<u-button class="detail-btn" type="primary" text="去提交"></u-button>
-			<u-button class="detail-btn ss-m-l-24" type="primary" text="去盘点"></u-button>
-		</view>
-	</view>
-</template>
-
-<script>
-	export default{
-		props:{
-			
-		},
-		data() {
-			return {
-				
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	.check-item {
-		padding: 24rpx 24rpx 0 24rpx;
-		// border-radius: 16px;
-		background: #FFF;
-		border-bottom: 4rpx solid #F0F6FB;
-		.header-box {
-			display: flex;
-			justify-content: space-between;
-			.header-box-l {
-				color: #999;
-				font-size: 28rpx;
-				font-weight: 400;
-				.header-box-name {
-					color: #333;
-					font-size: 28rpx;
-					font-weight: 500;
-				}
-			}
-			.tips-box {
-				width: 120rpx;
-				height: 44rpx;
-				font-size: 22rpx;
-				text-align: center;
-				line-height: 44rpx;
-				border-radius: 8rpx;
-			}
-			.tips-red {
-				color: #FF3B1D;
-				background: rgba(255, 59, 29, 0.20);
-			}
-			.tips-green {
-				color: #00B97B;
-				background: rgba(0, 185, 123, 0.20);
-			}
-			.tips-hui {
-				color: #BFC8DB;
-				background: rgba(173, 181, 189, 0.26);
-			}
-			.tips-yellow {
-				color: #F59701;
-				background: rgba(245, 151, 1, 0.20);
-			}
-		}
-		.cont-box {
-			border-radius: 16rpx;
-			background: #F6F8FA;
-			margin-top: 16rpx;
-			padding: 24rpx;
-			display: grid;
-			grid-template-columns: 33.3% 33.3% 33.3%;
-			.cont-item {
-				margin-bottom: 20rpx;
-				.item-label {
-					color: #999;
-					font-size: 24rpx;
-					font-weight: 400;
-					margin-bottom: 6rpx;
-				}
-				.item-val {
-					color: #000;
-					font-size: 28rpx;
-					font-weight: 400;
-				}
-			}
-		}
-		.btn-box {
-			display: flex;
-			align-items: center;
-			justify-content: flex-end;
-			padding: 16rpx 0 24rpx;
-			.detail-btn {
-				width: 144rpx;
-				height: 56rpx;
-				border-radius: 28rpx;
-				background: #0256FF;
-				font-size: 32rpx;
-				border-radius: 8rpx;
-			}
-		}
-	}
-</style>

+ 0 - 119
pages/check/index.vue

@@ -1,119 +0,0 @@
-<template>
-	<view class="check-page">
-		<u-navbar height="40px" title="盘点" bgColor="#fff" autoBack placeholder>
-		</u-navbar>
-		<view class="container_main">
-			<u-sticky :offsetTop="offsetTop" bgColor="#fff">
-				<view class="search-box">
-					<u-search placeholder="请输入单据编号或名称" shape="square" v-model="searchKey" :showAction="false"></u-search>
-				</view>
-				<view class="type-box">
-					<u-tabs 
-						:list="tabList" 
-						:inactiveStyle="{color:'#000',fontSize:'24rpx'}"
-						:activeStyle="{color:'#000',fontSize:'24rpx'}" 
-						lineColor="#0256FF" 
-						lineWidth="66rpx" 
-						:scrollable="false"
-						@click="tabClick"
-						>
-					</u-tabs>
-				</view>
-			</u-sticky>
-			<view class="content-box">
-				<view class="content-box-val">
-					<check-item v-for="item in 6" :key="item"></check-item>
-				</view>
-			</view>
-		</view>
-	</view>
-</template>
-
-<script>
-	import checkItem from './components/check-item.vue'
-	export default{
-		components:{
-			checkItem
-		},
-		data() {
-			return {
-				searchKey:'',
-				offsetTop:0,
-				tabList: [{
-						index: 0,
-						name: '全部任务'
-					},
-					{
-						index: 1,
-						name: '待盘点'
-					},
-					{
-						index: 2,
-						name: '盘点中'
-					},
-					{
-						index: 3,
-						name: '已盘点'
-					},
-					{
-						index: 4,
-						name: '已取消'
-					}
-				],
-			}
-		},
-		onLoad() {
-			let systemInfo = uni.getSystemInfoSync();
-			let statusBarHeight = systemInfo.statusBarHeight;
-			this.offsetTop = statusBarHeight + 40
-		},
-		methods:{
-			tabClick() {
-				
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	.check-page {
-		min-height: 100vh;
-		background-color: #F0F6FB;
-		.container_main {
-			.search-box {
-				background-color: rgba(191, 200, 219, 0.2);
-				margin: 0 32rpx;
-				display: flex;
-				align-items: center;
-				justify-content: space-between;
-				border-radius: 8rpx;
-			
-				::v-deep .u-search__content {
-					background-color: transparent !important;
-			
-					.u-search__content__input {
-						background-color: transparent !important;
-					}
-				}
-			
-				.scan-icon {
-					width: 100rpx;
-					height: 100%;
-			
-					image {
-						width: 40rpx;
-						height: 40rpx;
-					}
-				}
-			}
-		
-			.content-box {
-				padding: 24rpx;
-				&-val {
-					border-radius: 16rpx 16rpx 0 0;
-					overflow: hidden;
-				}
-			}
-		}
-	}
-</style>

+ 1 - 1
pages/index/index.vue

@@ -63,7 +63,7 @@
 						src:require('@/static/image/home/icon-pdrw.png'),
 						text:'盘点任务',
 						num:0,
-						url:'/pages/check/index'
+						url:'/pages/inventory-task/index'
 					}
 				],
 				meunShow:false,

+ 92 - 78
pages/inventory-task/components/actionNumPopup.vue

@@ -3,39 +3,60 @@
     :show="show"
     mode="center"
     @close="close"
-    @open="open"
     :round="10"
     :closeOnClickOverlay="false"
   >
     <view class="action-num-popup">
       <view class="icon-wrapper">
-					<u-image src="@/static/image/error-img.png" width="112rpx" height="112rpx"></u-image>
-				</view>
+        <u-image
+          src="@/static/image/error-img.png"
+          width="112rpx"
+          height="112rpx"
+        ></u-image>
+      </view>
       <view class="title">请确认该商品盘点数量</view>
       <view class="num-box">
-        <u-number-box v-model="count">
-          <view slot="minus" class="minus">
+        <u-number-box
+          v-model="count"
+          :min="minCount"
+          :inputWidth="56"
+          :max="maxCount"
+          integer
+        >
+          <!-- <view slot="minus" class="minus">
             <u-icon name="minus" color="#0256FF" size="12"></u-icon>
           </view>
-          <text slot="input" class="input">{{count}}</text>
+          <text slot="input" class="input">{{ count }}</text>
           <view slot="plus" class="plus">
             <u-icon name="plus" color="#ffffff" size="12"></u-icon>
-          </view>
+          </view> -->
         </u-number-box>
       </view>
       <view class="btn-group">
-        <u-button 
-          class="btn cancel-btn" 
-          :plain="true" 
-          shape="square" 
+        <u-button
+          class="btn cancel-btn"
+          :plain="true"
+          shape="square"
+          :customStyle="{
+            fontSize: '32rpx',
+            marginRight: '20rpx',
+            color: '#666',
+            borderColor: '#ddd',
+          }"
           @click="onCancel"
-        >取消</u-button>
-        <u-button 
-          class="btn confirm-btn" 
-          type="primary" 
-          shape="square" 
+          >取消</u-button
+        >
+        <u-button
+          class="btn confirm-btn"
+          type="primary"
+          shape="square"
+          :customStyle="{
+            fontSize: '32rpx',
+            backgroundColor: '#2979ff',
+          }"
           @click="onConfirm"
-        >确认</u-button>
+          >确认</u-button
+        >
       </view>
     </view>
   </u-popup>
@@ -51,51 +72,48 @@ export default {
     },
     defaultCount: {
       type: [Number, String],
-      default: 1
+      default: 0,
     },
     minCount: {
-      type: Number,
-      default: 0
+      type: [Number, String],
+      default: 0,
     },
     maxCount: {
-      type: Number,
-      default: 9999
-    }
+      type: [Number, String],
+      default: 9999,
+    },
   },
   data() {
     return {
-      count: 2,
+      count: 0,
+      confirmCount: 0,
     };
   },
   watch: {
-    show(newVal) {
-      if (newVal) {
-        this.count = this.defaultCount || 2;
+    show(val) {
+      if (val) {
+        this.count = this.defaultCount || 0;
       }
     },
     defaultCount: {
       immediate: true,
       handler(val) {
-        this.count = val || 2;
-      }
-    }
+        this.count = val || 0;
+      },
+    },
   },
   methods: {
     close() {
-      this.$emit('update:show', false);
-    },
-    open() {},
-    onNumberChange(value) {
-      this.count = value;
+      this.$emit("update:show", false);
     },
     onCancel() {
       this.close();
-      this.$emit('cancel');
+      this.$emit("cancel");
     },
     onConfirm() {
+      this.$emit("confirm", this.count);
       this.close();
-      this.$emit('confirm', this.count);
-    }
+    },
   },
 };
 </script>
@@ -103,14 +121,14 @@ export default {
 <style lang="scss" scoped>
 .action-num-popup {
   padding: 40rpx 30rpx;
-	width: 580rpx;
-  
+  width: 580rpx;
+
   .icon-wrapper {
     display: flex;
     justify-content: center;
     margin-bottom: 20rpx;
   }
-  
+
   .title {
     font-size: 32rpx;
     color: #333;
@@ -118,55 +136,51 @@ export default {
     font-weight: 500;
     margin-bottom: 40rpx;
   }
-  
+
   .num-box {
-		display: flex;
-		align-items: center;
-		justify-content: center;
-		margin: 30rpx 0;
-		.input {
-			width: 112rpx;
-			text-align: center;
-			border-bottom: 1px solid #0256FF;
-			margin: 0 8rpx;
-		}
-		.minus {
-			width: 40rpx;
-			height: 40rpx;
-			border-radius: 8rpx;
-			border: 1px solid #0256FF;
-			display: flex;
-			align-items: center;
-			justify-content: center;
-		}
-		.plus {
-			width: 40rpx;
-			height: 40rpx;
-			border-radius: 8rpx;
-			background-color: #0256FF;
-			display: flex;
-			align-items: center;
-			justify-content: center;
-		}
-	}
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    margin: 30rpx 0;
+    .input {
+      width: 112rpx;
+      text-align: center;
+      border-bottom: 1px solid #0256ff;
+      margin: 0 8rpx;
+    }
+    .minus {
+      width: 40rpx;
+      height: 40rpx;
+      border-radius: 8rpx;
+      border: 1px solid #0256ff;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+    .plus {
+      width: 40rpx;
+      height: 40rpx;
+      border-radius: 8rpx;
+      background-color: #0256ff;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+  }
 
   .btn-group {
     display: flex;
     justify-content: space-between;
-    
+
     .btn {
-      flex: 1;
-      display: flex;
-      align-items: center;
-      justify-content: center;
       font-size: 32rpx;
-      
+
       &.cancel-btn {
         margin-right: 20rpx;
         color: #666;
         border-color: #ddd;
       }
-      
+
       &.confirm-btn {
         background-color: #2979ff;
       }

+ 165 - 170
pages/inventory-task/components/categoryPopup.vue

@@ -1,187 +1,182 @@
 <template>
-    <u-popup
-      :show="show"
-      mode="center"
-      @close="close"
-      @open="open"
-      :round="10"
-      :closeOnClickOverlay="false"
-      width="580rpx"
-    >
-      <view class="location-edit-popup">
-        <view class="popup-header">
-          <text class="popup-title">修改库位</text>
-          <u-icon name="close" size="20" @click="close"></u-icon>
-        </view>
-        
-        <u--form 
-          :model="formData" 
-          ref="locationForm"
-          :rules="rules"
-          labelPosition="top"
-          labelWidth="100%"
+  <u-popup
+    :show="show"
+    mode="center"
+    @close="close"
+    @open="open"
+    :round="10"
+    :closeOnClickOverlay="false"
+    width="580rpx"
+  >
+    <view class="location-edit-popup">
+      <view class="popup-header">
+        <text class="popup-title">修改库位</text>
+        <u-icon name="close" size="20" @click="close"></u-icon>
+      </view>
+
+      <u-form
+        :model="formData"
+        ref="locationForm"
+        labelPosition="top"
+        labelWidth="100%"
+        :borderBottom="false"
+      >
+        <u-form-item label="原库位" prop="originLocation" :borderBottom="false">
+          <u--input
+            v-model="formData.originLocation"
+            border="surround"
+            placeholder="请输入原库位"
+            height="80rpx"
+            disabled
+            fontSize="28rpx"
+            color="#333333"
+          ></u--input>
+        </u-form-item>
+
+        <u-form-item
+          label="新库位"
+          prop="newLocation"
           :borderBottom="false"
+          class="mt-20"
+        >
+          <u--input
+            v-model="formData.newLocation"
+            border="surround"
+            placeholder="请输入新库位"
+            height="80rpx"
+            clearable
+            fontSize="28rpx"
+            color="#333333"
+          ></u--input>
+        </u-form-item>
+      </u-form>
+
+      <view class="btn-group">
+        <u-button
+          class="btn cancel-btn"
+          :plain="true"
+          shape="square"
+          @click="onCancel"
+          >取消</u-button
+        >
+        <u-button
+          class="btn confirm-btn"
+          type="primary"
+          shape="square"
+          @click="onConfirm"
+          >确认</u-button
         >
-          <u-form-item
-            label="原库位"
-            prop="originLocation"
-            :borderBottom="false"
-          >
-            <u--input
-              v-model="formData.originLocation"
-              border="surround"
-              placeholder="请输入原库位"
-              height="80rpx"
-              clearable
-              fontSize="28rpx"
-              color="#333333"
-            ></u--input>
-          </u-form-item>
-          
-          <u-form-item
-            label="新库位"
-            prop="newLocation"
-            :borderBottom="false"
-            class="mt-20"
-          >
-            <u--input
-              v-model="formData.newLocation"
-              border="surround"
-              placeholder="请输入新库位"
-              height="80rpx"
-              clearable
-              fontSize="28rpx"
-              color="#333333"
-            ></u--input>
-          </u-form-item>
-        </u--form>
-        
-        <view class="btn-group">
-          <u-button 
-            class="btn cancel-btn" 
-            :plain="true" 
-            shape="square" 
-            @click="onCancel"
-          >取消</u-button>
-          <u-button 
-            class="btn confirm-btn" 
-            type="primary" 
-            shape="square" 
-            @click="onConfirm"
-          >确认</u-button>
-        </view>
       </view>
-    </u-popup>
-  </template>
-  
-  <script>
-  export default {
-    name: "locationEditPopup",
-    props: {
-      show: {
-        type: Boolean,
-        default: false
-      },
-      originalLocation: {
-        type: String,
-        default: ''
-      }
+    </view>
+  </u-popup>
+</template>
+
+<script>
+export default {
+  name: "locationEditPopup",
+  props: {
+    show: {
+      type: Boolean,
+      default: false,
     },
-    data() {
-      return {
-        formData: {
-          originLocation: '',
-          newLocation: ''
-        },
-        rules: {
-          newLocation: {
-            type: 'string',
-            required: true,
-            message: '请输入新库位',
-            trigger: ['blur', 'change']
-          }
-        }
-      };
+    originalLocation: {
+      type: String,
+      default: "",
     },
-    watch: {
-      show(newVal) {
-        if (newVal) {
-          this.formData.originLocation = this.originalLocation
-          this.formData.newLocation = '';
-        }
+  },
+  data() {
+    return {
+      formData: {
+        originLocation: "",
+        newLocation: "",
       },
-      originalLocation(val) {
-        this.formData.originLocation = val
+      // rules: {
+      //   newLocation: {
+      //     type: "string",
+      //     required: true,
+      //     message: "请输入新库位",
+      //     trigger: ["blur", "change"],
+      //   },
+      // },
+    };
+  },
+  watch: {
+    show(newVal) {
+      if (newVal) {
+        this.formData.originLocation = this.originalLocation;
+        this.formData.newLocation = "";
       }
     },
-    methods: {
-      close() {
-        this.$emit('update:show', false);
-      },
-      open() {},
-      onCancel() {
-        this.close();
-        this.$emit('cancel');
-      },
-      onConfirm() {
-        this.$refs.locationForm.validate(valid => {
-          if (valid) {
-            this.close();
-            this.$emit('confirm', this.formData.newLocation);
-          }
-        });
+    originalLocation(val) {
+      this.formData.originLocation = val;
+    },
+  },
+  methods: {
+    close() {
+      this.$emit("update:show", false);
+    },
+    open() {},
+    onCancel() {
+      this.close();
+      this.$emit("cancel");
+    },
+    onConfirm() {
+      console.log(999000);
+      if (!this.formData.newLocation) {
+        uni.$u.toast("请输入新库存");
+        return;
       }
+      this.$emit("confirm", this.formData.newLocation);
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.location-edit-popup {
+  padding: 30rpx;
+  width: 580rpx;
+
+  .popup-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 30rpx;
+
+    .popup-title {
+      font-size: 36rpx;
+      font-weight: 500;
+      color: #333333;
     }
-  };
-  </script>
-  
-  <style lang="scss" scoped>
-  .location-edit-popup {
-    padding: 30rpx;
-	width: 580rpx;
-    
-    .popup-header {
+  }
+
+  .mt-20 {
+    margin-top: 20rpx;
+  }
+
+  .btn-group {
+    display: flex;
+    justify-content: space-between;
+    margin-top: 40rpx;
+
+    .btn {
+      flex: 1;
+      height: 88rpx;
       display: flex;
-      justify-content: space-between;
       align-items: center;
-      margin-bottom: 30rpx;
-      
-      .popup-title {
-        font-size: 36rpx;
-        font-weight: 500;
-        color: #333333;
+      justify-content: center;
+      font-size: 32rpx;
+
+      &.cancel-btn {
+        margin-right: 20rpx;
+        color: #666666;
+        border-color: #dddddd;
       }
-    }
-    
-    .mt-20 {
-      margin-top: 20rpx;
-    }
-    
-    
-    .btn-group {
-      display: flex;
-      justify-content: space-between;
-      margin-top: 40rpx;
-      
-      .btn {
-        flex: 1;
-        height: 88rpx;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        font-size: 32rpx;
-        
-        &.cancel-btn {
-          margin-right: 20rpx;
-          color: #666666;
-          border-color: #dddddd;
-        }
-        
-        &.confirm-btn {
-          background-color: #2979ff;
-        }
+
+      &.confirm-btn {
+        background-color: #2979ff;
       }
     }
   }
-  </style>
-  
+}
+</style>

+ 208 - 0
pages/inventory-task/components/check-item.vue

@@ -0,0 +1,208 @@
+<template>
+  <view class="check-item">
+    <view class="header-box">
+      <view class="header-box-l">
+        <view class="header-box-name">{{ info.taskName }}</view>
+        <view>盘点单号:{{ info.number }}</view>
+      </view>
+      <view>
+        <view :class="['tips-box', curTaskStatusInfo.className]">{{
+          curTaskStatusInfo.name
+        }}</view>
+        <!-- <view class="tips-box tips-green">已盘点</view>
+				<view class="tips-box tips-hui">已取消</view>
+				<view class="tips-box tips-yellow">盘点中</view> -->
+      </view>
+    </view>
+    <view class="cont-box">
+      <view class="cont-item">
+        <view class="item-label">盘点仓库</view>
+        <view class="item-val">{{ info.depotName }}</view>
+      </view>
+      <view class="cont-item">
+        <view class="item-label">创建人</view>
+        <view class="item-val">{{ info.createByName }}</view>
+      </view>
+      <view class="cont-item">
+        <view class="item-label">盘点负责人</view>
+        <view class="item-val">{{ info.creatorName }}</view>
+      </view>
+      <view class="cont-item">
+        <view class="item-label">货物种类</view>
+        <view class="item-val">{{ info.categoryCount }}</view>
+      </view>
+      <view class="cont-item">
+        <view class="item-label">货物总量</view>
+        <view class="item-val">{{ info.materialCount }}</view>
+      </view>
+      <view class="cont-item">
+        <view class="item-label">库位范围</view>
+        <view class="item-val">{{ info.positionRange }}</view>
+      </view>
+      <view class="cont-item">
+        <view class="item-label">创建时间</view>
+        <view class="item-val">{{ info.createTime }}</view>
+      </view>
+      <view class="cont-item">
+        <view class="item-label">盘点时间</view>
+        <view class="item-val">{{ info.operTime }}</view>
+      </view>
+      <view class="cont-item">
+        <view class="item-label">盘点人</view>
+        <view class="item-val">{{ info.operName }}</view>
+      </view>
+    </view>
+
+    <view class="btn-box">
+      <u-button
+        class="detail-btn"
+        type="primary"
+        text="详情"
+        :customStyle="customBtnStyle"
+        @click="handleCick('详情')"
+        v-if="status === 3 || status === 4"
+      ></u-button>
+      <u-button
+        class="detail-btn"
+        type="primary"
+        text="去盘点"
+        :customStyle="customBtnStyle"
+        @click="handleCick('去盘点')"
+        v-if="status === 1 || status === 2"
+      ></u-button>
+      <u-button
+        class="detail-btn"
+        type="primary"
+        text="去提交"
+        :customStyle="customBtnStyle"
+        @click="handleCick('去提交')"
+        v-if="status === 2"
+      ></u-button>
+    </view>
+  </view>
+</template>
+
+<script>
+import { getTaskStatusInfoByVal } from "../../inventory-task/utils/index.js";
+
+export default {
+  props: {
+    info: {
+      type: Object,
+      default: () => {},
+    },
+  },
+  computed: {
+    status() {
+      return this.info.taskStatus;
+    },
+    curTaskStatusInfo() {
+      return getTaskStatusInfoByVal(this.info.taskStatus);
+    },
+  },
+  data() {
+    return {
+      customBtnStyle: {
+        width: "144rpx",
+        height: "56rpx",
+        borderRadius: "28rpx",
+        background: "#0256ff",
+        fontSize: "32rpx",
+        borderRadius: "8rpx",
+      },
+    };
+  },
+  methods: {
+    handleCick(btnName) {
+      const params = {
+        ...this.info,
+        btnName,
+      };
+      this.$emit("btnClick", params);
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.check-item {
+  padding: 24rpx 24rpx 0 24rpx;
+  // border-radius: 16px;
+  background: #fff;
+  border-bottom: 4rpx solid #f0f6fb;
+  .header-box {
+    display: flex;
+    justify-content: space-between;
+    .header-box-l {
+      color: #999;
+      font-size: 28rpx;
+      font-weight: 400;
+      .header-box-name {
+        color: #333;
+        font-size: 28rpx;
+        font-weight: 500;
+      }
+    }
+    .tips-box {
+      width: 120rpx;
+      height: 44rpx;
+      font-size: 22rpx;
+      text-align: center;
+      line-height: 44rpx;
+      border-radius: 8rpx;
+    }
+    .tips-red {
+      color: #ff3b1d;
+      background: rgba(255, 59, 29, 0.2);
+    }
+    .tips-green {
+      color: #00b97b;
+      background: rgba(0, 185, 123, 0.2);
+    }
+    .tips-hui {
+      color: #bfc8db;
+      background: rgba(173, 181, 189, 0.26);
+    }
+    .tips-yellow {
+      color: #f59701;
+      background: rgba(245, 151, 1, 0.2);
+    }
+  }
+  .cont-box {
+    border-radius: 16rpx;
+    background: #f6f8fa;
+    margin-top: 16rpx;
+    padding: 24rpx;
+    display: grid;
+    grid-template-columns: 33.3% 33.3% 33.3%;
+    .cont-item {
+      margin-bottom: 20rpx;
+      .item-label {
+        color: #999;
+        font-size: 24rpx;
+        font-weight: 400;
+        margin-bottom: 6rpx;
+      }
+      .item-val {
+        color: #000;
+        font-size: 28rpx;
+        font-weight: 400;
+      }
+    }
+  }
+  .btn-box {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    padding: 16rpx 0 24rpx;
+    .detail-btn {
+      width: 144rpx;
+      height: 56rpx;
+      border-radius: 28rpx;
+      background: #0256ff;
+      font-size: 32rpx;
+      border-radius: 8rpx;
+    }
+  }
+}
+</style>

+ 123 - 130
pages/inventory-task/components/inventoryFilterPopup.vue

@@ -25,42 +25,54 @@
         ></u-tabs>
       </view>
       <view class="filter-content">
-        <!-- 货物选项 -->
+        <!-- 盘点状态 -->
         <scroll-view scroll-y class="filter-scroll" v-if="currentTab === 0">
-          <view
-            v-for="(item, index) in goodsOptions"
-            :key="index"
-            class="filter-item"
-            :class="{ active: selectedValues.goods === item.value }"
-            @click="selectFilter('goods', item.value)"
-          >
-            <text>{{ item.label }}</text>
-            <u-icon
-              v-if="selectedValues.goods === item.value"
-              name="checkbox-mark"
-              color="#4080FF"
-              size="20"
-            ></u-icon>
+          <view class="category-content">
+            <u-checkbox-group
+              v-model="selectedValues.statusList"
+              placement="column"
+              @change="onStatusChange"
+            >
+              <view
+                v-for="(item, index) in inventoryStatusList"
+                :key="index"
+                class="checkbox-item"
+              >
+                <u-checkbox
+                  :name="item.value"
+                  shape="circle"
+                  activeColor="#4080FF"
+                  :label="item.name"
+                  size="20"
+                >
+                </u-checkbox>
+              </view>
+            </u-checkbox-group>
           </view>
         </scroll-view>
 
         <!-- 盘点人选项 -->
         <scroll-view scroll-y class="filter-scroll" v-if="currentTab === 1">
-          <view
-            v-for="(item, index) in userOptions"
-            :key="index"
-            class="filter-item"
-            :class="{ active: selectedValues.user === item.value }"
-            @click="selectFilter('user', item.value)"
+          <u-checkbox-group
+            v-model="selectedValues.userIdList"
+            placement="column"
+            @change="onUserChange"
           >
-            <text>{{ item.label }}</text>
-            <u-icon
-              v-if="selectedValues.user === item.value"
-              name="checkbox-mark"
-              color="#4080FF"
-              size="20"
-            ></u-icon>
-          </view>
+            <view
+              v-for="(item, index) in userOptions"
+              :key="index"
+              class="checkbox-item"
+            >
+              <u-checkbox
+                :name="item.value"
+                shape="circle"
+                activeColor="#4080FF"
+                :label="item.label"
+                size="20"
+              >
+              </u-checkbox>
+            </view>
+          </u-checkbox-group>
         </scroll-view>
 
         <!-- 类目选项 - 左右布局实现二级联动 -->
@@ -81,7 +93,7 @@
           <view class="category-content">
             <scroll-view scroll-y style="height: 100%">
               <u-checkbox-group
-                v-model="selectedValues.category"
+                v-model="selectedValues.categoryIdList"
                 placement="column"
                 @change="onCategoryChange"
               >
@@ -91,10 +103,10 @@
                   class="checkbox-item"
                 >
                   <u-checkbox
-                    :name="item.value"
+                    :name="item.id"
                     shape="circle"
                     activeColor="#4080FF"
-                    :label="item.label"
+                    :label="item.title"
                     size="20"
                   >
                   </u-checkbox>
@@ -122,7 +134,7 @@
           <view class="category-content">
             <scroll-view scroll-y style="height: 100%">
               <u-checkbox-group
-                v-model="selectedValues.location"
+                v-model="selectedValues.positionList"
                 placement="column"
                 @change="onLocationChange"
               >
@@ -166,6 +178,11 @@
 </template>
 
 <script>
+import {
+  getMaterialCategoryTree,
+  creatorSpinnerList,
+} from "@/common/request/apis/inventoryTask";
+import { goodsInventoryStatus } from "../utils/index.js";
 export default {
   name: "InventoryFilterPopup",
   props: {
@@ -177,89 +194,42 @@ export default {
     defaultValues: {
       type: Object,
       default: () => ({
-        goods: "",
-        user: "",
-        category: [],
-        location: [],
+        statusList: [],
+        userIdList: [],
+        categoryIdList: [],
+        positionList: [],
       }),
     },
+    taskId: {
+      type: String,
+      default: "",
+    },
   },
   data() {
     return {
       currentTab: 0,
       tabList: [
-        { name: "盘" },
+        { name: "盘点状态" },
         { name: "盘点人" },
         { name: "类目" },
         { name: "库位" },
       ],
-      // 货物选项
-      goodsOptions: [
-        { label: "全部", value: "" },
-        { label: "未盘", value: "unchecked" },
-        { label: "盘盈", value: "overflow" },
-        { label: "盘亏", value: "loss" },
-        { label: "无差异", value: "normal" },
-      ],
+      // 盘点状态
+      inventoryStatusList: goodsInventoryStatus,
       // 盘点人选项
-      userOptions: [
-        { label: "全部", value: "" },
-        { label: "刘双秀", value: "刘双秀" },
-      ],
+      userOptions: [],
       // 类目树形数据
-      categoryTree: [
-        {
-          id: "all",
-          name: "全部",
-          children: [
-            { label: "生活用品", value: "daily" },
-            { label: "厨房餐具", value: "kitchen" },
-            { label: "个人洗护", value: "personal" },
-          ],
-        },
-        {
-          id: "summer",
-          name: "夏季热卖",
-          children: [
-            { label: "防晒", value: "summer_sunscreen" },
-            { label: "泳衣", value: "summer_swimwear" },
-          ],
-        },
-        {
-          id: "disposable",
-          name: "一次用品",
-          children: [
-            { label: "餐具", value: "disposable_tableware" },
-            { label: "纸巾", value: "disposable_tissue" },
-          ],
-        },
-        {
-          id: "swimming",
-          name: "游泳运动",
-          children: [
-            { label: "泳镜", value: "swimming_goggles" },
-            { label: "泳帽", value: "swimming_caps" },
-          ],
-        },
-        {
-          id: "cleaning",
-          name: "家庭清洁",
-          children: [
-            { label: "洗衣液", value: "cleaning_detergent" },
-            { label: "清洁剂", value: "cleaning_agent" },
-          ],
-        },
-      ],
+      categoryTree: [],
       // 当前选中的类目侧边栏索引
       currentCategoryIndex: 0,
 
       // 库位树形数据
       locationTree: [
-        {
-          id: "all",
-          name: "全部",
-          children: [],
-        },
+        // {
+        //   id: "all",
+        //   name: "全部",
+        //   children: [],
+        // },
         {
           id: "zone_a",
           name: "A区",
@@ -293,10 +263,10 @@ export default {
 
       // 选中的筛选值
       selectedValues: {
-        goods: "",
-        user: "",
-        category: [],
-        location: [],
+        statusList: [],
+        userIdList: [],
+        categoryIdList: [],
+        positionList: [],
       },
     };
   },
@@ -304,7 +274,7 @@ export default {
     // 类目侧边栏列表
     categorySidebarList() {
       return this.categoryTree.map((item) => ({
-        name: item.name,
+        name: item.title,
         id: item.id,
       }));
     },
@@ -324,31 +294,49 @@ export default {
       return this.locationTree[this.currentLocationIndex]?.children || [];
     },
   },
+  watch: {
+    taskId: {
+      handler(val) {
+        if (val) {
+          //负责人下拉列表
+          creatorSpinnerList(val).then((res) => {
+            console.log("creatorSpinnerList=======", res);
+            this.userOptions = res.data;
+          });
+        }
+      },
+      immediate: true,
+    },
+  },
   created() {
     // 初始化选中值
     this.selectedValues = {
-      goods: this.defaultValues.goods || "",
-      user: this.defaultValues.user || "",
-      category: this.defaultValues.category || [],
-      location: this.defaultValues.location || [],
+      statusList: this.defaultValues.statusList || [],
+      userIdList: this.defaultValues.userIdList || [],
+      categoryIdList: this.defaultValues.categoryIdList || [],
+      positionList: this.defaultValues.positionList || [],
     };
+    this.loadData();
   },
   methods: {
+    loadData() {
+      //类目数据
+      getMaterialCategoryTree().then((res) => {
+        console.log("getMaterialCategoryTree=======", res);
+        this.categoryTree = res;
+      });
+    },
     // 标签切换
     tabChange({ index }) {
       this.currentTab = index;
     },
-    // 选择筛选项(单选)
-    selectFilter(type, value) {
-      this.selectedValues[type] = value;
-    },
     // 切换类目侧边栏
     changeCategoryIndex(index) {
       // 如果切换了侧边栏,则重置该类别下的选择状态
       if (this.currentCategoryIndex !== index) {
         this.currentCategoryIndex = index;
         // 重置当前类别的选择状态
-        this.selectedValues.category = [];
+        this.selectedValues.categoryIdList = [];
       }
     },
     // 切换库位侧边栏
@@ -357,16 +345,16 @@ export default {
       if (this.currentLocationIndex !== index) {
         this.currentLocationIndex = index;
         // 重置当前库位的选择状态
-        this.selectedValues.location = [];
+        this.selectedValues.positionList = [];
       }
     },
     // 重置筛选
     resetFilter() {
       this.selectedValues = {
-        goods: "",
-        user: "",
-        category: [],
-        location: [],
+        statusList: [],
+        userIdList: [],
+        categoryIdList: [],
+        positionList: [],
       };
     },
     // 确认筛选
@@ -381,11 +369,19 @@ export default {
     },
     // 处理类目选择变化
     onCategoryChange(value) {
-      this.selectedValues.category = value;
+      this.selectedValues.categoryIdList = value;
     },
     // 处理库位选择变化
     onLocationChange(value) {
-      this.selectedValues.location = value;
+      this.selectedValues.positionList = value;
+    },
+    // 处理盘点状态变化
+    onStatusChange(value) {
+      this.selectedValues.statusList = value;
+    },
+    // 处理盘点负责人变化
+    onUserChange(value) {
+      this.selectedValues.userIdList = value;
     },
   },
 };
@@ -464,20 +460,17 @@ export default {
       }
 
       .category-content {
-        flex: 1;
         height: 100%;
         background-color: #ffffff;
-        padding: 0 30rpx;
-
-        .checkbox-item {
-          padding: 30rpx 0;
-          font-size: 28rpx;
-          border-bottom: 1rpx solid #f5f6f7;
+      }
+    }
+    .checkbox-item {
+      padding: 30rpx;
+      font-size: 28rpx;
+      border-bottom: 1rpx solid #f5f6f7;
 
-          &:last-child {
-            border-bottom: none;
-          }
-        }
+      &:last-child {
+        border-bottom: none;
       }
     }
   }

+ 270 - 158
pages/inventory-task/detail.vue

@@ -2,7 +2,7 @@
   <view class="inventory-detail">
     <!-- 导航栏 -->
     <u-navbar
-      :title="pageTitle"
+      :title="inventoryInfo.taskName"
       :autoBack="true"
       fixed
       safe-area-inset-top
@@ -15,36 +15,45 @@
       </template>
     </u-navbar>
 
-    <!-- 基本信息 吸顶 -->
-    <view class="info-card">
-      <view class="info-item">
-        <text class="info-label">盘点单号:</text>
-        <text class="info-value">{{ inventoryInfo.code }}</text>
-      </view>
-      <view class="info-item">
-        <text class="info-label">盘点人:</text>
-        <text class="info-value">{{ inventoryInfo.operator }}</text>
-      </view>
-      <view class="progress-box">
-        <view class="progress-label-box">
-          <text class="progress-label"> 盘点进度 </text>
-          <text class="progress-value"
-            >{{ inventoryInfo.progress }}/{{ inventoryInfo.total }}</text
-          >
+    <u-sticky bgColor="#F5F6F7" :offsetTop="offsetTop">
+      <!-- 基本信息 吸顶 -->
+      <view class="info-card">
+        <view class="info-item page-title">
+          {{ inventoryInfo.taskName }}
         </view>
-        <view class="progress-bar-wrap">
-          <u-line-progress
-            :percentage="getProgressPercentage"
-            height="4"
-            :show-text="false"
-            activeColor="#4080FF"
-          >
-          </u-line-progress>
+        <view class="info-item-box">
+          <view class="info-item">
+            <text class="info-label">盘点单号:</text>
+            <text class="info-value">{{ inventoryInfo.number }}</text>
+          </view>
+          <view class="info-item">
+            <text class="info-label">盘点人:</text>
+            <text class="info-value">{{ inventoryInfo.creatorName }}</text>
+          </view>
+        </view>
+
+        <view class="progress-box">
+          <view class="progress-label-box">
+            <text class="progress-label"> 盘点进度 </text>
+            <text class="progress-value"
+              ><text class="finished-value">{{
+                inventoryInfo.finishCount
+              }}</text
+              >/{{ inventoryInfo.materialCount }}</text
+            >
+          </view>
+          <view class="progress-bar-wrap">
+            <u-line-progress
+              :percentage="getProgressPercentage"
+              height="6"
+              :show-text="false"
+              activeColor="#4080FF"
+            >
+            </u-line-progress>
+          </view>
         </view>
       </view>
-    </view>
-    <!-- 筛选按钮 -->
-    <u-sticky bgColor="#F5F6F7" :offsetTop="44">
+      <!-- 筛选按钮 -->
       <view class="filter-wrap">
         <view class="filter-btn" @click="filterPopupVisible = true">
           <text>筛选</text>
@@ -63,14 +72,15 @@
         <view class="location-row">
           <view class="location-left">
             <text class="location-label">库位:</text>
-            <text class="location-value">{{ item.location }}</text>
+            <text class="location-value">{{ item.position }}</text>
             <image
               src="@/static/image/bianji-icon.png"
               mode=""
               class="icon"
+              @click="handlePositionEdit(item)"
             ></image>
           </view>
-          <text class="category-text">{{ item.category }}</text>
+          <text class="category-text">{{ item.categoryName }}</text>
         </view>
 
         <view class="goods-content">
@@ -80,33 +90,40 @@
             mode="aspectFill"
           ></image>
           <view class="goods-info">
-            <text class="goods-name u-line-2">{{ item.name }}</text>
+            <text class="goods-name u-line-2">{{ item.materialName }}</text>
             <view class="goods-field half-w">
               <text class="field-label">规格:</text>
-              <text class="field-value">{{ item.spec }}</text>
+              <text class="field-value">{{ item.standard }}</text>
             </view>
             <view class="goods-field half-w">
               <text class="field-label">盘点人:</text>
-              <text class="field-value">{{ item.checkUser }}</text>
+              <text class="field-value">{{ item.createName }}</text>
             </view>
             <view class="goods-field">
               <text class="field-label">盘点时间:</text>
-              <text class="field-value">{{ item.checkTime }}</text>
+              <text class="field-value">{{ item.operTime }}</text>
             </view>
             <view class="stock-row">
               <view class="stock-item">
                 <text class="stock-label">系统库存</text>
-                <text class="stock-value">{{ item.systemStock }}瓶</text>
+                <text class="stock-value"
+                  >{{ item.inventory }}{{ item.commodityUnit }}</text
+                >
               </view>
               <view class="stock-item">
                 <text class="stock-label">已盘库存</text>
                 <text
                   class="stock-value"
-                  :class="{
-                    'stock-value-zero': item.actualStock === '未盘',
-                    'stock-value-warning': item.actualStock === '0瓶',
-                  }"
-                  >{{ item.actualStock }}</text
+                  :class="
+                    Number(item.newInventory || 0) > 0
+                      ? 'stock-value-warning'
+                      : ''
+                  "
+                  >{{
+                    Number(item.newInventory || 0) === 0
+                      ? "未盘"
+                      : `${Number(item.newInventory || 0)}${item.commodityUnit}`
+                  }}</text
                 >
               </view>
             </view>
@@ -115,47 +132,81 @@
 
         <view class="action-row">
           <u-button
+            v-if="item.status === 1"
             type="primary"
-            size="mini"
+            text="盘点"
+            :customStyle="customBtnStyle"
             @click="handleCheck(item)"
             class="action-btn"
-            >盘点</u-button
-          >
+          ></u-button>
           <u-button
+            v-else
             type="primary"
-            size="mini"
-            @click="handleRecheck(item)"
+            text="重新盘点"
+            :customStyle="customBtnStyle"
+            @click="handleCheck(item)"
             class="action-btn"
-            >重新盘点
+          >
           </u-button>
-          <u-button
+          <u-tag
+            text="盘亏"
+            type="error"
+            plain
+            plainFill
+            v-if="item.status === 3"
+          >
+          </u-tag>
+          <u-tag
+            text="盘盈"
+            type="error"
+            plain
+            plainFill
+            v-if="item.status === 4"
+          >
+          </u-tag>
+          <!-- <u-button
             type="warning"
-            size="mini"
+            text="盘亏"
+            v-if="
+              getGoodsInventoryStatusInfo(item.inventory, item.newInventory)
+                .value === 3
+            "
+            :customStyle="customBtnStyle"
             plain
-            @click="handleCheck2(item)"
             class="action-btn action-btn-secondary"
-            >盘点2</u-button
-          >
+          ></u-button> -->
         </view>
       </view>
-
       <!-- 加载更多 -->
-      <u-loadmore :status="loadMoreStatus" @loadmore="onLoadMore" />
+      <u-loadmore :status="loadStatus" @loadmore="onLoadMore" />
     </view>
+    <!-- 过滤条件弹框 -->
     <InventoryFilterPopup
       :show.sync="filterPopupVisible"
-      :defaultValues="defaultFilterValues"
+      :defaultValues="queryFilterValues"
       @confirm="handleFilterConfirm"
+      :taskId="taskId"
+    />
+    <!-- 盘点数量 -->
+    <actionNumPopup
+      :show.sync="actionPop.showNumPop"
+      :min-count="actionPop.minCount"
+      :max-count="actionPop.maxCount"
+      @confirm="handleConfirmNum"
+    />
+    <!-- 修改库位 -->
+    <categoryPopup
+      :show.sync="actionPop.showCategoryPop"
+      :original-location="actionPop.originalLocation"
+      @confirm="haandleComfirmLocation"
     />
-    <actionNumPopup :show.sync="actionPop.showNumPop" />
-    <categoryPopup :show.sync="actionPop.showCategoryPop" />
     <error-pop
       v-model="actionPop.errorShow"
       isCenter
       cancelBtnText="取消"
       confirmBtnText="确定"
       @close="actionPop.errorShow = false"
-      @confirm="confirm"
+      @confirm="submit"
       :content="actionPop.errorText"
     ></error-pop>
   </view>
@@ -166,6 +217,14 @@ import InventoryFilterPopup from "./components/inventoryFilterPopup.vue";
 import actionNumPopup from "./components/actionNumPopup.vue";
 import categoryPopup from "./components/categoryPopup.vue";
 import errorPop from "@/components/error-pop/error-pop.vue";
+import { getGoodsInventoryStatusInfo } from "./utils/index.js";
+import {
+  taskStocktakingDetail,
+  taskStocktakingItemList,
+  stocktaking,
+} from "@/common/request/apis/inventoryTask";
+import { mapGetters } from "vuex";
+
 export default {
   components: {
     InventoryFilterPopup,
@@ -175,9 +234,17 @@ export default {
   },
   data() {
     return {
+      offsetTop: 0,
+      pageType: "1", // 1:去盘点,可操作 2:盘点详情
+      taskId: "", //任务id
+      customBtnStyle: {
+        width: "144rpx",
+        height: "56rpx",
+        borderRadius: "28rpx",
+        fontSize: "32rpx",
+        borderRadius: "8rpx",
+      },
       pageTitle: "2025年中心仓第三季度食品盘点",
-      isRefreshing: false,
-      loadMoreStatus: "loadmore",
       pageNum: 1,
       pageSize: 10,
       inventoryInfo: {
@@ -186,58 +253,47 @@ export default {
         progress: 105,
         total: 604,
       },
-      goodsList: [
-        {
-          location: "C6-2-2",
-          category: "母婴用品-家居旅行",
-          image: "/static/demo/goods1.png",
-          name: "4层汗巾儿童全棉幼儿类吸汗巾婴儿纱布毛巾1条装",
-          spec: "4层-随机",
-          checkUser: "刘双秀",
-          checkTime: "2025-04-03",
-          systemStock: "5瓶",
-          actualStock: "未盘",
-          isChecked: false,
-        },
-        {
-          location: "C6-2-2",
-          category: "母婴用品-家居旅行",
-          image: "/static/demo/goods1.png",
-          name: "4层汗巾儿童全棉幼儿类吸汗巾婴儿纱布毛巾1条装",
-          spec: "4层-随机",
-          checkUser: "刘双秀",
-          checkTime: "2025-04-03",
-          systemStock: "5瓶",
-          actualStock: "0瓶",
-          isChecked: true,
-        },
-      ],
+      loadStatus: "loadmore", //加载前值为loadmore,加载中为loading,没有数据为nomore
+      goodsList: [],
       filterPopupVisible: false,
-      defaultFilterValues: {
-        goods: "",
-        user: "",
-        category: "",
-        location: "",
+      queryFilterValues: {
+        statusList: [], //盘点状态
+        userIdList: [], // 盘点负责人id
+        categoryIdList: [], // 类目
+        positionList: [], // 库位
       },
       actionPop: {
         // 盘点数量弹框状态
         showNumPop: false,
+        minCount: 0,
+        maxCount: 9,
+        activeGoodsItem: null,
         // 警告提示弹框状态
         errorShow: false,
         errorText: "是否提交盘点?",
         // 修改库位弹框状态
         showCategoryPop: false,
+        originalLocation: "",
       },
     };
   },
   computed: {
     getProgressPercentage() {
-      return (this.inventoryInfo.progress / this.inventoryInfo.total) * 100;
+      return (
+        (this.inventoryInfo.finishCount / this.inventoryInfo.materialCount) *
+        100
+      );
     },
+    ...mapGetters(["userInfo"]),
   },
-  onLoad() {
-    // 初始化数据
-    this.loadData();
+  onLoad(opt) {
+    let systemInfo = uni.getSystemInfoSync();
+    let statusBarHeight = systemInfo.statusBarHeight;
+    this.offsetTop = statusBarHeight + 40;
+    console.log("222222", opt);
+    this.pageType = opt.pageType;
+    this.taskId = opt.id;
+    this.loadData(opt.id);
   },
   onPullDownRefresh() {
     // 下拉刷新
@@ -248,78 +304,125 @@ export default {
     this.onLoadMore();
   },
   methods: {
+    getGoodsInventoryStatusInfo,
     async onRefresh() {
       try {
-        await this.loadData(true);
+        await this.loadData(this.taskId, true);
       } finally {
         uni.stopPullDownRefresh();
       }
     },
     async onLoadMore() {
-      if (this.loadMoreStatus !== "loadmore") return;
-      this.loadMoreStatus = "loading";
+      if (this.loadStatus !== "loadmore") return;
+      this.loadStatus = "loading";
       try {
-        await this.loadData();
+        await this.loadData(this.taskId);
       } catch (e) {
-        this.loadMoreStatus = "loadmore";
+        this.loadStatus = "loadmore";
       }
     },
-    async loadData(isRefresh = false) {
+    // 商品列表
+    async getTaskStocktakingItemList(taskId) {
+      try {
+        const pageNum = this.pageNum;
+        const pageSize = this.pageSize;
+        const params = {
+          taskId,
+          ...this.queryFilterValues,
+        };
+        const res = await taskStocktakingItemList(params);
+        const { total, rows } = res.data;
+        this.goodsList = [...this.goodsList, ...rows];
+        if (pageNum * pageSize < Number(total)) {
+          this.pageNum++;
+          this.loadStatus = "loadmore";
+        } else {
+          this.loadStatus = "nomore";
+        }
+        console.log("taskStocktakingItemList======", res);
+      } catch (error) {}
+    },
+    // 任务详情
+    async getTaskStocktakingDetail(taskId) {
+      try {
+        const res = await taskStocktakingDetail(taskId);
+        console.log("taskStocktakingDetail======", res);
+        this.inventoryInfo = res.data;
+      } catch (error) {}
+    },
+    resetData() {
+      this.pageNum = 1;
+      this.goodsList = [];
+    },
+    async loadData(id, isRefresh = false) {
       if (isRefresh) {
-        this.pageNum = 1;
-        this.goodsList = [];
-      }
-
-      // 模拟数据加载
-      await new Promise((resolve) => setTimeout(resolve, 1000));
-
-      // 模拟新数据
-      const mockData = [
-        {
-          location: "C6-2-2",
-          category: "母婴用品-家居旅行",
-          image: "/static/demo/goods1.png",
-          name: "4层汗巾儿童全棉幼儿类吸汗巾婴儿纱布毛巾1条装",
-          spec: "4层-随机",
-          checkUser: "刘双秀",
-          checkTime: "2025-04-03",
-          systemStock: "5瓶",
-          actualStock: isRefresh ? "未盘" : "0瓶",
-          isChecked: !isRefresh,
-        },
-      ];
-
-      this.goodsList = [...this.goodsList, ...mockData];
-      this.pageNum++;
-
-      // 模拟没有更多数据
-      if (this.pageNum > 3) {
-        this.loadMoreStatus = "nomore";
-      } else {
-        this.loadMoreStatus = "loadmore";
+        this.resetData();
       }
+      try {
+        this.getTaskStocktakingItemList(id);
+        this.getTaskStocktakingDetail(id);
+      } catch (error) {}
     },
-    handleCheck(item) {
-      uni.showToast({
-        title: "开始盘点",
-        icon: "none",
-      });
+    // 库位编辑
+    handlePositionEdit(item) {
+      this.actionPop.showCategoryPop = true;
+      this.actionPop.activeGoodsItem = { ...item };
+      this.actionPop.originalLocation = item.position;
+      console.log("handlePositionEdit======", item);
+      console.log("userInfo======", this.userInfo);
     },
-    handleRecheck(item) {
-      uni.showToast({
-        title: "开始重新盘点",
-        icon: "none",
-      });
+    async haandleComfirmLocation(val) {
+      console.log("haandleComfirmLocation======", val);
+      const activeGoodsItem = this.actionPop.activeGoodsItem;
+      try {
+        const params = {
+          id: activeGoodsItem.id,
+          materialItemId: activeGoodsItem.materialItemId,
+          newPosition: val,
+        };
+        const res = await stocktaking(params);
+        console.log("res----------", res);
+        if (res.code === 200) {
+          uni.$u.toast(res.msg);
+          this.onRefresh();
+          this.actionPop.showCategoryPop = false;
+        } else {
+          uni.$u.toast(res.data);
+        }
+      } catch (error) {}
     },
-    handleCheck2(item) {
-      uni.showToast({
-        title: "开始盘点2",
-        icon: "none",
-      });
+    handleCheck(item) {
+      this.actionPop.showNumPop = true;
+      this.actionPop.activeGoodsItem = { ...item };
+      this.actionPop.maxCount = item.inventory;
+    },
+    async handleConfirmNum(val) {
+      console.log(111223, val);
+      const activeGoodsItem = this.actionPop.activeGoodsItem;
+      console.log("activeGoodsItem========", activeGoodsItem);
+      try {
+        const params = {
+          id: activeGoodsItem.id,
+          materialItemId: activeGoodsItem.materialItemId,
+          newInventory: val,
+        };
+        const res = await stocktaking(params);
+        console.log("res----------", res);
+        if (res.code === 200) {
+          uni.$u.toast(res.msg);
+          this.onRefresh();
+        } else {
+          uni.$u.toast(res.data);
+        }
+      } catch (error) {}
     },
+    // 盘点提交
+    submit() {},
     handleFilterConfirm(values) {
-      this.defaultFilterValues = values;
+      console.log("handleFilterConfirm======", values);
+      this.queryFilterValues = values;
       this.filterPopupVisible = false;
+      this.onRefresh();
     },
   },
 };
@@ -339,18 +442,27 @@ export default {
     background-color: #fff;
     padding: 16rpx 32rpx;
 
+    .info-item-box {
+      display: flex;
+      justify-content: space-between;
+    }
+
     .info-item {
       display: flex;
       font-size: 28rpx;
       margin-bottom: 10rpx;
 
+      &.page-title {
+        color: #333;
+      }
       .info-label {
-        color: #666;
+        color: #999;
         margin-right: 8rpx;
       }
 
       .info-value {
-        color: #333;
+        flex: 1;
+        color: #999;
       }
     }
 
@@ -362,7 +474,7 @@ export default {
 
       .progress-label {
         font-size: 28rpx;
-        color: #666;
+        color: #999;
         display: block;
         margin-bottom: 16rpx;
       }
@@ -372,11 +484,15 @@ export default {
       }
 
       .progress-value {
+        color: #999;
         font-size: 24rpx;
-        color: #4080ff;
         display: block;
         text-align: right;
       }
+
+      .finished-value {
+        color: #4080ff;
+      }
     }
   }
 
@@ -414,7 +530,6 @@ export default {
         display: flex;
         align-items: center;
         padding: 24rpx 32rpx;
-        border-bottom: 1px solid #f5f6f7;
         gap: 40rpx;
 
         .location-left {
@@ -467,6 +582,7 @@ export default {
           }
 
           .goods-name {
+            width: 100%;
             font-size: 28rpx;
             line-height: 1.4;
             color: #333;
@@ -511,12 +627,8 @@ export default {
             font-size: 24rpx;
             color: #333;
 
-            &-zero {
-              color: #999;
-            }
-
             &-warning {
-              color: #ff9900;
+              color: #ff4e02;
             }
           }
         }
@@ -529,7 +641,7 @@ export default {
         gap: 24rpx;
 
         .action-btn {
-          width: 140rpx;
+          width: 144rpx;
           height: 56rpx;
           padding: 0;
 

+ 209 - 0
pages/inventory-task/index.vue

@@ -0,0 +1,209 @@
+<template>
+  <view class="check-page">
+    <u-navbar height="40px" title="盘点" bgColor="#fff" autoBack placeholder>
+    </u-navbar>
+    <view class="container_main">
+      <u-sticky :offsetTop="offsetTop" bgColor="#fff">
+        <view class="search-box">
+          <u-search
+            placeholder="请输入单据编号或名称"
+            shape="square"
+            v-model="query.number"
+            :showAction="false"
+            :clearabled="true"
+            @search="handleSearch"
+            @clear="handleSearch"
+          ></u-search>
+        </view>
+        <view class="type-box">
+          <u-tabs
+            :list="tabList"
+            :inactiveStyle="{ color: '#000', fontSize: '28rpx' }"
+            :activeStyle="{ color: '#000', fontSize: '28rpx' }"
+            lineColor="#0256FF"
+            lineWidth="66rpx"
+            :scrollable="false"
+            @click="tabClick"
+          >
+          </u-tabs>
+        </view>
+      </u-sticky>
+      <view class="content-box">
+        <view class="content-box-val">
+          <check-item
+            v-for="item in list"
+            :key="item.id"
+            :info="item"
+            @btnClick="handleBtnClick"
+          ></check-item>
+        </view>
+        <!-- 加载更多 -->
+        <u-loadmore :status="loadStatus" @loadmore="onLoadMore" />
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+import checkItem from "./components/check-item.vue";
+import {
+  taskStocktakingList,
+  startTask,
+} from "@/common/request/apis/inventoryTask";
+import { taskStatusList } from "../inventory-task/utils/index.js";
+
+export default {
+  components: {
+    checkItem,
+  },
+  data() {
+    return {
+      offsetTop: 0,
+      tabList: taskStatusList,
+      query: {
+        number: "",
+        status: "",
+      },
+      pageNum: 1,
+      pageSize: 10,
+      loadStatus: "loadmore", //加载前值为loadmore,加载中为loading,没有数据为nomore
+      list: [],
+    };
+  },
+  onLoad() {
+    let systemInfo = uni.getSystemInfoSync();
+    let statusBarHeight = systemInfo.statusBarHeight;
+    this.offsetTop = statusBarHeight + 40;
+    // 初始化数据
+    this.loadData();
+  },
+  onPullDownRefresh() {
+    // 下拉刷新
+    this.onRefresh();
+  },
+  onReachBottom() {
+    // 触底加载更多
+    this.onLoadMore();
+  },
+  methods: {
+    async onRefresh() {
+      try {
+        await this.loadData(true);
+      } finally {
+        uni.stopPullDownRefresh();
+      }
+    },
+    async onLoadMore() {
+      if (this.loadStatus !== "loadmore") return;
+      this.loadStatus = "loading";
+      try {
+        await this.loadData();
+      } catch (e) {
+        this.loadStatus = "loadmore";
+      }
+    },
+    async loadData(isRefresh = false) {
+      if (isRefresh) {
+        this.pageNum = 1;
+        this.list = [];
+      }
+
+      try {
+        this.loadStatus = "loading";
+        const pageNum = this.pageNum;
+        const pageSize = this.pageSize;
+        const params = {
+          pageNum,
+          pageSize,
+          ...this.query,
+        };
+        const res = await taskStocktakingList(params);
+        const { rows, total } = res.data;
+        this.list = [...this.list, ...rows];
+        if (pageNum * pageSize < Number(total)) {
+          this.pageNum++;
+          this.loadStatus = "loadmore";
+        } else {
+          this.loadStatus = "nomore";
+        }
+      } catch (error) {}
+    },
+    tabClick({ index }) {
+      this.query.status = this.tabList[index].value;
+      this.loadData(true);
+    },
+    handleSearch(value) {
+      this.loadData(true);
+    },
+    // 前往盘点任务详情
+    handleBtnClick(data) {
+      console.log(11111, data);
+      // params.id--->任务id   params.btnName--->按钮label
+      const { btnName } = data;
+      switch (btnName) {
+        case "详情":
+          uni.navigateTo({
+            url: `/pages/inventory-task/taskDetail?id=${data.id}`,
+          });
+          break;
+        case "去盘点":
+          startTask(data.id).then((res) => {
+            if (res.code === 200) {
+              uni.navigateTo({
+                url: `/pages/inventory-task/detail?id=${data.id}&pageType=1`,
+              });
+            } else {
+              uni.$u.toast(res.data);
+            }
+          });
+          break;
+        case "去提交":
+          break;
+      }
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.check-page {
+  min-height: 100vh;
+  background-color: #f0f6fb;
+  .container_main {
+    .search-box {
+      background-color: rgba(191, 200, 219, 0.2);
+      margin: 0 32rpx;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      border-radius: 8rpx;
+
+      ::v-deep .u-search__content {
+        background-color: transparent !important;
+
+        .u-search__content__input {
+          background-color: transparent !important;
+        }
+      }
+
+      .scan-icon {
+        width: 100rpx;
+        height: 100%;
+
+        image {
+          width: 40rpx;
+          height: 40rpx;
+        }
+      }
+    }
+
+    .content-box {
+      padding: 24rpx;
+      &-val {
+        border-radius: 16rpx 16rpx 0 0;
+        overflow: hidden;
+      }
+    }
+  }
+}
+</style>

+ 489 - 0
pages/inventory-task/inventoryDetail.vue

@@ -0,0 +1,489 @@
+<template>
+  <view class="inventory-detail">
+    <!-- 导航栏 -->
+    <u-navbar
+      :title="pageTitle"
+      :autoBack="true"
+      fixed
+      safe-area-inset-top
+      placeholder
+    >
+      <template #right>
+        <view class="nav-right">
+          <u-icon name="search" size="20" color="#333"></u-icon>
+        </view>
+      </template>
+    </u-navbar>
+
+    <!-- 基本信息 吸顶 -->
+    <view class="info-card">
+      <view class="info-item">
+        <text class="info-label">盘点单号:</text>
+        <text class="info-value">{{ inventoryInfo.code }}</text>
+      </view>
+      <view class="info-item">
+        <text class="info-label">盘点人:</text>
+        <text class="info-value">{{ inventoryInfo.operator }}</text>
+      </view>
+      <view class="progress-box">
+        <view class="progress-label-box">
+          <text class="progress-label"> 盘点进度 </text>
+          <text class="progress-value"
+            >{{ inventoryInfo.progress }}/{{ inventoryInfo.total }}</text
+          >
+        </view>
+        <view class="progress-bar-wrap">
+          <u-line-progress
+            :percentage="getProgressPercentage"
+            height="4"
+            :show-text="false"
+            activeColor="#4080FF"
+          >
+          </u-line-progress>
+        </view>
+      </view>
+    </view>
+    <!-- 筛选按钮 -->
+    <u-sticky bgColor="#F5F6F7" :offsetTop="44">
+      <view class="filter-wrap">
+        <view class="filter-btn" @click="filterPopupVisible = true">
+          <text>筛选</text>
+          <image
+            src="@/static/image/saixuan-icon.png"
+            mode=""
+            class="icon"
+          ></image>
+        </view>
+      </view>
+    </u-sticky>
+
+    <!-- 商品列表 -->
+    <view class="goods-list">
+      <view class="goods-item" v-for="(item, index) in goodsList" :key="index">
+        <view class="location-row">
+          <view class="location-left">
+            <text class="location-label">库位:</text>
+            <text class="location-value">{{ item.location }}</text>
+            <image
+              src="@/static/image/bianji-icon.png"
+              mode=""
+              class="icon"
+            ></image>
+          </view>
+          <text class="category-text">{{ item.category }}</text>
+        </view>
+
+        <view class="goods-content">
+          <image
+            class="goods-image"
+            :src="item.image"
+            mode="aspectFill"
+          ></image>
+          <view class="goods-info">
+            <text class="goods-name u-line-2">{{ item.name }}</text>
+            <view class="goods-field half-w">
+              <text class="field-label">规格:</text>
+              <text class="field-value">{{ item.spec }}</text>
+            </view>
+            <view class="goods-field half-w">
+              <text class="field-label">盘点人:</text>
+              <text class="field-value">{{ item.checkUser }}</text>
+            </view>
+            <view class="goods-field">
+              <text class="field-label">盘点时间:</text>
+              <text class="field-value">{{ item.checkTime }}</text>
+            </view>
+            <view class="stock-row">
+              <view class="stock-item">
+                <text class="stock-label">系统库存</text>
+                <text class="stock-value">{{ item.systemStock }}瓶</text>
+              </view>
+              <view class="stock-item">
+                <text class="stock-label">已盘库存</text>
+                <text
+                  class="stock-value"
+                  :class="{
+                    'stock-value-zero': item.actualStock === '未盘',
+                    'stock-value-warning': item.actualStock === '0瓶',
+                  }"
+                  >{{ item.actualStock }}</text
+                >
+              </view>
+            </view>
+          </view>
+        </view>
+
+        <view class="action-row">
+          <u-button
+            type="primary"
+            size="mini"
+            @click="handleCheck(item)"
+            class="action-btn"
+            >盘点</u-button
+          >
+          <u-button
+            type="primary"
+            size="mini"
+            @click="handleRecheck(item)"
+            class="action-btn"
+            >重新盘点
+          </u-button>
+          <u-button
+            type="warning"
+            size="mini"
+            plain
+            @click="handleCheck2(item)"
+            class="action-btn action-btn-secondary"
+            >盘亏</u-button
+          >
+        </view>
+      </view>
+    </view>
+    <InventoryFilterPopup
+      :show.sync="filterPopupVisible"
+      :defaultValues="defaultFilterValues"
+      @confirm="handleFilterConfirm"
+    />
+    <actionNumPopup :show.sync="actionPop.showNumPop" />
+    <categoryPopup :show.sync="actionPop.showCategoryPop" />
+    <error-pop
+      v-model="actionPop.errorShow"
+      isCenter
+      cancelBtnText="取消"
+      confirmBtnText="确定"
+      @close="actionPop.errorShow = false"
+      @confirm="confirm"
+      :content="actionPop.errorText"
+    ></error-pop>
+  </view>
+</template>
+
+<script>
+import InventoryFilterPopup from "./components/inventoryFilterPopup.vue";
+import actionNumPopup from "./components/actionNumPopup.vue";
+import categoryPopup from "./components/categoryPopup.vue";
+import errorPop from "@/components/error-pop/error-pop.vue";
+
+export default {
+  components: {
+    InventoryFilterPopup,
+    actionNumPopup,
+    errorPop,
+    categoryPopup,
+  },
+  data() {
+    return {
+      pageTitle: "2025年中心仓第三季度食品盘点",
+      loadMoreStatus: "loadmore", //加载前值为loadmore,加载中为loading,没有数据为nomore
+      pageNum: 1,
+      pageSize: 10,
+      inventoryInfo: {
+        code: "2024202244",
+        operator: "刘双秀",
+        progress: 105,
+        total: 604,
+      },
+      goodsList: [
+        {
+          location: "C6-2-2",
+          category: "母婴用品-家居旅行",
+          image: "/static/demo/goods1.png",
+          name: "4层汗巾儿童全棉幼儿类吸汗巾婴儿纱布毛巾1条装",
+          spec: "4层-随机",
+          checkUser: "刘双秀",
+          checkTime: "2025-04-03",
+          systemStock: "5瓶",
+          actualStock: "未盘",
+          isChecked: false,
+        },
+        {
+          location: "C6-2-2",
+          category: "母婴用品-家居旅行",
+          image: "/static/demo/goods1.png",
+          name: "4层汗巾儿童全棉幼儿类吸汗巾婴儿纱布毛巾1条装",
+          spec: "4层-随机",
+          checkUser: "刘双秀",
+          checkTime: "2025-04-03",
+          systemStock: "5瓶",
+          actualStock: "0瓶",
+          isChecked: true,
+        },
+      ],
+      filterPopupVisible: false,
+      defaultFilterValues: {
+        goods: "",
+        user: "",
+        category: "",
+        location: "",
+      },
+      actionPop: {
+        // 盘点数量弹框状态
+        showNumPop: false,
+        // 警告提示弹框状态
+        errorShow: false,
+        errorText: "是否提交盘点?",
+        // 修改库位弹框状态
+        showCategoryPop: false,
+      },
+    };
+  },
+  computed: {
+    getProgressPercentage() {
+      return (this.inventoryInfo.progress / this.inventoryInfo.total) * 100;
+    },
+  },
+  onLoad(opt) {
+    console.log("222222", opt);
+    // 初始化数据
+    // this.loadData(opt.id);
+  },
+  methods: {
+    async loadData(id) {
+      try {
+      } catch (error) {}
+    },
+    handleCheck(item) {
+      uni.showToast({
+        title: "开始盘点",
+        icon: "none",
+      });
+    },
+    handleRecheck(item) {
+      uni.showToast({
+        title: "开始重新盘点",
+        icon: "none",
+      });
+    },
+    handleCheck2(item) {
+      uni.showToast({
+        title: "开始盘点2",
+        icon: "none",
+      });
+    },
+    handleFilterConfirm(values) {
+      this.defaultFilterValues = values;
+      this.filterPopupVisible = false;
+    },
+  },
+};
+</script>
+
+<style lang="scss">
+.inventory-detail {
+  min-height: 100vh;
+  background-color: #f0f6fb;
+  padding-bottom: 40rpx;
+
+  .nav-right {
+    padding: 0 24rpx;
+  }
+
+  .info-card {
+    background-color: #fff;
+    padding: 16rpx 32rpx;
+
+    .info-item {
+      display: flex;
+      font-size: 28rpx;
+      margin-bottom: 10rpx;
+
+      .info-label {
+        color: #666;
+        margin-right: 8rpx;
+      }
+
+      .info-value {
+        color: #333;
+      }
+    }
+
+    .progress-box {
+      .progress-label-box {
+        display: flex;
+        justify-content: space-between;
+      }
+
+      .progress-label {
+        font-size: 28rpx;
+        color: #666;
+        display: block;
+        margin-bottom: 16rpx;
+      }
+
+      .progress-bar-wrap {
+        margin-bottom: 16rpx;
+      }
+
+      .progress-value {
+        font-size: 24rpx;
+        color: #4080ff;
+        display: block;
+        text-align: right;
+      }
+    }
+  }
+
+  .filter-wrap {
+    display: flex;
+    justify-content: flex-end;
+    padding: 20rpx;
+
+    .filter-btn {
+      display: flex;
+      align-items: center;
+      border-radius: 8rpx;
+      font-size: 24rpx;
+      color: #333333;
+
+      .icon {
+        margin-left: 8rpx;
+        width: 32rpx;
+        height: 32rpx;
+      }
+    }
+  }
+
+  .goods-list {
+    width: 710rpx;
+    margin: 0 20rpx;
+    border-radius: 16rpx;
+
+    .goods-item {
+      background-color: #fff;
+      overflow: hidden;
+      border-bottom: 1px solid #f5f6f7;
+
+      .location-row {
+        display: flex;
+        align-items: center;
+        padding: 24rpx 32rpx;
+        border-bottom: 1px solid #f5f6f7;
+        gap: 40rpx;
+
+        .location-left {
+          display: flex;
+          align-items: center;
+
+          .location-label {
+            font-size: 28rpx;
+            color: #333;
+          }
+
+          .location-value {
+            font-size: 28rpx;
+            color: #4080ff;
+            margin: 0 8rpx;
+          }
+
+          .icon {
+            width: 32rpx;
+            height: 32rpx;
+          }
+        }
+
+        .category-text {
+          font-size: 24rpx;
+          color: #999;
+        }
+      }
+
+      .goods-content {
+        padding: 24rpx 32rpx;
+        display: flex;
+
+        .goods-image {
+          width: 160rpx;
+          flex-basis: 160rpx;
+          height: 160rpx;
+          border-radius: 8rpx;
+          background-color: #f5f6f7;
+        }
+
+        .goods-info {
+          display: flex;
+          flex-wrap: wrap;
+          flex: 1;
+          margin-left: 24rpx;
+
+          .half-w {
+            width: 50%;
+          }
+
+          .goods-name {
+            font-size: 28rpx;
+            line-height: 1.4;
+            color: #333;
+            margin-bottom: 16rpx;
+          }
+
+          .goods-field {
+            font-size: 24rpx;
+            color: #666;
+            margin-bottom: 16rpx;
+
+            .field-label {
+              color: #999;
+            }
+
+            .field-value {
+              color: #666;
+            }
+          }
+        }
+      }
+
+      .stock-row {
+        display: grid;
+        grid-template-columns: 50% 50%;
+        width: 100%;
+        padding: 24rpx;
+        background-color: #f6f8fa;
+        border-radius: 8rpx;
+
+        .stock-item {
+          display: flex;
+          flex-direction: column;
+
+          .stock-label {
+            font-size: 24rpx;
+            color: #999;
+            margin-bottom: 20rpx;
+          }
+
+          .stock-value {
+            font-size: 24rpx;
+            color: #333;
+
+            &-zero {
+              color: #999;
+            }
+
+            &-warning {
+              color: #ff9900;
+            }
+          }
+        }
+      }
+
+      .action-row {
+        padding: 0 32rpx 32rpx;
+        display: flex;
+        justify-content: flex-end;
+        gap: 24rpx;
+
+        .action-btn {
+          width: 140rpx;
+          height: 56rpx;
+          padding: 0;
+
+          &-secondary {
+            background-color: transparent;
+            border-color: #ff9900;
+            color: #ff9900;
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 31 - 22
pages/inventory-task/taskDetail.vue

@@ -13,12 +13,12 @@
     <!-- 任务信息卡片 -->
     <view class="info-card">
       <view class="task-title">
-        {{ taskInfo.title }}
+        {{ taskInfo.taskName }}
         <view
           class="task-status"
-          :class="{ 'status-completed': taskInfo.status === '已完成' }"
+          :class="{ 'status-completed': taskInfo.taskStatus === 3 }"
         >
-          {{ taskInfo.status }}
+          {{ curTaskStatusInfo.name2 }}
         </view>
       </view>
 
@@ -29,7 +29,7 @@
         <view class="stat-item">
           <view class="stat-label">盘点商品</view>
           <view class="stat-value highlight">
-            {{ taskInfo.inventoryCount }}/{{ taskInfo.totalCount }}
+            {{ taskInfo.finishCount }}/{{ taskInfo.itemCount }}
           </view>
         </view>
         <view class="stat-item">
@@ -49,19 +49,19 @@
       <view class="info-list">
         <view class="info-item">
           <text class="info-label">盘点类型</text>
-          <text class="info-value">{{ taskInfo.type }}</text>
+          <text class="info-value">{{ curTaskTyoeInfo.name }}</text>
         </view>
         <view class="info-item">
           <text class="info-label">盘点仓库</text>
-          <text class="info-value">{{ taskInfo.warehouse }}</text>
+          <text class="info-value">{{ taskInfo.depotName }}</text>
         </view>
         <view class="info-item">
           <text class="info-label">盘点范围</text>
-          <text class="info-value">{{ taskInfo.scope }}</text>
+          <text class="info-value">{{ taskInfo.positionRange }}</text>
         </view>
         <view class="info-item">
           <text class="info-label">参与人员</text>
-          <text class="info-value">{{ taskInfo.participants }}</text>
+          <text class="info-value">{{ taskInfo.operBy }}</text>
         </view>
       </view>
     </view>
@@ -69,31 +69,40 @@
 </template>
 
 <script>
+import { taskStocktakingDetail } from "@/common/request/apis/inventoryTask";
+import { getTaskTypeInfoByVal, getTaskStatusInfoByVal } from "./utils/index.js";
+
 export default {
   data() {
     return {
-      taskInfo: {
-        title: "2023年中心仓第三季度食品盘点",
-        status: "已完成",
-        number: "2024202244",
-        inventoryCount: "604",
-        totalCount: "604",
-        differenceRate: "6.29%",
-        accuracyRate: "97.80%",
-        type: "盘点类型",
-        warehouse: "中心仓",
-        scope: "A区-B区",
-        participants: "张三、李四",
-      },
+      taskInfo: {},
     };
   },
+  computed: {
+    curTaskStatusInfo() {
+      return getTaskStatusInfoByVal(this.taskInfo.taskStatus);
+    },
+    curTaskTyoeInfo() {
+      return getTaskTypeInfoByVal(this.taskInfo.taskType);
+    },
+  },
+  onLoad(opt) {
+    this.loadData(opt.id);
+  },
   methods: {
     viewDetail() {
       // 跳转到盘点详情页面
       uni.navigateTo({
-        url: "/pages/inventory-task/inventory-detail",
+        url: "/pages/inventory-task/inventoryDetail",
       });
     },
+    async loadData(id) {
+      try {
+        const res = await taskStocktakingDetail(id);
+        console.log("res====", res);
+        this.taskInfo = res.data;
+      } catch (error) {}
+    },
   },
 };
 </script>

+ 131 - 0
pages/inventory-task/utils/index.js

@@ -0,0 +1,131 @@
+// 盘点-任务状态
+// 任务状态 1.未开始,2.进行中,3.已完成,4.已取消
+export const taskStatusList = [
+  {
+    value: "",
+    name: "全部任务",
+    name2: "",
+    className: "",
+  },
+  {
+    value: 1,
+    name: "待盘点",
+    name2: "未开始",
+    className: "tips-red",
+  },
+  {
+    value: 2,
+    name: "盘点中",
+    name2: "进行中",
+    className: "tips-green",
+  },
+  {
+    value: 3,
+    name: "已盘点",
+    name2: "已完成",
+    className: "tips-hui",
+  },
+  {
+    value: 4,
+    name: "已取消",
+    name2: "已取消",
+    className: "tips-yellow",
+  },
+];
+
+export function getTaskStatusInfoByVal(val) {
+  const target = taskStatusList.find((item) => item.value === val);
+  return target || {};
+}
+
+export const taskTypeList = [
+  {
+    value: 1,
+    name: "全盘",
+  },
+  {
+    value: 2,
+    name: "抽盘",
+  },
+];
+
+export function getTaskTypeInfoByVal(val) {
+  const target = taskTypeList.find((item) => item.value === val);
+  return target || {};
+}
+
+// 盘点状态 商品盘点类型:1.未盘,2.盘盈,3.盘亏 4.无差异 其余为全部
+export const goodsInventoryStatus = [
+  {
+    name: "未盘",
+    value: 1,
+  },
+  {
+    name: "盘盈",
+    value: 2,
+  },
+  {
+    name: "盘亏",
+    value: 3,
+  },
+  {
+    name: "无差异",
+    value: 4,
+  },
+];
+
+export function getGoodsInventoryStatusInfoByVal(val) {
+  const target = goodsInventoryStatus.find((item) => item.value === val);
+  return target || {};
+}
+/**
+ * @des 前端计算系统库存、已盘库存数量 获取盘点状态信息
+ * @parms inventory 系统库存
+ * @parms newInventory 系统库存
+ */
+
+export function getGoodsInventoryStatusInfo(inventory, newInventory) {
+  const goodsInventoryStatus = [
+    {
+      label: "去盘点",
+      value: "1",
+    },
+    {
+      label: "盘盈",
+      value: "2",
+    },
+    {
+      label: "盘亏",
+      value: "3",
+    },
+    {
+      label: "无差异",
+      value: "4",
+    },
+  ];
+  let val;
+  const a = inventory || 0; // 系统库存
+  const b = newInventory || 0; // 已盘库存
+  const diffVal = Number(a) - Number(b);
+  if (b === 0) {
+    val = "1";
+  } else if (diffVal === 0 && a !== 0) {
+    val = "4";
+  } else if (diffVal > 0) {
+    val = "3";
+  } else {
+    val = "2";
+  }
+  const target = goodsInventoryStatus.find((item) => item.value === val);
+  if (target) {
+    return {
+      ...target,
+      inventory: a,
+      newInventory: b,
+    };
+  }
+  return {
+    inventory: a,
+    newInventory: b,
+  };
+}