huangxw 1 ヶ月 前
コミット
cf14ca45b9

+ 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>

+ 5 - 5
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: {
@@ -153,7 +153,7 @@ const rules = reactive({
     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: '请输入入库人' }],
 });
 

+ 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;
     /** 存放库房 */

+ 22 - 37
src/plant/storage/fresh-goods/add/index.vue

@@ -9,41 +9,28 @@
                 <view class="startline-title">鲜货信息</view>
             </view>
             <view class="pd-24 bg-#fff">
-                <!-- TODO: 后续按 seedInfoList 设计鲜货信息明细,此处先留空结构避免表单错误 -->
-                <up-form-item borderBottom label="添加鲜货信息" required prop="seedInfoList">
+                <!-- TODO: 后续按 goodsInfoList 设计鲜货信息明细,此处先留空结构避免表单错误 -->
+                <up-form-item borderBottom label="添加鲜货信息" required prop="goodsInfoList">
                     <view class="flex1">
-                        <template v-for="(item, index) in form.seedInfoList" :key="index">
+                        <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="flex1">
-                                        <span class="f-s-34 c-#333 f-w-500 mr-10">{{ uidMapData[item]?.varietyInfo?.varietyName }}</span>
-                                        <span class="f-s-24 c-#666">{{ selectDictLabel(pt_seed_type, uidMapData[item]?.seedType) }}</span>
-                                    </view>
+                                    <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="flex1 f-s-28 pr-10 pd2-4-0">
-                                        <span class="c-#666">来源:</span>
-                                        <span class="c-#333 f-w-500">{{ selectDictLabel(pt_seed_source, uidMapData[item]?.seedSource) }}</span>
-                                    </view>
-                                    <view class="flex1 f-s-28 pd2-4-0">
-                                        <span class="c-#666">入库量:</span>
-                                        <span class="c-#333 f-w-500">{{ uidMapData[item]?.capacity }}{{ uidMapData[item]?.unit }}</span>
+                                    <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 ov-hd">
-                                        <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 class="f-s-28 pr-10 pd2-4-0">
-                                            <span class="c-#666">受托单位:</span>
-                                            <span class="c-#333 f-w-500">{{ uidMapData[item]?.entrustInfo?.cusName }}</span>
-                                        </view>
+                                    <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>
@@ -89,8 +76,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">
@@ -115,22 +102,22 @@
 </template>
 <script setup lang="ts">
 import { useClientRequest } from '@/utils/request';
-import { SeedSourceAddTypeEnum } from '../models/type';
+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, 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>({
+const form = ref<FreshGoodsInstoreEnum>({
     instoreType: '2',
-    storeType: '4',
-    seedInfoList: [],
+    storageType: '4',
+    goodsInfoList: [],
     warehouses: [],
     instoreBizInfo: {
         instoreDate: parseTime(new Date(), '{y}-{m}-{d}'),
@@ -139,7 +126,7 @@ const form = ref<SeedSourceAddTypeEnum>({
     },
 });
 const rules = reactive({
-    seedInfoList: [{ required: true, message: '请添加鲜货信息', type: 'array', min: 1 }],
+    goodsInfoList: [{ required: true, message: '请添加鲜货信息', type: 'array', min: 1 }],
     instoreType: [{ required: true, message: '请选择入库类型' }],
     'instoreBizInfo.instoreDate': [{ required: true, message: '请选择入库日期' }],
     batchCode: [{ required: true, message: '请输入入库批号' }],
@@ -147,8 +134,6 @@ const rules = reactive({
 });
 
 const submitForm = async () => {
-    console.log(form.value);
-
     uni.$u.debounce(
         async () => {
             try {
@@ -163,7 +148,7 @@ const submitForm = async () => {
             uni.showLoading({
                 title: '提交中...',
             });
-            const params = form.value.seedInfoList.map((uid) => {
+            const params = form.value.goodsInfoList.map((uid) => {
                 return {
                     ...uidMapData.value[uid],
                     ...form.value,
@@ -174,7 +159,7 @@ const submitForm = async () => {
                 };
             });
             try {
-                const res = await useClientRequest.post('/plt-api/app/storageSeed/batchInstore', params);
+                const res = await useClientRequest.post('/plt-api/app/storage/batchInstore', params);
                 if (!res || res.code !== 200) return;
                 uni.hideLoading();
                 uni.showToast({
@@ -221,7 +206,7 @@ const navigateToAddSeedSource = (uid = '', mode = 'add') => {
     uni.$on('submitForm', (data: any) => {
         uidMapData.value[data.uid] = data.form;
         if (data?.mode == 'add') {
-            form.value.seedInfoList.push(data.uid);
+            form.value.goodsInfoList.push(data.uid);
         }
         uni.$off('submitForm');
     });
@@ -237,7 +222,7 @@ const navigateToAddSeedSource = (uid = '', mode = 'add') => {
     });
 };
 const deleteRow = (index: number, uid: string) => {
-    form.value.seedInfoList.splice(index, 1);
+    form.value.goodsInfoList.splice(index, 1);
     delete uidMapData.value[uid];
 };
 // 编辑时加载详情

+ 11 - 15
src/plant/storage/fresh-goods/detail/index.vue

@@ -1,7 +1,7 @@
 <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>
+            <ut-navbar title="鲜货详情" :fixed="false" border></ut-navbar>
         </template>
 
         <template>
@@ -60,12 +60,12 @@
                 </view>
             </view>
             <view class="pd-24">
-                <view class="startline-title">种源信息</view>
+                <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-#666">鲜货类型:</span>
                     <span class="c-#333 f-w-600">{{ selectDictLabel(pt_seed_type, form?.seedType) || '-' }}</span>
                 </view>
                 <view class="f-s-30 pd2-16-0 info-border-bottom">
@@ -86,7 +86,7 @@
                     <span class="c-#333 f-w-600">{{ form?.seedName || '-' }}</span>
                 </view>
                 <view class="f-s-30 pd2-16-0 info-border-bottom">
-                    <span class="c-#666">种源来源:</span>
+                    <span class="c-#666">鲜货来源:</span>
                     <span class="c-#333 f-w-600">{{ selectDictLabel(pt_seed_source, form?.seedSource) || '-' }}</span>
                 </view>
                 <view class="f-s-30 pd2-16-0 info-border-bottom" v-if="form?.instoreBizInfo?.motherFatherFlag">
@@ -184,15 +184,15 @@
                     <span class="c-#333 f-w-600">{{ form?.instoreBizInfo?.storageMethod || '-' }}</span>
                 </view>
                 <view v-if="form?.imgs" class="f-s-30 pd2-16-0 info-border-bottom">
-                    <view class="c-#666 mb-10">种源图片:</view>
+                    <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>
+                    <view class="c-#666 mb-10">鲜货视频:</view>
                     <ut-album :urls="form?.vedios"></ut-album>
                 </view>
                 <view class="f-s-30 pd2-16-0 info-border-bottom">
-                    <span class="c-#666">种源产地:</span>
+                    <span class="c-#666">鲜货产地:</span>
                     <span class="c-#333 f-w-600">{{ form?.adcodeName || '-' }}</span>
                 </view>
                 <view class="f-s-30 pd2-16-0 info-border-bottom">
@@ -208,11 +208,11 @@
                     <ut-album :urls="form?.spCert"></ut-album>
                 </view>
                 <view class="f-s-30 pd2-16-0 info-border-bottom">
-                    <span class="c-#666">种源检疫证号:</span>
+                    <span class="c-#666">鲜货检疫证号:</span>
                     <span class="c-#333 f-w-600">{{ form?.seedCheckSn || '-' }}</span>
                 </view>
                 <view v-if="form?.seedCheckCert && form?.seedCheckCert.length" class="f-s-30 pd2-16-0 info-border-bottom">
-                    <view class="c-#666 mb-10">种源检疫证书:</view>
+                    <view class="c-#666 mb-10">鲜货检疫证书:</view>
                     <ut-album :urls="form?.seedCheckCert"></ut-album>
                 </view>
             </view>
@@ -220,10 +220,6 @@
                 <view class="startline-title">入库信息</view>
             </view>
             <view class="bg-#fff pd-24">
-                <view class="f-s-30 pd2-16-0 info-border-bottom">
-                    <span class="c-#666">种源级别:</span>
-                    <span class="c-#333 f-w-600">{{ form?.seedLevel || '-' }}</span>
-                </view>
                 <view class="f-s-30 pd2-16-0 info-border-bottom">
                     <span class="c-#666">入库类型:</span>
                     <span class="c-#333 f-w-600">{{ selectDictLabel(pt_seed_instore_type, form?.instoreType) || '-' }}</span>
@@ -238,7 +234,7 @@
                 </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>
+                    <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>

+ 67 - 13
src/plant/storage/fresh-goods/info-edit/index.vue

@@ -34,9 +34,13 @@
                         </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="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">
@@ -74,7 +78,7 @@
                     </div>
                 </up-form-item>
 
-                <template v-if="['2', '3'].includes(form.seedSource as string)">
+                <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>
@@ -94,7 +98,8 @@
                     <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="选择鲜货产地" >
+                <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>
@@ -103,10 +108,10 @@
                         </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>
+                        <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>
@@ -129,20 +134,68 @@
     </z-paging>
 </template>
 <script setup lang="ts">
-import { useClientRequest } from '@/utils/request';
-import { seedInfoListType } from '../models/type';
+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, } = toRefs<any>(proxy?.useDict('pt_medicine_source', 'pt_medicine_unit'));
+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 form = ref<seedInfoListType>({
 
+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 (['3'].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 () => {
@@ -199,8 +252,9 @@ onLoad((options: any) => {
             mode: data?.mode || 'add',
         };
         form.value = {
-            ...form.value,
+            ...createDefaultForm(),
             ...data?.form,
+            uid: data?.uid || data?.form?.uid || '',
         };
     });
 });

+ 66 - 64
src/plant/storage/fresh-goods/models/type.ts

@@ -1,77 +1,92 @@
 /**
  * 入库信息类
  */
-export interface SeedSourceAddTypeEnum {
-    // 种信息数组
-    seedInfoList: string[];
-    /** 种源级别 */
-    seedLevel?: string;
+export interface FreshGoodsInstoreEnum {
+    /** 鲜货信息 uid 数组(外层只保存 uid,明细由页面自行维护映射) */
+    goodsInfoList: string[];
     /** 入库类型 */
     instoreType: string;
     /** 入库批号 */
     batchCode?: string;
     /** 库房类型 */
-    storeType?: string;
-    /** 库房类型 */
+    storageType?: string;
+    /** 库房编码 */
     storeCode?: string;
     /** 存放库房 */
     warehouses?: warehousesType[];
-    /**
-     * 入库业务传输对象
-     */
+    /** 入库业务信息 */
     instoreBizInfo: instoreBizInfoType1;
-     [property: string]: any;
+    [property: string]: any;
+}
+
+/** 动植物(物种/基原)信息:从选择页回传,字段较多,这里只列页面用到的 */
+export interface VarietyInfo {
+    id?: string;
+    varietyName?: string;
+    latinName?: string;
+    genusName?: string;
+    genusLatinName?: string;
+    medicineName?: string;
+    [property: string]: any;
 }
-// 种源信息返回体
-export interface seedInfoListType {
-    /** 种源类型 */
-    seedType?: string;
-    /** 物种基原 */
+
+/** 往来单位信息:组件回传字段不固定,这里保留常用字段并允许扩展 */
+
+
+/**
+ * 单条鲜货入库信息(当前 info-edit 页面表单)
+ * 说明:仍保留旧名 seedInfoListType 的兼容导出,避免影响已有页面。
+ */
+export interface FreshGoodsInstoreItemForm {
+    /** 页面内部 uid(用于在父页面映射 uid -> 明细) */
+    uid?: string;
+
+    /** 动植物名称 */
     varietyId?: string;
-    /** 具体品种/品系名称 */
-    seedName?: string;
-    /** 种源来源 */
-    seedSource?: string;
-    /** 受托单位 */
-    entrustId?: string;
+    varietyInfo?: VarietyInfo | null;
+
+    /** 药用部位/对象 */
+    part?: string;
+    partName?: string;
+
+    /** 鲜货来源(字典:pt_medicine_source) */
+    sourceType?: string;
+
     /** 入库量 */
-    capacity?: number;
-    /** 计量单位 */
+    capacity?: string | number;
+    /** 计量单位(字典:pt_medicine_unit) */
     unit?: string;
-    /** 检验报告 */
-    examinReport?: AccesseryDTO;
+
     /** 供应商 */
     supplierId?: string;
-    /** 供应商名称 */
-    supplier?: string;
-    /** 生产商名称 */
+    supplierInfo?: any | null;
+    /** 供应商是否是生产商(字典:yes_no) */
+    supplierProducerFlag?: string;
+    /** 生产商 */
     producer?: string;
-    /** 菌种/菌株编号 */
-    fungusCode?: string;
-    /** 菌种编码类型 */
-    fungusCodeType?: string;
-    /** 是否有个体标识 */
-    animalIds?: 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;
-    /** 种源产地 */
-    adcode?: string;
-    /** 繁殖材料 */
-    generationMaterial?: string;
-    /** 繁殖地点/采集地点 */
-    generationAdcode?: string;
-    /** 物种鉴定证书 */
-    spCert?: AccesseryDTO[];
-    /** 种源检疫证号 */
-    seedCheckSn?: string;
-     /** 种源检疫证书 */
-    seedCheckCert?: AccesseryDTO[];
-    uid?: string;
+
     [property: string]: any;
-    instoreBizInfo: instoreBizInfoType;
 }
+
+// 兼容旧命名(历史页面仍在使用)
+export type seedInfoListType = FreshGoodsInstoreItemForm;
+
 export interface AccesseryDTO {
     /**
      * 文件名称
@@ -99,19 +114,6 @@ export interface warehousesType {
  * 入库业务传输对象
  */
 export interface instoreBizInfoType {
-   
-    /** 父母本情况 */
-    motherFatherFlag: string;
-    /** 父本品种ID */
-    fatherVarietyId?: string;
-        /** 母本品种ID */
-    motherVarietyId?: string;
-    fatherVarietyInfo?: any;
-    motherVarietyInfo?: any;
-    idFlag: string;
-    animals?: any[];
-    storageMethod?: string;
-    genUnit?: string;
     [property: string]: any;
 }
 export interface instoreBizInfoType1 {

+ 5 - 5
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 } = toRefs<any>(proxy?.useDict('pt_seed_instore_type, pt_warehouse_type, pt_seed_type, pt_seed_source'));
+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: {

+ 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;
     /** 存放库房 */