Quellcode durchsuchen

部分码完成

lisy vor 1 Woche
Ursprung
Commit
b4981f52c2

+ 19 - 0
src/pages.json

@@ -378,6 +378,19 @@
                     "style": {
                         "navigationBarTitleText": "药材库"
                     }
+                },
+                //成品库
+                {
+                    "path": "finished-product/list/index",
+                    "style": {
+                        "navigationBarTitleText": "成品库"
+                    }
+                },
+                {
+                    "path": "finished-product/detail/index",
+                    "style": {
+                        "navigationBarTitleText": "成品详情"
+                    }
                 }
             ]
         },
@@ -638,6 +651,12 @@
                     "style": {
                         "navigationBarTitleText": "码生成及管理"
                     }
+                },
+                {
+                    "path": "code-detail-list/index",
+                    "style": {
+                        "navigationBarTitleText": "码详情"
+                    }
                 }
             ]
         }

+ 43 - 17
src/pages/plant/port/index.vue

@@ -2,20 +2,26 @@
     <z-paging ref="paging" v-model="list" bgColor="#f7f7f7" @query="query" hide-no-more-inside>
         <template #top>
             <up-navbar title="种养殖任务" :fixed="false">
-                <template #left><view class=""></view></template>
+                <template #left>
+                    <view class=""></view>
+                </template>
             </up-navbar>
         </template>
         <view class="d-flex a-c pd-24 pb-0 bg-#f7f7f7">
             <view class="min-w-170 flex1">
-                <ut-action-sheet v-model="form.taskType" :tabs="[{ label: '全部', value: '' }, ...pt_task_type]" @change="onRefresh" title="选择原料类型">
+                <ut-action-sheet v-model="form.taskType" :tabs="[{ label: '全部', value: '' }, ...pt_task_type]"
+                    @change="onRefresh" title="选择原料类型">
                     <view class="d-flex search-select-item a-c">
-                        <view class="flex1 ov-hd f-s-28 c-333 text-center f-w-5 w-s-no">{{ selectDictLabel(pt_task_type, form.taskType) || '全部' }}</view>
+                        <view class="flex1 ov-hd f-s-28 c-333 text-center f-w-5 w-s-no">{{ selectDictLabel(pt_task_type,
+                            form.taskType) || '全部' }}</view>
                         <up-icon size="24rpx" color="#333" name="arrow-down-fill" class="mr-5"></up-icon>
                     </view>
                 </ut-action-sheet>
             </view>
             <view class="h-86 pl-20 w-100%">
-                <ut-search ref="searchRef" v-model="form.keyword" @search="changeSeach" @change="changeSeach" margin="0" :border="false" placeholder="搜批次号、品种名、基地名" bgColor="#fff" height="86rpx" borderRadius="10rpx"></ut-search>
+                <ut-search ref="searchRef" v-model="form.keyword" @search="changeSeach" @change="changeSeach" margin="0"
+                    :border="false" placeholder="搜批次号、品种名、基地名" bgColor="#fff" height="86rpx"
+                    borderRadius="10rpx"></ut-search>
             </view>
         </view>
         <view class="pd-24 bg-#f7f7f7">
@@ -23,50 +29,68 @@
         </view>
         <view class="pd-24 pt-0">
             <up-swipe-action>
-                <up-swipe-action-item v-for="(item, index) in list" :key="index" :name="item?.id" :options="form?.status == '1' ? options2 : options" class="mb-20" @click="clickTempSwipe">
-                    <task :data="item" :status="form?.status" @click="$u.route({ type: 'navigateTo', url: '/plant/port/port-detail/index', params: { id: item?.id } })" @toSupervise="$u.route({ type: 'navigateTo', url: '/plant/port/port-supervise/index', params: { id: item?.id } })" @toInformation="$u.route({ type: 'navigateTo', url: '/plant/port/port-listinfo/index', params: { id: item?.id } })" @toHarvest="$u.route({ type: 'navigateTo', url: '/plant/port/port-harvest/index', params: { id: item?.id } })" />
+                <up-swipe-action-item v-for="(item, index) in list" :key="index" :name="item?.id"
+                    :options="form?.status == '1' ? options2 : options" class="mb-20" @click="clickTempSwipe">
+                    <task :data="item" :status="form?.status"
+                        @cardClick="$u.route({ type: 'navigateTo', url: '/plant/port/port-detail/index', params: { id: item?.id } })"
+                        @toSupervise="$u.route({ type: 'navigateTo', url: '/plant/port/port-supervise/index', params: { id: item?.id } })"
+                        @toInformation="$u.route({ type: 'navigateTo', url: '/plant/port/port-listinfo/index', params: { id: item?.id } })"
+                        @toHarvest="$u.route({ type: 'navigateTo', url: '/plant/port/port-harvest/index', params: { id: item?.id } })" />
                 </up-swipe-action-item>
             </up-swipe-action>
         </view>
         <template #empty v-if="form?.status == '1'">
             <view class="d-flex flex-cln a-c" style="margin-top: -200rpx">
-                <ut-empty class="mg-at" color="#ccc" size="28rpx" image="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/noEmptyBase.png">暂无进行中的养殖任务</ut-empty>
+                <ut-empty class="mg-at" color="#ccc" size="28rpx"
+                    image="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/noEmptyBase.png">暂无进行中的养殖任务</ut-empty>
                 <text class="c-#ccc f-s-28">点击下方按钮去添加吧~</text>
             </view>
         </template>
         <template #empty v-if="form?.status == '9'">
             <view class="d-flex flex-cln a-c" style="margin-top: -200rpx">
-                <ut-empty class="mg-at" color="#ccc" size="28rpx" image="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/noEmptyBase.png">暂无已经结束的养殖任务</ut-empty>
+                <ut-empty class="mg-at" color="#ccc" size="28rpx"
+                    image="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/noEmptyBase.png">暂无已经结束的养殖任务</ut-empty>
             </view>
         </template>
         <template #bottom>
             <ut-tabar activeTab="planting"></ut-tabar>
         </template>
     </z-paging>
-    <ut-suspension v-if="sus?.left" :imageWidth="60" :imageHeight="60" :x="sus?.left" :y="sus?.bottom" :inertia="false" :snap-threshold="40">
-        <image src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/common/btn_add_logo.png" mode="widthFix" class="w-120 h-120" @click="showDeleteDialog = true"></image>
+    <ut-suspension v-if="sus?.left" :imageWidth="60" :imageHeight="60" :x="sus?.left" :y="sus?.bottom" :inertia="false"
+        :snap-threshold="40">
+        <image src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/common/btn_add_logo.png" mode="widthFix"
+            class="w-120 h-120" @click="showDeleteDialog = true"></image>
     </ut-suspension>
-    <ut-confirm-dialog v-model:show="showDeleteDialog" width="80vw" title="请选择要创建的任务类型" :confirmText="'确认选择'" :cancelText="'取消'" @confirm="handlechoseConfirm" @cancel="handleDeleteCancel">
+    <ut-confirm-dialog v-model:show="showDeleteDialog" width="80vw" title="请选择要创建的任务类型" :confirmText="'确认选择'"
+        :cancelText="'取消'" @confirm="handlechoseConfirm" @cancel="handleDeleteCancel">
         <view class="" v-for="item in pt_task_type" :key="item?.value">
-            <view style="border: 1rpx solid" :style="{ backgroundColor: item?.value == basetype ? '#EBF6EE' : '#f7f7f7', borderColor: item?.value == basetype ? '#37A954' : 'transparent' }" class="pr-30 d-flex a-c mb-20 radius-100" @click="handlechose(item.value)">
+            <view style="border: 1rpx solid"
+                :style="{ backgroundColor: item?.value == basetype ? '#EBF6EE' : '#f7f7f7', borderColor: item?.value == basetype ? '#37A954' : 'transparent' }"
+                class="pr-30 d-flex a-c mb-20 radius-100" @click="handlechose(item.value)">
                 <view class="radius-50% mg-8 bg-#F0F0F0" v-if="item?.value == '1'">
-                    <up-avatar size="90rpx" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/TaskType_plant.png"></up-avatar>
+                    <up-avatar size="90rpx"
+                        src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/TaskType_plant.png"></up-avatar>
                 </view>
                 <view class="radius-50% mg-8 bg-#F0F0F0" v-if="item?.value == '2'">
-                    <up-avatar size="90rpx" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/TaskType_breeding.png"></up-avatar>
+                    <up-avatar size="90rpx"
+                        src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/TaskType_breeding.png"></up-avatar>
                 </view>
                 <view class="radius-50% mg-8 bg-#F0F0F0" v-if="item?.value == '11'">
-                    <up-avatar size="90rpx" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/TaskType_SeedlingBreeding.png"></up-avatar>
+                    <up-avatar size="90rpx"
+                        src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/TaskType_SeedlingBreeding.png"></up-avatar>
                 </view>
                 <view class="radius-50% mg-8 bg-#F0F0F0" v-if="item?.value == '21'">
-                    <up-avatar size="90rpx" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/TaskType_BreedingLivestock.png"></up-avatar>
+                    <up-avatar size="90rpx"
+                        src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/TaskType_BreedingLivestock.png"></up-avatar>
                 </view>
                 <view class="c-#333 f-s-34">
                     {{ item?.label }}
                 </view>
                 <view class="flex1"></view>
                 <view class="d-flex">
-                    <img v-if="basetype === item.value" class="w-30 h-30" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/chooseSuccessfully.png" mode="widthFix" alt="" />
+                    <img v-if="basetype === item.value" class="w-30 h-30"
+                        src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/chooseSuccessfully.png"
+                        mode="widthFix" alt="" />
                 </view>
             </view>
         </view>
@@ -219,9 +243,11 @@ onMounted(() => {
     padding-top: 14rpx;
     padding-bottom: 14rpx;
 }
+
 :deep(.u-subsection__item) {
     border: 1px solid transparent !important;
 }
+
 :deep(.u-swipe-action-item__right__button__wrapper__text) {
     line-height: 1.6 !important;
     white-space: normal;

+ 35 - 35
src/pages/plant/port/models/task.vue

@@ -9,11 +9,11 @@
                 src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/over.png" mode="widthFix"
                 style="position: absolute; top: 50rpx; right: 20rpx" />
             <view class="d-flex j-ed f-s-22 c-#666">{{ data?.plannedStartDate }}至{{ data?.plannedEndDate }}</view>
-            <view class="d-flex a-ed pd-16 pt-8 pb-8">
+            <view class="d-flex a-ed pd-16 pt-8 pb-8" @click.stop="$emit('cardClick')">
                 <view class="c-#333 f-s-34 f-w-5 mr-6">{{ data?.variety }}</view>
                 <view class="c-#666 f-s-26">{{ data?.genusName }}</view>
             </view>
-            <view class="d-flex a-c f-s-28 pd-16 pt-8 pb-8">
+            <view class="d-flex a-c f-s-28 pd-16 pt-8 pb-8" @click.stop="$emit('cardClick')">
                 <view class="c-#666 w-s-no">养殖批号:</view>
                 <view class="c-#333 f-w-5">{{ data?.plantationCode }}</view>
             </view>
@@ -26,7 +26,7 @@
                     <view class="c-#666">暂无完善种源信息</view>
                 </view>
             </view>
-            <view class="d-flex a-c f-s-28 pd-16 pt-8 pb-8" @click="$emit('click')">
+            <view class="d-flex a-c f-s-28 pd-16 pt-8 pb-8" @click.stop="$emit('cardClick')">
                 <view class="c-#666 w-s-no">基地:</view>
                 <view class="c-#333 f-w-5 tx-ov w-s-no ov-hd d-flex a-c">
                     {{ data?.baseRef?.baseName }}
@@ -38,7 +38,7 @@
                 </view>
                 <view class="flex1 d-flex j-ed"><up-icon name="arrow-right" size="34rpx"></up-icon></view>
             </view>
-            <view class="d-flex f-s-28 pd-16 pt-8 pb-8">
+            <view class="d-flex f-s-28 pd-16 pt-8 pb-8" @click.stop="$emit('cardClick')">
                 <view class="d-flex a-c w-50%">
                     <view class="c-#666 w-s-no">养殖区域:</view>
                     <view class="c-#333 f-w-5 tx-ov w-s-no ov-hd">{{ data?.breedScale }}{{ data?.breedScaleUnit }}
@@ -54,7 +54,7 @@
                 <up-line color="#f7f7f7"></up-line>
             </view>
             <view class="pd-16 pt-8 pb-8 d-flex j-sb gap-20">
-                <up-button :customStyle="customStyle1" @click="$emit('toInformation')">
+                <up-button :customStyle="customStyle1" @click.stop="$emit('toInformation')">
                     <view class="d-flex a-c j-c">
                         <image class="w-28 h-24"
                             src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/Task_Species_source_information.png"
@@ -62,7 +62,7 @@
                         <text class="f-s-26">种源信息</text>
                     </view>
                 </up-button>
-                <up-button :customStyle="customStyle2" @click="$emit('toSupervise')">
+                <up-button :customStyle="customStyle2" @click.stop="$emit('toSupervise')">
                     <view class="d-flex a-c j-c">
                         <image class="w-28 h-24"
                             src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/Task_Breeding_management.png"
@@ -70,7 +70,7 @@
                         <text class="f-s-26">饲养管理</text>
                     </view>
                 </up-button>
-                <up-button :customStyle="customStyle3" @click="$emit('toHarvest')">
+                <up-button :customStyle="customStyle3" @click.stop="$emit('toHarvest')">
                     <view class="d-flex a-c j-c">
                         <image class="w-28 h-24"
                             src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/Task_Harvest_management.png"
@@ -82,7 +82,7 @@
         </view>
     </view>
     <!-- 种苗繁育 -->
-    <view class="" v-if="data.taskType === '11'" @click="$emit('click')">
+    <view class="" v-if="data.taskType === '11'">
         <view class="b-radius bg-#fff pd-10 p-rtv">
             <image class="w-112 h-34"
                 src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/Task_Seedling_breeding.png"
@@ -91,15 +91,15 @@
                 src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/over.png" mode="widthFix"
                 style="position: absolute; top: 50rpx; right: 20rpx" />
             <view class="d-flex j-ed f-s-22 c-#666">{{ data?.plannedStartDate }} 至 {{ data?.plannedEndDate }}</view>
-            <view class="d-flex a-ed pd-16 pt-8 pb-8">
+            <view class="d-flex a-ed pd-16 pt-8 pb-8" @click.stop="$emit('cardClick')">
                 <view class="c-#333 f-s-34 f-w-5 mr-6">{{ data?.variety }}</view>
                 <view class="c-#666 f-s-26">{{ data?.genusName }}</view>
             </view>
-            <view class="d-flex a-c f-s-28 pd-16 pt-8 pb-8">
+            <view class="d-flex a-c f-s-28 pd-16 pt-8 pb-8" @click.stop="$emit('cardClick')">
                 <view class="c-#666 w-s-no">繁育批号:</view>
                 <view class="c-#333 f-w-5">{{ data?.plantationCode }}</view>
             </view>
-            <view class="d-flex a-c f-s-28 pd-16 pt-8 pb-8">
+            <view class="d-flex a-c f-s-28 pd-16 pt-8 pb-8" @click.stop="$emit('cardClick')">
                 <view class="c-#666 w-s-no">种源批号:</view>
                 <view v-if="data?.seedCodeList.length !== 0">
                     <view class="c-#333 f-w-5" v-for="item in data?.seedCodeList" :key="item">{{ item }}</view>
@@ -108,7 +108,7 @@
                     <view class="c-#666">暂无完善种源信息</view>
                 </view>
             </view>
-            <view class="d-flex a-c f-s-28 pd-16 pt-8 pb-8">
+            <view class="d-flex a-c f-s-28 pd-16 pt-8 pb-8" @click.stop="$emit('cardClick')">
                 <view class="c-#666 w-s-no">基地:</view>
                 <view class="c-#333 f-w-5 tx-ov w-s-no ov-hd d-flex a-c">
                     {{ data?.baseRef?.baseName }}
@@ -120,7 +120,7 @@
                 </view>
                 <view class="flex1 d-flex j-ed"><up-icon name="arrow-right" size="34rpx"></up-icon></view>
             </view>
-            <view class="d-flex f-s-28 pd-16 pt-8 pb-8">
+            <view class="d-flex f-s-28 pd-16 pt-8 pb-8" @click.stop="$emit('cardClick')">
                 <view v-if="data?.lands[0]?.landType == '3'" class="d-flex a-c w-50%">
                     <view class="c-#666 w-s-no">接种数量:</view>
                     <view class="c-#333 f-w-5 tx-ov w-s-no ov-hd">{{ data?.inoculationAmount }}{{ data?.inoculationUnit
@@ -141,7 +141,7 @@
                 <up-line color="#f7f7f7"></up-line>
             </view>
             <view class="pd-16 pt-8 pb-8 d-flex j-sb gap-20">
-                <up-button :customStyle="customStyle1" @click="$emit('toInformation')">
+                <up-button :customStyle="customStyle1" @click.stop="$emit('toInformation')">
                     <view class="d-flex a-c j-c">
                         <image class="w-28 h-24"
                             src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/Task_Species_source_information.png"
@@ -150,7 +150,7 @@
                     </view>
                 </up-button>
                 <up-button v-if="data?.lands[0]?.landType == '3'" :customStyle="customStyle2"
-                    @click="$emit('toSupervise')">
+                    @click.stop="$emit('toSupervise')">
                     <view class="d-flex a-c j-c">
                         <image class="w-28 h-24"
                             src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/Task_Breeding_management.png"
@@ -158,7 +158,7 @@
                         <text class="f-s-26"> 繁育管理 </text>
                     </view>
                 </up-button>
-                <up-button v-else :customStyle="customStyle2" @click="$emit('toSupervise')">
+                <up-button v-else :customStyle="customStyle2" @click.stop="$emit('toSupervise')">
                     <view class="d-flex a-c j-c">
                         <image class="w-28 h-24"
                             src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/Task_Breeding_management.png"
@@ -166,7 +166,7 @@
                         <text class="f-s-26"> 种植管理 </text>
                     </view>
                 </up-button>
-                <up-button :customStyle="customStyle3" @click="$emit('toHarvest')">
+                <up-button :customStyle="customStyle3" @click.stop="$emit('toHarvest')">
                     <view class="d-flex a-c j-c">
                         <image class="w-28 h-24"
                             src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/Task_Harvest_management.png"
@@ -178,7 +178,7 @@
         </view>
     </view>
     <!-- 种植 -->
-    <view class="" v-if="data.taskType === '1'" @click="$emit('click')">
+    <view class="" v-if="data.taskType === '1'">
         <view class="b-radius bg-#fff pd-10 p-rtv">
             <image class="w-80 h-34"
                 src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/Task_Planting.png"
@@ -187,15 +187,15 @@
                 src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/over.png" mode="widthFix"
                 style="position: absolute; top: 50rpx; right: 20rpx" />
             <view class="d-flex j-ed f-s-22 c-#666">{{ data?.plannedStartDate }}至{{ data?.plannedEndDate }}</view>
-            <view class="d-flex a-ed pd-16 pt-8 pb-8">
+            <view class="d-flex a-ed pd-16 pt-8 pb-8" @click.stop="$emit('cardClick')">
                 <view class="c-#333 f-s-34 f-w-5 mr-6">{{ data?.variety }}</view>
                 <view class="c-#666 f-s-26">{{ data?.genusName }}</view>
             </view>
-            <view class="d-flex a-c f-s-28 pd-16 pt-8 pb-8">
+            <view class="d-flex a-c f-s-28 pd-16 pt-8 pb-8" @click.stop="$emit('cardClick')">
                 <view class="c-#666 w-s-no">种植批号:</view>
                 <view class="c-#333 f-w-5">{{ data?.plantationCode }}</view>
             </view>
-            <view class="d-flex a-c f-s-28 pd-16 pt-8 pb-8">
+            <view class="d-flex a-c f-s-28 pd-16 pt-8 pb-8" @click.stop="$emit('cardClick')">
                 <view class="c-#666 w-s-no">种源批号:</view>
                 <view v-if="data?.seedCodeList.length !== 0">
                     <view class="c-#333 f-w-5" v-for="item in data?.seedCodeList" :key="item">{{ item }}</view>
@@ -204,7 +204,7 @@
                     <view class="c-#666">暂无完善种源信息</view>
                 </view>
             </view>
-            <view class="d-flex a-c f-s-28 pd-16 pt-8 pb-8">
+            <view class="d-flex a-c f-s-28 pd-16 pt-8 pb-8" @click.stop="$emit('cardClick')">
                 <view class="c-#666 w-s-no">基地:</view>
                 <view class="c-#333 f-w-5 tx-ov w-s-no ov-hd d-flex a-c">
                     {{ data?.baseRef?.baseName }}
@@ -216,7 +216,7 @@
                 </view>
                 <view class="flex1 d-flex j-ed"><up-icon name="arrow-right" size="34rpx"></up-icon></view>
             </view>
-            <view class="d-flex f-s-28 pd-16 pt-8 pb-8">
+            <view class="d-flex f-s-28 pd-16 pt-8 pb-8" @click.stop="$emit('cardClick')">
                 <view class="d-flex a-c w-50%">
                     <view class="c-#666 w-s-no">种植面积:</view>
                     <view class="c-#333 f-w-5 tx-ov w-s-no ov-hd">{{ data?.plantingAmount }}{{ data?.plantingUnit }}
@@ -232,7 +232,7 @@
                 <up-line color="#f7f7f7"></up-line>
             </view>
             <view class="pd-16 pt-8 pb-8 d-flex j-sb gap-20">
-                <up-button :customStyle="customStyle1" @click="$emit('toInformation')">
+                <up-button :customStyle="customStyle1" @click.stop="$emit('toInformation')">
                     <view class="d-flex a-c j-c">
                         <image class="w-28 h-24"
                             src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/Task_Species_source_information.png"
@@ -240,7 +240,7 @@
                         <text class="f-s-26">种源信息</text>
                     </view>
                 </up-button>
-                <up-button :customStyle="customStyle2" @click="$emit('toSupervise')">
+                <up-button :customStyle="customStyle2" @click.stop="$emit('toSupervise')">
                     <view class="d-flex a-c j-c">
                         <image class="w-28 h-24"
                             src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/Task_Breeding_management.png"
@@ -248,7 +248,7 @@
                         <text class="f-s-26"> 种植管理 </text>
                     </view>
                 </up-button>
-                <up-button :customStyle="customStyle3" @click="$emit('toHarvest')">
+                <up-button :customStyle="customStyle3" @click.stop="$emit('toHarvest')">
                     <view class="d-flex a-c j-c">
                         <image class="w-28 h-24"
                             src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/Task_Harvest_management.png"
@@ -260,7 +260,7 @@
         </view>
     </view>
     <!-- 种畜繁育 -->
-    <view class="" v-if="data.taskType === '21'" @click="$emit('click')">
+    <view class="" v-if="data.taskType === '21'">
         <view class="b-radius bg-#fff pd-10 p-rtv">
             <image class="w-112 h-34"
                 src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/Task_Breeding_Livestock.png"
@@ -269,15 +269,15 @@
                 src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/over.png" mode="widthFix"
                 style="position: absolute; top: 50rpx; right: 20rpx" />
             <view class="d-flex j-ed f-s-22 c-#666">{{ data?.plannedStartDate }}至{{ data?.plannedEndDate }}</view>
-            <view class="d-flex a-ed pd-16 pt-8 pb-8">
+            <view class="d-flex a-ed pd-16 pt-8 pb-8" @click.stop="$emit('cardClick')">
                 <view class="c-#333 f-s-34 f-w-5 mr-6">{{ data?.variety }}</view>
                 <view class="c-#666 f-s-26">{{ data?.genusName }}</view>
             </view>
-            <view class="d-flex a-c f-s-28 pd-16 pt-8 pb-8">
+            <view class="d-flex a-c f-s-28 pd-16 pt-8 pb-8" @click.stop="$emit('cardClick')">
                 <view class="c-#666 w-s-no">繁育批号:</view>
                 <view class="c-#333 f-w-5">{{ data?.plantationCode }}</view>
             </view>
-            <view class="d-flex a-c f-s-28 pd-16 pt-8 pb-8">
+            <view class="d-flex a-c f-s-28 pd-16 pt-8 pb-8" @click.stop="$emit('cardClick')">
                 <view class="c-#666 w-s-no">种源批号:</view>
                 <view v-if="data?.seedCodeList.length !== 0">
                     <view class="c-#333 f-w-5" v-for="item in data?.seedCodeList" :key="item">{{ item }}</view>
@@ -286,7 +286,7 @@
                     <view class="c-#666">暂无完善种源信息</view>
                 </view>
             </view>
-            <view class="d-flex a-c f-s-28 pd-16 pt-8 pb-8">
+            <view class="d-flex a-c f-s-28 pd-16 pt-8 pb-8" @click.stop="$emit('cardClick')">
                 <view class="c-#666 w-s-no">基地:</view>
                 <view class="c-#333 f-w-5 tx-ov w-s-no ov-hd d-flex a-c">
                     {{ data?.baseRef?.baseName }}
@@ -298,7 +298,7 @@
                 </view>
                 <view class="flex1 d-flex j-ed"><up-icon name="arrow-right" size="34rpx"></up-icon></view>
             </view>
-            <view class="d-flex f-s-28 pd-16 pt-8 pb-8">
+            <view class="d-flex f-s-28 pd-16 pt-8 pb-8" @click.stop="$emit('cardClick')">
                 <view class="d-flex a-c w-50%">
                     <view class="c-#666 w-s-no">养殖区域:</view>
                     <view class="c-#333 f-w-5 tx-ov w-s-no ov-hd">{{ data?.breedScale }}{{ data?.breedScaleUnit }}
@@ -314,7 +314,7 @@
                 <up-line color="#f7f7f7"></up-line>
             </view>
             <view class="pd-16 pt-8 pb-8 d-flex j-sb gap-20">
-                <up-button :customStyle="customStyle1" @click="$emit('toInformation')">
+                <up-button :customStyle="customStyle1" @click.stop="$emit('toInformation')">
                     <view class="d-flex a-c j-c">
                         <image class="w-28 h-24"
                             src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/Task_Species_source_information.png"
@@ -322,7 +322,7 @@
                         <text class="f-s-26">种源信息</text>
                     </view>
                 </up-button>
-                <up-button :customStyle="customStyle2" @click="$emit('toSupervise')">
+                <up-button :customStyle="customStyle2" @click.stop="$emit('toSupervise')">
                     <view class="d-flex a-c j-c">
                         <image class="w-28 h-24"
                             src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/Task_Breeding_management.png"
@@ -330,7 +330,7 @@
                         <text class="f-s-26">饲养管理</text>
                     </view>
                 </up-button>
-                <up-button :customStyle="customStyle3" @click="$emit('toHarvest')">
+                <up-button :customStyle="customStyle3" @click.stop="$emit('toHarvest')">
                     <view class="d-flex a-c j-c">
                         <image class="w-28 h-24"
                             src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/port/Task_Harvest_management.png"

+ 141 - 0
src/plant/code/code-detail-list/index.vue

@@ -0,0 +1,141 @@
+<template>
+    <z-paging ref="paging" v-model="list" bgColor="#f7f7f7" @query="queryList" safe-area-inset-bottom>
+        <template #top>
+            <ut-navbar :title="title" :fixed="false"></ut-navbar>
+        </template>
+        <view class="pd-24">
+            <!-- 头部信息卡片 - 使用 code-item 组件 -->
+            <code-item :item="detailData" :show-buttons="false"></code-item>
+            <view class="d-flex a-c pb-20" style="margin-left: -10rpx;">
+                <up-tabs :list="list1" lineWidth="60"></up-tabs>
+            </view>
+            <!-- 使用记录列表 -->
+            <view v-for="(item, index) in list" :key="index" class="bg-#fff b-radius-16 pd-24 mb-16 b-radius">
+                <view class="d-flex a-c pb-10">
+                    <span class="f-s-28 c-#666">使用数量:</span>
+                    <span class="f-s-28 c-#333 f-w-500">{{ item.useCount || 0 }}</span>
+                </view>
+                <view class="d-flex a-c pb-10">
+                    <span class="f-s-28 c-#666">使用对象:</span>
+                    <span class="f-s-28 c-#333">{{ item?.packTask?.proName }}</span>
+                    <span class="ml-10 f-s-22 c-#333" v-if="+item?.packTask?.packTaskType !== 2">
+                        {{ item?.packTask?.proLevel }}</span>
+                    <span class="ml-10 f-s-22 c-#333" v-else>种子</span>
+                </view>
+                <view class="d-flex a-c pb-10">
+                    <span class="f-s-28 c-#666">包装批号:</span>
+                    <span class="f-s-28 c-#333 f-w-500">{{ item?.packTask?.packSn || '-' }}</span>
+                </view>
+                <view class="d-flex a-c pb-10">
+                    <span class="f-s-28 c-#666">成品批号:</span>
+                    <span class="f-s-28 c-#333 f-w-500">{{ item?.packTask?.batchSn || '-' }}</span>
+                </view>
+                <view class="d-flex a-c j-sb">
+                    <view>
+                        <span class="f-s-24 c-#666">打印人:</span>
+                        <span class="f-s-24 c-#333 f-w-500">{{ item?.createByName || '-' }}</span>
+                    </view>
+                    <view>
+                        <span class="f-s-24 c-#666">打印时间:</span>
+                        <span class="f-s-24 c-#333 f-w-500">{{ formatItemTime(item.updateTime || item?.createTime)
+                            }}</span>
+                    </view>
+                </view>
+            </view>
+        </view>
+    </z-paging>
+</template>
+
+<script setup lang="ts">
+import { useClientRequest } from '@/utils/request';
+import CodeItem from '../code-list/models/code-item.vue'
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const paging = ref();
+const list = ref<any>([]);
+const id = ref('');
+const title = ref('码详情');
+const detailData = ref<any>({});
+const list1 = reactive([
+    { name: '使用情况', value: '' },
+]);
+
+// 格式化列表项时间
+const formatItemTime = (timeStr: string) => {
+    if (!timeStr) return '-';
+    const date = new Date(timeStr);
+    if (isNaN(date.getTime())) {
+        return String(timeStr);
+    }
+    const year = date.getFullYear();
+    const month = String(date.getMonth() + 1).padStart(2, '0');
+    const day = String(date.getDate()).padStart(2, '0');
+    const hours = String(date.getHours()).padStart(2, '0');
+    const minutes = String(date.getMinutes()).padStart(2, '0');
+    const seconds = String(date.getSeconds()).padStart(2, '0');
+    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+};
+
+// 获取头部详情数据
+const getDetailData = async () => {
+    if (!id.value) return;
+    try {
+        const res = await useClientRequest.get(`/plt-api/app/traceCodeLog/${id.value}`);
+        if (res) {
+            detailData.value = res.data || res;
+        }
+    } catch (error) {
+        console.error('获取码详情失败:', error);
+    }
+};
+
+// 分页查询使用记录列表
+const queryList = async (pageNo: number, pageSize: number) => {
+    try {
+        const res = await useClientRequest.get('/plt-api/app/traceCodeUseLog/list', {
+            pageNo,
+            pageSize,
+            logId: id.value,
+        });
+        if (res) {
+            const { rows } = res;
+            paging.value.complete(rows);
+        }
+    } catch (error) {
+        console.error('获取使用记录列表失败:', error);
+    }
+};
+
+onLoad((options: any) => {
+    id.value = options?.id;
+    getDetailData();
+});
+
+onMounted(() => {
+    // 页面挂载时刷新列表
+    if (paging.value) {
+        paging.value.reload();
+    }
+});
+</script>
+
+<style scoped lang="scss">
+.startline-title {
+    font-size: 32rpx;
+    font-weight: 500;
+    color: #333;
+    position: relative;
+    padding-left: 20rpx;
+
+    &::before {
+        content: '';
+        position: absolute;
+        left: 0;
+        top: 50%;
+        transform: translateY(-50%);
+        width: 8rpx;
+        height: 32rpx;
+        background-color: #37a954;
+        border-radius: 4rpx;
+    }
+}
+</style>

+ 30 - 31
src/plant/code/code-list/index.vue

@@ -7,11 +7,12 @@
             <!-- 搜索栏 -->
             <view class="d-flex a-c pd-24 pb-0 bg-#f7f7f7">
                 <view class="min-w-220 flex1">
-                    <ut-action-sheet v-model="form.type" :tabs="[{ label: '全部', value: '' }, ...typeOptions]"
-                        @change="onRefresh" title="选择类型">
+                    <ut-action-sheet v-model="form.downloadFlag"
+                        :tabs="[{ label: '全部', value: '' }, ...pt_code_downflag]" @change="onRefresh" title="选择类型">
                         <view class="d-flex search-select-item a-c">
                             <view class="flex1 ov-hd f-s-28 c-333 text-center f-w-5 w-s-no d-flex a-c j-c">
-                                <view class="w-s-no">{{ selectDictLabel(typeOptions, form.type) || '全部' }}</view>
+                                <view class="w-s-no">{{ selectDictLabel(pt_code_downflag, form?.downloadFlag) || '全部' }}
+                                </view>
                             </view>
                             <up-icon size="24rpx" color="#333" name="arrow-down-fill" class="mr-5"></up-icon>
                         </view>
@@ -23,7 +24,6 @@
                         borderRadius="10rpx"></ut-search>
                 </view>
             </view>
-
             <!-- 列表 -->
             <view class="pd-24">
                 <view v-for="(item, index) in list" :key="item.id || index">
@@ -57,22 +57,17 @@
 
 <script setup lang="ts">
 import { useClientRequest } from '@/utils/request';
+import { exportDataFn } from '@/utils/upload';
 import CodeItem from './models/code-item.vue';
 import GenerateDialog from './models/generate-dialog.vue';
-
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { pt_code_downflag } = toRefs<any>(proxy?.useDict('pt_code_downflag'));
 const paging = ref();
 const list = ref<any[]>([]);
 
-// 类型选项(可根据实际字典数据配置)
-const typeOptions = ref([
-    { label: '原料码', value: '1' },
-    { label: '半成品码', value: '2' },
-    { label: '成品码', value: '3' },
-]);
-
 // 搜索表单
 const form = ref({
-    type: '',
+    downloadFlag: '',
     keyword: '',
 });
 
@@ -93,12 +88,6 @@ const initSuspension = () => {
     sus.value.bottom = systemInfo.windowHeight - 200;
 };
 
-// 字典标签选择函数
-const selectDictLabel = (dict: any[], value: string | number) => {
-    const item = dict.find((item) => item.value == value);
-    return item ? item.label : '';
-};
-
 // 分页查询
 const query = async (pageNum: number, pageSize: number) => {
     const params = {
@@ -154,12 +143,26 @@ const handleRefresh = async (id: number) => {
 };
 
 // 处理下载按钮点击
-const handleDownload = (item: any) => {
-    console.log('下载:', item);
-    uni.showToast({
-        title: '下载功能开发中',
-        icon: 'none',
-    });
+const handleDownload = async (item: any) => {
+    if (!item.id) {
+        uni.showToast({
+            title: '缺少下载参数',
+            icon: 'none',
+        });
+        return;
+    }
+    try {
+        const downloadUrl = `/plt-api/app/traceCodeLog/download/${item.id}`;
+        await exportDataFn(
+            {
+                url: downloadUrl,
+                fileName: `traceCode_${item.id}.xlsx`,
+            },
+            '下载中',
+        );
+    } catch (error) {
+        console.error('下载失败:', error);
+    }
 };
 
 // 处理找人代制作按钮点击
@@ -180,13 +183,9 @@ const handleViewOrder = (item: any) => {
     });
 };
 
-// 处理重新下载按钮点击
+// 处理重新下载按钮点击(与下载使用同一接口)
 const handleReDownload = (item: any) => {
-    console.log('重新下载:', item);
-    uni.showToast({
-        title: '重新下载功能开发中',
-        icon: 'none',
-    });
+    handleDownload(item);
 };
 
 // 处理 item 点击

+ 17 - 14
src/plant/code/code-list/models/code-item.vue

@@ -1,12 +1,12 @@
 <template>
-    <view class="bg-#fff b-radius-16 pd-24 mb-16 p-rtv">
+    <view class="bg-#fff b-radius-16 pd-24 mb-16 p-rtv b-radius">
         <!-- 状态标签 -->
         <view class="d-flex a-c j-ed " style="position: absolute;right: 0;top: 0;">
-            <view class="bg-#EBF6EE c-primary f-w-5 pd-10 pt-4 pb-4 f-s-20" style="border-radius: 0 16rpx 0 16rpx ;"
+            <view class="bg-#FAECE9 c-#F74C30 f-w-5 pd-10 pt-4 pb-4 f-s-20" style="border-radius: 0 16rpx 0 16rpx ;"
                 v-if="item.status === '0'">追溯码生成中...</view>
             <view class="bg-#EBF6EE c-primary f-w-5 pd-10 pt-4 pb-4 f-s-20" style="border-radius: 0 16rpx 0 16rpx ;"
                 v-else-if="item.downloadFlag === '0' && item.status !== '0'">未下载</view>
-            <view class="bg-#EBF6EE c-primary f-w-5 pd-10 pt-4 pb-4 f-s-20" style="border-radius: 0 16rpx 0 16rpx ;"
+            <view class="bg-#E8F0F7 c-#2289E0 f-w-5 pd-10 pt-4 pb-4 f-s-20" style="border-radius: 0 16rpx 0 16rpx ;"
                 v-else-if="item.downloadFlag === '1' && item.status !== '0'">已下载</view>
         </view>
         <!-- 主要内容 -->
@@ -18,7 +18,7 @@
             <view class=" d-flex a-c pb-10">
                 <span class="f-s-28 c-#666 ">码段:</span>
                 <span class="f-s-28 c-#333 f-w-500 flex1">{{ formatCodeRange }}</span>
-                <up-icon name="arrow-right" size="26rpx" color="#999"></up-icon>
+                <up-icon v-if="showButtons" name="arrow-right" size="26rpx" color="#999"></up-icon>
             </view>
             <view class=" d-flex a-c pb-10">
                 <view class="w-50%">
@@ -29,7 +29,6 @@
                     <span class="f-s-28 c-#666 ">剩余数量:</span>
                     <span class="f-s-28 c-#333 f-w-500">{{ getRemainingCount }}个</span>
                 </view>
-
             </view>
             <view class=" d-flex a-c pb-10">
                 <span class="f-s-28 c-#666 ">备注:</span>
@@ -60,11 +59,11 @@
             </template>
             <!-- 未下载状态 -->
             <view class="d-flex j-ed a-c" v-else-if="item.downloadFlag === '0' && item.status !== '0'">
-                <up-button class="mr-16"
+                <!-- <up-button class="mr-16"
                     customStyle="height: 64rpx; font-size: 28rpx; border-radius: 8rpx; background-color: #18BECA; color: #fff; width: 200rpx;"
                     @click="handleFindAgent">
                     找人代制作
-                </up-button>
+                </up-button> -->
                 <up-button type="primary"
                     customStyle="height: 64rpx; font-size: 28rpx; border-radius: 8rpx; background-color: #37A954; color: #fff; width: 160rpx;"
                     @click="handleDownload">
@@ -73,19 +72,17 @@
             </view>
             <!-- 已下载状态 -->
             <view v-else-if="item.downloadFlag === '1' && item.status !== '0'" class="d-flex j-ed a-c">
-                <up-button class="mr-16"
-                    customStyle="height: 64rpx; font-size: 28rpx; border-radius: 8rpx; background-color: #18BECA; color: #fff;"
+                <!-- <up-button class="mr-16"
+                    customStyle="height: 64rpx; font-size: 28rpx; border-radius: 8rpx; background-color: #2289E0; color: #fff;"
                     @click="handleViewOrder">
                     查看代做订单
-                </up-button>
-                <up-button type="primary"
-                    customStyle="height: 64rpx; font-size: 28rpx; border-radius: 8rpx; background-color: #37A954; color: #fff;"
+                </up-button> -->
+                <up-button
+                    customStyle="height: 64rpx; font-size: 28rpx; border-radius: 8rpx; background-color: #91C747; color: #fff;"
                     @click="handleReDownload">
                     重新下载
                 </up-button>
             </view>
-
-
         </view>
     </view>
 </template>
@@ -183,6 +180,12 @@ const handleReDownload = () => {
 
 // 处理 item 点击
 const handleItemClick = () => {
+    // 跳转到码详情页面
+    uni.$u.route({
+        type: 'navigateTo',
+        url: '/plant/code/code-detail-list/index',
+        params: { id: props.item.id }
+    });
     emit('itemClick', props.item);
 };
 

+ 137 - 0
src/plant/models/warehouseCard/product-item.vue

@@ -0,0 +1,137 @@
+<template>
+    <view class="b-radius bg-#fff pd-20 p-rtv"
+        @click.stop="$u.route({ url: '/plant/storage/finished-product/detail/index', params: { id: item.id } })">
+        <!-- 顶部类型标签和日期 -->
+        <view class="d-flex j-sb a-c li-item-head mb-16">
+            <view :class="['li-left-tag', typeBgClass]">{{ typeName }}</view>
+            <view class="f-s-22 c-#666">{{ item?.packagingDate || '' }}</view>
+        </view>
+
+        <!-- 主标题和状态 -->
+        <view class="d-flex flex1 mb-10">
+            <view class="flex1">
+                <span class="f-s-34 c-#333 f-w-500 mr-10">{{ item?.variety || '' }}</span>
+                <span v-if="item?.level || item?.partName" class="f-s-24 c-#666">{{
+                    (item?.level || '') + (item?.partName || '')
+                    }}</span>
+            </view>
+            <view>
+                <!-- 成品已检/未检状态标签 -->
+                <view v-if="item?.isInspected" class="tag-span c-primary bg-#EBF6EE">成品已检</view>
+                <view v-else class="tag-span c-danger bg-#F9ECEA">成品未检</view>
+            </view>
+        </view>
+
+        <!-- 详细信息 -->
+        <view class="pd2-4-0 f-s-28 d-flex a-c">
+            <span class="c-#666">成品批号:</span>
+            <span class="c-#333 f-w-500 flex1">{{ item?.productBatchNo || '-' }}</span>
+            <up-icon name="arrow-right" size="24rpx" color="#333"></up-icon>
+        </view>
+
+        <view class="pd2-4-0 f-s-28">
+            <span class="c-#666">包装批号:</span>
+            <span class="c-#333 f-w-500">{{ item?.packagingBatchNo || '-' }}</span>
+        </view>
+
+        <view class="pd2-4-0 f-s-28">
+            <span class="c-#666">存放库房:</span>
+            <span class="c-#333 f-w-500">{{ item?.warehouseInfo || '-' }}</span>
+        </view>
+
+        <view class="pd2-4-0 f-s-28">
+            <span class="c-#666">入库量:</span>
+            <span class="c-#333 f-w-500">{{ item?.instoreAmount || '' }}{{ item?.unit || '' }}</span>
+        </view>
+
+        <!-- 剩余量(可能有多个) -->
+        <view v-for="(rest, idx) in restAmountList" :key="idx" class="d-flex mt-10">
+            <view class="pd2-4-0 f-s-28 flex1">
+                <span class="c-danger">剩余量:</span>
+                <span class="c-danger f-w-500">{{ rest.amount || '' }}{{ rest.unit || '' }}</span>
+            </view>
+        </view>
+    </view>
+</template>
+
+<script setup lang="ts">
+interface RestAmountItem {
+    amount?: string | number;
+    unit?: string;
+    packInfo?: string;
+}
+
+const props = defineProps({
+    item: {
+        type: Object as () => Record<string, any>,
+        default: () => ({})
+    }
+});
+
+const emit = defineEmits<{
+    click: [value: typeof props.item]
+}>();
+
+// 类型名称映射(根据数据结构变化可调整)
+const typeNameMap: Record<string, string> = {
+    '1': '药材',
+    '2': '鲜货',
+    '3': '种源'
+};
+
+const typeName = computed(() => {
+    const type = props.item?.instoreType || props.item?.typeName;
+    return typeNameMap[type] || '药材';
+});
+
+const typeBgClass = computed(() => `bg-instore-${props.item?.instoreType || '1'}`);
+
+// 剩余量列表(数据结构待定,暂留空数组)
+const restAmountList = computed<RestAmountItem[]>(() => {
+    // 预留数据结构,等待外部传入
+    // 期望格式:[{ amount: '50', unit: 'kg', packInfo: '袋*40 袋' }]
+    return [];
+});
+
+const handleClick = () => {
+    emit('click', props.item);
+};
+</script>
+
+<style lang="scss" scoped>
+.tag-span {
+    padding: 4rpx 12rpx;
+    font-size: 20rpx;
+    border-radius: 18rpx;
+}
+
+.li-item-head {
+    margin-left: -24rpx;
+    margin-top: -24rpx;
+}
+
+.li-left-tag {
+    padding: 6rpx 16rpx;
+    color: #fff;
+    border-radius: 16rpx 0 16rpx 0;
+    font-size: 20rpx;
+    font-weight: 500;
+}
+
+/* 类型标签背景色 */
+.bg-instore-1 {
+    background-color: #4CAF50;
+}
+
+/* 药材 - 绿色 */
+.bg-instore-2 {
+    background-color: #FF9800;
+}
+
+/* 鲜货 - 橙色 */
+.bg-instore-3 {
+    background-color: #2196F3;
+}
+
+/* 种源 - 蓝色 */
+</style>

+ 49 - 29
src/plant/processing/processing-create/index.vue

@@ -3,35 +3,41 @@
         <template #top>
             <ut-navbar :title="pageTitle" :fixed="false"> </ut-navbar>
         </template>
-        <view class="pt-24">
+        <view class="pt-24 pb-24">
             <up-form class="p-rtv" labelPosition="top" :model="form" :rules="rules" labelWidth="auto" ref="upFormRef">
                 <view class="bg-#fff pd-24 mb-20">
                     <!-- 加工方式 -->
                     <up-form-item borderBottom label="加工方式" required prop="processType">
-                        <view class="f-s-30 c-#666 f-w-5 flex1">{{ selectDictLabel(pt_process_type, form.processType) }}</view>
+                        <view class="f-s-30 c-#666 f-w-5 flex1">{{ selectDictLabel(pt_process_type, form.processType) }}
+                        </view>
                     </up-form-item>
                     <!-- 加工对象 -->
-                    <up-form-item v-if="+form.processType == 2" borderBottom label="加工对象" required prop="processMedType">
-                        <view class="f-s-30 c-#666 f-w-5 flex1">{{ selectDictLabel(pt_stock_type, form.processMedType) }}</view>
+                    <up-form-item v-if="+form.processType == 2" borderBottom label="加工对象" required
+                        prop="processMedType">
+                        <view class="f-s-30 c-#666 f-w-5 flex1">{{ selectDictLabel(pt_stock_type, form.processMedType)
+                        }}</view>
                     </up-form-item>
                     <!-- 加工对象 -->
                     <ut-action-sheet v-else v-model="form.processMedType" :tabs="pt_stock_type" title="选择加工对象">
                         <up-form-item borderBottom label="加工对象" required prop="processMedType">
-                            <view v-if="form?.processMedType" class="f-s-30 c-#333 f-w-5 flex1">{{ selectDictLabel(pt_stock_type, form.processMedType) }}</view>
+                            <view v-if="form?.processMedType" class="f-s-30 c-#333 f-w-5 flex1">{{
+                                selectDictLabel(pt_stock_type, form.processMedType) }}</view>
                             <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择加工对象</view>
                             <template #right>
                                 <up-icon size="22rpx" color="#37A954" name="arrow-down-fill"></up-icon>
                             </template>
                         </up-form-item>
                     </ut-action-sheet>
-                    <up-form-item v-if="+form?.processMedType == 1" @click="selectMedicine" borderBottom label="加工品种" required prop="varietyId">
+                    <up-form-item v-if="+form?.processMedType == 1" @click="selectMedicine" borderBottom label="加工品种"
+                        required prop="varietyId">
                         <view v-if="form.varietyName" class="f-s-30 c-333 f-w-5 flex1">{{ form.varietyName }}</view>
                         <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择加工品种</view>
                         <template #right>
                             <up-icon size="22rpx" color="#37A954" name="arrow-down-fill"></up-icon>
                         </template>
                     </up-form-item>
-                    <up-form-item v-if="+form?.processMedType == 2" @click="selectMedicine" borderBottom label="加工品种" required prop="medicineCode">
+                    <up-form-item v-if="+form?.processMedType == 2" @click="selectMedicine" borderBottom label="加工品种"
+                        required prop="medicineCode">
                         <view v-if="form.varietyName" class="f-s-30 c-333 f-w-5 flex1">{{ form.varietyName }}</view>
                         <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择加工品种</view>
                         <template #right>
@@ -42,27 +48,34 @@
                     <!-- 加工日期 -->
                     <up-form-item :borderBottom="false" label="加工日期" required>
                         <up-form-item :borderBottom="false" prop="processingDate">
-                            <ut-datetime-picker v-model="form.processingDate" mode="date" dateFields="day" @change="changeStartTime">
+                            <ut-datetime-picker v-model="form.processingDate" mode="date" dateFields="day"
+                                @change="changeStartTime">
                                 <view class="d-flex mr-20">
-                                    <up-input v-model="form.processingDate" readonly placeholder="请选择加工开始日期" border="bottom" :customStyle="{ paddingLeft: '0rpx' }"></up-input>
-                                    <up-icon size="22rpx" color="#37A954" name="arrow-down-fill" style="margin-left: -20rpx"></up-icon>
+                                    <up-input v-model="form.processingDate" readonly placeholder="请选择加工开始日期"
+                                        border="bottom" :customStyle="{ paddingLeft: '0rpx' }"></up-input>
+                                    <up-icon size="22rpx" color="#37A954" name="arrow-down-fill"
+                                        style="margin-left: -20rpx"></up-icon>
                                 </view>
                             </ut-datetime-picker>
                         </up-form-item>
                         <up-form-item :borderBottom="false" prop="processingDateEnd">
                             <ut-datetime-picker v-model="form.processingDateEnd" mode="date" dateFields="day">
                                 <view class="d-flex">
-                                    <up-input v-model="form.processingDateEnd" readonly placeholder="请选择加工结束日期" border="bottom" :customStyle="{ paddingLeft: '0rpx' }"></up-input>
-                                    <up-icon size="22rpx" color="#37A954" name="arrow-down-fill" style="margin-left: -20rpx"></up-icon>
+                                    <up-input v-model="form.processingDateEnd" readonly placeholder="请选择加工结束日期"
+                                        border="bottom" :customStyle="{ paddingLeft: '0rpx' }"></up-input>
+                                    <up-icon size="22rpx" color="#37A954" name="arrow-down-fill"
+                                        style="margin-left: -20rpx"></up-icon>
                                 </view>
                             </ut-datetime-picker>
                         </up-form-item>
                     </up-form-item>
 
-                    <up-form-item v-if="+form?.processType == 2" borderBottom label="是否属于趁鲜切制目录品种" required prop="freshCatalogueStatus">
+                    <up-form-item v-if="+form?.processType == 2" borderBottom label="是否属于趁鲜切制目录品种" required
+                        prop="freshCatalogueStatus">
                         <view class="d-flex a-c w-100%">
                             <up-radio-group v-model="form.freshCatalogueStatus">
-                                <up-radio :customStyle="{ marginRight: '60rpx' }" v-for="(item, index) in yes_no" :key="index" :label="item.label" :name="item.value"></up-radio>
+                                <up-radio :customStyle="{ marginRight: '60rpx' }" v-for="(item, index) in yes_no"
+                                    :key="index" :label="item.label" :name="item.value"></up-radio>
                             </up-radio-group>
                         </view>
                     </up-form-item>
@@ -70,8 +83,10 @@
                     <up-form-item v-if="+form?.processType == 2" borderBottom label="生产批号" required prop="processCode">
                         <view class="d-flex a-c j-sb w-100%">
                             <view class="flex1 d-flex">
-                                <up-input v-model="form.processCode" placeholder="请输入生产批号" border="none" clearable></up-input>
-                                <up-button @click="randomCode" class="c-#fff" type="primary" style="height: 50rpx; width: 130rpx">随机生成</up-button>
+                                <up-input v-model="form.processCode" placeholder="请输入生产批号" border="none"
+                                    clearable></up-input>
+                                <up-button @click="randomCode" class="c-#fff" type="primary"
+                                    style="height: 50rpx; width: 130rpx">随机生成</up-button>
                             </view>
                         </view>
                     </up-form-item>
@@ -79,16 +94,20 @@
                     <up-form-item v-else borderBottom label="加工批号" required prop="processCode">
                         <view class="d-flex a-c j-sb w-100%">
                             <view class="flex1 d-flex">
-                                <up-input v-model="form.processCode" placeholder="请输入加工批号" border="none" clearable></up-input>
-                                <up-button @click="randomCode" class="c-#fff" type="primary" style="height: 50rpx; width: 130rpx">随机生成</up-button>
+                                <up-input v-model="form.processCode" placeholder="请输入加工批号" border="none"
+                                    clearable></up-input>
+                                <up-button @click="randomCode" class="c-#fff" type="primary"
+                                    style="height: 50rpx; width: 130rpx">随机生成</up-button>
                             </view>
                         </view>
                     </up-form-item>
 
                     <!-- 加工执行标准 -->
-                    <ut-action-sheet v-if="+form?.processType == 1" v-model="form.standardType" :tabs="pt_standard_type" title="选择加工执行标准">
+                    <ut-action-sheet v-if="+form?.processType == 1" v-model="form.standardType" :tabs="pt_standard_type"
+                        title="选择加工执行标准">
                         <up-form-item borderBottom label="加工执行标准" required prop="standardType">
-                            <view v-if="form?.standardType" class="f-s-30 c-#333 f-w-5 flex1">{{ selectDictLabel(pt_standard_type, form.standardType) }}</view>
+                            <view v-if="form?.standardType" class="f-s-30 c-#333 f-w-5 flex1">{{
+                                selectDictLabel(pt_standard_type, form.standardType) }}</view>
                             <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择加工执行标准</view>
                             <template #right>
                                 <up-icon size="22rpx" color="#37A954" name="arrow-down-fill"></up-icon>
@@ -97,24 +116,28 @@
                     </ut-action-sheet>
                     <!-- 执行标准 -->
                     <up-form-item v-if="+form?.processType == 2" borderBottom label="执行标准" prop="standardDetailName">
-                        <up-input v-model="form.standardDetailName" placeholder="请输入执行标准" border="none" clearable></up-input>
+                        <up-input v-model="form.standardDetailName" placeholder="请输入执行标准" border="none"
+                            clearable></up-input>
                     </up-form-item>
                     <!-- 具体标准名称 -->
                     <up-form-item v-else borderBottom label="具体标准名称" prop="standardDetailName">
-                        <up-input v-model="form.standardDetailName" placeholder="请输入具体标准名称" border="none" clearable></up-input>
+                        <up-input v-model="form.standardDetailName" placeholder="请输入具体标准名称" border="none"
+                            clearable></up-input>
                     </up-form-item>
 
                     <!-- 加工负责人 -->
                     <up-form-item borderBottom label="加工负责人" required prop="contactName">
                         <view class="d-flex a-c j-sb w-100%">
-                            <up-input style="padding-left: 0" v-model="form.contactName" placeholder="请输入加工负责人" border="none"></up-input>
+                            <up-input style="padding-left: 0" v-model="form.contactName" placeholder="请输入加工负责人"
+                                border="none"></up-input>
                         </view>
                     </up-form-item>
 
                     <!-- 加工工艺及流程 -->
                     <up-form-item label="加工工艺及流程" prop="ptech">
                         <view class="w-100%">
-                            <view v-if="form?.ptech?.length !== 0" class="pd-24 d-flex flex-cln bg-#FBFDFB border-#37A954 b-radius p-rtv mb-20">
+                            <view v-if="form?.ptech?.length !== 0"
+                                class="pd-24 d-flex flex-cln bg-#FBFDFB border-#37A954 b-radius p-rtv mb-20">
                                 <view class="">
                                     <template v-for="(item, index) in form?.ptech?.split(',')" :key="index">
                                         <span v-if="index !== 0" class="c-#999 f-s-32 ml-10 mr-10">→ </span>
@@ -123,7 +146,8 @@
                                 </view>
                                 <view class="d-flex">
                                     <view class="flex1"></view>
-                                    <up-button type="primary" @click="goPtech" style="width: 130rpx; height: 60rpx; border-radius: 10rpx">选择工艺</up-button>
+                                    <up-button type="primary" @click="goPtech"
+                                        style="width: 130rpx; height: 60rpx; border-radius: 10rpx">选择工艺</up-button>
                                 </view>
                             </view>
                             <Go_button v-else @click="goPtech" title="请选择加工工艺及流程" style="flex: 1" />
@@ -417,10 +441,6 @@ onLoad((options: any) => {
 
 <style scoped lang="scss">
 .base-bottom-wrap {
-    position: fixed;
-    bottom: 0;
-    left: 0;
-    right: 0;
     background: #fff;
     padding: 24rpx;
     z-index: 99;

+ 55 - 24
src/plant/processing/processing-index/models/outputInfo.vue

@@ -1,6 +1,6 @@
 <template>
-    <up-popup :show="show" mode="bottom" @close="handleClose" :round="20" closeable>
-        <view class="d-flex flex-cln" style="max-height: 70vh">
+    <up-popup :show="show" mode="bottom" @close="handleClose" :round="20" closeable safeAreaInsetBottom>
+        <view class="d-flex flex-cln">
             <view class="f-s-34 f-w-5 pd-24 pb-16">{{ getTitle() }}</view>
             <scroll-view scroll-y class="flex1" style="max-height: 70vh">
                 <view class="pd-24">
@@ -9,10 +9,15 @@
                             <!-- 规格等级 -->
                             <up-form-item label="规格等级" required prop="specnLevel">
                                 <view class="flex1" @click="goToSpecLevel">
-                                    <up-input readonly v-model="formData.specnLevel" type="number" placeholder="请选择规格等级" style="padding-left: 0; padding-right: 0" border="bottom" clearable suffixIcon="arrow-down-fill" suffixIconStyle="color: #2A6D52;font-size: 22rpx"> </up-input>
+                                    <up-input readonly v-model="formData.specnLevel" type="number" placeholder="请选择规格等级"
+                                        style="padding-left: 0; padding-right: 0" border="bottom" clearable
+                                        suffixIcon="arrow-down-fill" suffixIconStyle="color: #2A6D52;font-size: 22rpx">
+                                    </up-input>
                                 </view>
                                 <view class="ml-20">
-                                    <up-checkbox :customStyle="{ marginBottom: '8px' }" label="统货" name="agree" usedAlone :checked="formData.specnLevel == '统货'" @change="handleSpecnLevelChange"> </up-checkbox>
+                                    <up-checkbox :customStyle="{ marginBottom: '8px' }" label="统货" name="agree"
+                                        usedAlone :checked="formData.specnLevel == '统货'"
+                                        @change="handleSpecnLevelChange"> </up-checkbox>
                                 </view>
                             </up-form-item>
                             <!-- 产量 -->
@@ -20,7 +25,8 @@
                                 <view class="flex1 d-flex">
                                     <view class="flex1 ov-hd" id="capacitypppp">
                                         <up-form-item border-bottom prop="capacity" class="form-item-top-padding-0">
-                                            <up-input v-model="formData.capacity" type="number" placeholder="请输入产量" border="none" clearable></up-input>
+                                            <up-input v-model="formData.capacity" type="number" placeholder="请输入产量"
+                                                border="none" clearable></up-input>
                                         </up-form-item>
                                     </view>
                                     <view class="pd-5"></view>
@@ -28,11 +34,13 @@
                                         <ut-action-sheet v-model="formData.unit" :tabs="pt_out_put_unit" title="选择单位">
                                             <up-form-item border-bottom prop="unit" class="form-item-top-padding-0">
                                                 <view class="flex1" style="line-height: 24px">
-                                                    <view v-if="formData?.unit" class="f-s-30 c-#333 f-w-5 flex1">{{ formData?.unit }}</view>
+                                                    <view v-if="formData?.unit" class="f-s-30 c-#333 f-w-5 flex1">{{
+                                                        formData?.unit }}</view>
                                                     <view v-else class="f-s-30 c-ccc f-w-4 flex1">单位</view>
                                                 </view>
                                                 <template #right>
-                                                    <up-icon size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
+                                                    <up-icon size="22rpx" color="#2A6D52"
+                                                        name="arrow-down-fill"></up-icon>
                                                 </template>
                                             </up-form-item>
                                         </ut-action-sheet>
@@ -41,12 +49,14 @@
                             </up-form-item>
                             <!-- 产出物图片 -->
                             <up-form-item borderBottom label="产出物图片">
-                                <ut-upload v-model="formData.imgs" :max-count="6" valueType="array" accept="image" width="210rpx" height="210rpx" style="card"></ut-upload>
+                                <ut-upload v-model="formData.imgs" :max-count="6" valueType="array" accept="image"
+                                    width="210rpx" height="210rpx" style="card"></ut-upload>
                             </up-form-item>
 
                             <!-- 检验报告 -->
                             <up-form-item borderBottom label="加工检验报告">
-                                <ut-upload v-model="formData.examinReport" :max-count="50" valueType="array" accept="image,file" width="210rpx" height="210rpx" style="card"></ut-upload>
+                                <ut-upload v-model="formData.examinReport" :max-count="50" valueType="array"
+                                    accept="image,file" width="210rpx" height="210rpx" style="card"></ut-upload>
                             </up-form-item>
                         </template>
 
@@ -55,10 +65,15 @@
                             <!-- 规格等级 -->
                             <up-form-item label="规格等级" required prop="specnLevel">
                                 <view class="flex1" @click="goToSpecLevel">
-                                    <up-input readonly v-model="formData.specnLevel" type="number" placeholder="请选择规格等级" style="padding-left: 0; padding-right: 0" border="bottom" clearable suffixIcon="arrow-down-fill" suffixIconStyle="color: #2A6D52;font-size: 22rpx"> </up-input>
+                                    <up-input readonly v-model="formData.specnLevel" type="number" placeholder="请选择规格等级"
+                                        style="padding-left: 0; padding-right: 0" border="bottom" clearable
+                                        suffixIcon="arrow-down-fill" suffixIconStyle="color: #2A6D52;font-size: 22rpx">
+                                    </up-input>
                                 </view>
                                 <view class="ml-20">
-                                    <up-checkbox :customStyle="{ marginBottom: '8px' }" label="统货" name="agree" usedAlone :checked="formData.specnLevel == '统货'" @change="handleSpecnLevelChange"> </up-checkbox>
+                                    <up-checkbox :customStyle="{ marginBottom: '8px' }" label="统货" name="agree"
+                                        usedAlone :checked="formData.specnLevel == '统货'"
+                                        @change="handleSpecnLevelChange"> </up-checkbox>
                                 </view>
                             </up-form-item>
                             <!-- 产量 -->
@@ -66,7 +81,8 @@
                                 <view class="flex1 d-flex">
                                     <view class="flex1 ov-hd" id="capacitypppp">
                                         <up-form-item border-bottom prop="capacity" class="form-item-top-padding-0">
-                                            <up-input v-model="formData.capacity" type="number" placeholder="请输入产量" border="none" clearable></up-input>
+                                            <up-input v-model="formData.capacity" type="number" placeholder="请输入产量"
+                                                border="none" clearable></up-input>
                                         </up-form-item>
                                     </view>
                                     <view class="pd-5"></view>
@@ -74,11 +90,13 @@
                                         <ut-action-sheet v-model="formData.unit" :tabs="pt_out_put_unit" title="选择单位">
                                             <up-form-item border-bottom prop="unit" class="form-item-top-padding-0">
                                                 <view class="flex1" style="line-height: 24px">
-                                                    <view v-if="formData?.unit" class="f-s-30 c-#333 f-w-5 flex1">{{ formData?.unit }}</view>
+                                                    <view v-if="formData?.unit" class="f-s-30 c-#333 f-w-5 flex1">{{
+                                                        formData?.unit }}</view>
                                                     <view v-else class="f-s-30 c-ccc f-w-4 flex1">单位</view>
                                                 </view>
                                                 <template #right>
-                                                    <up-icon size="22rpx" color="#37A954" name="arrow-down-fill"></up-icon>
+                                                    <up-icon size="22rpx" color="#37A954"
+                                                        name="arrow-down-fill"></up-icon>
                                                 </template>
                                             </up-form-item>
                                         </ut-action-sheet>
@@ -88,7 +106,9 @@
                             <!-- 切制形态 -->
                             <ut-action-sheet v-model="formData.finalFormType" :tabs="pt_final_form_type" title="选择切制形态">
                                 <up-form-item borderBottom label="切制形态" prop="finalFormType" required>
-                                    <view v-if="formData?.finalFormType" class="f-s-30 c-#333 f-w-5 flex1">{{ selectDictLabel(pt_final_form_type, formData?.finalFormType) }}</view>
+                                    <view v-if="formData?.finalFormType" class="f-s-30 c-#333 f-w-5 flex1">{{
+                                        selectDictLabel(pt_final_form_type,
+                                            formData?.finalFormType) }}</view>
                                     <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择切制形态</view>
                                     <template #right>
                                         <up-icon size="22rpx" color="#37A954" name="arrow-down-fill"></up-icon>
@@ -97,7 +117,8 @@
                             </ut-action-sheet>
                             <!-- 具体切制形态 -->
                             <up-form-item borderBottom label="具体切制形态" prop="finalFormOther" required>
-                                <up-input v-model="formData.finalFormOther" placeholder="请输入具体切制形态" border="none" clearable></up-input>
+                                <up-input v-model="formData.finalFormOther" placeholder="请输入具体切制形态" border="none"
+                                    clearable></up-input>
                             </up-form-item>
 
                             <!-- 切制尺寸 -->
@@ -105,19 +126,25 @@
                                 <view class="flex1 d-flex">
                                     <view class="flex1 ov-hd" id="finalSpecnpppp">
                                         <up-form-item border-bottom prop="finalSpecn" class="form-item-top-padding-0">
-                                            <up-input v-model="formData.finalSpecn" type="number" placeholder="请输入切制尺寸" border="none" clearable></up-input>
+                                            <up-input v-model="formData.finalSpecn" type="number" placeholder="请输入切制尺寸"
+                                                border="none" clearable></up-input>
                                         </up-form-item>
                                     </view>
                                     <view class="pd-5"></view>
                                     <view class="min-w-100">
-                                        <ut-action-sheet v-model="formData.finalUnit" :tabs="pt_final_unit" title="选择切制单位">
-                                            <up-form-item border-bottom prop="finalUnit" class="form-item-top-padding-0">
+                                        <ut-action-sheet v-model="formData.finalUnit" :tabs="pt_final_unit"
+                                            title="选择切制单位">
+                                            <up-form-item border-bottom prop="finalUnit"
+                                                class="form-item-top-padding-0">
                                                 <view class="flex1" style="line-height: 24px">
-                                                    <view v-if="formData?.finalUnit" class="f-s-30 c-#333 f-w-5 flex1">{{ selectDictLabel(pt_final_unit, formData?.finalUnit) }}</view>
+                                                    <view v-if="formData?.finalUnit" class="f-s-30 c-#333 f-w-5 flex1">
+                                                        {{
+                                                            selectDictLabel(pt_final_unit, formData?.finalUnit) }}</view>
                                                     <view v-else class="f-s-30 c-ccc f-w-4 flex1">单位</view>
                                                 </view>
                                                 <template #right>
-                                                    <up-icon size="22rpx" color="#37A954" name="arrow-down-fill"></up-icon>
+                                                    <up-icon size="22rpx" color="#37A954"
+                                                        name="arrow-down-fill"></up-icon>
                                                 </template>
                                             </up-form-item>
                                         </ut-action-sheet>
@@ -126,22 +153,26 @@
                             </up-form-item>
                             <!-- 产出物图片 -->
                             <up-form-item borderBottom label="产出物图片">
-                                <ut-upload v-model="formData.imgs" :max-count="6" valueType="array" accept="image" width="210rpx" height="210rpx" style="card"></ut-upload>
+                                <ut-upload v-model="formData.imgs" :max-count="6" valueType="array" accept="image"
+                                    width="210rpx" height="210rpx" style="card"></ut-upload>
                             </up-form-item>
 
                             <!-- 检验报告 -->
                             <up-form-item borderBottom label="加工检验报告">
-                                <ut-upload v-model="formData.examinReport" :max-count="50" valueType="array" accept="image,file" width="210rpx" height="210rpx" style="card"></ut-upload>
+                                <ut-upload v-model="formData.examinReport" :max-count="50" valueType="array"
+                                    accept="image,file" width="210rpx" height="210rpx" style="card"></ut-upload>
                             </up-form-item>
                         </template>
                     </up-form>
                 </view>
                 <!-- 底部按钮 -->
+            </scroll-view>
+            <template #bottom>
                 <view class="d-flex gap-20 pd-24">
                     <up-button plain type="info" @click="handleClose">取消</up-button>
                     <up-button type="primary" @click="handleSubmit">确认</up-button>
                 </view>
-            </scroll-view>
+            </template>
         </view>
     </up-popup>
 </template>

+ 311 - 0
src/plant/storage/finished-product/detail/index.vue

@@ -0,0 +1,311 @@
+<template>
+    <z-paging ref="paging" bgColor="#F7F7F7" safe-area-inset-bottom paging-class="paging-btm-shadow"
+        scroll-with-animation>
+        <template #top>
+            <ut-navbar title="成品详情" :fixed="false" border></ut-navbar>
+        </template>
+
+        <template>
+            <view class="pd-24 d-flex a-c">
+                <view class="flex1 ov-hd">
+                    <view class="startline-title">库存信息</view>
+                </view>
+                <view>
+                    <up-button @click="navigateToInOutRecords" type="primary" :customStyle="formItemBtnStyle">
+                        <image class="w-30 h-30 mr-10"
+                            src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/storage/ckcrkjl_icon.png"
+                            mode="widthFix" />
+                        <span>查看出入库记录</span>
+                    </up-button>
+                </view>
+            </view>
+            <view class="bg-#fff pd-24">
+                <view class="d-flex j-sb a-c li-item-head mb-16">
+                    <view class="li-left-tag" :class="{ [`bg-instore-${form?.instoreType}`]: true }">{{
+                        selectDictLabel(pt_seed_instore_type, form?.instoreType) }}</view>
+                    <view class="f-s-22 c-#666">{{ form?.instoreBizInfo?.instoreDate }}</view>
+                </view>
+                <view class="mb-10">
+                    <span class="f-s-34 c-#333 f-w-500 mr-10">{{ form?.variety }}</span>
+                    <span v-if="form?.partName" class="f-s-24 c-#666">{{ form?.level || '' }}{{ form?.partName }}</span>
+                </view>
+                <template v-if="form?.instoreType == '2'">
+                    <view class="pd2-4-0 f-s-28">
+                        <span class="c-#666">入库批号:</span>
+                        <span class="c-#333 f-w-500">{{ form?.batchCode || '-' }}</span>
+                    </view>
+                    <view v-if="form?.supplierId" class="pd2-4-0 f-s-28">
+                        <span class="c-#666">供应商:</span>
+                        <span class="c-#333 f-w-500">{{ form?.supplierInfo?.cusName || '-' }}</span>
+                    </view>
+                </template>
+                <template v-if="form?.instoreType == '3'">
+                    <view class="pd2-4-0 f-s-28">
+                        <span class="c-#666">采收批号:</span>
+                        <span class="c-#333 f-w-500">{{ form?.harvestInfo?.harvestCode || '-' }}</span>
+                    </view>
+                    <view class="pd2-4-0 f-s-28">
+                        <span class="c-#666">采收基地:</span>
+                        <span class="c-#333 f-w-500">
+                            {{ form?.harvestInfo?.baseInfo?.baseName || '-' }}
+                        </span>
+                    </view>
+                </template>
+                <view v-if="form?.warehouses?.length" class="pd2-4-0 f-s-28">
+                    <span class="c-#666">存放库房:</span>
+                    <span class="c-#333 f-w-500">{{ getStorageRoomNames(form?.warehouses) || '-' }}</span>
+                </view>
+                <view class="pd2-4-0 f-s-28">
+                    <span class="c-#666">入库量:</span>
+                    <span class="c-#333 f-w-500">{{ form?.capacity }}{{ form?.unit }}</span>
+                </view>
+                <view class="d-flex">
+                    <view v-if="form?.inputAmount" class="pd2-4-0 f-s-28 flex1">
+                        <span class="c-#666">出库量:</span>
+                        <span class="c-#333 f-w-500">{{ form?.inputAmount || '0' }}{{ form?.unit }}</span>
+                    </view>
+                    <view v-if="form?.restAmount" class="pd2-4-0 f-s-28 flex1">
+                        <span class="c-primary">剩余量:</span>
+                        <span class="c-primary f-w-500">{{ form?.restAmount || '0' }}{{ form?.unit }}</span>
+                    </view>
+                </view>
+                <view v-if="+form?.restAmount" class="pd3-20-40-0">
+                    <up-button @click="navigateToInventoryLoss" type="warning" plain
+                        :customStyle="{ background: '#FFF9EF', borderColor: '#F9D9A3' }">库存有消耗?库存损耗登记{{ '>'
+                        }}</up-button>
+                </view>
+            </view>
+            <view class="pd-24">
+                <view class="startline-title">成品信息</view>
+            </view>
+            <view class="bg-#fff pd-24">
+                <!-- 成品信息详情 -->
+                <view class="f-s-30 pd2-16-0 info-border-bottom">
+                    <view class="c-#666 mb-10">动植物名称:</view>
+                    <view v-if="form?.varietyInfo" class="bg-#FBFDFB card-info-block pd-24 p-rtv">
+                        <view class="mb-10">
+                            <span class="f-s-34 c-#333 f-w-5 mr-16">{{ form?.varietyInfo?.varietyName || '-' }}</span>
+                            <span class="f-s-24 c-#666">{{ form?.varietyInfo?.latinName || '' }}</span>
+                        </view>
+                        <view class="mb-10">
+                            <span class="f-s-28 c-#333 f-w-5 mr-16">{{ form?.varietyInfo?.genusName || '' }}</span>
+                            <span class="f-s-24 c-#666">{{ form?.varietyInfo?.genusLatinName || '' }}</span>
+                        </view>
+                        <view class="f-s-24 c-#666" v-if="form?.varietyInfo?.medicineName">产出:{{
+                            form?.varietyInfo?.medicineName }}
+                        </view>
+                    </view>
+                    <view v-else class="c-#333 f-w-600">{{ form?.variety || '-' }}</view>
+                </view>
+
+                <view class="f-s-30 pd2-16-0 info-border-bottom">
+                    <span class="c-#666">药用部位/对象:</span>
+                    <span class="c-#333 f-w-600">{{ form?.partName || form?.part || '-' }}</span>
+                </view>
+
+                <view class="f-s-30 pd2-16-0 info-border-bottom">
+                    <span class="c-#666">鲜货来源:</span>
+                    <span class="c-#333 f-w-600">{{ selectDictLabel(pt_medicine_source_tag, form?.sourceType) || '-'
+                    }}</span>
+                </view>
+
+                <view class="f-s-30 pd2-16-0 info-border-bottom">
+                    <span class="c-#666">入库量:</span>
+                    <span class="c-#333 f-w-600">{{ form?.capacity || '-' }}{{ selectDictLabel(pt_medicine_unit,
+                        form?.unit) ||
+                        form?.unit || '' }}</span>
+                </view>
+
+                <view class="f-s-30 pd2-16-0 info-border-bottom">
+                    <span class="c-#666">鲜货产地:</span>
+                    <span class="c-#333 f-w-600">{{ form?.producePlaceName || form?.producePlace || '-' }}</span>
+                </view>
+
+                <view v-if="form?.instoreType == '2'" class="f-s-30 pd2-16-0 info-border-bottom">
+                    <span class="c-#666">采收日期:</span>
+                    <span class="c-#333 f-w-600">{{ form?.productDate || '-' }}~{{ form?.productDateEnd || '-' }}</span>
+                </view>
+
+                <template v-if="['2'].includes(form?.sourceType as string)">
+                    <view class="f-s-30 pd2-16-0 info-border-bottom">
+                        <span class="c-#666">供应商:</span>
+                        <span class="c-#333 f-w-600">{{ form?.supplier || form?.supplierInfo?.cusName || '-' }}</span>
+                    </view>
+                    <view class="f-s-30 pd2-16-0 info-border-bottom">
+                        <span class="c-#666">供应商是否是生产商:</span>
+                        <span class="c-#333 f-w-600">{{ selectDictLabel(yes_no, form?.supplierProducerFlag) || '-'
+                        }}</span>
+                    </view>
+                    <view class="f-s-30 pd2-16-0 info-border-bottom">
+                        <span class="c-#666">生产商:</span>
+                        <span class="c-#333 f-w-600">{{ form?.producer || '-' }}</span>
+                    </view>
+                </template>
+
+                <view v-if="form?.imgs" class="f-s-30 pd2-16-0 info-border-bottom">
+                    <view class="c-#666 mb-10">鲜货图片:</view>
+                    <ut-album :urls="form?.imgs"></ut-album>
+                </view>
+                <view v-if="form?.vedios" class="f-s-30 pd2-16-0 info-border-bottom">
+                    <view class="c-#666 mb-10">鲜货视频:</view>
+                    <ut-album :urls="form?.vedios"></ut-album>
+                </view>
+                <view v-if="form?.examinReport && form?.examinReport.length" class="f-s-30 pd2-16-0 info-border-bottom">
+                    <view class="c-#666 mb-10">检验报告:</view>
+                    <ut-album :urls="form?.examinReport"></ut-album>
+                </view>
+            </view>
+            <view class="pd-24">
+                <view class="startline-title">入库信息</view>
+            </view>
+            <view class="bg-#fff pd-24">
+                <view class="f-s-30 pd2-16-0 info-border-bottom">
+                    <span class="c-#666">鲜货级别:</span>
+                    <span class="c-#333 f-w-600">{{ form?.level || '-' }}</span>
+                </view>
+                <view class="f-s-30 pd2-16-0 info-border-bottom">
+                    <span class="c-#666">入库类型:</span>
+                    <span class="c-#333 f-w-600">{{ selectDictLabel(pt_seed_instore_type, form?.instoreType) || '-'
+                    }}</span>
+                </view>
+                <template v-if="form.instoreType == '2'">
+                    <view class="f-s-30 pd2-16-0 info-border-bottom">
+                        <span class="c-#666">入库日期:</span>
+                        <span class="c-#333 f-w-600">{{ form?.instoreBizInfo?.instoreDate || '-' }}</span>
+                    </view>
+                    <view class="f-s-30 pd2-16-0 info-border-bottom">
+                        <span class="c-#666">入库批号:</span>
+                        <span class="c-#333 f-w-600">{{ form?.batchCode || '-' }}</span>
+                    </view>
+                </template>
+                <view class="f-s-30 pd2-16-0 info-border-bottom">
+                    <span class="c-#666">库房类型:</span>
+                    <span class="c-#333 f-w-600">鲜货库</span>
+                </view>
+                <view v-if="form?.warehouses?.length" class="pd2-4-0 f-s-28">
+                    <span class="c-#666">存放库房:</span>
+                    <span class="c-#333 f-w-500">{{ getStorageRoomNames(form?.warehouses) || '-' }}</span>
+                </view>
+                <view class="f-s-30 pd2-16-0 info-border-bottom">
+                    <span class="c-#666">入库人:</span>
+                    <span class="c-#333 f-w-600">{{ form?.instoreBizInfo?.instoreMg || '-' }}</span>
+                </view>
+                <view class="f-s-30 pd2-16-0 info-border-bottom">
+                    <span class="c-#666">入库备注:</span>
+                    <span class="c-#333 f-w-600">{{ form?.instoreBizInfo?.remark || '-' }}</span>
+                </view>
+                <view class="f-s-30 pd2-16-0 info-border-bottom">
+                    <span class="c-#666">最后修改人:</span>
+                    <span class="c-#333 f-w-600">{{ form?.operatorName || form?.updateByName || form?.createByName ||
+                        '-' }}</span>
+                </view>
+                <view class="f-s-30 pd2-16-0 info-border-bottom">
+                    <span class="c-#666">最后修改时间:</span>
+                    <span class="c-#333 f-w-600">{{ form?.operateTime || form?.updateTime || form?.createTime || '-'
+                    }}</span>
+                </view>
+            </view>
+        </template>
+        <template #bottom>
+            <view class="pd-24 d-flex a-c">
+                <up-button type="primary" @click="clickEdit">修改</up-button>
+            </view>
+        </template>
+    </z-paging>
+</template>
+
+<script setup lang="ts">
+import { formItemBtnStyle } from '@/assets/styles/uview-plus';
+import { getStorageRoomNames } from '@/utils/common';
+import { useClientRequest } from '@/utils/request';
+import { selectDictListClass } from '@/utils/ruoyi';
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+
+const { pt_seed_instore_type, yes_no, pt_medicine_source_tag, pt_medicine_unit } = toRefs<any>(proxy?.useDict('pt_seed_instore_type', 'yes_no', 'pt_medicine_source_tag', 'pt_medicine_unit'));
+const paging = ref<any>(null);
+const form = ref<any>({});
+const did = ref('');
+
+// 繁衍世代显示文案
+const genCountMap = reactive({
+    A4: '累计扩繁代数',
+    A3: '继代培养次数',
+});
+
+// 获取详情(仓库信息)
+const getDetailById = async (id: string) => {
+    if (!id) return;
+    const res = await useClientRequest.get(`/plt-api/app/storage/getInfo/${id}`);
+    if (res && res.code === 200) {
+        form.value = res.data || {};
+    }
+};
+const navigateToInOutRecords = () => {
+    uni.$u.route({
+        type: 'navigateTo',
+        url: '/plant/storage/stock-list/index',
+        params: {
+            id: did.value,
+            stockType: '4',
+        },
+    });
+};
+const navigateToInventoryLoss = () => {
+    uni.$on('storage-registered', () => {
+        getDetailById(did.value);
+        uni.$emit('refreshStorageRoomList');
+        uni.$off('storage-registered');
+    });
+    uni.navigateTo({
+        url: '/plant/storage/loss-register/index',
+        success: (res) => {
+            res.eventChannel.emit('storage-data', {
+                stockType: '4',
+                ...form.value,
+            });
+        },
+    });
+};
+const onRefresh = () => {
+    getDetailById(did.value);
+    paging.value?.complete();
+};
+const clickEdit = () => {
+    uni.$on('fresh-goods-detail-refresh', () => {
+        getDetailById(did.value);
+        uni.$off('fresh-goods-detail-refresh');
+    });
+    uni.$u.route({
+        type: 'navigateTo',
+        url: '/plant/storage/fresh-goods/info-update/index',
+        params: {
+            id: did.value,
+        },
+    });
+};
+// 页面入参解析并加载
+onLoad((options: any) => {
+    did.value = options?.id || '';
+    getDetailById(did.value);
+});
+</script>
+
+<style lang="scss" scoped>
+.card-info-block {
+    border: 1rpx solid #afddbb;
+    border-radius: 10rpx;
+}
+
+.li-item-head {
+    margin-left: -24rpx;
+    margin-top: -24rpx;
+}
+
+.li-left-tag {
+    padding: 6rpx 16rpx;
+    color: #fff;
+    border-radius: 0 0 16rpx 0;
+    font-size: 20rpx;
+    font-weight: 500;
+}
+</style>

+ 165 - 0
src/plant/storage/finished-product/list/index.vue

@@ -0,0 +1,165 @@
+<template>
+    <z-paging ref="paging" v-model="list" bgColor="#f7f7f7" @query="query" hide-no-more-inside>
+        <template #top>
+            <ut-navbar title="成品库" :fixed="false" :breadcrumb="false"></ut-navbar>
+        </template>
+        <view class="pd3-24-24-0">
+            <view class="mb-20">
+                <ut-tabs mode="subsection" v-model="form.restFlag" :tabs="tabs" @change="onRefresh"></ut-tabs>
+            </view>
+            <view class="d-flex a-c">
+                <view class="min-w-230 flex1">
+                    <ut-action-sheet v-model="form.instoreType" :tabs="tabs_pt_fresh_instore_type" mode="custom"
+                        @change="onRefresh" title="选择入库类型">
+                        <view class="d-flex search-select-item a-c">
+                            <view class="flex1 ov-hd f-s-28 c-333 text-center f-w-5 w-s-no">{{
+                                selectDictLabel(pt_fresh_instore_type, form.instoreType) || '全部' }} </view>
+                            <up-icon size="24rpx" color="#333" name="arrow-down-fill" class="mr-5"></up-icon>
+                        </view>
+                    </ut-action-sheet>
+                </view>
+                <view class="h-86 pl-20 w-100%">
+                    <ut-search ref="searchRef" v-model="form.keyword" @search="changeSeach" margin="0" :border="false"
+                        placeholder="搜名称、批号、库房、供应商" bgColor="#fff" height="86rpx" borderRadius="10rpx"></ut-search>
+                </view>
+            </view>
+            <view></view>
+        </view>
+        <view class="pd-24 bg-#f7f7f7">
+            <up-swipe-action>
+                <up-swipe-action-item v-for="(item, index) in list" :key="index" :name="item?.id"
+                    :options="optionsActionTemp" @click="clickTempSwipe($event, item)" class="mb-20 b-radius">
+                    <product-item :item="item" />
+                </up-swipe-action-item>
+            </up-swipe-action>
+        </view>
+        <template #empty>
+            <view class="d-flex flex-cln a-c" style="margin-top: -200rpx">
+                <ut-empty class="mg-at" color="#ccc" size="28rpx">暂无成品信息,点击下方+号新增吧</ut-empty>
+            </view>
+        </template>
+        <template #bottom>
+            <fresh-goods-bottom></fresh-goods-bottom>
+        </template>
+    </z-paging>
+</template>
+<script setup lang="ts">
+import { useClientRequest } from '@/utils/request';
+import { selectDictListClass } from '@/utils/ruoyi';
+import { getStorageRoomNames } from '@/utils/common';
+import FreshGoodsBottom from './model/fresh-goods-bottom.vue';
+import ProductItem from '@/plant/models/warehouseCard/product-item.vue'
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { pt_fresh_instore_type } = toRefs<any>(proxy?.useDict('pt_fresh_instore_type'));
+const list = ref<any[]>();
+const form = ref({ keyword: '', restFlag: '1', instoreType: '', storageType: '3' });
+const paging = ref();
+const tabs = ref([
+    { label: '有库存', value: '1' },
+    { label: '无库存', value: '0' },
+]);
+const tabs_pt_fresh_instore_type = computed(() => {
+    return [{ label: '全部', value: '' }, ...pt_fresh_instore_type.value].filter((item: any) => item.value != '4');
+});
+const changeSeach = () => {
+    paging.value.reload();
+};
+const query = async (pageNum: number, pageSize: number) => {
+    const params = {
+        pageNum,
+        pageSize,
+        ...form.value,
+    };
+    const res = await useClientRequest.get('/plt-api/app/storage/list', params);
+    if (res) {
+        const { rows } = res;
+        paging.value.complete(rows);
+    }
+};
+// 暂存项左滑删除配置
+const optionsActionTemp = reactive([
+    {
+        text: '删除',
+        style: {
+            backgroundColor: '#F74C30',
+        },
+    },
+]);
+// 暂存项删除点击(本地移除)
+const clickTempSwipe = async (event: object, item: any) => {
+    const { name, index } = event as any;
+    if (index === 0) {
+        if (item.instoreType == '3') {
+            return uni.showModal({
+                title: '提示',
+                content: '该批次为采收入库的种源,请前往种养殖-采收管理里删除采收记录,入库记录将同步删除。',
+                showCancel: false,
+                confirmText: '知道了',
+                confirmColor: '#41c06d',
+            });
+        }
+        try {
+            const res = await uni.showModal({
+                title: '删除提示',
+                content: '确定删除鲜货信息吗?',
+                confirmColor: '#F74C30',
+            });
+            if (!res.confirm) return;
+            await uni.showLoading({
+                title: '删除中...',
+                mask: true,
+            });
+            await useClientRequest.get(`/plt-api/app/storage/removeById/${name}`);
+            uni.hideLoading();
+            uni.showToast({
+                title: '删除成功',
+                icon: 'success',
+            });
+            paging.value?.reload();
+        } catch (error) {
+            console.error('删除暂存鲜货信息失败:', error);
+        }
+    }
+};
+
+const onRefresh = () => {
+    try {
+        paging.value?.reload();
+    } catch (error) {
+        console.error('刷新列表失败:', error);
+    }
+};
+onMounted(() => {
+    uni.$on('refreshStorageRoomList', () => {
+        onRefresh();
+    });
+});
+</script>
+<style lang="scss" scoped>
+.search-select-item {
+    height: 86rpx;
+    background-color: #fff;
+    border-radius: 10rpx;
+    box-sizing: border-box;
+    padding: 12rpx;
+}
+
+.tag-span {
+    padding: 4rpx 12rpx;
+    font-size: 20rpx;
+    border-radius: 18rpx;
+}
+
+.li-item-head {
+    margin-left: -24rpx;
+    margin-top: -24rpx;
+}
+
+.li-left-tag {
+    padding: 6rpx 16rpx;
+    color: #fff;
+    border-radius: 16rpx 0 16rpx 0;
+    font-size: 20rpx;
+    font-weight: 500;
+}
+</style>

+ 141 - 0
src/plant/storage/finished-product/list/model/fresh-goods-bottom.vue

@@ -0,0 +1,141 @@
+<template>
+    <view class="source-bottom-fixed">
+        <view class="source-top-view h-49"></view>
+        <view class="source-bottom-view pt-49 text-center bg-#fff pt-60"
+            :style="{ opacity: btnStyle == 'close' ? 0 : 1 }">
+            <view style="opacity: 0;">{{ mapTextBtn[btnStyle] }}</view>
+
+        </view>
+        <view @click="clickBtnBall" class="source-center-view d-flex flex-cln a-c j-c">
+            <view class="source-btn-ball d-flex a-c j-c" :class="{ [`btn-deg-${btnStyle}`]: true }"
+                :style="{ backgroundImage: 'url(https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/storage/add_c_btn.png)' }">
+            </view>
+            <view class="c-primary f-s-28 pt-6">{{ mapTextBtn[btnStyle] }}</view>
+
+        </view>
+        <view class="bg-#fff" :style="{ height: safeAreaBottom + 'px' }"></view>
+        <view class="bottom-circle-line" :class="{ 'bottom-circle-line-active': btnStyle == 'close' }"
+            :style="{ bottom: safeAreaBottom + 'px' }">
+            <view class="bottom-circle d-flex"
+                :style="{ backgroundImage: 'url(https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/storage/send_btm_bg_c.png)' }">
+                <view class="flex1 d-flex flex-cln a-c pt-160 pl-30">
+                    <view>
+                        <image class="w-68 h-68"
+                            src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/storage/xzhwk_icon_sd.png"
+                            mode="widthFix" />
+                    </view>
+                    <view class="f-s-28 c-#333">下载货位卡</view>
+                    <view class="f-s-22 c-#999">库存结余清晰</view>
+                </view>
+                <view class="d-flex flex-cln a-c pt-24">
+                    <view>
+                        <image class="w-68 h-68"
+                            src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/storage/xzsyrk_icon_sd.png"
+                            mode="widthFix" />
+                    </view>
+                    <view class="f-s-28 c-#333">销售记录清单</view>
+                    <view class="f-s-22 c-#999">销售登记的记录都在这里</view>
+                </view>
+                <view class="flex1 d-flex flex-cln a-c pt-160 pr-30"
+                    @click="clickBtnBall(); $u.route({ url: '/plant/storage/fresh-goods/add/index' });">
+                    <view>
+                        <image class="w-68 h-68"
+                            src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/storage/xzfsyrk_icon_sd.png"
+                            mode="widthFix" />
+                    </view>
+                    <view class="f-s-28 c-#333">销售登记</view>
+                    <view class="f-s-22 c-#999">按订单包装或按数量登记都可</view>
+                </view>
+            </view>
+        </view>
+    </view>
+    <view class="pt-60">
+        <view style="opacity: 0;">{{ mapTextBtn[btnStyle] }}</view>
+    </view>
+    <view class="bg-#fff" :style="{ height: safeAreaBottom + 'px' }"></view>
+</template>
+<script setup lang="ts">
+const windowInfo = uni.getWindowInfo();
+const safeAreaBottom = windowInfo.safeAreaInsets.bottom;
+const btnStyle = ref('add')
+const mapTextBtn = ref<any>({
+    add: '新增鲜货信息',
+    close: '关闭',
+});
+const clickBtnBall = () => {
+    btnStyle.value = btnStyle.value === 'add' ? 'close' : 'add';
+}
+</script>
+
+<style scoped lang="scss">
+.source-bottom-fixed {
+    position: fixed;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    z-index: 10;
+}
+
+.source-center-view {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    margin: auto;
+    width: 200rpx;
+    z-index: 99;
+
+    .source-btn-ball {
+        width: 98rpx;
+        height: 98rpx;
+        border-radius: 50%;
+        background-size: contain;
+        background-position: center;
+        background-repeat: no-repeat;
+    }
+}
+
+.bottom-circle-line {
+    position: absolute;
+    left: 0;
+    bottom: 0;
+    right: 0;
+    height: 1rpx;
+    opacity: 0;
+    transform: translateY(80rpx);
+    pointer-events: none;
+    transition: opacity 0.3s ease, transform 0.3s ease;
+}
+
+.bottom-circle-line-active {
+    opacity: 1;
+    transform: translateY(0);
+    pointer-events: auto;
+}
+
+.source-bottom-view {
+    box-shadow: 0px 0px 6rpx 0px #F1F6F4;
+    transition: all 0.3s ease;
+}
+
+.bottom-circle {
+    position: absolute;
+    width: 750rpx;
+    height: 750rpx;
+    border-radius: 50%;
+    left: 0;
+    bottom: -375rpx;
+    background-size: contain;
+    background-position: top;
+}
+
+.btn-deg-add {
+    transform: rotate(0);
+    transition: transform 0.3s ease;
+}
+
+.btn-deg-close {
+    transform: rotate(135deg);
+    transition: transform 0.3s ease;
+}
+</style>

+ 109 - 28
src/utils/upload.ts

@@ -3,6 +3,7 @@ import errorCode from '@/utils/errorCode';
 import { tansParams } from '@/utils/common';
 import config from '@/config';
 import { getCurrentPage } from '@/utils/public';
+import { useInfoStore } from '@/store';
 
 interface UploadConfig {
     url: string;
@@ -33,14 +34,14 @@ const upload = (uploadConfig: UploadConfig): Promise<UploadResult> => {
     }
     uploadConfig.header['Clientid'] = clientId; // 默认值
     uploadConfig.header['xid'] = appid; // 默认值
-    
+
     // get请求映射params参数
     if (uploadConfig.params) {
         let url = uploadConfig.url + '?' + tansParams(uploadConfig.params);
         url = url.slice(0, -1);
         uploadConfig.url = url;
     }
-    
+
     return new Promise((resolve, reject) => {
         uni.uploadFile({
             timeout: uploadConfig.timeout || timeout,
@@ -53,7 +54,7 @@ const upload = (uploadConfig: UploadConfig): Promise<UploadResult> => {
                 const result: UploadResult = JSON.parse(res.data);
                 const code = result.code || 200;
                 const msg = errorCode[code.toString()] || result.msg || errorCode['default'];
-                
+
                 if (code === 200) {
                     resolve(result);
                 } else if (code === 401) {
@@ -63,20 +64,20 @@ const upload = (uploadConfig: UploadConfig): Promise<UploadResult> => {
                         type: 'reLaunch',
                         url: '/pages/login/login',
                         params: {
-                            redirect: getCurrentPage()?.route || ''
-                        }
+                            redirect: getCurrentPage()?.route || '',
+                        },
                     });
                     reject('无效的会话,或者会话已过期,请重新登录。');
                 } else if (code === 500) {
                     uni.showToast({
                         title: msg,
-                        icon: 'none'
+                        icon: 'none',
                     });
                     reject('500');
                 } else if (code !== 200) {
                     uni.showToast({
                         title: msg,
-                        icon: 'none'
+                        icon: 'none',
                     });
                     reject(code);
                 }
@@ -93,40 +94,120 @@ const upload = (uploadConfig: UploadConfig): Promise<UploadResult> => {
                 }
                 uni.showToast({
                     title: message,
-                    icon: 'none'
+                    icon: 'none',
                 });
                 reject(error);
-            }
+            },
         });
     });
 };
 
-// 导出数据函数(简化版本)
-export const exportDataFn = (config: any): Promise<void> => {
-    return new Promise((resolve, reject) => {
-        if (config.url) {
-            uni.downloadFile({
-                url: config.url,
-                success: (result) => {
+/**
+ * 获取文件扩展名
+ * @param {string} url - 文件 URL
+ * @param {object} [result] - 响应结果对象
+ * @param {object} [result.header] - 响应头
+ * @returns {string|null} 文件扩展名(不带点),找不到则返回 null
+ */
+const getFileType = (url: string, result?: { header?: Record<string, any> }): string | null => {
+    // 1. 首先尝试从 URL 获取扩展名
+    if (url) {
+        // 获取 URL 中最后一个斜杠后的文件名
+        const filenameFromUrl = url.split('/').pop();
+        // 提取扩展名(处理可能存在的查询参数)
+        const urlExt = filenameFromUrl?.includes('.') ? filenameFromUrl.split('.').pop()?.split(/[?#]/)[0] : null;
+
+        if (urlExt) return urlExt.toLowerCase() || 'pdf';
+    }
+
+    // 2. 如果 URL 中没有扩展名,尝试从 Content-Disposition 头获取
+    if (result?.header?.['content-disposition']) {
+        try {
+            const disposition = result.header['content-disposition'];
+            // 匹配 filename="file.ext" 或 filename*=UTF-8''file.ext 格式
+            const filenameMatch = disposition.match(/filename\*?=(?:UTF-8''|")?([^;"\n]*)/i);
+
+            if (filenameMatch && filenameMatch[1]) {
+                const filename = filenameMatch[1].replace(/['"]/g, '');
+                if (filename.includes('.')) {
+                    const ext = filename.split('.').pop()?.split(/[?#]/)[0];
+                    return ext?.toLowerCase() || 'pdf';
+                }
+            }
+        } catch (e) {
+            console.warn('解析 Content-Disposition 失败:', e);
+        }
+    }
+
+    // 3. 都找不到则返回 pdf 作为默认值
+    return 'pdf';
+};
+
+// 导出数据函数(按照 handleDownload 规范完善)
+export const exportDataFn = (config: { url: string; fileName?: string; params?: Record<string, any>; timeout?: number }, showTitle?: string): Promise<void> =>
+    new Promise((resolve, reject) => {
+        // 判断是否为完整 URL(以 http://或 https://开头)
+        const isFullUrl = config.url.startsWith('http://') || config.url.startsWith('https://');
+        // 获取基础 URL 并拼接完整路径
+        const baseUrl = isFullUrl ? '' : import.meta.env.VITE_API_BASE_URL || config.url.split('/').slice(0, 3).join('/');
+        const downloadUrl = baseUrl + config.url;
+
+        // 获取 token
+        const token = useInfoStore().token;
+
+        // 设置请求头
+        const header = {
+            'Content-Type': 'application/json',
+            Authorization: `Bearer ${token}`,
+            xid: appid,
+            clientId: clientId,
+        };
+
+        uni.showLoading({
+            title: showTitle || '正在导出数据...',
+            mask: true,
+        });
+
+        uni.downloadFile({
+            url: downloadUrl,
+            header: header,
+            success: (res) => {
+                uni.hideLoading();
+                if (res.statusCode === 200) {
+                    // 直接打开文件
                     uni.openDocument({
-                        filePath: result.tempFilePath,
+                        filePath: res.tempFilePath,
                         showMenu: true,
+                        fileType: getFileType(config.fileName || config.url, res as any) as any,
                         success: () => {
                             resolve();
                         },
-                        fail: (error) => {
-                            reject(error);
-                        }
+                        fail: (err) => {
+                            console.log('打开文档失败:', err);
+                            uni.showToast({
+                                title: '打开文件失败',
+                                icon: 'none',
+                            });
+                            reject(err);
+                        },
                     });
-                },
-                fail: (error) => {
-                    reject(error);
+                } else {
+                    uni.showToast({
+                        title: '下载失败',
+                        icon: 'none',
+                    });
+                    reject(res);
                 }
-            });
-        } else {
-            reject(new Error('No URL provided'));
-        }
+            },
+            fail: () => {
+                uni.hideLoading();
+                uni.showToast({
+                    title: '下载失败',
+                    icon: 'none',
+                });
+                reject();
+            },
+        });
     });
-};
 
 export default upload;