AchPaperSubmission.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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. <!-- 1. 基本信息 -->
  6. <view class="common-section-card">
  7. <view class="section-title">基本信息</view>
  8. <view class="info-row">
  9. <text class="label">论文名称</text>
  10. <text class="value">{{ form.paperTitle || '-' }}</text>
  11. </view>
  12. <view class="info-row">
  13. <text class="label">投稿刊物名称</text>
  14. <text class="value">{{ form.pubName || '-' }}</text>
  15. </view>
  16. <view class="info-row">
  17. <text class="label">备注</text>
  18. <text class="value">{{ form.remark || '-' }}</text>
  19. </view>
  20. </view>
  21. <!-- 2. 单位排名 -->
  22. <view class="common-section-card mt20">
  23. <view class="section-title">单位排名</view>
  24. <view class="info-row">
  25. <text class="label">第一名</text>
  26. <text class="value">{{ form.unitRankFirst || '-' }}</text>
  27. </view>
  28. <view class="info-row">
  29. <text class="label">第二名</text>
  30. <text class="value">{{ form.unitRankSecond || '-' }}</text>
  31. </view>
  32. <view class="info-row">
  33. <text class="label">第三名</text>
  34. <text class="value">{{ form.unitRankThird || '-' }}</text>
  35. </view>
  36. </view>
  37. <!-- 3. 标注经济来源 -->
  38. <view class="common-section-card mt20" v-if="form.projList?.length">
  39. <view class="section-title">标注经济来源</view>
  40. <view class="achievement-card" v-for="(item, index) in form.projList" :key="index">
  41. <view class="a-row border-bottom mb10 pb10">
  42. <text class="al">关联类型:</text>
  43. <text class="av font-bold">{{ item.sourceType === '10' ? '项目' : '学科' }}</text>
  44. </view>
  45. <view class="a-row">
  46. <text class="al">关联项目/学科:</text>
  47. <text class="av">{{ item.projectSource || '-' }}</text>
  48. </view>
  49. </view>
  50. </view>
  51. <!-- 4. 作者信息 -->
  52. <view class="common-section-card mt20" v-if="form.authorList?.length">
  53. <view class="section-title">作者信息</view>
  54. <view class="member-list">
  55. <view class="member-item" v-for="(author, index) in form.authorList" :key="index">
  56. <view class="member-header">
  57. <view class="name-box">
  58. <text class="m-name">{{ author.memberName }}</text>
  59. <text class="m-tag">{{ getDictLabel('sci_paper_author_type', author.authorType) }}</text>
  60. </view>
  61. <text class="m-type-tag">{{ getDictLabel('sci_paper_member_type', author.memberType) }}</text>
  62. </view>
  63. <view class="m-body">
  64. <view class="m-line">
  65. <text class="l">所属科室:</text>
  66. <text class="v">{{ author.deptName || '-' }}</text>
  67. </view>
  68. </view>
  69. </view>
  70. </view>
  71. </view>
  72. <!-- 5. 附件信息 (投稿登记表 & 科研诚信表) -->
  73. <view class="common-section-card mt20" v-if="uploadList.length">
  74. <view class="section-title">附件资料</view>
  75. <view class="common-file-list">
  76. <view class="file-item" v-for="(file, index) in uploadList" :key="index" @click="previewFile(file.url, file.name)">
  77. <view class="file-info">
  78. <text class="f-name">{{ file.name }}</text>
  79. <text class="f-meta">{{ file.type }}</text>
  80. </view>
  81. </view>
  82. </view>
  83. </view>
  84. </template>
  85. <uv-empty v-else mode="data" text="暂无数据"></uv-empty>
  86. </view>
  87. </template>
  88. <script setup lang="ts">
  89. import { ref, onMounted, watch, computed } from 'vue';
  90. import { useDocumentApi } from '@/api/document';
  91. import { useDict } from '@/hooks/useDict';
  92. import { previewFile } from '@/utils/file';
  93. import to from 'await-to-js';
  94. const props = defineProps<{
  95. code: string;
  96. }>();
  97. const { getDictLabel } = useDict('sci_paper_author_type', 'sci_paper_member_type');
  98. const documentApi = useDocumentApi();
  99. const form = ref<any>(null);
  100. const loading = ref(false);
  101. const uploadList = computed(() => {
  102. if (!form.value) return [];
  103. const list = [];
  104. if (form.value.fromUrl) {
  105. list.push({ name: '下载', url: form.value.fromUrl, type: '投稿登记表' });
  106. }
  107. if (form.value.honestUrl) {
  108. list.push({ name: '下载', url: form.value.honestUrl, type: '科研诚信表' });
  109. }
  110. return list;
  111. });
  112. const fetchData = async () => {
  113. if (!props.code) return;
  114. loading.value = true;
  115. const [err, res] = await to(documentApi.getPaperSubmissionByCode(props.code));
  116. if (!err && res?.data) {
  117. form.value = res.data;
  118. }
  119. loading.value = false;
  120. };
  121. onMounted(() => {
  122. fetchData();
  123. });
  124. watch(() => props.code, () => {
  125. fetchData();
  126. });
  127. </script>
  128. <style lang="scss" scoped>
  129. @import "./common.scss";
  130. .achievement-card {
  131. background: #f8f9fc;
  132. border-radius: 12rpx;
  133. padding: 20rpx;
  134. margin-bottom: 20rpx;
  135. &:last-child { margin-bottom: 0; }
  136. .a-row {
  137. display: flex;
  138. font-size: 26rpx;
  139. line-height: 1.5;
  140. .al { color: #999; flex-shrink: 0; }
  141. .av { color: #333; }
  142. }
  143. }
  144. .border-bottom { border-bottom: 1rpx solid #eef0f5; }
  145. .pb10 { padding-bottom: 10rpx; }
  146. .mb10 { margin-bottom: 10rpx; }
  147. .font-bold { font-weight: bold; }
  148. </style>