ソースを参照

Merge branch 'master' of http://git.yujin.shuziyunyao.com/yujin/forestry-wx

lisy 1 ヶ月 前
コミット
a7d8a1ff26

+ 1 - 1
src/audit/plant/base/audit-detail/models/gap-detail.vue

@@ -186,7 +186,7 @@ const noPassAudit = async () => {
             res: '2',
             ...formNoPass.value,
         });
-        if (!res || res !== 200) return;
+        if (!res || res.code !== 200) return;
         uni.hideLoading();
         uni.showToast({
             title: '操作成功',

+ 126 - 0
src/models/select-medicinal-part/select-medicinal-part.vue

@@ -0,0 +1,126 @@
+<template>
+    <view @click="showPart = true">
+        <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;">
+            <up-navbar :fixed="false" border>
+                <template #left>
+                    <view class="f-s-34 c-#333 f-w-500">{{ title }}</view>
+                </template>
+            </up-navbar>
+            <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>
+                    </template>
+                </scroll-view>
+                <scroll-view class="flex1" scroll-y style="height: 100%">
+                    <view class="pd2-12-24">
+                        <up-radio-group v-model="value" iconPlacement="right" placement="column">
+                            <template v-for="son in mapGroupSons[groupId]" :key="son.partCode">
+                                <up-radio activeColor="#37A954" :name="son.partCode">
+                                    <template #label>
+                                        <span class="f-s-24 c-#333" :class="{ 'c-primary': value === son.partCode }">{{ son.partName }}</span>
+                                    </template>
+                                </up-radio>
+                            </template>
+                        </up-radio-group>
+                    </view>
+                </scroll-view>
+            </view>
+            <view class="pd-24 bg-#fff d-flex">
+                <up-button @click="close" class="mr-30" color="#F2F2F2" style="color: #333">取消</up-button>
+                <up-button @click="confirmSelection" type="primary">确认选择</up-button>
+            </view>
+            <!-- 底部安全区域适配 -->
+            <view class="safe-area-bottom"></view>
+        </view>
+    </up-popup>
+</template>
+<script setup lang="ts">
+import { useClientRequest } from '@/utils/request';
+const showPart = ref(false);
+const props = defineProps({
+    modelValue: {
+        type: String,
+        default: '',
+    },
+    title: {
+        type: String,
+        default: '选择药用部位/对象',
+    },
+    params: {
+        type: Object,
+        default: () => ({}),
+    },
+    valueName: {
+        type: String,
+        default: '',
+    },
+});
+const emit = defineEmits(['update:modelValue', 'update:valueName']);
+// 获取药用部位信息
+const groups = ref<any[]>([]);
+const mapGroupSons = reactive<any>({});
+const mapValueName = reactive<any>({});
+const getGroupList = async () => {
+    const res = await useClientRequest.get<any>('/plt-api/app/harvestPartInfo/groupList', props.params);
+    if (!res || res.code !== 200) return;
+    groups.value = res.data || [];
+    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;
+            });
+    });
+    groupId.value = groups.value?.[0]?.partCode || '';
+};
+const close = () => {
+    showPart.value = false;
+};
+const groupId = ref('');
+const value = ref();
+const confirmSelection = () => {
+    emit('update:valueName', mapValueName[value.value] || '');
+    emit('update:modelValue', value.value);
+    close();
+};
+// 如果props.modelValue
+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 });
+</script>
+<style lang="scss" scoped>
+.tabs-group {
+    font-size: 28rpx;
+    color: #333;
+    background-color: #f7f7f7;
+    border-bottom: 1rpx solid #e6e6e6;
+
+    &.active {
+        font-weight: 500;
+        color: #fff;
+        background-color: $up-primary;
+    }
+}
+.c-primary {
+    color: $up-primary;
+}
+.safe-area-bottom {
+    height: env(safe-area-inset-bottom);
+}
+</style>

+ 35 - 0
src/pages.json

@@ -317,6 +317,41 @@
                     "style": {
                         "navigationBarTitleText": "农资库存损耗登记"
                     }
+                },
+                // 鲜货库
+                {
+                    "path": "fresh-goods/list/index",
+                    "style": {
+                        "navigationBarTitleText": "鲜货库"
+                    }
+                },
+                // 鲜货详情
+                {
+                    "path": "fresh-goods/detail/index",
+                    "style": {
+                        "navigationBarTitleText": "鲜货详情"
+                    }
+                },
+                // 新增鲜货入库
+                {
+                    "path": "fresh-goods/add/index",
+                    "style": {
+                        "navigationBarTitleText": "新增鲜货入库"
+                    }
+                },
+                 // 新增鲜货入库信息
+                {
+                    "path": "fresh-goods/info-edit/index",
+                    "style": {
+                        "navigationBarTitleText": "新增鲜货入库信息"
+                    }
+                },
+                // 修改鲜货信息,单条
+                {
+                    "path": "fresh-goods/info-update/index",
+                    "style": {
+                        "navigationBarTitleText": "修改鲜货信息"
+                    }
                 }
             ]
         },

+ 52 - 51
src/pages/plant/storage/index.vue

@@ -1,59 +1,60 @@
 <template>
-    <z-paging ref="paging" bgColor="#fff">
+    <z-paging ref="paging" bgColor="#F7F7F7">
         <template #top>
             <ut-navbar title="仓储与放行" :fixed="false" :isLeftBack="false" :breadcrumb="false"></ut-navbar>
         </template>
         <view class="base-content pd-20">
-            <up-grid :border="false" :column="3" gap="10rpx">
-                <up-grid-item>
-                    <view class="pd2-10-0 d-flex flex-cln a-c j-c" @click="$u.route({ url: '/plant/storage/storage-room/list/index' })">
-                        <view class="w-109 h-109 bg-#fff radius-50% d-flex a-c j-c mb-10">
-                            <image class="w-72 h-72" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/storage/nav_kfgl_icon.png" mode="widthFix" />
-                        </view>
-                        <view class="c-#333 f-s-28 text-center">库房管理</view>
-                    </view>
-                </up-grid-item>
-                <up-grid-item>
-                    <view class="pd2-10-0 d-flex flex-cln a-c j-c" @click="$u.route({ url: '/plant/storage/agro-product/list/index' })">
-                        <view class="w-109 h-109 bg-#fff radius-50% d-flex a-c j-c mb-10">
-                            <image class="w-72 h-72" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/storage/nav_nzk_icon.png" mode="widthFix" />
-                        </view>
-                        <view class="c-#333 f-s-28 text-center">农资库</view>
-                    </view>
-                </up-grid-item>
-                <up-grid-item>
-                    <view class="pd2-10-0 d-flex flex-cln a-c j-c" @click="$u.route({ url: '/plant/storage/seed-source/list/index' })">
-                        <view class="w-109 h-109 bg-#fff radius-50% d-flex a-c j-c mb-10">
-                            <image class="w-72 h-72" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/storage/nav_zyk_icon.png" mode="widthFix" />
-                        </view>
-                        <view class="c-#333 f-s-28 text-center">种源库</view>
-                    </view>
-                </up-grid-item>
-                <up-grid-item>
-                    <view class="pd2-10-0 d-flex flex-cln a-c j-c">
-                        <view class="w-109 h-109 bg-#fff radius-50% d-flex a-c j-c mb-10">
-                            <image class="w-72 h-72" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/storage/nav_xhk_icon.png" mode="widthFix" />
-                        </view>
-                        <view class="c-#333 f-s-28 text-center">鲜货库</view>
-                    </view>
-                </up-grid-item>
-                <up-grid-item>
-                    <view class="pd2-10-0 d-flex flex-cln a-c j-c">
-                        <view class="w-109 h-109 bg-#fff radius-50% d-flex a-c j-c mb-10">
-                            <image class="w-72 h-72" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/storage/nav_zjpk_icon.png" mode="widthFix" />
-                        </view>
-                        <view class="c-#333 f-s-28 text-center">中间品库</view>
-                    </view>
-                </up-grid-item>
-                <up-grid-item>
-                    <view class="pd2-10-0 d-flex flex-cln a-c j-c">
-                        <view class="w-109 h-109 bg-#fff radius-50% d-flex a-c j-c mb-10">
-                            <image class="w-72 h-72" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/storage/nav_cpk_icon.png" mode="widthFix" />
-                        </view>
-                        <view class="c-#333 f-s-28 text-center">成品库</view>
-                    </view>
-                </up-grid-item>
-            </up-grid>
+            <view class="bg-#fff d-flex a-c j-c radius-16 pd2-30-24 mb-20" @click="$u.route({ url: '/plant/storage/storage-room/list/index' })">
+                <image class="w-72 h-72" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/storage/nav_kfgl_icon.png" mode="widthFix" />
+                <view class="flex1 pd2-0-20">
+                    <view class="f-s-30 c-#333 f-w-500">库房管理</view>
+                    <view class="f-s-22 c-#999">可创立不同基地的库房和货位,分基地进行库房管理</view>
+                </view>
+                <up-icon name="arrow-right"></up-icon>
+            </view>
+            <view class="bg-#fff d-flex a-c j-c radius-16 pd2-30-24 mb-20" @click="$u.route({ url: '/plant/storage/seed-source/list/index' })">
+                <image class="w-72 h-72" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/storage/nav_zyk_icon.png" mode="widthFix" />
+                <view class="flex1 pd2-0-20">
+                    <view class="f-s-30 c-#333 f-w-500">种源库</view>
+                    <view class="f-s-22 c-#999">内部采收种源和外部采购种源的存储库房</view>
+                </view>
+                <up-icon name="arrow-right"></up-icon>
+            </view>
+            <view class="bg-#fff d-flex a-c j-c radius-16 pd2-30-24 mb-20" @click="$u.route({ url: '/plant/storage/agro-product/list/index' })">
+                <image class="w-72 h-72" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/storage/nav_nzk_icon.png" mode="widthFix" />
+                <view class="flex1 pd2-0-20">
+                    <view class="f-s-30 c-#333 f-w-500">农资库</view>
+                    <view class="f-s-22 c-#999">种养殖和种源繁育所需农资投入品的存储库房</view>
+                </view>
+                <up-icon name="arrow-right"></up-icon>
+            </view>
+            <!-- 鲜货库 -->
+            <view class="bg-#fff d-flex a-c j-c radius-16 pd2-30-24 mb-20" @click="$u.route({ url: '/plant/storage/fresh-goods/list/index' })">
+                <image class="w-72 h-72" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/storage/nav_xhk_icon.png" mode="widthFix" />
+                <view class="flex1 pd2-0-20">
+                    <view class="f-s-30 c-#333 f-w-500">鲜货库</view>
+                    <view class="f-s-22 c-#999">内部采收鲜货和外部采收鲜货的存储库房</view>
+                </view>
+                <up-icon name="arrow-right"></up-icon>
+            </view>
+            <!-- 中间品库 -->
+            <view class="bg-#fff d-flex a-c j-c radius-16 pd2-30-24 mb-20" @click="$u.route({ url: '/plant/storage/intermediate-product/list/index' })">
+                <image class="w-72 h-72" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/storage/nav_zjpk_icon.png" mode="widthFix" />
+                <view class="flex1 pd2-0-20">
+                    <view class="f-s-30 c-#333 f-w-500">中间品库</view>
+                    <view class="f-s-22 c-#999">加工后待包装药材的存储库房</view>
+                </view>
+                <up-icon name="arrow-right"></up-icon>
+            </view>
+            <!-- 成品库 -->
+            <view class="bg-#fff d-flex a-c j-c radius-16 pd2-30-24 mb-20" @click="$u.route({ url: '/plant/storage/finished-product/list/index' })">
+                <image class="w-72 h-72" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/storage/nav_cpk_icon.png" mode="widthFix" />
+                <view class="flex1 pd2-0-20">
+                    <view class="f-s-30 c-#333 f-w-500">成品库</view>
+                    <view class="f-s-22 c-#999">包装后待售的鲜货、种源、药材等成品的存储库房</view>
+                </view>
+                <up-icon name="arrow-right"></up-icon>
+            </view>
         </view>
     </z-paging>
     <ut-tabar activeTab="storage"></ut-tabar>

+ 0 - 1
src/plant/base/base-edit/index.vue

@@ -684,7 +684,6 @@ const submitForm = async () => {
             });
             try {
                 const res = did.value && !+form.value?.baseInfo?.tempFlag ? await useClientRequest.post('/plt-api//app/base/update', form.value) : await useClientRequest.post('/plt-api/app/base/add', form.value);
-                uni.hideLoading();
                 if (!res || res.code !== 200) return;
                 uni.hideLoading();
                 uni.showToast({

+ 1 - 2
src/plant/base/gap-base-info-edit/index.vue

@@ -190,8 +190,7 @@ const submitForm = async () => {
             });
             try {
                 const res = did.value ? await useClientRequest.post(`/plt-api/app/gapCertificationInfo/update`, form.value) : await useClientRequest.post('/plt-api/app/gapCertificationInfo/add', form.value);
-                uni.hideLoading();
-                if (!res || res !== 200) return;
+                if (!res || res.code !== 200) return;
                 uni.hideLoading();
                 uni.showToast({
                     title: '提交成功',

+ 7 - 8
src/plant/storage/agro-product/add/index.vue

@@ -94,9 +94,9 @@
                     </template>
                 </up-form-item>
                 <!-- 库房类型 -->
-                <up-form-item borderBottom label="库房类型" prop="storeType" required>
-                    <view v-if="form.storeType" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_warehouse_type,
-                        form.storeType) }}</view>
+                <up-form-item borderBottom label="库房类型" prop="storageType" required>
+                    <view v-if="form.storageType" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_warehouse_type,
+                        form.storageType) }}</view>
                     <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择库房类型</view>
                 </up-form-item>
                      <!-- 存放库房(具体库房/货架信息稍后补充为选择器) -->
@@ -139,7 +139,7 @@ const upFormRef = ref<any>(null);
 // 农资入库汇总表单
 const form = ref<AgroProductInstoreAddTypeEnum>({
     instoreType: '2',
-    storeType: '1',
+    storageType: '1',
     agroProductInfoList: [],
     warehouses: [],
     instoreBizInfo: {
@@ -149,11 +149,11 @@ const form = ref<AgroProductInstoreAddTypeEnum>({
     },
 });
 const rules = reactive({
-    agroProductInfoList: [{ required: true, message: '请添加农资信息', type: 'array', min: 1 }],
+    
     instoreType: [{ required: true, message: '请选择入库类型' }],
     'instoreBizInfo.instoreDate': [{ required: true, message: '请选择入库日期' }],
     batchCode: [{ required: true, message: '请输入入库批号' }],
-    storeType: [{ required: true, message: '请选择库房类型' }],
+    storageType: [{ required: true, message: '请选择库房类型' }],
     'instoreBizInfo.instoreMg': [{ required: true, message: '请输入入库人' }],
 });
 
@@ -186,8 +186,7 @@ const submitForm = async () => {
             })
             try {
                 const res = await useClientRequest.post('/plt-api/app/material/batchInstore', params);
-                uni.hideLoading();
-                if (!res || res !== 200) return;
+                if (!res || res.code !== 200) return;
                 uni.hideLoading();
                 uni.showToast({
                     title: '提交成功',

+ 2 - 2
src/plant/storage/agro-product/detail/index.vue

@@ -205,9 +205,9 @@ const onRefresh = () => {
     paging.value?.complete();
 };
 const clickEdit = () => {
-    uni.$on('seed-source-detail-refresh', () => {
+    uni.$on('seed-agro-detail-refresh', () => {
         getDetailById(did.value);
-        uni.$off('seed-source-detail-refresh');
+        uni.$off('seed-agro-detail-refresh');
     });
     uni.$u.route({
         type: 'navigateTo',

+ 133 - 390
src/plant/storage/agro-product/info-update/index.vue

@@ -1,238 +1,86 @@
 <template>
     <z-paging class="" ref="paging" bgColor="#f7f7f7" paging-class="paging-btm-shadow" safe-area-inset-bottom scroll-with-animation>
         <template #top>
-            <ut-navbar :title="did ? '编辑种源入库' : '新增种源入库'" :fixed="false" border></ut-navbar>
+            <ut-navbar :title="did ? '编辑农资入库' : '新增农资入库'" :fixed="false" border></ut-navbar>
         </template>
         <up-form class="p-rtv" labelPosition="top" :model="form" :rules="rules" labelWidth="auto" ref="upFormRef">
-            <!-- 种源信息(复制自 info-edit 字段与顺序) -->
+            <!-- 农资信息(复制自 info-edit 字段与顺序) -->
             <view class="pd-24">
-                <view class="startline-title">种源信息</view>
+                <view class="startline-title">农资信息</view>
             </view>
             <view class="pd-24 bg-#fff">
-                <!-- 基本信息 -->
-                <view class="h-1" id="seedTypepppp"></view>
-                <ut-action-sheet :tabs="pt_seed_type" mode="custom" title="种源类型" v-model="form.seedType">
-                    <up-form-item borderBottom label="种源类型" required prop="seedType">
-                        <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>
-                <view class="h-1" id="varietyIdpppp"></view>
-                <up-form-item borderBottom label="物种基原" required prop="varietyId">
-                    <view class="flex1">
-                        <up-button v-if="!form.varietyId" @click="selectVarietyId" type="primary" 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>请选择物种基原</span>
-                        </up-button>
-                        <view v-else class="bg-#FBFDFB card-info-block pd-24 p-rtv">
-                            <view class="mb-16">
-                                <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-16">
-                                <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">产出:{{ form?.varietyInfo?.medicineName }}</view>
-                            <view
-                                class="close-icon pd-16"
-                                @click="
-                                    form.varietyId = '';
-                                    form.varietyInfo = null;
-                                "
-                            >
-                                <up-icon color="#F81242" name="close" size="32rpx"></up-icon>
-                            </view>
-                        </view>
-                    </view>
+                <view class="h-1" id="materialNamepppp"></view>
+                <up-form-item borderBottom label="产品名称" prop="materialName" required>
+                    <up-input v-model="form.materialName" placeholder="请输入产品名称" border="none" clearable></up-input>
                 </up-form-item>
-                <up-form-item borderBottom label="具体品种/品系名称" prop="seedName">
-                    <up-input v-model="form.seedName" placeholder="请输入具体品种/品系名称" border="none" clearable></up-input>
-                </up-form-item>
-                <view class="h-1" id="seedSourcepppp"></view>
-                <ut-action-sheet :tabs="pt_seed_source" mode="custom" title="种源来源" v-model="form.seedSource">
-                    <up-form-item borderBottom label="种源来源" required prop="seedSource">
-                        <view v-if="form.seedSource" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_seed_source, form.seedSource) }}</view>
-                        <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择种源来源</view>
+                <view class="h-1" id="materialTypepppp"></view>
+                <ut-action-sheet :tabs="pt_material_type" mode="custom" title="农资类别" v-model="form.materialType">
+                    <up-form-item borderBottom label="农资类别" required prop="materialType">
+                        <view v-if="form.materialType" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_material_type, form.materialType) }}</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>
-                <view class="h-1" id="motherFatherFlagpppp"></view>
-                <ut-action-sheet :tabs="pt_mother_father_flag" mode="custom" title="父母本情况" v-model="form.instoreBizInfo.motherFatherFlag">
-                    <template v-if="['A3', 'A4'].includes(form.seedType as string) || ['3'].includes(form.seedSource as string)">
-                        <up-form-item borderBottom label="父母本情况" prop="instoreBizInfo.motherFatherFlag" required>
-                            <view v-if="form.instoreBizInfo.motherFatherFlag" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_mother_father_flag, form.instoreBizInfo.motherFatherFlag) }}</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>
-                    </template>
-                    <template v-else>
-                        <up-form-item borderBottom label="父母本情况">
-                            <view v-if="form.instoreBizInfo.motherFatherFlag" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_mother_father_flag, form.instoreBizInfo.motherFatherFlag) }}</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>
-                    </template>
-                </ut-action-sheet>
-                <template>
-                    <!-- 父本品种 -->
-                    <up-form-item v-if="form?.instoreBizInfo?.motherFatherFlag == '2'" borderBottom label="父本品种" prop="fatherVarietyId">
-                        <view class="flex1">
-                            <up-button v-if="!form.instoreBizInfo.fatherVarietyId" @click="selectFatherVarietyId" type="primary" 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>请选择父本品种</span>
-                            </up-button>
-                            <view v-else class="bg-#FBFDFB card-info-block pd-24 p-rtv">
-                                <view class="mb-16">
-                                    <span class="f-s-34 c-#333 f-w-5 mr-16">{{ form?.instoreBizInfo?.fatherVarietyInfo?.varietyName }}</span>
-                                    <span class="f-s-24 c-#666">{{ form?.instoreBizInfo?.fatherVarietyInfo?.latinName }}</span>
-                                </view>
-                                <view class="mb-16">
-                                    <span class="f-s-28 c-#333 f-w-5 mr-16">{{ form?.instoreBizInfo?.fatherVarietyInfo?.genusName }}</span>
-                                    <span class="f-s-24 c-#666">{{ form?.instoreBizInfo?.fatherVarietyInfo?.genusLatinName }}</span>
-                                </view>
-                                <view class="f-s-24 c-#666">产出:{{ form?.instoreBizInfo?.fatherVarietyInfo?.medicineName }}</view>
-                                <view
-                                    class="close-icon pd-16"
-                                    @click="
-                                        form.instoreBizInfo.fatherVarietyId = '';
-                                        form.instoreBizInfo.fatherVarietyInfo = null;
-                                    "
-                                >
-                                    <up-icon color="#F81242" name="close" size="32rpx"></up-icon>
-                                </view>
-                            </view>
-                        </view>
-                    </up-form-item>
-                    <!-- 母本品种 -->
-                    <up-form-item borderBottom label="母本品种" prop="instoreBizInfo.motherVarietyId">
-                        <view class="flex1">
-                            <up-button v-if="!form.instoreBizInfo.motherVarietyId" @click="selectMotherVarietyId" type="primary" 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>请选择母本品种</span>
-                            </up-button>
-                            <view v-else class="bg-#FBFDFB card-info-block pd-24 p-rtv mt-16">
-                                <view class="mb-16">
-                                    <span class="f-s-34 c-#333 f-w-5 mr-16">{{ form?.instoreBizInfo?.motherVarietyInfo?.varietyName }}</span>
-                                    <span class="f-s-24 c-#666">{{ form?.instoreBizInfo?.motherVarietyInfo?.latinName }}</span>
-                                </view>
-                                <view class="mb-16">
-                                    <span class="f-s-28 c-#333 f-w-5 mr-16">{{ form?.instoreBizInfo?.motherVarietyInfo?.genusName }}</span>
-                                    <span class="f-s-24 c-#666">{{ form?.instoreBizInfo?.motherVarietyInfo?.genusLatinName }}</span>
-                                </view>
-                                <view class="f-s-24 c-#666">产出:{{ form?.instoreBizInfo?.motherVarietyInfo?.medicineName }}</view>
-                                <view
-                                    class="close-icon pd-16"
-                                    @click="
-                                        form.instoreBizInfo.motherVarietyId = '';
-                                        form.instoreBizInfo.motherVarietyInfo = null;
-                                    "
-                                >
-                                    <up-icon color="#F81242" name="close" size="32rpx"></up-icon>
-                                </view>
-                            </view>
-                        </view>
-                    </up-form-item>
-                </template>
-                <view class="h-1" id="genCountpppp"></view>
-                <view class="h-1" id="genUnitpppp"></view>
-                <template v-if="['A3', 'A4'].includes(form.seedType as string)">
-                    <up-form-item :label="`${genCountMap[form.seedType as 'A3' | 'A4']}`" required class="form-item-bottom-padding-0">
-                        <view class="d-flex flex1">
-                            <view class="flex1 ov-hd">
-                                <up-form-item prop="instoreBizInfo.genCount" border-bottom class="form-item-top-padding-0">
-                                    <up-input v-model="form.instoreBizInfo.genCount" :placeholder="`请输入${genCountMap[form.seedType as 'A3' | 'A4']}`" border="none" clearable></up-input>
-                                </up-form-item>
-                            </view>
-                            <view class="pd-5"></view>
-                            <view class="min-w-200">
-                                <ut-action-sheet v-model="form.instoreBizInfo.genUnit" :tabs="pt_gen_unit" mode="custom" title="选择单位">
-                                    <up-form-item prop="instoreBizInfo.genUnit" border-bottom class="form-item-top-padding-0">
-                                        <view class="flex1" style="line-height: 24px">
-                                            <view v-if="form.instoreBizInfo.genUnit" class="f-s-30 c-333 f-w-5 text-center">{{ selectDictLabel(pt_gen_unit, form.instoreBizInfo.genUnit) }}</view>
-                                            <view v-else class="f-s-30 c-ccc f-w-4 text-center">单位</view>
-                                        </view>
-                                        <template #right>
-                                            <up-icon size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
-                                        </template>
-                                    </up-form-item>
-                                </ut-action-sheet>
-                            </view>
-                        </view>
-                    </up-form-item>
-                </template>
-                <template v-else>
-                    <up-form-item label="繁衍世代" class="form-item-bottom-padding-0">
-                        <view class="d-flex flex1">
-                            <view class="flex1 ov-hd">
-                                <up-form-item border-bottom class="form-item-top-padding-0">
-                                    <up-input v-model="form.instoreBizInfo.genCount" placeholder="请输入繁衍世代" border="none" clearable></up-input>
+
+                <!-- 入库数量与单位 -->
+                <view class="h-1" id="capacitypppp"></view>
+                <view class="h-1" id="unitpppp"></view>
+                <up-form-item label="入库量" prop="capacity" required class="form-item-bottom-padding-0">
+                    <view class="f-s-30 c-333 f-w-5 flex1">{{ form?.capacity }}{{ form?.unit }}</view>
+                </up-form-item>
+                <view class="h-1" id="specpppp"></view>
+                <view class="h-1" id="specUnitpppp"></view>
+                <template v-if="!['kg', 'L'].includes(form?.unit as string)">
+                    <up-form-item label="规格" prop="spec" required class="form-item-bottom-padding-0">
+                        <div class="flex1 d-flex">
+                            <div class="flex1 ov-hd">
+                                <up-form-item prop="spec" border-bottom class="form-item-top-padding-0">
+                                    <up-input v-model="form.spec" placeholder="请输入规格" border="none" clearable></up-input>
                                 </up-form-item>
-                            </view>
-                            <view class="pd-5"></view>
-                            <view class="min-w-200">
-                                <ut-action-sheet v-model="form.instoreBizInfo.genUnit" :tabs="pt_gen_unit" mode="custom" title="选择单位">
-                                    <up-form-item border-bottom class="form-item-top-padding-0">
+                            </div>
+                            <div class="pd-5"></div>
+                            <div class="min-w-200">
+                                <ut-action-sheet v-model="form.specUnit" :tabs="pt_materail_spec_unit" mode="custom" title="选择单位">
+                                    <up-form-item prop="specUnit" border-bottom class="form-item-top-padding-0">
                                         <view class="flex1" style="line-height: 24px">
-                                            <view v-if="form.instoreBizInfo.genUnit" class="f-s-30 c-333 f-w-5 text-center">{{ selectDictLabel(pt_gen_unit, form.instoreBizInfo.genUnit) }}</view>
+                                            <view v-if="form.specUnit" class="f-s-30 c-333 f-w-5 text-center">{{ selectDictLabel(pt_materail_spec_unit, form.specUnit) }}</view>
                                             <view v-else class="f-s-30 c-ccc f-w-4 text-center">单位</view>
                                         </view>
                                         <template #right>
-                                            <up-icon size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
+                                            <up-icon class="mr-10" size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
                                         </template>
                                     </up-form-item>
                                 </ut-action-sheet>
-                            </view>
-                        </view>
-                    </up-form-item>
-                </template>
-
-                <view class="h-1" id="entrustIdpppp"></view>
-                <up-form-item borderBottom label="受托单位" prop="entrustId" required>
-                    <view class="flex1">
-                        <ContactUnitInput v-model="form.entrustId" v-model:info="form.entrustInfo" :params="{ cpyType: '2' }" title="选择受托单位" placeholder="请选择受托单位信息"></ContactUnitInput>
-                    </view>
-                </up-form-item>
-
-                <!-- 入库数量与单位 -->
-                <view class="h-1" id="capacitypppp"></view>
-                <up-form-item label="入库量" prop="capacity" required class="form-item-bottom-padding-0">
-                    <div class="flex1 d-flex">
-                        <div class="flex1 ov-hd">
-                            <up-form-item prop="capacity" border-bottom class="form-item-top-padding-0">
-                                <up-input v-model="form.capacity" placeholder="请输入入库量" border="none" clearable></up-input>
-                            </up-form-item>
-                        </div>
-                        <div class="pd-5"></div>
-                        <div class="min-w-200">
-                            <ut-action-sheet v-model="form.unit" :tabs="pt_seed_unit" mode="custom" title="选择单位">
+                            </div>
+                            <div class="pd2-0-10 c-#ccc">/</div>
+                            <div class="min-w-200">
                                 <up-form-item prop="unit" border-bottom class="form-item-top-padding-0">
                                     <view class="flex1" style="line-height: 24px">
-                                        <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-if="form.unit" class="f-s-30 c-333 f-w-5 text-center">{{ selectDictLabel(pt_materail_unit, form.unit) }}</view>
                                         <view v-else class="f-s-30 c-ccc f-w-4 text-center">单位</view>
                                     </view>
                                     <template #right>
-                                        <up-icon size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
+                                        <up-icon size="22rpx" color="#fff" name="arrow-down-fill"></up-icon>
                                     </template>
                                 </up-form-item>
-                            </ut-action-sheet>
+                            </div>
                         </div>
-                    </div>
-                </up-form-item>
-                <!-- 检验报告与供应商信息 -->
-                <up-form-item borderBottom label="检验报告" prop="examinReport">
-                    <ut-upload v-model="form.examinReport" :max-count="50" valueType="array" accept="image,file"></ut-upload>
-                </up-form-item>
-                <template v-if="['2', '3'].includes(form.seedSource as string)">
+                    </up-form-item>
+                </template>
+
+                <view class="h-1" id="sourceTypepppp"></view>
+                <ut-action-sheet :tabs="pt_source_type" mode="custom" title="农资来源" v-model="form.sourceType">
+                    <up-form-item borderBottom label="农资来源" required prop="sourceType">
+                        <view v-if="form.sourceType" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_source_type, form.sourceType) }}</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 v-if="['1'].includes(form.sourceType as string)">
                     <up-form-item borderBottom label="供应商" prop="supplierId" required>
                         <view class="flex1">
                             <ContactUnitInput v-model="form.supplierId" v-model:info="form.supplierInfo" :params="{ cpyType: '4' }" title="选择供应商" placeholder="请选择供应商信息"></ContactUnitInput>
@@ -247,95 +95,36 @@
                         <up-input v-model="form.producer" placeholder="请输入生产商名称" border="none" clearable></up-input>
                     </up-form-item>
                 </template>
-                <!-- 菌种编码信息 -->
-                <up-form-item required v-if="['A4', 'A8'].includes(form.seedType as string)" :label="`${selectDictLabel(pt_seed_type, form.seedType as string)}编号`" class="form-item-bottom-padding-0">
-                    <view class="d-flex flex1">
-                        <view class="flex1">
-                            <ut-action-sheet v-model="form.fungusCodeType" :tabs="pt_fungus_code_type" mode="custom" title="选择单位">
-                                <up-form-item prop="fungusCodeType" border-bottom class="form-item-top-padding-0">
-                                    <view class="flex1" style="line-height: 24px">
-                                        <view v-if="form.fungusCodeType" class="f-s-30 c-333 f-w-5">{{ selectDictLabel(pt_fungus_code_type, form.fungusCodeType) }}</view>
-                                        <view v-else class="f-s-30 c-ccc f-w-4">选择编号类型</view>
-                                    </view>
-                                    <template #right>
-                                        <up-icon class="pr-20" size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
-                                    </template>
-                                </up-form-item>
-                            </ut-action-sheet>
-                        </view>
-                        <view class="pd-5"></view>
-                        <view class="flex1">
-                            <up-form-item prop="fungusCode" border-bottom class="form-item-top-padding-0">
-                                <up-input v-model="form.fungusCode" placeholder="输入数字小数点" border="none" clearable></up-input>
-                            </up-form-item>
-                        </view>
-                    </view>
+                <up-form-item borderBottom label="生产批号" prop="productCode">
+                    <up-input v-model="form.productCode" placeholder="请输入生产批号" border="none" clearable></up-input>
                 </up-form-item>
-                <!-- 个体标识:此处仅占位,后续可改为多选列表 -->
-                <view class="h-1" id="instoreBizInfo.idFlagpppp"></view>
-                <up-form-item borderBottom label="是否有个体标识" prop="instoreBizInfo.idFlag" required>
-                    <up-radio-group v-model="form.instoreBizInfo.idFlag">
-                        <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>
+                <ut-datetime-picker v-model="form.productDate" :maxDate="new Date()" mode="date">
+                    <up-form-item borderBottom label="生产日期" prop="productDate">
+                        <up-input v-model="form.productDate" readonly placeholder="请选择生产日期" border="none" clearable></up-input>
+                        <template #right>
+                            <up-icon size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
+                        </template>
+                    </up-form-item>
+                </ut-datetime-picker>
+                <up-form-item borderBottom label="品牌" prop="brand">
+                    <up-input v-model="form.brand" placeholder="请输入品牌" border="none" clearable></up-input>
                 </up-form-item>
-                <!-- 个体标识:此处仅占位,后续可改为多选列表 -->
-                <template v-if="+form?.instoreBizInfo?.idFlag">
-                    <view class="h-1" id="instoreBizInfo.animalspppp"></view>
-                    <up-form-item borderBottom label="个体标识号" prop="instoreBizInfo.animals" required>
-                        <AnimalsInput v-model="form.instoreBizInfo.animals"></AnimalsInput>
+                <!-- 登记证号 肥料和农药才有登记证号 -->
+                <template v-if="['1', '2'].includes(form.materialType as string)">
+                    <up-form-item borderBottom label="登记证号" prop="materialCode">
+                        <up-input v-model="form.materialCode" placeholder="请输入登记证号" border="none" clearable></up-input>
                     </up-form-item>
                 </template>
-                <!-- 保藏方法 -->
-                <up-form-item borderBottom label="保藏方法" prop="instoreBizInfo.storageMethod">
-                    <up-input v-model="form.instoreBizInfo.storageMethod" placeholder="请输入保藏方法" border="none" clearable></up-input>
-                </up-form-item>
                 <!-- 媒体与附件 -->
-                <up-form-item borderBottom label="种源图片" prop="imgs">
+                <up-form-item borderBottom label="农资图片" prop="imgs">
                     <ut-upload v-model="form.imgs" :max-count="9" valueType="string"></ut-upload>
                 </up-form-item>
-                <up-form-item borderBottom label="种源视频" prop="vedios">
+                <up-form-item borderBottom label="农资视频" prop="vedios">
                     <ut-upload v-model="form.vedios" :max-count="3" accept="video" valueType="string"></ut-upload>
                 </up-form-item>
-
-                <!-- 种源产地 -->
-                <PickerAreaInput v-model="form.adcode" v-model:full-name="form.adcodeName" title="选择种源产地">
-                    <up-form-item borderBottom label="种源产地" prop="adcode">
-                        <view v-if="form.adcode" class="f-s-30 c-333 f-w-5 flex1">{{ form.adcodeName }}</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>
-                </PickerAreaInput>
-                <ut-action-sheet :tabs="pt_breeding_materials" mode="custom" title="繁殖材料" multiple v-model="form.generationMaterial">
-                    <up-form-item borderBottom label="繁殖材料" prop="generationMaterial">
-                        <view v-if="form.generationMaterial" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabels(pt_breeding_materials, form.generationMaterial, ',') }}</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>
-
-                <PickerAreaInput v-model="form.generationAdcode" v-model:full-name="form.generationAdcodeName" :maxLevel="4" title="选择繁殖地点/采集地点">
-                    <up-form-item borderBottom label="繁殖地点/采集地点" prop="generationAdcode">
-                        <view v-if="form.generationAdcode" class="f-s-30 c-333 f-w-5 flex1">{{ form.generationAdcodeName }}</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>
-                </PickerAreaInput>
-                <!-- 资质证明附件(暂按上传控件处理,可后续细化) -->
-                <up-form-item borderBottom label="物种鉴定证书" prop="spCert">
-                    <ut-upload v-model="form.spCert" :max-count="9" valueType="array" accept="file"></ut-upload>
-                </up-form-item>
-                <!-- 检疫信息 -->
-                <up-form-item borderBottom label="种源检疫证号" prop="seedCheckSn">
-                    <up-input v-model="form.seedCheckSn" placeholder="请输入种源检疫证号" border="none" clearable></up-input>
-                </up-form-item>
-                <up-form-item borderBottom label="种源检疫证书" prop="seedCheckCert">
-                    <ut-upload v-model="form.seedCheckCert" :max-count="9" valueType="array" accept="file"></ut-upload>
+                <!-- 检验报告 -->
+                <up-form-item borderBottom label="检验报告" prop="examinReport">
+                    <ut-upload v-model="form.examinReport" :max-count="50" valueType="array" accept="image,file"></ut-upload>
                 </up-form-item>
             </view>
 
@@ -343,10 +132,6 @@
                 <view class="startline-title">入库信息</view>
             </view>
             <view class="pd-24 bg-#fff">
-                <!-- 种源级别 -->
-                <up-form-item borderBottom label="种源级别" prop="seedLevel">
-                    <up-input v-model="form.seedLevel" placeholder="请输入种源级别" border="none" clearable></up-input>
-                </up-form-item>
                 <!-- 入库类型 -->
                 <up-form-item borderBottom label="入库类型" required prop="instoreType">
                     <view v-if="form.instoreType" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_seed_instore_type, form.instoreType) }}</view>
@@ -356,7 +141,7 @@
                 <view class="h-1" id="instoreDatepppp"></view>
                 <ut-datetime-picker v-model="form.instoreBizInfo.instoreDate" :maxDate="new Date()" mode="date">
                     <up-form-item borderBottom label="入库日期" required prop="instoreBizInfo.instoreDate">
-                        <up-input v-model="form.instoreBizInfo.instoreDate" placeholder="请选择入库日期" border="none" clearable></up-input>
+                        <up-input v-model="form.instoreBizInfo.instoreDate" readonly placeholder="请选择入库日期" border="none" clearable></up-input>
                         <template #right>
                             <up-icon size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
                         </template>
@@ -364,16 +149,14 @@
                 </ut-datetime-picker>
                 <!-- 入库批号 -->
                 <up-form-item borderBottom label="入库批号" required prop="batchCode">
-                    <up-input v-model="form.batchCode" placeholder="请输入入库批号" border="none" clearable></up-input>
-                    <template #right>
-                        <up-button @click="generateBatchCode" type="primary" :customStyle="formItemBtnStyle">随机生成</up-button>
-                    </template>
+                    <view class="f-s-30 c-333 f-w-5 flex1">{{ form.batchCode }}</view>
                 </up-form-item>
                 <!-- 库房类型 -->
                 <up-form-item borderBottom label="库房类型" prop="storeType" required>
                     <view v-if="form.storeType" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_warehouse_type, form.storeType) }}</view>
                     <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择库房类型</view>
                 </up-form-item>
+                <!-- 存放库房(具体库房/货架信息稍后补充为选择器) -->
                 <up-form-item borderBottom label="存放库房" prop="warehouses">
                     <select-warehouse-input v-model="form.warehouses" title="添加农资存放库房" :params="{ type: '1' }"></select-warehouse-input>
                 </up-form-item>
@@ -398,90 +181,90 @@
 import { useClientRequest } from '@/utils/request';
 import { formItemBtnStyle } from '@/assets/styles/uview-plus';
 import { AgroProductInstoreAddTypeEnum } from '../models/type';
-import AnimalsInput from '../models/animals-input.vue';
 import ContactUnitInput from '@/models/contact-unit-input/contact-unit-input.vue';
-import PickerAreaInput from '@/models/picker-area-input/picker-area-input.vue';
 import SelectWarehouseInput from '@/models/select-warehouse-input/select-warehouse-input.vue';
-
+import { parseTime } from '@/utils/ruoyi';
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const { pt_seed_instore_type, pt_warehouse_type, pt_seed_type, pt_seed_source, pt_materail_unit, pt_mother_father_flag, pt_op_method, pt_seed_unit, pt_fungus_code_type, pt_breeding_materials, yes_no, pt_cus_type, pt_cpy_type, pt_gen_unit } = toRefs<any>(
-    proxy?.useDict('pt_seed_instore_type', 'pt_warehouse_type', 'pt_seed_type', 'pt_seed_source', 'pt_materail_unit', 'pt_mother_father_flag', 'pt_op_method', 'pt_seed_unit', 'pt_fungus_code_type', 'pt_breeding_materials', 'yes_no', 'pt_cus_type', 'pt_cpy_type', 'pt_gen_unit'),
-);
+const { pt_material_type, pt_materail_unit, pt_materail_spec_unit, pt_source_type, yes_no, pt_seed_instore_type, pt_warehouse_type } = toRefs<any>(proxy?.useDict('pt_material_type', 'pt_materail_unit', 'pt_materail_spec_unit', 'pt_source_type', 'yes_no', 'pt_seed_instore_type', 'pt_warehouse_type') || {});
 const paging = ref<any>(null);
 const upFormRef = ref<any>(null);
-// 单条种源信息 + 入库信息的合并表单
+// 单条农资信息 + 入库信息的合并表单
 const form = ref<AgroProductInstoreAddTypeEnum | any>({
+    materialName: '',
+    materialType: '',
+    capacity: '',
+    unit: '',
+    spec: '',
+    specUnit: '',
+    sourceType: '',
+    supplierId: undefined,
+    supplierInfo: undefined,
+    supplierProducerFlag: '',
+    producer: '',
+    productCode: '',
+    productDate: '',
+    brand: '',
+    materialCode: '',
     imgs: undefined,
     vedios: undefined,
-    spCert: [],
-    newSpCert: [],
-    importCert: [],
-    seedCheckCert: [],
-    unit: '',
-    adcode: '',
+    examinReport: [],
+    instoreType: '2',
+    storeType: '1',
+    agroProductInfoList: [],
+    warehouses: [],
     instoreBizInfo: {
-        motherFatherFlag: '',
-        idFlag: '1',
-        genUnit: '',
-        instoreDate: '',
+        instoreDate: parseTime(new Date(), '{y}-{m}-{d}'),
         instoreMg: '',
         remark: '',
     },
-    generationMaterial: '',
-    instoreType: '2',
-    storeType: '2',
 });
 const rules = reactive({
-    // 种源信息校验(来自 info-edit)
-    seedType: [{ required: true, message: '请选择种源类型' }],
-    varietyId: [{ required: true, message: '请选择物种基原' }],
-    seedSource: [{ required: true, message: '请选择种源来源' }],
-    'instoreBizInfo.motherFatherFlag': [{ required: true, message: '请选择父母本情况' }],
-    'instoreBizInfo.genCount': [
+    materialName: [{ required: true, message: '请输入产品名称' }],
+    materialType: [{ required: true, message: '请选择农资类别' }],
+    capacity: [{ required: true, message: '请输入入库量' }],
+    unit: [{ required: true, message: '请选择单位' }],
+    sourceType: [{ required: true, message: '请选择农资来源' }],
+    // 规格与规格单位仅在单位为 kg/L 时必填
+    spec: [
         {
             asyncValidator: (rule: any, value: any) => {
-                if (['A3', 'A4'].includes(form.value.seedType as string)) {
-                    if (!value) {
-                        return Promise.reject('请输入' + genCountMap[form.value.seedType as 'A3' | 'A4']);
-                    }
+                if (!['kg', 'L'].includes(form.value.unit as string) && !value) {
+                    return Promise.reject('请输入规格');
                 }
                 return Promise.resolve();
             },
         },
     ],
-    'instoreBizInfo.genUnit': [
+    specUnit: [
         {
             asyncValidator: (rule: any, value: any) => {
-                if (['A3', 'A4'].includes(form.value.seedType as string)) {
-                    if (!value) {
-                        return Promise.reject('请选择单位');
-                    }
+                if (!['kg', 'L'].includes(form.value.unit as string) && !value) {
+                    return Promise.reject('请选择规格单位');
                 }
                 return Promise.resolve();
             },
         },
     ],
-    entrustId: [{ required: true, message: '请选择受托单位' }],
-    capacity: [{ required: true, message: '请输入入库量' }],
-    unit: [{ required: true, message: '请选择单位' }],
-    supplierId: [{ required: true, message: '请选择供应商' }],
-    fungusCodeType: [{ required: true, message: '请选择编号类型' }],
-    fungusCode: [{ required: true, message: '请输入编号' }],
-    'instoreBizInfo.idFlag': [{ required: true, message: '请选择是否有个体标识' }],
-    'instoreBizInfo.animals': [{ type: 'array', required: true, message: '请输入个体标识号' }],
-    // 入库信息校验(来自 add)
+    // 供应商仅在来源为“采购”等特定来源时必选(目前为来源=1)
+    supplierId: [
+        {
+            asyncValidator: (rule: any, value: any) => {
+                if (['1'].includes(form.value.sourceType as string) && !value) {
+                    return Promise.reject('请选择供应商');
+                }
+                return Promise.resolve();
+            },
+        },
+    ],
+    agroProductInfoList: [{ required: true, message: '请添加农资信息', type: 'array', min: 1 }],
     instoreType: [{ required: true, message: '请选择入库类型' }],
     'instoreBizInfo.instoreDate': [{ required: true, message: '请选择入库日期' }],
     batchCode: [{ required: true, message: '请输入入库批号' }],
+    storeType: [{ required: true, message: '请选择库房类型' }],
     'instoreBizInfo.instoreMg': [{ required: true, message: '请输入入库人' }],
 });
-// 繁衍世代对象
-const genCountMap = reactive({
-    A4: '累计扩繁代数',
-    A3: '继代培养次数',
-});
 
-// 提交:当前页面改为单条种源信息,直接提交合并后的对象
+// 提交:当前页面改为单条农资信息,直接提交合并后的对象
 const submitForm = async () => {
     uni.$u.debounce(
         async () => {
@@ -497,14 +280,14 @@ const submitForm = async () => {
             });
             try {
                 // 这里使用单条入库接口,后端若仍要求 batch,可根据需要包装成数组
-                const res = await useClientRequest.post('/plt-api/app/storageSeed/batchInstore', [form.value]);
+                const res = await useClientRequest.post('/plt-api/app/material/edit', form.value);
                 uni.hideLoading();
-                if (!res || res !== 200) return;
+                if (!res || res.code !== 200) return;
                 uni.showToast({
                     title: '提交成功',
                     icon: 'success',
                 });
-                uni.$emit('seed-source-detail-refresh');
+                uni.$emit('seed-agro-detail-refresh');
                 uni.$emit('refreshStorageRoomList');
                 setTimeout(() => {
                     uni.navigateBack({
@@ -524,8 +307,8 @@ const generateBatchCode = async () => {
     uni.showLoading({
         title: '生成中...',
     });
-    const res = await useClientRequest.post('/plt-api/app/plantationTask/getBatchCode', {
-        plType: 'S',
+    const res = await useClientRequest.post('/plt-api/app/material/getBatchCode', {
+        plType: 'M',
         linkType: 'I',
     });
     if (res && res.code === 200) {
@@ -538,51 +321,11 @@ const generateBatchCode = async () => {
     }
 };
 
-// 选择物种、父母本逻辑保持与 info-edit 一致
-const selectVarietyId = () => {
-    uni.$once('updateBiologicalname', function (data) {
-        form.value.varietyId = data.msg.id;
-        form.value.varietyInfo = data.msg;
-    });
-    uni.$u.route({
-        type: 'navigateTo',
-        url: '/tools/por-torganism/index',
-        params: {
-            title: '选择物种基原',
-        },
-    });
-};
-const selectFatherVarietyId = () => {
-    uni.$once('updateBiologicalname', function (data) {
-        form.value.instoreBizInfo.fatherVarietyId = data.msg.id;
-        form.value.instoreBizInfo.fatherVarietyInfo = data.msg;
-    });
-    uni.$u.route({
-        type: 'navigateTo',
-        url: '/tools/por-torganism/index',
-        params: {
-            title: '选择父本品种',
-        },
-    });
-};
-const selectMotherVarietyId = () => {
-    uni.$once('updateBiologicalname', function (data) {
-        form.value.instoreBizInfo.motherVarietyId = data.msg.id;
-        form.value.instoreBizInfo.motherVarietyInfo = data.msg;
-    });
-    uni.$u.route({
-        type: 'navigateTo',
-        url: '/tools/por-torganism/index',
-        params: {
-            title: '选择母本品种',
-        },
-    });
-};
 const did = ref('');
 // 获取详情(仓库信息)
 const getDetailById = async (id: string) => {
     if (!id) return;
-    const res = await useClientRequest.get(`/plt-api/app/storageSeed/getById/${id}`);
+    const res = await useClientRequest.get(`/plt-api/app/material/getInfo/${id}`);
     if (res && res.code === 200) {
         form.value = {
             ...form.value,

+ 2 - 2
src/plant/storage/agro-product/list/index.vue

@@ -115,7 +115,7 @@ const clickTempSwipe = async (event: object) => {
         try {
             const res = await uni.showModal({
                 title: '删除提示',
-                content: '确定删除种源信息吗?',
+                content: '确定删除农资信息吗?',
                 confirmColor: '#F74C30',
             });
             if (!res.confirm) return;
@@ -131,7 +131,7 @@ const clickTempSwipe = async (event: object) => {
             });
             paging.value?.reload();
         } catch (error) {
-            console.error('删除暂存种源信息失败:', error);
+            console.error('删除暂存农资信息失败:', error);
         }
     }
 };

+ 1 - 1
src/plant/storage/agro-product/models/type.ts

@@ -11,7 +11,7 @@ export interface AgroProductInstoreAddTypeEnum {
     /** 入库批号 */
     batchCode?: string;
     /** 库房类型 */
-    storeType?: string;
+    storageType?: string;
     /** 库房类型 */
     storeCode?: string;
     /** 存放库房 */

+ 248 - 0
src/plant/storage/fresh-goods/add/index.vue

@@ -0,0 +1,248 @@
+<template>
+    <z-paging class="" ref="paging" bgColor="#f7f7f7" paging-class="paging-btm-shadow" safe-area-inset-bottom scroll-with-animation>
+        <template #top>
+            <ut-navbar :title="'新增外部鲜货入库'" :fixed="false" border></ut-navbar>
+        </template>
+        <up-form class="p-rtv" labelPosition="top" :model="form" :rules="rules" labelWidth="auto" ref="upFormRef">
+            <!-- 鲜货信息 -->
+            <view class="pd-24">
+                <view class="startline-title">鲜货信息</view>
+            </view>
+            <view class="pd-24 bg-#fff">
+                <!-- TODO: 后续按 goodsInfoList 设计鲜货信息明细,此处先留空结构避免表单错误 -->
+                <up-form-item borderBottom label="添加鲜货信息" required prop="goodsInfoList">
+                    <view class="flex1">
+                        <template v-for="(item, index) in form.goodsInfoList" :key="index">
+                            <view class="bg-#FBFDFB card-info-block pd-24 p-rtv mb-12">
+                                <view class="d-flex flex1 mb-10">
+                                    <view class="f-s-34 c-#333 f-w-500 mr-10 flex1">{{ uidMapData[item]?.varietyInfo?.varietyName }}</view>
+                                    <view class="pr-60">
+                                        <view v-if="uidMapData[item]?.examinReport?.length" class="tag-span c-primary bg-#EBF6EE">已检</view>
+                                        <view v-else class="tag-span c-danger bg-#F9ECEA">未检</view>
+                                    </view>
+                                </view>
+                                <view class="d-flex">
+                                    <view class="f-s-28 pr-10 pd2-4-0">
+                                        <span class="c-#666">供应商:</span>
+                                        <span class="c-#333 f-w-500">{{ uidMapData[item]?.supplierInfo?.cusName }}</span>
+                                    </view>
+                                </view>
+                                <view class="d-flex">
+                                    <view class="flex1 f-s-28 pd2-4-0 ov-hd">
+                                        <span class="c-#666">入库量:</span>
+                                        <span class="c-#333 f-w-500">{{ uidMapData[item]?.capacity }}{{ uidMapData[item]?.unit }}</span>
+                                    </view>
+                                    <view class="d-flex a-ed" @click="navigateToAddSeedSource(item, 'edit')">
+                                        <view class="pd-10 c-primary f-s-20">去编辑{{ '>' }}</view>
+                                    </view>
+                                </view>
+                                <view class="close-icon pd-16" @click.stop="deleteRow(index, item)">
+                                    <up-icon color="#F81242" name="close" size="32rpx"></up-icon>
+                                </view>
+                            </view>
+                        </template>
+
+                        <up-button type="primary" plain @click="navigateToAddSeedSource('', 'add')">
+                            <up-icon class="mr-10" name="plus" color="#37A954"></up-icon>
+                            <span>点击添加鲜货信息</span>
+                        </up-button>
+                    </view>
+                </up-form-item>
+            </view>
+            <view class="pd-24">
+                <view class="startline-title">入库信息</view>
+            </view>
+            <view class="pd-24 bg-#fff">
+                <!-- 入库类型 -->
+                <up-form-item borderBottom label="入库类型" required prop="instoreType">
+                    <view v-if="form.instoreType" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_seed_instore_type, form.instoreType) }}</view>
+                    <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择入库类型</view>
+                </up-form-item>
+                <!-- 入库日期 -->
+                <view class="h-1" id="instoreDatepppp"></view>
+                <ut-datetime-picker v-model="form.instoreBizInfo.instoreDate" :maxDate="new Date()" mode="date">
+                    <up-form-item borderBottom label="入库日期" required prop="instoreBizInfo.instoreDate">
+                        <up-input v-model="form.instoreBizInfo.instoreDate" readonly placeholder="请选择入库日期" border="none" clearable></up-input>
+                        <template #right>
+                            <up-icon size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
+                        </template>
+                    </up-form-item>
+                </ut-datetime-picker>
+                <!-- 入库批号 -->
+                <up-form-item borderBottom label="入库批号" required prop="batchCode">
+                    <up-input v-model="form.batchCode" placeholder="请输入入库批号" border="none" clearable></up-input>
+                    <template #right>
+                        <up-button @click="generateBatchCode" type="primary" :customStyle="formItemBtnStyle">随机生成</up-button>
+                    </template>
+                </up-form-item>
+                <!-- 库房类型 -->
+                <up-form-item borderBottom label="库房类型" prop="storageType" required>
+                    <view v-if="form.storageType" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_warehouse_type, form.storageType) }}</view>
+                    <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择库房类型</view>
+                </up-form-item>
+                <up-form-item borderBottom label="存放库房" prop="warehouses">
+                    <select-warehouse-input v-model="form.warehouses" title="添加鲜货存放库房" :params="{ type: '4' }"></select-warehouse-input>
+                </up-form-item>
+                <!-- 入库人 -->
+                <up-form-item borderBottom label="入库人" required prop="instoreBizInfo.instoreMg">
+                    <up-input v-model="form.instoreBizInfo.instoreMg" placeholder="请输入入库人" border="none" clearable></up-input>
+                </up-form-item>
+                <!-- 入库备注 -->
+                <up-form-item borderBottom label="入库备注" prop="instoreBizInfo.remark">
+                    <up-textarea v-model="form.instoreBizInfo.remark" placeholder="请输入入库备注" autoHeight></up-textarea>
+                </up-form-item>
+            </view>
+        </up-form>
+        <template #bottom>
+            <view class="pd-20 d-flex">
+                <up-button @click="submitForm" type="primary">确认入库</up-button>
+            </view>
+        </template>
+    </z-paging>
+</template>
+<script setup lang="ts">
+import { useClientRequest } from '@/utils/request';
+import { FreshGoodsInstoreEnum } from '../models/type';
+import { formItemBtnStyle } from '@/assets/styles/uview-plus';
+import { generateUniqueId } from '@/utils/public';
+import { parseTime } from '@/utils/ruoyi';
+import SelectWarehouseInput from '@/models/select-warehouse-input/select-warehouse-input.vue';
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { pt_seed_instore_type, pt_warehouse_type, pt_seed_type, pt_seed_source } = toRefs<any>(proxy?.useDict('pt_seed_instore_type', 'pt_warehouse_type', 'pt_seed_type', 'pt_seed_source'));
+// 表单与分页等基础状态(参考 base-edit 风格)
+const paging = ref<any>(null);
+const upFormRef = ref<any>(null);
+const showArea = ref(false);
+const form = ref<FreshGoodsInstoreEnum>({
+    instoreType: '2',
+    storageType: '4',
+    goodsInfoList: [],
+    warehouses: [],
+    instoreBizInfo: {
+        instoreDate: parseTime(new Date(), '{y}-{m}-{d}'),
+        instoreMg: '',
+        remark: '',
+    },
+});
+const rules = reactive({
+    goodsInfoList: [{ required: true, message: '请添加鲜货信息', type: 'array', min: 1 }],
+    instoreType: [{ required: true, message: '请选择入库类型' }],
+    'instoreBizInfo.instoreDate': [{ required: true, message: '请选择入库日期' }],
+    batchCode: [{ required: true, message: '请输入入库批号' }],
+    'instoreBizInfo.instoreMg': [{ required: true, message: '请输入入库人' }],
+});
+
+const submitForm = async () => {
+    uni.$u.debounce(
+        async () => {
+            try {
+                await upFormRef.value?.validate();
+            } catch (error: any) {
+                // 滚动到第一个错误字段
+                const firstErrorField = error && error[0].prop + 'pppp';
+                paging.value?.scrollIntoViewById(firstErrorField, 30, true);
+                return;
+            }
+            // 提交表单
+            uni.showLoading({
+                title: '提交中...',
+            });
+            const params = form.value.goodsInfoList.map((uid) => {
+                return {
+                    ...uidMapData.value[uid],
+                    ...form.value,
+                    instoreBizInfo: {
+                        ...form.value.instoreBizInfo,
+                        ...uidMapData.value[uid]?.instoreBizInfo,
+                    },
+                };
+            });
+            try {
+                const res = await useClientRequest.post('/plt-api/app/storage/batchInstore', params);
+                if (!res || res.code !== 200) return;
+                uni.hideLoading();
+                uni.showToast({
+                    title: '提交成功',
+                    icon: 'success',
+                });
+                uni.$emit('refreshStorageRoomList');
+                // 返回上一页
+                setTimeout(() => {
+                    uni.navigateBack({
+                        delta: 1,
+                    });
+                }, 1500);
+            } catch (error) {
+                uni.hideLoading();
+            }
+        },
+        500,
+        true,
+    );
+};
+// 点击随机生成服务端生成唯一的批号
+const generateBatchCode = async () => {
+    uni.showLoading({
+        title: '生成中...',
+    });
+    const res = await useClientRequest.post('/plt-api/app/plantationTask/getBatchCode', {
+        plType: 'X',
+        linkType: 'I',
+    });
+    if (res && res.code === 200) {
+        uni.hideLoading();
+        form.value.batchCode = res.data;
+        uni.showToast({
+            title: '批号生成成功',
+            icon: 'success',
+        });
+    }
+};
+
+const uidMapData = ref({} as any);
+// 添加鲜货入库跳转
+const navigateToAddSeedSource = (uid = '', mode = 'add') => {
+    uni.$on('submitForm', (data: any) => {
+        uidMapData.value[data.uid] = data.form;
+        if (data?.mode == 'add') {
+            form.value.goodsInfoList.push(data.uid);
+        }
+        uni.$off('submitForm');
+    });
+    uni.navigateTo({
+        url: '/plant/storage/fresh-goods/info-edit/index',
+        success(res) {
+            res.eventChannel.emit('optionsParam', {
+                uid: uid || generateUniqueId(),
+                mode: mode,
+                form: uid ? uidMapData.value[uid] : {},
+            });
+        },
+    });
+};
+const deleteRow = (index: number, uid: string) => {
+    form.value.goodsInfoList.splice(index, 1);
+    delete uidMapData.value[uid];
+};
+// 编辑时加载详情
+onLoad((optins: any) => {});
+</script>
+<style lang="scss" scoped>
+.card-info-block {
+    border: 1rpx solid #afddbb;
+    border-radius: 10rpx;
+}
+
+.tag-span {
+    padding: 4rpx 12rpx;
+    font-size: 20rpx;
+    border-radius: 18rpx;
+}
+.close-icon {
+    position: absolute;
+    top: 0;
+    right: 0;
+    z-index: 10;
+}
+</style>

+ 297 - 0
src/plant/storage/fresh-goods/detail/index.vue

@@ -0,0 +1,297 @@
+<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="@/static/images/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-${selectDictListClass(pt_seed_instore_type, 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 class="f-s-24 c-#666">{{ selectDictLabel(pt_seed_type, form?.seedType) }}</span>
+                </view>
+                <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="['A3', 'A4'].includes(form?.fungusCodeType)" class="pd2-4-0 f-s-28">
+                    <span class="c-#666">菌种/菌株编号:</span>
+                    <span class="c-#333 f-w-500">{{ selectDictLabel(pt_fungus_code_type, form?.fungusCodeType) }}/{{ form?.fungusCode }}</span>
+                </view>
+                <view class="pd2-4-0 f-s-28">
+                    <span class="c-#666">供应商:</span>
+                    <span class="c-#333 f-w-500">{{ form?.supplier }}</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="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?.restAmount" 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, 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 class="f-s-30 pd2-16-0 info-border-bottom">
+                    <span class="c-#666">采收日期:</span>
+                    <span class="c-#333 f-w-600">{{ form?.productDate || '-' }}</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">{{ selectDictLabel(pt_seed_instore_type, form?.instoreType) || '-' }}</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?.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>
+                <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, pt_warehouse_type, pt_seed_type, pt_seed_source, pt_materail_unit, pt_mother_father_flag, pt_op_method, pt_seed_unit, pt_fungus_code_type, pt_breeding_materials, yes_no, pt_cus_type, pt_cpy_type, pt_gen_unit, pt_medicine_source, pt_medicine_unit } = toRefs<any>(
+    proxy?.useDict(
+        'pt_seed_instore_type',
+        'pt_warehouse_type',
+        'pt_seed_type',
+        'pt_seed_source',
+        'pt_materail_unit',
+        'pt_mother_father_flag',
+        'pt_op_method',
+        'pt_seed_unit',
+        'pt_fungus_code_type',
+        'pt_breeding_materials',
+        'yes_no',
+        'pt_cus_type',
+        'pt_cpy_type',
+        'pt_gen_unit',
+        'pt_medicine_source',
+        '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/storageSeed/getById/${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: '2',
+        },
+    });
+};
+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: '2',
+                ...form.value,
+            });
+        },
+    });
+};
+const onRefresh = () => {
+    getDetailById(did.value);
+    paging.value?.complete();
+};
+const clickEdit = () => {
+    uni.$on('seed-source-detail-refresh', () => {
+        getDetailById(did.value);
+        uni.$off('seed-source-detail-refresh');
+    });
+    uni.$u.route({
+        type: 'navigateTo',
+        url: '/plant/storage/seed-source/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>

+ 283 - 0
src/plant/storage/fresh-goods/info-edit/index.vue

@@ -0,0 +1,283 @@
+<template>
+    <z-paging class="" ref="paging" bgColor="#fff" paging-class="paging-btm-shadow" safe-area-inset-bottom scroll-with-animation>
+        <template #top>
+            <ut-navbar :title="optionsParam?.mode == 'edit' ? '编辑鲜货入库信息' : '添加鲜货入库信息'" :fixed="false" border></ut-navbar>
+        </template>
+        <view class="pd-24">
+            <up-form class="p-rtv" labelPosition="top" :model="form" :rules="rules" labelWidth="auto" ref="upFormRef">
+                <view class="h-1" id="varietyIdpppp"></view>
+                <up-form-item borderBottom label="动植物名称" required prop="varietyId">
+                    <view class="flex1">
+                        <up-button v-if="!form.varietyId" @click="selectVarietyId" type="primary" 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>请选择动植物名称</span>
+                        </up-button>
+                        <view v-else class="bg-#FBFDFB card-info-block pd-24 p-rtv">
+                            <view class="mb-16">
+                                <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-16">
+                                <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">产出:{{ form?.varietyInfo?.medicineName }}</view>
+                            <view
+                                class="close-icon pd-16"
+                                @click="
+                                    form.varietyId = '';
+                                    form.varietyInfo = null;
+                                "
+                            >
+                                <up-icon color="#F81242" name="close" size="32rpx"></up-icon>
+                            </view>
+                        </view>
+                    </view>
+                </up-form-item>
+                <view class="h-1" id="partpppp"></view>
+                <SelectMedicinalPart v-model="form.part" v-model:value-name="form.partName">
+                    <up-form-item borderBottom label="药用部位/对象" prop="part" required>
+                        <up-input v-model="form.partName" placeholder="请选择药用部位/对象" border="none" readonly clearable></up-input>
+                    </up-form-item>
+                </SelectMedicinalPart>
+
+                <view class="h-1" id="sourceTypepppp"></view>
+                <ut-action-sheet :tabs="pt_medicine_source" mode="custom" title="鲜货来源" v-model="form.sourceType">
+                    <up-form-item borderBottom label="鲜货来源" required prop="sourceType">
+                        <view v-if="form.sourceType" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_medicine_source, form.sourceType) }}</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>
+                <!-- 入库数量与单位 -->
+                <view class="h-1" id="capacitypppp"></view>
+                <view class="h-1" id="unitpppp"></view>
+                <up-form-item label="入库量" prop="capacity" required class="form-item-bottom-padding-0">
+                    <div class="flex1 d-flex">
+                        <div class="flex1 ov-hd">
+                            <up-form-item prop="capacity" border-bottom class="form-item-top-padding-0">
+                                <up-input v-model="form.capacity" placeholder="请输入入库量" border="none" clearable></up-input>
+                            </up-form-item>
+                        </div>
+                        <div class="pd-5"></div>
+                        <div class="min-w-200">
+                            <ut-action-sheet v-model="form.unit" :tabs="pt_medicine_unit" mode="custom" 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.unit" class="f-s-30 c-333 f-w-5 text-center">{{ selectDictLabel(pt_medicine_unit, form.unit) }}</view>
+                                        <view v-else class="f-s-30 c-ccc f-w-4 text-center">单位</view>
+                                    </view>
+                                    <template #right>
+                                        <up-icon size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
+                                    </template>
+                                </up-form-item>
+                            </ut-action-sheet>
+                        </div>
+                    </div>
+                </up-form-item>
+
+                <template v-if="['2'].includes(form.sourceType as string)">
+                    <up-form-item borderBottom label="供应商" prop="supplierId" required>
+                        <view class="flex1">
+                            <ContactUnitInput v-model="form.supplierId" v-model:info="form.supplierInfo" :params="{ cpyType: '4' }" title="选择供应商" placeholder="请选择供应商信息"></ContactUnitInput>
+                        </view>
+                    </up-form-item>
+                    <up-form-item borderBottom label="供应商是否是生产商" prop="supplierProducerFlag">
+                        <up-radio-group v-model="form.supplierProducerFlag">
+                            <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>
+                    </up-form-item>
+                    <up-form-item borderBottom label="生产商" prop="producer">
+                        <up-input v-model="form.producer" placeholder="请输入生产商名称" border="none" clearable></up-input>
+                    </up-form-item>
+                </template>
+                <!-- 检验报告与供应商信息 -->
+                <up-form-item borderBottom label="检验报告" prop="examinReport">
+                    <ut-upload v-model="form.examinReport" :max-count="50" valueType="array" accept="image,file"></ut-upload>
+                </up-form-item>
+                <!-- 鲜货产地 -->
+                <PickerAreaInput v-model="form.producePlace" v-model:full-name="form.producePlaceName" title="选择鲜货产地">
+                    <view class="h-1" id="producePlacepppp"></view>
+                    <up-form-item borderBottom label="鲜货产地" prop="producePlace" required>
+                        <view v-if="form.producePlace" class="f-s-30 c-333 f-w-5 flex1">{{ form.producePlaceName }}</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>
+                </PickerAreaInput>
+                <view class="h-1" id="productDatepppp"></view>
+                <ut-datetime-picker v-model="form.productDate" :maxDate="new Date()" mode="date">
+                    <up-form-item borderBottom label="采收日期" prop="productDate" required>
+                        <up-input v-model="form.productDate" readonly placeholder="请选择采收日期" border="none" clearable></up-input>
+                        <template #right>
+                            <up-icon size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
+                        </template>
+                    </up-form-item>
+                </ut-datetime-picker>
+                <!-- 媒体与附件 -->
+                <up-form-item borderBottom label="鲜货图片" prop="imgs">
+                    <ut-upload v-model="form.imgs" :max-count="9" valueType="string"></ut-upload>
+                </up-form-item>
+                <up-form-item borderBottom label="鲜货视频" prop="vedios">
+                    <ut-upload v-model="form.vedios" :max-count="3" accept="video" valueType="string"></ut-upload>
+                </up-form-item>
+            </up-form>
+        </view>
+        <template #bottom>
+            <view class="pd-20 d-flex">
+                <up-button @click="submitForm" type="primary">保存</up-button>
+            </view>
+        </template>
+    </z-paging>
+</template>
+<script setup lang="ts">
+import { FreshGoodsInstoreItemForm } from '../models/type';
+import ContactUnitInput from '@/models/contact-unit-input/contact-unit-input.vue';
+import PickerAreaInput from '@/models/picker-area-input/picker-area-input.vue';
+import SelectMedicinalPart from '@/models/select-medicinal-part/select-medicinal-part.vue';
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { pt_medicine_source, pt_medicine_unit, yes_no } = toRefs<any>(proxy?.useDict('pt_medicine_source', 'pt_medicine_unit', 'yes_no'));
+const paging = ref<any>(null);
+const upFormRef = ref<any>(null);
+
+const createDefaultForm = (): FreshGoodsInstoreItemForm => ({
+    uid: '',
+    varietyId: '',
+    varietyInfo: null,
+    part: '',
+    partName: '',
+    sourceType: '',
+    capacity: '',
+    unit: '',
+    supplierId: undefined,
+    supplierProducerFlag: '',
+    producer: '',
+    examinReport: [],
+    producePlace: '',
+    producePlaceName: '',
+    productDate: '',
+    imgs: '',
+    vedios: '',
+});
+
+const form = ref<FreshGoodsInstoreItemForm>(createDefaultForm());
+
+const rules = reactive({
+    varietyId: [{ required: true, message: '请选择动植物名称' }],
+    part: [{ required: true, message: '请选择药用部位/对象' }],
+    sourceType: [{ required: true, message: '请选择鲜货来源' }],
+    capacity: [
+        { required: true, message: '请输入入库量' },
+        {
+            asyncValidator: (rule: any, value: any) => {
+                if (value === 0 || value === '0') return Promise.reject('入库量需大于0');
+                if (value === undefined || value === null || value === '') return Promise.resolve();
+                const num = Number(value);
+                if (Number.isNaN(num)) return Promise.reject('入库量请输入数字');
+                if (num <= 0) return Promise.reject('入库量需大于0');
+                return Promise.resolve();
+            },
+        },
+    ],
+    unit: [{ required: true, message: '请选择单位' }],
+    supplierId: [
+        {
+            asyncValidator: (rule: any, value: any) => {
+                if (['2'].includes(form.value.sourceType as string)) {
+                    if (!value) return Promise.reject('请选择供应商');
+                }
+                return Promise.resolve();
+            },
+        },
+    ],
+    producePlace: [{ required: true, message: '请选择鲜货产地' }],
+    productDate: [{ required: true, message: '请选择采收日期' }],
+});
+
+const submitForm = async () => {
+    console.log(form.value);
+    uni.$u.debounce(
+        async () => {
+            try {
+                await upFormRef.value?.validate();
+            } catch (error: any) {
+                // 滚动到第一个错误字段
+                const firstErrorField = error && error[0].prop + 'pppp';
+                paging.value?.scrollIntoViewById(firstErrorField, 30, true);
+                return;
+            }
+            // 提交表单
+            uni.$emit('submitForm', {
+                ...optionsParam.value,
+                form: { ...form.value, uid: optionsParam.value?.uid || '' },
+            });
+            uni.navigateBack({
+                delta: 1,
+            });
+            try {
+            } catch (error) {
+                uni.hideLoading();
+            }
+        },
+        500,
+        true,
+    );
+};
+// 去选择动植物名称
+const selectVarietyId = () => {
+    uni.$once('updateBiologicalname', function (data) {
+        form.value.varietyId = data.msg.id;
+        form.value.varietyInfo = data.msg;
+    });
+    uni.$u.route({
+        type: 'navigateTo',
+        url: '/tools/por-torganism/index',
+        params: {
+            title: '选择动植物名称',
+        },
+    });
+};
+const optionsParam = ref({} as any);
+onLoad((options: any) => {
+    const instance: any = getCurrentInstance()?.proxy;
+    const eventChannel = instance?.getOpenerEventChannel();
+    eventChannel.on('optionsParam', (data: any) => {
+        console.log(data);
+        optionsParam.value = {
+            uid: data?.uid || '',
+            mode: data?.mode || 'add',
+        };
+        form.value = {
+            ...createDefaultForm(),
+            ...data?.form,
+            uid: data?.uid || data?.form?.uid || '',
+        };
+    });
+});
+</script>
+<style lang="scss" scoped>
+.card-info-block {
+    border: 1rpx solid #afddbb;
+    border-radius: 10rpx;
+}
+
+.close-icon {
+    position: absolute;
+    top: 0rpx;
+    right: 0rpx;
+}
+:deep(.form-item-top-padding-0) {
+    > .u-form-item__body {
+        padding-top: 0rpx;
+    }
+}
+:deep(.form-item-bottom-padding-0) {
+    > .u-form-item__body {
+        padding-bottom: 0rpx;
+    }
+}
+</style>

+ 595 - 0
src/plant/storage/fresh-goods/info-update/index.vue

@@ -0,0 +1,595 @@
+<template>
+    <z-paging class="" ref="paging" bgColor="#f7f7f7" paging-class="paging-btm-shadow" safe-area-inset-bottom scroll-with-animation>
+        <template #top>
+            <ut-navbar :title="did ? '编辑种源入库' : '新增种源入库'" :fixed="false" border></ut-navbar>
+        </template>
+        <up-form class="p-rtv" labelPosition="top" :model="form" :rules="rules" labelWidth="auto" ref="upFormRef">
+            <!-- 种源信息(复制自 info-edit 字段与顺序) -->
+            <view class="pd-24">
+                <view class="startline-title">种源信息</view>
+            </view>
+            <view class="pd-24 bg-#fff">
+                <!-- 基本信息 -->
+                <view class="h-1" id="seedTypepppp"></view>
+                <ut-action-sheet :tabs="pt_seed_type" mode="custom" title="种源类型" v-model="form.seedType">
+                    <up-form-item borderBottom label="种源类型" required prop="seedType">
+                        <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>
+                <view class="h-1" id="varietyIdpppp"></view>
+                <up-form-item borderBottom label="物种基原" required prop="varietyId">
+                    <view class="flex1">
+                        <up-button v-if="!form.varietyId" @click="selectVarietyId" type="primary" 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>请选择物种基原</span>
+                        </up-button>
+                        <view v-else class="bg-#FBFDFB card-info-block pd-24 p-rtv">
+                            <view class="mb-16">
+                                <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-16">
+                                <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 v-if="form?.varietyInfo?.medicineName" class="f-s-24 c-#666">产出:{{ form?.varietyInfo?.medicineName }}</view>
+                            <view
+                                class="close-icon pd-16"
+                                @click="
+                                    form.varietyId = '';
+                                    form.varietyInfo = null;
+                                "
+                            >
+                                <up-icon color="#F81242" name="close" size="32rpx"></up-icon>
+                            </view>
+                        </view>
+                    </view>
+                </up-form-item>
+                <up-form-item borderBottom label="具体品种/品系名称" prop="seedName">
+                    <up-input v-model="form.seedName" placeholder="请输入具体品种/品系名称" border="none" clearable></up-input>
+                </up-form-item>
+                <view class="h-1" id="seedSourcepppp"></view>
+                <ut-action-sheet :tabs="pt_seed_source" mode="custom" title="种源来源" v-model="form.seedSource">
+                    <up-form-item borderBottom label="种源来源" required prop="seedSource">
+                        <view v-if="form.seedSource" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_seed_source, form.seedSource) }}</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>
+                <view class="h-1" id="motherFatherFlagpppp"></view>
+                <ut-action-sheet :tabs="pt_mother_father_flag" mode="custom" title="父母本情况" v-model="form.instoreBizInfo.motherFatherFlag">
+                    <template v-if="['A3', 'A4'].includes(form.seedType as string) || ['3'].includes(form.seedSource as string)">
+                        <up-form-item borderBottom label="父母本情况" prop="instoreBizInfo.motherFatherFlag" required>
+                            <view v-if="form.instoreBizInfo.motherFatherFlag" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_mother_father_flag, form.instoreBizInfo.motherFatherFlag) }}</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>
+                    </template>
+                    <template v-else>
+                        <up-form-item borderBottom label="父母本情况">
+                            <view v-if="form.instoreBizInfo.motherFatherFlag" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_mother_father_flag, form.instoreBizInfo.motherFatherFlag) }}</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>
+                    </template>
+                </ut-action-sheet>
+                <template>
+                    <!-- 父本品种 -->
+                    <up-form-item v-if="form?.instoreBizInfo?.motherFatherFlag == '2'" borderBottom label="父本品种" prop="fatherVarietyId">
+                        <view class="flex1">
+                            <up-button v-if="!form.instoreBizInfo.fatherVarietyId" @click="selectFatherVarietyId" type="primary" 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>请选择父本品种</span>
+                            </up-button>
+                            <view v-else class="bg-#FBFDFB card-info-block pd-24 p-rtv">
+                                <view class="mb-16">
+                                    <span class="f-s-34 c-#333 f-w-5 mr-16">{{ form?.instoreBizInfo?.fatherVarietyInfo?.varietyName }}</span>
+                                    <span class="f-s-24 c-#666">{{ form?.instoreBizInfo?.fatherVarietyInfo?.latinName }}</span>
+                                </view>
+                                <view class="mb-16">
+                                    <span class="f-s-28 c-#333 f-w-5 mr-16">{{ form?.instoreBizInfo?.fatherVarietyInfo?.genusName }}</span>
+                                    <span class="f-s-24 c-#666">{{ form?.instoreBizInfo?.fatherVarietyInfo?.genusLatinName }}</span>
+                                </view>
+                                <view v-if="form?.varietyInfo?.medicineName" class="f-s-24 c-#666">产出:{{ form?.instoreBizInfo?.fatherVarietyInfo?.medicineName }}</view>
+                                <view
+                                    class="close-icon pd-16"
+                                    @click="
+                                        form.instoreBizInfo.fatherVarietyId = '';
+                                        form.instoreBizInfo.fatherVarietyInfo = null;
+                                    "
+                                >
+                                    <up-icon color="#F81242" name="close" size="32rpx"></up-icon>
+                                </view>
+                            </view>
+                        </view>
+                    </up-form-item>
+                    <!-- 母本品种 -->
+                    <up-form-item borderBottom label="母本品种" prop="instoreBizInfo.motherVarietyId">
+                        <view class="flex1">
+                            <up-button v-if="!form.instoreBizInfo.motherVarietyId" @click="selectMotherVarietyId" type="primary" 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>请选择母本品种</span>
+                            </up-button>
+                            <view v-else class="bg-#FBFDFB card-info-block pd-24 p-rtv mt-16">
+                                <view class="mb-16">
+                                    <span class="f-s-34 c-#333 f-w-5 mr-16">{{ form?.instoreBizInfo?.motherVarietyInfo?.varietyName }}</span>
+                                    <span class="f-s-24 c-#666">{{ form?.instoreBizInfo?.motherVarietyInfo?.latinName }}</span>
+                                </view>
+                                <view class="mb-16">
+                                    <span class="f-s-28 c-#333 f-w-5 mr-16">{{ form?.instoreBizInfo?.motherVarietyInfo?.genusName }}</span>
+                                    <span class="f-s-24 c-#666">{{ form?.instoreBizInfo?.motherVarietyInfo?.genusLatinName }}</span>
+                                </view>
+                                <view v-if="form?.varietyInfo?.medicineName" class="f-s-24 c-#666">产出:{{ form?.instoreBizInfo?.motherVarietyInfo?.medicineName }}</view>
+                                <view
+                                    class="close-icon pd-16"
+                                    @click="
+                                        form.instoreBizInfo.motherVarietyId = '';
+                                        form.instoreBizInfo.motherVarietyInfo = null;
+                                    "
+                                >
+                                    <up-icon color="#F81242" name="close" size="32rpx"></up-icon>
+                                </view>
+                            </view>
+                        </view>
+                    </up-form-item>
+                </template>
+                <view class="h-1" id="genCountpppp"></view>
+                <view class="h-1" id="genUnitpppp"></view>
+                <template v-if="['A3', 'A4'].includes(form.seedType as string)">
+                    <up-form-item :label="`${genCountMap[form.seedType as 'A3' | 'A4']}`" required class="form-item-bottom-padding-0">
+                        <view class="d-flex flex1">
+                            <view class="flex1 ov-hd">
+                                <up-form-item prop="instoreBizInfo.genCount" border-bottom class="form-item-top-padding-0">
+                                    <up-input v-model="form.instoreBizInfo.genCount" :placeholder="`请输入${genCountMap[form.seedType as 'A3' | 'A4']}`" border="none" clearable></up-input>
+                                </up-form-item>
+                            </view>
+                            <view class="pd-5"></view>
+                            <view class="min-w-200">
+                                <ut-action-sheet v-model="form.instoreBizInfo.genUnit" :tabs="pt_gen_unit" mode="custom" title="选择单位">
+                                    <up-form-item prop="instoreBizInfo.genUnit" border-bottom class="form-item-top-padding-0">
+                                        <view class="flex1" style="line-height: 24px">
+                                            <view v-if="form.instoreBizInfo.genUnit" class="f-s-30 c-333 f-w-5 text-center">{{ selectDictLabel(pt_gen_unit, form.instoreBizInfo.genUnit) }}</view>
+                                            <view v-else class="f-s-30 c-ccc f-w-4 text-center">单位</view>
+                                        </view>
+                                        <template #right>
+                                            <up-icon size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
+                                        </template>
+                                    </up-form-item>
+                                </ut-action-sheet>
+                            </view>
+                        </view>
+                    </up-form-item>
+                </template>
+                <template v-else>
+                    <up-form-item label="繁衍世代" class="form-item-bottom-padding-0">
+                        <view class="d-flex flex1">
+                            <view class="flex1 ov-hd">
+                                <up-form-item border-bottom class="form-item-top-padding-0">
+                                    <up-input v-model="form.instoreBizInfo.genCount" placeholder="请输入繁衍世代" border="none" clearable></up-input>
+                                </up-form-item>
+                            </view>
+                            <view class="pd-5"></view>
+                            <view class="min-w-200">
+                                <ut-action-sheet v-model="form.instoreBizInfo.genUnit" :tabs="pt_gen_unit" mode="custom" title="选择单位">
+                                    <up-form-item border-bottom class="form-item-top-padding-0">
+                                        <view class="flex1" style="line-height: 24px">
+                                            <view v-if="form.instoreBizInfo.genUnit" class="f-s-30 c-333 f-w-5 text-center">{{ selectDictLabel(pt_gen_unit, form.instoreBizInfo.genUnit) }}</view>
+                                            <view v-else class="f-s-30 c-ccc f-w-4 text-center">单位</view>
+                                        </view>
+                                        <template #right>
+                                            <up-icon size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
+                                        </template>
+                                    </up-form-item>
+                                </ut-action-sheet>
+                            </view>
+                        </view>
+                    </up-form-item>
+                </template>
+
+                <view class="h-1" id="entrustIdpppp"></view>
+                <up-form-item borderBottom label="受托单位" prop="entrustId" required>
+                    <view class="flex1">
+                        <ContactUnitInput v-model="form.entrustId" v-model:info="form.entrustInfo" :params="{ cpyType: '2' }" title="选择受托单位" placeholder="请选择受托单位信息"></ContactUnitInput>
+                    </view>
+                </up-form-item>
+
+                <!-- 入库数量与单位 -->
+                <view class="h-1" id="capacitypppp"></view>
+                <view class="h-1" id="unitpppp"></view>
+                <up-form-item label="入库量" prop="capacity" required class="form-item-bottom-padding-0">
+                     <view class="f-s-30 c-333 f-w-5 flex1">{{ form?.capacity }}{{ form?.unit }}</view>
+                </up-form-item>
+                <!-- 检验报告与供应商信息 -->
+                <up-form-item borderBottom label="检验报告" prop="examinReport">
+                    <ut-upload v-model="form.examinReport" :max-count="50" valueType="array" accept="image,file"></ut-upload>
+                </up-form-item>
+                <template v-if="['2', '3'].includes(form.seedSource as string)">
+                    <up-form-item borderBottom label="供应商" prop="supplierId" required>
+                        <view class="flex1">
+                            <ContactUnitInput v-model="form.supplierId" v-model:info="form.supplierInfo" :params="{ cpyType: '4' }" title="选择供应商" placeholder="请选择供应商信息"></ContactUnitInput>
+                        </view>
+                    </up-form-item>
+                    <up-form-item borderBottom label="供应商是否是生产商" prop="supplierProducerFlag">
+                        <up-radio-group v-model="form.supplierProducerFlag">
+                            <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>
+                    </up-form-item>
+                    <up-form-item borderBottom label="生产商" prop="producer">
+                        <up-input v-model="form.producer" placeholder="请输入生产商名称" border="none" clearable></up-input>
+                    </up-form-item>
+                </template>
+                <!-- 菌种编码信息 -->
+                <up-form-item required v-if="['A4', 'A8'].includes(form.seedType as string)" :label="`${selectDictLabel(pt_seed_type, form.seedType as string)}编号`" class="form-item-bottom-padding-0">
+                    <view class="d-flex flex1">
+                        <view class="flex1">
+                            <ut-action-sheet v-model="form.fungusCodeType" :tabs="pt_fungus_code_type" mode="custom" title="选择单位">
+                                <up-form-item prop="fungusCodeType" border-bottom class="form-item-top-padding-0">
+                                    <view class="flex1" style="line-height: 24px">
+                                        <view v-if="form.fungusCodeType" class="f-s-30 c-333 f-w-5">{{ selectDictLabel(pt_fungus_code_type, form.fungusCodeType) }}</view>
+                                        <view v-else class="f-s-30 c-ccc f-w-4">选择编号类型</view>
+                                    </view>
+                                    <template #right>
+                                        <up-icon class="pr-20" size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
+                                    </template>
+                                </up-form-item>
+                            </ut-action-sheet>
+                        </view>
+                        <view class="pd-5"></view>
+                        <view class="flex1">
+                            <up-form-item prop="fungusCode" border-bottom class="form-item-top-padding-0">
+                                <up-input v-model="form.fungusCode" placeholder="输入数字小数点" border="none" clearable></up-input>
+                            </up-form-item>
+                        </view>
+                    </view>
+                </up-form-item>
+                <!-- 个体标识:此处仅占位,后续可改为多选列表 -->
+                <view class="h-1" id="instoreBizInfo.idFlagpppp"></view>
+                <up-form-item borderBottom label="是否有个体标识" prop="instoreBizInfo.idFlag" required>
+                    <up-radio-group v-model="form.instoreBizInfo.idFlag">
+                        <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>
+                </up-form-item>
+                <!-- 个体标识:此处仅占位,后续可改为多选列表 -->
+                <template v-if="+form?.instoreBizInfo?.idFlag">
+                    <view class="h-1" id="instoreBizInfo.animalspppp"></view>
+                    <up-form-item borderBottom label="个体标识号" prop="instoreBizInfo.animals" required>
+                        <AnimalsInput v-model="form.instoreBizInfo.animals"></AnimalsInput>
+                    </up-form-item>
+                </template>
+                <!-- 保藏方法 -->
+                <up-form-item borderBottom label="保藏方法" prop="instoreBizInfo.storageMethod">
+                    <up-input v-model="form.instoreBizInfo.storageMethod" placeholder="请输入保藏方法" border="none" clearable></up-input>
+                </up-form-item>
+                <!-- 媒体与附件 -->
+                <up-form-item borderBottom label="种源图片" prop="imgs">
+                    <ut-upload v-model="form.imgs" :max-count="9" valueType="string"></ut-upload>
+                </up-form-item>
+                <up-form-item borderBottom label="种源视频" prop="vedios">
+                    <ut-upload v-model="form.vedios" :max-count="3" accept="video" valueType="string"></ut-upload>
+                </up-form-item>
+
+                <!-- 种源产地 -->
+                <PickerAreaInput v-model="form.adcode" v-model:full-name="form.adcodeName" title="选择种源产地">
+                    <up-form-item borderBottom label="种源产地" prop="adcode">
+                        <view v-if="form.adcode" class="f-s-30 c-333 f-w-5 flex1">{{ form.adcodeName }}</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>
+                </PickerAreaInput>
+                <ut-action-sheet :tabs="pt_breeding_materials" mode="custom" title="繁殖材料" multiple v-model="form.generationMaterial">
+                    <up-form-item borderBottom label="繁殖材料" prop="generationMaterial">
+                        <view v-if="form.generationMaterial" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabels(pt_breeding_materials, form.generationMaterial, ',') }}</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>
+
+                <PickerAreaInput v-model="form.generationAdcode" v-model:full-name="form.generationAdcodeName" :maxLevel="4" title="选择繁殖地点/采集地点">
+                    <up-form-item borderBottom label="繁殖地点/采集地点" prop="generationAdcode">
+                        <view v-if="form.generationAdcode" class="f-s-30 c-333 f-w-5 flex1">{{ form.generationAdcodeName }}</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>
+                </PickerAreaInput>
+                <!-- 资质证明附件(暂按上传控件处理,可后续细化) -->
+                <up-form-item borderBottom label="物种鉴定证书" prop="spCert">
+                    <ut-upload v-model="form.spCert" :max-count="9" valueType="array" accept="file"></ut-upload>
+                </up-form-item>
+                <!-- 检疫信息 -->
+                <up-form-item borderBottom label="种源检疫证号" prop="seedCheckSn">
+                    <up-input v-model="form.seedCheckSn" placeholder="请输入种源检疫证号" border="none" clearable></up-input>
+                </up-form-item>
+                <up-form-item borderBottom label="种源检疫证书" prop="seedCheckCert">
+                    <ut-upload v-model="form.seedCheckCert" :max-count="9" valueType="array" accept="file"></ut-upload>
+                </up-form-item>
+            </view>
+
+            <view class="pd-24">
+                <view class="startline-title">入库信息</view>
+            </view>
+            <view class="pd-24 bg-#fff">
+                <!-- 种源级别 -->
+                <up-form-item borderBottom label="种源级别" prop="seedLevel">
+                    <up-input v-model="form.seedLevel" placeholder="请输入种源级别" border="none" clearable></up-input>
+                </up-form-item>
+                <!-- 入库类型 -->
+                <up-form-item borderBottom label="入库类型" required prop="instoreType">
+                    <view v-if="form.instoreType" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_seed_instore_type, form.instoreType) }}</view>
+                    <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择入库类型</view>
+                </up-form-item>
+                <!-- 入库日期 -->
+                <view class="h-1" id="instoreDatepppp"></view>
+                <ut-datetime-picker v-model="form.instoreBizInfo.instoreDate" :maxDate="new Date()" mode="date">
+                    <up-form-item borderBottom label="入库日期" required prop="instoreBizInfo.instoreDate">
+                        <up-input v-model="form.instoreBizInfo.instoreDate" placeholder="请选择入库日期" border="none" clearable></up-input>
+                        <template #right>
+                            <up-icon size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
+                        </template>
+                    </up-form-item>
+                </ut-datetime-picker>
+                <!-- 入库批号 -->
+                <up-form-item borderBottom label="入库批号" required prop="batchCode">
+                    <view class="f-s-30 c-333 f-w-5 flex1">{{ form.batchCode }}</view>
+                </up-form-item>
+                <!-- 库房类型 -->
+                <up-form-item borderBottom label="库房类型" prop="storeType" required>
+                    <view v-if="form.storeType" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_warehouse_type, form.storeType) }}</view>
+                    <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择库房类型</view>
+                </up-form-item>
+                <!-- 存放库房(具体库房/货架信息稍后补充为选择器) -->
+                <up-form-item borderBottom label="存放库房" prop="warehouses">
+                    <select-warehouse-input v-model="form.warehouses" title="添加种源存放库房" :params="{ type: '2' }"></select-warehouse-input>
+                </up-form-item>
+                <!-- 入库人 -->
+                <up-form-item borderBottom label="入库人" required prop="instoreBizInfo.instoreMg">
+                    <up-input v-model="form.instoreBizInfo.instoreMg" placeholder="请输入入库人" border="none" clearable></up-input>
+                </up-form-item>
+                <!-- 入库备注 -->
+                <up-form-item borderBottom label="入库备注" prop="instoreBizInfo.remark">
+                    <up-textarea v-model="form.instoreBizInfo.remark" placeholder="请输入入库备注" autoHeight></up-textarea>
+                </up-form-item>
+            </view>
+        </up-form>
+        <template #bottom>
+            <view class="pd-20 d-flex">
+                <up-button @click="submitForm" type="primary">保存</up-button>
+            </view>
+        </template>
+    </z-paging>
+</template>
+<script setup lang="ts">
+import { useClientRequest } from '@/utils/request';
+import { formItemBtnStyle } from '@/assets/styles/uview-plus';
+import { seedInfoListType } from '../models/type';
+import AnimalsInput from '../models/animals-input.vue';
+import ContactUnitInput from '@/models/contact-unit-input/contact-unit-input.vue';
+import PickerAreaInput from '@/models/picker-area-input/picker-area-input.vue';
+import SelectWarehouseInput from '@/models/select-warehouse-input/select-warehouse-input.vue';
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { pt_seed_instore_type, pt_warehouse_type, pt_seed_type, pt_seed_source, pt_materail_unit, pt_mother_father_flag, pt_op_method, pt_seed_unit, pt_fungus_code_type, pt_breeding_materials, yes_no, pt_cus_type, pt_cpy_type, pt_gen_unit } = toRefs<any>(
+    proxy?.useDict('pt_seed_instore_type', 'pt_warehouse_type', 'pt_seed_type', 'pt_seed_source', 'pt_materail_unit', 'pt_mother_father_flag', 'pt_op_method', 'pt_seed_unit', 'pt_fungus_code_type', 'pt_breeding_materials', 'yes_no', 'pt_cus_type', 'pt_cpy_type', 'pt_gen_unit'),
+);
+const paging = ref<any>(null);
+const upFormRef = ref<any>(null);
+// 单条种源信息 + 入库信息的合并表单
+const form = ref<seedInfoListType | any>({
+    imgs: undefined,
+    vedios: undefined,
+    spCert: [],
+    newSpCert: [],
+    importCert: [],
+    seedCheckCert: [],
+    unit: '',
+    adcode: '',
+    instoreBizInfo: {
+        motherFatherFlag: '',
+        idFlag: '1',
+        genUnit: '',
+        instoreDate: '',
+        instoreMg: '',
+        remark: '',
+    },
+    generationMaterial: '',
+    instoreType: '2',
+    storeType: '2',
+});
+const rules = reactive({
+    // 种源信息校验(来自 info-edit)
+    seedType: [{ required: true, message: '请选择种源类型' }],
+    varietyId: [{ required: true, message: '请选择物种基原' }],
+    seedSource: [{ required: true, message: '请选择种源来源' }],
+    'instoreBizInfo.motherFatherFlag': [{ required: true, message: '请选择父母本情况' }],
+    'instoreBizInfo.genCount': [
+        {
+            asyncValidator: (rule: any, value: any) => {
+                if (['A3', 'A4'].includes(form.value.seedType as string)) {
+                    if (!value) {
+                        return Promise.reject('请输入' + genCountMap[form.value.seedType as 'A3' | 'A4']);
+                    }
+                }
+                return Promise.resolve();
+            },
+        },
+    ],
+    'instoreBizInfo.genUnit': [
+        {
+            asyncValidator: (rule: any, value: any) => {
+                if (['A3', 'A4'].includes(form.value.seedType as string)) {
+                    if (!value) {
+                        return Promise.reject('请选择单位');
+                    }
+                }
+                return Promise.resolve();
+            },
+        },
+    ],
+    entrustId: [{ required: true, message: '请选择受托单位' }],
+    capacity: [{ required: true, message: '请输入入库量' }],
+    unit: [{ required: true, message: '请选择单位' }],
+    supplierId: [{ required: true, message: '请选择供应商' }],
+    fungusCodeType: [{ required: true, message: '请选择编号类型' }],
+    fungusCode: [{ required: true, message: '请输入编号' }],
+    'instoreBizInfo.idFlag': [{ required: true, message: '请选择是否有个体标识' }],
+    'instoreBizInfo.animals': [{ type: 'array', required: true, message: '请输入个体标识号' }],
+    // 入库信息校验(来自 add)
+    instoreType: [{ required: true, message: '请选择入库类型' }],
+    'instoreBizInfo.instoreDate': [{ required: true, message: '请选择入库日期' }],
+    batchCode: [{ required: true, message: '请输入入库批号' }],
+    'instoreBizInfo.instoreMg': [{ required: true, message: '请输入入库人' }],
+});
+// 繁衍世代对象
+const genCountMap = reactive({
+    A4: '累计扩繁代数',
+    A3: '继代培养次数',
+});
+
+// 提交:当前页面改为单条种源信息,直接提交合并后的对象
+const submitForm = async () => {
+    uni.$u.debounce(
+        async () => {
+            try {
+                await upFormRef.value?.validate();
+            } catch (error: any) {
+                const firstErrorField = error && error[0].prop + 'pppp';
+                paging.value?.scrollIntoViewById(firstErrorField, 30, true);
+                return;
+            }
+            uni.showLoading({
+                title: '提交中...',
+            });
+            try {
+                // 这里使用单条入库接口,后端若仍要求 batch,可根据需要包装成数组
+                const res = await useClientRequest.post('/plt-api/app/storageSeed/edit', form.value);
+                if (!res || res.code !== 200) return;
+                uni.hideLoading();
+                uni.showToast({
+                    title: '提交成功',
+                    icon: 'success',
+                });
+                uni.$emit('seed-source-detail-refresh');
+                uni.$emit('refreshStorageRoomList');
+                setTimeout(() => {
+                    uni.navigateBack({
+                        delta: 1,
+                    });
+                }, 1500);
+            } catch (error) {
+                uni.hideLoading();
+            }
+        },
+        500,
+        true,
+    );
+};
+// 点击随机生成服务端生成唯一的批号(与 add 一致)
+const generateBatchCode = async () => {
+    uni.showLoading({
+        title: '生成中...',
+    });
+    const res = await useClientRequest.post('/plt-api/app/plantationTask/getBatchCode', {
+        plType: 'S',
+        linkType: 'I',
+    });
+    if (res && res.code === 200) {
+        uni.hideLoading();
+        form.value.batchCode = res.data;
+        uni.showToast({
+            title: '批号生成成功',
+            icon: 'success',
+        });
+    }
+};
+
+// 选择物种、父母本逻辑保持与 info-edit 一致
+const selectVarietyId = () => {
+    uni.$once('updateBiologicalname', function (data) {
+        form.value.varietyId = data.msg.id;
+        form.value.varietyInfo = data.msg;
+    });
+    uni.$u.route({
+        type: 'navigateTo',
+        url: '/tools/por-torganism/index',
+        params: {
+            title: '选择物种基原',
+        },
+    });
+};
+const selectFatherVarietyId = () => {
+    uni.$once('updateBiologicalname', function (data) {
+        form.value.instoreBizInfo.fatherVarietyId = data.msg.id;
+        form.value.instoreBizInfo.fatherVarietyInfo = data.msg;
+    });
+    uni.$u.route({
+        type: 'navigateTo',
+        url: '/tools/por-torganism/index',
+        params: {
+            title: '选择父本品种',
+        },
+    });
+};
+const selectMotherVarietyId = () => {
+    uni.$once('updateBiologicalname', function (data) {
+        form.value.instoreBizInfo.motherVarietyId = data.msg.id;
+        form.value.instoreBizInfo.motherVarietyInfo = data.msg;
+    });
+    uni.$u.route({
+        type: 'navigateTo',
+        url: '/tools/por-torganism/index',
+        params: {
+            title: '选择母本品种',
+        },
+    });
+};
+const did = ref('');
+// 获取详情(仓库信息)
+const getDetailById = async (id: string) => {
+    if (!id) return;
+    const res = await useClientRequest.get(`/plt-api/app/storageSeed/getById/${id}`);
+    if (res && res.code === 200) {
+        form.value = {
+            ...form.value,
+            ...res.data,
+        };
+    }
+};
+
+// 页面入参解析并加载
+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;
+}
+
+.tag-span {
+    padding: 4rpx 12rpx;
+    font-size: 20rpx;
+    border-radius: 18rpx;
+}
+.close-icon {
+    position: absolute;
+    top: 0;
+    right: 0;
+    z-index: 10;
+}
+</style>

+ 194 - 0
src/plant/storage/fresh-goods/list/index.vue

@@ -0,0 +1,194 @@
+<template>
+    <z-paging ref="paging" v-model="list" bgColor="#f7f7f7" @query="query">
+        <template #top>
+            <ut-navbar title="鲜货库" :fixed="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="[{ label: '全部', value: '' }, ...pt_seed_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_seed_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" class="mb-20 b-radius">
+                    <view class="b-radius bg-#fff pd-20 p-rtv" @click.stop="$u.route({ url: '/plant/storage/seed-source/detail/index', params: { id: item.id } })">
+                        <view class="d-flex j-sb a-c li-item-head mb-16">
+                            <view class="li-left-tag" :class="{ [`bg-${selectDictListClass(pt_seed_instore_type, item?.instoreType)}`]: true }">{{ selectDictLabel(pt_seed_instore_type, item?.instoreType) }}</view>
+                            <view class="f-s-22 c-#666">{{ item?.instoreBizInfo?.instoreDate }}</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 class="f-s-24 c-#666">{{ selectDictLabel(pt_seed_type, item?.seedType) }}</span>
+                            </view>
+                            <view>
+                                <view v-if="item?.examinReport?.length" 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">
+                            <span class="c-#666">入库批号:</span>
+                            <span class="c-#333 f-w-500">{{ item?.batchCode }}</span>
+                        </view>
+                        <!-- <view class="pd2-4-0 f-s-28">
+                            <span class="c-#666">溯源批号:</span>
+                            <span class="c-#333 f-w-500">暂无</span>
+                        </view> -->
+                        <view v-if="['A3', 'A4'].includes(item?.fungusCodeType)" class="pd2-4-0 f-s-28">
+                            <span class="c-#666">菌种/菌株编号:</span>
+                            <span class="c-#333 f-w-500">{{ selectDictLabel(pt_fungus_code_type, item?.fungusCodeType) }}/{{ item?.fungusCode }}</span>
+                        </view>
+                        <view class="pd2-4-0 f-s-28">
+                            <span class="c-#666">供应商:</span>
+                            <span class="c-#333 f-w-500">{{ item?.supplierInfo?.cusName || '-' }}</span>
+                        </view>
+                        <view v-if="item?.warehouses?.length" class="pd2-4-0 f-s-28">
+                            <span class="c-#666">存放库房:</span>
+                            <span class="c-#333 f-w-500">{{ getStorageRoomNames(item?.warehouses) || '-' }}</span>
+                        </view>
+                        <view class="pd2-4-0 f-s-28">
+                            <span class="c-#666">入库量:</span>
+                            <span class="c-#333 f-w-500">{{ item?.capacity }}{{ item?.unit }}</span>
+                        </view>
+                        <view class="d-flex">
+                            <view v-if="item?.restAmount" class="pd2-4-0 f-s-28 flex1">
+                                <span class="c-#666">出库量:</span>
+                                <span class="c-#333 f-w-500">{{ item?.inputAmount || '0' }}{{ item?.unit }}</span>
+                            </view>
+                            <view v-if="item?.restAmount" class="pd2-4-0 f-s-28 flex1">
+                                <span class="c-danger">剩余量:</span>
+                                <span class="c-danger f-w-500">{{ item?.restAmount || '0' }}{{ item?.unit }}</span>
+                            </view>
+                        </view>
+                    </view>
+                </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';
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { pt_seed_instore_type, pt_warehouse_type, pt_seed_type, pt_seed_source, pt_materail_unit, pt_mother_father_flag, pt_op_method, pt_seed_unit, pt_fungus_code_type, pt_breeding_materials, yes_no, pt_cus_type, pt_cpy_type, pt_gen_unit } = toRefs<any>(proxy?.useDict('pt_seed_instore_type', 'pt_warehouse_type', 'pt_seed_type', 'pt_seed_source', 'pt_materail_unit', 'pt_mother_father_flag', 'pt_op_method', 'pt_seed_unit', 'pt_fungus_code_type', 'pt_breeding_materials', 'yes_no', 'pt_cus_type', 'pt_cpy_type', 'pt_gen_unit'));
+const list = ref<any[]>();
+const form = ref({ keyword: '', restFlag: '1', instoreType: '', storageType: '2' });
+const paging = ref();
+const tabs = ref([
+    { label: '有库存', value: '1' },
+    { label: '无库存', value: '0' },
+]);
+
+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) => {
+    const { name, index } = event as any;
+    if (index === 0) {
+        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/storageSeed/removeById/${name}`);
+            uni.hideLoading();
+            uni.showToast({
+                title: '删除成功',
+                icon: 'success',
+            });
+            paging.value?.reload();
+        } catch (error) {
+            console.error('删除暂存鲜货信息失败:', error);
+        }
+    }
+};
+
+const onRefresh = () => {
+    paging.value.reload();
+};
+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>

+ 110 - 0
src/plant/storage/fresh-goods/list/model/fresh-goods-bottom.vue

@@ -0,0 +1,110 @@
+<template>
+    <view class="source-bottom p-rtv">
+        <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>
+</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-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>

+ 162 - 0
src/plant/storage/fresh-goods/models/animals-input.vue

@@ -0,0 +1,162 @@
+<template>
+    <view class="flex1">
+        <view>
+            <up-swipe-action>
+                <template v-for="(item, index) in list" :key="index">
+                    <up-swipe-action-item class="mb-20" :options="options" @click="clickPlotSwipe($event, item, index)">
+                        <view class="ul-block-item pd-24">
+                            {{ item.animalId }}
+                        </view>
+                    </up-swipe-action-item>
+                </template>
+            </up-swipe-action>
+        </view>
+        <view class="d-flex">
+            <up-button class="flex1 mr-20" color="#18BECA" plain @click="onScan">
+                <image class="w-36 h-36 mr-10" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/common/scan_icon_o.png" mode="widthFix" />
+                <span>扫一扫添加</span>
+            </up-button>
+            <up-button @click="onAddClick" class="flex1" color="#37A954" plain>
+                <image class="w-36 h-36 mr-10" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/common/edit_icon.png" mode="widthFix" />
+                <span>手动输入添加</span>
+            </up-button>
+        </view>
+    </view>
+    <ut-confirm-dialog title="添加个体标识" v-model:show="showPop" width="680rpx">
+        <view>
+            <up-form ref="upFormRef" :model="form" :rules="rules" labelWidth="auto" class="p-rtv" labelPosition="top">
+                <up-form-item label="个体标识号" border-bottom prop="animalId" required>
+                    <up-input v-model="form.animalId" border="none" :maxlength="200" clearable placeholder="请输入个体标识号"></up-input>
+                </up-form-item>
+            </up-form>
+        </view>
+        <template #footer>
+            <view class="d-flex j-c pd-30">
+                <up-button @click="showPop = false" class="mr-30" style="color: #333" color="#F2F2F2">取消</up-button>
+                <up-button @click="onConfirm" type="primary">确认</up-button>
+            </view>
+        </template>
+    </ut-confirm-dialog>
+</template>
+<script setup lang="ts">
+const props = defineProps({
+    modelValue: {
+        type: Array,
+        default: () => [],
+    },
+});
+const upFormRef = ref();
+const rules = reactive({
+    animalId: [{ required: true, message: '请输入个体标识号', trigger: 'blur' }],
+});
+const showPop = ref(false);
+const form = ref({
+    animalId: '',
+});
+// -1 表示新增,其它为编辑的下标
+const editIndex = ref<number>(-1);
+const emit = defineEmits(['update:modelValue']);
+const list = ref<any[]>(props.modelValue);
+const options = ref([
+    {
+        text: '编辑',
+        name: 'edit',
+        style: {
+            backgroundColor: '#37a954',
+            color: '#fff',
+        },
+    },
+    {
+        text: '删除',
+        name: 'delete',
+        style: {
+            backgroundColor: '#FF3B30',
+            color: '#fff',
+        },
+    },
+]);
+const clickPlotSwipe = (e: any, item: any, index: number) => {
+    console.log(e);
+    
+    if (e.index == 0) {
+        // 编辑个体标识
+        console.log('编辑个体标识', item, index);
+        editIndex.value = index;
+        form.value.animalId = item?.animalId || '';
+        showPop.value = true;
+    } else if (e.index == 1) {
+        // 删除个体标识
+        list.value.splice(index, 1);
+        emit('update:modelValue', [...list.value]);
+        
+    }
+};
+const onConfirm = async () => {
+    try {
+        // uview-plus 的 up-form 暴露 validate 方法
+        await upFormRef.value?.validate();
+        if (editIndex.value > -1) {
+            // 编辑模式:更新当前项
+            list.value[editIndex.value] = { ...list.value[editIndex.value], ...form.value };
+        } else {
+            // 新增模式:追加一项
+            list.value.push({ ...form.value });
+        }
+        emit('update:modelValue', [...list.value]);
+        showPop.value = false;
+        form.value.animalId = '';
+        editIndex.value = -1;
+    } catch (e) {
+        // 校验不通过
+    }
+};
+// 手动新增按钮点击
+const onAddClick = () => {
+    editIndex.value = -1;
+    form.value.animalId = '';
+    showPop.value = true;
+};
+
+// 扫一扫添加
+const onScan = () => {
+    // #ifdef MP-WEIXIN
+    uni.scanCode({
+        onlyFromCamera: true,
+        success: (res) => {
+            const code = (res.result || '').trim();
+            if (!code) return;
+            // 直接追加到列表
+            list.value.push({ animalId: code });
+            emit('update:modelValue', [...list.value]);
+        },
+        fail: () => {},
+    });
+    // #endif
+    // 其他端如 H5/App 可按需再做兼容
+};
+watch(
+    () => props.modelValue,
+    (newVal) => {
+        list.value = newVal;
+    },
+);
+</script>
+<script lang="ts">
+export default {
+    options: {
+        // 微信小程序中 options 选项
+        multipleSlots: true, //  在组件定义时的选项中启动多slot支持,默认启用
+        styleIsolation: 'shared', //  启动样式隔离。当使用页面自定义组件,希望父组件影响子组件样式时可能需要配置。具体配置选项参见:微信小程序自定义组件的样式
+        addGlobalClass: true, //  表示页面样式将影响到自定义组件,但自定义组件中指定的样式不会影响页面。这个选项等价于设置 styleIsolation: apply-shared
+        virtualHost: true, //  将自定义节点设置成虚拟的,更加接近Vue组件的表现。我们不希望自定义组件的这个节点本身可以设置样式、响应 flex 布局等,而是希望自定义组件内部的第一层节点能够响应 flex 布局或者样式由自定义组件本身完全决定
+    },
+};
+</script>
+<style lang="scss" scoped>
+.ul-block-item {
+    border-radius: 16rpx;
+    border: 1px solid #AFDDBB;
+    // 字体数字可换行
+    word-break: break-all;
+}
+</style>

+ 127 - 0
src/plant/storage/fresh-goods/models/type.ts

@@ -0,0 +1,127 @@
+/**
+ * 入库信息类
+ */
+export interface FreshGoodsInstoreEnum {
+    /** 鲜货信息 uid 数组(外层只保存 uid,明细由页面自行维护映射) */
+    goodsInfoList: string[];
+    /** 入库类型 */
+    instoreType: string;
+    /** 入库批号 */
+    batchCode?: string;
+    /** 库房类型 */
+    storageType?: string;
+    /** 库房编码 */
+    storeCode?: string;
+    /** 存放库房 */
+    warehouses?: warehousesType[];
+    /** 入库业务信息 */
+    instoreBizInfo: instoreBizInfoType1;
+    [property: string]: any;
+}
+
+/** 动植物(物种/基原)信息:从选择页回传,字段较多,这里只列页面用到的 */
+export interface VarietyInfo {
+    id?: string;
+    varietyName?: string;
+    latinName?: string;
+    genusName?: string;
+    genusLatinName?: string;
+    medicineName?: string;
+    [property: string]: any;
+}
+
+/** 往来单位信息:组件回传字段不固定,这里保留常用字段并允许扩展 */
+
+
+/**
+ * 单条鲜货入库信息(当前 info-edit 页面表单)
+ * 说明:仍保留旧名 seedInfoListType 的兼容导出,避免影响已有页面。
+ */
+export interface FreshGoodsInstoreItemForm {
+    /** 页面内部 uid(用于在父页面映射 uid -> 明细) */
+    uid?: string;
+
+    /** 动植物名称 */
+    varietyId?: string;
+    varietyInfo?: VarietyInfo | null;
+
+    /** 药用部位/对象 */
+    part?: string;
+    partName?: string;
+
+    /** 鲜货来源(字典:pt_medicine_source) */
+    sourceType?: string;
+
+    /** 入库量 */
+    capacity?: string | number;
+    /** 计量单位(字典:pt_medicine_unit) */
+    unit?: string;
+
+    /** 供应商 */
+    supplierId?: string;
+    supplierInfo?: any | null;
+    /** 供应商是否是生产商(字典:yes_no) */
+    supplierProducerFlag?: string;
+    /** 生产商 */
+    producer?: string;
+
+    /** 检验报告(上传:image/file,valueType=array) */
+    examinReport?: (string | AccesseryDTO)[];
+
+    /** 鲜货产地(行政区划 code) */
+    producePlace?: string;
+    /** 鲜货产地全称 */
+    producePlaceName?: string;
+
+    /** 采收日期(yyyy-MM-dd) */
+    productDate?: string;
+
+    /** 鲜货图片(上传:valueType=string,通常为逗号分隔或单串) */
+    imgs?: string;
+    /** 鲜货视频(上传:valueType=string) */
+    vedios?: string;
+
+    [property: string]: any;
+}
+
+// 兼容旧命名(历史页面仍在使用)
+export type seedInfoListType = FreshGoodsInstoreItemForm;
+
+export interface AccesseryDTO {
+    /**
+     * 文件名称
+     */
+    fileName?: string;
+    /**
+     * 文件大小
+     */
+    fileSize?: number;
+    /**
+     * 文件URL
+     */
+    url?: string;
+    [property: string]: any;
+}
+// 存放库房对象
+export interface warehousesType {
+    /** 仓库id */
+    warehouseId?: string;
+    /** 货架id */
+    shelfId?: string;
+    [property: string]: any;
+}
+/**
+ * 入库业务传输对象
+ */
+export interface instoreBizInfoType {
+    [property: string]: any;
+}
+export interface instoreBizInfoType1 {
+ /** 入库日期 */
+    instoreDate?: string;
+    /** 入库人 */
+    instoreMg?: string;
+    /** 备注 */
+    remark?: string;
+    [property: string]: any;
+}

+ 6 - 7
src/plant/storage/seed-source/add/index.vue

@@ -72,7 +72,7 @@
                 </up-form-item>
                 <!-- 入库类型 -->
                 <up-form-item borderBottom label="入库类型" required prop="instoreType">
-                    <view v-if="form.instoreType" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_seed_instore_type, form.instoreType) }}</view>
+                    <view v-if="form.instoreType" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_seed_instore_type, form?.instoreType) }}</view>
                     <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择入库类型</view>
                 </up-form-item>
                 <!-- 入库日期 -->
@@ -93,8 +93,8 @@
                     </template>
                 </up-form-item>
                 <!-- 库房类型 -->
-                <up-form-item borderBottom label="库房类型" prop="storeType" required>
-                    <view v-if="form.storeType" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_warehouse_type, form.storeType) }}</view>
+                <up-form-item borderBottom label="库房类型" prop="storageType" required>
+                    <view v-if="form.storageType" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_warehouse_type, form?.storageType) }}</view>
                     <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择库房类型</view>
                 </up-form-item>
                 <up-form-item borderBottom label="存放库房" prop="warehouses">
@@ -126,14 +126,14 @@ import { parseTime } from '@/utils/ruoyi';
 import SelectWarehouseInput from '@/models/select-warehouse-input/select-warehouse-input.vue';
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const { pt_seed_instore_type, pt_warehouse_type, pt_seed_type, pt_seed_source, pt_materail_unit, pt_mother_father_flag, pt_op_method, pt_seed_unit, pt_fungus_code_type, pt_breeding_materials, yes_no, pt_cus_type, pt_cpy_type, pt_gen_unit } = toRefs<any>(proxy?.useDict('pt_seed_instore_type', 'pt_warehouse_type', 'pt_seed_type', 'pt_seed_source', 'pt_materail_unit', 'pt_mother_father_flag', 'pt_op_method', 'pt_seed_unit', 'pt_fungus_code_type', 'pt_breeding_materials', 'yes_no', 'pt_cus_type', 'pt_cpy_type', 'pt_gen_unit'));
+const { pt_seed_instore_type, pt_warehouse_type, pt_seed_type, pt_seed_source } = toRefs<any>(proxy?.useDict('pt_seed_instore_type', 'pt_warehouse_type', 'pt_seed_type', 'pt_seed_source'));
 // 表单与分页等基础状态(参考 base-edit 风格)
 const paging = ref<any>(null);
 const upFormRef = ref<any>(null);
 const showArea = ref(false);
 const form = ref<SeedSourceAddTypeEnum>({
     instoreType: '2',
-    storeType: '2',
+    storageType: '2',
     seedInfoList: [],
     warehouses: [],
     instoreBizInfo: {
@@ -179,8 +179,7 @@ const submitForm = async () => {
             });
             try {
                 const res = await useClientRequest.post('/plt-api/app/storageSeed/batchInstore', params);
-                uni.hideLoading();
-                if (!res || res !== 200) return;
+                if (!res || res.code !== 200) return;
                 uni.hideLoading();
                 uni.showToast({
                     title: '提交成功',

+ 1 - 1
src/plant/storage/seed-source/detail/index.vue

@@ -277,7 +277,7 @@ import { useClientRequest } from '@/utils/request';
 import { selectDictListClass } from '@/utils/ruoyi';
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 
-const { pt_seed_instore_type, pt_warehouse_type, pt_seed_type, pt_seed_source, pt_materail_unit, pt_mother_father_flag, pt_op_method, pt_seed_unit, pt_fungus_code_type, pt_breeding_materials, yes_no, pt_cus_type, pt_cpy_type, pt_gen_unit } = toRefs<any>(proxy?.useDict('pt_seed_instore_type', 'pt_warehouse_type', 'pt_seed_type', 'pt_seed_source', 'pt_materail_unit', 'pt_mother_father_flag', 'pt_op_method', 'pt_seed_unit', 'pt_fungus_code_type', 'pt_breeding_materials', 'yes_no', 'pt_cus_type', 'pt_cpy_type', 'pt_gen_unit'));
+const { pt_seed_instore_type,  pt_seed_type, pt_seed_source,pt_mother_father_flag, pt_fungus_code_type, pt_breeding_materials, yes_no, pt_gen_unit } = toRefs<any>(proxy?.useDict('pt_seed_instore_type', 'pt_seed_type', 'pt_seed_source', 'pt_mother_father_flag', 'pt_fungus_code_type', 'pt_breeding_materials', 'yes_no', 'pt_gen_unit'));
 const paging = ref<any>(null);
 const form = ref<any>({});
 const did = ref('');

+ 3 - 5
src/plant/storage/seed-source/info-edit/index.vue

@@ -49,7 +49,7 @@
                     <up-input v-model="form.seedName" placeholder="请输入具体品种/品系名称" border="none" clearable></up-input>
                 </up-form-item>
                 <view class="h-1" id="seedSourcepppp"></view>
-                <ut-action-sheet :tabs="pt_seed_source" mode="custom" title="种源来源" v-model="form.seedSource">
+                <ut-action-sheet :tabs="pt_seed_source_tag" mode="custom" title="种源来源" v-model="form.seedSource">
                     <up-form-item borderBottom label="种源来源" required prop="seedSource">
                         <view v-if="form.seedSource" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_seed_source, form.seedSource) }}</view>
                         <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择种源来源</view>
@@ -202,7 +202,7 @@
                 <!-- 入库数量与单位 -->
                 <view class="h-1" id="capacitypppp"></view>
                 <view class="h-1" id="unitpppp"></view>
-                <up-form-item label="入库量" prop="capacity" required class="form-item-bottom-padding-0">
+                <up-form-item label="入库量" required class="form-item-bottom-padding-0">
                     <div class="flex1 d-flex">
                         <div class="flex1 ov-hd">
                             <up-form-item prop="capacity" border-bottom class="form-item-top-padding-0">
@@ -349,11 +349,9 @@ import { seedInfoListType } from '../models/type';
 import AnimalsInput from '../models/animals-input.vue';
 import ContactUnitInput from '@/models/contact-unit-input/contact-unit-input.vue';
 import PickerAreaInput from '@/models/picker-area-input/picker-area-input.vue';
-
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const { pt_seed_type, pt_seed_source, pt_materail_unit, pt_mother_father_flag, pt_seed_unit, pt_fungus_code_type, pt_breeding_materials, yes_no, pt_cus_type, pt_cpy_type, pt_gen_unit } = toRefs<any>(proxy?.useDict('pt_seed_type', 'pt_seed_source', 'pt_materail_unit', 'pt_mother_father_flag', 'pt_op_method', 'pt_seed_unit', 'pt_fungus_code_type', 'pt_breeding_materials', 'yes_no', 'pt_cus_type', 'pt_cpy_type', 'pt_gen_unit'));
+const { pt_seed_type, pt_seed_source,  pt_mother_father_flag, pt_seed_unit, pt_fungus_code_type, pt_breeding_materials, yes_no, pt_gen_unit, pt_seed_source_tag } = toRefs<any>(proxy?.useDict('pt_seed_type', 'pt_seed_source', 'pt_mother_father_flag', 'pt_seed_unit', 'pt_fungus_code_type', 'pt_breeding_materials', 'yes_no', 'pt_gen_unit', 'pt_seed_source_tag'));
 const paging = ref<any>(null);
-const selectContactUnitShow = ref(false);
 const upFormRef = ref<any>(null);
 const form = ref<seedInfoListType>({
     imgs: undefined,

+ 5 - 30
src/plant/storage/seed-source/info-update/index.vue

@@ -53,7 +53,7 @@
                     <up-input v-model="form.seedName" placeholder="请输入具体品种/品系名称" border="none" clearable></up-input>
                 </up-form-item>
                 <view class="h-1" id="seedSourcepppp"></view>
-                <ut-action-sheet :tabs="pt_seed_source" mode="custom" title="种源来源" v-model="form.seedSource">
+                <ut-action-sheet :tabs="pt_seed_source_tag" mode="custom" title="种源来源" v-model="form.seedSource">
                     <up-form-item borderBottom label="种源来源" required prop="seedSource">
                         <view v-if="form.seedSource" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_seed_source, form.seedSource) }}</view>
                         <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择种源来源</view>
@@ -207,27 +207,7 @@
                 <view class="h-1" id="capacitypppp"></view>
                 <view class="h-1" id="unitpppp"></view>
                 <up-form-item label="入库量" prop="capacity" required class="form-item-bottom-padding-0">
-                    <div class="flex1 d-flex">
-                        <div class="flex1 ov-hd">
-                            <up-form-item prop="capacity" border-bottom class="form-item-top-padding-0">
-                                <up-input v-model="form.capacity" placeholder="请输入入库量" border="none" clearable></up-input>
-                            </up-form-item>
-                        </div>
-                        <div class="pd-5"></div>
-                        <div class="min-w-200">
-                            <ut-action-sheet v-model="form.unit" :tabs="pt_seed_unit" mode="custom" 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.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>
-                                        <up-icon size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
-                                    </template>
-                                </up-form-item>
-                            </ut-action-sheet>
-                        </div>
-                    </div>
+                    <view class="f-s-30 c-333 f-w-5 flex1">{{ form?.capacity }}{{ form?.unit }}</view>
                 </up-form-item>
                 <!-- 检验报告与供应商信息 -->
                 <up-form-item borderBottom label="检验报告" prop="examinReport">
@@ -365,10 +345,7 @@
                 </ut-datetime-picker>
                 <!-- 入库批号 -->
                 <up-form-item borderBottom label="入库批号" required prop="batchCode">
-                    <up-input v-model="form.batchCode" placeholder="请输入入库批号" border="none" clearable></up-input>
-                    <template #right>
-                        <up-button @click="generateBatchCode" type="primary" :customStyle="formItemBtnStyle">随机生成</up-button>
-                    </template>
+                    <view class="f-s-30 c-333 f-w-5 flex1">{{ form.batchCode }}</view>
                 </up-form-item>
                 <!-- 库房类型 -->
                 <up-form-item borderBottom label="库房类型" prop="storeType" required>
@@ -405,9 +382,7 @@ import ContactUnitInput from '@/models/contact-unit-input/contact-unit-input.vue
 import PickerAreaInput from '@/models/picker-area-input/picker-area-input.vue';
 import SelectWarehouseInput from '@/models/select-warehouse-input/select-warehouse-input.vue';
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const { pt_seed_instore_type, pt_warehouse_type, pt_seed_type, pt_seed_source, pt_materail_unit, pt_mother_father_flag, pt_op_method, pt_seed_unit, pt_fungus_code_type, pt_breeding_materials, yes_no, pt_cus_type, pt_cpy_type, pt_gen_unit } = toRefs<any>(
-    proxy?.useDict('pt_seed_instore_type', 'pt_warehouse_type', 'pt_seed_type', 'pt_seed_source', 'pt_materail_unit', 'pt_mother_father_flag', 'pt_op_method', 'pt_seed_unit', 'pt_fungus_code_type', 'pt_breeding_materials', 'yes_no', 'pt_cus_type', 'pt_cpy_type', 'pt_gen_unit'),
-);
+const { pt_seed_instore_type, pt_warehouse_type, pt_seed_type, pt_seed_source, pt_materail_unit, pt_mother_father_flag, pt_op_method, pt_seed_unit, pt_fungus_code_type, pt_breeding_materials, yes_no, pt_cus_type, pt_cpy_type, pt_gen_unit, pt_seed_source_tag } = toRefs<any>(proxy?.useDict('pt_seed_instore_type', 'pt_warehouse_type', 'pt_seed_type', 'pt_seed_source', 'pt_materail_unit', 'pt_mother_father_flag', 'pt_op_method', 'pt_seed_unit', 'pt_fungus_code_type', 'pt_breeding_materials', 'yes_no', 'pt_cus_type', 'pt_cpy_type', 'pt_gen_unit', 'pt_seed_source_tag'));
 const paging = ref<any>(null);
 const upFormRef = ref<any>(null);
 // 单条种源信息 + 入库信息的合并表单
@@ -499,8 +474,8 @@ const submitForm = async () => {
             try {
                 // 这里使用单条入库接口,后端若仍要求 batch,可根据需要包装成数组
                 const res = await useClientRequest.post('/plt-api/app/storageSeed/edit', form.value);
+                if (!res || res.code !== 200) return;
                 uni.hideLoading();
-                if (!res || res !== 200) return;
                 uni.showToast({
                     title: '提交成功',
                     icon: 'success',

+ 1 - 1
src/plant/storage/seed-source/list/index.vue

@@ -96,7 +96,7 @@ import SourceBottom from './model/source-bottom.vue';
 import { selectDictListClass } from '@/utils/ruoyi';
 import { getStorageRoomNames } from '@/utils/common';
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const { pt_seed_instore_type, pt_warehouse_type, pt_seed_type, pt_seed_source, pt_materail_unit, pt_mother_father_flag, pt_op_method, pt_seed_unit, pt_fungus_code_type, pt_breeding_materials, yes_no, pt_cus_type, pt_cpy_type, pt_gen_unit } = toRefs<any>(proxy?.useDict('pt_seed_instore_type', 'pt_warehouse_type', 'pt_seed_type', 'pt_seed_source', 'pt_materail_unit', 'pt_mother_father_flag', 'pt_op_method', 'pt_seed_unit', 'pt_fungus_code_type', 'pt_breeding_materials', 'yes_no', 'pt_cus_type', 'pt_cpy_type', 'pt_gen_unit'));
+const { pt_seed_instore_type, pt_seed_type, pt_fungus_code_type, } = toRefs<any>(proxy?.useDict('pt_seed_instore_type', 'pt_seed_type', 'pt_fungus_code_type'));
 const list = ref<any[]>();
 const form = ref({ keyword: '', restFlag: '1', instoreType: '' });
 const paging = ref();

+ 1 - 1
src/plant/storage/seed-source/models/type.ts

@@ -11,7 +11,7 @@ export interface SeedSourceAddTypeEnum {
     /** 入库批号 */
     batchCode?: string;
     /** 库房类型 */
-    storeType?: string;
+    storageType?: string;
     /** 库房类型 */
     storeCode?: string;
     /** 存放库房 */