index.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. <template>
  2. <!-- 筛选 -->
  3. <div class="pa-3 d-flex justify-space-between align-center">
  4. <Autocomplete v-model="enterpriseId" @change="getList" :item="selectItems" style="width: 300px;" />
  5. <div>
  6. <v-btn color="primary" elevation="5" prepend-icon="mdi-refresh" @click="getList(true)">刷 新</v-btn>
  7. <v-btn color="#00897B" class="ml-5" elevation="5" prepend-icon="mdi-plus" @click="handleAddReport">新增报告</v-btn>
  8. </div>
  9. </div>
  10. <v-divider class="ma-3"></v-divider>
  11. <!-- 实习报告 -->
  12. <div class="pa-3">
  13. <div v-if="items && items.length > 0">
  14. <div v-for="item in items" :key="item.date" class="mb-3">
  15. <div class="title-date">{{ item.date }}</div>
  16. <div class="d-flex flex-wrap">
  17. <img
  18. v-for="(src, index) in item.arr"
  19. :key="index"
  20. :src="src"
  21. @click="handlePreview(item.arr, index)"
  22. class="cursor-pointer"
  23. style="width: 200px; height: 250px;"
  24. />
  25. </div>
  26. </div>
  27. </div>
  28. <Empty v-else :elevation="false" />
  29. </div>
  30. <CtDialog :visible="showDialog" :widthType="2" titleClass="text-h6" :footer="true" title="新增实习报告" @close="handleClose" @submit="handleSubmit">
  31. <CtForm ref="CtFormRef" :items="formItems">
  32. <template #urlList="{ item }">
  33. <div>
  34. <p class="color-primary">*请上传实习报告图片(最多可上传9张图片)</p>
  35. <p class="mb-3 color-primary">*只支持JPG、JPEG、PNG类型的图片</p>
  36. <Imgs v-model="item.value" :showTips="false" limit="9"></Imgs>
  37. </div>
  38. </template>
  39. </CtForm>
  40. </CtDialog>
  41. </template>
  42. <script setup>
  43. defineOptions({ name: 'InternshipReport' })
  44. import { ref, onMounted } from 'vue'
  45. import { usePersonCenterStore } from '@/store/personCenter'
  46. import { useRoute } from 'vue-router'
  47. import { getStudentReportList, saveStudentReport, getStudentPracticeCompanyList } from '@/api/recruit/personal/student'
  48. import Snackbar from '@/plugins/snackbar'
  49. import { formatName } from '@/utils/getText'
  50. const route = useRoute()
  51. const enterpriseId = ref(null)
  52. const CtFormRef = ref(null)
  53. const items = ref([])
  54. const formItems = ref({
  55. options: [
  56. {
  57. type: 'autocomplete',
  58. key: 'enterpriseId',
  59. value: null,
  60. defaultValue: null,
  61. label: '实习企业 *',
  62. outlined: true,
  63. itemText: 'enterpriseName',
  64. itemValue: 'id',
  65. rules: [v => !!v || '请选择实习企业'],
  66. items: []
  67. },
  68. {
  69. slotName: 'urlList',
  70. value: [],
  71. defaultValue: [],
  72. key: 'urlList',
  73. label: '实习报告 *'
  74. },
  75. ]
  76. })
  77. const selectItems = ref({
  78. label: '请选择要查看的企业',
  79. itemText: 'enterpriseName',
  80. itemValue: 'id',
  81. clearable: true,
  82. hideDetails: true,
  83. items: []
  84. })
  85. // 获取实习企业列表
  86. const getCompanyList = async () => {
  87. try {
  88. const data = await getStudentPracticeCompanyList()
  89. data.forEach(e => {
  90. e.id = e.id.toString()
  91. e.enterpriseName = formatName(e.anotherName || e.name)
  92. })
  93. selectItems.value.items = data
  94. formItems.value.options.find(e => e.key === 'enterpriseId').items = data
  95. } catch {}
  96. }
  97. // 实习报告列表
  98. const getList = async (isRefresh = false) => {
  99. if ((!items.value || !items.value.length) && isRefresh) return Snackbar.warning('暂无实习报告')
  100. items.value = []
  101. try {
  102. const data = await getStudentReportList(enterpriseId.value ? { enterpriseId: enterpriseId.value } : {})
  103. if (!data || !Object.keys(data).length) return
  104. for (let item in data) {
  105. items.value.push({ date: item, arr: data[item].map(e => e.url) })
  106. }
  107. } catch {}
  108. }
  109. onMounted(() => {
  110. getCompanyList()
  111. const { id } = route.query
  112. if (id) {
  113. enterpriseId.value = id
  114. }
  115. getList()
  116. })
  117. // 新增实习报告
  118. const showDialog = ref(false)
  119. const handleAddReport = () => {
  120. if (!selectItems.value.items || !selectItems.value.items.length) return Snackbar.warning('暂无实习企业')
  121. formItems.value.options.find(e => e.key === 'urlList').value = []
  122. showDialog.value = true
  123. }
  124. const handleClose = () => {
  125. formItems.value.options.forEach(e => e.value = e.defaultValue)
  126. showDialog.value = false
  127. }
  128. const handleSubmit = async () => {
  129. const { valid } = await CtFormRef.value.formRef.validate()
  130. if (!valid) return
  131. let obj = {}
  132. formItems.value.options.forEach(e => {
  133. obj[e.key] = e.value
  134. })
  135. if (!obj.urlList || !obj.urlList.length) return Snackbar.warning('请上传实习报告')
  136. try {
  137. await saveStudentReport(obj)
  138. Snackbar.success('保存成功')
  139. handleClose()
  140. getList()
  141. } catch {
  142. handleClose()
  143. }
  144. }
  145. // 预览
  146. const personCenterStore = usePersonCenterStore()
  147. const handlePreview = (arr, index) => {
  148. personCenterStore.setPreviewData(arr, index)
  149. }
  150. </script>
  151. <style scoped lang="scss">
  152. .title-date {
  153. border-left: 5px solid var(--v-primary-base);
  154. padding-left: 12px;
  155. line-height: 17px;
  156. }
  157. </style>