addReport.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. <template>
  2. <scroll-view class="scrollBox" scroll-y="true">
  3. <view class="content">
  4. <uni-forms
  5. ref="infoRef"
  6. v-model="formData"
  7. :rules="formRules"
  8. validateTrigger="bind"
  9. label-width="86px"
  10. labelAlign="right"
  11. >
  12. <uni-forms-item name="enterpriseId" label="实习企业" required>
  13. <uni-data-picker v-model="formData.enterpriseId" :localdata="companyList" :clear-icon="false" popup-title="请选择实习企业" :clear="false" :map="{ text: 'enterpriseName', value: 'id' }"></uni-data-picker>
  14. </uni-forms-item>
  15. <uni-forms-item label="实习报告" name="report" class="f-straight">
  16. <view style="display: flex;flex-wrap: wrap;">
  17. <view v-for="(img, index) of reportList" :key="index">
  18. <view class="upload-img" v-if="img">
  19. <uni-icons size="35" type="clear" color="#fe574a" style="position: absolute;right: -15px; top: -15px; z-index: 9" @click="delReport(index)"></uni-icons>
  20. <image :src="img" mode="contain" style="width: 200rpx;height: 200rpx;" @click="handlePreviewImage(index)"></image>
  21. </view>
  22. </view>
  23. <view v-if="reportList?.length < 9" class="upload-file" @click="uploadPhotos">
  24. <uni-icons type="plusempty" size="50" color="#f1f1f1"></uni-icons>
  25. </view>
  26. </view>
  27. </uni-forms-item>
  28. <view class="uploadTip text-center">*请上传实习报告图片(最多可上传9张图片)</view>
  29. <view class="uploadTip text-center">*只支持JPG、JPEG、PNG类型的图片</view>
  30. </uni-forms>
  31. </view>
  32. <view class="bottom-sticky">
  33. <button type="primary" size="default" class="recomm-button" :disabled="disabled" @click="submit">确认</button>
  34. </view>
  35. </scroll-view>
  36. </template>
  37. <script setup>
  38. import { ref, unref } from 'vue'
  39. import { onLoad } from '@dcloudio/uni-app'
  40. import { uploadFile } from '@/api/file'
  41. import { saveStudentReport } from '@/api/student.js'
  42. const companyList = ref([])
  43. onLoad((options) => {
  44. if (options.companyList) {
  45. companyList.value = JSON.parse(options.companyList)
  46. }
  47. })
  48. const formData = ref({
  49. enterpriseId: null,
  50. })
  51. const formRules = {
  52. enterpriseId: {
  53. rules: [{required: true, errorMessage: '请选择实习企业' }]
  54. },
  55. }
  56. const disabled = ref(false)
  57. const infoRef = ref()
  58. const submit = async () => {
  59. const validate = await unref(infoRef).validate()
  60. if (!validate) return uni.showToast({ title: '请选择企业', icon: 'none' })
  61. if (!reportList.value?.length) return uni.showToast({ title: '请上传实习报告', icon: 'none' })
  62. disabled.value = true
  63. try {
  64. await saveStudentReport({
  65. ...formData.value,
  66. urlList: reportList.value
  67. })
  68. uni.showToast({ title: '保存成功', icon: 'none' })
  69. setTimeout(() => {
  70. uni.navigateBack({
  71. delta: 1
  72. })
  73. disabled.value = false
  74. }, 500)
  75. } catch (err) {
  76. disabled.value = false
  77. uni.showToast({ title: err?.msg || '保存失败', icon: 'none' })
  78. }
  79. }
  80. const reportList = ref([])
  81. const delReport = (index) => {
  82. reportList.value.splice(index, 1)
  83. }
  84. // 图片预览
  85. const handlePreviewImage = (index) => {
  86. uni.previewImage({
  87. current: 0,
  88. urls: [reportList.value[index]]
  89. })
  90. }
  91. // 上传
  92. const uploadPhotos = () => {
  93. wx.chooseImage({
  94. count: 1,
  95. sizeType: ['original', 'compressed'],
  96. sourceType: ['album', 'camera'],
  97. success: function(res){
  98. const size = res.tempFiles[0]?.size || 0
  99. if (size >= 31457280) {
  100. uni.showToast({
  101. icon: 'none',
  102. title: '头像上传大小不得超过 20MB !',
  103. duration: 2000
  104. })
  105. return
  106. }
  107. const path = res.tempFilePaths[0]
  108. uploadFile(path, 'img').then(res => {
  109. formData.value.avatar = res.data
  110. reportList.value.push(res.data)
  111. }).catch(error => {
  112. uni.showToast({
  113. icon: 'error',
  114. title: '图片上传失败!',
  115. duration: 2000
  116. })
  117. })
  118. }
  119. })
  120. }
  121. </script>
  122. <style lang="scss" scoped>
  123. .img{
  124. width: 28%;
  125. height: 200rpx;
  126. margin: 10rpx;
  127. border: 1px solid #f4f4f4;
  128. }
  129. .wrapper{
  130. height: 84vh;
  131. overflow: auto;
  132. }
  133. :deep(.uni-section .uni-section-header__decoration) {
  134. background-color: #00B760 !important;
  135. }
  136. .line {
  137. border-top: 1px solid #ccc;
  138. }
  139. .picker {
  140. flex: 1;
  141. overflow: hidden;
  142. margin-right: 12px;
  143. }
  144. .content {
  145. padding: 20rpx;
  146. padding-bottom: 50rpx;
  147. .uploadTip {
  148. color: #00B760;
  149. margin-bottom: 20px;
  150. font-size: 13px;
  151. }
  152. }
  153. .upload-img{
  154. position: relative;
  155. width: 200rpx;
  156. height: 200rpx;
  157. border: 1px solid #f1f1f1;
  158. margin: 10rpx;
  159. }
  160. .upload-file{
  161. width: 200rpx;
  162. height: 200rpx;
  163. border: 1px solid #f1f1f1;
  164. margin: 10rpx;
  165. display: flex;
  166. justify-content: center;
  167. align-items: center;
  168. border-radius: 10rpx;
  169. }
  170. </style>