lisy 2 주 전
부모
커밋
bc1c3bbe58

+ 42 - 37
src/components/ut-col/ut-col.vue

@@ -1,64 +1,69 @@
 <template>
-	<view class="ut-col" :style="colStyle">
-		<slot />
-	</view>
+    <view class="ut-col" :style="colStyle" @click="handleClick">
+        <slot />
+    </view>
 </template>
 
 <script setup lang="ts">
 import { computed, inject, unref } from 'vue';
 
 interface UtColProps {
-	/** 占用份数(列宽),最大不超过 30 */
-	span?: number;
+    /** 占用份数(列宽),最大不超过 30 */
+    span?: number;
 }
 
 const props = withDefaults(defineProps<UtColProps>(), {
-	span: 10,
+    span: 10,
 });
 
+const emit = defineEmits(['click']);
+
+const handleClick = () => {
+    emit('click');
+};
+
 const ROW_INJECT_KEY = 'ut-row-context';
 
 const rowContext = inject<any>(ROW_INJECT_KEY, null);
 
 const colStyle = computed(() => {
-	const styles: Record<string, string> = {};
-	if (!rowContext) return styles;
-	const columns = Number(unref(rowContext.columns) || 0);
-	const gap = Number(unref(rowContext.gap) || 0);
-	const span = props.span || 0;
+    const styles: Record<string, string> = {};
+    if (!rowContext) return styles;
+    const columns = Number(unref(rowContext.columns) || 0);
+    const gap = Number(unref(rowContext.gap) || 0);
+    const span = props.span || 0;
 
-	if (columns > 0 && span > 0) {
-		const percent = (span / columns) * 100;
-		styles.flex = `0 0 ${percent}%`;
-		styles.maxWidth = `${percent}%`;
-	}
+    if (columns > 0 && span > 0) {
+        const percent = (span / columns) * 100;
+        styles.flex = `0 0 ${percent}%`;
+        styles.maxWidth = `${percent}%`;
+    }
 
-	if (gap > 0) {
-		const half = `${gap / 2}px`;
-		styles.paddingLeft = half;
-		styles.paddingRight = half;
-		styles.paddingTop = half;
-		styles.paddingBottom = half;
-	}
+    if (gap > 0) {
+        const half = `${gap / 2}px`;
+        styles.paddingLeft = half;
+        styles.paddingRight = half;
+        styles.paddingTop = half;
+        styles.paddingBottom = half;
+    }
 
-	return styles;
+    return styles;
 });
 </script>
-<script  lang="ts">  
-export default {  
-  options: {  
-    // 微信小程序中 options 选项  
-    multipleSlots: true, //  在组件定义时的选项中启动多slot支持,默认启用  
-    styleIsolation: 'shared', //  启动样式隔离。当使用页面自定义组件,希望父组件影响子组件样式时可能需要配置。具体配置选项参见:微信小程序自定义组件的样式  
-    addGlobalClass: true, //  表示页面样式将影响到自定义组件,但自定义组件中指定的样式不会影响页面。这个选项等价于设置 styleIsolation: apply-shared  
-    virtualHost: true //  将自定义节点设置成虚拟的,更加接近Vue组件的表现。我们不希望自定义组件的这个节点本身可以设置样式、响应 flex 布局等,而是希望自定义组件内部的第一层节点能够响应 flex 布局或者样式由自定义组件本身完全决定  
-  }  
-}  
+<script lang="ts">
+export default {
+    options: {
+        // 微信小程序中 options 选项
+        multipleSlots: true, //  在组件定义时的选项中启动多slot支持,默认启用
+        styleIsolation: 'shared', //  启动样式隔离。当使用页面自定义组件,希望父组件影响子组件样式时可能需要配置。具体配置选项参见:微信小程序自定义组件的样式
+        addGlobalClass: true, //  表示页面样式将影响到自定义组件,但自定义组件中指定的样式不会影响页面。这个选项等价于设置 styleIsolation: apply-shared
+        virtualHost: true, //  将自定义节点设置成虚拟的,更加接近Vue组件的表现。我们不希望自定义组件的这个节点本身可以设置样式、响应 flex 布局等,而是希望自定义组件内部的第一层节点能够响应 flex 布局或者样式由自定义组件本身完全决定
+    },
+};
 </script>
 <style scoped lang="scss">
 .ut-col {
-	min-width: 0; // 防止内容撑破
-	box-sizing: border-box;
+    min-width: 0; // 防止内容撑破
+    box-sizing: border-box;
 }
 </style>
-

+ 7 - 0
src/pages.json

@@ -390,6 +390,13 @@
                     "style": {
                         "navigationBarTitleText": "创建加工任务"
                     }
+                },
+                //加工任务详情列表
+                {
+                    "path": "processing-detail-list/index",
+                    "style": {
+                        "navigationBarTitleText": "加工任务详情"
+                    }
                 }
             ]
         },

+ 37 - 11
src/pages/plant/processing/index.vue

@@ -25,28 +25,43 @@
             <view class="pd-24">
                 <template v-for="(item, index) in list" :key="index">
                     <view class="bg-#fff b-radius pd-24 p-rtv mb-16">
-                        <view v-if="+item?.processType == 1 && +item?.processMedType == 1" class="bg-#91C747 c-#fff f-w-5 pd-10 pt-4 pb-4 f-s-20" style="border-radius: 16rpx 0 16rpx 0; width: max-content; position: relative; top: -24rpx; left: -24rpx">种子初加工</view>
-                        <view v-if="+item?.processType == 1 && +item?.processMedType == 2" class="bg-#C7A262 c-#fff f-w-5 pd-10 pt-4 pb-4 f-s-20" style="border-radius: 16rpx 0 16rpx 0; width: max-content; position: relative; top: -24rpx; left: -24rpx">药材初加工</view>
-                        <view v-if="+item?.processType == 2" class="bg-#37A954 c-#fff f-w-5 pd-10 pt-4 pb-4 f-s-20" style="border-radius: 16rpx 0 16rpx 0; width: max-content; position: relative; top: -24rpx; left: -24rpx">趁鲜切制</view>
-                        <view class="mb-10">
-                            <span class="f-s-34 c-#333 f-w-500 mr-10">{{ item?.variety }}</span>
-                            <span class="f-s-24 c-#666" v-if="+item?.stockType == 1">{{ selectDictLabel(pt_stock_type, item?.stockType) }}</span>
+                        <view v-if="+item?.processType == 1 && +item?.processMedType == 1" class="bg-#91C747 c-#fff f-w-5 pd-10 pt-4 pb-4 f-s-20" style="border-radius: 16rpx 0 16rpx 0; width: max-content; position: absolute; top: 0rpx; left: 0rpx">种子初加工</view>
+                        <view v-if="+item?.processType == 1 && +item?.processMedType == 2" class="bg-#C7A262 c-#fff f-w-5 pd-10 pt-4 pb-4 f-s-20" style="border-radius: 16rpx 0 16rpx 0; width: max-content; position: absolute; top: 0rpx; left: 0rpx">药材初加工</view>
+                        <view v-if="+item?.processType == 2" class="bg-#37A954 c-#fff f-w-5 pd-10 pt-4 pb-4 f-s-20" style="border-radius: 16rpx 0 16rpx 0; width: max-content; position: absolute; top: 0rpx; left: 0rpx">趁鲜切制</view>
+                        <view v-if="item?.processingDate || item?.processingDateEnd" class="d-flex a-c j-ed">
+                            <view class="c-#999 f-s-24">{{ item?.processingDate }} 至 {{ item?.processingDateEnd }}</view>
+                        </view>
+                        <view class="mb-10 d-flex a-c" @click="gotodetaillist(item)">
+                            <view class="">
+                                <span v-if="item?.variety" class="f-s-34 c-#333 f-w-500 mr-10">{{ item?.variety }}</span>
+                                <span v-else class="f-s-34 c-#333 f-w-500 mr-10">{{ item?.medicineName }}(鲜制)</span>
+                                <span class="f-s-24 c-#666" v-if="+item?.processMedType == 1">{{ selectDictLabel(pt_stock_type, item?.processMedType) }}</span>
+                            </view>
+                            <view class="flex1"></view>
+                            <up-icon name="arrow-right" size="26rpx"></up-icon>
                         </view>
                         <view class="pd2-4-0 f-s-28">
                             <span class="c-#666">加工批号:</span>
                             <span class="c-#333 f-w-500">{{ item?.processCode }}</span>
                         </view>
-                        <view class="pd2-4-0 f-s-28">
+                        <view v-if="+item?.processType == 1" class="pd2-4-0 f-s-28">
                             <span class="c-#666">执行标准:</span>
                             <span class="c-#333 f-w-500">{{ selectDictLabel(pt_standard_type, item?.standardType) }}</span>
                             <span class="c-#666" v-if="item?.standardDetailName">({{ item?.standardDetailName }})</span>
                         </view>
+                        <view v-else class="pd2-4-0 f-s-28">
+                            <span class="c-#666">执行标准:</span>
+                            <span class="c-#666" v-if="item?.standardDetailName">{{ item?.standardDetailName }}</span>
+                        </view>
                         <view class="pd2-4-0 f-s-28">
                             <span class="c-#666">加工工艺:</span>
-                            <template v-for="(items, indexs) in item?.ptech?.split(',')" :key="indexs">
+                            <template v-for="(items, indexs) in item?.ptech?.split(',')" v-if="item?.ptech" :key="indexs">
                                 <span v-if="indexs !== 0" class="c-#999 f-s-32 ml-10 mr-10">→ </span>
                                 <span class="f-s-32">{{ items }}</span>
                             </template>
+                            <template v-else>
+                                <span class="c-#999 f-s-32">-</span>
+                            </template>
                         </view>
                         <view class="pd2-4-0 f-s-28">
                             <span class="c-#666">加工负责人:</span>
@@ -140,7 +155,7 @@ const tabs = [
     },
 ];
 const form = ref({
-    restFlag: '0',
+    storageType: '4',
 });
 const query = async (pageNum: number, pageSize: number) => {
     const params = {
@@ -154,10 +169,21 @@ const query = async (pageNum: number, pageSize: number) => {
         paging.value.complete(rows);
     }
 };
-
+const gotodetaillist = (item: any) => {
+    uni.$u.route({
+        type: 'navigateTo',
+        url: '/plant/processing/processing-detail-list/index',
+        params: { id: item?.id },
+    });
+};
 const onRefresh = () => {
-    paging.value?.complete();
+    paging.value?.reload();
 };
+onMounted(() => {
+    uni.$on('updateprocesstasklist', function () {
+        paging.value?.reload();
+    });
+});
 </script>
 <style scoped lang="scss">
 .search-select-item {

+ 30 - 5
src/pages/plant/processing/models/output.vue

@@ -4,7 +4,7 @@
             <view class="">原</view>
             <view class="">料</view>
         </view>
-        <view class="bg-#F5FBF7 flex1 d-flex a-c" v-if="inputList?.length === 0">
+        <view class="bg-#F5FBF7 flex1 d-flex a-c" v-if="Object.keys(inputList || {}).length === 0">
             <view class="d-flex flex1 f-s-26">
                 <view class="c-#999 ml-16"> 暂无关联原料信息 </view>
                 <view class="flex1"></view>
@@ -22,12 +22,12 @@
                         <span class="c-#999 f-s-22 ml-10">{{ inputList?.storageInfo?.partName }}</span>
                     </view>
                     <view class="d-flex">
-                        <span class="c-#999 f-s-22">1mm极薄片</span>
+                        <span class="c-#999 f-s-22">{{ inputList?.storageInfo?.batchCode }}</span>
                     </view>
                 </ut-col>
                 <ut-col class="d-flex a-c c-#666" :span="10">{{ inputList?.quantity }}{{ inputList?.unit }}</ut-col>
-                <ut-col class="d-flex a-c j-ed" :span="5">
-                    <span class="c-#666">修改</span>
+                <ut-col class="d-flex a-c j-ed" :span="5" @click.stop="withdraw">
+                    <span class="c-#666">撤回</span>
                     <up-icon name="arrow-right" size="26rpx"></up-icon>
                 </ut-col>
             </ut-row>
@@ -74,16 +74,41 @@
     </view>
 </template>
 <script setup lang="ts">
+import { useClientRequest } from '@/utils/request';
 const props = defineProps<{
     data: any;
 }>();
+watch(
+    () => props.data,
+    (val) => {
+        inputList.value = val?.inputList[0] || {};
+    },
+);
 const inputList = ref<any>(props?.data?.inputList[0] || {});
 const goAssociate = () => {
-    console.log(props?.data?.id, 'processId');
     uni.$u.route({
         type: 'navigateTo',
         url: '/tools/species-info-process/index',
         params: { id: props?.data?.id, processMedType: props?.data?.processMedType },
     });
 };
+uni.$on(`updatesupervise-${props?.data?.id}`, function (data) {
+    inputList.value = data;
+});
+const withdraw = async () => {
+    // 删除
+    const res = await uni.showModal({
+        title: '撤回提示',
+        content: '撤回后不可恢复,请谨慎操作!',
+        confirmColor: '#F74C30',
+    });
+    console.log(res);
+    if (res.confirm) {
+        const delRes = await useClientRequest.get(`/plt-api/app/processInputMaterial/callbackInput/${inputList?.value?.id}`);
+        if (delRes && delRes.code === 200) {
+            uni.showToast({ title: '删除成功', icon: 'none' });
+            inputList.value = {};
+        }
+    }
+};
 </script>

+ 44 - 19
src/plant/processing/processing-create/index.vue

@@ -1,7 +1,7 @@
 <template>
     <z-paging ref="paging" v-model="list" bgColor="#f7f7f7" safe-area-inset-bottom>
         <template #top>
-            <ut-navbar title="创建加工任务" :fixed="false"> </ut-navbar>
+            <ut-navbar :title="pageTitle" :fixed="false"> </ut-navbar>
         </template>
         <view class="pt-24">
             <up-form class="p-rtv" labelPosition="top" :model="form" :rules="rules" labelWidth="auto" ref="upFormRef">
@@ -9,13 +9,13 @@
                     <!-- 加工方式 -->
                     <up-form-item borderBottom label="加工方式" required prop="processType">
                         <view class="f-s-30 c-#666 f-w-5 flex1">{{ selectDictLabel(pt_process_type, form.processType) }}</view>
-                        <template #right>
-                            <up-icon size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
-                        </template>
                     </up-form-item>
-
                     <!-- 加工对象 -->
-                    <ut-action-sheet v-model="form.processMedType" :tabs="pt_stock_type" title="选择加工对象">
+                    <up-form-item v-if="+form.processType == 2" borderBottom label="加工对象" required prop="processMedType">
+                        <view class="f-s-30 c-#666 f-w-5 flex1">{{ selectDictLabel(pt_stock_type, form.processMedType) }}</view>
+                    </up-form-item>
+                    <!-- 加工对象 -->
+                    <ut-action-sheet v-else v-model="form.processMedType" :tabs="pt_stock_type" title="选择加工对象">
                         <up-form-item borderBottom label="加工对象" required prop="processMedType">
                             <view v-if="form?.processMedType" class="f-s-30 c-#333 f-w-5 flex1">{{ selectDictLabel(pt_stock_type, form.processMedType) }}</view>
                             <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择加工对象</view>
@@ -59,8 +59,24 @@
                         </up-form-item>
                     </up-form-item>
 
+                    <up-form-item v-if="+form?.processType == 2" borderBottom label="是否属于趁鲜切制目录品种" required prop="freshCatalogueStatus">
+                        <view class="d-flex a-c w-100%">
+                            <up-radio-group v-model="form.freshCatalogueStatus">
+                                <up-radio :customStyle="{ marginRight: '60rpx' }" v-for="(item, index) in yes_no" :key="index" :label="item.label" :name="item.value"></up-radio>
+                            </up-radio-group>
+                        </view>
+                    </up-form-item>
+                    <!-- 生产批号 -->
+                    <up-form-item v-if="+form?.processType == 2" borderBottom label="生产批号" required prop="processCode">
+                        <view class="d-flex a-c j-sb w-100%">
+                            <view class="flex1 d-flex">
+                                <up-input v-model="form.processCode" placeholder="请输入生产批号" border="none" clearable></up-input>
+                                <up-button @click="randomCode" class="c-#fff" type="primary" style="height: 50rpx; width: 130rpx">随机生成</up-button>
+                            </view>
+                        </view>
+                    </up-form-item>
                     <!-- 加工批号 -->
-                    <up-form-item borderBottom label="加工批号" required prop="processCode">
+                    <up-form-item v-else borderBottom label="加工批号" required prop="processCode">
                         <view class="d-flex a-c j-sb w-100%">
                             <view class="flex1 d-flex">
                                 <up-input v-model="form.processCode" placeholder="请输入加工批号" border="none" clearable></up-input>
@@ -70,7 +86,7 @@
                     </up-form-item>
 
                     <!-- 加工执行标准 -->
-                    <ut-action-sheet v-model="form.standardType" :tabs="pt_standard_type" title="选择加工执行标准">
+                    <ut-action-sheet v-if="+form?.processType == 1" v-model="form.standardType" :tabs="pt_standard_type" title="选择加工执行标准">
                         <up-form-item borderBottom label="加工执行标准" required prop="standardType">
                             <view v-if="form?.standardType" class="f-s-30 c-#333 f-w-5 flex1">{{ selectDictLabel(pt_standard_type, form.standardType) }}</view>
                             <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择加工执行标准</view>
@@ -79,9 +95,12 @@
                             </template>
                         </up-form-item>
                     </ut-action-sheet>
-
+                    <!-- 执行标准 -->
+                    <up-form-item v-if="+form?.processType == 2" borderBottom label="执行标准" prop="standardDetailName">
+                        <up-input v-model="form.standardDetailName" placeholder="请输入执行标准" border="none" clearable></up-input>
+                    </up-form-item>
                     <!-- 具体标准名称 -->
-                    <up-form-item borderBottom label="具体标准名称" prop="standardDetailName">
+                    <up-form-item v-else borderBottom label="具体标准名称" prop="standardDetailName">
                         <up-input v-model="form.standardDetailName" placeholder="请输入具体标准名称" border="none" clearable></up-input>
                     </up-form-item>
 
@@ -138,10 +157,10 @@ import { useInfoStore } from '@/store';
 import Go_button from '@/components/go-button/Go_button.vue';
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const { pt_process_type, pt_stock_type, pt_standard_type } = toRefs<any>(proxy?.useDict('pt_process_type', 'pt_stock_type', 'pt_standard_type'));
+const { pt_process_type, pt_stock_type, pt_standard_type, yes_no } = toRefs<any>(proxy?.useDict('pt_process_type', 'pt_stock_type', 'pt_standard_type', 'yes_no'));
 
 const infoStore = useInfoStore();
-const pageTitle = ref('创建加工任务');
+const pageTitle = ref('创建加工任务');
 
 // 表单数据
 const form = ref({
@@ -150,8 +169,8 @@ const form = ref({
     // 加工对象
     processMedType: '',
     // 加工品种 ID
-    varietyId: '',
-    medicineCode: '',
+    varietyId: null as string | null,
+    medicineCode: null as string | null,
     // 加工品种名称
     varietyName: '',
     // 加工开始日期
@@ -172,6 +191,8 @@ const form = ref({
     imgs: null as string | null,
     // 视频
     videos: null as string | null,
+    //是否属于趁鲜切制目录品种 (0-否 1-是)
+    freshCatalogueStatus: null as string | null,
 });
 
 // 自定义校验函数 - 日期结束不能早于开始
@@ -222,8 +243,10 @@ const rules = reactive({
         { required: true, message: '请生成加工批号' },
         { validator: validateProcessCode, trigger: 'blur' },
     ],
-    standardType: [{ required: true, message: '请选择加工执行标准' }],
+    standardType: [{ required: !!(+form.value.processType == 1), message: '请选择加工执行标准' }],
+    standardDetailName: [{ required: !!(+form.value.standardType == 2), message: '请选择执行标准' }],
     contactName: [{ required: true, message: '请输入加工负责人' }],
+    freshCatalogueStatus: [{ required: !!(+form.value.processType == 2), message: '请选择是否属于趁鲜切制目录品种' }],
 });
 
 const paging = ref();
@@ -233,9 +256,8 @@ const upFormRef = ref<any>();
 // 处理开始时间变化
 const changeStartTime = (value: string) => {
     form.value.processingDate = value;
-    // 如果结束时间早于开始时间,清空结束时间
-    if (form.value.processingDateEnd && new Date(form.value.processingDateEnd) < new Date(value)) {
-        form.value.processingDateEnd = '';
+    if (!form.value?.processingDateEnd) {
+        form.value.processingDateEnd = form.value.processingDate;
     }
 };
 
@@ -328,8 +350,11 @@ const selectMedicine = () => {
     }
 };
 onLoad((options: any) => {
-    console.log('页面加载');
     form.value.processType = options?.taskType;
+    if (+options?.taskType == 2) {
+        pageTitle.value = '创建趁鲜切制任务';
+        form.value.processMedType = '2';
+    }
 });
 </script>
 

+ 323 - 0
src/plant/processing/processing-detail-list/index.vue

@@ -0,0 +1,323 @@
+<template>
+    <z-paging ref="paging" v-model="list" bgColor="#f7f7f7" @query="query" hide-no-more-inside hide-empty-view>
+        <template #top>
+            <ut-navbar title="加工任务详情" :fixed="false"> </ut-navbar>
+        </template>
+        <view class="pd-24">
+            <view class="bg-#fff pd-24 pt-16 b-radius p-rtv">
+                <!-- 任务类型标签 -->
+                <view v-if="+taskDetail?.processType == 1 && +taskDetail?.processMedType == 1" class="bg-#91C747 c-#fff f-w-5 pd-10 pt-4 pb-4 f-s-20" style="border-radius: 16rpx 0 16rpx 0; width: max-content; position: absolute; top: 0rpx; left: 0rpx">种子初加工</view>
+                <view v-if="+taskDetail?.processType == 1 && +taskDetail?.processMedType == 2" class="bg-#C7A962 c-#fff f-w-5 pd-10 pt-4 pb-4 f-s-20" style="border-radius: 16rpx 0 16rpx 0; width: max-content; position: absolute; top: 0rpx; left: 0rpx">药材初加工</view>
+                <view v-if="+taskDetail?.processType == 2" class="bg-#37A954 c-#fff f-w-5 pd-10 pt-4 pb-4 f-s-20" style="border-radius: 16rpx 0 16rpx 0; width: max-content; position: absolute; top: 0rpx; left: 0rpx">趁鲜切制</view>
+                <!-- 日期范围 -->
+                <view v-if="taskDetail?.processingDate || taskDetail?.processingDateEnd" class="d-flex a-c j-ed">
+                    <view class="c-#999 f-s-24">{{ taskDetail?.processingDate }} 至 {{ taskDetail?.processingDateEnd }}</view>
+                </view>
+                <!-- 药材名称 -->
+                <view class="d-flex a-c mb-10">
+                    <view class="f-s-34 f-w-5 c-#333 mr-10">{{ taskDetail?.variety || taskDetail?.medicineName }}</view>
+                    <view v-if="+taskDetail?.processMedType == 1" class="f-s-24 c-#666">{{ selectDictLabel(pt_stock_type, taskDetail?.processMedType) }}</view>
+                </view>
+                <!-- 加工批号 -->
+                <view class="d-flex f-s-28 pd2-4-0">
+                    <view class="c-#666">加工批号:</view>
+                    <view class="c-#333 f-w-5 flex1">{{ taskDetail?.processCode }}</view>
+                </view>
+                <!-- 执行标准 -->
+                <view class="d-flex f-s-28 pd2-4-0">
+                    <view class="c-#666">执行标准:</view>
+                    <view class="c-#333 f-w-5 flex1">
+                        <span>{{ selectDictLabel(pt_standard_type, taskDetail?.standardType) }}</span>
+                        <span v-if="taskDetail?.standardDetailName" class="c-#666">({{ taskDetail?.standardDetailName }})</span>
+                    </view>
+                </view>
+                <!-- 加工工艺 -->
+                <view class="d-flex f-s-28 pd2-4-0">
+                    <view class="c-#666">加工工艺:</view>
+                    <view class="c-#333 f-w-5 flex1 d-flex a-c" style="justify-content: flex-start">
+                        <template v-for="(item, index) in (taskDetail?.ptech || '').split(',')" :key="index">
+                            <span v-if="+index > 0 && item" class="c-#999 mx-10">→</span>
+                            <span v-if="item">{{ item }}</span>
+                        </template>
+                        <span v-if="!taskDetail?.ptech" class="c-#999">-</span>
+                    </view>
+                </view>
+                <view class="d-flex j-sb">
+                    <!-- 加工负责人 -->
+                    <view class="d-flex f-s-28 pd2-4-0">
+                        <view class="c-#666">加工负责人:</view>
+                        <view class="c-#333 f-w-5 flex1">{{ taskDetail?.contactName || '-' }}</view>
+                    </view>
+                    <!-- 去修改按钮 -->
+                    <view class="d-flex a-c j-ed pd2-4-0">
+                        <view class="c-primary f-s-28 d-flex a-c" @click="goEdit">
+                            <span>去修改</span>
+                            <up-icon name="arrow-right" size="24rpx" class="ml-5"></up-icon>
+                        </view>
+                    </view>
+                </view>
+            </view>
+            <!-- Tab 切换 -->
+            <view class="d-flex a-c bg-#f7f7f7 mb-16">
+                <ut-tabs v-model="activeTab" :tabs="tabs" @change="onTabChange"></ut-tabs>
+            </view>
+            <!-- 原料信息列表 -->
+            <view v-if="activeTab == '0'">
+                <view v-if="list.length === 0 && activeTab == '0'" class="d-flex flex-cln a-c pd-40">
+                    <ut-empty color="#ccc" size="28rpx" image=" https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/noEmpty.png">暂无加工原料信息</ut-empty>
+                    <up-button type="primary" @click="goAssociate">去关联原料信息</up-button>
+                </view>
+                <view v-else class="d-flex a-c mb-16">
+                    <view class="c-#999 f-s-28">使用的加工原料批次</view>
+                    <view class="flex1"></view>
+                    <up-button type="error" style="width: 160rpx; height: 60rpx" @click="withdraw">撤回用料</up-button>
+                </view>
+                <view v-for="(item, index) in list" :key="index" class="bg-#fff b-radius pd-24">
+                    <!-- 类型标签 -->
+                    <view class="d-flex j-sb a-c li-item-head mb-16">
+                        <view class="li-left-tag" :class="{ [`bg-instore-${item?.storageInfo?.instoreType}`]: true }">{{ selectDictLabel(pt_fresh_instore_type, item?.storageInfo?.instoreType) }}</view>
+                        <view class="f-s-22 c-#666 pt-10">{{ item?.updateTime || item?.createTime }}</view>
+                    </view>
+                    <view class="d-flex a-c j-sb mb-10">
+                        <!-- 物料名称 -->
+                        <view class="d-flex" style="align-items: flex-end">
+                            <view class="f-s-32 f-w-5 c-#333 mr-10">{{ item?.materialName }}</view>
+                            <view class="f-s-24 c-#999">{{ item?.storageInfo?.partName }}</view>
+                        </view>
+                        <!-- 状态 -->
+                        <view class="d-flex a-c" v-if="item?.storageInfo?.examinReport">
+                            <view class="c-#37A954 f-s-24 bg-#EDF7F0 pd-8 radius-8">已检验</view>
+                        </view>
+                    </view>
+                    <!-- 溯源入库 -->
+                    <template v-if="+item?.storageInfo?.instoreType == 1">
+                        <!-- 采收批号 -->
+                        <view class="d-flex pd2-4-0 f-s-28">
+                            <view class="c-#666">入库批号:</view>
+                            <view class="c-#333 f-w-5 flex1">{{ item?.storageInfo?.batchCode }}</view>
+                        </view>
+                        <view class="d-flex pd2-4-0 f-s-28">
+                            <view class="c-#666">供应商:</view>
+                            <view class="c-#333 f-w-5 flex1">{{ item?.storageInfo?.supplier || '-' }}</view>
+                        </view>
+                    </template>
+                    <!-- 非溯源入库 -->
+                    <template v-if="+item?.storageInfo?.instoreType == 2">
+                        <!-- 采收批号 -->
+                        <view class="d-flex pd2-4-0 f-s-28">
+                            <view class="c-#666">入库批号:</view>
+                            <view class="c-#333 f-w-5 flex1">{{ item?.storageInfo?.batchCode }}</view>
+                        </view>
+                        <view class="d-flex pd2-4-0 f-s-28">
+                            <view class="c-#666">供应商:</view>
+                            <view class="c-#333 f-w-5 flex1">{{ item?.storageInfo?.supplier || '-' }}</view>
+                        </view>
+                        <view class="d-flex pd2-4-0 f-s-28">
+                            <view class="c-#666">存放库房:</view>
+                            <view class="c-#333 f-w-5 flex1">
+                                {{ getStorageRoomNames(item?.storageInfo?.warehouses) || '-' }}
+                            </view>
+                        </view>
+                    </template>
+                    <!-- 采收入库 -->
+                    <template v-if="+item?.storageInfo?.instoreType == 3">
+                        <!-- 采收批号 -->
+                        <view class="d-flex pd2-4-0 f-s-28">
+                            <view class="c-#666">采收批号:</view>
+                            <view class="c-#333 f-w-5 flex1">{{ item?.storageInfo?.batchCode }}</view>
+                        </view>
+                        <view class="d-flex pd2-4-0 f-s-28">
+                            <view class="c-#666">采收基地:</view>
+                            <view class="c-#333 f-w-5 flex1">{{ item?.storageInfo?.baseName || '-' }}</view>
+                        </view>
+                    </template>
+                    <!-- 本次使用量 -->
+                    <view class="d-flex pd2-4-0 f-s-28">
+                        <view class="c-#666">本次使用量:</view>
+                        <view class="c-#333 f-w-5 flex1">{{ item?.quantity || 0 }}{{ item?.unit }}</view>
+                    </view>
+                </view>
+            </view>
+            <!-- 产出信息列表 -->
+            <view v-else>
+                <view v-if="outputList?.length === 0" class="d-flex flex-cln a-c pd-40">
+                    <ut-empty color="#ccc" size="28rpx" image="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images-plt/plant/noEmpty.png">暂无产出信息</ut-empty>
+                    <up-button type="primary" @click="handleShowOutputModel">去添加产出信息</up-button>
+                </view>
+                <view v-for="(item, index) in outputList" :key="index" class="bg-#fff b-radius pd-24 mb-16">
+                    <!-- 序号 -->
+                    <view class="d-flex a-c mb-12">
+                        <view class="bg-#2289E0 c-#fff f-s-20 f-w-5 pd-10 pt-4 pb-4 radius-8 mr-10">{{ String(index + 1).padStart(2, '0') }}</view>
+                        <view class="f-s-32 f-w-5 c-#333">{{ item?.specnLevel || '统货' }}</view>
+                    </view>
+                    <!-- 规格 -->
+                    <view class="d-flex mb-12 f-s-28">
+                        <view class="c-#666">规格:</view>
+                        <view class="c-#333 f-w-5 flex1">{{ item?.specn || '-' }}</view>
+                    </view>
+                    <!-- 产能 -->
+                    <view class="d-flex mb-12 f-s-28">
+                        <view class="c-#666">产能:</view>
+                        <view class="c-#333 f-w-5 flex1">{{ item?.capacity || 0 }}{{ item?.unit }}</view>
+                    </view>
+                    <!-- 状态 -->
+                    <view class="d-flex a-c j-end mt-16">
+                        <view v-if="item?.examinReport?.length > 0" class="c-#37A954 f-s-24 bg-#EDF7F0 pd-8 radius-8">已检</view>
+                        <view v-else class="c-#F74C30 f-s-24 bg-#FEF3E8 pd-8 radius-8">未检</view>
+                    </view>
+                </view>
+            </view>
+        </view>
+    </z-paging>
+
+    <!-- 添加产出信息弹框 -->
+    <OutputInfo v-if="showOutputModel" v-model:show="showOutputModel" :type="taskDetail?.processType" :processId="taskId" @confirm="handleOutputConfirm" />
+</template>
+
+<script setup lang="ts">
+import { getStorageRoomNames } from '@/utils/common';
+import { useClientRequest } from '@/utils/request';
+import OutputInfo from './models/outputInfo.vue';
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { pt_stock_type, pt_standard_type, pt_fresh_instore_type, pt_final_form_type } = toRefs<any>(proxy?.useDict('pt_stock_type', 'pt_standard_type', 'pt_fresh_instore_type', 'pt_final_form_type'));
+
+const paging = ref();
+const list = ref<any[]>([]);
+const taskId = ref('');
+const taskDetail = ref<any>({});
+const outputList = ref<any[]>([]);
+
+const activeTab = ref('0');
+const tabs = [
+    {
+        label: '原料信息',
+        value: '0',
+    },
+    {
+        label: '产出信息',
+        value: '1',
+    },
+];
+// 加载任务详情
+const loadTaskDetail = async () => {
+    try {
+        const res = await useClientRequest.get(`/plt-api/app/processe/getInfoById/${taskId.value}`);
+        if (res && res.data) {
+            taskDetail.value = res.data;
+        }
+    } catch (error) {
+        console.error('加载任务详情失败:', error);
+    }
+};
+
+// z-paging 查询原料列表
+const query = async (pageNum: number, pageSize: number) => {
+    try {
+        const res = await useClientRequest.get('/plt-api/app/processInputMaterial/pageList', {
+            pageNum,
+            pageSize,
+            processId: taskId.value,
+        });
+        if (res) {
+            const { rows } = res;
+            paging.value.complete(rows);
+        }
+    } catch (error) {
+        console.error('加载原料列表失败:', error);
+        paging.value.complete([]);
+    }
+};
+const goAssociate = () => {
+    uni.$once(`updatesupervise-${taskDetail?.value?.id}`, function (data) {
+        paging.value?.reload();
+    });
+
+    uni.$u.route({
+        type: 'navigateTo',
+        url: '/tools/species-info-process/index',
+        params: { id: taskDetail?.value?.id, processMedType: taskDetail?.value?.processMedType },
+    });
+};
+// Tab 切换
+const onTabChange = () => {
+    if (activeTab.value === '1') {
+        // 切换到产出信息,加载产出信息列表
+        getOutputList();
+    } else {
+        // 切换回原料信息,重新加载
+        paging.value?.reload();
+    }
+};
+
+// 获取产出信息列表
+const getOutputList = async () => {
+    try {
+        const res: any = await useClientRequest.get('/plt-api/app/processOutPut/pageList', {
+            processId: taskId.value,
+        });
+        if (res && res.rows) {
+            outputList.value = res.rows;
+        }
+    } catch (error) {
+        console.error('加载产出信息失败:', error);
+        outputList.value = [];
+    }
+};
+
+// 去修改
+const goEdit = () => {
+    uni.$u.route({
+        type: 'navigateTo',
+        url: '/plant/processing/processing-create/index',
+        params: { id: taskId.value, edit: 1 },
+    });
+};
+
+onLoad((options: any) => {
+    taskId.value = options?.id || '';
+    if (taskId.value) {
+        loadTaskDetail();
+    }
+});
+const withdraw = async () => {
+    // 删除
+    const res = await uni.showModal({
+        title: '撤回提示',
+        content: '撤回后不可恢复,请谨慎操作!',
+        confirmColor: '#F74C30',
+    });
+    console.log(res);
+    if (res.confirm) {
+        const delRes = await useClientRequest.get(`/plt-api/app/processInputMaterial/callbackInput/${taskDetail.value?.id}`);
+        if (delRes && delRes.code === 200) {
+            uni.showToast({ title: '删除成功', icon: 'none' });
+            paging.value?.reload();
+        }
+    }
+};
+
+// 显示添加产出信息弹框
+const showOutputModel = ref(false);
+const handleShowOutputModel = () => {
+    showOutputModel.value = true;
+};
+
+// 处理添加成功
+const handleOutputConfirm = () => {
+    getOutputList();
+};
+</script>
+
+<style scoped lang="scss">
+.li-left-tag {
+    padding: 6rpx 16rpx;
+    color: #fff;
+    border-radius: 16rpx 0 16rpx 0;
+    font-size: 20rpx;
+    font-weight: 500;
+}
+.li-item-head {
+    margin-left: -24rpx;
+    margin-top: -24rpx;
+}
+</style>

+ 183 - 0
src/plant/processing/processing-detail-list/models/outputInfo.vue

@@ -0,0 +1,183 @@
+<template>
+    <up-popup :show="show" mode="bottom" @close="handleClose" :round="20" closeable style="height: 70vh">
+        <view class="d-flex flex-cln h-100% pd-24 bg-#fff" style="max-height: 70vh">
+            <view class="f-s-34 f-w-5">添加产出信息</view>
+            <scroll-view scroll-y class="h-0 flex1">
+                <up-form ref="formRef" :model="formData" :rules="rules" labelPosition="top" labelWidth="auto">
+                    <template v-if="+type == 1">
+                        <!-- 规格等级 -->
+                        <up-form-item borderBottom label="规格等级" required prop="specnLevel">
+                            <ut-action-sheet v-model="formData.specnLevel" :tabs="specnLevelList" title="选择规格等级">
+                                <template #right>
+                                    <up-icon size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
+                                </template>
+                            </ut-action-sheet>
+                        </up-form-item>
+                        <!-- 产量 -->
+                        <up-form-item borderBottom label="产量" prop="capacity" required>
+                            <view class="d-flex a-c w-100%">
+                                <up-input v-model="formData.capacity" type="number" placeholder="请输入产量" border="none" clearable></up-input>
+                                <ut-action-sheet v-model="formData.unit" :tabs="unitList" title="选择单位" style="margin-left: 10rpx"></ut-action-sheet>
+                            </view>
+                        </up-form-item>
+
+                        <!-- 产出物图片 -->
+                        <up-form-item borderBottom label="产出物图片">
+                            <ut-upload v-model="formData.imgs" :max-count="6" valueType="array" accept="image" width="210rpx" height="210rpx" style="card"></ut-upload>
+                        </up-form-item>
+
+                        <!-- 检验报告 -->
+                        <up-form-item borderBottom label="检验报告">
+                            <ut-upload v-model="formData.examinReport" :max-count="50" valueType="array" accept="image,file" width="260rpx" height="260rpx" style="card" uploadImageText="上传图片" uploadFileText="上传 PDF"></ut-upload>
+                        </up-form-item>
+                    </template>
+
+                    <!-- 类型 2 特有字段 -->
+                    <template v-if="+type == 2">
+                        <!-- 切制形态 -->
+                        <up-form-item borderBottom label="切制形态" prop="finalFormType" required>
+                            <ut-action-sheet v-model="formData.finalFormType" :tabs="finalFormTypeList" title="选择切制形态">
+                                <template #right>
+                                    <up-icon size="22rpx" color="#2A6D52" name="arrow-down-fill"></up-icon>
+                                </template>
+                            </ut-action-sheet>
+                        </up-form-item>
+
+                        <!-- 具体切制形态 -->
+                        <up-form-item borderBottom label="具体切制形态" prop="finalFormOther">
+                            <up-input v-model="formData.finalFormOther" placeholder="请输入具体切制形态" border="none" clearable></up-input>
+                        </up-form-item>
+
+                        <!-- 切制尺寸 -->
+                        <up-form-item borderBottom label="切制尺寸" prop="finalUnit">
+                            <view class="d-flex a-c w-100%">
+                                <up-input v-model="formData.finalSpecn" type="number" placeholder="请输入切制尺寸" border="none" clearable></up-input>
+                                <view class="ml-10" style="font-size: 28rpx; font-weight: 500; color: #333">mm</view>
+                            </view>
+                        </up-form-item>
+                        <!-- 产出物图片 -->
+                        <up-form-item borderBottom label="产出物图片">
+                            <ut-upload v-model="formData.imgs" :max-count="6" valueType="array" accept="image" width="210rpx" height="210rpx" style="card"></ut-upload>
+                        </up-form-item>
+
+                        <!-- 检验报告 -->
+                        <up-form-item borderBottom label="检验报告">
+                            <ut-upload v-model="formData.examinReport" :max-count="50" valueType="array" accept="image,file" width="260rpx" height="260rpx" style="card" uploadImageText="上传图片" uploadFileText="上传 PDF"></ut-upload>
+                        </up-form-item>
+                    </template>
+                </up-form>
+            </scroll-view>
+
+            <!-- 底部按钮 -->
+            <view class="d-flex gap-20">
+                <up-button plain type="info" @click="handleClose">取消</up-button>
+                <up-button type="primary" @click="handleSubmit">确认</up-button>
+            </view>
+        </view>
+    </up-popup>
+</template>
+
+<script setup lang="ts">
+import { useClientRequest } from '@/utils/request';
+const props = defineProps<{
+    show: boolean;
+    type: number; // 1: 初加工,2: 趁鲜切制
+    processId: string | number; // 加工任务 ID
+}>();
+console.log(props.type, 'type');
+
+const emit = defineEmits<{
+    'update:show': [value: boolean];
+    confirm: [data: any];
+}>();
+
+const formRef = ref();
+const specnLevelList = ref<any[]>([]); // 规格等级列表(先空着)
+const unitList = ref<any[]>([]); // 单位列表(先空着)
+const finalFormTypeList = ref<any[]>([]); // 切制形态列表 pt_final_form_type
+
+// 表单数据
+const formData = ref({
+    specnLevel: '',
+    capacity: '',
+    unit: '',
+    imgs: [] as any[],
+    examinReport: [] as any[],
+    finalFormType: '',
+    finalFormOther: '',
+    finalSpecn: '',
+    finalUnit: '',
+});
+
+// 表单验证规则
+const rules = {
+    specnLevel: [{ required: true, message: '请选择规格等级', trigger: 'change' }],
+    capacity: [
+        { required: true, message: '请输入产量', trigger: 'blur' },
+        { type: 'number', message: '产量必须为数字', trigger: 'blur' },
+    ],
+    unit: [{ required: true, message: '请选择单位', trigger: 'change' }],
+    finalFormType: [{ required: true, message: '请选择切制形态', trigger: 'change' }],
+};
+
+// 关闭弹框
+const handleClose = () => {
+    emit('update:show', false);
+    resetForm();
+};
+
+// 重置表单
+const resetForm = () => {
+    formData.value = {
+        specnLevel: '',
+        capacity: '',
+        unit: '',
+        imgs: [],
+        examinReport: [],
+        finalFormType: '',
+        finalFormOther: '',
+        finalSpecn: '',
+        finalUnit: '',
+    };
+    formRef.value?.clearValidate();
+};
+
+// 提交表单
+const handleSubmit = async () => {
+    try {
+        const valid = await formRef.value?.validate();
+        if (!valid) return;
+
+        // 准备提交数据
+        const submitData = {
+            processId: props.processId,
+            specnLevel: formData.value.specnLevel,
+            capacity: Number(formData.value.capacity),
+            unit: formData.value.unit,
+            imgs: formData.value.imgs.map((item: any) => item.url).join(','),
+            examinReport: formData.value.examinReport.map((item: any) => ({
+                fileName: item.fileName || '',
+                url: item.url || '',
+                fileSize: item.fileSize || 0,
+            })),
+            finalFormType: formData.value.finalFormType,
+            finalFormOther: formData.value.finalFormOther,
+            finalSpecn: formData.value.finalSpecn,
+            finalUnit: formData.value.finalUnit,
+        };
+
+        // 调用接口
+        const res: any = await useClientRequest.post('/plt-api/app/processOutPut/output', submitData);
+
+        if (res && res.code === 200) {
+            uni.showToast({ title: '添加成功', icon: 'success' });
+            handleClose();
+            emit('confirm', res.data);
+        }
+    } catch (error) {
+        console.error('提交失败:', error);
+    }
+};
+</script>
+
+<style scoped lang="scss"></style>

+ 7 - 2
src/tools/species-info-process/index.vue

@@ -1,7 +1,7 @@
 <template>
     <z-paging ref="paging" v-model="list" paging-class="paging-btm-shadow" bgColor="#f7f7f7" safe-area-inset-bottom @query="query">
         <template #top>
-            <ut-navbar leftText="请选择任务所使用的种信息" :fixed="false"></ut-navbar>
+            <ut-navbar leftText="请选择任务所使用的种信息" :fixed="false"></ut-navbar>
         </template>
         <view class="d-flex a-c pd-24 pb-0 bg-#f7f7f7">
             <view class="min-w-170 flex1">
@@ -74,6 +74,7 @@ const paging = ref();
 const form = ref({
     keyword: '',
     instoreType: '',
+    storageType: '4',
     part: '',
     notIncludePart: '',
 });
@@ -225,7 +226,7 @@ const saveSeedInfo = async () => {
                     });
                     setTimeout(() => {
                         //发送emit
-                        uni.$emit('updatesuperviselist');
+                        uni.$emit(`updatesupervise-${processId.value}`, res?.data);
                         uni.navigateBack({
                             delta: 1,
                         });
@@ -254,6 +255,10 @@ onLoad((options: any) => {
         form.value.notIncludePart = 'PL-FR-05';
     }
 });
+//卸载监听
+onUnload(() => {
+    uni.$off(`updatesupervise-${processId.value}`);
+});
 </script>
 <style lang="scss" scoped>
 .search-select-item {

+ 4 - 0
src/tools/species-info/index.vue

@@ -270,6 +270,10 @@ const taskId = ref('');
 onLoad((options: any) => {
     taskId.value = options?.taskId;
 });
+//卸载监听
+onUnload(() => {
+    uni.$off('updatesuperviselist');
+});
 </script>
 <style lang="scss" scoped>
 .search-select-item {