浏览代码

盘点*下架*审核未完成

Alex 11 月之前
父节点
当前提交
fdf1b15518
共有 32 个文件被更改,包括 2376 次插入1382 次删除
  1. 173 159
      pages/book/components/feedbackPopup.vue
  2. 1 6
      pages/book/index.vue
  3. 1 1
      pages/index/detail/components/BookItem.vue
  4. 142 49
      pages/index/wms/bad-off.vue
  5. 68 33
      pages/index/wms/bad-out-order.vue
  6. 1 1
      pages/index/wms/bad-out.vue
  7. 13 10
      pages/index/wms/components/BadOutCard.vue
  8. 5 1
      pages/index/wms/components/LocationOrderItem.vue
  9. 61 34
      pages/index/wms/speedy-check-add.vue
  10. 343 69
      pages/index/wms/speedy-check.vue
  11. 231 89
      pages/index/wms/task-detail.vue
  12. 3 3
      pages/my/components/orderItem.vue
  13. 19 11
      pages/my/page/audit-unfinished.vue
  14. 二进制
      static/img/location-active.png
  15. 二进制
      static/img/location.png
  16. 二进制
      static/img/share.png
  17. 0 0
      unpackage/dist/build/app-plus/app-config-service.js
  18. 0 0
      unpackage/dist/build/app-plus/app-service.js
  19. 0 0
      unpackage/dist/build/app-plus/pages/index/audit/express-order.css
  20. 0 0
      unpackage/dist/build/app-plus/pages/index/detail/batch-audit.css
  21. 0 0
      unpackage/dist/build/app-plus/pages/index/detail/book-audit.css
  22. 0 0
      unpackage/dist/build/app-plus/pages/index/detail/index.css
  23. 0 0
      unpackage/dist/build/app-plus/pages/index/express/quick-unpack.css
  24. 1 1
      unpackage/dist/build/app-plus/pages/index/index.css
  25. 0 0
      unpackage/dist/build/app-plus/pages/index/wms/bad-in.css
  26. 0 0
      unpackage/dist/build/app-plus/pages/index/wms/bad-out-order.css
  27. 0 0
      unpackage/dist/build/app-plus/pages/index/wms/order-query-list.css
  28. 909 738
      unpackage/dist/dev/app-plus/app-service.js
  29. 209 173
      unpackage/dist/dev/app-plus/pages/book/index.css
  30. 179 0
      unpackage/dist/dev/app-plus/pages/index/wms/bad-off.css
  31. 14 1
      unpackage/dist/dev/app-plus/pages/index/wms/bad-out-order.css
  32. 3 3
      unpackage/dist/dev/app-plus/pages/index/wms/task-detail.css

+ 173 - 159
pages/book/components/feedbackPopup.vue

@@ -1,166 +1,180 @@
 <template>
-	<u-popup mode="center" :show="show" @close="handleCancel" :closeOnClickOverlay="false">
-		<view class="popup-container">
-			<u-form ref="formRef" :model="formData" :rules="rules" labelPosition="top" labelWidth="100%"
-				error-type="toast">
-
-				<!-- 反馈信息 -->
-				<u-form-item label="反馈图书信息" prop="feedbackContent" :borderBottom="true">
-					<u-input v-model="formData.feedbackContent" type="textarea" placeholder="请输入反馈信息" :border="true"
-						height="100"></u-input>
-				</u-form-item>
-
-				<!-- 图片上传 -->
-				<u-form-item label="上传照片" prop="imgUrl" :borderBottom="false">
-					<u-upload :fileList="formData.imgUrl" @afterRead="afterRead" @delete="deletePic" name="1" multiple
-						:maxCount="1" :imageMode="true">
-						<view class="upload-slot">
-							<u-icon name="plus" size="30"></u-icon>
-							<text class="upload-text">上传照片</text>
-						</view>
-					</u-upload>
-				</u-form-item>
-			</u-form>
-
-			<!-- 按钮组 -->
-			<view class="button-group">
-				<u-button type="info" text="取消" :plain="true" @click="handleCancel" :disabled="submitting"></u-button>
-				<u-button type="primary" text="确认" @click="handleConfirm" :loading="submitting"></u-button>
-			</view>
-		</view>
-	</u-popup>
+    <u-popup mode="center" :show="show" @close="handleCancel" :closeOnClickOverlay="false">
+        <view class="popup-container">
+            <u-form
+                ref="formRef"
+                :model="formData"
+                :rules="rules"
+                labelPosition="top"
+                labelWidth="100%"
+                error-type="toast"
+            >
+                <!-- 反馈信息 -->
+                <u-form-item label="反馈图书信息" prop="feedbackContent" :borderBottom="true">
+                    <u-input
+                        v-model="formData.feedbackContent"
+                        type="textarea"
+                        placeholder="请输入反馈信息"
+                        height="100"
+                    ></u-input>
+                </u-form-item>
+
+                <!-- 图片上传 -->
+                <u-form-item label="上传照片" prop="imgUrl" :borderBottom="false">
+                    <cy-upload v-model:filename="formData.imgUrl" multiple :maxCount="4">
+                        <view class="upload-slot">
+                            <u-icon name="plus" size="30"></u-icon>
+                            <text class="upload-text">上传照片</text>
+                        </view>
+                    </cy-upload>
+                </u-form-item>
+            </u-form>
+
+            <!-- 按钮组 -->
+            <view class="button-group">
+                <u-button type="info" text="取消" :plain="true" @click="handleCancel" :disabled="submitting"></u-button>
+                <u-button type="primary" text="确认" @click="handleConfirm" :loading="submitting"></u-button>
+            </view>
+        </view>
+    </u-popup>
 </template>
 
 <script setup>
-	import {
-		ref,
-		reactive
-	} from 'vue'
-
-	const show = ref(false)
-	const emit = defineEmits(['submit'])
-
-	// 表单引用
-	const formRef = ref(null)
-
-	// 提交状态
-	const submitting = ref(false)
-
-	// 表单数据
-	const formData = reactive({
-		feedbackContent: '',
-		imgUrl: '',
-		isbn: ''
-	})
-
-	// 表单验证规则
-	const rules = {
-		feedbackContent: [{
-			required: true,
-			message: '请输入反馈信息',
-			trigger: ['blur', 'change']
-		}],
-	}
-
-	//打开
-	function open(data) {
-		show.value = true
-		formData.isbn = data.isbn
-	}
-
-	// 取消操作
-	function handleCancel() {
-		resetForm()
-		show.value = false
-	}
-
-	// 确认操作
-	async function handleConfirm() {
-		// 表单验证
-		formRef.value?.validate().then(res => {
-			submitting.value = true
-			uni.$u.http.post('/app/feedback/add', formData).then(res => {
-				if (res.code == 200) {
-					// 提交成功
-					uni.showToast({
-						title: '反馈已提交',
-						icon: 'success'
-					})
-
-					// 触发提交事件
-					emit('submit', formData)
-					show.value = false
-				} else {
-					uni.$u.toast(res.msg)
-				}
-			}).finally(() => {
-				submitting.value = false
-			})
-		})
-	}
-
-	// 重置表单
-	function resetForm() {
-		formData.feedbackContent = ''
-		formData.imgUrl = ''
-		formRef.value?.resetFields()
-	}
-	
-	defineExpose({
-		open
-	})
+import cyUpload from "@/components/cy-upload/index.vue";
+import { ref, reactive } from "vue";
+
+const show = ref(false);
+const emit = defineEmits(["submit"]);
+
+// 表单引用
+const formRef = ref(null);
+
+// 提交状态
+const submitting = ref(false);
+
+// 表单数据
+const formData = reactive({
+    feedbackContent: "",
+    imgUrl: [],
+    isbn: "",
+});
+
+// 表单验证规则
+const rules = {
+    feedbackContent: [
+        {
+            required: true,
+            message: "请输入反馈信息",
+            trigger: ["blur", "change"],
+        },
+    ],
+};
+
+//打开
+function open(data) {
+    show.value = true;
+    formData.isbn = data.isbn;
+}
+
+// 取消操作
+function handleCancel() {
+    resetForm();
+    show.value = false;
+}
+
+// 确认操作
+async function handleConfirm() {
+    // 表单验证
+    formRef.value?.validate().then((res) => {
+        submitting.value = true;
+
+        let data = JSON.parse(JSON.stringify(formData));
+        data.imgUrl = data.imgUrl.join(",");
+        uni.$u.http
+            .post("/app/feedback/add", data)
+            .then((res) => {
+                if (res.code == 200) {
+                    // 提交成功
+                    uni.showToast({
+                        title: "反馈已提交",
+                        icon: "success",
+                    });
+
+                    // 触发提交事件
+                    emit("submit", formData);
+                    show.value = false;
+                } else {
+                    uni.$u.toast(res.msg);
+                }
+            })
+            .finally(() => {
+                submitting.value = false;
+            });
+    });
+}
+
+// 重置表单
+function resetForm() {
+    formData.feedbackContent = "";
+    formData.imgUrl = "";
+    formRef.value?.resetFields();
+}
+
+defineExpose({
+    open,
+});
 </script>
 
 <style lang="scss" scoped>
-	:deep(.u-popup__content) {
-		border-radius: 12px;
-	}
-
-	.popup-container {
-		width: 640rpx;
-		background-color: #ffffff;
-		border-radius: 12rpx;
-		padding: 30rpx;
-
-		:deep(.u-form) {
-			.u-form-item {
-				&__body {
-					padding: 20rpx 0;
-				}
-
-				&__body__left__content {
-					padding-bottom: 8rpx;
-				}
-			}
-		}
-
-		.upload-slot {
-			width: 160rpx;
-			height: 160rpx;
-			border: 2rpx dashed #dcdfe6;
-			border-radius: 8rpx;
-			display: flex;
-			flex-direction: column;
-			align-items: center;
-			justify-content: center;
-
-			.upload-text {
-				font-size: 24rpx;
-				color: #909399;
-				margin-top: 10rpx;
-			}
-		}
-
-		.button-group {
-			display: flex;
-			justify-content: space-between;
-			margin-top: 40rpx;
-			padding: 0 20rpx;
-
-			:deep(.u-button) {
-				width: 45%;
-				border-radius: 8rpx;
-			}
-		}
-	}
-</style>
+:deep(.u-popup__content) {
+    border-radius: 12px;
+}
+
+.popup-container {
+    width: 640rpx;
+    background-color: #ffffff;
+    border-radius: 12rpx;
+    padding: 30rpx;
+
+    :deep(.u-form) {
+        .u-form-item {
+            &__body {
+                padding: 20rpx 0;
+            }
+
+            &__body__left__content {
+                padding-bottom: 8rpx;
+            }
+        }
+    }
+
+    .upload-slot {
+        width: 160rpx;
+        height: 160rpx;
+        border: 2rpx dashed #dcdfe6;
+        border-radius: 8rpx;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+
+        .upload-text {
+            font-size: 24rpx;
+            color: #909399;
+            margin-top: 10rpx;
+        }
+    }
+
+    .button-group {
+        display: flex;
+        justify-content: space-between;
+        margin-top: 40rpx;
+        padding: 0 20rpx;
+
+        :deep(.u-button) {
+            width: 45%;
+            border-radius: 8rpx;
+        }
+    }
+}
+</style>

+ 1 - 6
pages/book/index.vue

@@ -50,12 +50,7 @@
 
 	// 搜索相关
 	const searchText = ref('')
-	const bookList = ref([{
-		bookName: '怪兽阿斗来了',
-		suit: 0,
-		price: 99,
-		isbn: '9787559603159'
-	}])
+	const bookList = ref([])
 
 	// 处理搜索
 	async function handleSearch() {

+ 1 - 1
pages/index/detail/components/BookItem.vue

@@ -56,7 +56,7 @@ const reasons = computed(() => {
     if (list.length > 0) {
         let poorList = list.filter(v => v.sts == 3)
         if (poorList.length == 0) return ''
-        return poorList.map(v => v.com).join('/')
+        return poorList.map(v => v.com).join(';')
     }
 })
 </script>

+ 142 - 49
pages/index/wms/bad-off.vue

@@ -2,88 +2,164 @@
     <view class="container">
         <!-- 任务列表 -->
         <view class="task-list">
-            <view v-for="(item, index) in taskList" :key="index" class="task-card" @click="handleTaskClick(item)">
-                <view class="task-header">
-                    <text class="task-no">作业单号:{{ item.taskNo }}</text>
-                </view>
-                <view class="task-content">
-                    <view class="flex-a mb-10">
-                        <text class="label">仓库:</text>
-                        <text class="value">{{ item.warehouse }}</text>
-                    </view>
-                    <view class="flex-a mb-10">
-                        <text class="label">任务数量:</text>
-                        <text class="value">{{ item.quantity }}</text>
+            <template v-if="!loading">
+                <view
+                    v-if="taskList.length > 0"
+                    v-for="(item, index) in taskList"
+                    :key="index"
+                    class="task-card"
+                    @click="handleTaskClick(item)"
+                >
+                    <view class="task-header">
+                        <text class="task-no">作业单号:{{ item.taskCode }}</text>
                     </view>
-                    <view class="flex-a">
-                        <text class="label">作业状态:</text>
-                        <text class="value">{{ item.status }}</text>
+                    <view class="task-content">
+                        <view class="flex-a mb-10">
+                            <text class="label">仓库:</text>
+                            <text class="value">{{ item.godownName }}</text>
+                        </view>
+                        <view class="flex-a mb-10">
+                            <text class="label">订单数量:</text>
+                            <text class="value">{{ item.orderNum }}</text>
+                        </view>
+                        <view class="flex-a mb-10">
+                            <text class="label">创建时间:</text>
+                            <text class="value">{{ item.createTime }}</text>
+                        </view>
+                        <view class="flex-a">
+                            <text class="label">作业状态:</text>
+                            <text class="value">{{ getTaskStatusText(item.taskStatus) }}</text>
+                        </view>
                     </view>
                 </view>
+                <view v-else class="empty-state">
+                    <text>暂无任务数据</text>
+                </view>
+            </template>
+            <view v-else class="loading-state">
+                <u-loading-icon></u-loading-icon>
+                <text>加载中...</text>
             </view>
         </view>
     </view>
 </template>
 
 <script setup>
-import { ref } from 'vue'
+import { ref, onMounted } from "vue";
 
 // 搜索文本
-const searchText = ref('')
+const searchText = ref("");
 
 // 任务列表数据
-const taskList = ref([
-    {
-        taskNo: 'XJ20245451421',
-        warehouse: '河南仓',
-        quantity: 40,
-        status: '待作业'
-    },
-    {
-        taskNo: 'XJ20245451421',
-        warehouse: '河南仓',
-        quantity: 40,
-        status: '待作业'
+const taskList = ref([]);
+
+// 加载状态
+const loading = ref(false);
+
+// 作业状态枚举
+const taskStatusEnum = {
+    1: "待作业",
+    2: "作业中",
+    3: "已完成",
+    4: "已关闭",
+};
+
+// 获取状态文本
+const getTaskStatusText = (status) => {
+    return taskStatusEnum[status] || "未知状态";
+};
+
+// 获取任务列表
+const fetchTaskList = async () => {
+    loading.value = true;
+    try {
+        const response = await uni.$u.http.post("/app/appstock/getNeedStockList");
+        console.log(response);
+        taskList.value = response;
+        if (response.code === 200) {
+            taskList.value = response.data || [];
+        } else {
+            uni.showToast({
+                title: response.msg || "获取任务列表失败",
+                icon: "none",
+            });
+        }
+    } catch (error) {
+        uni.showToast({
+            title: "获取任务列表失败",
+            icon: "none",
+        });
+    } finally {
+        loading.value = false;
     }
-])
+};
 
 // 搜索处理
 const onSearch = () => {
-    // 实现搜索逻辑
-}
+    fetchTaskList();
+};
 
 // 打开扫码
 const openScan = () => {
     // #ifdef APP-PLUS || MP-WEIXIN
     uni.scanCode({
         success: (res) => {
-            searchText.value = res.result
-            onSearch()
+            searchText.value = res.result;
+            onSearch();
         },
         fail: (err) => {
             uni.showToast({
-                title: '扫码失败',
-                icon: 'error'
-            })
-        }
-    })
+                title: "扫码失败",
+                icon: "error",
+            });
+        },
+    });
     // #endif
 
     // #ifdef H5
     uni.showToast({
-        title: 'H5环境不支持扫码',
-        icon: 'none'
-    })
+        title: "H5环境不支持扫码",
+        icon: "none",
+    });
     // #endif
-}
+};
 
 // 点击任务卡片
 const handleTaskClick = (task) => {
-    // 处理任务点击,可以跳转到详情页
-    uni.navigateTo({
-        url: `/pages/index/wms/task-detail?taskNo=${task.taskNo}`
-    })
-}
+    uni.showModal({
+        title: "领取确认",
+        content: "是否确认领取下架任务?",
+        cancelText: "取消",
+        confirmText: "确认",
+        success: async (res) => {
+            if (res.confirm) {
+                try {
+                    const response = await uni.$u.http.post(`/app/appstock/lockStockTask?taskCode=${task.taskCode}`);
+                    if (response.code === 200) {
+                        uni.navigateTo({
+                            url: `/pages/index/wms/task-detail?taskCode=${task.taskCode}`,
+                        });
+                    } else {
+                        uni.showToast({
+                            title: response.msg || "任务锁定失败",
+                            icon: "none",
+                        });
+                    }
+                } catch (error) {
+                    uni.showToast({
+                        title: error,
+                        icon: "none",
+                    });
+                }
+            }
+        },
+    });
+};
+
+// 页面加载时获取任务列表
+onMounted(() => {
+    fetchTaskList();
+});
 </script>
 
 <style scoped>
@@ -105,4 +181,21 @@ const handleTaskClick = (task) => {
     font-size: 28rpx;
     font-weight: bold;
 }
-</style>
+
+.empty-state {
+    text-align: center;
+    padding: 40rpx;
+    color: #999;
+}
+
+.loading-state {
+    text-align: center;
+    padding: 40rpx;
+}
+
+.loading-state text {
+    margin-left: 12rpx;
+    color: #666;
+    font-size: 28rpx;
+}
+</style>

+ 68 - 33
pages/index/wms/bad-out-order.vue

@@ -12,22 +12,30 @@
         </u-sticky>
 
         <view class="content">
-            <!-- 基本信息 -->
-            <view class="info-section">
-                <view class="info-item">库位:{{ locationInfo.location }}</view>
-                <view class="info-item">物流单号:{{ locationInfo.logisticsNo }}</view>
-                <view class="info-item">订单编号:{{ locationInfo.orderNo }}</view>
-                <view class="info-item">订单商品:{{ locationInfo.goodsCount }}</view>
-                <view class="info-item">备注信息:{{ locationInfo.remark }}</view>
+            <!-- 错误提示 -->
+            <view v-if="errorMsg" class="error-section">
+                <u-icon name="info-circle" color="#fa3534" size="20"></u-icon>
+                <text class="error-text">{{ errorMsg }}</text>
             </view>
 
-            <!-- 极差商品列表 -->
-            <view class="bad-list">
-                <view class="list-title mb-6">极差</view>
-                <view v-for="(item, index) in badList" :key="index">
-                    <BadOutCard :item="item" />
+            <!-- 基本信息 -->
+            <template v-if="hasData">
+                <view class="info-section">
+                    <view class="info-item">库位:{{ locationInfo.positionCode }}</view>
+                    <view class="info-item">物流单号:{{ locationInfo.waybillCode||'-' }}</view>
+                    <view class="info-item">订单编号:{{ locationInfo.orderId }}</view>
+                    <view class="info-item">订单商品:{{ locationInfo.badNum }}</view>
+                    <view class="info-item">备注信息:{{ locationInfo.remark||'-' }}</view>
                 </view>
-            </view>
+
+                <!-- 极差商品列表 -->
+                <view class="bad-list">
+                    <view class="list-title mb-6">极差</view>
+                    <view v-for="(item, index) in badList" :key="index">
+                        <BadOutCard :item="item" :index="index" />
+                    </view>
+                </view>
+            </template>
         </view>
 
         <!-- 底部按钮 -->
@@ -50,15 +58,16 @@ import VolumeTTS from '@/utils/VolumeTTS.js';
 import { onLoad } from '@dcloudio/uni-app'
 
 const ttsModule = ref(null)
-// 搜索文本
 const searchText = ref('')
+const errorMsg = ref('')
+const hasData = ref(false)
 
 // 位置信息
 const locationInfo = ref({
-    location: '',
-    logisticsNo: '',
-    orderNo: '',
-    goodsCount: '',
+    positionCode: '',
+    waybillCode: '',
+    orderId: '',
+    badNum: '',
     remark: ''
 })
 
@@ -82,27 +91,39 @@ const getSearchType = (text) => {
 
 // 搜索处理
 const onSearch = async () => {
-    if (!searchText.value) return
+    if (!searchText.value) {
+        errorMsg.value = '请输入运单号或订单编号'
+        hasData.value = false
+        return
+    }
 
     try {
         const searchType = getSearchType(searchText.value)
-        const { data } = await uni.$u.http.post('/app/stock/findOrderOutStock', {
+        const res = await uni.$u.http.post('/app/stock/findOrderOutStock', {
             search: searchText.value,
             searchType: searchType
         })
-
-        if (data) {
+        if (res.code == 200) {
+            const data = res.data
+            errorMsg.value = ''
+            hasData.value = true
             // 更新页面数据
             locationInfo.value = {
-                location: data.location || '',
-                logisticsNo: data.logisticsNo || '',
-                orderNo: data.orderNo || '',
-                goodsCount: data.goodsCount || '',
+                positionCode: data.positionCode || '',
+                waybillCode: data.waybillCode || '',
+                orderId: data.orderId || '',
+                badNum: data.badNum || '',
                 remark: data.remark || ''
             }
-            badList.value = data.badList || []
+            badList.value = data.detailVoList || []
+        } else {
+            errorMsg.value = res.msg || '未找到相关数据'
+            hasData.value = false
+            return
         }
     } catch (error) {
+        errorMsg.value = error.message || '获取数据失败'
+        hasData.value = false
         uni.showToast({
             title: '获取数据失败',
             icon: 'none'
@@ -144,8 +165,8 @@ const onConfirm = () => {
             if (res.confirm) {
                 try {
                     await uni.$u.http.post('/app/stock/outStock', {
-                        orderId: locationInfo.value.orderNo,
-                        positionCode: locationInfo.value.location,
+                        orderId: locationInfo.value.orderId,
+                        positionCode: locationInfo.value.positionCode,
                         outputRemark: locationInfo.value.remark
                     })
 
@@ -158,10 +179,10 @@ const onConfirm = () => {
                     // 清空数据
                     searchText.value = ''
                     locationInfo.value = {
-                        location: '',
-                        logisticsNo: '',
-                        orderNo: '',
-                        goodsCount: '',
+                        positionCode: '',
+                        waybillCode: '',
+                        orderId: '',
+                        badNum: '',
                         remark: ''
                     }
                     badList.value = []
@@ -203,6 +224,20 @@ const handleRemarkConfirm = (remark) => {
     padding-bottom: 120rpx;
 }
 
+.error-section {
+    background-color: #fef0f0;
+    padding: 20rpx;
+    border-radius: 8rpx;
+    margin-bottom: 20rpx;
+    display: flex;
+    align-items: center;
+}
+
+.error-text {
+    color: #fa3534;
+    margin-left: 10rpx;
+    font-size: 28rpx;
+}
 
 .info-section {
     background-color: #fff;

+ 1 - 1
pages/index/wms/bad-out.vue

@@ -7,7 +7,7 @@
 
         <!-- 底部搜索框 -->
         <view class="pad-20 flex-a" style="background: #ffffff;">
-            <u-search v-model="searchText" placeholder="请输入库位条码" :show-action="false" :clearabled="true"
+            <u-search v-model="searchText" placeholder="请输入快递单号/订单编号" :show-action="false" :clearabled="true"
                 @change="onSearch" height="40" @click="searchText = ''">
             </u-search>
             <u-icon name="scan" size="28" color="#19be6b" @click="openScan"></u-icon>

+ 13 - 10
pages/index/wms/components/BadOutCard.vue

@@ -2,29 +2,30 @@
     <view class="card">
         <view class="flex w100">
             <view class="flex-d">
-                <image style="width: 80px;height: 100px;" :src="item.image" mode="aspectFill"></image>
-                <view class="quantity mt-20">数量: {{ item.quantity }}</view>
+                <image style="width: 80px;height: 100px;" :src="item.cover" mode="aspectFill"></image>
+                <view class="quantity mt-20">数量: {{ item.num }}</view>
             </view>
             <view class="book-info ml-20 flex-1">
                 <view class="common-title mb-20">{{ item.title }}</view>
                 <view class="flex flex-j-b mb-10">
                     <view class="isbn">ISBN: {{ item.isbn }}</view>
-                    <view class="set">套装: {{ item.set }}</view>
+                    <view class="set">套装: {{ item.suit == 1 ? '是' : '否' }}</view>
 
                 </view>
                 <view class="flex flex-j-b mb-10">
-                    <view class="discount">回收折扣: {{ item.discount }}</view>
-                    <view class="review">审核金额: {{ item.review }}</view>
+                    <view class="discount">回收折扣: {{ item.recycleDiscount }}</view>
+                    <view class="review">审核金额: {{ item.finalMoney }}</view>
                 </view>
                 <view class="flex flex-j-b mb-10">
-                    <view class="price">定价: {{ item.price }}</view>
-                    <view class="estimate">预估单价: {{ item.estimate }}</view>
+                    <view class="price">定价: {{ item.bookPrice }}</view>
+                    <view class="estimate">预估单价: {{ item.expectMoney }}</view>
                 </view>
 
                 <view class="quality mb-10">
-                    品相: 良好({{ item.good }}) 、 一般({{ item.average }}) 、 极差({{ item.bad }})
+                    品相: 良好({{ item.goodNum }}) 、 一般({{ item.generalNum }}) 、 极差({{ item.badNum }})
                 </view>
-                <view class="reason color-red">原因: {{ item.reason }}</view>
+                <view class="reason color-red">原因: {{
+                    item.auditCommentList?.filter(item => item.sts == 3).map(item => item.com).join(';') }}</view>
             </view>
         </view>
     </view>
@@ -50,9 +51,11 @@ const props = defineProps({
         display: flex;
         width: 100%;
     }
-    .book-info{
+
+    .book-info {
         font-size: 26rpx;
     }
+
     .color-red {
         color: #bd3124;
     }

+ 5 - 1
pages/index/wms/components/LocationOrderItem.vue

@@ -30,7 +30,7 @@
                     :color="item.checked ? '#19be6b' : '#c8c9cc'" size="28" @click="toggleSelect"></u-icon>
             </view>
 
-            <view class="flex flex-d flex-a-c flex-j-c quick-jump" @click="handleQuickJump">
+            <view class="flex flex-d flex-a-c flex-j-c quick-jump" @click="handleQuickJump" v-if="isLink">
                 <image src="/static/img/share.png" mode="widthFix" style="width: 30px;"></image>
                 <text style="font-size: 28rpx;color: #19be6b;">快速跳转</text>
             </view>
@@ -49,6 +49,10 @@ const props = defineProps({
     isCheck: {
         type: Boolean,
         default: false
+    },
+    isLink: {
+        type: Boolean,
+        default: true
     }
 })
 

+ 61 - 34
pages/index/wms/speedy-check-add.vue

@@ -1,23 +1,26 @@
 <template>
-	<view class="container">
-		<u-navbar title="选择商品" :border="false" fixed safe-area-inset-top>
-			<template #left>
-				<u-icon name="arrow-left" color="#333333" size="20" @click="goBack"></u-icon>
-			</template>
-			<template #right>
-				<u-text type="primary" text="确定" @click="onSubmit"></u-text>
-			</template>
-		</u-navbar>
+	<view class="container speedy-add">
+        <u-navbar title="选择商品" :border="false" fixed safe-area-inset-top bgColor="#22ac38"
+        titleStyle="font-size:36rpx;color:#fff">
+            <template #left>
+                <u-icon name="arrow-left" color="#fff" size="20" @click="goBack"></u-icon>
+            </template>
+            <template #right>
+                <text style="color: #ffffff;" @click="onSubmit">确定</text>
+            </template>
+        </u-navbar>
 
 		<!-- 库位显示 -->
 		<view class="location-info">
-			<text>{{ location }}</text>
+			<text>库位: {{ location }}</text>
+			<text v-if="godownName">仓库: {{ godownName }}</text>
+			<text v-if="orderNum">订单号: {{ orderNum }}</text>
 		</view>
 
 		<!-- 订单列表 -->
 		<view class="product-details">
 			<LocationOrderItem isCheck v-for="(item, index) in products" :key="index" :item="item"
-				@select="toggleItemSelect" />
+				@select="toggleItemSelect" :isLink="false" />
 		</view>
 
 		<!-- 底部全选栏 -->
@@ -37,30 +40,39 @@
 		ref,
 		computed
 	} from 'vue'
+    import { onLoad,onUnload } from "@dcloudio/uni-app";
 	import LocationOrderItem from './components/LocationOrderItem.vue'
 
 	// 库位相关
-	const location = ref('k01-01-4A')
-
-	// 其他数据
-	const searchValue = ref('')
-	const products = ref([{
-			orderNo: '4846464',
-			logisticsNo: "DPK2023497491611",
-			inspectionDate: "2024-11-14",
-			badCount: 5,
-			operator: '李程雪',
-			checked: false
-		},
-		{
-			orderNo: '4846464',
-			logisticsNo: "DPK2023497491611",
-			inspectionDate: "2024-11-14",
-			badCount: 5,
-			operator: '李程雪',
-			checked: false
+	const location = ref('')
+	const products = ref([])
+	const orderNum = ref('')
+	const godownName = ref('')
+
+	// 获取库位订单
+	const getOrderByPositionCode = (positionCode) => {
+		uni.$u.http.get('/app/stock/getOrderByPositionCode?positionCode=' + positionCode).then(res => {
+			if (res.code === 200) {
+				const data = res.data
+				orderNum.value = data.orderNum
+				godownName.value = data.godownName
+				products.value = data.godownStockLogResults || []
+				// 初始化选中状态
+				products.value.forEach(item => {
+					item.checked = false
+				})
+			} else {
+				uni.$u.toast(res.msg)
+			}
+		})
+	}
+
+	onLoad((options) => {
+		if (options.location) {
+			location.value = options.location
+			getOrderByPositionCode(options.location)
 		}
-	])
+	})
 
 	// 计算是否全选
 	const isAllSelected = computed(() => {
@@ -85,22 +97,37 @@
 		const selectedItems = products.value.filter(item => item.checked)
 		// 这里可以通过 uni.$emit 传递选中的数据到上一页
 		uni.$emit('selectedProducts', selectedItems)
-		uni.navigateBack()
+		goBack()
 	}
 
 	// 返回上一页
 	const goBack = () => {
-		uni.navigateBack()
+		uni.navigateBack({
+			delta: 1
+		})
 	}
 </script>
 
 <style lang="scss" scoped>
+    .speedy-add{
+        padding-top: 44px;
+        padding-bottom: 70px;
+    }
 	.location-info {
 		background-color: #fff;
 		padding: 20rpx;
-		text-align: center;
+		text-align: left;
 		font-size: 32rpx;
 		margin-bottom: 16rpx;
+
+		text {
+			display: block;
+			margin-bottom: 10rpx;
+
+			&:last-child {
+				margin-bottom: 0;
+			}
+		}
 	}
 
 	.product-details {

+ 343 - 69
pages/index/wms/speedy-check.vue

@@ -1,102 +1,321 @@
 <template>
     <view class="container">
-		<u-navbar title="快速盘点" :border="false" fixed safe-area-inset-top>
-		    <template #left>
-		        <u-icon name="arrow-left" color="#333333" size="20" @click="goBack"></u-icon>
-		    </template>
-		    <template #right>
-		        <u-text type="primary" text="提交" @click="onSubmit"></u-text>
-		    </template>
-		</u-navbar>
+        <u-navbar title="快速盘点" :border="false" fixed safe-area-inset-top bgColor="#22ac38"
+        titleStyle="font-size:36rpx;color:#fff">
+            <template #left>
+                <u-icon name="arrow-left" color="#fff" size="20" @click="goBack"></u-icon>
+            </template>
+            <template #right>
+                <text style="color: #ffffff;" @click="onSubmit">提交</text>
+            </template>
+        </u-navbar>
         <!-- 盘点信息选择区域 -->
-        <view class="select-area" style="margin-top: 44px;">
-            <u-cell-group>
-                <u-cell title="盘点方式" :value="checkMethod" @click="showCheckMethodPicker = true" isLink />
-                <u-cell title="目标库位" :value="location" @click="handleLocationSelect" isLink />
+        <view class="select-area" style="margin-top: 44px">
+            <u-cell-group :border="true">
+                <u-cell
+                    title="盘点方式"
+                    :value="checkMethod"
+                    @click="showCheckMethodPicker = true"
+                    :isLink="true"
+                    :border="true"
+                />
+                <u-cell
+                    title="目标库位"
+                    :value="location"
+                    @click="handleLocationSelect"
+                    :isLink="true"
+                    :border="true"
+                />
             </u-cell-group>
         </view>
 
         <!-- 盘点方式选择器 -->
-        <u-picker :show="showCheckMethodPicker" :columns="[checkMethodOptions]" @confirm="onCheckMethodConfirm"
-            @cancel="showCheckMethodPicker = false" />
+        <u-picker
+            :show="showCheckMethodPicker"
+            :columns="[checkMethodOptions]"
+            @confirm="onCheckMethodConfirm"
+            @cancel="showCheckMethodPicker = false"
+            :showToolbar="true"
+            title="选择盘点方式"
+            :closeOnClickOverlay="true"
+            cancelText="取消"
+            confirmText="确定"
+            :itemHeight="44"
+            :visibleItemCount="5"
+        />
+
+        <!-- 库位选择弹出层 -->
+        <u-popup
+            :show="showLocationPopup"
+            mode="bottom"
+            @close="close"
+            @open="open"
+            :closeOnClickOverlay="true"
+            :round="10"
+            :safeAreaInsetBottom="true"
+        >
+            <view class="location-popup">
+                <view class="location-popup-header">
+                    <text style="flex: 1">选择库位</text>
+                    <u-text
+                        style="width: 40px; flex: none"
+                        type="primary"
+                        text="确定"
+                        @click="onLocationConfirm"
+                    ></u-text>
+                </view>
+                <view class="location-popup-content">
+                    <u-input
+                        v-model="selectedLocation"
+                        placeholder="请输入库位"
+                        customStyle="background-color: #f6f6f6; border-radius: 4px;"
+                    ></u-input>
+                    <view class="location-list">
+                        <view
+                            class="location-item"
+                            v-for="(item, index) in locationList"
+                            :key="index"
+                            @click="selectLocation(item)"
+                            :class="{ 'location-item--selected': selectedLocation === item }"
+                        >
+                            <text>{{ item }}</text>
+                            <u-icon
+                                v-if="selectedLocation === item"
+                                name="checkmark"
+                                color="#19be6b"
+                                size="16"
+                            ></u-icon>
+                        </view>
+                    </view>
+                </view>
+            </view>
+        </u-popup>
 
         <!-- 订单列表 -->
         <view class="product-details">
-            <LocationOrderItem v-for="(item, index) in products" :key="index" :item="item" />
+            <LocationOrderItem v-for="(item, index) in products" :isLink :key="index" :item="item" />
+        </view>
+
+        <view class="add-btn" @click="handleAdd">
+            <u-icon name="plus-circle" size="40" color="#19be6b" @click="openScan"></u-icon>
         </view>
-		
-		<view class="add-btn" @click="handleAdd">
-			<u-icon name="plus-circle" size="40" color="#19be6b" @click="openScan"></u-icon>
-		</view>
 
         <!-- 底部扫码输入框 -->
-        <view class="fixed-bottom pad-20" style="background: #ffffff;">
-            <u-search placeholder="请输入快递单号/订单编号" v-model="searchValue" @confirm="onSearch" :show-action="false"
-                custom-style="margin-right:10px"></u-search>
+        <view class="fixed-bottom pad-20" style="background: #ffffff">
+            <u-search
+                placeholder="请输入快递单号/订单编号"
+                v-model="searchValue"
+                @search="onSearch"
+                :show-action="false"
+                custom-style="margin-right:10px"
+            ></u-search>
             <u-icon name="scan" size="28" color="#19be6b" @click="openScan"></u-icon>
         </view>
     </view>
 </template>
 
 <script setup>
-import {
-    reactive,
-    ref
-} from 'vue'
-import LocationOrderItem from './components/LocationOrderItem.vue'
+import { reactive, ref } from "vue";
+import { onLoad,onUnload } from "@dcloudio/uni-app";
+import LocationOrderItem from "./components/LocationOrderItem.vue";
+
+const goBack = () => {
+    uni.navigateBack();
+};
 
 // 盘点方式相关
-const showCheckMethodPicker = ref(false)
-const checkMethod = ref('实际数量')
-const checkMethodOptions = ['实际数量', '增加数量', '减少数量']
+const showCheckMethodPicker = ref(false);
+const checkMethod = ref("实际数量");
+const resetType = ref(1);
+const checkMethodOptions = ["实际数量", "增加数量", "减少数量"];
+
+//获取用户的默认仓库
+const getUserDefaultWarehouse = () => {
+    uni.$u.http.get("/app/appUser/getUserBindGodown").then((res) => {
+        if (res.code == 200) {
+            getWarehouseLocationList(res.data.id);
+        }
+    });
+};
 
 // 库位相关
-const location = ref('k01-01-4A')
+const location = ref("");
+const showLocationPopup = ref(false);
+const locationList = ref([]);
+const selectedLocation = ref("");
+
+//根据仓库获取库位列表
+const godownId = ref()
+const getWarehouseLocationList = (id) => {
+    godownId.value = id
+    uni.$u.http.get("/app/stock/getGodownPosition?godownId=" + id).then((res) => {
+        if (res.code == 200) {
+            locationList.value = res.data;
+        }
+    });
+};
 
 // 其他数据
-const searchValue = ref('')
-const products = ref([{
-    orderNo: '4846464',
-    logisticsNo: "DPK2023497491611",
-    inspectionDate: "2024-11-14",
-    badCount: 5,
-    operator: '李程雪',
-},
-{
-    orderNo: '4846464',
-    logisticsNo: "DPK2023497491611",
-    inspectionDate: "2024-11-14",
-    badCount: 5,
-    operator: '李程雪',
-}
-])
+const searchValue = ref("");
+const products = ref([]);
 
 // 方法
 const onCheckMethodConfirm = (e) => {
-    checkMethod.value = e.value[0]
-    showCheckMethodPicker.value = false
-}
+    checkMethod.value = e.value[0];
+    showCheckMethodPicker.value = false;
+    resetType.value = e.indexs[0] + 1;
+};
 
 const handleLocationSelect = () => {
-    // 跳转到库位选择页面
-    uni.navigateTo({
-        url: '/pages/location-select/index'
-    })
+    showLocationPopup.value = true;
+    selectedLocation.value = location.value;
+};
+
+const onLocationConfirm = () => {
+    if (selectedLocation.value) {
+        location.value = selectedLocation.value;
+        showLocationPopup.value = false;
+        selectedLocation.value = "";
+    } else {
+        uni.$u.toast("请选择库位");
+    }
+};
+
+const selectLocation = (item) => {
+    selectedLocation.value = item;
+};
+
+//盘点提交
+const onSubmit = () => {
+    if (products.value.length === 0) {
+        uni.$u.toast('请添加盘点订单');
+        return;
+    }
+
+    // 构建请求参数
+    const params = {
+        godownId: godownId.value, 
+        positionCode: location.value,
+        orderInfo: products.value.map(item => ({
+            orderId: item.orderId,
+            waybillCode: item.waybillCode,
+            bookNum: item.badNum,
+            remark: item.remark || ''
+        })),
+        resetType: resetType.value
+    };
+
+    // 调用重置库存API
+    uni.$u.http.post('/app/stock/resetStock', params).then(res => {
+        if (res.code === 200) {
+            uni.$u.toast('盘点成功');
+            location.value = ""
+            products.value = []
+            searchValue.value = ""
+        } else {
+            uni.$u.toast(res.msg || '提交失败');
+        }
+    }).catch(err => {
+        uni.$u.toast('提交失败');
+        console.error(err);
+    });
 }
 
 const onSearch = () => {
-    // 实现搜索逻辑
-}
+    if (!searchValue.value) {
+        uni.$u.toast('请输入快递单号或订单编号');
+        return;
+    }
+
+    // 判断搜索类型:纯数字为订单号(searchType=1),字母+数字组合为物流单号(searchType=2)
+    const searchType = /^[0-9]+$/.test(searchValue.value) ? 1 : 2;
+
+    // 调用接口获取订单数据
+    uni.$u.http.get('/app/stock/searchBadOrderForReset', {
+        params: {
+            searchType,
+            search: searchValue.value
+        }
+    }).then(res => {
+        if (res.code === 200) {
+            // 检查是否已存在相同订单
+            const exists = products.value.some(item => 
+                item.orderId === res.data.orderId || 
+                item.waybillCode === res.data.waybillCode
+            );
+
+            if (exists) {
+                uni.$u.toast('该订单已添加');
+                return;
+            }
+
+            // 添加新订单到列表
+            products.value.push(res.data);
+            searchValue.value = ''; // 清空搜索框
+        } else {
+            uni.$u.toast(res.msg || '查询失败');
+        }
+    }).catch(err => {
+        uni.$u.toast('查询失败');
+        console.error(err);
+    });
+};
 
 const openScan = () => {
-    // 实现扫描逻辑
-}
+    // #ifdef APP-PLUS || MP-WEIXIN
+    uni.scanCode({
+        success: (res) => {
+            searchValue.value = res.result;
+            onSearch();
+        },
+        fail: (err) => {
+            uni.showToast({
+                title: '扫码失败',
+                icon: 'error'
+            });
+        }
+    });
+    // #endif
+};
 
-function handleAdd(){
-	uni.navigateTo({
-		url:"/pages/index/wms/speedy-check-add"
-	})
+function handleAdd() {
+    if (!location.value) {
+        uni.$u.toast("请选择库位");
+        return;
+    }
+    uni.navigateTo({
+        url: "/pages/index/wms/speedy-check-add?location=" + location.value,
+    });
 }
+
+const close = () => {
+    showLocationPopup.value = false;
+};
+
+const open = () => {
+    showLocationPopup.value = true;
+};
+
+onLoad(() => {
+    getUserDefaultWarehouse();
+
+    uni.$on('selectedProducts', (list) => {
+        products.value = list;
+    });
+
+    // #ifdef APP-PLUS
+    uni.$u.useGlobalEvent((e) => {
+        if (e.barcode) {
+            searchValue.value = e.barcode;
+            onSearch();
+        }
+    });
+    // #endif
+});
+
+onUnload(() => {
+    uni.$off('selectedProducts');
+});
 </script>
 
 <style lang="scss" scoped>
@@ -120,11 +339,66 @@ function handleAdd(){
     box-shadow: 0 -2rpx 6rpx rgba(0, 0, 0, 0.1);
 }
 
-.add-btn{
-	position: absolute;
-	right: 0;
-	bottom: 30%;
-	z-index: 99;
-	cursor: pointer;
+.add-btn {
+    position: absolute;
+    right: 0;
+    bottom: 30%;
+    z-index: 99;
+    cursor: pointer;
+}
+
+.location-input-wrapper {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+}
+
+.location-popup {
+    background-color: #fff;
+    padding: 20rpx;
+
+    &-header {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        padding-bottom: 24rpx;
+        border-bottom: 1px solid #eee;
+        position: relative;
+
+        text {
+            font-size: 32rpx;
+            font-weight: 500;
+            flex: 1;
+        }
+
+        .u-button {
+            position: absolute;
+            right: 20rpx;
+        }
+    }
+
+    &-content {
+        padding: 20rpx 0;
+        max-height: 600rpx;
+        overflow-y: auto;
+    }
+}
+
+.location-list {
+    margin-top: 20rpx;
+    max-height: 400rpx;
+    overflow-y: auto;
+}
+
+.location-item {
+    padding: 20rpx;
+    border-bottom: 1px solid #eee;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+
+    &--selected {
+        color: #19be6b;
+    }
 }
-</style>
+</style>

+ 231 - 89
pages/index/wms/task-detail.vue

@@ -13,37 +13,50 @@
         <!-- 任务进度 -->
         <view class="progress-section">
             <u-alert title="当前任务" type="info" center></u-alert>
-            <view class="flex flex-j-b pad-10" style="padding-right:40rpx">
-                <view class="next-task" @click="handleNextTask">
+            <view class="flex flex-j-c pad-10" style="padding-right: 40rpx">
+                <!-- <view class="next-task" @click="handleNextTask">
                     <text>上一个</text>
-                </view>
+                </view> -->
                 <view class="flex-c">
-                    <text>{{ currentTask }}<text class="progress-text font-18 color-green">/{{ totalTasks
-                            }}</text></text>
+                    <text
+                        >{{ currentTask }}<text class="progress-text font-20 color-green">/{{ totalTasks }}</text></text
+                    >
                 </view>
-                <view class="color-green" @click="handleNextTask">
+                <!-- <view class="color-green" @click="handleNextTask">
                     <text>下一个</text>
-                </view>
+                </view> -->
             </view>
         </view>
         <!-- 库位信息 -->
-        <view class="flex flex-j-b pad-10 next-location" style="padding-right:40rpx;align-items: center;">
-            <view class="font-14 mb-20">{{ currentIndex }}/{{ totalTasks }}</view>
+        <view class="flex flex-j-b pad-10 next-location" style="padding-right: 40rpx; align-items: center">
+            <view class="font-14 mb-20">{{ currentTask + 1 }}/{{ totalTasks }}</view>
             <view class="flex-d">
                 <view class="font-20 text-center">
-                    {{ nextLocation }}
+                    {{ curTaskInfo.positionCode }}
                 </view>
-                <view class="location-detail font-13 mt-10">下一库位 {{ nextLocation }}</view>
+                <view class="location-detail font-13 mt-10" v-if="nextLocation"
+                    >下一库位 {{ nextLocation || "无" }}</view
+                >
             </view>
-            <u-icon name="attach" size="28"></u-icon>
+            <image
+                v-if="!curTaskInfo.isValid"
+                src="/static/img/location.png"
+                mode="widthFix"
+                style="width: 70rpx; height: 70rpx"
+            ></image>
+            <image
+                v-else
+                src="/static/img/location-active.png"
+                mode="widthFix"
+                style="width: 70rpx; height: 70rpx"
+            ></image>
         </view>
 
-
         <!-- 订单信息 -->
         <view class="order-info">
-            <view class="info-item">订单编号:{{ orderInfo.orderNo }}</view>
-            <view class="info-item">物流单号:{{ orderInfo.logisticsNo }}</view>
-            <view class="info-item">不良数量:{{ orderInfo.badCount }}</view>
+            <view class="info-item">订单编号:{{ curTaskInfo.orderId }}</view>
+            <view class="info-item">物流单号:{{ curTaskInfo.waybillCode || "-" }}</view>
+            <view class="info-item">不良数量:{{ curTaskInfo.badNum }}</view>
         </view>
 
         <!-- 极差商品列表 -->
@@ -55,9 +68,15 @@
         </view>
 
         <!-- 底部搜索框 -->
-        <view class="fixed-bottom pad-20" style="background: #ffffff;">
-            <u-search v-model="searchText" placeholder="请输入订单编号" :show-action="false" :clearabled="true"
-                @change="onSearch" height="40">
+        <view class="fixed-bottom pad-20" style="background: #ffffff">
+            <u-search
+                v-model="searchText"
+                placeholder="请输入订单编号/物流单号/库位号"
+                :show-action="false"
+                :clearabled="true"
+                @change="checkScanText(searchText)"
+                height="40"
+            >
             </u-search>
             <u-icon name="scan" size="28" color="#19be6b" @click="openScan"></u-icon>
         </view>
@@ -65,115 +84,232 @@
 </template>
 
 <script setup>
-import {
-    ref,onMounted
-} from 'vue'
-import BadOutCard from '@/pages/index/wms/components/BadOutCard.vue'
-import VolumeTTS from '@/utils/VolumeTTS.js'
+import { ref, onMounted } from "vue";
+import BadOutCard from "@/pages/index/wms/components/BadOutCard.vue";
+import VolumeTTS from "@/utils/VolumeTTS.js";
+import { onLoad, onUnload } from "@dcloudio/uni-app";
 
 // 任务进度
-const currentTask = ref(0)
-const totalTasks = ref(77)
-const currentIndex = ref(1)
-const nextLocation = ref('K01-02-4A')
+const currentTask = ref(0);
+const totalTasks = ref(0);
+const curTaskInfo = ref({});
+const nextLocation = ref("");
 
 // 订单信息
-const orderInfo = ref({
-    orderNo: '4571211',
-    logisticsNo: 'DPK203156442584',
-    badCount: 10
-})
-const ttsModule = ref(null)
-onMounted(() => {
-    ttsModule.value = new VolumeTTS()
-})
+const orderList = ref([]);
+const ttsModule = ref(null);
+const taskCode = ref("");
+
+onUnload(() => {
+    ttsModule.value.stop();
+});
 
 // 搜索文本
-const searchText = ref('')
-
-// 极差商品列表
-const badList = ref([{
-    image: 'https://img20.360buyimg.com/da/jfs/t1/141592/25/8861/261559/5f68d8c1E33ed78ab/698ad655bfcfbaed.png',
-    title: '公文写作教程',
-    isbn: '978704051555',
-    price: 49.5,
-    discount: 0.85,
-    quantity: 5,
-    set: '不是',
-    good: 0,
-    average: 0,
-    bad: 1,
-    reason: '明显泛黄水印/发霉/明显异味'
-}])
+const searchText = ref("");
+
+// 极差商品列表 - 使用detailVoList中的数据
+const badList = ref([]);
 
 // 处理下一个任务
 const handleNextTask = () => {
     if (currentTask.value < totalTasks.value) {
-        currentTask.value++
-        VolumeTTS.speak(nextLocation.value)
+        currentTask.value++;
+
+        if (currentTask.value == totalTasks.value) {
+            ttsModule.value.speak("任务完成");
+        } else {
+            curTaskInfo.value = orderList.value[currentTask.value];
+            badList.value = curTaskInfo.value.detailVoList || [];
+
+            let nextInfo = orderList.value[currentTask.value + 1];
+            nextLocation.value = nextInfo.positionCode;
+        }
     }
-}
+};
 
 // 搜索处理
 const onSearch = () => {
-    // 实现搜索逻辑
-}
+    // TODO: 调用API获取订单详情
+    uni.$u.http.get(`/app/appstock/getStockTaskDetail?taskCode=${taskCode.value}`).then((res) => {
+        if (res.code == 200) {
+            orderList.value = res.data;
+            totalTasks.value = res.data.length;
+
+            //默认选中第一个任务
+            curTaskInfo.value = res.data[currentTask.value];
+            badList.value = curTaskInfo.value.detailVoList || [];
+        }
+    });
+};
+
+// 确认下架任务
+const confirmStockTask = () => {
+    const params = {
+        positionCode: curTaskInfo.value.positionCode,
+        orderId: curTaskInfo.value.orderId,
+    };
+
+    uni.$u.http.post("/app/appstock/setStockTask", params).then((res) => {
+        if (res.code === 200) {
+            curTaskInfo.value.isCompleted = true;
+            orderList.value[currentTask.value] = curTaskInfo.value;
+
+            handleNextTask();
+            ttsModule.value.speak("下架成功");
+        } else {
+            uni.showToast({
+                title: res.msg,
+                icon: "error",
+            });
+        }
+    });
+};
+
+//解锁任务
+const unlockTask = () => {
+    uni.$u.http.post("/app/appstock/unlockStockTask?taskCode=" + taskCode.value).then((res) => {
+        if (res.code == 200) {
+            uni.showToast({
+                title: "解锁成功",
+                icon: "success",
+            });
+        } else {
+            uni.showToast({
+                title: res.msg || "解锁失败",
+                icon: "error",
+            });
+        }
+    });
+};
 
 // 提交处理
 const onSubmit = () => {
     uni.showModal({
-        title: '确认提示',
-        content: '是否确认提交本次下架?',
+        title: "确认提示",
+        content: "是否确认提交本次下架?",
         success: (res) => {
             if (res.confirm) {
-                // 处理提交逻辑
-                uni.showToast({
-                    title: '提交成功',
-                    icon: 'success'
-                })
-                ttsModule.value.speak('任务已提交')
+                uni.navigateBack();
+                ttsModule.value.speak("任务已提交");
+                unlockTask();
             }
-        }
-    })
-}
+        },
+    });
+};
 
 function goBack() {
     uni.showModal({
-        title: '确认提示',
-        content: '是否确认放弃本次下架?',
+        title: "确认提示",
+        content: "是否确认放弃本次下架?",
         success: (res) => {
             if (res.confirm) {
-                uni.navigateBack()
-                ttsModule.value.speak('任务已放弃')
+                uni.navigateBack();
+                ttsModule.value.speak("任务已放弃");
+                unlockTask();
             }
-        }
-    })
+        },
+    });
 }
+let isFirstScan = ref(false); //是否验证了库位号
+//扫码首先校验库位号,如果库位号不正确,则提示库位号不正确 如果正确,curTaskInfo.isValid = true
+//正确后继续校验物流号或者订单号,如果正确,则调用
+//库位号格式 字母+数字+横杠-  物流号格式 必须有字母+数字组合  订单号 数字
+const checkScanText = (scanText) => {
+    console.log(scanText, "scanText");
+    //先判断扫描到的scanText是库位号还是物流号或者订单号
+    let isPositionCode = scanText.indexOf("-") > -1;
+    let isWaybillCode = /^(?=.*[A-Z])(?=.*\d)[A-Z0-9]+$/.test(scanText);
+    let isOrderId = /^\d+$/.test(scanText);
+
+    console.log(
+        isPositionCode,
+        isWaybillCode,
+        isOrderId,
+        isFirstScan.value,
+        "isPositionCode, isWaybillCode, isOrderId"
+    );
+
+    //库位号校验
+    if (isPositionCode) {
+        let positionCode = curTaskInfo.value.positionCode;
+        if (positionCode != scanText) {
+            uni.showToast({
+                title: "库位号不正确",
+                icon: "error",
+            });
+        } else {
+            isFirstScan.value = true;
+            curTaskInfo.value.isValid = true;
+        }
+    }
+    if (!isFirstScan.value) {
+        ttsModule.value.speak("请先校验库位号");
+        return;
+    }
+
+    //物流号校验
+    if (isWaybillCode && !isOrderId) {
+        let waybillCode = curTaskInfo.value.waybillCode;
+        if (waybillCode == scanText) {
+            confirmStockTask();
+        } else {
+            uni.showToast({
+                title: "物流号不正确",
+                icon: "error",
+            });
+        }
+    }
+
+    //订单号校验
+    if (isOrderId && !isWaybillCode) {
+        let orderId = curTaskInfo.value.orderId;
+        if (orderId == scanText) {
+            confirmStockTask();
+        } else {
+            curTaskInfo.value.isValid = true;
+        }
+    }
+};
 
 // 打开扫码
 const openScan = () => {
     // #ifdef APP-PLUS || MP-WEIXIN
     uni.scanCode({
         success: (res) => {
-            searchText.value = res.result
-            onSearch()
+            searchText.value = res.result;
+            checkScanText(res.result);
         },
         fail: (err) => {
             uni.showToast({
-                title: '扫码失败',
-                icon: 'error'
-            })
-        }
-    })
+                title: "扫码失败",
+                icon: "error",
+            });
+        },
+    });
     // #endif
 
     // #ifdef H5
     uni.showToast({
-        title: 'H5环境不支持扫码',
-        icon: 'none'
-    })
+        title: "H5环境不支持扫码",
+        icon: "none",
+    });
     // #endif
-}
+};
+
+onLoad((opts) => {
+    taskCode.value = opts.taskCode;
+    onSearch();
+    // #ifdef APP-PLUS
+    ttsModule.value = new VolumeTTS();
+
+    uni.$u.useGlobalEvent((e) => {
+        if (e.barcode) {
+            searchText.value = e.barcode;
+            checkScanText(e.barcode);
+        }
+    });
+    // #endif
+});
 </script>
 
 <style scoped>
@@ -185,7 +321,8 @@ const openScan = () => {
     padding: 10rpx;
     padding-top: 56px;
 }
-.next-location{
+
+.next-location {
     background-color: #fff;
     border-bottom: 1rpx solid #f0f0f0;
     border-top: 1rpx solid #f0f0f0;
@@ -193,7 +330,7 @@ const openScan = () => {
 }
 
 .color-green {
-    color: #4CAF50;
+    color: #4caf50;
 }
 
 .location-info {
@@ -222,4 +359,9 @@ const openScan = () => {
     padding: 10rpx 0;
     padding-left: 30rpx;
 }
-</style>
+.container {
+    /* #ifdef H5 */
+    padding-bottom: 70px;
+    /* #endif */
+}
+</style>

+ 3 - 3
pages/my/components/orderItem.vue

@@ -22,7 +22,7 @@
                     <text>订单ID:</text>
                     <text class="link" @click="copyToClipboard(item.orderId)">{{ item.orderId }}</text>
                 </view>
-                <view class="flex-1">
+                <view class="flex-1" style="flex: 1.5;">
                     <text>运单号:</text>
                     <text class="link" @click="copyToClipboard(item.waybillCode)">{{ item.waybillCode }}</text>
                 </view>
@@ -74,8 +74,8 @@ const statusEnum = {
 
 // 处理昵称显示
 const maskedNickName = computed(() => {
-    if (!props.item.nickName) return '';
-    return props.item.nickName.charAt(0) + '*'.repeat(props.item.nickName.length - 1);
+    if (!props.item.userNick) return '';
+    return props.item.userNick.charAt(0) + '*'.repeat(props.item.userNick.length - 1);
 });
 
 let statusText = computed(() => {

+ 19 - 11
pages/my/page/audit-unfinished.vue

@@ -1,18 +1,26 @@
 <template>
-	<view class="audit-list">
-		<order-item></order-item>
-		<order-item></order-item>
-		<order-item></order-item>
-	</view>
+    <view class="audit-list">
+        <page-scroll requestStr="/app/orderinfo/myNeedCheckOrder" @updateList="updateList">
+            <order-item v-for="(item, index) in list" :key="index" :item="item"></order-item>
+        </page-scroll>
+    </view>
 </template>
 
 <script setup>
-	import orderItem from '../components/orderItem.vue';
+import orderItem from "../components/orderItem.vue";
+import pageScroll from "@/components/pageScroll/index.vue";
+import { ref } from "vue";
+
+const list = ref([]);
+
+const updateList = (newList) => {
+    list.value = newList;
+};
 </script>
 
 <style lang="scss">
-	.audit-list{
-		padding: 20rpx;
-		box-sizing: border-box;
-	}
-</style>
+.audit-list {
+    padding: 20rpx;
+    box-sizing: border-box;
+}
+</style>

二进制
static/img/location-active.png


二进制
static/img/location.png


二进制
static/img/share.png


文件差异内容过多而无法显示
+ 0 - 0
unpackage/dist/build/app-plus/app-config-service.js


文件差异内容过多而无法显示
+ 0 - 0
unpackage/dist/build/app-plus/app-service.js


文件差异内容过多而无法显示
+ 0 - 0
unpackage/dist/build/app-plus/pages/index/audit/express-order.css


文件差异内容过多而无法显示
+ 0 - 0
unpackage/dist/build/app-plus/pages/index/detail/batch-audit.css


文件差异内容过多而无法显示
+ 0 - 0
unpackage/dist/build/app-plus/pages/index/detail/book-audit.css


文件差异内容过多而无法显示
+ 0 - 0
unpackage/dist/build/app-plus/pages/index/detail/index.css


文件差异内容过多而无法显示
+ 0 - 0
unpackage/dist/build/app-plus/pages/index/express/quick-unpack.css


+ 1 - 1
unpackage/dist/build/app-plus/pages/index/index.css

@@ -1 +1 @@
-.operation-container[data-v-238d40be]{padding:.625rem;box-sizing:border-box}.section[data-v-238d40be]{margin-bottom:.9375rem;background:#fff;border-radius:.5rem;padding:.625rem;box-shadow:0 .0625rem .375rem rgba(0,0,0,.05)}.section .section-title[data-v-238d40be]{font-size:1.5625rem;font-weight:600;color:#333;padding:.625rem;padding-top:0;border-bottom:.0625rem solid #f0f0f0;margin-bottom:.625rem}.section .grid-container[data-v-238d40be]{display:grid;grid-template-columns:repeat(2,1fr);gap:.625rem;padding:.3125rem}.section .grid-container .grid-item[data-v-238d40be]{min-height:4.625rem;display:flex;align-items:center;justify-content:center;text-align:center;padding:.625rem .9375rem;line-height:1.875rem;font-size:1.5625rem;border-radius:.375rem;color:#fff;transition:all .3s;white-space:pre-wrap}.section .grid-container .grid-item.primary[data-v-238d40be]{background:linear-gradient(135deg,#4cd964,#3ac555)}.section .grid-container .grid-item.primary[data-v-238d40be]:active{background:linear-gradient(135deg,#3ac555,#2fb548)}.section .grid-container .grid-item.warning[data-v-238d40be]{background:linear-gradient(135deg,#ff9500,#ff8000)}.section .grid-container .grid-item.warning[data-v-238d40be]:active{background:linear-gradient(135deg,#ff8000,#e67300)}.section .grid-container .grid-item[data-v-238d40be]:active{transform:scale(.98)}
+.operation-container[data-v-3becea2b]{padding:.625rem;box-sizing:border-box}.section[data-v-3becea2b]{margin-bottom:.9375rem;background:#fff;border-radius:.5rem;padding:.625rem;box-shadow:0 .0625rem .375rem rgba(0,0,0,.05)}.section .section-title[data-v-3becea2b]{font-size:1.5625rem;font-weight:600;color:#333;padding:.625rem;padding-top:0;border-bottom:.0625rem solid #f0f0f0;margin-bottom:.625rem}.section .grid-container[data-v-3becea2b]{display:flex;flex-wrap:wrap;gap:.625rem;padding:.3125rem}.section .grid-container .grid-item[data-v-3becea2b]{flex:0 0 calc(50% - .3125rem);min-height:4.625rem;display:flex;align-items:center;justify-content:center;text-align:center;padding:.625rem .9375rem;line-height:1.875rem;font-size:1.5625rem;border-radius:.375rem;color:#fff;transition:all .3s;white-space:pre-wrap;box-sizing:border-box}.section .grid-container .grid-item[style*="grid-column: span 2"][data-v-3becea2b]{flex:0 0 100%}.section .grid-container .grid-item.primary[data-v-3becea2b]{background:linear-gradient(135deg,#4cd964,#3ac555)}.section .grid-container .grid-item.primary[data-v-3becea2b]:active{background:linear-gradient(135deg,#3ac555,#2fb548)}.section .grid-container .grid-item.warning[data-v-3becea2b]{background:linear-gradient(135deg,#ff9500,#ff8000)}.section .grid-container .grid-item.warning[data-v-3becea2b]:active{background:linear-gradient(135deg,#ff8000,#e67300)}.section .grid-container .grid-item[data-v-3becea2b]:active{transform:scale(.98)}

文件差异内容过多而无法显示
+ 0 - 0
unpackage/dist/build/app-plus/pages/index/wms/bad-in.css


文件差异内容过多而无法显示
+ 0 - 0
unpackage/dist/build/app-plus/pages/index/wms/bad-out-order.css


文件差异内容过多而无法显示
+ 0 - 0
unpackage/dist/build/app-plus/pages/index/wms/order-query-list.css


文件差异内容过多而无法显示
+ 909 - 738
unpackage/dist/dev/app-plus/app-service.js


+ 209 - 173
unpackage/dist/dev/app-plus/pages/book/index.css

@@ -636,179 +636,6 @@ to {
 /* 垂直间距 */
 /* 透明度 */
 /* 文章场景相关 */
-uni-view[data-v-c8491d64], uni-scroll-view[data-v-c8491d64], uni-swiper-item[data-v-c8491d64] {
-  display: flex;
-  flex-direction: column;
-  flex-shrink: 0;
-  flex-grow: 0;
-  flex-basis: auto;
-  align-items: stretch;
-  align-content: flex-start;
-}
-.u-upload[data-v-c8491d64] {
-
-  display: flex;
-
-  flex-direction: column;
-  flex: 1;
-}
-.u-upload__wrap[data-v-c8491d64] {
-
-  display: flex;
-
-  flex-direction: row;
-  flex-wrap: wrap;
-  flex: 1;
-}
-.u-upload__wrap__preview[data-v-c8491d64] {
-  border-radius: 2px;
-  margin: 0 8px 8px 0;
-  position: relative;
-  overflow: hidden;
-
-  display: flex;
-
-  flex-direction: row;
-}
-.u-upload__wrap__preview__image[data-v-c8491d64] {
-  width: 80px;
-  height: 80px;
-}
-.u-upload__wrap__preview__other[data-v-c8491d64] {
-  width: 80px;
-  height: 80px;
-  background-color: #f2f2f2;
-  flex: 1;
-
-  display: flex;
-
-  flex-direction: column;
-  justify-content: center;
-  align-items: center;
-}
-.u-upload__wrap__preview__other__text[data-v-c8491d64] {
-  font-size: 11px;
-  color: #909193;
-  margin-top: 2px;
-}
-.u-upload__deletable[data-v-c8491d64] {
-  position: absolute;
-  top: 0;
-  right: 0;
-  background-color: #373737;
-  height: 14px;
-  width: 14px;
-
-  display: flex;
-
-  flex-direction: row;
-  border-bottom-left-radius: 100px;
-  align-items: center;
-  justify-content: center;
-  z-index: 3;
-}
-.u-upload__deletable__icon[data-v-c8491d64] {
-  position: absolute;
-  transform: scale(0.7);
-  top: 0px;
-  right: 0px;
-}
-.u-upload__success[data-v-c8491d64] {
-  position: absolute;
-  bottom: 0;
-  right: 0;
-
-  display: flex;
-
-  flex-direction: row;
-  border-style: solid;
-  border-top-color: transparent;
-  border-left-color: transparent;
-  border-bottom-color: #22ac38;
-  border-right-color: #22ac38;
-  border-width: 9px;
-  align-items: center;
-  justify-content: center;
-}
-.u-upload__success__icon[data-v-c8491d64] {
-  position: absolute;
-  transform: scale(0.7);
-  bottom: -10px;
-  right: -10px;
-}
-.u-upload__status[data-v-c8491d64] {
-  position: absolute;
-  top: 0;
-  bottom: 0;
-  left: 0;
-  right: 0;
-  background-color: rgba(0, 0, 0, 0.5);
-
-  display: flex;
-
-  flex-direction: column;
-  align-items: center;
-  justify-content: center;
-}
-.u-upload__status__icon[data-v-c8491d64] {
-  position: relative;
-  z-index: 1;
-}
-.u-upload__status__message[data-v-c8491d64] {
-  font-size: 12px;
-  color: #FFFFFF;
-  margin-top: 5px;
-}
-.u-upload__button[data-v-c8491d64] {
-
-  display: flex;
-
-  flex-direction: column;
-  align-items: center;
-  justify-content: center;
-  width: 80px;
-  height: 80px;
-  background-color: #f4f5f7;
-  border-radius: 2px;
-  margin: 0 8px 8px 0;
-  box-sizing: border-box;
-}
-.u-upload__button__text[data-v-c8491d64] {
-  font-size: 11px;
-  color: #909193;
-  margin-top: 2px;
-}
-.u-upload__button--hover[data-v-c8491d64] {
-  background-color: #e6e7e9;
-}
-.u-upload__button--disabled[data-v-c8491d64] {
-  opacity: 0.5;
-}
-/**
- * 这里是uni-app内置的常用样式变量
- *
- * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
- * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
- *
- */
-/**
- * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
- *
- * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
- */
-/* 颜色变量 */
-/* 行为相关颜色 */
-/* 文字基本颜色 */
-/* 背景颜色 */
-/* 边框颜色 */
-/* 尺寸变量 */
-/* 文字尺寸 */
-/* 图片尺寸 */
-/* Border Radius */
-/* 水平间距 */
-/* 垂直间距 */
-/* 透明度 */
-/* 文章场景相关 */
 uni-view[data-v-5ce41ee6], uni-scroll-view[data-v-5ce41ee6], uni-swiper-item[data-v-5ce41ee6] {
   display: flex;
   flex-direction: column;
@@ -1315,6 +1142,215 @@ uni-view[data-v-05c24e9b], uni-scroll-view[data-v-05c24e9b], uni-swiper-item[dat
 /* 垂直间距 */
 /* 透明度 */
 /* 文章场景相关 */
+uni-view[data-v-c8491d64], uni-scroll-view[data-v-c8491d64], uni-swiper-item[data-v-c8491d64] {
+  display: flex;
+  flex-direction: column;
+  flex-shrink: 0;
+  flex-grow: 0;
+  flex-basis: auto;
+  align-items: stretch;
+  align-content: flex-start;
+}
+.u-upload[data-v-c8491d64] {
+
+  display: flex;
+
+  flex-direction: column;
+  flex: 1;
+}
+.u-upload__wrap[data-v-c8491d64] {
+
+  display: flex;
+
+  flex-direction: row;
+  flex-wrap: wrap;
+  flex: 1;
+}
+.u-upload__wrap__preview[data-v-c8491d64] {
+  border-radius: 2px;
+  margin: 0 8px 8px 0;
+  position: relative;
+  overflow: hidden;
+
+  display: flex;
+
+  flex-direction: row;
+}
+.u-upload__wrap__preview__image[data-v-c8491d64] {
+  width: 80px;
+  height: 80px;
+}
+.u-upload__wrap__preview__other[data-v-c8491d64] {
+  width: 80px;
+  height: 80px;
+  background-color: #f2f2f2;
+  flex: 1;
+
+  display: flex;
+
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+.u-upload__wrap__preview__other__text[data-v-c8491d64] {
+  font-size: 11px;
+  color: #909193;
+  margin-top: 2px;
+}
+.u-upload__deletable[data-v-c8491d64] {
+  position: absolute;
+  top: 0;
+  right: 0;
+  background-color: #373737;
+  height: 14px;
+  width: 14px;
+
+  display: flex;
+
+  flex-direction: row;
+  border-bottom-left-radius: 100px;
+  align-items: center;
+  justify-content: center;
+  z-index: 3;
+}
+.u-upload__deletable__icon[data-v-c8491d64] {
+  position: absolute;
+  transform: scale(0.7);
+  top: 0px;
+  right: 0px;
+}
+.u-upload__success[data-v-c8491d64] {
+  position: absolute;
+  bottom: 0;
+  right: 0;
+
+  display: flex;
+
+  flex-direction: row;
+  border-style: solid;
+  border-top-color: transparent;
+  border-left-color: transparent;
+  border-bottom-color: #22ac38;
+  border-right-color: #22ac38;
+  border-width: 9px;
+  align-items: center;
+  justify-content: center;
+}
+.u-upload__success__icon[data-v-c8491d64] {
+  position: absolute;
+  transform: scale(0.7);
+  bottom: -10px;
+  right: -10px;
+}
+.u-upload__status[data-v-c8491d64] {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  background-color: rgba(0, 0, 0, 0.5);
+
+  display: flex;
+
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+}
+.u-upload__status__icon[data-v-c8491d64] {
+  position: relative;
+  z-index: 1;
+}
+.u-upload__status__message[data-v-c8491d64] {
+  font-size: 12px;
+  color: #FFFFFF;
+  margin-top: 5px;
+}
+.u-upload__button[data-v-c8491d64] {
+
+  display: flex;
+
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  width: 80px;
+  height: 80px;
+  background-color: #f4f5f7;
+  border-radius: 2px;
+  margin: 0 8px 8px 0;
+  box-sizing: border-box;
+}
+.u-upload__button__text[data-v-c8491d64] {
+  font-size: 11px;
+  color: #909193;
+  margin-top: 2px;
+}
+.u-upload__button--hover[data-v-c8491d64] {
+  background-color: #e6e7e9;
+}
+.u-upload__button--disabled[data-v-c8491d64] {
+  opacity: 0.5;
+}
+/**
+ * 这里是uni-app内置的常用样式变量
+ *
+ * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
+ * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
+ *
+ */
+/**
+ * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
+ *
+ * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
+ */
+/* 颜色变量 */
+/* 行为相关颜色 */
+/* 文字基本颜色 */
+/* 背景颜色 */
+/* 边框颜色 */
+/* 尺寸变量 */
+/* 文字尺寸 */
+/* 图片尺寸 */
+/* Border Radius */
+/* 水平间距 */
+/* 垂直间距 */
+/* 透明度 */
+/* 文章场景相关 */
+.tips[data-v-5002576b] {
+  font-size: 0.75rem;
+  font-family: PingFangSC, PingFang SC;
+  font-weight: 400;
+  color: #969696;
+  line-height: 1.5rem;
+  margin-top: 0.3125rem;
+}
+[data-v-5002576b] .align-right .u-upload__wrap {
+  justify-content: flex-end;
+}
+/**
+ * 这里是uni-app内置的常用样式变量
+ *
+ * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
+ * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
+ *
+ */
+/**
+ * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
+ *
+ * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
+ */
+/* 颜色变量 */
+/* 行为相关颜色 */
+/* 文字基本颜色 */
+/* 背景颜色 */
+/* 边框颜色 */
+/* 尺寸变量 */
+/* 文字尺寸 */
+/* 图片尺寸 */
+/* Border Radius */
+/* 水平间距 */
+/* 垂直间距 */
+/* 透明度 */
+/* 文章场景相关 */
 [data-v-0265fb8a] .u-popup__content {
   border-radius: 12px;
 }

+ 179 - 0
unpackage/dist/dev/app-plus/pages/index/wms/bad-off.css

@@ -1,3 +1,168 @@
+/**
+ * 这里是uni-app内置的常用样式变量
+ *
+ * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
+ * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
+ *
+ */
+/**
+ * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
+ *
+ * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
+ */
+/* 颜色变量 */
+/* 行为相关颜色 */
+/* 文字基本颜色 */
+/* 背景颜色 */
+/* 边框颜色 */
+/* 尺寸变量 */
+/* 文字尺寸 */
+/* 图片尺寸 */
+/* Border Radius */
+/* 水平间距 */
+/* 垂直间距 */
+/* 透明度 */
+/* 文章场景相关 */
+uni-view[data-v-2af81691], uni-scroll-view[data-v-2af81691], uni-swiper-item[data-v-2af81691] {
+  display: flex;
+  flex-direction: column;
+  flex-shrink: 0;
+  flex-grow: 0;
+  flex-basis: auto;
+  align-items: stretch;
+  align-content: flex-start;
+}
+.u-loading-icon[data-v-2af81691] {
+  flex-direction: row;
+  align-items: center;
+  justify-content: center;
+  color: #c8c9cc;
+}
+.u-loading-icon__text[data-v-2af81691] {
+  margin-left: 4px;
+  color: #606266;
+  font-size: 14px;
+  line-height: 20px;
+}
+.u-loading-icon__spinner[data-v-2af81691] {
+  width: 30px;
+  height: 30px;
+  position: relative;
+  box-sizing: border-box;
+  max-width: 100%;
+  max-height: 100%;
+  animation: u-rotate-2af81691 1s linear infinite;
+}
+.u-loading-icon__spinner--semicircle[data-v-2af81691] {
+  border-width: 2px;
+  border-color: transparent;
+  border-top-right-radius: 100px;
+  border-top-left-radius: 100px;
+  border-bottom-left-radius: 100px;
+  border-bottom-right-radius: 100px;
+  border-style: solid;
+}
+.u-loading-icon__spinner--circle[data-v-2af81691] {
+  border-top-right-radius: 100px;
+  border-top-left-radius: 100px;
+  border-bottom-left-radius: 100px;
+  border-bottom-right-radius: 100px;
+  border-width: 2px;
+  border-top-color: #e5e5e5;
+  border-right-color: #e5e5e5;
+  border-bottom-color: #e5e5e5;
+  border-left-color: #e5e5e5;
+  border-style: solid;
+}
+.u-loading-icon--vertical[data-v-2af81691] {
+  flex-direction: column;
+}
+[data-v-2af81691]:host {
+  font-size: 0px;
+  line-height: 1;
+}
+.u-loading-icon__spinner--spinner[data-v-2af81691] {
+  animation-timing-function: steps(12);
+}
+.u-loading-icon__text[data-v-2af81691]:empty {
+  display: none;
+}
+.u-loading-icon--vertical .u-loading-icon__text[data-v-2af81691] {
+  margin: 6px 0 0;
+  color: #606266;
+}
+.u-loading-icon__dot[data-v-2af81691] {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+}
+.u-loading-icon__dot[data-v-2af81691]:before {
+  display: block;
+  width: 2px;
+  height: 25%;
+  margin: 0 auto;
+  background-color: currentColor;
+  border-radius: 40%;
+  content: " ";
+}
+.u-loading-icon__dot[data-v-2af81691]:nth-of-type(1) {
+  transform: rotate(30deg);
+  opacity: 1;
+}
+.u-loading-icon__dot[data-v-2af81691]:nth-of-type(2) {
+  transform: rotate(60deg);
+  opacity: 0.9375;
+}
+.u-loading-icon__dot[data-v-2af81691]:nth-of-type(3) {
+  transform: rotate(90deg);
+  opacity: 0.875;
+}
+.u-loading-icon__dot[data-v-2af81691]:nth-of-type(4) {
+  transform: rotate(120deg);
+  opacity: 0.8125;
+}
+.u-loading-icon__dot[data-v-2af81691]:nth-of-type(5) {
+  transform: rotate(150deg);
+  opacity: 0.75;
+}
+.u-loading-icon__dot[data-v-2af81691]:nth-of-type(6) {
+  transform: rotate(180deg);
+  opacity: 0.6875;
+}
+.u-loading-icon__dot[data-v-2af81691]:nth-of-type(7) {
+  transform: rotate(210deg);
+  opacity: 0.625;
+}
+.u-loading-icon__dot[data-v-2af81691]:nth-of-type(8) {
+  transform: rotate(240deg);
+  opacity: 0.5625;
+}
+.u-loading-icon__dot[data-v-2af81691]:nth-of-type(9) {
+  transform: rotate(270deg);
+  opacity: 0.5;
+}
+.u-loading-icon__dot[data-v-2af81691]:nth-of-type(10) {
+  transform: rotate(300deg);
+  opacity: 0.4375;
+}
+.u-loading-icon__dot[data-v-2af81691]:nth-of-type(11) {
+  transform: rotate(330deg);
+  opacity: 0.375;
+}
+.u-loading-icon__dot[data-v-2af81691]:nth-of-type(12) {
+  transform: rotate(360deg);
+  opacity: 0.3125;
+}
+@keyframes u-rotate-2af81691 {
+0% {
+    transform: rotate(0deg);
+}
+to {
+    transform: rotate(1turn);
+}
+}
 
 .task-card[data-v-58677b56] {
     background-color: #ffffff;
@@ -15,3 +180,17 @@
     font-size: 0.875rem;
     font-weight: bold;
 }
+.empty-state[data-v-58677b56] {
+    text-align: center;
+    padding: 1.25rem;
+    color: #999;
+}
+.loading-state[data-v-58677b56] {
+    text-align: center;
+    padding: 1.25rem;
+}
+.loading-state uni-text[data-v-58677b56] {
+    margin-left: 0.375rem;
+    color: #666;
+    font-size: 0.875rem;
+}

+ 14 - 1
unpackage/dist/dev/app-plus/pages/index/wms/bad-out-order.css

@@ -585,7 +585,7 @@ uni-view[data-v-5ce41ee6], uni-scroll-view[data-v-5ce41ee6], uni-swiper-item[dat
         display: flex;
         width: 100%;
 }
-.book-info[data-v-e52c1f77]{
+.book-info[data-v-e52c1f77] {
         font-size: 0.8125rem;
 }
 .color-red[data-v-e52c1f77] {
@@ -1211,6 +1211,19 @@ uni-view[data-v-05c24e9b], uni-scroll-view[data-v-05c24e9b], uni-swiper-item[dat
 .container[data-v-43bc1c65] {
     padding-bottom: 3.75rem;
 }
+.error-section[data-v-43bc1c65] {
+    background-color: #fef0f0;
+    padding: 0.625rem;
+    border-radius: 0.25rem;
+    margin-bottom: 0.625rem;
+    display: flex;
+    align-items: center;
+}
+.error-text[data-v-43bc1c65] {
+    color: #fa3534;
+    margin-left: 0.3125rem;
+    font-size: 0.875rem;
+}
 .info-section[data-v-43bc1c65] {
     background-color: #fff;
     padding: 0.625rem;

+ 3 - 3
unpackage/dist/dev/app-plus/pages/index/wms/task-detail.css

@@ -702,7 +702,7 @@ uni-view[data-v-e082a34a], uni-scroll-view[data-v-e082a34a], uni-swiper-item[dat
         display: flex;
         width: 100%;
 }
-.book-info[data-v-e52c1f77]{
+.book-info[data-v-e52c1f77] {
         font-size: 0.8125rem;
 }
 .color-red[data-v-e52c1f77] {
@@ -719,14 +719,14 @@ uni-view[data-v-e082a34a], uni-scroll-view[data-v-e082a34a], uni-swiper-item[dat
     padding: 0.3125rem;
     padding-top: 56px;
 }
-.next-location[data-v-ca763ad9]{
+.next-location[data-v-ca763ad9] {
     background-color: #fff;
     border-bottom: 0.03125rem solid #f0f0f0;
     border-top: 0.03125rem solid #f0f0f0;
     padding: 0.625rem;
 }
 .color-green[data-v-ca763ad9] {
-    color: #4CAF50;
+    color: #4caf50;
 }
 .location-info[data-v-ca763ad9] {
     background-color: #fff;

部分文件因为文件数量过多而无法显示