lisy před 3 týdny
rodič
revize
b03d1d573b

+ 30 - 16
src/models/select-medicinal-part/select-medicinal-part.vue

@@ -3,16 +3,21 @@
         <slot></slot>
     </view>
     <up-popup v-model:show="showPart" mode="right" @close="close" a>
-        <view class="w-700 d-flex flex-cln" style="height: 100vh;">
+        <view class="w-700 d-flex flex-cln" style="height: 100vh">
             <up-navbar :fixed="false" border>
                 <template #left>
                     <view class="f-s-34 c-#333 f-w-500">{{ title }}</view>
                 </template>
             </up-navbar>
+            <view class="d-flex pd-20">
+                <view class="f-s-26 w-90 h-54 radius-100 bg-#f7f7f7 d-flex a-c j-c mr-20 c-#333" @click="changeSelect(0)" :style="{ backgroundColor: activeSelect == 0 ? '#37A954' : '', color: activeSelect == 0 ? '#FFF' : '' }">全部</view>
+                <view class="f-s-26 w-90 h-54 radius-100 bg-#f7f7f7 d-flex a-c j-c mr-20 c-#333" @click="changeSelect(1)" :style="{ backgroundColor: activeSelect == 1 ? '#37A954' : '', color: activeSelect == 1 ? '#FFF' : '' }">动物</view>
+                <view class="f-s-26 w-90 h-54 radius-100 bg-#f7f7f7 d-flex a-c j-c mr-20 c-#333" @click="changeSelect(2)" :style="{ backgroundColor: activeSelect == 2 ? '#37A954' : '', color: activeSelect == 2 ? '#FFF' : '' }">植物</view>
+            </view>
             <view class="flex1 ov-hd d-flex">
                 <scroll-view class="w-330 bg-#f7f7f7" scroll-y style="height: 100%; border-right: 1rpx solid #e6e6e6">
                     <template v-for="group in groups" :key="group.partCode">
-                        <view class="pd-24 tabs-group" @click="groupId = group.partCode" :class="{ active: group?.partCode === groupId }">{{ group?.partName }}</view>
+                        <view v-if="activeSelect !== +group?.type" class="pd-24 tabs-group" @click="groupId = group.partCode" :class="{ active: group?.partCode === groupId }">{{ group?.partName }}</view>
                     </template>
                 </scroll-view>
                 <scroll-view class="flex1" scroll-y style="height: 100%">
@@ -71,9 +76,9 @@ const getGroupList = async () => {
     groups.value.forEach((group: any) => {
         mapGroupSons[group.partCode] = group.children || [];
         mapValueName[group.partCode] = group.partName;
-            (group.children || []).forEach((son: any) => {
-                mapValueName[son.partCode] = son.partName;
-            });
+        (group.children || []).forEach((son: any) => {
+            mapValueName[son.partCode] = son.partName;
+        });
     });
     groupId.value = groups.value?.[0]?.partCode || '';
 };
@@ -92,17 +97,26 @@ onMounted(() => {
     getGroupList();
 });
 // 如果有传入value,则设置默认选中
-watch(() => props.modelValue, (newVal) => {
-    value.value = newVal;
-    // 分组高亮
-    if (newVal) {
-       // 分隔
-        const parts = newVal.split('-');
-        // 去掉最后一项再合并回去,得到分组code
-        const groupCode = parts.slice(0, -1).join('-');
-        groupId.value = groupCode;
-    }
-}, { immediate: true });
+watch(
+    () => props.modelValue,
+    (newVal) => {
+        value.value = newVal;
+        // 分组高亮
+        if (newVal) {
+            // 分隔
+            const parts = newVal.split('-');
+            // 去掉最后一项再合并回去,得到分组code
+            const groupCode = parts.slice(0, -1).join('-');
+            groupId.value = groupCode;
+        }
+    },
+    { immediate: true },
+);
+const activeSelect = ref(0);
+const changeSelect = (index: number) => {
+    activeSelect.value = index;
+    groupId.value = '';
+};
 </script>
 <style lang="scss" scoped>
 .tabs-group {

+ 19 - 1
src/pages.json

@@ -205,6 +205,18 @@
                     "style": {
                         "navigationBarTitleText": "采收管理列表"
                     }
+                },
+                {
+                    "path": "port-harvest-create/index",
+                    "style": {
+                        "navigationBarTitleText": "新增采收入库"
+                    }
+                },
+                {
+                    "path": "port-harvest-detail/index",
+                    "style": {
+                        "navigationBarTitleText": "采收管理详情"
+                    }
                 }
             ]
         },
@@ -339,7 +351,7 @@
                         "navigationBarTitleText": "新增鲜货入库"
                     }
                 },
-                 // 新增鲜货入库信息
+                // 新增鲜货入库信息
                 {
                     "path": "fresh-goods/info-edit/index",
                     "style": {
@@ -454,6 +466,12 @@
                     "style": {
                         "navigationBarTitleText": "选择种源信息"
                     }
+                },
+                {
+                    "path": "pro-process-steps/index",
+                    "style": {
+                        "navigationBarTitleText": "选择加工工艺信息"
+                    }
                 }
             ]
         },

+ 545 - 55
src/plant/port/port-harvest-create/index.vue

@@ -5,75 +5,104 @@
         </template>
         <view class="pt-24">
             <up-form class="p-rtv" labelPosition="top" :model="form" :rules="rules" labelWidth="auto" ref="upFormRef">
-                <view class="startline-title pl-24 ml-24 mb-16">管理记录信息</view>
                 <view class="bg-#fff pd-24 mb-20">
-                    <!-- 操作日期 -->
-                    <view class="h-1" id="operationDatepppp"></view>
+                    <up-form-item borderBottom label="动植物名称">
+                        <view class="w-100%">
+                            <view class="f-s-24 c-#999 mb-20">此为种养殖的动植物品种,无法更改</view>
+                            <view class="pd-24 d-flex flex-cln bg-#FBFDFB border-#37A954 b-radius p-rtv">
+                                <view class="mb-20">
+                                    <text class="c-#333 f-s-34 f-w-5 mr-5">{{ plantDate?.varietyName }}</text>
+                                    <text class="c-#666 f-s-24">{{ plantDate?.latinName }}</text>
+                                </view>
+                                <view>
+                                    <text class="c-#333 f-s-28 f-w-5 mr-5">{{ plantDate?.genusName }}</text>
+                                    <text class="c-#666 f-s-24">{{ plantDate?.genusLatinName }}</text>
+                                </view>
+                            </view>
+                        </view>
+                    </up-form-item>
                     <!-- 采收类型 -->
-                    <ut-action-sheet v-model="form.opMethod" :tabs="pt_op_method" title="选择操作类型" mode="custom">
-                        <up-form-item borderBottom label="操作类型" required prop="opMethod" id="opMethodpppp">
-                            <view v-if="form.opMethod" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_op_method, form.opMethod) }}</view>
-                            <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择采收类型</view>
-                            <template #right>
-                                <up-icon size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
-                            </template>
+                    <view class="h-1" id="outputTypepppp"></view>
+                    <template v-if="+taskType == 11 || +taskType == 21 || changeRevisions">
+                        <up-form-item borderBottom label="采收类型" required prop="outputType">
+                            <view v-if="form?.outputType" class="f-s-30 c-#999 f-w-5 flex1">{{ selectDictLabel(pt_output_type, form?.outputType) }}</view>
                         </up-form-item>
-                    </ut-action-sheet>
+                    </template>
+                    <template v-else>
+                        <ut-action-sheet v-model="form.outputType" :tabs="pt_output_type" title="选择采收类型">
+                            <up-form-item borderBottom label="采收类型" required prop="outputType">
+                                <view v-if="form?.outputType" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_output_type, form?.outputType) }}</view>
+                                <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择采收类型</view>
+                                <template #right>
+                                    <up-icon size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
+                                </template>
+                            </up-form-item>
+                        </ut-action-sheet>
+                    </template>
                     <!-- 种源类型 -->
-                    <ut-action-sheet v-model="form.opMethod" :tabs="pt_op_method" title="选择操作类型" mode="custom">
-                        <up-form-item borderBottom label="操作类型" required prop="opMethod" id="opMethodpppp">
-                            <view v-if="form.opMethod" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_op_method, form.opMethod) }}</view>
-                            <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择种源类型</view>
-                            <template #right>
-                                <up-icon size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
-                            </template>
+                    <template v-if="+form?.outputType == 1">
+                        <ut-action-sheet v-model="form.seedType" :tabs="pt_seed_type" title="选择种源类型" mode="custom">
+                            <up-form-item borderBottom label="种源类型" required prop="seedType" id="seedTypepppp">
+                                <view v-if="form.seedType" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_seed_type, form?.seedType) }}</view>
+                                <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择种源类型</view>
+                                <template #right>
+                                    <up-icon size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
+                                </template>
+                            </up-form-item>
+                        </ut-action-sheet>
+                        <!-- 菌种/菌株编号 -->
+                        <up-form-item v-if="form?.seedType == 'A4' || form?.seedType == 'A8'" borderBottom label="菌种/菌株编号" required prop="fungusCode" id="fungusCodeppppp">
+                            <up-input v-model="form.fungusCode" placeholder="请输入菌种/菌株编号" border="none"></up-input>
                         </up-form-item>
-                    </ut-action-sheet>
-                    <!-- 菌种/菌株编号 -->
-                    <up-form-item borderBottom label="菌种/菌株编号" required prop="cusOp" id="cusOppppp">
-                        <up-input v-model="form.cusOp" placeholder="请输入菌种/菌株编号" border="none"></up-input>
-                    </up-form-item>
+                    </template>
                     <!-- 采收日期 -->
-                    <up-form-item :borderBottom="false" label="采收日期">
-                        <up-form-item :borderBottom="false" required prop="activityStart">
-                            <ut-datetime-picker v-model="form.activityStart" mode="date" dateFields="day" @change="changeStartTime">
+                    <up-form-item :borderBottom="false" label="采收日期" required>
+                        <up-form-item :borderBottom="false" prop="harvestDate" id="harvestDatepppp">
+                            <ut-datetime-picker v-model="form.harvestDate" mode="date" dateFields="day" @change="changeStartTime">
                                 <view class="d-flex mr-20">
-                                    <up-input v-model="form.activityStart" placeholder="请选择采收开始时间" border="bottom" :customStyle="{ paddingLeft: '0rpx' }"></up-input>
+                                    <up-input v-model="form.harvestDate" placeholder="请选择采收开始时间" border="bottom" :customStyle="{ paddingLeft: '0rpx' }"></up-input>
                                     <up-icon size="22rpx" color="#2A6D52" name="arrow-down-fill" style="margin-left: -20rpx"></up-icon>
                                 </view>
                             </ut-datetime-picker>
                         </up-form-item>
-                        <up-form-item :borderBottom="false" required prop="activityEnd">
-                            <ut-datetime-picker v-model="form.activityEnd" mode="date" dateFields="day">
+                        <up-form-item :borderBottom="false" prop="harvestDateEnd" id="harvestDateEndpppp">
+                            <ut-datetime-picker v-model="form.harvestDateEnd" mode="date" dateFields="day">
                                 <view class="d-flex">
-                                    <up-input v-model="form.activityEnd" placeholder="请选择采收结束时间" border="bottom" :customStyle="{ paddingLeft: '0rpx' }"></up-input>
+                                    <up-input v-model="form.harvestDateEnd" placeholder="请选择采收结束时间" border="bottom" :customStyle="{ paddingLeft: '0rpx' }"></up-input>
                                     <up-icon size="22rpx" color="#2A6D52" name="arrow-down-fill" style="margin-left: -20rpx"></up-icon>
                                 </view>
                             </ut-datetime-picker>
                         </up-form-item>
                     </up-form-item>
+                    <!-- 采收部位 -->
+                    <up-form-item borderBottom label="药用部位/对象" prop="harvestPart" required>
+                        <SelectMedicinalPart v-if="+form?.outputType == 2" v-model="form.harvestPart" v-model:value-name="form.harvestPartName" title="选择采收部位">
+                            <up-input v-model="form.harvestPartName" placeholder="请选择药用部位/对象" border="none" readonly clearable></up-input>
+                        </SelectMedicinalPart>
+                    </up-form-item>
                     <!-- 采收批号 -->
-                    <up-form-item borderBottom label="采收批号" required prop="plantationCode" id="plantationCodepppp">
+                    <up-form-item borderBottom label="采收批号" required prop="harvestCode" id="harvestCodepppp">
                         <view class="d-flex a-c j-sb w-100%">
-                            <view v-if="!form.plantationCode" class="flex1 c-#999">请生成采收批号</view>
-                            <view v-else class="flex1 c-#333">{{ form.plantationCode }}</view>
-                            <up-button @click="randomCode" class="c-#fff" type="primary" style="height: 50rpx; width: 130rpx">随机生成</up-button>
+                            <view class="flex1 d-flex">
+                                <up-input v-model="form.harvestCode" 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>
                     <!-- 采收量 -->
                     <up-form-item label="采收量" required class="form-item-bottom-padding-0">
                         <div class="flex1 d-flex">
-                            <div class="flex1 ov-hd" id="plantingMgAmountpppp">
-                                <up-form-item prop="plantingMgAmount" border-bottom class="form-item-top-padding-0">
-                                    <up-input v-model="form.plantingMgAmount" placeholder="请输入采收量" border="none" clearable></up-input>
+                            <div class="flex1 ov-hd" id="quantitypppp">
+                                <up-form-item prop="quantity" border-bottom class="form-item-top-padding-0">
+                                    <up-input v-model="form.quantity" placeholder="请输入采收量" border="none" clearable></up-input>
                                 </up-form-item>
                             </div>
-                            <div class="pd-5" id="plantingMgUnitpppp"></div>
+                            <div class="pd-5" id="unitpppp"></div>
                             <div class="min-w-200">
-                                <ut-action-sheet v-model="form.plantingMgUnit" :tabs="pt_planting_mg_unit" title="选择单位">
-                                    <up-form-item prop="plantingMgUnit" border-bottom class="form-item-top-padding-0">
+                                <ut-action-sheet v-model="form.unit" :tabs="pt_seed_unit" title="选择单位">
+                                    <up-form-item prop="unit" border-bottom class="form-item-top-padding-0">
                                         <view class="flex1" style="line-height: 24px">
-                                            <view v-if="form.plantingMgUnit" class="f-s-30 c-333 f-w-5 text-center">{{ selectDictLabel(pt_planting_mg_unit, form.plantingMgUnit) }}</view>
+                                            <view v-if="form.unit" class="f-s-30 c-333 f-w-5 text-center">{{ selectDictLabel(pt_seed_unit, form.unit) }}</view>
                                             <view v-else class="f-s-30 c-ccc f-w-4 text-center">单位</view>
                                         </view>
                                         <template #right>
@@ -85,15 +114,15 @@
                         </div>
                     </up-form-item>
                     <!-- 采收负责人 -->
-                    <up-form-item borderBottom label="采收负责人" required prop="mgName" id="namepppp">
+                    <up-form-item borderBottom label="采收负责人" required prop="mgrName" id="mgr_namepppp">
                         <view class="d-flex a-c j-sb w-100%">
-                            <up-input style="padding-left: 0" v-model="form.mgName" placeholder="请输入采收负责人" border="none"></up-input>
+                            <up-input style="padding-left: 0" v-model="form.mgrName" placeholder="请输入采收负责人" border="none"></up-input>
                         </view>
                     </up-form-item>
                     <!-- 采收方式 -->
-                    <ut-action-sheet v-model="form.opMethod" :tabs="pt_op_method" title="选择采收方式" mode="custom">
-                        <up-form-item borderBottom label="采收方式" required prop="opMethod" id="opMethodpppp">
-                            <view v-if="form.opMethod" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_op_method, form.opMethod) }}</view>
+                    <ut-action-sheet v-model="form.harvestType" :tabs="pt_harvest_type" title="选择采收方式">
+                        <up-form-item borderBottom label="采收方式" prop="harvestType" id="harvestTypepppp">
+                            <view v-if="form.harvestType" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_harvest_type, form.harvestType) }}</view>
                             <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择采收方式</view>
                             <template #right>
                                 <up-icon size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
@@ -101,18 +130,17 @@
                         </up-form-item>
                     </ut-action-sheet>
                     <!-- 采收地块 -->
-                    <up-form-item :borderBottom="false" label="操作地块" prop="landIds" id="baseIdpppp">
-                        <view v-if="!deawerData" class="w-100% d-flex a-c j-c pd-24 b-radius bg-#FBFDFB border-#AFDDBB" @click="goSelectBase()">
-                            <view class=""></view>
-                            <view class="f-s-34 c-primary">请选择操作地块</view>
-                        </view>
+                    <up-form-item v-if="+mgMethod !== 2" :borderBottom="false" :label="'采收' + landIdsTitle" prop="landIds" id="landIdspppp">
+                        <Go_button v-if="!deawerData" @click="openDrawer" :title="'请选择采收的' + landIdsTitle" style="flex: 1" />
                         <view class="w-100%" v-else>
-                            <Baseinfo :modeValue="deawerData" @close="handleBaseinfoClose" :baseType="'1'" />
+                            <Baseinfo :modeValue="deawerData" @close="handleBaseinfoClose" :baseType="baseType" />
                         </view>
                     </up-form-item>
-                    <!-- 操作方式 -->
-                    <up-form-item borderBottom label="操作方式" prop="opRemark" id="opRemarkpppp">
-                        <up-input v-model="form.opRemark" placeholder="如:人工锄草、机械中耕、喷雾器叶面喷施等" border="none"></up-input>
+                    <up-form-item v-else :borderBottom="false" :label="'采收' + landIdsTitle" prop="animalIds" id="animalIdspppp">
+                        <view class="flex1">
+                            <Individualinfo v-if="individualLandIds?.checkBox?.length > 0" v-model="individualLandIds" v-model:landIds="form.animalIds" />
+                            <Go_button @click="goIndividual()" :title="'请选择采收的' + landIdsTitle" style="flex: 1" />
+                        </view>
                     </up-form-item>
                     <up-form-item label="过程图片" prop="imgs" borderBottom id="imgspppp">
                         <ut-upload v-model="form.imgs" :max-count="9" accept="image"></ut-upload>
@@ -120,8 +148,470 @@
                     <up-form-item label="过程视频" prop="videos" borderBottom id="videospppp">
                         <ut-upload v-model="form.videos" :max-count="9" accept="video"></ut-upload>
                     </up-form-item>
+                    <up-form-item v-if="+form.outputType == 1" label="种源加工处理工艺" prop="ptech" borderBottom id="ptechpppp">
+                        <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 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>
+                                        <span class="f-s-32">{{ item }}</span>
+                                    </template>
+                                </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>
+                                </view>
+                            </view>
+                            <Go_button v-else @click="goPtech" title="请选择种源加工处理工艺" style="flex: 1" />
+                        </view>
+                    </up-form-item>
+                    <up-form-item label="存放库房类型" borderBottom>
+                        <view class="d-flex a-c j-sb w-100%">
+                            <view v-if="form.outputType" class="f-s-30 c-#999 f-w-5 flex1">{{ selectDictLabel(pt_output_type, form.outputType) }}</view>
+                        </view>
+                    </up-form-item>
                 </view>
             </up-form>
         </view>
+        <template #bottom>
+            <view class="pd-24 d-flex j-c gap-20 base-bottom-wrap">
+                <up-button v-if="changeRevisions" type="primary" @click="change()">确认修改</up-button>
+                <up-button v-else type="primary" @click="save()">确认添加</up-button>
+            </view>
+        </template>
     </z-paging>
+    <Drawer v-if="drawerVisible" :baseType="baseType" v-model="drawerVisible" @confirm="onDrawerConfirm" />
+    <up-popup :show="showptech" mode="center" @close="showptech = false" @open="showptech = true" closeable>
+        <view style="width: 80vw">
+            <view class="pd-24">
+                <view class="f-s-32 c-#333 f-w-5">请选择种源加工处理工艺</view>
+            </view>
+            <view class="pd-24" v-if="form?.ptech?.length">
+                <view class="c-#999 f-s-26 f-w-5 pb-10">已选择工艺步骤</view>
+                <view class="d-flex flex-wrap pd-24 a-c gap-10 border-#37A954 b-radius">
+                    <template v-for="(item, index) in form?.ptech?.split(',')" :key="index">
+                        <image v-if="index !== 0" src="@/static/images/common/craftArrow.png" class="mr-10 ml-10" style="width: 44rpx; height: 44rpx"> </image>
+                        <view class="p-rtv">
+                            <up-icon color="red" name="close-circle-fill" @click="removePtech(index)" style="position: absolute; right: -10rpx; top: -10rpx"></up-icon>
+                            <view class="pd-16 bg-#37A9541A c-primary b-radius mb-10"> {{ item }}</view>
+                        </view>
+                    </template>
+                </view>
+            </view>
+            <view class="pd-24 pb-0 c-#999 f-s-26 f-w-5">快捷选择加工工艺</view>
+            <template v-if="ptechData?.length == 0">
+                <ut-empty class="mg-at" color="#ccc" size="28rpx">暂未配置种源加工工艺,</ut-empty>
+                <view class="d-flex j-c c-#ccc f-s-28">请前往 <span class="c-primary">更多-加工工艺字典</span>进行配置,</view>
+                <view class="d-flex j-c c-#ccc f-s-28">配置后再来选择</view>
+            </template>
+            <template v-else>
+                <scroll-view class="h-400" scroll-y>
+                    <view class="d-flex j-sb flex-wrap pd-24 pb-0">
+                        <view v-for="(item, idnex) in ptechData" :key="idnex" class="bg-#f7f7f7 c-#333 radius-10 pd4-16-24-16-24 mb-16" @click="addPtech(item)">
+                            {{ item }}
+                        </view>
+                    </view>
+                </scroll-view>
+            </template>
+        </view>
+        <view class="gap-20 d-flex pd-24">
+            <up-button @click="emptyPtech" color="#F2F2F2" style="color: #333">清空重选</up-button>
+            <up-button type="primary" @click="changePtech">确认选择</up-button>
+        </view>
+    </up-popup>
 </template>
+<script setup lang="ts">
+import { ref, reactive, computed, getCurrentInstance, type ComponentInternalInstance } from 'vue';
+import { useClientRequest } from '@/utils/request';
+import { useInfoStore } from '@/store';
+import Go_button from './models/go_button.vue';
+import Baseinfo from './models/baseinfo.vue';
+import Drawer from './models/drawer.vue';
+import Individualinfo from './models/individualinfo.vue';
+import SelectMedicinalPart from '@/models/select-medicinal-part/select-medicinal-part.vue';
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { pt_output_type, pt_seed_type, pt_seed_unit, pt_harvest_type } = toRefs<any>(proxy?.useDict('pt_output_type', 'pt_seed_type', 'pt_seed_unit', 'pt_harvest_type'));
+const deawerData = ref();
+const infoStore = useInfoStore();
+// 表单数据
+const form = ref({
+    taskId: '',
+    // 管理类型 - 采收入库
+    activityType: '3',
+    // 采收类型
+    outputType: '',
+    // 种源类型
+    seedType: '',
+    // 菌种/菌株编号
+    fungusCode: '',
+    // 采收开始时间
+    harvestDate: '',
+    // 采收结束时间
+    harvestDateEnd: '',
+    // 采收批号
+    harvestCode: '',
+    // 采收量
+    quantity: '',
+    // 采收单位
+    unit: '',
+    // 采收负责人
+    mgrName: infoStore.userInfo?.name || '',
+    // 采收方式
+    harvestType: '',
+    // 操作地块
+    landIds: [] as any[],
+    // 操作个体
+    animalIds: [] as any[],
+    // 过程图片
+    imgs: null as string | null,
+    // 过程视频
+    videos: null as string | null,
+    ptech: '' as string,
+    landFlag: null as string | null,
+    //采收部位
+    harvestPart: null as string | any,
+    //采收部位名称
+    harvestPartName: null as string | any,
+});
+const baseType = ref();
+// 自定义校验函数 - 采收量必须大于0
+const validateHarvestAmount = (rule: any, value: any, callback: any) => {
+    if (!value) {
+        callback(new Error('请输入采收量'));
+        return;
+    }
+
+    const amount = Number(value);
+    if (isNaN(amount) || amount <= 0) {
+        callback(new Error('采收量必须大于0'));
+        return;
+    }
+
+    callback();
+};
+
+// 自定义校验函数 - 采收结束时间不能早于开始时间
+const validateHarvestDate = (rule: any, value: any, callback: any) => {
+    if (!form.value.harvestDate || !form.value.harvestDateEnd) {
+        callback();
+        return;
+    }
+
+    const startDate = new Date(form.value.harvestDate);
+    const endDate = new Date(form.value.harvestDateEnd);
+
+    if (endDate < startDate) {
+        callback(new Error('采收结束时间不能早于开始时间'));
+        return;
+    }
+
+    callback();
+};
+
+// 自定义校验函数 - 采收批号格式
+const validatePlantationCode = (rule: any, value: any, callback: any) => {
+    if (!value) {
+        callback(new Error('请生成采收批号'));
+        return;
+    }
+
+    // 简单的批号格式校验:至少包含字母和数字
+    if (!/^[A-Za-z0-9_-]+$/.test(value)) {
+        callback(new Error('采收批号格式不正确,只能包含字母、数字、下划线和横线'));
+        return;
+    }
+
+    callback();
+};
+
+// 表单验证规则
+const rules = reactive({
+    outputType: [{ required: true, message: '请选择采收类型' }],
+    seedType: [{ required: !!(form?.value?.outputType == '1'), message: '请选择种源类型' }],
+    fungusCode: [{ required: !!(form?.value?.seedType == 'A4' || form?.value?.seedType == 'A8'), message: '请输入菌种/菌株编号' }],
+    harvestDate: [{ required: true, message: '请选择采收开始时间' }],
+    harvestDateEnd: [
+        { required: true, message: '请选择采收结束时间' },
+        { validator: validateHarvestDate, trigger: 'blur' },
+    ],
+    harvestPart: [{ required: !!(form?.value?.outputType == '2'), message: '请选择采收部位' }],
+    harvestCode: [
+        { required: true, message: '请生成采收批号' },
+        { validator: validatePlantationCode, trigger: 'blur' },
+    ],
+    quantity: [
+        { required: true, message: '请输入采收量' },
+        { validator: validateHarvestAmount, trigger: 'blur' },
+    ],
+    unit: [{ required: true, message: '请选择单位' }],
+    mgrName: [{ required: true, message: '请输入采收负责人' }],
+    harvestType: [{ required: false, message: '请选择采收方式' }],
+    landIds: [{ required: false, message: '请选择采收地块' }],
+});
+
+const paging = ref();
+const list = ref();
+const upFormRef = ref<any>();
+
+const query = async (pageNo: number, pageSize: number) => {
+    // 这里可以根据需要实现分页查询
+    const res = await useClientRequest.get('/plt-api/app/plantationTask/list', {
+        pageNo,
+        pageSize,
+    });
+    // return res.data;
+};
+
+// 处理开始时间变化
+const changeStartTime = (value: string) => {
+    form.value.harvestDate = value;
+    // 如果结束时间早于开始时间,清空结束时间
+    if (form.value.harvestDateEnd && new Date(form.value.harvestDateEnd) < new Date(value)) {
+        form.value.harvestDateEnd = '';
+    }
+};
+
+// 控制抽屉显示状态
+const drawerVisible = ref(false);
+
+// 打开抽屉
+function openDrawer() {
+    drawerVisible.value = true;
+}
+//去选择个体
+const goIndividual = () => {
+    uni.$once('updateIndividual', function (data) {
+        let flag = false;
+        console.log('选择个体', data);
+        console.log(individualLandIds.value, '12312');
+
+        data?.checkBox.forEach((item: any) => {
+            //判断有没有重复的值,如果有这个就不添加,没有就添加
+            if (individualLandIds.value.checkBox.some((item2: any) => item2 === item)) {
+                console.log('????', item);
+                flag = true;
+            } else {
+                individualLandIds.value.checkBox.push(item);
+                console.log('????', form.value);
+                form.value.animalIds.push(item);
+            }
+        });
+        if (flag) {
+            uni.showToast({
+                title: '有重复的个体,已经帮您过滤的',
+                icon: 'none',
+            });
+        }
+        paging.value?.scrollIntoViewById('selectanimalId', 30, true);
+    });
+    uni.$u.route({ type: 'navigateTo', url: '/tools/supervise-individual/index', params: { taskId: form.value.taskId } });
+};
+
+// 处理地块选择关闭
+const handleBaseinfoClose = () => {
+    deawerData.value = null;
+    form.value.landIds = [];
+};
+
+// 提交表单
+const save = () => {
+    uni.$u.debounce(
+        async () => {
+            try {
+                console.log('开始提交采收入库记录');
+                await upFormRef.value?.validate();
+                console.log('校验完成');
+
+                const params = {
+                    ...form.value,
+                    landFlag: deawerData?.value?.aloneChecked ? '1' : '0',
+                };
+
+                console.log('提交参数:', params);
+
+                // 这里需要根据实际 API 进行调整
+                const res = await useClientRequest.post('/plt-api/app/harvestRecord/save', params);
+                if (res.code == 200) {
+                    uni.showToast({
+                        title: '提交成功',
+                        icon: 'success',
+                        duration: 2000,
+                    });
+                    setTimeout(() => {
+                        // 发送更新事件
+                        uni.$emit('updateharvestlist');
+                        uni.navigateBack({
+                            delta: 1,
+                        });
+                    }, 1000);
+                }
+            } catch (error: any) {
+                console.log('表单验证错误:', error);
+                // 滚动到第一个错误字段
+                if (error && error[0]?.field) {
+                    const firstErrorField = error[0].field + 'pppp';
+                    paging.value?.scrollIntoViewById(firstErrorField, 30, true);
+                }
+                return;
+            }
+        },
+        1000,
+        true,
+    );
+};
+
+const change = () => {
+    uni.$u.debounce(
+        async () => {
+            try {
+                console.log('开始提交采收入库记录');
+                await upFormRef.value?.validate();
+                console.log('校验完成');
+                const params = {
+                    ...form.value,
+                    landFlag: deawerData?.value?.aloneChecked ? '1' : '0',
+                };
+
+                console.log('提交参数:', params);
+
+                // 这里需要根据实际 API 进行调整
+                const res = await useClientRequest.post('/plt-api/app/harvestRecord/update', params);
+                if (res.code == 200) {
+                    uni.showToast({
+                        title: '提交成功',
+                        icon: 'success',
+                        duration: 2000,
+                    });
+                    setTimeout(() => {
+                        // 发送更新事件
+                        uni.$emit('updateharvestdetail');
+                        uni.navigateBack({
+                            delta: 1,
+                        });
+                    }, 1000);
+                }
+            } catch (error: any) {
+                console.log('表单验证错误:', error);
+                // 滚动到第一个错误字段
+                if (error && error[0]?.field) {
+                    const firstErrorField = error[0].field + 'pppp';
+                    paging.value?.scrollIntoViewById(firstErrorField, 30, true);
+                }
+                return;
+            }
+        },
+        1000,
+        true,
+    );
+};
+// 处理抽屉确认事件
+function onDrawerConfirm(data: any) {
+    console.log('收到基地选择数据:', data);
+    deawerData.value = data;
+    form.value.landIds = data?.checkBox;
+}
+const randomCode = async () => {
+    let plType = '';
+    if (+taskType.value === 1) {
+        plType = 'P';
+    } else if (+taskType.value === 2) {
+        plType = 'F';
+    } else {
+        plType = 'C';
+    }
+    const code = await useClientRequest.post('/plt-api/app/plantationTask/getBatchCode', { plType: plType, linkType: 'R' });
+    form.value.harvestCode = code.data;
+};
+const taskType = ref();
+const mgMethod = ref();
+const landIdsTitle = ref('');
+const variety = ref();
+const individualLandIds = ref();
+const changeRevisions = ref();
+// 获取动植物的品种
+const plantDate = ref();
+const getVariety = async (varietyCode: any) => {
+    const res = await useClientRequest.get(`/plt-api/app/medicine/getMedicineByCode/${varietyCode}`);
+    plantDate.value = res.data;
+};
+
+//工艺的弹框
+const showptech = ref(false);
+
+const ptechData = ref();
+//模拟工艺的字典
+const getptechData = async () => {
+    const res = await useClientRequest.get(`/plt-api/app/process/tech/listAllGroup`);
+    ptechData.value = res?.data;
+    console.log(ptechData.value, '工艺字典');
+};
+const goPtech = () => {
+    // 跳转到pro-process-steps
+    uni.$once('updatePtechTransit', function (data) {
+        form.value.ptech = data?.data;
+    });
+    uni.$u.route({ type: 'navigateTo', url: '/tools/pro-process-steps/index', params: { ptechTransit: form?.value?.ptech } });
+};
+onLoad(async (options: any) => {
+    form.value.taskId = options?.taskId || '';
+    baseType.value = options?.baseType || '';
+    taskType.value = options?.taskType || '';
+    mgMethod.value = options?.mgMethod;
+    variety.value = options?.variety;
+    individualLandIds.value = {
+        checkBox: [],
+        variety: variety.value,
+    };
+    if (options?.change) {
+        //重选获取一下
+        const res = await useClientRequest.get(`/plt-api/app/harvestRecord/getInfo/${options?.recordId}`);
+        changeRevisions.value = true;
+        form.value = res.data;
+        individualLandIds.value.checkBox = res.data?.animalIds;
+        taskType.value = res.data?.taskType || '';
+        baseType.value = res.data?.baseInfo?.baseType;
+        deawerData.value = {};
+        deawerData.value.baseName = res.data?.baseInfo?.baseName;
+        deawerData.value.areaUnit = res.data?.baseInfo?.gapInfo.areaUnit;
+        deawerData.value.area = res.data?.baseInfo?.gapInfo.area;
+        deawerData.value.address = res.data?.baseInfo?.gapInfo.address;
+        if (+res.data?.landFlag) {
+            deawerData.value.aloneChecked = true;
+        } else {
+            deawerData.value.aloneChecked = false;
+        }
+        deawerData.value.data = res.data?.lands;
+    } else {
+        if (+taskType?.value == 11) {
+            form.value.outputType = '1';
+        } else if (+taskType?.value == 21) {
+            form.value.outputType = '1';
+        } else if (+taskType?.value == 1) {
+            form.value.outputType = '2';
+        } else {
+            form.value.outputType = '2';
+        }
+    }
+    getptechData();
+    getVariety(options?.varietyCode);
+    //判断溯源级别
+    if (+options?.mgMethod == 2) {
+        landIdsTitle.value = '个体';
+    } else {
+        if (+baseType.value == 1) {
+            landIdsTitle.value = '地块';
+        } else if (+baseType.value == 2) {
+            landIdsTitle.value = '圈舍';
+        } else {
+            landIdsTitle.value = '培养架';
+        }
+    }
+    // 监听地块选择事件
+    uni.$on('selectBaseInfo', (data: any) => {
+        deawerData.value = data;
+        if (data && data.id) {
+            form.value.landIds = [data.id];
+        }
+    });
+});
+</script>

+ 90 - 0
src/plant/port/port-harvest-create/models/baseinfo.vue

@@ -0,0 +1,90 @@
+<template>
+    <view class="border-#AFDDBB pd-26 pb-10 pt-10 bg-#FBFDFB p-rtv">
+        <!-- 关闭按钮 -->
+        <view v-if="showClose" class="c-#F81242 f-s-36 ab2-10-10 pl-20 pr-10" style="position: absolute; right: 10rpx; top: 0rpx" @click="handleClose"> × </view>
+        <!-- 标签显示:GAP和三无一全 -->
+        <view v-if="+modeValue?.gapFlag || +modeValue?.swyqRes" class="pt-8 pb-8 d-flex pr-20 pl-20" style="width: max-content; margin-top: -10rpx; margin-left: -26rpx; background: linear-gradient(90deg, #5eba75, #c6e391); border-bottom-right-radius: 88rpx">
+            <view v-if="+modeValue?.gapFlag && !+modeValue?.swyqRes" class="c-#fff f-s-24 f-w-6">获评{{ modeValue?.medicineName }}GAP基地</view>
+            <view v-if="+modeValue?.swyqRes && !+modeValue?.gapFlag" class="c-#fff f-s-24 f-w-6">获评{{ modeValue?.swyqMedicineName }}三无一全基地</view>
+            <view v-if="+modeValue?.gapFlag && +modeValue?.swyqRes" class="c-#fff f-s-24 f-w-6">获评{{ modeValue?.medicineName }}GAP基地和{{ modeValue?.swyqMedicineName }}三无一全基地</view>
+        </view>
+        <view class="c-#333 f-s-34 f-w-5 pt-8 pb-8 pr-16">{{ modeValue?.baseName }}</view>
+        <view class="pt-8 pb-8">
+            <text class="c-#666 f-s-28">基地面积:</text>
+            <text class="c-#333 f-s-28 f-w-5">{{ modeValue?.area }}{{ modeValue?.areaUnit }}</text>
+        </view>
+        <view class="pt-8 pb-8">
+            <text class="c-#666 f-s-28">基地地址:</text>
+            <text class="c-#333 f-s-28 f-w-5">{{ modeValue?.adcodeName }}{{ modeValue?.address }}</text>
+        </view>
+        <view style="margin-left: -26rpx; margin-right: -26rpx; border-bottom: 1rpx solid #d4ecda"></view>
+        <view class="pt-16 pb-8">
+            <text v-if="+modeValue?.data?.[0]?.landType == 1" class="c-#666 f-s-28">地块信息:</text>
+            <text v-if="+modeValue?.data?.[0]?.landType == 2" class="c-#666 f-s-28">圈舍信息:</text>
+            <text v-if="+modeValue?.data?.[0]?.landType == 3" class="c-#666 f-s-28">培养架信息:</text>
+            <text v-if="!modeValue?.aloneChecked" class="c-#333 f-s-28 f-w-5">{{ modeValue?.data?.length }}个</text>
+            <text v-if="modeValue?.aloneChecked" class="c-#333 f-s-28 f-w-5">该基地所有{{ +modeValue?.data?.[0]?.landType == 1 ? '地块' : +modeValue?.data?.[0]?.landType == 2 ? '圈舍' : '培养架' }}</text>
+        </view>
+        <view v-if="!modeValue?.aloneChecked" class="pt-8 pb-8" v-for="(item, index) in modeValue?.data" :key="index">
+            <text class="c-#666 f-s-28 mr-20">{{ item?.landName }}:</text>
+            <text v-if="+modeValue?.data?.[0]?.landType == 3" class="c-#333 f-s-28 f-w-5">{{ item?.capacityAmount }}{{ item?.capacityUnit }}</text>
+            <text v-else class="c-#333 f-s-28 f-w-5">{{ item?.area }}{{ item?.areaUnit }}</text>
+        </view>
+    </view>
+</template>
+<script setup lang="ts">
+// 定义props接口
+interface ModeValue {
+    baseName?: string;
+    area?: string | number;
+    areaUnit?: string;
+    address?: string;
+    adcodeName?: string;
+    gapFlag?: any;
+    swyqRes?: any;
+    aloneChecked?: boolean;
+    data?: any[];
+    // 保留原有字段以保持向后兼容
+    checkBox?: any[];
+    medicineName: string | null;
+    swyqMedicineName: string | null;
+}
+
+// 接收modeValue对象
+const props = withDefaults(
+    defineProps<{
+        modeValue?: ModeValue;
+        baseType: string;
+        showClose?: boolean;
+    }>(),
+    {
+        showClose: true,
+    },
+);
+// 定义emit事件
+const emit = defineEmits<{
+    (e: 'update:modeValue', value: ModeValue | null): void;
+    (e: 'close'): void;
+}>();
+
+// 处理关闭
+const handleClose = () => {
+    // 触发事件清空modeValue
+    emit('update:modeValue', null);
+    emit('close');
+};
+</script>
+
+<style scoped lang="scss">
+.label {
+    font-size: 24rpx;
+    color: #37a954;
+    border-radius: 100rpx;
+    background-color: #e3efe6;
+    width: max-content;
+    padding-left: 14rpx;
+    padding-right: 14rpx;
+    padding-top: 6rpx;
+    padding-bottom: 6rpx;
+}
+</style>

+ 329 - 0
src/plant/port/port-harvest-create/models/drawer.vue

@@ -0,0 +1,329 @@
+<template>
+    <up-popup :show="modelValue" mode="right" @close="handleClose" @open="handleOpen">
+        <ut-navbar :fixed="false" bgColor="transparent" :breadcrumb="false">
+            <template #left>
+                <view class="c-#333 f-s-34 f-w-5">请选择采收所在基地</view>
+            </template>
+        </ut-navbar>
+        <view class="h-86 pd-20 pt-0">
+            <ut-search ref="searchRef" v-model="form.keyword" @search="changeSeach" margin="0" :border="false" placeholder="搜基地名称、编号、地址、负责人" bgColor="#f7f7f7" height="86rpx" borderRadius="16rpx"></ut-search>
+        </view>
+        <view class="d-flex pl-20 mb-20">
+            <view class="f-s-26 w-90 h-54 radius-100 bg-#f7f7f7 d-flex a-c j-c mr-20 c-#333" @click="changeSelect(0)" :style="{ backgroundColor: activeSelect == 0 ? '#37A954' : '', color: activeSelect == 0 ? '#FFF' : '' }">全部</view>
+            <view class="f-s-26 w-150 h-54 radius-100 bg-#f7f7f7 d-flex a-c j-c mr-20 c-#333" @click="changeSelect(1)" :style="{ backgroundColor: activeSelect == 1 ? '#37A954' : '', color: activeSelect == 1 ? '#FFF' : '' }">GAP基地</view>
+            <view class="f-s-26 w-200 h-54 radius-100 bg-#f7f7f7 d-flex a-c j-c mr-20 c-#333" @click="changeSelect(2)" :style="{ backgroundColor: activeSelect == 2 ? '#37A954' : '', color: activeSelect == 2 ? '#FFF' : '' }">三无一全基地</view>
+        </view>
+        <view class="w-700 d-flex flex-cln" id="scroll">
+            <view class="d-flex">
+                <scroll-view class="w-50% bg-#f7f7f7 c-#fff" :style="`height: calc(100vh - 70px - ${top}px)`" scroll-y="true" @scrolltolower="scrolltolower">
+                    <view v-for="(item, index) in list" :key="index" class="border-#E6E6E6 pd-20 title" :class="{ activeTitle: activeBase == index }" @click="changeBase(index, item)">
+                        <view class="">
+                            <text class="base">{{ item?.baseName }}</text>
+                            <text class="area">{{ item?.gapInfo?.area }}{{ item?.gapInfo?.areaUnit }}</text>
+                        </view>
+                        <view class="pt-10 d-flex">
+                            <view v-if="+item?.gapFlag" class="label mr-10">GAP</view>
+                            <view v-if="+item?.swyqRes" class="label">三无一全</view>
+                        </view>
+                    </view>
+                </scroll-view>
+                <scroll-view class="w-50% pd-16" :style="`height: calc(100vh - ${top}px)`" scroll-y="true">
+                    <up-checkbox v-if="mixData.length > 0" label="全选" labelColor="#333" name="agree" usedAlone :checked="aloneChecked" @change="handleAllCheckboxChange"></up-checkbox>
+                    <!-- 复选框组包含全选框 -->
+                    <up-checkbox-group v-if="mixData.length > 0" activeColor="#37a954" :modelValue="checkBox" @change="handleCheckboxGroupChange" iconPlacement="right" placement="column">
+                        <up-checkbox v-for="(item, index) in mixData" :key="index" :name="item?.id" :label="item?.landName"></up-checkbox>
+                    </up-checkbox-group>
+                    <view v-if="mixData.length == 0 && showtitle" class="">请先在左侧添加选择基地,选择后此处将会展示地块/圈舍/组培架信息。</view>
+                </scroll-view>
+            </view>
+            <view v-if="medicineName || swyqMedicineName" class="w-700 c-primary bg-#EBF6EE f-s-24" style="position: fixed; bottom: 140rpx; right: 0">
+                <view class="pd4-10-20-10-20 d-flex a-c">
+                    <view class="">该基地获评:</view>
+                    <view class="" v-if="medicineName">{{ medicineName }}GAP基地</view>
+                    <view class="" v-if="medicineName && swyqMedicineName">和</view>
+                    <view class="" v-if="swyqMedicineName">{{ swyqMedicineName }}三无一全基地 </view>
+                </view>
+            </view>
+            <view class="w-700 bg-#fff h-100 d-flex a-c gap-20 pt-20 pb-20" style="position: fixed; bottom: 0; right: 0">
+                <up-button @click="handleClose" style="margin-left: 20rpx">取消</up-button>
+                <up-button type="primary" @click="confirm" style="margin-right: 20rpx">确定</up-button>
+            </view>
+        </view>
+    </up-popup>
+</template>
+<script setup lang="ts">
+import { useClientRequest } from '@/utils/request';
+import { ref, reactive, watch, computed } from 'vue';
+const instance = getCurrentInstance();
+const props = defineProps<{ modelValue: boolean; baseType?: string }>();
+const form = ref({
+    keyword: '',
+    tempFlag: 0,
+    gapFlag: '',
+    swyqRes: '',
+    plBaseType: props.baseType,
+});
+// 左侧基地列表数据
+const list = ref<any[]>([]);
+//左侧GAP基地的名称(种植的作物)
+const medicineName = ref<string>('');
+//左侧三无一全基地的名称
+const swyqMedicineName = ref<string>('');
+// 右侧地块数据
+const mixData = ref<any[]>([]);
+const showtitle = ref(true);
+// 当前选择基地
+const baseID = ref(-1);
+// 请求的次数
+const pageNum = ref(1);
+// 定义emit事件:通知父组件状态变化
+const emit = defineEmits<{
+    (e: 'update:modelValue', value: boolean): void;
+    (e: 'open'): void;
+    (e: 'close'): void;
+    (e: 'confirm', data: { medicineName: string; swyqMedicineName: string; checkBox: any[]; data: any[]; aloneChecked: boolean; baseName: string; area?: string; gapFlag: number; swyqRes: number; areaUnit: string; adcodeName: string; address: string }): void; // 新增
+}>();
+// 处理关闭事件
+function handleClose() {
+    emit('update:modelValue', false);
+    emit('close');
+}
+// 处理打开事件
+function handleOpen() {
+    emit('open');
+}
+// 处理切换搜索
+const activeSelect = ref(0);
+const changeSelect = (index: number) => {
+    if (activeSelect.value == index) return;
+    activeBase.value = -1;
+    activeSelect.value = index;
+    if (index == 0) {
+        form.value.gapFlag = '';
+        form.value.swyqRes = '';
+    } else if (index == 1) {
+        form.value.gapFlag = '1';
+        form.value.swyqRes = '';
+    } else if (index == 2) {
+        form.value.gapFlag = '';
+        form.value.swyqRes = '1';
+    }
+    baseID.value = -1;
+    pageNum.value = 1;
+    list.value = [];
+    mixData.value = [];
+    medicineName.value = '';
+    swyqMedicineName.value = '';
+    allCheckboxNames.value = [];
+    checkBox.value = [];
+    aloneChecked.value = false;
+    getBaseInfo(pageNum.value, 10);
+};
+
+// 处理搜索
+const changeSeach = () => {
+    console.log('搜索关键词:', form.value.keyword);
+    // 这里可以添加实际的搜索逻辑
+};
+// 切换基地>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+const activeBase = ref(-1);
+const changeBase = (index: number, item: any) => {
+    if (activeBase.value == index) return;
+    activeBase.value = index;
+    mixData.value = [];
+    baseID.value = item.id;
+    medicineName.value = '';
+    swyqMedicineName.value = '';
+    allCheckboxNames.value = [];
+    checkBox.value = [];
+    aloneChecked.value = false;
+    if (item.gapInfo?.medicineName) {
+        medicineName.value = item.gapInfo.medicineName;
+    }
+    if (item.gapInfo?.swyqMedicineName) {
+        swyqMedicineName.value = item.swyqMedicineName;
+    }
+};
+// 选择checkbox>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+// 所有复选框的name值
+let allCheckboxNames = ref<string[]>([]);
+let checkBox = ref<string[]>([]);
+const aloneChecked = ref(false);
+
+// 全选框change事件处理
+const handleAllCheckboxChange = (value: boolean) => {
+    aloneChecked.value = value;
+    if (value) {
+        // 全选:将checkBox设置为所有name
+        checkBox.value = [...allCheckboxNames.value];
+    } else {
+        // 取消全选:清空checkBox
+        checkBox.value = [];
+    }
+};
+
+// 复选框组change事件处理
+const handleCheckboxGroupChange = (value: string[]) => {
+    checkBox.value = value;
+    // 检查是否所有复选框都被选中
+    const allSelected = allCheckboxNames.value.every((name) => value.includes(name));
+    aloneChecked.value = allSelected;
+};
+const top = ref(0);
+
+//scroll-view滚动监听
+const scrolltolower = () => {
+    console.log('滚动到底部');
+    pageNum.value += 1;
+    getBaseInfo(pageNum.value, 10);
+};
+// 获取基地信息
+const getBaseInfo = async (pageNum: number, pageSize: number) => {
+    const params = {
+        pageNum,
+        pageSize,
+        ...form.value,
+        baseType: props.baseType,
+    };
+    const res = await useClientRequest.get('/plt-api/app/base/pageList', params);
+    if (res) {
+        const { rows } = res;
+        list.value.push(...rows);
+    }
+};
+// 提交
+const confirm = () => {
+    if (baseID.value == -1) {
+        uni.showToast({
+            title: '请选择基地',
+            icon: 'none',
+        });
+        return;
+    } else {
+        if (checkBox.value.length == 0) {
+            uni.showToast({
+                title: '请选择地块',
+                icon: 'none',
+            });
+            return;
+        }
+    }
+
+    // 通过 baseID 查找选中的基地
+    const selectedBase = list.value.find((item) => item.id === baseID.value);
+    //checkBox是一个数组,里边存的是mixData里的id,找到对应的id的mixData
+    const data = checkBox.value.map((id) => mixData.value.find((item) => item.id === id));
+    if (selectedBase) {
+        // 抛出对象给父组件
+        emit('confirm', {
+            baseName: selectedBase.baseName,
+            area: selectedBase.gapInfo?.area,
+            areaUnit: selectedBase.gapInfo?.areaUnit,
+            adcodeName: selectedBase.gapInfo?.adcodeName,
+            address: selectedBase.gapInfo?.address,
+            aloneChecked: aloneChecked.value,
+            gapFlag: selectedBase.gapFlag,
+            swyqRes: selectedBase.swyqRes,
+            swyqMedicineName: selectedBase.swyqMedicineName,
+            medicineName: selectedBase.gapInfo?.medicineName,
+            data: data,
+            checkBox: checkBox.value,
+        });
+    }
+
+    // 关闭抽屉
+    emit('update:modelValue', false);
+    emit('close');
+};
+watch(
+    () => baseID.value,
+    async () => {
+        if (baseID.value == -1) {
+            showtitle.value = true;
+            return;
+        }
+        showtitle.value = false;
+        const res = await useClientRequest.get('/plt-api/app/baseLandInfo/pageList', { baseId: baseID.value });
+        mixData.value = [];
+        const { rows } = res;
+        mixData.value = rows;
+        allCheckboxNames.value = [];
+        checkBox.value = [];
+        aloneChecked.value = false;
+        mixData.value.forEach((item) => {
+            allCheckboxNames.value.push(item.id);
+        });
+        showtitle.value = true;
+    },
+);
+onMounted(() => {
+    const querys = uni.createSelectorQuery().in(instance?.proxy);
+    querys
+        .select('#scroll')
+        .boundingClientRect((data: any) => {
+            top.value = data.top;
+        })
+        .exec();
+    getBaseInfo(pageNum.value, 10);
+});
+</script>
+<style scoped lang="scss">
+:deep(.u-border-bottom) {
+    border-color: transparent !important;
+}
+.title {
+    .base {
+        font-size: 28rpx;
+        color: #333;
+        font-weight: 500;
+        margin-right: 20rpx;
+        word-break: break-all;
+    }
+    .area {
+        font-size: 24rpx;
+        color: #999;
+    }
+    .label {
+        font-size: 24rpx;
+        color: #37a954;
+        border-radius: 100rpx;
+        background-color: #e3efe6;
+        width: max-content;
+        padding-left: 14rpx;
+        padding-right: 14rpx;
+        padding-top: 6rpx;
+        padding-bottom: 6rpx;
+    }
+}
+.activeTitle {
+    background-color: #37a954;
+    .base {
+        font-size: 28rpx;
+        color: #fff;
+        font-weight: 500;
+        margin-right: 20rpx;
+    }
+    .area {
+        font-size: 24rpx;
+        color: #ebf6ee;
+    }
+    .label {
+        font-size: 24rpx;
+        color: #fff;
+        border-radius: 100rpx;
+        background-color: #5fba76;
+        width: max-content;
+        padding-left: 14rpx;
+        padding-right: 14rpx;
+        padding-top: 6rpx;
+        padding-bottom: 6rpx;
+    }
+}
+:deep(.u-checkbox-label--left) {
+    flex-direction: row-reverse !important;
+}
+:deep(.u-checkbox__icon-wrap) {
+    margin-right: 0 !important;
+    margin-left: 10px;
+}
+</style>

+ 18 - 0
src/plant/port/port-harvest-create/models/go_button.vue

@@ -0,0 +1,18 @@
+<template>
+    <up-button type="primary" @click="click" plain>
+        <image class="w-36 h-36 mr-10" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/common/select_push_icon.png" mode="widthFix" />
+        <span>{{ title }}</span>
+    </up-button>
+</template>
+<script setup lang="ts">
+const props = defineProps({
+    title: {
+        type: String,
+        default: '',
+    },
+});
+const emit = defineEmits(['click']);
+const click = () => {
+    emit('click');
+};
+</script>

+ 58 - 0
src/plant/port/port-harvest-create/models/individualinfo.vue

@@ -0,0 +1,58 @@
+<template>
+    <view class="d-flex j-sb b-radius border-#AFDDBB bg-#FBFDFB mb-20 pd-24 p-rtv" v-for="(item, index) in modelValue?.checkBox" :key="index">
+        <view v-if="showClose" @click="handleDelete(index)" class="d-flex j-c a-c c-#FF4444 f-s-28" style="position: absolute; top: 10rpx; right: 10rpx">
+            <up-icon name="close" color="#FF4444" size="12"></up-icon>
+        </view>
+        <view class="flex1 ov-hd">
+            <view class="ov-hd tx-ov d-flex a-c">
+                <view class="c-primary f-s-24 f-w-5 bg-#EBF6EE pd4-4-12-4-6 b-radius" style="font-style: italic">{{ Number(index) + 1 < 10 ? '0' + (Number(index) + 1) : Number(index) + 1 }}</view>
+                <view class="w-10"></view>
+                <view class="c-#333 f-w-5 f-s-34 tx-ov ov-hd">{{ modelValue?.variety }}</view>
+            </view>
+            <view class="d-flex a-c pt-10">
+                <text class="c-#666 f-s-24 tx-ov ov-hd">{{ item }}</text>
+            </view>
+        </view>
+    </view>
+</template>
+<script setup lang="ts">
+const props = withDefaults(
+    defineProps<{
+        modelValue: any;
+        landIds?: any[];
+        showClose?: boolean;
+    }>(),
+    {
+        showClose: true,
+    },
+);
+
+const emit = defineEmits<{
+    'update:modelValue': [value: any];
+    'update:landIds': [value: any[]];
+}>();
+
+const handleDelete = (index: number) => {
+    if (!props.modelValue || !props.modelValue.checkBox) return;
+
+    // 创建新的checkBox数组,移除指定索引的元素
+    const newCheckBox = [...props.modelValue.checkBox];
+    newCheckBox.splice(index, 1);
+
+    // 创建新的对象,保持其他属性不变
+    const newValue = {
+        ...props.modelValue,
+        checkBox: newCheckBox,
+    };
+
+    // 触发更新事件
+    emit('update:modelValue', newValue);
+
+    // 同时更新landIds,确保与checkBox保持一致
+    if (props.landIds && Array.isArray(props.landIds)) {
+        const newLandIds = [...props.landIds];
+        newLandIds.splice(index, 1);
+        emit('update:landIds', newLandIds);
+    }
+};
+</script>

+ 252 - 0
src/plant/port/port-harvest-detail/index.vue

@@ -0,0 +1,252 @@
+<template>
+    <z-paging ref="paging" bgColor="#f7f7f7" safe-area-inset-bottom>
+        <template #top>
+            <ut-navbar title="采收记录详情" :fixed="false"></ut-navbar>
+        </template>
+        <template>
+            <view class="startline-title pl-24 ml-24 mb-16">采收信息</view>
+            <view class="bg-#fff pd-24 mb-16">
+                <view class="pb-16 info-border-bottom">
+                    <text class="c-#666 f-s-30">采收类型:</text>
+                    <text class="c-#333 f-s-30 f-w-5">{{ form?.outputType ? selectDictLabel(pt_output_type, form?.outputType) : '--' }}</text>
+                </view>
+                <template v-if="+form?.outputType == 1">
+                    <view class="pt-16 pb-16 info-border-bottom">
+                        <text class="c-#666 f-s-30">种源类型:</text>
+                        <text class="c-#333 f-s-30 f-w-5">{{ form?.seedType ? selectDictLabel(pt_seed_type, form?.seedType) : '--' }}</text>
+                    </view>
+                    <view v-if="form?.seedType == 'A4' || form?.seedType == 'A8'" class="pt-16 pb-16 info-border-bottom">
+                        <text class="c-#666 f-s-30">菌种/菌株编号:</text>
+                        <text class="c-#333 f-s-30 f-w-5">{{ form?.fungusCode || '-' }}</text>
+                    </view>
+                </template>
+                <view class="pt-16 pb-16 info-border-bottom">
+                    <text class="c-#666 f-s-30">采收日期:</text>
+                    <text class="c-#333 f-s-30 f-w-5">{{ form?.harvestDate ? `${form?.harvestDate} 至 ${form?.harvestDateEnd || '无'}` : '-' }}</text>
+                </view>
+                <view v-if="+form?.outputType == 2" class="pt-16 pb-16 info-border-bottom">
+                    <text class="c-#666 f-s-30">采收部位:</text>
+                    <text class="c-#333 f-s-30 f-w-5">{{ form?.harvestPartName || '-' }}</text>
+                </view>
+                <view class="pt-16 pb-16 info-border-bottom">
+                    <text class="c-#666 f-s-30">采收批号:</text>
+                    <text class="c-#333 f-s-30 f-w-5">{{ form?.harvestCode || '-' }}</text>
+                </view>
+                <view class="pt-16 pb-16 info-border-bottom">
+                    <text class="c-#666 f-s-30">采收量:</text>
+                    <text class="c-#333 f-s-30 f-w-5">{{ form?.quantity ? `${form?.quantity}${form?.unit ? selectDictLabel(pt_seed_unit, form?.unit) : ''}` : '-' }}</text>
+                </view>
+                <view class="pt-16 pb-16 info-border-bottom">
+                    <text class="c-#666 f-s-30">采收负责人:</text>
+                    <text class="c-#333 f-s-30 f-w-5">{{ form?.mgrName || '-' }}</text>
+                </view>
+                <view class="pt-16 pb-16 info-border-bottom">
+                    <text class="c-#666 f-s-30">采收方式:</text>
+                    <text class="c-#333 f-s-30 f-w-5">{{ form?.harvestType ? selectDictLabel(pt_harvest_type, form?.harvestType) : '-' }}</text>
+                </view>
+                <view class="pt-16 pb-16 info-border-bottom">
+                    <text class="c-#666 f-s-30">采收{{ landIdsTitle }}:</text>
+                    <template v-if="+form?.mgMethod !== 2">
+                        <!-- <text class="c-#333 f-s-30 f-w-5" v-if="+form?.landFlag">全部{{ landIdsTitle }}</text> -->
+                        <view class="c-#333 f-s-28 f-w-5 d-flex a-c w-s-no tx-ov ov-hd">
+                            <template v-if="form?.lands?.length == 0">
+                                <text>{{ '-' }}</text>
+                            </template>
+                            <view v-else class="w-100%">
+                                <Baseinfo v-if="deawerData" :modeValue="deawerData" :baseType="form.taskType" :showClose="false" />
+                            </view>
+                        </view>
+                    </template>
+                    <template v-else>
+                        <view class="c-#333 f-s-28 f-w-5 d-flex a-c w-s-no tx-ov ov-hd">
+                            <template v-if="form?.animalIds?.length == 0">
+                                <text>{{ '-' }}</text>
+                            </template>
+                            <view v-else v-for="(data, indexs) in form?.animalIds">
+                                <text v-if="indexs !== 0">、</text>
+                                <text>{{ data }}</text>
+                            </view>
+                        </view>
+                    </template>
+                </view>
+                <view class="d-flex flex-cln pt-16 pb-16 info-border-bottom">
+                    <text class="c-#666 f-s-30 mb-10">采收图片:</text>
+                    <ut-album v-if="form?.imgs?.length > 0" :urls="form?.imgs"></ut-album>
+                    <text v-else class="c-#999 f-s-30">-</text>
+                </view>
+                <view class="d-flex flex-cln pt-16 pb-16 info-border-bottom">
+                    <text class="c-#666 f-s-30 mb-10">采收视频:</text>
+                    <ut-album v-if="form?.videos?.length > 0" :urls="form?.videos" :video="true"></ut-album>
+                    <text v-else class="c-#999 f-s-30">-</text>
+                </view>
+                <view v-if="+form?.outputType == 1" class="d-flex flex-cln pt-16 pb-16 info-border-bottom">
+                    <text class="c-#666 f-s-30 mb-10">种源加工处理工艺:</text>
+                    <view v-if="form?.ptech" class="d-flex a-c flex-wrap gap-10">
+                        <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>
+                            <span class="f-s-32">{{ item }}</span>
+                        </template>
+                    </view>
+                    <text v-else class="c-#999 f-s-30">--</text>
+                </view>
+                <view class="pt-16 pb-16 info-border-bottom">
+                    <text class="c-#666 f-s-30">最新修改人:</text>
+                    <text class="c-#333 f-s-30 f-w-5">{{ form?.operatorName || '-' }}</text>
+                </view>
+                <view class="pt-16 pb-16 info-border-bottom">
+                    <text class="c-#666 f-s-30">最新修改时间:</text>
+                    <text class="c-#333 f-s-30 f-w-5">{{ form?.updateTime || form?.createTime || '-' }}</text>
+                </view>
+                <view class="d-flex j-c pt-32">
+                    <up-button type="primary" class="b-radius w-300 h-80 f-s-32" @click="handleEdit">修改</up-button>
+                </view>
+            </view>
+            <!-- 存放信息区块 -->
+            <view class="startline-title pl-24 ml-24 mb-16">存放信息</view>
+            <view class="bg-#fff pd-24">
+                <view class="mb-10">
+                    <span class="f-s-34 c-#333 f-w-500 mr-10">{{ storageInfo?.variety }}</span>
+                    <span class="f-s-24 c-#666" v-if="storageInfo?.seedType">{{ selectDictLabel(pt_seed_type, storageInfo?.seedType) }}</span>
+                    <span class="f-s-24 c-#666" v-else>{{ storageInfo?.partName }}</span>
+                </view>
+                <view class="pd2-4-0 f-s-28">
+                    <span class="c-#666">采收批号:</span>
+                    <span class="c-#333 f-w-500">{{ form?.harvestCode || '-' }}</span>
+                </view>
+                <view class="pd2-4-0 f-s-28">
+                    <span class="c-#666">存放库房:</span>
+                    <span class="c-#333 f-w-500">{{ getStorageRoomNames(storageInfo?.warehouses) || '-' }}</span>
+                </view>
+                <view class="pd2-4-0 f-s-28">
+                    <span class="c-#666">入库量:</span>
+                    <span class="c-#333 f-w-500">{{ storageInfo?.capacity }}{{ storageInfo?.unit }}</span>
+                </view>
+                <view class="d-flex">
+                    <view v-if="storageInfo?.inputAmount" class="pd2-4-0 f-s-28 flex1">
+                        <span class="c-#666">出库量:</span>
+                        <span class="c-#333 f-w-500">{{ storageInfo?.inputAmount || '0' }}{{ storageInfo?.unit }}</span>
+                    </view>
+                    <view v-if="storageInfo?.restAmount" class="pd2-4-0 f-s-28 flex1">
+                        <span class="c-primary">剩余量:</span>
+                        <span class="c-primary f-w-500">{{ storageInfo?.restAmount || '0' }}{{ storageInfo?.unit }}</span>
+                    </view>
+                </view>
+                <view class="pd3-20-40-0">
+                    <up-button type="primary" :customStyle="{ background: '#ebf6ee', borderColor: '#3FAD5B' }" style="color: #3fad5b">去库房查看详细信息{{ '>' }}</up-button>
+                </view>
+            </view>
+        </template>
+    </z-paging>
+</template>
+
+<script setup lang="ts">
+import { ref, getCurrentInstance, type ComponentInternalInstance } from 'vue';
+import { useClientRequest } from '@/utils/request';
+import { getStorageRoomNames } from '@/utils/common';
+import Baseinfo from '../port-create/models/baseinfo.vue';
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { pt_output_type, pt_seed_type, pt_seed_unit, pt_harvest_type, pt_fungus_code_type } = toRefs<any>(proxy?.useDict('pt_output_type', 'pt_seed_type', 'pt_seed_unit', 'pt_harvest_type', 'pt_fungus_code_type'));
+
+// 表单数据
+const form = ref<any>();
+
+// 存放信息
+const storageInfo = ref<any>({
+    warehouseName: '',
+    quantity: '',
+    unit: '',
+    usedQuantity: '',
+    remainingQuantity: '',
+});
+
+const landIdsTitle = ref('地块');
+const recordId = ref('');
+const deawerData = ref<any>(null);
+// 获取详情
+const getDetail = async () => {
+    try {
+        const res = await useClientRequest.get(`/plt-api/app/harvestRecord/getInfo/${recordId.value}`);
+        if (res.code === 200 && res.data) {
+            form.value = res.data;
+            // 获取存放信息
+            if (res.data.outputType == '1') {
+                const storageRes = await useClientRequest.get(`/plt-api/app/storageSeed/getByHarvestId/${recordId.value}`);
+                if (storageRes.code === 200 && storageRes.data) {
+                    storageInfo.value = storageRes.data;
+                }
+            } else {
+                const storageRes = await useClientRequest.get(`/plt-api/app/storage/getByHarvestId/${recordId.value}`);
+                if (storageRes.code === 200 && storageRes.data) {
+                    storageInfo.value = storageRes.data;
+                }
+            }
+            // 设置地块/个体标题
+            if (+res.data.mgMethod === 2) {
+                landIdsTitle.value = '个体';
+            } else if (+res.data?.baseInfo?.baseType == 1) {
+                landIdsTitle.value = '地块';
+            } else if (+res.data?.baseInfo?.baseType == 2) {
+                landIdsTitle.value = '圈舍';
+            } else {
+                landIdsTitle.value = '培养架';
+            }
+            if (res.data?.lands.length > 0) {
+                deawerData.value = {};
+                deawerData.value.baseName = res.data?.baseInfo?.baseName;
+                deawerData.value.areaUnit = res.data?.baseInfo?.gapInfo.areaUnit;
+                deawerData.value.area = res.data?.baseInfo?.gapInfo.area;
+                deawerData.value.address = res.data?.baseInfo?.gapInfo.address;
+                if (+res.data?.landFlag) {
+                    deawerData.value.aloneChecked = true;
+                } else {
+                    deawerData.value.aloneChecked = false;
+                }
+                deawerData.value.data = res.data?.lands;
+            }
+        }
+    } catch (error) {
+        console.error('获取详情失败:', error);
+        uni.showToast({
+            title: '获取详情失败',
+            icon: 'none',
+        });
+    }
+};
+
+// 修改
+const handleEdit = () => {
+    uni.$u.route({
+        type: 'navigateTo',
+        url: '/plant/port/port-harvest-create/index',
+        params: { recordId: recordId.value, change: true, ...form.value },
+    });
+};
+
+// 去库房详情
+const goStorageDetail = () => {
+    if (storageInfo.value.warehouseId) {
+        uni.$u.route({
+            type: 'navigateTo',
+            url: '/plant/storage/storage-room/index',
+            params: {
+                id: storageInfo.value.warehouseId,
+            },
+        });
+    } else {
+        uni.showToast({
+            title: '暂无库房信息',
+            icon: 'none',
+        });
+    }
+};
+
+onLoad((options: any) => {
+    recordId.value = options?.id || '';
+    if (recordId.value) {
+        getDetail();
+    }
+    uni.$on('updateharvestdetail', () => {
+        getDetail();
+    });
+});
+</script>

+ 62 - 57
src/plant/port/port-harvest/index.vue

@@ -1,5 +1,5 @@
 <template>
-    <z-paging ref="paging" v-model="list" bgColor="#f7f7f7" @query="query" safe-area-inset-bottom empty-view-text="该任务暂未关联种源信息">
+    <z-paging ref="paging" v-model="list" bgColor="#f7f7f7" @query="query" safe-area-inset-bottom empty-view-text="该任务暂无采收入库记录">
         <template #top>
             <ut-navbar title="采收管理" :fixed="false"> </ut-navbar>
         </template>
@@ -14,43 +14,60 @@
                     </view>
                 </view>
             </view>
-            <view class="pd-10"></view>
             <up-swipe-action>
                 <up-swipe-action-item v-for="(item, index) in list" :key="index" :name="item?.id" :options="options2" class="mb-20" @click="clickTempSwipe">
                     <view class="bg-#fff b-radius pd-24" @click="gotoDetail(item)">
                         <view class="d-flex a-c j-sb">
                             <view class="d-flex a-c">
-                                <view class="f-s-34 f-w-5 pb-10 mr-10">{{ item?.seedInfo?.variety }}</view>
-                                <view class="f-s-24 c-#666">{{ selectDictLabel(pt_seed_type, item?.seedInfo?.seedType) }}</view>
+                                <view class="f-s-34 f-w-5 pb-10 mr-10">采收{{ selectDictLabel(pt_seed_type, item?.seedType) || '药材' }}</view>
                             </view>
                             <view class="d-flex a-c">
-                                <view class="f-s-22 c-#666">{{ item?.seedInfo?.updateTime || item?.seedInfo?.createTime }}</view>
+                                <view class="f-s-22 c-#666">{{ item?.updateTime || item?.createTime }}</view>
                             </view>
                         </view>
                         <view class="d-flex pd4-8-0-8-0">
-                            <view class="c-#666 f-s-28 w-s-no">入库批号:</view>
-                            <view class="c-#333 f-s-28 f-w-5 w-s-no tx-ov ov-hd">{{ item?.seedInfo?.batchCode }}</view>
+                            <view class="c-#666 f-s-28 w-s-no">采收批号:</view>
+                            <view class="c-#333 f-s-28 f-w-5 w-s-no tx-ov ov-hd">{{ item?.harvestCode }}</view>
                         </view>
                         <view class="d-flex pd4-8-0-8-0">
-                            <view class="c-#666 f-s-28 w-s-no">供应商:</view>
-                            <view class="c-#333 f-s-28 f-w-5 w-s-no tx-ov ov-hd">{{ item?.seedInfo?.supplierInfo?.cusName || '-' }}</view>
+                            <view class="c-#666 f-s-28 w-s-no">采收量:</view>
+                            <view class="c-#333 f-s-28 f-w-5 w-s-no tx-ov ov-hd">{{ item?.quantity }}{{ item?.unit }}</view>
                         </view>
-                        <view class="d-flex pd4-8-0-8-0">
-                            <view class="c-primary f-s-28 w-s-no">投入量:</view>
-                            <view class="c-primary f-s-28 f-w-5 w-s-no tx-ov ov-hd">{{ item?.amount }}{{ item?.seedInfo?.unit }}</view>
+                        <view v-if="+item?.mgMethod !== 2" class="d-flex pd4-8-0-8-0">
+                            <view class="c-#666 f-s-28 w-s-no">操作{{ +taskDate?.baseType == 1 ? '地块' : +taskDate?.baseType == 2 ? '圈舍' : '培养架' }}:</view>
+                            <view class="c-#333 f-s-28 f-w-5" v-if="+item?.landFlag">全部{{ +taskDate?.baseType == 1 ? '地块' : +taskDate?.baseType == 2 ? '圈舍' : '培养架' }}</view>
+                            <view class="c-#333 f-s-28 f-w-5 d-flex a-c w-s-no tx-ov ov-hd" v-else>
+                                <template v-if="item?.lands?.length == 0">
+                                    <text>{{ '-' }}</text>
+                                </template>
+                                <view v-else v-for="(data, indexs) in item?.lands">
+                                    <text v-if="indexs !== 0">、</text>
+                                    <text>{{ data?.landName }}</text>
+                                </view>
+                            </view>
                         </view>
-                        <view class="d-flex pd4-8-0-8-0">
-                            <view class="c-#666 f-s-28 w-s-no">备注/说明:</view>
-                            <view class="c-#333 f-s-28 f-w-5 w-s-no tx-ov ov-hd">{{ item?.remark || '-' }}</view>
+                        <view v-else class="d-flex pd4-8-0-8-0">
+                            <view class="c-#666 f-s-28 w-s-no">操作个体:</view>
+                            <template v-if="item?.animalIds?.length == 0">
+                                <text>{{ '-' }}</text>
+                            </template>
+                            <view v-else v-for="(data, indexs) in item?.animalIds">
+                                <text v-if="indexs !== 0">、</text>
+                                <text class="c-#333 f-s-28 f-w-5">{{ data }}</text>
+                            </view>
+                        </view>
+                        <view v-if="item?.outputType == 1" class="d-flex pd4-8-0-8-0">
+                            <view class="c-#666 f-s-28 w-s-no">种源处理工艺:</view>
+                            <view class="c-#333 f-s-28 f-w-5 w-s-no tx-ov ov-hd">{{ item?.ptech?.split(',').join('、') || '-' }}</view>
                         </view>
                         <view class="d-flex">
-                            <view class="pd2-4-0 f-s-24 w-40%">
-                                <span class="c-#666">记录人:</span>
-                                <span class="c-#666">{{ item?.seedInfo?.createByName || '-' }}</span>
+                            <view class="pd2-4-0 f-s-28 w-40%">
+                                <span class="c-#666">采收方式:</span>
+                                <span class="c-#333 f-w-5">{{ selectDictLabel(pt_harvest_type, item?.harvestType) || '-' }}</span>
                             </view>
-                            <view class="pd2-4-0 f-s-24 flex1">
-                                <span class="c-#666">操作时间:</span>
-                                <span class="c-#666">{{ item?.seedInfo?.updateTime || item?.seedInfo?.createTime }}</span>
+                            <view class="pd2-4-0 f-s-28 flex1">
+                                <span class="c-#666">采收负责人:</span>
+                                <span class="c-#333 f-w-5">{{ item?.mgrName }}</span>
                             </view>
                         </view>
                     </view>
@@ -63,47 +80,40 @@
 import { useClientRequest } from '@/utils/request';
 import Task_card from './models/task_card.vue';
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const { pt_seed_type, pt_breed_op_method, pt_raise_op_method } = toRefs<any>(proxy?.useDict('pt_seed_type', 'pt_breed_op_method', 'pt_raise_op_method'));
+const { pt_seed_type, pt_harvest_type, pt_raise_op_method } = toRefs<any>(proxy?.useDict('pt_seed_type', 'pt_harvest_type', 'pt_raise_op_method'));
 const paging = ref();
 const list = ref<any>([]);
 const taskId = ref('');
 const taskDate = ref<any>();
 const from = ref({
     keyword: '',
-    activityType: '',
 });
 const query = async (pageNo: number, pageSize: number) => {
-    const res = await useClientRequest.get(`/plt-api/app/seedInfo/getSeedInfoList/${taskId.value}`, {
+    const res = await useClientRequest.get(`/plt-api/app/harvestRecord/list`, {
         pageNo,
         pageSize,
         ...from.value,
         taskId: taskId.value,
     });
-    console.log(res, 'res');
-
     if (res) {
-        const { data } = res;
-        paging.value.complete(data);
+        const { rows } = res;
+        paging.value.complete(rows);
     }
 };
 // 添加种源信息
 const addManagementRecord = () => {
     uni.$u.route({
         type: 'navigateTo',
-        url: '/tools/species-info/index',
-        params: { taskId: taskId.value },
+        url: '/plant/port/port-harvest-create/index',
+        params: { taskId: taskId.value, ...taskDate.value },
     });
 };
-
-const changeSeach = async () => {
-    paging.value.reload();
-};
 const options2 = reactive([
     {
         text: '撤回采收入库',
         style: {
             backgroundColor: '#F74C30',
-            width: '80rpx',
+            width: '100rpx',
             fontSize: '28rpx',
         },
     },
@@ -113,15 +123,15 @@ const clickTempSwipe = async (event: object) => {
     try {
         const res = await uni.showModal({
             title: '撤回提示',
-            content: '删除后,删除的物料将自动退回相应库存。不能恢复,请谨慎操作!',
+            content: '撤回采收,将同步撤回删除入库存放信息,不能恢复,请谨慎操作!',
             confirmColor: '#f56c6c',
         });
         if (!res.confirm) return;
         await uni.showLoading({
-            title: '删除中...',
+            title: '撤回中...',
             mask: true,
         });
-        await useClientRequest.get(`/plt-api/app/seedInfo/deleteSeedInfo/${name}`);
+        await useClientRequest.get(`/plt-api/app/harvestRecord/delete/${name}`);
         uni.hideLoading();
         uni.showToast({
             title: '删除成功',
@@ -133,23 +143,13 @@ const clickTempSwipe = async (event: object) => {
     }
 };
 const gotoDetail = async (item: any) => {
-    if (item?.activityType == '2') {
-        uni.$u.route({
-            type: 'navigateTo',
-            url: `/plant/port/supervise/supervise-material-detail/index`,
-            params: {
-                id: item?.id,
-            },
-        });
-    } else if (item?.activityType == '1') {
-        uni.$u.route({
-            type: 'navigateTo',
-            url: `/plant/port/supervise/supervise-plant-detail/index`,
-            params: {
-                id: item?.id,
-            },
-        });
-    }
+    uni.$u.route({
+        type: 'navigateTo',
+        url: `plant/port/port-harvest-detail/index`,
+        params: {
+            id: item?.id,
+        },
+    });
 };
 onMounted(async () => {
     const res = await useClientRequest.get(`/plt-api/app/plantationTask/getInfo/${taskId.value}`, {
@@ -160,9 +160,14 @@ onMounted(async () => {
 });
 onLoad((options: any) => {
     taskId.value = options?.id;
-    //接收 uni.$emit('updatesuperviselist');
-    uni.$on('updatesuperviselist', () => {
+    //接收 uni.$emit('updateharvestlist');
+    uni.$on('updateharvestlist', () => {
         paging.value?.reload();
     });
 });
 </script>
+<style lang="scss">
+:deep(.u-swipe-action-item__right__button__wrapper__text) {
+    white-space: normal;
+}
+</style>

binární
src/static/images/common/craftArrow.png


+ 145 - 0
src/tools/pro-process-steps/index.vue

@@ -0,0 +1,145 @@
+<template>
+    <z-paging ref="paging" safe-area-inset-bottom v-model="list">
+        <template #top>
+            <ut-navbar title="加工工艺及步骤" :fixed="false"></ut-navbar>
+            <view class="pd-24 bg-#fff">
+                <view class="c-#333 f-s-26 f-w-5 pb-10">已选择工艺步骤</view>
+                <scroll-view scroll-y v-if="ptechTransit?.length > 0" style="max-height: 360rpx" class="border-#37A954 b-radius">
+                    <view style="max-height: 360rpx" class="d-flex flex-wrap pd-24 a-c gap-10">
+                        <template v-for="(item, index) in ptechTransit?.split(',')" :key="index">
+                            <image v-if="index !== 0" src="@/static/images/common/craftArrow.png" class="mr-10 ml-10" style="width: 44rpx; height: 44rpx"> </image>
+                            <view class="p-rtv">
+                                <up-icon color="red" name="close-circle-fill" @click="removePtech(index)" style="position: absolute; right: -10rpx; top: -10rpx"></up-icon>
+                                <view class="pd-16 bg-#37A9541A c-primary b-radius mb-10"> {{ item }}</view>
+                            </view>
+                        </template>
+                    </view>
+                </scroll-view>
+                <view v-else class="pd-24 a-c border-#37A954 b-radius h-84">
+                    <view class="f-s-26 c-#ccc">请按照顺序,点击下方工艺或者自填进行添加工艺</view>
+                </view>
+                <view class="h-16"></view>
+                <up-button type="primary" @click="changePtech">确认</up-button>
+            </view>
+            <view class="">
+                <up-tabs :list="list1" @change="changeType" lineWidth="30" :current="activetab"></up-tabs>
+            </view>
+        </template>
+        <view class="">
+            <view class="pd-24 pt-0 d-flex flex-cln">
+                <template v-if="+activetab == 0">
+                    <view v-if="commonly?.length > 0" class="pt-16 d-flex flex-wrap gap-16" style="justify-content: start">
+                        <view v-for="(item, idnex) in commonly" :key="idnex" class="bg-#fff c-#333 radius-10 pd4-16-24-16-24 mb-16" @click="unAddPtech(item)">
+                            {{ item }}
+                        </view>
+                    </view>
+                    <template v-else>
+                        <ut-empty class="mg-at mt-30" color="#ccc" size="28rpx">暂无常用加工工艺</ut-empty>
+                    </template>
+                </template>
+                <template v-if="+activetab == 1">
+                    <view class="d-flex flex-cln" style="justify-content: start">
+                        <view v-for="(item, idnexs) in ptechData" :key="idnexs">
+                            <view class="pt-16 pb-16">{{ item?.dictTypeLabel }}</view>
+                            <view class="d-flex flex-wrap gap-16">
+                                <view v-for="(items, idnex) in item?.childVos" :key="idnex" class="bg-#fff c-#333 radius-10 pd4-16-24-16-24 mb-10" @click="addPtech(items?.dictLabel)">
+                                    {{ items?.dictLabel }}
+                                </view>
+                            </view>
+                        </view>
+                    </view>
+                </template>
+                <template v-if="+activetab == 2">
+                    <view class="d-flex flex-cln">
+                        <view class="pt-16 f-s-28">加工工艺名称</view>
+                        <view class="d-flex flex-wrap gap-16 f-s-28">
+                            <up-input v-model="temPtech" clearable border="bottom" placeholder="请输入加工工艺名称">
+                                <template #suffix>
+                                    <up-button type="primary" @click="addPtech(temPtech)" style="height: 60rpx; width: 120rpx; font-size: 22rpx">确认添加</up-button>
+                                </template>
+                            </up-input>
+                        </view>
+                    </view>
+                </template>
+            </view>
+        </view>
+    </z-paging>
+</template>
+<script setup lang="ts">
+import { useClientRequest } from '@/utils/request';
+const list = ref<any>();
+const ptechTransit = ref<string>('');
+const activetab = ref<number>(0);
+const STORAGE_KEY = 'pro-process-steps-cache';
+const temPtech = ref<string>('');
+const list1 = reactive([
+    { name: '常用', value: 0 },
+    { name: '工艺库', value: 1 },
+    { name: '自行填写工艺', value: 2 },
+]);
+const changeType = (tabItem: any) => {
+    console.log(tabItem, 'tabItem');
+
+    activetab.value = tabItem?.value;
+};
+const commonly = ref<string[]>([]);
+const ptechData = ref<any[]>([]);
+const removePtech = (index: number) => {
+    if (!ptechTransit.value) return;
+    const lists = ptechTransit.value.split(',');
+    lists.splice(index, 1);
+    ptechTransit.value = lists.join(',');
+};
+const addPtech = (item: string) => {
+    // 从缓存读取现有数据
+    let cached = uni.getStorageSync(STORAGE_KEY) || '';
+    let items = cached ? cached.split(',') : [];
+    // 去重:如果已存在相同的 item,先移除
+    const index = items.indexOf(item);
+    if (index > -1) {
+        items.splice(index, 1);
+    }
+    // 添加新的 item
+    items.push(item);
+
+    // 限制最多40个:如果超过,移除最旧的(第一个)
+    const MAX_ITEMS = 40;
+    if (items.length > MAX_ITEMS) {
+        items.splice(0, items.length - MAX_ITEMS); // 移除超出部分
+    }
+
+    // 更新缓存和UI
+    const newCached = items.join(',');
+    uni.setStorageSync(STORAGE_KEY, newCached);
+    commonly.value = items;
+    ptechTransit.value = ptechTransit.value ? `${ptechTransit.value},${item}` : item;
+    temPtech.value = '';
+};
+//不存储在缓存中
+const unAddPtech = (item: string) => {
+    ptechTransit.value = ptechTransit.value ? `${ptechTransit.value},${item}` : item;
+};
+const query = async () => {
+    const res = await useClientRequest.get(`/plt-api/app/process/tech/listAllGroup`);
+    ptechData.value = res?.data;
+};
+
+const changePtech = () => {
+    uni?.$emit('updatePtechTransit', {
+        data: ptechTransit.value,
+    });
+    setTimeout(() => {
+        uni.navigateBack({
+            delta: 1,
+        });
+    }, 1000);
+};
+
+onLoad((options) => {
+    query();
+    ptechTransit.value = options?.ptechTransit;
+    let cached = uni.getStorageSync(STORAGE_KEY) || '';
+    commonly.value = cached ? cached.split(',') : [];
+    console.log(commonly.value, 'commonly.value');
+});
+</script>

+ 1 - 1
src/tools/supervise-individual/index.vue

@@ -40,7 +40,7 @@
                     <view class="d-flex c-primary f-s-26">
                         <text>已选择:</text>
                         <text>{{ checkboxValue.length }}</text>
-                        <text>个地块</text>
+                        <text>个个体</text>
                     </view>
                     <view class="d-flex a-c">
                         <view class="c-#333 f-s-28 mr-10">全选</view>