ImportVue.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. <template>
  2. <n-button type="primary" @click="showImportModal">导入数据</n-button>
  3. <n-modal
  4. v-model:show="showModal"
  5. :show-icon="false"
  6. preset="dialog"
  7. title="导入"
  8. >
  9. <n-form :model="formValue" label-width="auto" show-require-mark>
  10. <n-form-item label="数据">
  11. <n-upload :default-upload="false" :max="1" @change="handleChange">
  12. <div style="display: flex;align-items: center;">
  13. <n-button>上传文件</n-button>
  14. <div style="margin-left: 20px;color: #2d8cf0;">进度:{{ sum }}/{{ dataList.length }}</div>
  15. </div>
  16. </n-upload>
  17. </n-form-item>
  18. </n-form>
  19. <div style="float: right;">
  20. <n-button @click="showModal=false">
  21. 取消
  22. </n-button>
  23. <n-button type="primary" @click="submitCallback" :disabled="disableds" style="margin-left: 20px;">
  24. 确认
  25. </n-button>
  26. </div>
  27. </n-modal>
  28. </template>
  29. <script setup>
  30. import { addTaskDatas } from '@/api';
  31. import { read, utils } from 'xlsx';
  32. import { useDateFormat } from '@vueuse/core';
  33. import { ref, watch } from 'vue';
  34. const props = defineProps({
  35. task: {
  36. required: true,
  37. default: {},
  38. },
  39. });
  40. const disableds = ref(false)
  41. const message = useMessage();
  42. const sum = ref(0)
  43. // 是否展示 Modal
  44. const showModal = ref(false);
  45. //
  46. const dataList = ref([]);
  47. /* 读取文件 */
  48. const readFile = (file) => {
  49. return new Promise((resolve) => {
  50. const reader = new FileReader();
  51. reader.readAsBinaryString(file);
  52. reader.onload = (ev) => {
  53. resolve(ev.target.result);
  54. };
  55. });
  56. };
  57. // 组件状态变化的回调
  58. const handleChange = async ({ file }) => {
  59. const dataBinary = await readFile(file.file);
  60. const workBook = read(dataBinary, {
  61. type: 'binary',
  62. cellDates: true,
  63. });
  64. const workSheet = workBook.Sheets[workBook.SheetNames[0]];
  65. dataList.value = utils.sheet_to_json(workSheet);
  66. dataList.value.forEach((item) => {
  67. item['记录时间'] = useDateFormat(
  68. item['记录时间'],
  69. 'YYYY-MM-DD HH:mm:ss'
  70. ).value;
  71. });
  72. };
  73. // 表单数据
  74. const formValue = reactive({
  75. Time_start: null,
  76. Time_end: null,
  77. T_sn: '',
  78. T_id: '',
  79. page: 1,
  80. page_z: 9999,
  81. });
  82. // 显示导入
  83. const showImportModal = () => {
  84. sum.value = 0
  85. showModal.value = true;
  86. disableds.value = false
  87. };
  88. watch(showModal,(newVal)=>{
  89. if(!newVal){
  90. sum.value = 0
  91. dataList.value=[]
  92. }
  93. })
  94. //
  95. const submitCallback = async () => {
  96. sum.value = 0
  97. if(dataList.value.length==0){
  98. message.error('没有可导入数据哦,检查文件是否为空数据')
  99. return
  100. }else{
  101. disableds.value = true
  102. let chunk = 100;
  103. for (let i = 0; i < dataList.value.length; i += chunk) {
  104. let dataIt = await dataFun(dataList.value.slice(i, i + chunk))
  105. const resIt = await addTask(dataIt)
  106. sum.value += Number(resIt.data.Data)
  107. if(sum.value==dataList.value.length){
  108. message.success('数据导入完成')
  109. // disableds.value = false
  110. }
  111. }
  112. }
  113. };
  114. const dataFun = (arr)=>{
  115. return new Promise(resolve=>{
  116. const arr1 = arr.map(item => item['SN'] + '|' + item['编号'] + '|' + item['温度℃'] + '|' + item['湿度%'] + '|' + item['记录时间'])
  117. setTimeout(()=>{
  118. resolve(arr1.join('?'))
  119. },100)
  120. })
  121. }
  122. //
  123. const addTask = async (item) => {
  124. return new Promise(resolve=>{
  125. setTimeout(() => {
  126. const res = addTaskDatas({
  127. T_task_id: props.task.T_task_id,
  128. T_Data:item
  129. });
  130. resolve(res)
  131. },100)
  132. })
  133. };
  134. </script>
  135. <style lang="scss" scoped></style>