AchPaperForm.vue 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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.paperName" />
  8. <CommonInfoRow label="学科类型" :value="getDictLabel('project_class', form.disciplineFirstName)" />
  9. <CommonInfoRow label="论文类型" :value="getDictLabel('sci_paper_type', form.paperType)" />
  10. <CommonInfoRow label="论文类别" :value="getDictLabel('paper_category', form.paperCategory)" />
  11. <CommonInfoRow label="发表/出版时间" :value="formatDate(form.publicationDate)" />
  12. <CommonInfoRow label="刊名" :value="form.publicationName" />
  13. <CommonInfoRow label="期刊类型" :value="form.periodicalType || '-'" />
  14. <template v-if="form.periodicalType?.toLowerCase() === 'sci'">
  15. <CommonInfoRow label="中科院分区" :value="getDictLabel('sci_paper_subTreasury', form.subTreasury)" />
  16. <CommonInfoRow label="IF" :value="form.impactFactors" />
  17. </template>
  18. <CommonInfoRow label="DOI号/PMID" :value="form.doi" />
  19. <CommonInfoRow label="所属年份" :value="form.statisticalYear" />
  20. <CommonInfoRow label="年/卷/期/页" :value="(form.yearNum || '') + '/' + (form.volNum || '') + '/' + (form.issueNum || '')" />
  21. <CommonInfoRow label="页码" :value="form.pageRange || '-'" />
  22. <CommonInfoRow label="本院署名" :value="getDictLabel('sci_paper_signType', form.signType)" />
  23. <CommonInfoRow label="ISSN号" :value="form.issnNum" />
  24. <CommonInfoRow label="所属平台" :value="platformText" />
  25. <CommonInfoRow label="所属团队" :value="form.belongTeam || '-'" />
  26. <CommonInfoRow label="合作单位" :value="form.partnerOrg || '-'" />
  27. <CommonInfoRow label="单位类型" :value="getDictLabel('partner_org_type', form.partnerOrgType)" />
  28. </CommonSection>
  29. <!-- 作者信息 -->
  30. <CommonSection title="作者信息" v-if="form.authorList?.length">
  31. <view class="member-list">
  32. <view class="member-item" v-for="(row, index) in form.authorList" :key="index">
  33. <view class="m-index">{{ Number(index) + 1 }}</view>
  34. <view class="m-body">
  35. <view class="member-header">
  36. <view class="name-box">
  37. <text class="m-name">{{ row.memberName }}</text>
  38. <text class="m-tag">{{ getDictLabel('sci_paper_author_type', row.authorType) }}</text>
  39. </view>
  40. <text class="m-type-tag">{{ getDictLabel('sci_paper_member_type', row.memberType) }}</text>
  41. </view>
  42. <view class="m-detail-row">
  43. <view class="m-line" v-if="row.deptName"><text class="l">科室/单位:</text><text class="v">{{ row.deptName }}</text></view>
  44. <view class="m-line" v-if="row.technicalTitle"><text class="l">职称:</text><text class="v">{{ row.technicalTitle }}</text></view>
  45. <view class="m-line" v-if="row.contributionRate"><text class="l">贡献率(%):</text><text class="v">{{ row.contributionRate }}</text></view>
  46. <view class="m-line" v-if="row.signOrder"><text class="l">排名:</text><text class="v">{{ row.signOrder }}</text></view>
  47. </view>
  48. </view>
  49. </view>
  50. </view>
  51. </CommonSection>
  52. <!-- 标注经济来源 -->
  53. <CommonSection title="标注经济来源" v-if="form.projList?.length">
  54. <view class="achievement-card" v-for="(item, index) in form.projList" :key="index">
  55. <view class="a-row">
  56. <text class="al">关联类型:</text>
  57. <text class="av">{{ item.sourceType === '10' ? '项目' : '学科' }}</text>
  58. </view>
  59. <view class="a-row">
  60. <text class="al">项目/学科:</text>
  61. <text class="av">{{ item.projectSource || '-' }}</text>
  62. </view>
  63. </view>
  64. </CommonSection>
  65. <!-- 电子附件 -->
  66. <AttachmentList :list="mergedFileList" title="电子附件" />
  67. <!-- 审批信息 -->
  68. <CommonSection title="审批信息" v-if="form.id">
  69. <FlowTable :id="form.id" :businessCode="'学术论文-' + form.paperCode" defCode="sci_academic_achievement" />
  70. </CommonSection>
  71. </template>
  72. <uv-empty v-else mode="data" text="暂无数据"></uv-empty>
  73. </view>
  74. </template>
  75. <script setup lang="ts">
  76. import { ref, onMounted, watch, computed } from 'vue';
  77. import { useDict } from '@/hooks/useDict';
  78. import { useDocumentApi } from '@/api/document';
  79. import { formatDate } from '@/utils/date';
  80. import to from 'await-to-js';
  81. import AttachmentList from './AttachmentList.vue';
  82. import FlowTable from '@/pages/project/components/detail/FlowTable.vue';
  83. import CommonSection from '@/components/ui/CommonSection.vue';
  84. import CommonInfoRow from '@/components/ui/CommonInfoRow.vue';
  85. const props = defineProps<{
  86. code: string;
  87. }>();
  88. const { getDictLabel } = useDict(
  89. 'project_class',
  90. 'sci_paper_type',
  91. 'paper_category',
  92. 'sci_publication_range',
  93. 'sci_paper_subTreasury',
  94. 'sci_paper_signType',
  95. 'sci_paper_author_type',
  96. 'sci_paper_member_type',
  97. 'partner_org_type'
  98. );
  99. const documentApi = useDocumentApi();
  100. const form = ref<any>(null);
  101. const loading = ref(false);
  102. const platformList = computed(() => {
  103. if (form.value?.belongPlatform) {
  104. try {
  105. const data = JSON.parse(form.value.belongPlatform);
  106. return Array.isArray(data) ? data : [];
  107. } catch (e) {
  108. if (form.value.belongPlatform === '其他') return [{ platformName: '其他' }];
  109. return [{ platformName: form.value.belongPlatform }];
  110. }
  111. }
  112. return [];
  113. });
  114. const platformText = computed(() => {
  115. if (platformList.value.length === 0) return '-';
  116. return platformList.value
  117. .map(p => p.platformName === '其他' ? '其他' : (p.platformType ? p.platformName + ' (' + p.platformType + ')' : p.platformName))
  118. .join('、');
  119. });
  120. const mergedFileList = computed(() => {
  121. if (!form.value) return [];
  122. const list: any[] = [];
  123. if (form.value.paperResultList) list.push(...form.value.paperResultList.map((item: any) => ({ ...item, fileType: '论文全文' })));
  124. if (form.value.includedProofList) list.push(...form.value.includedProofList.map((item: any) => ({ ...item, fileType: '收录证明' })));
  125. if (form.value.ethicsApprovalList) list.push(...form.value.ethicsApprovalList.map((item: any) => ({ ...item, fileType: '伦理批件' })));
  126. if (form.value.rawDataList) list.push(...form.value.rawDataList.map((item: any) => ({ ...item, fileType: '原始数据' })));
  127. return list;
  128. });
  129. const fetchData = async () => {
  130. if (!props.code) return;
  131. loading.value = true;
  132. const paperCode = props.code.includes('-') ? props.code.split('-')[1] : props.code;
  133. const [err, res] = await to(documentApi.getPaperByCode(paperCode));
  134. if (!err && res?.data) {
  135. form.value = res.data;
  136. }
  137. loading.value = false;
  138. };
  139. onMounted(() => {
  140. fetchData();
  141. });
  142. watch(() => props.code, () => {
  143. fetchData();
  144. });
  145. </script>
  146. <style lang="scss" scoped>
  147. @import "./common.scss";
  148. .info-row {
  149. display: flex;
  150. justify-content: space-between;
  151. padding: 24rpx 0;
  152. border-bottom: 2rpx dashed #f5f5f5;
  153. font-size: 28rpx;
  154. .label {
  155. color: #343a3f;
  156. width: 200rpx;
  157. flex-shrink: 0;
  158. margin-right: 20rpx;
  159. }
  160. }
  161. .member-list {
  162. .member-item {
  163. display: flex;
  164. align-items: flex-start;
  165. padding: 20rpx 0;
  166. border-bottom: 2rpx solid #f5f5f5;
  167. &:last-child { border-bottom: none; }
  168. }
  169. .m-index {
  170. width: 40rpx;
  171. height: 40rpx;
  172. background: #3b82f6;
  173. color: #fff;
  174. border-radius: 50%;
  175. display: flex;
  176. align-items: center;
  177. justify-content: center;
  178. font-size: 22rpx;
  179. flex-shrink: 0;
  180. margin-right: 16rpx;
  181. margin-top: 4rpx;
  182. }
  183. .m-body {
  184. flex: 1;
  185. }
  186. }
  187. .member-header {
  188. .name-box {
  189. display: flex;
  190. align-items: center;
  191. gap: 12rpx;
  192. flex-wrap: wrap;
  193. }
  194. }
  195. .m-detail-row {
  196. margin-top: 12rpx;
  197. display: flex;
  198. flex-direction: column;
  199. gap: 6rpx;
  200. .m-line {
  201. font-size: 24rpx;
  202. color: #64748b;
  203. .l { color: #94a3b8; margin-right: 8rpx; }
  204. .v { color: #343a3f; }
  205. }
  206. }
  207. </style>