huangxw 1 mese fa
parent
commit
79e559b742

+ 16 - 1
src/components/ut-action-sheet/ut-action-sheet.vue

@@ -66,6 +66,10 @@ const props = defineProps({
         type: Boolean,
         default: false, // 只有自定义弹窗模式下生效
     },
+    valueType: {
+        type: String,
+        default: 'string', // 数组 array 或 字符串 string,只有多选时生效
+    },
 });
 const options = computed(() => {
     return props.tabs.map((item: any) => {
@@ -141,7 +145,7 @@ const clickCol = (item: any) => {
 const onConfirm = () => {
     const values = getSelectedValues();
     let out: any;
-    if (Array.isArray(props.modelValue)) {
+    if (Array.isArray(props.modelValue) || props.valueType === 'array') {
         out = values;
     } else {
         // 字符串场景下,用逗号拼接
@@ -194,6 +198,17 @@ watch(
     { immediate: true },
 );
 </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>
 .ut-custom-item-sheet {
     padding: 18rpx 6rpx;

+ 172 - 28
src/components/ut-upload/ut-upload.vue

@@ -3,13 +3,13 @@
         <view class="ut-upload-card">
             <template v-for="(item, index) in fileList" :key="index">
                 <view :style="{ width, height }" class="card-item">
-                    <template v-if="accept === 'image'">
+                    <template v-if="getItemKind(item) === 'image'">
                         <image :src="item.status === 'uploading' && item.tempUrl ? item.tempUrl : item.url" :mode="mode" style="width: 100%; height: 100%" @click="onPreview(index)"></image>
                     </template>
-                    <template v-else-if="accept === 'video'">
+                    <template v-else-if="getItemKind(item) === 'video'">
                         <video :src="item.status === 'uploading' && item.tempUrl ? item.tempUrl : item.url" controls style="width: 100%; height: 100%" @click="onPreview(index)"></video>
                     </template>
-                    <template v-if="accept === 'file'">
+                    <template v-else>
                         <view class="d-flex flex-cln file-box" @click="onPreview(index)">
                             <view class="flex1">
                                 <view class="f-s-28 c-primary up-line-2">{{ item.fileName || '文件' }}</view>
@@ -28,12 +28,37 @@
                     </view>
                 </view>
             </template>
-            <view v-if="(fileList.length < maxCount)" :style="{ width, height }" @click="clickBtnUpload" class="card-item btn-select d-flex flex-cln j-c a-c">
-                <view class="mb-10">
-                    <up-icon :color="iconColor" :name="iconName" :iconSize="iconSize"></up-icon>
+            <template v-if="fileList.length < maxCount">
+                <!-- 兼容旧用法:只有一种类型时,仍然只展示一个按钮,文案/样式按类型和配置对象决定 -->
+                <view
+                    v-if="getAcceptKinds().length === 1"
+                    :style="[{ width, height }, getUploadBtnStyle(getAcceptKinds()[0])]"
+                    @click="clickBtnUpload"
+                    class="card-item btn-select d-flex flex-cln j-c a-c"
+                    :class="getUploadBtnClass(getAcceptKinds()[0])"
+                >
+                    <view class="mb-10">
+                        <up-icon :color="getUploadIconColor(getAcceptKinds()[0])" :name="getUploadIconName(getAcceptKinds()[0])" :iconSize="getUploadIconSize(getAcceptKinds()[0])"></up-icon>
+                    </view>
+                    <view class="f-s-24 c-primary" :style="getUploadBtnTextStyle(getAcceptKinds()[0])">{{ getUploadTextByKind(getAcceptKinds()[0]) }}</view>
                 </view>
-                <view class="f-s-24 c-primary">{{ uploadText }}</view>
-            </view>
+                <!-- 多种类型时,根据 accept 展示多个按钮,每个按钮对应一种上传类型 -->
+                <template v-else>
+                    <view
+                        v-for="kind in getAcceptKinds()"
+                        :key="kind"
+                        :style="[{ width, height }, getUploadBtnStyle(kind)]"
+                        @click="onClickUpload(kind)"
+                        class="card-item btn-select d-flex flex-cln j-c a-c"
+                        :class="getUploadBtnClass(kind)"
+                    >
+                        <view class="mb-10">
+                            <up-icon :color="getUploadIconColor(kind)" :name="getUploadIconName(kind)" :iconSize="getUploadIconSize(kind)"></up-icon>
+                        </view>
+                        <view class="f-s-24 c-primary" :style="getUploadBtnTextStyle(kind)">{{ getUploadTextByKind(kind) }}</view>
+                    </view>
+                </template>
+            </template>
         </view>
     </template>
 </template>
@@ -43,6 +68,18 @@ import upload from '@/utils/upload';
 import { fileExt, isUrl } from '@/utils/ruoyi';
 import { getFileIconByUrl } from '@/utils/common';
 
+type AcceptKind = 'image' | 'video' | 'file';
+
+interface UploadButtonConfigItem {
+    text?: string; // 按钮文字
+    bgColor?: string; // 按钮背景色
+    textColor?: string; // 文字颜色
+    iconName?: string; // 覆盖默认图标名
+    iconColor?: string; // 覆盖默认图标颜色
+    iconSize?: string | number; // 覆盖默认图标大小
+    customClass?: string; // 自定义 class
+}
+
 interface FileItem {
     url: string;
     fileName?: string;
@@ -52,6 +89,7 @@ interface FileItem {
     tempUrl?: string;
     status?: 'uploading' | 'done' | 'error';
     progress?: number;
+    kind?: AcceptKind;
 }
 
 interface UploadEvent {
@@ -69,8 +107,12 @@ interface Props {
     height: string;
     multiple: boolean;
     uploadText: string;
+    uploadImageText?: string;
+    uploadVideoText?: string;
+    uploadFileText?: string;
+    uploadButtonConfig?: Partial<Record<AcceptKind, UploadButtonConfigItem>>; // 统一配置 image/file/video 按钮
     uploadIcon: string;
-    accept: string; // image/video/file
+    accept: string; // image/video/file image,file,video
     uploadUrl?: string;
     uploadTimeout?: number;
     extension?: string | string[]; // 限制选择的文件扩展名(仅在 accept==='file' 生效)
@@ -89,8 +131,11 @@ const props = withDefaults(defineProps<Props>(), {
     height: '210rpx',
     multiple: true,
     uploadText: '点击上传',
+    uploadImageText: '上传图片',
+    uploadVideoText: '上传视频',
+    uploadFileText: '上传文件',
     uploadIcon: 'plus',
-    accept: 'image',
+    accept: 'image', // image/video/file   image,file,video
     uploadUrl: '/resource/oss/upload',
     uploadTimeout: 600000,
     extension: () => ['pdf'],
@@ -100,6 +145,7 @@ const props = withDefaults(defineProps<Props>(), {
     iconColor: '#37a954',
     iconSize: '30rpx',
     mode: 'aspectFill',
+    uploadButtonConfig: () => ({}),
 });
 
 const emit = defineEmits<{
@@ -108,14 +154,43 @@ const emit = defineEmits<{
 }>();
 
 const fileList = ref<FileItem[]>([]);
-const buildFileName = (path: string, kind: 'image' | 'video' | 'file') => {
+const buildFileName = (path: string, kind: AcceptKind) => {
     const ext = fileExt(path) || 'dat';
     const prefix = kind === 'image' ? 'img' : kind === 'video' ? 'video' : 'file';
     return `${prefix}_${Date.now()}.${ext}`;
 };
-const clickBtnUpload = async () => {
-    // 判断是图片/视频/文件不同的上传
-    // 使用chooseMedia选择图片或视频 chooseMessageFile选择文件
+const getAcceptKinds = (): AcceptKind[] => {
+    if (!props.accept) return ['image'];
+    const parts = String(props.accept)
+        .split(',')
+        .map((s) => s.trim())
+        .filter(Boolean) as AcceptKind[];
+    const all: AcceptKind[] = ['image', 'video', 'file'];
+    const result = parts.filter((p) => all.includes(p));
+    return result.length ? result : ['image'];
+};
+
+const getBtnConfig = (kind: AcceptKind): UploadButtonConfigItem => {
+    return (props.uploadButtonConfig && props.uploadButtonConfig[kind]) || {};
+};
+
+const detectKindByUrl = (path?: string | null): AcceptKind => {
+    if (!path) return 'file';
+    const ext = (fileExt(path) || '').toLowerCase();
+    const imageExts = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'];
+    const videoExts = ['mp4', 'mov', 'avi', 'wmv', 'flv', 'mkv', 'webm', '3gp'];
+    if (imageExts.includes(ext)) return 'image';
+    if (videoExts.includes(ext)) return 'video';
+    return 'file';
+};
+
+const getItemKind = (item: FileItem): AcceptKind => {
+    if (item.kind) return item.kind;
+    const path = item.tempUrl || item.url;
+    return detectKindByUrl(path);
+};
+
+const doUploadByKind = async (kind: AcceptKind) => {
     try {
         const remain = props.maxCount - fileList.value.length;
         if (remain <= 0) {
@@ -123,7 +198,7 @@ const clickBtnUpload = async () => {
             return;
         }
 
-        if (props.accept === 'file') {
+        if (kind === 'file') {
             const res: any = await uni.chooseMessageFile({
                 count: props.multiple ? remain : 1,
                 type: 'file',
@@ -132,7 +207,7 @@ const clickBtnUpload = async () => {
             const files = (res?.tempFiles || []) as Array<{ name?: string; size: number; path: string }>;
             for (const f of files) {
                 const name = f.name || buildFileName(f.path, 'file');
-                const placeholder: FileItem = { url: '', fileName: name, fileSize: f.size, tempUrl: f.path, status: 'uploading' };
+                const placeholder: FileItem = { url: '', fileName: name, fileSize: f.size, tempUrl: f.path, status: 'uploading', kind: 'file' };
                 const idx = fileList.value.push(placeholder) - 1;
                 try {
                     const upRes = await upload({ url: props.uploadUrl!, filePath: f.path, name: 'file', timeout: props.uploadTimeout });
@@ -156,13 +231,21 @@ const clickBtnUpload = async () => {
         } else {
             const res: any = await uni.chooseMedia({
                 count: props.multiple ? remain : 1,
-                mediaType: props.accept === 'image' ? ['image'] : ['video'],
+                mediaType: kind === 'image' ? ['image'] : ['video'],
                 sourceType: ['album', 'camera'],
             });
             const files = (res?.tempFiles || []) as Array<{ tempFilePath: string; size: number; thumbTempFilePath?: string }>;
             for (const f of files) {
-                const name = buildFileName(f.tempFilePath, props.accept === 'image' ? 'image' : 'video');
-                const placeholder: FileItem = { url: '', fileName: name, fileSize: f.size, tempUrl: f.tempFilePath, status: 'uploading' };
+                const name = buildFileName(f.tempFilePath, kind);
+                const placeholder: FileItem = {
+                    url: '',
+                    fileName: name,
+                    fileSize: f.size,
+                    tempUrl: f.tempFilePath,
+                    coverUrl: f.thumbTempFilePath,
+                    status: 'uploading',
+                    kind
+                };
                 const idx = fileList.value.push(placeholder) - 1;
                 try {
                     const upRes = await upload({ url: props.uploadUrl!, filePath: f.tempFilePath, name: 'file', timeout: props.uploadTimeout });
@@ -184,20 +267,76 @@ const clickBtnUpload = async () => {
                 }
             }
         }
-
-        // 最后再统一触发一次
         emitCurrentValue();
     } catch (e) {
         console.log('upload error:', e);
     }
 };
 
+// 兼容旧用法:当模板中只用一个上传按钮时,默认使用 accept 中的第一种类型
+const clickBtnUpload = async () => {
+    const kinds = getAcceptKinds();
+    await doUploadByKind(kinds[0]);
+};
+
+const onClickUpload = async (kind: AcceptKind) => {
+    await doUploadByKind(kind);
+};
+
+const getUploadTextByKind = (kind: AcceptKind) => {
+    const cfg = getBtnConfig(kind);
+    if (cfg.text) return cfg.text;
+    // 兼容旧用法:如果外部显式传入了 uploadText(且不是默认值),统一用这个文案
+    if (props.uploadText && props.uploadText !== '点击上传') {
+        return props.uploadText;
+    }
+    if (kind === 'image') return props.uploadImageText || '上传图片';
+    if (kind === 'video') return props.uploadVideoText || '上传视频';
+    if (kind === 'file') return props.uploadFileText || '上传文件';
+    return props.uploadText || '点击上传';
+};
+
+const getUploadBtnStyle = (kind: AcceptKind) => {
+    const cfg = getBtnConfig(kind);
+    const style: Record<string, string> = {};
+    if (cfg.bgColor) style.backgroundColor = cfg.bgColor;
+    return style;
+};
+
+const getUploadBtnTextStyle = (kind: AcceptKind) => {
+    const cfg = getBtnConfig(kind);
+    const style: Record<string, string> = {};
+    if (cfg.textColor) style.color = cfg.textColor;
+    return style;
+};
+
+const getUploadBtnClass = (kind: AcceptKind) => {
+    const cfg = getBtnConfig(kind);
+    return cfg.customClass || '';
+};
+
+const getUploadIconName = (kind: AcceptKind) => {
+    const cfg = getBtnConfig(kind);
+    return cfg.iconName || props.iconName;
+};
+
+const getUploadIconColor = (kind: AcceptKind) => {
+    const cfg = getBtnConfig(kind);
+    return cfg.iconColor || props.iconColor;
+};
+
+const getUploadIconSize = (kind: AcceptKind) => {
+    const cfg = getBtnConfig(kind);
+    return cfg.iconSize || props.iconSize;
+};
+
 
 const onPreview = (index: number) => {
     const item = fileList.value[index];
     if (!item) return;
+    const kind = getItemKind(item);
     // 文件类型:上传中也允许预览本地临时文件
-    if (props.accept === 'file') {
+    if (kind === 'file') {
         const localPath = item.status === 'uploading' && item.tempUrl
             ? item.tempUrl
             : (!isUrl(item.url) ? item.url : '');
@@ -238,21 +377,26 @@ const onPreview = (index: number) => {
     }
     // 图片/视频:上传中不允许预览
     if (item?.status === 'uploading') return;
-    if (props.accept === 'image') {
-        const urls = fileList.value.map((i) => i.url);
+    if (kind === 'image') {
+        const images = fileList.value.filter((i) => getItemKind(i) === 'image');
+        const urls = images.map((i) => i.url);
+        const currentUrl = item.url;
+        const current = urls.indexOf(currentUrl);
         uni.previewImage({
             urls,
-            current: urls[index]
+            current: current >= 0 ? urls[current] : urls[0]
         });
         return;
     }
-    if (props.accept === 'video') {
+    if (kind === 'video') {
         // #ifdef MP-WEIXIN
-        const sources = fileList.value.map((i) => ({ url: i.url, type: 'video', poster: i.coverUrl || '' }));
+        const videos = fileList.value.filter((i) => getItemKind(i) === 'video');
+        const sources = videos.map((i) => ({ url: i.url, type: 'video', poster: i.coverUrl || '' }));
+        const current = videos.findIndex((v) => v === item);
         // @ts-ignore
         wx.previewMedia({
             sources,
-            current: index
+            current: current >= 0 ? current : 0
         });
         // #endif
         // #ifndef MP-WEIXIN

+ 2 - 2
src/main.ts

@@ -25,12 +25,12 @@ const uviewProps: any = {
         input: {
             color: '#333',
             fontSize: '30rpx',
-            placeholderStyle: 'color: #ccc; font-weight: 400;',
+            placeholderStyle: 'color: #ccc; font-weight: 400;fontSize:30rpx;',
         },
         textarea: {
             color: '#333',
             fontSize: '30rpx',
-            placeholderStyle: 'color: #ccc; font-weight: 400;',
+            placeholderStyle: 'color: #ccc; font-weight: 400;fontSize:30rpx;',
         },
         radio: {
             activeColor: '#37A954',

+ 62 - 0
src/models/picker-area-input/picker-area-input.vue

@@ -0,0 +1,62 @@
+<template>
+    <view @click="showArea = true">
+        <slot></slot>
+    </view>
+    <ut-picker-area v-model:show="showArea" v-model="value" :title="title" :selectCodeMax="selectCodeMax" :maxLevel="maxLevel" @confirm="confirmArea"></ut-picker-area>
+</template>
+<script setup lang="ts">
+const props = defineProps({
+    modelValue: {
+        type: String,
+        default: '',
+    },
+    title: {
+        type: String,
+        default: '请选择地址',
+    },
+    maxLevel: {
+        type: Number,
+        default: 3,
+    },
+    name: {
+        type: String,
+        default: '',
+    },
+    fullName: {
+        type: String,
+        default: '',
+    },
+    fullNames: {
+        type: String,
+        default: '',
+    },
+    selectCodeMax: {
+        type: String,
+        default: '',
+    }
+});
+const showArea = ref(false);
+const value = ref(props.modelValue);
+const emit = defineEmits(['update:modelValue', 'update:name', 'update:fullName', 'update:fullNames', 'change']);
+const confirmArea = (area: any) => {
+    value.value = area.value;
+    emit('update:modelValue', area.value);
+    emit('update:name', area.name);
+    emit('update:fullName', area.fullName);
+    emit('update:fullNames', area.fullNames);
+    emit('change', area);
+    showArea.value = false;
+};
+</script>
+<style scoped lang="scss">
+.close-icon {
+    position: absolute;
+    top: 0;
+    right: 0;
+    z-index: 10;
+}
+.card-info-block {
+    border: 1rpx solid #afddbb;
+    border-radius: 10rpx;
+}
+</style>

+ 1 - 1
src/plant/contact-unit/unit-edit/index.vue

@@ -7,7 +7,7 @@
             <view class="pd-24 bg-#fff mb-10">
                 <!-- 往来单位类型(多个可用逗号分隔) -->
                 <view class="h-1" id="cpyTypepppp"></view>
-                <ut-action-sheet v-model="form.cpyType" :tabs="pt_cpy_type" mode="custom" title="选择往来单位类型" multiple>
+                <ut-action-sheet v-model="form.cpyType" :tabs="pt_cpy_type" valueType="array" mode="custom" title="选择往来单位类型" multiple>
                     <up-form-item borderBottom label="往来单位类型" required prop="cpyType">
                         <view v-if="form.cpyType?.length" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabels(pt_cpy_type, form.cpyType, ',') }}</view>
                         <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择往来单位类型</view>

+ 58 - 21
src/plant/storage/seed-source/info-edit/index.vue

@@ -161,19 +161,39 @@
                 </up-form-item>
                 <!-- 检验报告与供应商信息 -->
                 <up-form-item borderBottom label="检验报告" prop="examinReport">
-                    <up-input v-model="form.examinReport" placeholder="请输入检验报告编号或说明" border="none" clearable></up-input>
+                    <ut-upload v-model="form.seedCheckCert" :max-count="50" valueType="array" accept="image,file"></ut-upload>
                 </up-form-item>
                 <up-form-item borderBottom label="供应商" prop="supplierId">
-                     <view class="flex1">
+                    <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="fungusCode">
-                    <up-input v-model="form.fungusCode" placeholder="请输入菌种/菌株编号" border="none" clearable></up-input>
+                <up-form-item label="菌种/菌株编号" 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>
                 <up-form-item borderBottom label="供应商是否是生产商" prop="supplierProducerFlag">
-                     <up-radio-group v-model="form.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>
@@ -205,10 +225,16 @@
                     <ut-upload v-model="form.vedios" :max-count="3" accept="video" valueType="array"></ut-upload>
                 </up-form-item>
 
-                <!-- 产地与繁殖信息 -->
-                <up-form-item borderBottom label="种源产地" prop="adcode">
-                    <up-input v-model="form.adcode" placeholder="请输入种源产地行政编码" border="none" clearable></up-input>
-                </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>
@@ -218,21 +244,20 @@
                         </template>
                     </up-form-item>
                 </ut-action-sheet>
-                <up-form-item borderBottom label="繁殖地点/采集地点" prop="generationAdcode">
-                    <up-input v-model="form.generationAdcode" placeholder="请输入繁殖/采集地点编码或名称" border="none" clearable></up-input>
-                </up-form-item>
 
+                <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="newSpCert">
-                    <ut-upload v-model="form.newSpCert" :max-count="9" valueType="array" accept="file"></ut-upload>
-                </up-form-item>
-                <up-form-item borderBottom label="引种证明" prop="importCert">
-                    <ut-upload v-model="form.importCert" :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>
@@ -248,14 +273,13 @@
             </view>
         </template>
     </z-paging>
-    
 </template>
 <script setup lang="ts">
 import { useClientRequest } from '@/utils/request';
 import { seedInfoListType } from '../models/type';
 import AnimalsInput from '../models/animals-input.vue';
-import SelectContactUnit from '@/models/select-contact-unit/select-contact-unit.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'));
@@ -269,15 +293,18 @@ const form = ref<seedInfoListType>({
     importCert: [],
     seedCheckCert: [],
     unit: '株',
+    adcode: '',
     instoreBizInfo: {
         motherFatherFlag: '',
         idFlag: '1',
         genUnit: '代',
     },
+    generationMaterial: '',
 });
 const rules = reactive({});
 
 const submitForm = async () => {
+    console.log(form.value);
     uni.$u.debounce(
         async () => {
             try {
@@ -363,4 +390,14 @@ onLoad((optins: any) => {
     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>

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

@@ -64,10 +64,6 @@ export interface seedInfoListType {
     generationAdcode?: string;
     /** 物种鉴定证书 */
     spCert?: AccesseryDTO[];
-    /** 新品种证书 */
-    newSpCert?: AccesseryDTO[];
-    /** 引种证明 */
-    importCert?: AccesseryDTO[];
     /** 种源检疫证号 */
     seedCheckSn?: string;
      /** 种源检疫证书 */