index.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. <script setup lang="ts">
  2. import { ref, onMounted } from "vue";
  3. import { useRoute, useRouter } from "vue-router";
  4. import * as XLSX from "xlsx";
  5. import {
  6. assessmentDownloadDataRosterTemplateApi,
  7. postImportAssessmentTemplate
  8. } from "@/api/download";
  9. import { ElMessage } from "element-plus";
  10. defineOptions({
  11. name: "IndexDefineImport"
  12. });
  13. const route = useRoute();
  14. const router = useRouter();
  15. const emit = defineEmits(["handleImport"]);
  16. const uploadShow = ref(true);
  17. const query = ref({});
  18. const fileDocument = ref<File | null>(null); // 存储文件
  19. onMounted(() => {
  20. // assessmentType
  21. Object.assign(query.value, route.query);
  22. console.log("111", query.value);
  23. });
  24. const uploadFile = () => {};
  25. const tableHeaders = ref<any>([]);
  26. const tableData = ref<any>([
  27. { name: "" },
  28. { defin: "" },
  29. { caliber: "" },
  30. { type: "" },
  31. { from: "" }
  32. ]);
  33. const handleUploadChange = (file: File) => {
  34. fileDocument.value = file; // 保存文件
  35. const reader = new FileReader();
  36. let fileType = file.name.slice(-4);
  37. console.log("文件", file.name.slice(-4));
  38. if (fileType == "xlsx") {
  39. reader.onload = e => {
  40. const data = new Uint8Array(e.target?.result as ArrayBuffer);
  41. const workbook = XLSX.read(data, { type: "array" }); // 读取 Excel 文件
  42. const firstSheetName = workbook.SheetNames[0]; // 获取第一个工作表名
  43. const worksheet = workbook.Sheets[firstSheetName]; // 获取第一个工作表
  44. const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 }); // 将工作表转为 JSON
  45. if (jsonData.length > 0) {
  46. tableHeaders.value = jsonData[0]; // 表头
  47. tableData.value = jsonData.slice(1).map(row => {
  48. const rowData = {};
  49. tableHeaders.value.forEach((header, index) => {
  50. rowData[header] = row[index] !== undefined ? row[index] : null; // 填充缺失值
  51. });
  52. return rowData;
  53. });
  54. console.log("表头", tableHeaders.value);
  55. ElMessage.success("文件上传成功");
  56. uploadShow.value = false; // 隐藏上传区域,显示数据表
  57. } else {
  58. ElMessage.error("文件为空或格式不正确");
  59. }
  60. };
  61. } else {
  62. ElMessage.error("请上传xlsx文件");
  63. }
  64. reader.readAsArrayBuffer(file); // 读取文件为 ArrayBuffer
  65. };
  66. // 上传
  67. const postImportAssessmentTemplateApi = async data => {
  68. if (!fileDocument.value) {
  69. ElMessage.error("请先上传文件");
  70. return;
  71. }
  72. try {
  73. const formData = new FormData();
  74. formData.append("file", fileDocument.value); // 将文件添加到表单数据
  75. // 调用 API 上传文件
  76. const { data } = await postImportAssessmentTemplate({
  77. formData,
  78. type: route.query.assessmentType,
  79. assessmentId: route.query.id
  80. });
  81. console.log("dsada", data);
  82. if (data.code === 200) {
  83. // 根据后端返回的 code 判断是否成功
  84. ElMessage.success("文件上传并导入成功");
  85. // 重置上传状态
  86. // uploadShow.value = true;
  87. // $router.push("/IndexDefine/children/define");
  88. router.back();
  89. uploadShow.value = !uploadShow.value;
  90. tableHeaders.value = []; // 清空表头
  91. tableData.value = [
  92. { name: "" },
  93. { defin: "" },
  94. { caliber: "" },
  95. { type: "" },
  96. { from: "" }
  97. ]; // 清空表格数据
  98. } else {
  99. ElMessage.error(data.msg);
  100. }
  101. } catch (error) {
  102. ElMessage.error("上传失败,请重试");
  103. console.error(error);
  104. }
  105. };
  106. const backDefine = () => {
  107. router.back();
  108. };
  109. </script>
  110. <template>
  111. <div>
  112. <div class="w-3/4 m-auto mt-4">
  113. <div class="w-full bg p-3">
  114. <h5>1.下载导入模板</h5>
  115. <p class="text-xs mt-2 text">根据提升信息完善表格内容</p>
  116. <el-button
  117. class="mt-2"
  118. @click="
  119. assessmentDownloadDataRosterTemplateApi(route.query.assessmentType)
  120. "
  121. ><el-icon><Download /></el-icon>下载空的模板表格</el-button
  122. >
  123. </div>
  124. <div class="w-full mt-4 bg p-3">
  125. <h5>2.上传完善后的模板</h5>
  126. <p class="text-xs mt-2 text mb-2">
  127. 更新信息的模板中,如有空的数据列,则相应字段信息会被清空,请谨慎填写
  128. </p>
  129. <div v-if="uploadShow">
  130. <el-upload
  131. class="upload-demo"
  132. drag
  133. action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
  134. :before-upload="file => handleUploadChange(file)"
  135. :show-file-list="false"
  136. >
  137. <el-icon class="el-icon--upload"><upload-filled /></el-icon>
  138. <div class="el-upload__text">
  139. 点击<em>图标选择上传</em>或者将文件拖拽到此区域
  140. </div>
  141. </el-upload>
  142. </div>
  143. <div v-else class="mb-2">
  144. <el-table
  145. :data="tableData"
  146. border
  147. style="width: 100%"
  148. max-height="250"
  149. >
  150. <el-table-column
  151. v-for="header in tableHeaders"
  152. :key="header"
  153. :label="header"
  154. :prop="header"
  155. />
  156. </el-table>
  157. </div>
  158. <div class="float-right">
  159. <el-button @click="backDefine">取消</el-button>
  160. <el-button type="primary" @click="postImportAssessmentTemplateApi"
  161. >确认</el-button
  162. >
  163. </div>
  164. <p class="h-11 no-select">.</p>
  165. </div>
  166. </div>
  167. </div>
  168. </template>
  169. <style lang="scss" scoped>
  170. .bg {
  171. background-color: #f8f9fa;
  172. }
  173. .text {
  174. color: #999;
  175. }
  176. .upoload {
  177. float: right;
  178. }
  179. .no-select {
  180. color: rgb(255 255 255 / 0%);
  181. user-select: none;
  182. }
  183. </style>