VerticalForm.vue 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. <template>
  2. <view class="document-form">
  3. <uv-loading-icon v-if="loading" mode="circle" text="正在加载纵向项目详情..."></uv-loading-icon>
  4. <template v-else-if="form">
  5. <!-- 基本信息 -->
  6. <CommonSection title="基本信息" :isFirst="true">
  7. <CommonInfoRow label="项目名称" :value="form.projectName" />
  8. <CommonInfoRow label="项目分类" :value="form.projectClazzName" />
  9. <CommonInfoRow label="项目级别" :value="getDictLabel('sci_pjt_level', form.projectLevel)" />
  10. <CommonInfoRow label="项目来源" :value="form.projectSource || '-'" />
  11. <CommonInfoRow label="项目执行期" :value="formatDateRange(form.planStartDate, form.planEndDate)" />
  12. <CommonInfoRow label="研究类型" :value="getDictLabel('sci_pjt_type', form.studyType)" />
  13. <CommonInfoRow label="统计年度" :value="form.statisticalYear" />
  14. <CommonInfoRow label="所属科室" :value="form.deptName" />
  15. <CommonInfoRow label="负责人" :value="form.projectLeaderName" />
  16. <CommonInfoRow label="负责人电话" :value="form.projectLeaderPhone || '-'" />
  17. <CommonInfoRow label="负责人邮箱" :value="form.projectLeaderMail || '-'" />
  18. <CommonInfoRow label="所属平台">
  19. <view class="platform-tags">
  20. <template v-if="platformList.length > 0">
  21. <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>
  22. </template>
  23. <text v-else>-</text>
  24. </view>
  25. </CommonInfoRow>
  26. <CommonInfoRow label="是否伦理" :value="form.isEthics === '10' ? '是' : '否'" />
  27. <CommonInfoRow label="是否中医药" :value="form.isMedicine === '10' ? '是' : '否'" />
  28. <CommonInfoRow label="包干制项目" :value="form.isLumpSum === '10' ? '是' : '否'" />
  29. <CommonInfoRow label="备注" :value="form.remark" isColumn />
  30. </CommonSection>
  31. <!-- 立项信息 -->
  32. <CommonSection title="立项信息">
  33. <CommonInfoRow label="获批时间" :value="form.approvalDate ? formatDate(form.approvalDate) : '-'" />
  34. <CommonInfoRow label="获批编号" :value="form.projectNo || '-'" />
  35. <CommonInfoRow label="合同经费" :value="formatAmount(form.contractFunds)" isAmount />
  36. <CommonInfoRow label="批准经费" :value="formatAmount(form.approvedFunds)" isAmount />
  37. <CommonInfoRow label="匹配经费" :value="formatAmount(form.supportFunds)" isAmount />
  38. <CommonInfoRow label="自筹经费" :value="formatAmount(form.selfFunds)" isAmount />
  39. <CommonInfoRow label="总经费" :value="formatAmount(form.totalAmount)" isAmount />
  40. </CommonSection>
  41. <!-- 成员信息 -->
  42. <CommonSection title="成员信息" v-if="form.memberList?.length">
  43. <view class="member-list">
  44. <view class="member-item" v-for="(row, index) in form.memberList" :key="index">
  45. <view class="member-header">
  46. <view class="name-box">
  47. <text class="m-name">{{ row.memberName }}</text>
  48. <text class="m-tag leader" v-if="row.projectRole === '10'">负责人</text>
  49. <text class="m-tag" v-else-if="row.projectRole === '20'">主要参与人</text>
  50. <text class="m-tag" v-else>一般参与人</text>
  51. </view>
  52. <text class="m-type-tag blue" v-if="row.memberType">{{ row.memberType === '10' ? '本院人员' : row.memberType === '20' ? '非本院人员' : '研究生' }}</text>
  53. </view>
  54. <view class="m-body">
  55. <view class="m-line" v-if="row.deptName"><text class="l">所属科室:</text><text class="v">{{ row.deptName }}</text></view>
  56. <view class="m-line" v-if="row.technicalTitle"><text class="l">职称:</text><text class="v">{{ row.technicalTitle }}</text></view>
  57. <view class="m-line" v-if="row.degree"><text class="l">学位:</text><text class="v">{{ getDictLabel('sci_academic_degree', row.degree) }}</text></view>
  58. <view class="m-line column" v-if="row.responsibleContent">
  59. <text class="l">负责内容:</text>
  60. <text class="v remark">{{ row.responsibleContent }}</text>
  61. </view>
  62. </view>
  63. </view>
  64. </view>
  65. </CommonSection>
  66. <!-- 合作单位 -->
  67. <CommonSection title="合作单位" v-if="form.companyList?.length">
  68. <view class="member-list">
  69. <view class="member-item" v-for="(item, index) in form.companyList" :key="index">
  70. <view class="member-header">
  71. <text class="m-name">{{ item.compName }}</text>
  72. <text class="m-type-tag" v-if="item.compType">{{ getDictLabel('sci_tripartite_type', item.compType) }}</text>
  73. </view>
  74. <view class="m-body">
  75. <view class="m-line" v-if="item.compCode"><text class="l">单位编号:</text><text class="v">{{ item.compCode }}</text></view>
  76. <view class="m-line" v-if="item.compContact"><text class="l">联系人:</text><text class="v">{{ item.compContact }} ({{ item.compPhoneNum || '-' }})</text></view>
  77. <view class="m-line" v-if="item.compLocalArea"><text class="l">单位地址:</text><text class="v">{{ item.compLocalArea }}</text></view>
  78. </view>
  79. </view>
  80. </view>
  81. </CommonSection>
  82. <!-- 预算信息 -->
  83. <CommonSection title="预算信息" v-if="form.fundsList?.length && form.isLumpSum === '20'">
  84. <view class="funds-list">
  85. <view class="funds-item" v-for="(item, index) in form.fundsList" :key="index">
  86. <view class="f-row">
  87. <text class="f-name">{{ item.fundsSubjName }}</text>
  88. </view>
  89. <view class="f-grid">
  90. <view class="g-item"><text class="gl">财政拨款</text><text class="gv">¥{{ item.projectFundsAmount || 0 }}</text></view>
  91. <view class="g-item"><text class="gl">匹配经费</text><text class="gv">¥{{ item.otherFundsAmount || 0 }}</text></view>
  92. <view class="g-item"><text class="gl">自筹经费</text><text class="gv">¥{{ item.raiseFundsAmount || 0 }}</text></view>
  93. <view class="g-item highlight"><text class="gl">预算金额</text><text class="gv">¥{{ item.totalFundsAmount || 0 }}</text></view>
  94. </view>
  95. </view>
  96. </view>
  97. </CommonSection>
  98. <!-- 附件信息 -->
  99. <AttachmentList :list="form.fileList" title="附件资料" />
  100. </template>
  101. <uv-empty v-else mode="data" text="暂无数据"></uv-empty>
  102. </view>
  103. </template>
  104. <script setup lang="ts">
  105. import { ref, onMounted, watch, computed } from 'vue';
  106. import { useDict } from '@/hooks/useDict';
  107. import { useDocumentApi } from '@/api/document';
  108. import { formatDate } from '@/utils/date';
  109. import { formatAmount } from '@/utils/format';
  110. import AttachmentList from './AttachmentList.vue';
  111. import CommonSection from '@/components/ui/CommonSection.vue';
  112. import CommonInfoRow from '@/components/ui/CommonInfoRow.vue';
  113. import to from 'await-to-js';
  114. const props = defineProps<{
  115. code: string | number;
  116. }>();
  117. const { getDictLabel } = useDict('sci_pjt_level', 'sci_pjt_type', 'sci_academic_degree', 'sci_tripartite_type');
  118. const documentApi = useDocumentApi();
  119. const form = ref<any>(null);
  120. const loading = ref(false);
  121. const platformList = computed(() => {
  122. if (form.value?.belongPlatform) {
  123. try {
  124. const data = JSON.parse(form.value.belongPlatform);
  125. return Array.isArray(data) ? data : [];
  126. } catch (e) {
  127. if (form.value.belongPlatform === '其他') return [{ platformName: '其他' }];
  128. return [{ platformName: form.value.belongPlatform }];
  129. }
  130. }
  131. return [];
  132. });
  133. const formatDateRange = (start: string, end: string) => {
  134. if (!start && !end) return '-';
  135. return `${formatDate(start)} 至 ${formatDate(end)}`;
  136. };
  137. const fetchData = async () => {
  138. if (!props.code) return;
  139. loading.value = true;
  140. const [err, res] = await to(documentApi.getVerticalByCode(String(props.code)));
  141. if (!err && res?.data) {
  142. form.value = res.data;
  143. }
  144. loading.value = false;
  145. };
  146. onMounted(() => {
  147. fetchData();
  148. });
  149. watch(() => props.code, () => {
  150. fetchData();
  151. });
  152. </script>
  153. <style lang="scss" scoped>
  154. @import "./common.scss";
  155. .m-type-tag {
  156. font-size: 20rpx;
  157. padding: 2rpx 8rpx;
  158. background-color: #f0f7ff;
  159. color: #007aff;
  160. border-radius: 4rpx;
  161. border: 1px solid #d0e7ff;
  162. }
  163. </style>