Browse Source

feature:按照pc端重新调整

liuzhenlin 4 months ago
parent
commit
ffbd15b1dd
32 changed files with 757 additions and 358 deletions
  1. 1 2
      components/ui/CommonInfoRow.vue
  2. 1 1
      constants/index.ts
  3. 2 2
      pages/fund/claim-records/detail.vue
  4. 12 12
      pages/fund/reimbursement/detail.vue
  5. 13 13
      pages/home/index.vue
  6. 34 6
      pages/login/index.vue
  7. 1 2
      pages/project/components/detail/ChangeDetailPopup.vue
  8. 47 12
      pages/project/components/detail/FlowTable.vue
  9. 9 5
      pages/project/components/detail/ProjectSetupHorizontal.vue
  10. 9 5
      pages/project/components/detail/ProjectSetupSafety.vue
  11. 9 5
      pages/project/components/detail/ProjectSetupSpontaneity.vue
  12. 11 7
      pages/project/components/detail/ProjectSetupVertical.vue
  13. 10 8
      pages/todo/components/document/AchAwardsAuthForm.vue
  14. 86 23
      pages/todo/components/document/AchAwardsForm.vue
  15. 11 10
      pages/todo/components/document/AchConversionForm.vue
  16. 51 22
      pages/todo/components/document/AchDecisionForm.vue
  17. 2 4
      pages/todo/components/document/AchEvaluationForm.vue
  18. 95 25
      pages/todo/components/document/AchPaperForm.vue
  19. 2 4
      pages/todo/components/document/AchPatentAuthForm.vue
  20. 85 51
      pages/todo/components/document/AchPatentForm.vue
  21. 55 13
      pages/todo/components/document/AchWorkForm.vue
  22. 21 12
      pages/todo/components/document/ConferenceForm.vue
  23. 1 1
      pages/todo/components/document/HorizontalForm.vue
  24. 2 4
      pages/todo/components/document/PlanListForm.vue
  25. 37 50
      pages/todo/components/document/SafetyForm.vue
  26. 5 6
      pages/todo/components/document/SciAchievementOther.vue
  27. 31 10
      pages/todo/components/document/SciAchievementSoftware.vue
  28. 38 33
      pages/todo/components/document/SciAchievementStandard.vue
  29. 53 5
      pages/todo/components/document/SpecialActivityForm.vue
  30. 1 1
      pages/todo/components/document/SpontaneityForm.vue
  31. 3 3
      pages/todo/components/document/VerticalForm.vue
  32. 19 1
      pages/todo/components/document/common.scss

+ 1 - 2
components/ui/CommonInfoRow.vue

@@ -106,8 +106,7 @@ defineProps<{
     .item-label {
       width: 100%;
       margin-bottom: 16rpx;
-      color: #909399;
-      /* 二级标题弱化 */
+      color: #343a3f;
     }
 
     .item-value {

+ 1 - 1
constants/index.ts

@@ -120,7 +120,7 @@ export const HOME_NAV_LIST = [
   { name: '科研项目', path: '/pages/project/index', icon: '/static/imgs/fund-claim.png', permission: 'project:list' },
   // { name: '经费认领', path: '/pages/fund/claim/index', icon: '/static/imgs/fund-claim.png' },
   { name: '经费入账', path: '/pages/fund/claim-records/index', icon: '/static/imgs/fund-entry.png', permission: 'fund:claim:records:list' },
-  { name: '经费报销', path: '/pages/fund/reimbursement/index', icon: '/static/imgs/fund-reimburse.png', permission: 'fund:reimbursement:list' },
+  { name: '经费支出', path: '/pages/fund/reimbursement/index', icon: '/static/imgs/fund-reimburse.png', permission: 'fund:reimbursement:list' },
   { name: '科研成果', path: '/pages/achievement/index', icon: '/static/imgs/fund-reimburse.png', permission: 'achievement:list' },
   // { name: '考核奖励', path: '/pages/fund/reimbursement-remind/index', icon: '/static/imgs/fund-reimburse.png' },
   { name: '业务审批', path: '/pages/todo/index', icon: '/static/imgs/home-tech.png', permission: 'todo:list' }

+ 2 - 2
pages/fund/claim-records/detail.vue

@@ -14,9 +14,9 @@
     <view class="scroll-wrapper">
       <scroll-view scroll-y class="content-area" :show-scrollbar="false">
         <view class="component-wrapper">
-          <CommonSection title="项目信息">
+     <!--     <CommonSection title="项目信息">
             <CommonInfoRow label="预算金额" :value="amountUnitFormatter(form.contractAmount) + '元'" :isAmount="true" />
-          </CommonSection>
+          </CommonSection> -->
 
           <CommonSection title="入账经费">
             <CommonInfoRow label="经费类型" :value="getDictLabel('PaymentReceivedType', form.amountType)" />

+ 12 - 12
pages/fund/reimbursement/detail.vue

@@ -11,12 +11,12 @@
         </view>
       </view>
     </view>
-    <view class="tabs-container">
+   <!-- <view class="tabs-container">
         <uv-tabs :list="tabList" :current="currentTab" @change="onTabChange"
         :activeStyle="{ color: '#1c9bfd', fontWeight: 'bold' }"
         :inactiveStyle="{ color: '#666' }" lineColor="#1c9bfd"
         :scrollable="true"></uv-tabs>
-    </view>
+    </view> -->
     <scroll-view scroll-y class="content-area" :show-scrollbar="false">
         <view class="component-wrapper" v-if="currentTab === 0">
           <CommonSection title="项目信息">
@@ -40,12 +40,12 @@
         <CommonSection title="报销经费">
           <CommonInfoRow label="经办人" :value="form.handle" />
           <CommonInfoRow label="支出金额" :value="amountUnitFormatter(form.amount) + '元'" :isAmount="true" />
-          <CommonInfoRow label="结算金额" :value="form.settleAmount !== null && form.settleAmount !== undefined ? amountUnitFormatter(form.settleAmount) + '元' : '-'" :isAmount="true" />
+          <!-- <CommonInfoRow label="结算金额" :value="form.settleAmount !== null && form.settleAmount !== undefined ? amountUnitFormatter(form.settleAmount) + '元' : '-'" :isAmount="true" /> -->
         </CommonSection>
         </view>
 
         <!-- 发票信息 -->
-        <view class="component-wrapper" v-else-if="currentTab === 1">
+        <!-- <view class="component-wrapper" v-else-if="currentTab === 1">
           <template v-if="form.invoice && form.invoice.length > 0">
             <CommonSection 
               v-for="(item, index) in form.invoice" 
@@ -78,10 +78,10 @@
             </CommonSection>
           </template>
           <uv-empty v-else mode="data" text="暂无发票信息" margin-top="100"></uv-empty>
-        </view>
+        </view> -->
 
         <!-- 支付信息 -->
-        <view class="component-wrapper" v-else-if="currentTab === 2">
+     <!--   <view class="component-wrapper" v-else-if="currentTab === 2">
           <template v-if="form.payment && form.payment.length > 0">
             <CommonSection 
               v-for="(item, index) in form.payment" 
@@ -100,10 +100,10 @@
             </CommonSection>
           </template>
           <uv-empty v-else mode="data" text="暂无支付信息" margin-top="100"></uv-empty>
-        </view>
+        </view> -->
 
         <!-- 附件信息 -->
-        <view class="component-wrapper" v-else-if="currentTab === 3">
+       <!-- <view class="component-wrapper" v-else-if="currentTab === 3">
           <template v-if="form.fileList && form.fileList.length > 0">
             <CommonSection title="附件信息">
               <view v-for="(file, idx) in form.fileList" :key="'file-' + idx" style="margin-bottom: 24rpx; padding-bottom: 24rpx; border-bottom: 1px dashed #eee;">
@@ -126,11 +126,11 @@
             </CommonSection>
           </template>
           <uv-empty v-else mode="data" text="暂无附件信息" margin-top="100"></uv-empty>
-        </view>
+        </view> -->
 
-      <view class="component-wrapper" v-else-if="currentTab === 4">
+     <!-- <view class="component-wrapper" v-else-if="currentTab === 4">
         <FlowTable :id="form.id || 0" :businessCode="'' + (form.id || '')" defCode="sci_fund_expense" />
-      </view>
+      </view> -->
     </scroll-view>
   </view>
 </template>
@@ -156,7 +156,7 @@ const receiverTypeOptions = ref<any[]>([]);
 const showAmount = ref(0);
 const showBalanceAmount = ref(0);
 
-const tabList = ref([{ name: '项目信息' }, { name: '发票信息' }, { name: '支付信息' }, { name: '附件信息' }, { name: '审批详情' }]);
+// const tabList = ref([{ name: '项目信息' }]);
 const currentTab = ref(0);
 
 const onTabChange = (e: any) => {

+ 13 - 13
pages/home/index.vue

@@ -59,7 +59,7 @@
     </view>
 
     <!-- 报销提醒 -->
-    <view class="section-box mt20" v-hasPermi="['fund:reimbursement:list']">
+    <!-- <view class="section-box mt20" v-hasPermi="['fund:reimbursement:list']">
       <view class="section-header flex justify-between align-center">
         <text class="section-title">报销提醒</text>
         <text class="link" @click="onRouterPush('/pages/fund/reimbursement-remind/index')">查看更多 ></text>
@@ -84,7 +84,7 @@
         </view>
         </view>
       </view>
-    </view>
+    </view> -->
 
     <!-- 通知公告列表 -->
     <view class="section-box mt20">
@@ -189,16 +189,16 @@ const getFundList = async () => {
 /**
  * 获取报销提醒简要列表
  */
-const getExpendseList = async () => {
-  try {
-    const res: any = await expenseRemindApi.getList({ pageNum: 1, pageSize: 3, expenseStatus: '10' });
-    if (res.code == 200) {
-      expendseList.value = res.data?.list || res.list || [];
-    }
-  } catch (err) {
-    console.error(err);
-  }
-};
+// const getExpendseList = async () => {
+//   try {
+//     const res: any = await expenseRemindApi.getList({ pageNum: 1, pageSize: 3, expenseStatus: '10' });
+//     if (res.code == 200) {
+//       expendseList.value = res.data?.list || res.list || [];
+//     }
+//   } catch (err) {
+//     console.error(err);
+//   }
+// };
 
 /**
  * 处理审批跳转逻辑
@@ -260,7 +260,7 @@ const refreshAllData = () => {
   
   todoStore.fetchHomeTodoList();
   getFundList();
-  getExpendseList();
+  // getExpendseList();
   getNoticeList();
 };
 

+ 34 - 6
pages/login/index.vue

@@ -120,11 +120,37 @@ const loading = ref(false);
 const showPassword = ref(false);
 const rememberMeArr = ref<string[]>([]);
 const toastRef = ref<any>(null);
+// 企业微信免登回调:显示加载态(避免用户看到账号/密码输入框)
+const showOAuthLoading = ref<boolean>(false);
+
+const getUrlCode = (): string | undefined => {
+  const rawCode = (uni.getLaunchOptionsSync()?.query as any)?.code as undefined | string | string[];
+  const urlCode = Array.isArray(rawCode) ? rawCode[0] : rawCode;
+  if (urlCode) return urlCode;
+
+  // H5: 形如 ?code=xxx&state=STATE#/pages/login/index,code 在 search 中
+  if (typeof window !== 'undefined') {
+    try {
+      const params = new URLSearchParams(window.location.search);
+      const searchCode = params.get('code');
+      if (searchCode) return searchCode;
+
+      // 兜底:如果 code 出现在 hash 的参数里,也尝试解析
+      const hash = window.location.hash || '';
+      const hashParamsIndex = hash.indexOf('?');
+      if (hashParamsIndex !== -1) {
+        const hashParams = hash.substring(hashParamsIndex + 1);
+        const hashSearchParams = new URLSearchParams(hashParams);
+        const hashCode = hashSearchParams.get('code');
+        if (hashCode) return hashCode;
+      }
+    } catch (e) {
+      // ignore
+    }
+  }
 
-// 企业微信免登回调通常会在 URL 上带 `code`,进入本页后直接走免登并展示加载态
-const rawLaunchCode = (uni.getLaunchOptionsSync()?.query as any)?.code as undefined | string | string[];
-const initialUrlCode = Array.isArray(rawLaunchCode) ? rawLaunchCode[0] : rawLaunchCode;
-const showOAuthLoading = ref<boolean>(!!initialUrlCode);
+  return undefined;
+};
 
 onMounted(async () => {
   // --- 新增:登录拦截 ---
@@ -151,8 +177,10 @@ onMounted(async () => {
   }
 
   // 检测 URL 是否携带 code (企业微信免登)
-  if (initialUrlCode) {
-    await handleEnterpriseLogin(initialUrlCode);
+  const urlCode = getUrlCode();
+  if (urlCode) {
+    showOAuthLoading.value = true;
+    await handleEnterpriseLogin(urlCode);
     return;
   }
 

+ 1 - 2
pages/project/components/detail/ChangeDetailPopup.vue

@@ -192,7 +192,7 @@
 import { ref, computed } from 'vue';
 import { useProjectStore } from '@/store/modules/project';
 import { useDict } from '@/hooks/useDict';
-import { changeTypeOptions, isClinicalTrialOptions } from '@/constants';
+import { changeTypeOptions } from '@/constants';
 import FlowTable from './FlowTable.vue';
 import dayjs from 'dayjs';
 import CommonSection from '@/components/ui/CommonSection.vue';
@@ -202,7 +202,6 @@ import { previewFile } from '@/utils/file';
 const projectStore = useProjectStore();
 const popupRef = ref<any>(null);
 
-// Pull globally dynamic dictionaries
 const sysDict = useDict('sci_pjt_level', 'sci_pjt_type', 'sci_academic_degree');
 
 /** Tab 页标题配置 */

+ 47 - 12
pages/project/components/detail/FlowTable.vue

@@ -2,16 +2,17 @@
   <view class="container">
     <ApprovalFlow
       :list="groupedNodes"
-      :currentNode="flowStore.currentNode"
-      :loading="flowStore.fetchFlowLoading"
+      :currentNode="currentNode"
+      :loading="fetchFlowLoading"
     />
   </view>
 </template>
 
 <script setup lang="ts">
-import { watch, computed } from 'vue';
-import { useFlowStore } from '@/store/modules/flow';
+import { watch, computed, ref } from 'vue';
 import ApprovalFlow from '@/components/ApprovalFlow.vue';
+import { useFlowApi } from '@/api/flow/index';
+import to from 'await-to-js';
 
 /**
  * 接收来自父组件的流程属性配置
@@ -23,12 +24,18 @@ const props = defineProps({
   memberList: { type: Array, default: () => [] }
 });
 
-// 引入统一的状态管理
-const flowStore = useFlowStore();
+const flowApi = useFlowApi();
+
+// 审批实例节点列表(组件内独立维护,避免多个 FlowTable 互相覆盖)
+const apprList = ref<any[]>([]);
+// 当前处于的节点
+const currentNode = ref<string>('');
+// 加载状态
+const fetchFlowLoading = ref<boolean>(false);
 
 // 将原始审批记录按节点分组
 const groupedNodes = computed(() => {
-  const list = flowStore.apprList || [];
+  const list = apprList.value || [];
   if (!list.length) return [];
   const map: Record<string, any> = {};
   list.forEach((item: any) => {
@@ -47,15 +54,43 @@ const groupedNodes = computed(() => {
   return Object.values(map);
 });
 
+const fetchFlowInstance = async () => {
+  if (!props.id) return;
+  fetchFlowLoading.value = true;
+  apprList.value = [];
+  currentNode.value = '';
+
+  const params = { id: props.id, businessCode: props.businessCode, defCode: props.defCode };
+  const [err, res] = await to(flowApi.getFlowInstance(params)) as [any, any];
+
+  fetchFlowLoading.value = false;
+
+  if (err) {
+    console.error('获取审批流实例失败:', err);
+    return;
+  }
+
+  if (res && res.code === 200) {
+    const arr = res.data?.nodes || [];
+    // 匹配附加数据
+    apprList.value = arr.map((item: any) => {
+      const obj = (props.memberList as any[]).find((i: any) => i.memberId === item.userId);
+      return {
+        ...item,
+        templateContent: obj?.templateContent || null
+      };
+    });
+    currentNode.value = res.data?.nodeId || '';
+  }
+};
+
 /**
  * 监听属性变化并在有传入的时候触发拉取审批流信息
  */
 watch(
-  () => props.id,
-  (val) => {
-    if (val) {
-      flowStore.fetchFlowInstance(val, props.businessCode, props.defCode, props.memberList);
-    }
+  () => [props.id, props.businessCode, props.defCode],
+  () => {
+    fetchFlowInstance();
   },
   { deep: true, immediate: true }
 );

+ 9 - 5
pages/project/components/detail/ProjectSetupHorizontal.vue

@@ -30,11 +30,9 @@
       <CommonInfoRow label="到账日期" :value="projectData?.arrivalDate ? formatDate(projectData.arrivalDate) : '--'" />
 
       <!-- 所属平台 -->
-      <CommonInfoRow label="所属平台">
+      <CommonInfoRow label="所属平台" isColumn>
         <view class="platform-tags" v-if="platformList.length > 0">
-          <view v-for="(item, index) in platformList" :key="index" class="platform-tag">
-            {{ item.platformName === '其他' ? item.platformName : `${item.platformName} (${item.platformType})` }}
-          </view>
+          <uv-tags v-for="(p, index) in platformList" :key="index" :text="p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
         </view>
         <text v-else>--</text>
       </CommonInfoRow>
@@ -115,7 +113,9 @@ const amountUnitFormatter = (num: any) => {
   display: flex;
   flex-wrap: wrap;
   gap: 8rpx;
-  justify-content: flex-end;
+  justify-content: flex-start;
+  width: 100%;
+  box-sizing: border-box;
 }
 
 .platform-tag {
@@ -125,6 +125,10 @@ const amountUnitFormatter = (num: any) => {
   padding: 4rpx 16rpx;
   border-radius: 6rpx;
   border: 1px solid #bae7ff;
+  max-width: 100%;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
 }
 
 .party-card {

+ 9 - 5
pages/project/components/detail/ProjectSetupSafety.vue

@@ -20,11 +20,9 @@
       <CommonInfoRow label="总金额(元)" :value="formatWithComma((Number(projectData?.contractFunds || 0) + Number(projectData?.supportFunds || 0) + Number(projectData?.selfFunds || 0)))" isAmount />
       <CommonInfoRow label="到账金额(元)" :value="formatWithComma(projectData?.arrivalFunds)" isAmount />
       <CommonInfoRow label="到账日期" :value="formatDate(projectData?.arrivalDate)" />
-      <CommonInfoRow label="所属平台">
+      <CommonInfoRow label="所属平台" isColumn>
         <view class="platform-tags" v-if="platformList.length > 0">
-          <view v-for="(item, index) in platformList" :key="index" class="platform-tag">
-            {{ item.platformName === '其他' ? item.platformName : `${item.platformName} (${item.platformType})` }}
-          </view>
+          <uv-tags v-for="(p, index) in platformList" :key="index" :text="p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
         </view>
         <text v-else>--</text>
       </CommonInfoRow>
@@ -79,7 +77,9 @@ const platformList = computed(() => {
   display: flex;
   flex-wrap: wrap;
   gap: 8rpx;
-  justify-content: flex-end;
+  justify-content: flex-start;
+  width: 100%;
+  box-sizing: border-box;
 }
 
 .platform-tag {
@@ -89,5 +89,9 @@ const platformList = computed(() => {
   padding: 4rpx 16rpx;
   border-radius: 6rpx;
   border: 1px solid #bae7ff;
+  max-width: 100%;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
 }
 </style>

+ 9 - 5
pages/project/components/detail/ProjectSetupSpontaneity.vue

@@ -15,11 +15,9 @@
       <CommonInfoRow label="所属年度" :value="projectData?.statisticalYear" />
       <CommonInfoRow label="项目负责人" :value="projectData?.projectLeaderName" />
       <CommonInfoRow label="项目负责人类型" :value="getDictLabel('sci_leader_type', projectData?.projectLeaderType)" />
-      <CommonInfoRow label="所属平台">
+      <CommonInfoRow label="所属平台" isColumn>
         <view class="platform-tags" v-if="platformList.length > 0">
-          <view v-for="(item, index) in platformList" :key="index" class="platform-tag">
-            {{ item.platformName === '其他' ? item.platformName : `${item.platformName} (${item.platformType})` }}
-          </view>
+          <uv-tags v-for="(p, index) in platformList" :key="index" :text="p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
         </view>
         <text v-else>--</text>
       </CommonInfoRow>
@@ -79,7 +77,9 @@ const platformList = computed(() => {
   display: flex;
   flex-wrap: wrap;
   gap: 8rpx;
-  justify-content: flex-end;
+  justify-content: flex-start;
+  width: 100%;
+  box-sizing: border-box;
 }
 
 .platform-tag {
@@ -89,5 +89,9 @@ const platformList = computed(() => {
   padding: 4rpx 16rpx;
   border-radius: 6rpx;
   border: 1px solid #bae7ff;
+  max-width: 100%;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
 }
 </style>

+ 11 - 7
pages/project/components/detail/ProjectSetupVertical.vue

@@ -6,7 +6,7 @@
       <CommonInfoRow label="项目来源单位" :value="projectData?.projectSource" />
       <CommonInfoRow label="负责人" :value="projectData?.projectLeaderName" />
       <CommonInfoRow label="负责人类型" :value="getDictLabel('sci_leader_type', projectData?.projectLeaderType)" />
-      <CommonInfoRow label="项目级别" :value="getDictLabel('sci_pjt_level', projectData?.projectLevel)" />
+      <CommonInfoRow label="项目级别" :value="getDictLabel('sci_vertical_level', projectData?.projectLevel)" />
       <CommonInfoRow label="项目分类" :value="projectData?.projectClazzName" />
       <CommonInfoRow label="项目状态" :value="getStatusLabel(verticalProjectStatusOptions, projectData?.projectStatus)" />
       <CommonInfoRow label="立项日期" :value="projectData?.approvalDate ? formatDate(projectData.approvalDate) : '--'" />
@@ -17,11 +17,9 @@
       <CommonInfoRow label="配套经费(元)" :value="amountUnitFormatter(projectData?.supportFunds)" isAmount />
       <CommonInfoRow label="外拨经费(元)" :value="amountUnitFormatter(projectData?.outsourcedFunds)" isAmount />
       <CommonInfoRow label="所属年度" :value="projectData?.statisticalYear || '--'" />
-      <CommonInfoRow label="所属平台">
+      <CommonInfoRow label="所属平台" isColumn>
         <view class="platform-tags" v-if="platformList.length > 0">
-          <view v-for="(item, index) in platformList" :key="index" class="platform-tag">
-            {{ item.platformName === '其他' ? item.platformName : `${item.platformName} (${item.platformType})` }}
-          </view>
+          <uv-tags v-for="(p, index) in platformList" :key="index" :text="p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
         </view>
         <text v-else>--</text>
       </CommonInfoRow>
@@ -46,7 +44,7 @@ const props = defineProps<{
   projectData: any;
 }>();
 
-const { getDictLabel } = useDict('sci_pjt_level', 'project_class', 'sci_leader_type');
+const { getDictLabel } = useDict('sci_vertical_level', 'project_class', 'sci_leader_type');
 
 /**
  * 计算属性:所属平台解析
@@ -80,7 +78,9 @@ const amountUnitFormatter = (num: any) => {
   display: flex;
   flex-wrap: wrap;
   gap: 8rpx;
-  justify-content: flex-end;
+  justify-content: flex-start;
+  width: 100%;
+  box-sizing: border-box;
 }
 
 .platform-tag {
@@ -90,5 +90,9 @@ const amountUnitFormatter = (num: any) => {
   padding: 4rpx 16rpx;
   border-radius: 6rpx;
   border: 1px solid #bae7ff;
+  max-width: 100%;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
 }
 </style>

+ 10 - 8
pages/todo/components/document/AchAwardsAuthForm.vue

@@ -6,7 +6,8 @@
       <CommonSection title="基本信息" :isFirst="true">
         <CommonInfoRow label="获奖编号" :value="form.awardCode || '-'" />
         <CommonInfoRow label="获奖项目名称" :value="form.projectSource || '-'" />
-        <CommonInfoRow label="获奖类别" :value="form.awardType === '10' ? '教学成果' : form.awardType === '20' ? '科研奖项' : '-'" />
+        <CommonInfoRow label="获奖类别"
+          :value="form.awardType === '10' ? '教学成果' : form.awardType === '20' ? '科研奖项' : '-'" />
         <CommonInfoRow label="获奖等级" :value="getDictLabel('sci_awards_grade', form.awardGrade)" />
         <CommonInfoRow label="获奖级别" :value="getDictLabel('sci_awards_level', form.awardLevel)" />
         <CommonInfoRow label="奖项所属年度" :value="form.awardYear || '-'" />
@@ -14,12 +15,10 @@
         <CommonInfoRow label="完成单位" :value="form.completionUnit || '-'" />
         <CommonInfoRow label="颁奖机构" :value="form.awardIssueAuthority || '-'" />
         <CommonInfoRow label="获奖金额(万元)" :value="form.awardAmount || '-'" />
-        <CommonInfoRow label="所属平台">
+        <CommonInfoRow label="所属平台" isColumn>
           <view class="platform-tags">
             <template v-if="platformList.length > 0">
-              <text v-for="(p, index) in platformList" :key="index" class="platform-tag">
-                {{ p.platformName }}
-              </text>
+              <uv-tags v-for="(p, index) in platformList" :key="index" :text="p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
             </template>
             <text v-else>-</text>
           </view>
@@ -29,8 +28,8 @@
       </CommonSection>
 
       <!-- 获奖人信息 -->
-      <CommonSection title="获奖人信息" v-if="form.memberList?.length">
-        <view class="member-list">
+      <CommonSection title="获奖人信息">
+        <view class="member-list" v-if="form.memberList?.length">
           <view class="member-item" v-for="(row, index) in form.memberList" :key="index">
             <view class="member-header">
               <view class="name-box">
@@ -39,10 +38,13 @@
               </view>
             </view>
             <view class="m-body">
-              <view class="m-line" v-if="row.deptName"><text class="l">所属部门:</text><text class="v">{{ row.deptName }}</text></view>
+              <view class="m-line" v-if="row.deptName"><text class="l">所属部门:</text><text class="v">{{ row.deptName
+                  }}</text>
+              </view>
             </view>
           </view>
         </view>
+        <uv-empty v-else mode="data" text="暂无数据"></uv-empty>
       </CommonSection>
 
       <!-- 附件信息 -->

+ 86 - 23
pages/todo/components/document/AchAwardsForm.vue

@@ -4,18 +4,19 @@
     <template v-else-if="form">
       <!-- 基本信息 -->
       <CommonSection title="基本信息" :isFirst="true">
-        <CommonInfoRow label="获奖项目名称" :value="form.projectSource" />
-        <CommonInfoRow label="所在科室" :value="form.deptName" />
+        <CommonInfoRow label="所在部门" :value="form.deptName" />
         <CommonInfoRow label="批文年月日" :value="formatDate(form.awardDate)" />
-        <CommonInfoRow label="奖项所属年度" :value="form.awardYear" />
+        <CommonInfoRow label="奖项所属年度" :value="form.awardYear ? formatDate(form.awardYear, 'YYYY') : '-'" />
+        <CommonInfoRow label="获奖项目名称" :value="form.projectSource" />
         <CommonInfoRow label="获奖类别" :value="form.awardType === '10' ? '教学成果' : '科研奖项'" />
         <CommonInfoRow label="获奖等级" :value="getDictLabel('sci_awards_grade', form.awardGrade)" />
-        <CommonInfoRow label="获奖级别" :value="getDictLabel('sci_awards_level', form.awardLevel)" />
-        <CommonInfoRow label="获奖人(备案人)" :value="showMembers(form.memberList)" />
+        <CommonInfoRow label="获奖级别" :value="getDictLabel('sci_awards_level', form.awardLevel)" /> 
+        <CommonInfoRow label="获奖人(备案人)" :value="form.members || showMembers(form.memberList)" />
+        <CommonInfoRow label="全部获奖完成人(按获奖顺序排列)" :value="form.remark" isColumn />
         <CommonInfoRow label="颁奖机构" :value="form.awardIssueAuthority" />
         <CommonInfoRow label="完成单位" :value="form.completionUnit" />
-        <CommonInfoRow label="获奖金额(万元)" :value="form.awardAmount" isAmount />
-        <CommonInfoRow label="所属平台">
+        <CommonInfoRow label="获奖金额" :value="'¥' + amountUnitTransferToYuan(form.awardAmount) + '元'" isAmount />
+        <CommonInfoRow label="所属平台" isColumn>
           <view class="platform-tags">
             <template v-if="platformList.length > 0">
               <uv-tags v-for="(p, index) in platformList" :key="index" :text="p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
@@ -24,16 +25,51 @@
           </view>
         </CommonInfoRow>
         <CommonInfoRow label="所属团队" :value="form.belongTeam || '-'" />
-        <CommonInfoRow label="全部获奖完成人" :value="form.remark" isColumn />
       </CommonSection>
 
-      <!-- 附件信息 -->
-      <AttachmentList :list="mergedFileList" title="电子附件" />
+      <!-- 电子附件 -->
+      <CommonSection title="电子附件">
+        <CommonInfoRow label="获奖批文" isColumn>
+          <view class="file-links">
+            <template v-if="awardIssueAuthorityProofList.length">
+              <view class="file-item" v-for="(item, index) in awardIssueAuthorityProofList" :key="'award-proof-' + index" @click="handlePreview(item)">
+                <text class="file-link">{{ item.fileName || item.name || '-' }}</text>
+              </view>
+            </template>
+            <text v-else>-</text>
+          </view>
+        </CommonInfoRow>
+        <CommonInfoRow label="获奖证书" isColumn>
+          <view class="file-links">
+            <template v-if="awardCertificateList.length">
+              <view class="file-item" v-for="(item, index) in awardCertificateList" :key="'award-certificate-' + index" @click="handlePreview(item)">
+                <text class="file-link">{{ item.fileName || item.name || '-' }}</text>
+              </view>
+            </template>
+            <text v-else>-</text>
+          </view>
+        </CommonInfoRow>
+        <CommonInfoRow label="获奖金额证明" isColumn>
+          <view class="file-links">
+            <template v-if="awardAmountProofList.length">
+              <view class="file-item" v-for="(item, index) in awardAmountProofList" :key="'award-amount-proof-' + index" @click="handlePreview(item)">
+                <text class="file-link">{{ item.fileName || item.name || '-' }}</text>
+              </view>
+            </template>
+            <text v-else>-</text>
+          </view>
+        </CommonInfoRow>
+      </CommonSection>
 
       <!-- 审批记录 -->
       <CommonSection title="审批记录" v-if="form.id">
         <FlowTable :id="form.id" :businessCode="'奖项荣誉-' + String(form.awardCode)" defCode="sci_academic_achievement" />
       </CommonSection>
+
+      <!-- 授权审核进度 -->
+      <CommonSection title="授权审核进度" v-if="form.id">
+        <FlowTable :id="form.id" :businessCode="'奖项荣誉授权-' + String(form.awardCode)" defCode="sci_academic_achievement_reward_auth" />
+      </CommonSection>
     </template>
     <uv-empty v-else mode="data" text="暂无数据"></uv-empty>
   </view>
@@ -44,8 +80,8 @@ import { ref, onMounted, watch, computed } from 'vue';
 import { useDict } from '@/hooks/useDict';
 import { useDocumentApi } from '@/api/document';
 import { formatDate } from '@/utils/date';
+import { previewFile } from '@/utils/file';
 import to from 'await-to-js';
-import AttachmentList from './AttachmentList.vue';
 import FlowTable from '@/pages/project/components/detail/FlowTable.vue';
 import CommonSection from '@/components/ui/CommonSection.vue';
 import CommonInfoRow from '@/components/ui/CommonInfoRow.vue';
@@ -73,22 +109,27 @@ const platformList = computed(() => {
   return [];
 });
 
-const mergedFileList = computed(() => {
-  if (!form.value?.awardCertificate) return [];
+const parseFileList = (fileStr: string) => {
+  if (!fileStr) return [];
   try {
-    const list = JSON.parse(form.value.awardCertificate);
-    if (Array.isArray(list)) {
-      const types = ['获奖批文', '获奖证书', '获奖金额证明'];
-      return list.map((item, index) => ({
-        ...item,
-        fileType: types[index] || '其他附件'
-      }));
-    }
-    return [];
+    const files = JSON.parse(fileStr);
+    return Array.isArray(files) ? files : [files];
   } catch (e) {
     return [];
   }
-});
+};
+
+const awardIssueAuthorityProofList = computed(() => parseFileList(form.value?.awardIssueAuthorityProof));
+const awardCertificateList = computed(() => parseFileList(form.value?.awardCertificate));
+const awardAmountProofList = computed(() => parseFileList(form.value?.awardAmountProof));
+
+const handlePreview = (file: any) => {
+  const url = file.fileUrl || file.url;
+  const name = file.fileName || file.name;
+  if (url) {
+    previewFile(url, name);
+  }
+};
 
 const fetchData = async () => {
   if (!props.code) return;
@@ -112,6 +153,16 @@ watch(() => props.code, () => {
 const showMembers = (list: any[]) => {
   return list?.map(m => m.memberName).join(', ') || '-';
 };
+
+const amountUnitTransferToYuan = (amount: number | string) => {
+  const num = Number(amount || 0);
+  const amountInYuan = num * 10000;
+  const formattedYuan = amountInYuan.toFixed(2);
+  const parts = formattedYuan.split('.');
+  const integerPart = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
+  const decimalPart = parts[1];
+  return `${integerPart}.${decimalPart}`;
+};
 </script>
 
 <style lang="scss" scoped>
@@ -132,4 +183,16 @@ const showMembers = (list: any[]) => {
     border: 1rpx solid #e2e8f0;
   }
 }
+
+.file-links {
+  .file-item {
+    padding: 6rpx 0;
+  }
+
+  .file-link {
+    color: #2979ff;
+    text-decoration: underline;
+    word-break: break-all;
+  }
+}
 </style>

+ 11 - 10
pages/todo/components/document/AchConversionForm.vue

@@ -13,10 +13,10 @@
           <CommonInfoRow label="专利范围" :value="getDictLabel('patent_scope', form.patentScope)" />
           <CommonInfoRow label="权利人" :value="form.patentObligee" />
           <CommonInfoRow label="所属单位" :value="form.deptName" />
-          <CommonInfoRow label="所属平台">
+          <CommonInfoRow label="所属平台" isColumn>
             <view class="platform-tags">
               <template v-if="platformList.length > 0">
-                <uv-tags v-for="(item, index) in platformList" :key="index" :text="item.platformName === '其他' ? '其他' : (item.platformType ? item.platformName + ' (' + item.platformType + ')' : item.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
+                <uv-tags v-for="(p, index) in platformList" :key="index" :text="p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
               </template>
               <text v-else>-</text>
             </view>
@@ -57,10 +57,10 @@
           <CommonInfoRow label="著作权人" :value="form.applicant" />
           <CommonInfoRow label="权利取得方式" :value="getDictLabel('rights_acquire_method', form.rightsAcquireMethod)" />
           <CommonInfoRow label="所属单位" :value="form.organization" />
-          <CommonInfoRow label="所属平台">
+          <CommonInfoRow label="所属平台" isColumn>
             <view class="platform-tags">
               <template v-if="platformList.length > 0">
-                <uv-tags v-for="(item, index) in platformList" :key="index" :text="item.platformName === '其他' ? '其他' : (item.platformType ? item.platformName + ' (' + item.platformType + ')' : item.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
+                <uv-tags v-for="(p, index) in platformList" :key="index" :text="p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
               </template>
               <text v-else>-</text>
             </view>
@@ -83,10 +83,10 @@
           <CommonInfoRow label="成果类型" :value="getDictLabel('other_achieve_type', form.achievementType)" />
           <CommonInfoRow label="获得日期" :value="formatDate(form.acquireTime)" />
           <CommonInfoRow label="所属单位" :value="form.organization" />
-          <CommonInfoRow label="所属平台">
+          <CommonInfoRow label="所属平台" isColumn>
             <view class="platform-tags">
               <template v-if="platformList.length > 0">
-                <uv-tags v-for="(item, index) in platformList" :key="index" :text="item.platformName === '其他' ? '其他' : (item.platformType ? item.platformName + ' (' + item.platformType + ')' : item.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
+                <uv-tags v-for="(p, index) in platformList" :key="index" :text="p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
               </template>
               <text v-else>-</text>
             </view>
@@ -147,20 +147,21 @@ const documentApi = useDocumentApi();
 const form = ref<any>(null);
 const loading = ref(false);
 
+
 const platformList = computed(() => {
   if (form.value?.belongPlatform) {
     try {
       const data = JSON.parse(form.value.belongPlatform);
-      if (Array.isArray(data) && data.length > 0) {
-        return data;
-      }
+      return Array.isArray(data) ? data : [];
     } catch (e) {
-      return [];
+      if (form.value.belongPlatform === '其他') return [{ platformName: '其他' }];
+      return [{ platformName: form.value.belongPlatform }];
     }
   }
   return [];
 });
 
+
 const formatDictList = (dictType: string, values: any) => {
   if (!values) return '-';
   const valList = Array.isArray(values) ? values : String(values).split(',');

+ 51 - 22
pages/todo/components/document/AchDecisionForm.vue

@@ -9,16 +9,16 @@
         <CommonInfoRow label="提交日期" :value="form.submitDate ? formatDate(form.submitDate, 'YYYY-MM-DD') : '-'" />
         <CommonInfoRow label="所属单位" :value="form.belongUnit" />
         <CommonInfoRow label="所属年度" :value="form.belongYear" />
-        <CommonInfoRow label="所属平台">
+        <CommonInfoRow label="所属平台" isColumn>
           <view class="platform-tags">
             <template v-if="platformList.length > 0">
-              <uv-tags v-for="(item, index) in platformList" :key="index" :text="item.platformName === '其他' ? '其他' : (item.platformType ? item.platformName + ' (' + item.platformType + ')' : item.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
+              <uv-tags v-for="(p, index) in platformList" :key="index" :text="p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
             </template>
             <text v-else>-</text>
           </view>
         </CommonInfoRow>
         <CommonInfoRow label="所属团队" :value="form.belongTeam" />
-        <CommonInfoRow label="学校署名" :value="form.schoolSignature === '10' ? '第一单位' : form.schoolSignature === '20' ? '非第一单位' : '-'" />
+        <CommonInfoRow label="学校署名" :value="form.schoolSignature === '10' ? '第一单位' : form.schoolSignature === '20' ? '非第一单位' : form.schoolSignature" />
         <CommonInfoRow label="是否被采纳" :value="form.isAdopted === 1 ? '是' : '否'" />
         <template v-if="form.isAdopted === 1">
           <CommonInfoRow label="采纳对象" :value="getDictLabel('adopt_subject', form.adoptTarget)" />
@@ -29,14 +29,22 @@
           <CommonInfoRow label="批示人姓名" :value="form.instructionPersonName" />
           <CommonInfoRow label="批示领导级别" :value="getDictLabel('leader_level', form.instructionLeaderLevel)" />
           <CommonInfoRow label="批示人职务" :value="form.instructionPersonPosition" />
-          <CommonInfoRow label="批示主要内容" :value="form.instructionContent" isColumn />
         </template>
-        <CommonInfoRow label="总字数" :value="(form.wordCount || '0') + ' 万字'" />
+        <CommonInfoRow label="总字数" :value="(form.wordCount || '0') + '万字'" />
+        <CommonInfoRow label="报告电子版" isColumn>
+          <view class="file-links">
+            <view v-if="reportFile" class="file-item" @click="handlePreview(reportFile)">
+              <text class="file-link">{{ reportFile.fileName || '-' }}</text>
+            </view>
+            <text v-else>-</text>
+          </view>
+        </CommonInfoRow>
+        <CommonInfoRow v-if="form.isInstruction === 1" label="批示主要内容" :value="form.instructionContent" isColumn />
         <CommonInfoRow label="备注" :value="form.remark" isColumn />
       </CommonSection>
 
       <!-- 完成人列表 -->
-      <CommonSection title="完成人列表" v-if="form.memberList?.length">
+      <CommonSection title="完成人列表" >
         <view class="member-list">
           <view class="member-item" v-for="(member, index) in form.memberList" :key="index">
             <view class="member-header">
@@ -61,8 +69,8 @@
       </CommonSection>
 
       <!-- 关联项目列表 -->
-      <CommonSection title="关联项目列表" v-if="form.projectList?.length">
-        <view class="funds-list">
+      <CommonSection title="关联项目列表">
+        <view class="funds-list" v-if="form.projectList?.length">
           <view class="funds-item" v-for="(project, index) in form.projectList" :key="index">
             <view class="f-row">
               <text class="f-name">{{ project.projectName }}</text>
@@ -82,6 +90,7 @@
             </view>
           </view>
         </view>
+        <uv-empty v-else mode="data" text="暂无数据"></uv-empty>
       </CommonSection>
 
       <!-- 附件信息 -->
@@ -100,6 +109,7 @@
 import { ref, onMounted, watch, computed } from 'vue';
 import { useDict } from '@/hooks/useDict';
 import { formatDate } from '@/utils/date';
+import { previewFile } from '@/utils/file';
 import AttachmentList from './AttachmentList.vue';
 import FlowTable from '@/pages/project/components/detail/FlowTable.vue';
 import CommonSection from '@/components/ui/CommonSection.vue';
@@ -120,11 +130,10 @@ const platformList = computed(() => {
   if (form.value?.belongPlatform) {
     try {
       const data = JSON.parse(form.value.belongPlatform);
-      if (Array.isArray(data) && data.length > 0) {
-        return data;
-      }
+      return Array.isArray(data) ? data : [];
     } catch (e) {
-      return [];
+      if (form.value.belongPlatform === '其他') return [{ platformName: '其他' }];
+      return [{ platformName: form.value.belongPlatform }];
     }
   }
   return [];
@@ -133,16 +142,7 @@ const platformList = computed(() => {
 const mergedFileList = computed(() => {
   if (!form.value) return [];
   const list: any[] = [];
-  
-  // 报告电子版
-  if (form.value.reportFileUrl) {
-    list.push({
-      fileName: form.value.reportFileName || '报告电子版',
-      fileUrl: form.value.reportFileUrl,
-      fileType: '报告电子版'
-    });
-  }
-  
+
   // 其他附件
   if (form.value.fileList?.length) {
     form.value.fileList.forEach((f: any) => {
@@ -157,6 +157,24 @@ const mergedFileList = computed(() => {
   return list;
 });
 
+const reportFile = computed(() => {
+  if (form.value?.reportFileUrl) {
+    return {
+      fileName: form.value.reportFileName || '查看附件',
+      fileUrl: form.value.reportFileUrl
+    };
+  }
+  return null;
+});
+
+const handlePreview = (file: any) => {
+  const url = file.fileUrl || file.url;
+  const name = file.fileName || file.name;
+  if (url) {
+    previewFile(url, name);
+  }
+};
+
 const getProjectType = (type: string) => {
   const map: any = { '10': '纵向', '20': '横向', '30': '内部' };
   return map[type] || type;
@@ -193,5 +211,16 @@ watch(() => props.code, () => {
 <style lang="scss" scoped>
 @import "./common.scss";
 
+.file-links {
+  .file-item {
+    padding: 6rpx 0;
+  }
+
+  .file-link {
+    color: #2979ff;
+    text-decoration: underline;
+    word-break: break-all;
+  }
+}
 
 </style>

+ 2 - 4
pages/todo/components/document/AchEvaluationForm.vue

@@ -15,12 +15,10 @@
         <CommonInfoRow label="所属年份" :value="form.belongYear" />
         <CommonInfoRow label="学校署名" :value="form.schoolSigned === '10' ? '第一单位' : '非第一单位'" />
         <CommonInfoRow label="完成单位" :value="form.completeDeptName" />
-        <CommonInfoRow label="所属平台">
+        <CommonInfoRow label="所属平台" isColumn>
           <view class="platform-tags">
             <template v-if="platformList.length > 0">
-              <text v-for="(p, index) in platformList" :key="index" class="platform-tag">
-                {{ p.platformName }}
-              </text>
+              <uv-tags v-for="(p, index) in platformList" :key="index" :text="p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
             </template>
             <text v-else>-</text>
           </view>

+ 95 - 25
pages/todo/components/document/AchPaperForm.vue

@@ -6,25 +6,34 @@
       <CommonSection title="基本信息" :isFirst="true">
         <CommonInfoRow label="题目" :value="form.paperName" />
         <CommonInfoRow label="学科类型" :value="getDictLabel('project_class', form.disciplineFirstName)" />
-        <CommonInfoRow label="论文类型" :value="getDictLabel('sci_paper_type', form.paperType)" />
+        <CommonInfoRow label="论文类型" :value="form.paperType" />
         <CommonInfoRow label="论文类别" :value="getDictLabel('paper_category', form.paperCategory)" />
         <CommonInfoRow label="发表/出版时间" :value="formatDate(form.publicationDate)" />
         <CommonInfoRow label="刊名" :value="form.publicationName" />
         <CommonInfoRow label="期刊类型" :value="form.periodicalType || '-'" />
+        <CommonInfoRow v-if="isConferenceType" label="会议名称" :value="form.conferenceName || '-'" />
+        <CommonInfoRow v-if="isConferenceType" label="会议地址" :value="form.conferenceAddress || '-'" />
         <template v-if="form.periodicalType?.toLowerCase() === 'sci'">
           <CommonInfoRow label="中科院分区" :value="getDictLabel('sci_paper_subTreasury', form.subTreasury)" />
           <CommonInfoRow label="IF" :value="form.impactFactors" />
         </template>
-        <CommonInfoRow label="DOI号/PMID" :value="form.doi" />
-        <CommonInfoRow label="所属年份" :value="form.statisticalYear" />
-        <CommonInfoRow label="年/卷/期/页" :value="(form.yearNum || '') + '/' + (form.volNum || '') + '/' + (form.issueNum || '')" />
-        <CommonInfoRow label="页码" :value="form.pageRange || '-'" />
+        <CommonInfoRow label="论文DOI号/PMID((PubMed标识码)" :isColumn="true" :value="form.doi" />
+        <CommonInfoRow label="所属年份" :value="form.statisticalYear ? formatDate(form.statisticalYear, 'YYYY') : '-'" />
+        <CommonInfoRow label="年、卷(期)" :value="`${form.yearNum || ''}、${form.volNum || ''}(${form.issueNum || ''})`" />
+        <CommonInfoRow v-if="form.pageRange" label="页码" :value="form.pageRange" />
         <CommonInfoRow label="本院署名" :value="getDictLabel('sci_paper_signType', form.signType)" />
         <CommonInfoRow label="ISSN号" :value="form.issnNum" />
-        <CommonInfoRow label="所属平台" :value="platformText" />
-        <CommonInfoRow label="所属团队" :value="form.belongTeam || '-'" />
         <CommonInfoRow label="合作单位" :value="form.partnerOrg || '-'" />
         <CommonInfoRow label="单位类型" :value="getDictLabel('partner_org_type', form.partnerOrgType)" />
+        <CommonInfoRow label="所属平台" isColumn>
+          <view class="platform-tags">
+            <template v-if="platformList.length > 0">
+              <uv-tags v-for="(p, index) in platformList" :key="index" :text="p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
+            </template>
+            <text v-else>-</text>
+          </view>
+        </CommonInfoRow>
+        <CommonInfoRow label="所属团队" :value="form.belongTeam || '-'" />
       </CommonSection>
 
       <!-- 作者信息 -->
@@ -51,8 +60,8 @@
         </view>
       </CommonSection>
 
-      <!-- 标注经济来源 -->
-      <CommonSection title="标注经济来源" v-if="form.projList?.length">
+      <!-- 关联项目 -->
+      <CommonSection title="关联项目" v-if="form.projList?.length">
         <view class="achievement-card" v-for="(item, index) in form.projList" :key="index">
           <view class="a-row">
             <text class="al">关联类型:</text>
@@ -66,7 +75,49 @@
       </CommonSection>
 
       <!-- 电子附件 -->
-      <AttachmentList :list="mergedFileList" title="电子附件" />
+      <CommonSection title="电子附件">
+        <CommonInfoRow label="论文全文" isColumn>
+          <view class="file-hint">附件说明:SCI上传文章;中文期刊上传封面、目录及文章</view>
+          <view class="file-links">
+            <template v-if="paperResultList.length">
+              <view class="file-item" v-for="(item, index) in paperResultList" :key="'paper-full-' + index" @click="handlePreview(item)">
+                <text class="file-link">{{ item.fileName || item.name || '-' }}</text>
+              </view>
+            </template>
+            <text v-else>-</text>
+          </view>
+        </CommonInfoRow>
+        <CommonInfoRow label="收录证明" isColumn>
+          <view class="file-links">
+            <template v-if="includedProofList.length">
+              <view class="file-item" v-for="(item, index) in includedProofList" :key="'paper-included-' + index" @click="handlePreview(item)">
+                <text class="file-link">{{ item.fileName || item.name || '-' }}</text>
+              </view>
+            </template>
+            <text v-else>-</text>
+          </view>
+        </CommonInfoRow>
+        <CommonInfoRow label="伦理批件" isColumn>
+          <view class="file-links">
+            <template v-if="ethicsApprovalList.length">
+              <view class="file-item" v-for="(item, index) in ethicsApprovalList" :key="'paper-ethics-' + index" @click="handlePreview(item)">
+                <text class="file-link">{{ item.fileName || item.name || '-' }}</text>
+              </view>
+            </template>
+            <text v-else>-</text>
+          </view>
+        </CommonInfoRow>
+        <CommonInfoRow label="原始数据" isColumn>
+          <view class="file-links">
+            <template v-if="rawDataList.length">
+              <view class="file-item" v-for="(item, index) in rawDataList" :key="'paper-raw-' + index" @click="handlePreview(item)">
+                <text class="file-link">{{ item.fileName || item.name || '-' }}</text>
+              </view>
+            </template>
+            <text v-else>-</text>
+          </view>
+        </CommonInfoRow>
+      </CommonSection>
 
       <!-- 审批信息 -->
       <CommonSection title="审批信息" v-if="form.id">
@@ -82,8 +133,8 @@ import { ref, onMounted, watch, computed } from 'vue';
 import { useDict } from '@/hooks/useDict';
 import { useDocumentApi } from '@/api/document';
 import { formatDate } from '@/utils/date';
+import { previewFile } from '@/utils/file';
 import to from 'await-to-js';
-import AttachmentList from './AttachmentList.vue';
 import FlowTable from '@/pages/project/components/detail/FlowTable.vue';
 import CommonSection from '@/components/ui/CommonSection.vue';
 import CommonInfoRow from '@/components/ui/CommonInfoRow.vue';
@@ -121,23 +172,24 @@ const platformList = computed(() => {
   return [];
 });
 
-const platformText = computed(() => {
-  if (platformList.value.length === 0) return '-';
-  return platformList.value
-    .map(p => p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName))
-    .join('、');
-});
+const paperResultList = computed(() => form.value?.paperResultList || []);
+const includedProofList = computed(() => form.value?.includedProofList || []);
+const ethicsApprovalList = computed(() => form.value?.ethicsApprovalList || []);
+const rawDataList = computed(() => form.value?.rawDataList || []);
 
-const mergedFileList = computed(() => {
-  if (!form.value) return [];
-  const list: any[] = [];
-  if (form.value.paperResultList) list.push(...form.value.paperResultList.map((item: any) => ({ ...item, fileType: '论文全文' })));
-  if (form.value.includedProofList) list.push(...form.value.includedProofList.map((item: any) => ({ ...item, fileType: '收录证明' })));
-  if (form.value.ethicsApprovalList) list.push(...form.value.ethicsApprovalList.map((item: any) => ({ ...item, fileType: '伦理批件' })));
-  if (form.value.rawDataList) list.push(...form.value.rawDataList.map((item: any) => ({ ...item, fileType: '原始数据' })));
-  return list;
+const isConferenceType = computed(() => {
+  const paperType = String(form.value?.paperType || '');
+  return paperType.includes('会议');
 });
 
+const handlePreview = (file: any) => {
+  const url = file.fileUrl || file.url;
+  const name = file.fileName || file.name;
+  if (url) {
+    previewFile(url, name);
+  }
+};
+
 const fetchData = async () => {
   if (!props.code) return;
   loading.value = true;
@@ -224,4 +276,22 @@ watch(() => props.code, () => {
     .v { color: #343a3f; }
   }
 }
+
+.file-hint {
+  font-size: 22rpx;
+  color: #ef4444;
+  margin-bottom: 8rpx;
+}
+
+.file-links {
+  .file-item {
+    padding: 6rpx 0;
+  }
+
+  .file-link {
+    color: #2979ff;
+    text-decoration: underline;
+    word-break: break-all;
+  }
+}
 </style>

+ 2 - 4
pages/todo/components/document/AchPatentAuthForm.vue

@@ -31,12 +31,10 @@
         <CommonInfoRow label="是否职务专利" :value="form.patentOffice === '10' ? '是' : '否'" />
         <CommonInfoRow label="是否为PCT专利" :value="form.patentCt === '10' ? '是' : '否'" />
 
-        <CommonInfoRow label="所属平台">
+        <CommonInfoRow label="所属平台" isColumn>
           <view class="platform-tags">
             <template v-if="platformList.length > 0">
-              <text v-for="(p, index) in platformList" :key="index" class="platform-tag">
-                {{ p.platformName }}
-              </text>
+              <uv-tags v-for="(p, index) in platformList" :key="index" :text="p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
             </template>
             <text v-else>-</text>
           </view>

+ 85 - 51
pages/todo/components/document/AchPatentForm.vue

@@ -5,8 +5,8 @@
       <!-- 基本信息 -->
       <CommonSection title="基本信息" :isFirst="true">
         <CommonInfoRow label="专利名称" :value="form.patentName" />
-        <CommonInfoRow label="所属科室" :value="form.deptName" />
-        <!-- <CommonInfoRow label="代理公司" :value="form.companyName" /> -->
+        <CommonInfoRow label="所属部门" :value="form.deptName" />
+        <CommonInfoRow label="代理公司" :value="form.companyName" />
         <CommonInfoRow label="专利类型" :value="getDictLabel('sci_patent_class', form.patentClass)" />
         <CommonInfoRow label="专利范围" :value="getDictLabel('sci_patent_scope', form.patentScope)" />
         <CommonInfoRow label="专利状态" :value="getDictLabel('sci_patent_condition', form.patentCondition)" />
@@ -25,16 +25,9 @@
         <CommonInfoRow label="专利代理机构" :value="form.entrustUnit" />
         <CommonInfoRow label="代理人" :value="form.agencyUserName" />
         <CommonInfoRow label="代理人联系电话" :value="form.agencyPhone" />
-        <CommonInfoRow label="专利文献出版日" :value="formatDate(form.publicationDate)" />
-        <CommonInfoRow label="所属年份" :value="form.patentYeat" />
-        <CommonInfoRow label="是否失效" :value="form.patentEffectiveness === '10' ? '是' : '否'" />
-        <CommonInfoRow label="合作类型" :value="getDictLabel('sci_cooperation', form.patentCooperation)" />
-        <CommonInfoRow label="是否职务专利" :value="form.patentOffice === '10' ? '是' : '否'" />
-        <CommonInfoRow label="是否为PCT专利" :value="form.patentCt === '10' ? '是' : '否'" />
-        <CommonInfoRow label="成果权属" :value="getDictLabel('achievement_owner_unit', form.achievementOwnerUnit)
-          " />
+        <CommonInfoRow label="所属年份" :value="form.patentYeat ? formatDate(form.patentYeat, 'YYYY') : '-'" />
 
-        <CommonInfoRow label="所属平台">
+        <CommonInfoRow label="所属平台" isColumn>
           <view class="platform-tags">
             <template v-if="platformList.length > 0">
               <uv-tags v-for="(p, index) in platformList" :key="index" :text="p.platformName === '其他'
@@ -48,23 +41,52 @@
           </view>
         </CommonInfoRow>
         <CommonInfoRow label="所属团队" :value="form.belongTeam || '-'" />
-
-        <!-- 专利转化特有字段 -->
-        <template v-if="code.includes('专利转化')">
-          <CommonInfoRow label="转化时间" :value="formatDate(form.invertTime)" />
-          <CommonInfoRow label="转化金额" :value="(form.invertAmount || '0') + ' 元'" isAmount />
-          <CommonInfoRow label="转化单位" :value="form.invertUnit" />
-          <CommonInfoRow label="知识产权交易类型" :value="form.tradeType === '10'
-            ? '转让'
-            : form.tradeType === '20'
-              ? '许可'
-              : '-'
-            " />
-        </template>
+        <CommonInfoRow label="成果权属" :value="getDictLabel('achievement_owner_unit', form.achievementOwnerUnit)" />
+        <CommonInfoRow label="是否失效" :value="form.patentEffectiveness === '10' ? '是' : form.patentEffectiveness === '20' ? '否' : '-'" />
+        <CommonInfoRow label="是否职务专利" :value="form.patentOffice === '10' ? '是' : form.patentOffice === '20' ? '否' : '-'" />
+        <CommonInfoRow label="是否为PCT专利" :value="form.patentCt === '10' ? '是' : form.patentCt === '20' ? '否' : '-'" />
+        <CommonInfoRow label="专利附件" isColumn>
+          <view class="file-links">
+            <template v-if="patentFileList.length">
+              <view class="file-item" v-for="(item, index) in patentFileList" :key="'patent-' + index" @click="handlePreview(item)">
+                <text class="file-link">{{ item.name || item.fileName || '-' }}</text>
+              </view>
+            </template>
+            <text v-else>-</text>
+          </view>
+        </CommonInfoRow>
+        <CommonInfoRow label="专利委托合同附件" isColumn>
+          <view class="file-links">
+            <template v-if="agencyContractFileList.length">
+              <view class="file-item" v-for="(item, index) in agencyContractFileList" :key="'agency-' + index" @click="handlePreview(item)">
+                <text class="file-link">{{ item.name || item.fileName || '-' }}</text>
+              </view>
+            </template>
+            <text v-else>-</text>
+          </view>
+        </CommonInfoRow>
 
         <CommonInfoRow label="专利简介" :value="form.patentDesc" isColumn />
       </CommonSection>
 
+      <!-- 转化信息 -->
+      <CommonSection title="转化信息" v-if="['60', '70', '80'].includes(form.patentStatus)">
+        <CommonInfoRow label="转化时间" :value="formatDate(form.invertTime)" />
+        <CommonInfoRow label="转化金额" :value="form.invertAmount || '-'" isAmount />
+        <CommonInfoRow label="转化单位" :value="form.invertUnit || '-'" />
+        <CommonInfoRow label="知识产权交易类型" :value="form.tradeType === '10' ? '转让' : form.tradeType === '20' ? '许可' : '-'" />
+        <CommonInfoRow label="转化附件" isColumn>
+          <view class="file-links">
+            <template v-if="invertFileList.length">
+              <view class="file-item" v-for="(item, index) in invertFileList" :key="'invert-' + index" @click="handlePreview(item)">
+                <text class="file-link">{{ item.name || item.fileName || '-' }}</text>
+              </view>
+            </template>
+            <text v-else>-</text>
+          </view>
+        </CommonInfoRow>
+      </CommonSection>
+
       <!-- 发明(设计)人信息 -->
       <CommonSection title="发明(设计)人信息" v-if="form.memberList?.length">
         <view class="member-list">
@@ -107,9 +129,6 @@
         </view>
       </CommonSection>
 
-      <!-- 附件信息 -->
-      <AttachmentList :list="mergedFileList" title="相关附件" />
-
       <!-- 标注经济来源 -->
       <CommonSection title="标注经济来源" v-if="form.projList?.length">
         <view class="achievement-card" v-for="(row, index) in form.projList" :key="index">
@@ -127,12 +146,17 @@
       </CommonSection>
 
       <!-- 审批信息 -->
-      <CommonSection title="审批信息" v-if="form.id">
+      <CommonSection title="审批信息">
         <FlowTable :id="form.id" :businessCode="'学术专利-' + form.patentCode" defCode="sci_academic_achievement" />
       </CommonSection>
 
+       <!-- 授权审核进度 -->
+       <CommonSection title="授权审核进度">
+        <FlowTable :id="form.id" :businessCode="'学术专利授权-' + form.patentCode" defCode="sci_academic_achievement_auth" />
+      </CommonSection>
+
       <!-- 转化审批信息 -->
-      <CommonSection title="转化审批信息" v-if="form.id && code.includes('专利转化')">
+      <CommonSection title="转化审批信息">
         <FlowTable :id="form.id" :businessCode="'专利转化-' + form.patentCode" defCode="sci_academic_achievement" />
       </CommonSection>
     </template>
@@ -145,8 +169,8 @@ import { ref, onMounted, watch, computed } from "vue";
 import { useDict } from "@/hooks/useDict";
 import { useDocumentApi } from "@/api/document";
 import { formatDate } from "@/utils/date";
+import { previewFile } from "@/utils/file";
 import to from "await-to-js";
-import AttachmentList from "./AttachmentList.vue";
 import FlowTable from "@/pages/project/components/detail/FlowTable.vue";
 import CommonSection from "@/components/ui/CommonSection.vue";
 import CommonInfoRow from "@/components/ui/CommonInfoRow.vue";
@@ -186,29 +210,27 @@ const platformList = computed(() => {
   return [];
 });
 
-const mergedFileList = computed(() => {
-  if (!form.value) return [];
-  const list: any[] = [];
-  if (form.value.patentFile) {
-    try {
-      const file = JSON.parse(form.value.patentFile);
-      list.push({ ...file, fileType: "专利附件" });
-    } catch (e) { }
+const parseFileList = (fileStr: string) => {
+  if (!fileStr) return [];
+  try {
+    const files = JSON.parse(fileStr);
+    return Array.isArray(files) ? files : [files];
+  } catch (e) {
+    return [];
   }
-  if (form.value.agencyContractFile) {
-    try {
-      const file = JSON.parse(form.value.agencyContractFile);
-      list.push({ ...file, fileType: "委托合同" });
-    } catch (e) { }
-  }
-  if (form.value.invertUrl) {
-    try {
-      const file = JSON.parse(form.value.invertUrl);
-      list.push({ ...file, fileType: "转化附件" });
-    } catch (e) { }
+};
+
+const patentFileList = computed(() => parseFileList(form.value?.patentFile));
+const agencyContractFileList = computed(() => parseFileList(form.value?.agencyContractFile));
+const invertFileList = computed(() => parseFileList(form.value?.invertUrl));
+
+const handlePreview = (file: any) => {
+  const url = file.fileUrl || file.url;
+  const name = file.fileName || file.name;
+  if (url) {
+    previewFile(url, name);
   }
-  return list;
-});
+};
 
 const fetchData = async () => {
   if (!props.code) return;
@@ -380,4 +402,16 @@ const getMemberBadgeType = (type: string) => {
     }
   }
 }
+
+.file-links {
+  .file-item {
+    padding: 6rpx 0;
+  }
+
+  .file-link {
+    color: #2979ff;
+    text-decoration: underline;
+    word-break: break-all;
+  }
+}
 </style>

+ 55 - 13
pages/todo/components/document/AchWorkForm.vue

@@ -3,7 +3,7 @@
     <uv-loading-icon
       v-if="loading"
       mode="circle"
-      text="正在加载著作详情..."
+      text="正在加载学术著作详情..."
     ></uv-loading-icon>
     <template v-else-if="form">
       <!-- 基本信息 -->
@@ -24,10 +24,17 @@
           label="出版时间"
           :value="formatDate(form.workPublicationDate)"
         />
-        <CommonInfoRow label="所属科室" :value="form.deptName" />
+        <CommonInfoRow label="所属部门" :value="form.deptName" />
         <CommonInfoRow label="CIP号" :value="form.cip" />
         <CommonInfoRow label="字数" :value="form.wordsNum" />
-        <CommonInfoRow label="所属年份" :value="form.statisticalYear" />
+        <CommonInfoRow
+          label="所属年份"
+          :value="
+            form.statisticalYear
+              ? formatDate(form.statisticalYear, 'YYYY')
+              : '-'
+          "
+        />
         <CommonInfoRow
           label="是否国家规范化教材"
           :value="form.isStandard === '10' ? '是' : '否'"
@@ -36,7 +43,24 @@
           label="是否翻译著作"
           :value="form.isTranslation === '10' ? '是' : '否'"
         />
-        <CommonInfoRow label="所属平台">
+        <CommonInfoRow label="著作附件(封面和版权页)" isColumn>
+          <view class="file-links">
+            <template v-if="workFileList.length > 0">
+              <view
+                class="file-item"
+                v-for="(item, index) in workFileList"
+                :key="'work-file-' + index"
+                @click="handlePreview(item)"
+              >
+                <text class="file-link">{{
+                  item.fileName || item.name || "-"
+                }}</text>
+              </view>
+            </template>
+            <text v-else>-</text>
+          </view>
+        </CommonInfoRow>
+        <CommonInfoRow label="所属平台" isColumn>
           <view class="platform-tags">
             <template v-if="platformList.length > 0">
               <uv-tags
@@ -58,10 +82,11 @@
             <text v-else>-</text>
           </view>
         </CommonInfoRow>
+        <CommonInfoRow label="所属团队" :value="form.belongTeam || '-'" />
       </CommonSection>
 
-      <!-- 标注经济来源 -->
-      <CommonSection title="标注经济来源" v-if="form.projList?.length">
+      <!-- 关联项目 -->
+      <CommonSection title="关联项目" v-if="form.projList?.length">
         <view
           class="achievement-card"
           v-for="(row, index) in form.projList"
@@ -109,9 +134,6 @@
         </view>
       </CommonSection>
 
-      <!-- 附件 -->
-      <AttachmentList :list="mergedFileList" title="著作附件(封面和版权页)" />
-
       <!-- 审批记录 -->
       <CommonSection title="审批记录" v-if="form.id">
         <FlowTable
@@ -130,8 +152,8 @@ import { ref, onMounted, watch, computed } from "vue";
 import { useDict } from "@/hooks/useDict";
 import { useDocumentApi } from "@/api/document";
 import { formatDate } from "@/utils/date";
+import { previewFile } from "@/utils/file";
 import to from "await-to-js";
-import AttachmentList from "./AttachmentList.vue";
 import FlowTable from "@/pages/project/components/detail/FlowTable.vue";
 import CommonSection from "@/components/ui/CommonSection.vue";
 import CommonInfoRow from "@/components/ui/CommonInfoRow.vue";
@@ -164,16 +186,24 @@ const platformList = computed(() => {
   return [];
 });
 
-const mergedFileList = computed(() => {
+const workFileList = computed(() => {
   if (!form.value?.workFile) return [];
   try {
-    const file = JSON.parse(form.value.workFile);
-    return [{ ...file, fileType: "著作附件" }];
+    const files = JSON.parse(form.value.workFile);
+    return Array.isArray(files) ? files : [files];
   } catch (e) {
     return [];
   }
 });
 
+const handlePreview = (file: any) => {
+  const url = file.fileUrl || file.url;
+  const name = file.fileName || file.name;
+  if (url) {
+    previewFile(url, name);
+  }
+};
+
 const fetchData = async () => {
   if (!props.code) return;
   loading.value = true;
@@ -212,4 +242,16 @@ watch(
   flex: 1;
   align-items: center;
 }
+
+.file-links {
+  .file-item {
+    padding: 6rpx 0;
+  }
+
+  .file-link {
+    color: #2979ff;
+    text-decoration: underline;
+    word-break: break-all;
+  }
+}
 </style>

+ 21 - 12
pages/todo/components/document/ConferenceForm.vue

@@ -1,24 +1,25 @@
 <template>
   <view class="document-form">
-    <uv-loading-icon v-if="loading" mode="circle" text="正在加载会议详情..."></uv-loading-icon>
+    <uv-loading-icon v-if="loading" mode="circle" text="正在加载学术会议详情..."></uv-loading-icon>
     <template v-else-if="form">
       <!-- 基本信息 -->
       <CommonSection title="基本信息" :isFirst="true">
         <CommonInfoRow label="会议名称" :value="form.codTitle" />
         <CommonInfoRow label="会议类型" :value="getLecTypeLabel(form.codType)" />
         <CommonInfoRow label="主办单位" :value="form.codOrganizer" />
-        <CommonInfoRow label="会议日期" :value="formatDate(form.codStartTime) + '' + formatDate(form.codEndTime)" />
+        <CommonInfoRow label="会议日期" :value="formatDate(form.codStartTime) + '~~' + formatDate(form.codEndTime)" />
         <CommonInfoRow label="主讲人" :value="form.applicantName" />
         <CommonInfoRow label="会议地址" :value="form.codAddress" />
-        <CommonInfoRow label="所属平台">
+        <CommonInfoRow label="所属平台" isColumn>
           <view class="platform-tags">
             <template v-if="platformList.length > 0">
-              <uv-tags v-for="(item, index) in platformList" :key="index" :text="item.platformName === '其他' ? '其他' : (item.platformType ? item.platformName + ' (' + item.platformType + ')' : item.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
+              <uv-tags v-for="(p, index) in platformList" :key="index" :text="p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
             </template>
             <text v-else>-</text>
           </view>
         </CommonInfoRow>
-        <CommonInfoRow label="所属团队" :value="form.belongTeam || '-'" />
+        <CommonInfoRow label="所属团队" :value="form.belongTeam || '-'" isColumn />
+        <CommonInfoRow label="审批状态" :value="getApprovalStatusLabel(form.approvalStatus)" />
         <CommonInfoRow label="会议简介" :value="form.codBriefInfo" isColumn />
       </CommonSection>
 
@@ -34,8 +35,8 @@
       <!-- 相关附件 -->
       <AttachmentList :list="uploadList" title="相关附件" />
 
-      <!-- 审批记录 -->
-      <CommonSection title="审批记录" v-if="form.id">
+      <!-- 审批信息 -->
+      <CommonSection title="审批信息" v-if="form.id">
         <FlowTable :id="form.id" :businessCode="String(form.id)" defCode="sci_academic_conferences" />
       </CommonSection>
     </template>
@@ -48,7 +49,6 @@ import { ref, onMounted, watch, computed } from 'vue';
 import { useDict } from '@/hooks/useDict';
 import { useDocumentApi } from '@/api/document';
 import { formatDate } from '@/utils/date';
-import { previewFile } from '@/utils/file';
 import to from 'await-to-js';
 import AttachmentList from './AttachmentList.vue';
 import FlowTable from '@/pages/project/components/detail/FlowTable.vue';
@@ -78,15 +78,24 @@ const getLecTypeLabel = (value: string | number) => {
   return item ? item.label : (value || '-');
 };
 
+const getApprovalStatusLabel = (status: string | number) => {
+  const map: Record<string, string> = {
+    '10': '待提交',
+    '20': '审批中',
+    '30': '审批通过',
+    '40': '审批退回'
+  };
+  return map[String(status)] || '-';
+};
+
 const platformList = computed(() => {
   if (form.value?.belongPlatform) {
     try {
       const data = JSON.parse(form.value.belongPlatform);
-      if (Array.isArray(data) && data.length > 0) {
-        return data;
-      }
+      return Array.isArray(data) ? data : [];
     } catch (e) {
-      return [];
+      if (form.value.belongPlatform === '其他') return [{ platformName: '其他' }];
+      return [{ platformName: form.value.belongPlatform }];
     }
   }
   return [];

+ 1 - 1
pages/todo/components/document/HorizontalForm.vue

@@ -13,7 +13,7 @@
         <CommonInfoRow label="签订日期" :value="formatDate(form.signDate)" />
         <CommonInfoRow label="执行期" :value="formatDateRange(form.planStartDate, form.planEndDate)" />
         <CommonInfoRow label="统计年度" :value="form.statisticalYear" />
-        <CommonInfoRow label="所属平台">
+        <CommonInfoRow label="所属平台" isColumn>
           <view class="platform-tags">
             <template v-if="platformList.length > 0">
               <uv-tags v-for="(p, index) in platformList" :key="index" :text="p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>

+ 2 - 4
pages/todo/components/document/PlanListForm.vue

@@ -14,12 +14,10 @@
         <CommonInfoRow label="项目负责人" :value="state.form.projectLeaderName" />
         <CommonInfoRow label="负责人电话" :value="state.form.projectLeaderPhone || '-'" />
         <CommonInfoRow label="负责人邮箱" :value="state.form.projectLeaderMail || '-'" />
-        <CommonInfoRow label="所属平台">
+        <CommonInfoRow label="所属平台" isColumn>
           <view class="platform-tags">
             <template v-if="platformList.length > 0">
-              <text v-for="(p, index) in platformList" :key="index" class="platform-tag">
-                {{ p.platformName }}
-              </text>
+              <uv-tags v-for="(p, index) in platformList" :key="index" :text="p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
             </template>
             <text v-else>-</text>
           </view>

+ 37 - 50
pages/todo/components/document/SafetyForm.vue

@@ -3,56 +3,42 @@
     <uv-loading-icon v-if="loading" mode="circle" text="正在加载安评项目详情..."></uv-loading-icon>
     <template v-else-if="form">
       <!-- 基本信息 -->
-      <view class="common-section-card">
-        <view class="section-title">基本信息</view>
-        <view class="info-row"><text class="label">项目编号</text><text class="value">{{ form.projectCode || '-' }}</text></view>
-        <view class="info-row"><text class="label">项目名称</text><text class="value">{{ form.projectName || '-' }}</text></view>
-        <view class="info-row">
-          <text class="label">学科分类</text>
-          <text class="value">{{ getDictLabel('project_class', form.disciplineFirstName) }}</text>
-        </view>
-        <view class="info-row">
-          <text class="label">负责人类型</text>
-          <text class="value">{{ form.projectLeaderType === '10' ? '教师' : form.projectLeaderType === '20' ? '学生' : '校外人员' }}</text>
-        </view>
-        <view class="info-row"><text class="label">负责人</text><text class="value">{{ form.projectLeaderName || '-' }}</text></view>
-        <view class="info-row">
-          <text class="label">合同类别</text>
-          <text class="value">{{ getDictLabel('contract_type', form.contractType) }}</text>
-        </view>
-        <view class="info-row"><text class="label">统计年度</text><text class="value">{{ form.statisticalYear || '-' }}</text></view>
-        <view class="info-row"><text class="label">签订时间</text><text class="value">{{ formatDate(form.signDate) }}</text></view>
-        <view class="info-row"><text class="label">项目时间</text><text class="value">{{ formatDate(form.planStartDate) }} 至 {{ formatDate(form.planEndDate) }}</text></view>
-        
-        <view class="info-row">
-          <text class="label">合同经费(元)</text>
-          <text class="value num-color">¥{{ formatAmount(form.contractFunds) }}</text>
-        </view>
-        <view class="info-row">
-          <text class="label">配套经费(元)</text>
-          <text class="value num-color">¥{{ formatAmount(form.supportFunds) }}</text>
-        </view>
-        <view class="info-row">
-          <text class="label">到账金额(元)</text>
-          <text class="value primary-color">¥{{ formatAmount(form.arrivalFunds) }}</text>
-        </view>
-        <view class="info-row"><text class="label">到账时间</text><text class="value">{{ formatDate(form.arrivalDate) }}</text></view>
-        
-        <view class="info-row">
-          <text class="label">所属平台</text>
+      <CommonSection title="基本信息" :isFirst="true">
+        <CommonInfoRow label="项目编号" :value="form.projectCode || '-'" />
+        <CommonInfoRow label="项目名称" :value="form.projectName || '-'" />
+        <CommonInfoRow label="学科分类" :value="getDictLabel('project_class', form.disciplineFirstName) || '-'" />
+        <CommonInfoRow label="负责人类型" :value="form.projectLeaderType === '10' ? '教师' : form.projectLeaderType === '20' ? '学生' : '校外人员'" />
+        <CommonInfoRow label="负责人" :value="form.projectLeaderName || '-'" />
+        <CommonInfoRow label="合同类别" :value="getDictLabel('contract_type', form.contractType) || '-'" />
+        <CommonInfoRow label="统计年度" :value="form.statisticalYear || '-'" />
+        <CommonInfoRow label="签订时间" :value="formatDate(form.signDate)" />
+        <CommonInfoRow label="项目时间" :value="`${formatDate(form.planStartDate)} 至 ${formatDate(form.planEndDate)}`" />
+
+        <CommonInfoRow label="合同经费(元)" :value="`¥${formatAmount(form.contractFunds)}`" isAmount />
+        <CommonInfoRow label="配套经费(元)" :value="`¥${formatAmount(form.supportFunds)}`" isAmount />
+        <CommonInfoRow label="到账金额(元)" :value="`¥${formatAmount(form.arrivalFunds)}`" isAmount />
+        <CommonInfoRow label="到账时间" :value="formatDate(form.arrivalDate)" />
+
+        <CommonInfoRow label="所属平台" isColumn>
           <view class="platform-tags">
             <template v-if="platformList.length > 0">
-              <uv-tags v-for="(item, index) in platformList" :key="index" :text="item.platformName === '其他' ? '其他' : (item.platformType ? item.platformName + ' (' + item.platformType + ')' : item.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
+              <uv-tags
+                v-for="(p, index) in platformList"
+                :key="index"
+                :text="p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName)"
+                type="primary"
+                plain
+                size="mini"
+                class="mr5"
+              ></uv-tags>
             </template>
             <text v-else>-</text>
           </view>
-        </view>
-        <view class="info-row"><text class="label">所属团队</text><text class="value">{{ form.belongTeam || '-' }}</text></view>
-        <view class="info-row column">
-          <text class="label mb10">备注</text>
-          <text class="value remark">{{ form.remark || '无' }}</text>
-        </view>
-      </view>
+        </CommonInfoRow>
+
+        <CommonInfoRow label="所属团队" :value="form.belongTeam || '-'" />
+        <CommonInfoRow label="备注" :value="form.remark || '无'" isColumn noBorder />
+      </CommonSection>
 
       <!-- 合作单位 -->
       <view class="common-section-card mt20" v-if="form.companyList?.length">
@@ -136,6 +122,8 @@ import { previewFile } from '@/utils/file';
 import { formatAmount } from '@/utils/format';
 import { formatDate } from '@/utils/date';
 import to from 'await-to-js';
+import CommonSection from '@/components/ui/CommonSection.vue';
+import CommonInfoRow from '@/components/ui/CommonInfoRow.vue';
 
 const props = defineProps<{
   code: string;
@@ -158,14 +146,13 @@ const fetchData = async () => {
 };
 
 const platformList = computed(() => {
-  const belong = form.value?.belongPlatform;
-  if (belong) {
-    if (belong === '其他') return [{ platformName: '其他' }];
+  if (form.value?.belongPlatform) {
     try {
-      const data = JSON.parse(belong);
+      const data = JSON.parse(form.value.belongPlatform);
       return Array.isArray(data) ? data : [];
     } catch (e) {
-      return [{ platformName: belong }];
+      if (form.value.belongPlatform === '其他') return [{ platformName: '其他' }];
+      return [{ platformName: form.value.belongPlatform }];
     }
   }
   return [];

+ 5 - 6
pages/todo/components/document/SciAchievementOther.vue

@@ -9,10 +9,10 @@
         <CommonInfoRow label="成果类型" :value="getDictLabel('sci_achievement_other_type', form.achievementType)" />
         <CommonInfoRow label="获得日期" :value="form.acquireTime ? formatDate(form.acquireTime, 'YYYY-MM-DD') : '-'" />
         <CommonInfoRow label="成果归属单位" :value="getDictLabel('achievement_owner_unit', form.achievementOwnerUnit) || form.achievementOwnerUnit || '-'" />
-        <CommonInfoRow label="所属平台">
+        <CommonInfoRow label="所属平台" isColumn>
           <view class="platform-tags">
             <template v-if="platformList.length > 0">
-              <uv-tags v-for="(item, index) in platformList" :key="index" :text="item.platformName === '其他' ? '其他' : (item.platformType ? item.platformName + ' (' + item.platformType + ')' : item.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
+              <uv-tags v-for="(p, index) in platformList" :key="index" :text="p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
             </template>
             <text v-else>-</text>
           </view>
@@ -66,11 +66,10 @@ const platformList = computed(() => {
   if (form.value?.belongPlatform) {
     try {
       const data = JSON.parse(form.value.belongPlatform);
-      if (Array.isArray(data) && data.length > 0) {
-        return data;
-      }
+      return Array.isArray(data) ? data : [];
     } catch (e) {
-      return [];
+      if (form.value.belongPlatform === '其他') return [{ platformName: '其他' }];
+      return [{ platformName: form.value.belongPlatform }];
     }
   }
   return [];

+ 31 - 10
pages/todo/components/document/SciAchievementSoftware.vue

@@ -9,15 +9,11 @@
         <CommonInfoRow label="版本号" :value="form.version" />
         <CommonInfoRow label="开发完成日期" :value="form.developmentFinishDate ? formatDate(form.developmentFinishDate, 'YYYY-MM-DD') : '-'" />
         <CommonInfoRow label="首次发表日期" :value="form.firstPublishDate ? formatDate(form.firstPublishDate, 'YYYY-MM-DD') : '-'" />
-        <CommonInfoRow label="成果归属单位" :value="getDictLabel('achievement_owner_unit', form.achievementOwnerUnit) || form.achievementOwnerUnit || '-'" />
+        <CommonInfoRow label="成果权属" :value="getDictLabel('achievement_owner_unit', form.achievementOwnerUnit) || form.achievementOwnerUnit || '-'" />
         <CommonInfoRow label="权利范围" :value="getDictLabel('rights_scope', form.rightsScope) || form.rightsScope || '-'" />
         <CommonInfoRow label="权利取得方式" :value="getDictLabel('rights_acquire_method', form.rightsAcquireMethod) || form.rightsAcquireMethod || '-'" />
         <CommonInfoRow label="开发方式" :value="getDictLabel('development_method', form.developmentMethod) || form.developmentMethod || '-'" />
-        
-        <!-- 合作单位(仅开发方式为合作开发时显示) -->
-        <CommonInfoRow v-if="form.developmentMethod === '20'" label="合作单位" :value="form.partnerUnit || '-'" />
-        
-        <CommonInfoRow label="所属平台">
+        <CommonInfoRow label="所属平台" isColumn>
           <view class="platform-tags">
             <template v-if="platformList.length > 0">
               <uv-tags v-for="(p, index) in platformList" :key="index" :text="p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
@@ -26,11 +22,17 @@
           </view>
         </CommonInfoRow>
         <CommonInfoRow label="所属团队" :value="form.belongTeam || '-'" />
-        
+        <CommonInfoRow v-if="form.developmentMethod === '20'" label="合作单位" :value="form.partnerUnit || '-'" />
+        <CommonInfoRow label="佐证附件" isColumn>
+          <view class="file-links">
+            <view v-if="attachment" class="file-item" @click="handlePreview(attachment)">
+              <text class="file-link">{{ attachment.fileName || '-' }}</text>
+            </view>
+            <text v-else>-</text>
+          </view>
+        </CommonInfoRow>
         <CommonInfoRow label="备注" :value="form.remark" isColumn />
       </CommonSection>
-      
-      <AttachmentList :file="attachment" title="佐证附件" />
 
       <!-- 审批记录 -->
       <CommonSection title="审批记录" v-if="form.id">
@@ -47,8 +49,8 @@ import { ref, onMounted, watch, computed } from 'vue';
 import { useDict } from '@/hooks/useDict';
 import { useDocumentApi } from '@/api/document';
 import { formatDate } from '@/utils/date';
+import { previewFile } from '@/utils/file';
 import to from 'await-to-js';
-import AttachmentList from './AttachmentList.vue';
 import FlowTable from '@/pages/project/components/detail/FlowTable.vue';
 import CommonSection from '@/components/ui/CommonSection.vue';
 import CommonInfoRow from '@/components/ui/CommonInfoRow.vue';
@@ -85,6 +87,14 @@ const attachment = computed(() => {
   return null;
 });
 
+const handlePreview = (file: any) => {
+  const url = file.fileUrl || file.url;
+  const name = file.fileName || file.name;
+  if (url) {
+    previewFile(url, name);
+  }
+};
+
 const fetchData = async () => {
   if (!props.code) return;
   loading.value = true;
@@ -107,5 +117,16 @@ watch(() => props.code, () => {
 <style lang="scss" scoped>
 @import "./common.scss";
 
+.file-links {
+  .file-item {
+    padding: 6rpx 0;
+  }
+
+  .file-link {
+    color: #2979ff;
+    text-decoration: underline;
+    word-break: break-all;
+  }
+}
 
 </style>

+ 38 - 33
pages/todo/components/document/SciAchievementStandard.vue

@@ -9,29 +9,33 @@
         <CommonInfoRow label="成果所属单位" :value="form.achievementBelongUnitName" />
         <CommonInfoRow label="提交部门" :value="form.commitDeptName" />
         <CommonInfoRow label="提交日期" :value="formatDate(form.commitDate, 'YYYY-MM-DD')" />
-        <CommonInfoRow label="是否已发布" :value="form.isPublished === '10' ? '是' : '否'" />
+        <CommonInfoRow label="是否已发布" :value="form.isPublished === '10' ? '已发布' : '未发布'" />
         <CommonInfoRow label="发布日期" :value="formatDate(form.publishDate, 'YYYY-MM-DD')" />
         <CommonInfoRow label="单位排名" :value="form.unitRanking" />
         <CommonInfoRow label="所有制定单位" :value="form.belongEnactedUnit" isColumn />
         <CommonInfoRow label="所有参与人员" :value="form.belongEngagePersonal" isColumn />
         <CommonInfoRow label="标准类型" :value="getDictLabel('achievement_standard_type', form.standardType)" />
+        <CommonInfoRow label="标准电子版" isColumn>
+          <view class="file-links">
+            <view v-if="attachment" class="file-item" @click="handlePreview(attachment)">
+              <text class="file-link">{{ attachment.fileName || attachment.name || '-' }}</text>
+            </view>
+            <text v-else>-</text>
+          </view>
+        </CommonInfoRow>
         <CommonInfoRow label="归属年度" :value="form.belongYear" />
         <CommonInfoRow label="归属团队" :value="form.belongTeam" />
-        <view class="info-row">
-          <text class="label">归属平台</text>
+        <CommonInfoRow label="所属平台" isColumn>
           <view class="platform-tags">
             <template v-if="platformList.length > 0">
-              <uv-tags v-for="(item, index) in platformList" :key="index" :text="item.platformName === '其他' ? '其他' : (item.platformType ? item.platformName + ' (' + item.platformType + ')' : item.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
+              <uv-tags v-for="(p, index) in platformList" :key="index" :text="p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
             </template>
             <text v-else>-</text>
           </view>
-        </view>
+        </CommonInfoRow>
         <CommonInfoRow label="备注" :value="form.remark" isColumn />
       </CommonSection>
 
-      <!-- 附件 -->
-      <AttachmentList :file="attachment" title="标准电子版" />
-
       <!-- 制定人信息 -->
       <view class="common-section-card mt20" v-if="form.enactedPersonal?.length">
         <view class="section-title">制定人信息</view>
@@ -71,8 +75,8 @@ import { ref, onMounted, watch, computed } from 'vue';
 import { useDict } from '@/hooks/useDict';
 import { useDocumentApi } from '@/api/document';
 import { formatDate } from '@/utils/date';
+import { previewFile } from '@/utils/file';
 import to from 'await-to-js';
-import AttachmentList from './AttachmentList.vue';
 import FlowTable from '@/pages/project/components/detail/FlowTable.vue';
 import CommonSection from '@/components/ui/CommonSection.vue';
 import CommonInfoRow from '@/components/ui/CommonInfoRow.vue';
@@ -97,38 +101,27 @@ const attachment = computed(() => {
   return null;
 });
 
-const platformDisplay = computed(() => {
-  const belong = form.value?.belongPlatform;
-  if (belong) {
-    if (belong === '其他') return '其他';
-    try {
-      const data = JSON.parse(belong);
-      if (Array.isArray(data)) {
-        return data.map((item: any) => item.platformName === '其他' ? item.platformName : `${item.platformName} (${item.platformType})`).join(', ');
-      }
-      return belong;
-    } catch (e) {
-      return belong;
-    }
-  }
-  return '-';
-});
-
 const platformList = computed(() => {
-  const belong = form.value?.belongPlatform;
-  if (belong) {
+  if (form.value?.belongPlatform) {
     try {
-      const data = JSON.parse(belong);
-      if (Array.isArray(data)) {
-        return data;
-      }
+      const data = JSON.parse(form.value.belongPlatform);
+      return Array.isArray(data) ? data : [];
     } catch (e) {
-      return [];
+      if (form.value.belongPlatform === '其他') return [{ platformName: '其他' }];
+      return [{ platformName: form.value.belongPlatform }];
     }
   }
   return [];
 });
 
+const handlePreview = (file: any) => {
+  const url = file.fileUrl || file.url;
+  const name = file.fileName || file.name;
+  if (url) {
+    previewFile(url, name);
+  }
+};
+
 const fetchData = async () => {
   if (!props.code) return;
   loading.value = true;
@@ -166,4 +159,16 @@ watch(() => props.code, () => {
     margin-right: 20rpx;
   }
 }
+
+.file-links {
+  .file-item {
+    padding: 6rpx 0;
+  }
+
+  .file-link {
+    color: #2979ff;
+    text-decoration: underline;
+    word-break: break-all;
+  }
+}
 </style>

+ 53 - 5
pages/todo/components/document/SpecialActivityForm.vue

@@ -15,7 +15,24 @@
         <CommonInfoRow label="结束日期" :value="formatDate(form.activityEndTime)" />
         <CommonInfoRow label="活动规模" :value="form.activityScale" />
         <CommonInfoRow label="产出成果" :value="form.outputAchievement" />
-        <CommonInfoRow label="所属平台" :value="platformNames" />
+        <CommonInfoRow label="所属平台" isColumn>
+          <view class="platform-tags">
+            <template v-if="platformList.length > 0">
+              <uv-tags v-for="(p, index) in platformList" :key="index" :text="p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
+            </template>
+            <text v-else>-</text>
+          </view>
+        </CommonInfoRow>
+        <CommonInfoRow label="佐证材料" isColumn>
+          <view class="file-links">
+            <template v-if="mergedFileList.length">
+              <view class="file-item" v-for="(item, index) in mergedFileList" :key="'evidence-' + index" @click="handlePreview(item)">
+                <text class="file-link">{{ item.name || '-' }}</text>
+              </view>
+            </template>
+            <text v-else>-</text>
+          </view>
+        </CommonInfoRow>
         <CommonInfoRow label="备注" :value="form.remark" isColumn />
       </CommonSection>
 
@@ -24,8 +41,6 @@
         <CommonInfoRow label="审核意见" :value="form.auditOpinion" isColumn />
       </CommonSection>
 
-      <!-- 佐证材料 -->
-      <AttachmentList :list="mergedFileList" title="佐证材料" />
     </template>
     <uv-empty v-else mode="data" text="暂无数据"></uv-empty>
   </view>
@@ -36,8 +51,8 @@ import { ref, onMounted, computed } from 'vue';
 import { useAchievementApi } from '@/api/achievement/index';
 import { useDeptApi } from '@/api/system/index';
 import { formatDate } from '@/utils/date';
+import { previewFile } from '@/utils/file';
 import to from 'await-to-js';
-import AttachmentList from './AttachmentList.vue';
 import CommonSection from '@/components/ui/CommonSection.vue';
 import CommonInfoRow from '@/components/ui/CommonInfoRow.vue';
 
@@ -89,6 +104,19 @@ const showAuditOpinion = computed(() => {
   return form.value.auditOpinion && (form.value.auditStatus === 1 || form.value.auditStatus === 3);
 });
 
+const platformList = computed(() => {
+  if (form.value?.belongPlatform) {
+    try {
+      const data = JSON.parse(form.value.belongPlatform);
+      return Array.isArray(data) ? data : [];
+    } catch (e) {
+      if (form.value.belongPlatform === '其他') return [{ platformName: '其他' }];
+      return [{ platformName: form.value.belongPlatform }];
+    }
+  }
+  return [];
+});
+
 const mergedFileList = computed(() => {
   if (!form.value?.evidenceMaterials) return [];
   let rawFiles: string[] = [];
@@ -107,9 +135,17 @@ const mergedFileList = computed(() => {
     const startIndex = fileData.indexOf('/');
     const url = import.meta.env.VITE_SCIENTIFIC_FILE_URL + fileData.slice(startIndex + 1);
     return { name, url };
-  }).filter(Boolean);
+  }).filter((item): item is { name: string; url: string } => Boolean(item));
 });
 
+const handlePreview = (file: any) => {
+  const url = file.fileUrl || file.url;
+  const name = file.fileName || file.name;
+  if (url) {
+    previewFile(url, name);
+  }
+};
+
 const fetchData = async () => {
   if (!props.code) return;
   loading.value = true;
@@ -150,4 +186,16 @@ onMounted(() => {
 
 <style lang="scss" scoped>
 @import "./common.scss";
+
+.file-links {
+  .file-item {
+    padding: 6rpx 0;
+  }
+
+  .file-link {
+    color: #2979ff;
+    text-decoration: underline;
+    word-break: break-all;
+  }
+}
 </style>

+ 1 - 1
pages/todo/components/document/SpontaneityForm.vue

@@ -14,7 +14,7 @@
         <CommonInfoRow label="负责人类型" :value="getDictLabel('sci_leader_type', form.projectLeaderType)" />
         <CommonInfoRow label="负责人电话" :value="form.projectLeaderPhone" />
         <CommonInfoRow label="负责人邮箱" :value="form.projectLeaderMail" />
-        <CommonInfoRow label="所属平台">
+        <CommonInfoRow label="所属平台" isColumn>
           <view class="platform-tags">
             <template v-if="platformList.length > 0">
               <uv-tags v-for="(p, index) in platformList" :key="index" :text="p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>

+ 3 - 3
pages/todo/components/document/VerticalForm.vue

@@ -6,7 +6,7 @@
       <CommonSection title="基本信息" :isFirst="true">
         <CommonInfoRow label="项目名称" :value="form.projectName" />
         <CommonInfoRow label="项目分类" :value="form.projectClazzName" />
-        <CommonInfoRow label="项目级别" :value="getDictLabel('sci_pjt_level', form.projectLevel)" />
+        <CommonInfoRow label="项目级别" :value="getDictLabel('sci_vertical_level', form.projectLevel)" />
         <CommonInfoRow label="项目来源" :value="form.projectSource || '-'" />
         <CommonInfoRow label="项目执行期" :value="formatDateRange(form.planStartDate, form.planEndDate)" />
         <CommonInfoRow label="研究类型" :value="getDictLabel('sci_pjt_type', form.studyType)" />
@@ -15,7 +15,7 @@
         <CommonInfoRow label="负责人" :value="form.projectLeaderName" />
         <CommonInfoRow label="负责人电话" :value="form.projectLeaderPhone || '-'" />
         <CommonInfoRow label="负责人邮箱" :value="form.projectLeaderMail || '-'" />
-        <CommonInfoRow label="所属平台">
+        <CommonInfoRow label="所属平台" isColumn>
           <view class="platform-tags">
             <template v-if="platformList.length > 0">
               <uv-tags v-for="(p, index) in platformList" :key="index" :text="p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName)" type="primary" plain size="mini" class="mr5"></uv-tags>
@@ -122,7 +122,7 @@ const props = defineProps<{
   code: string | number;
 }>();
 
-const { getDictLabel } = useDict('sci_pjt_level', 'sci_pjt_type', 'sci_academic_degree', 'sci_tripartite_type');
+const { getDictLabel } = useDict('sci_vertical_level', 'sci_pjt_type', 'sci_academic_degree', 'sci_tripartite_type');
 const documentApi = useDocumentApi();
 const form = ref<any>(null);
 const loading = ref(false);

+ 19 - 1
pages/todo/components/document/common.scss

@@ -193,8 +193,10 @@
   .platform-tags {
     display: flex;
     flex-wrap: wrap;
-    justify-content: flex-end;
+    justify-content: flex-start;
     gap: 8rpx;
+    width: 100%;
+    box-sizing: border-box;
     
     .platform-tag {
       font-size: 20rpx;
@@ -203,9 +205,25 @@
       color: #64748b;
       border-radius: 4rpx;
       border: 1rpx solid #e2e8f0;
+      max-width: 100%;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      white-space: nowrap;
     }
   }
 
+  :deep(.platform-tags .uv-tags) {
+    max-width: 100%;
+  }
+
+  :deep(.platform-tags .uv-tags__text) {
+    max-width: 560rpx;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    display: block;
+  }
+
   /* 成员身份标签基础样式 */
   .m-type-tag {
     font-size: 20rpx;