DbBackupLog.vue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. <template>
  2. <div class="qpage">
  3. <el-form :inline="true" :model="queryForm" class="query-form-inline" label-width="auto">
  4. <el-form-item label="备份对象">
  5. <el-select v-model="queryForm.tabsort" clearable>
  6. <el-option v-for="(item,index) in backupTargets" :key="index" :label="item.name" :value="item.sort"/>
  7. </el-select>
  8. </el-form-item>
  9. <el-form-item label="备份时间">
  10. <el-date-picker
  11. v-model="queryForm.dataTime"
  12. type="daterange"
  13. start-placeholder="开始时间"
  14. end-placeholder="截止时间"
  15. :unlink-panels="true"
  16. value-format="YYYY-MM-DD"
  17. />
  18. </el-form-item>
  19. <el-form-item>
  20. <el-button type="primary" :loading="isQuerying" @click="queryHandle">检索</el-button>
  21. </el-form-item>
  22. </el-form>
  23. <div class="qpage-body">
  24. <CrudTable
  25. ref="crudTable"
  26. page-info-opts="total, prev, pager, next,sizes"
  27. url="/backup/log/query"
  28. :pageSize="20"
  29. >
  30. <template #tabColumns={indexGenerate}>
  31. <el-table-column type="index" :index="indexGenerate" label="序号" width="60" align="center"/>
  32. <el-table-column prop="taskName" label="备份任务" width="160" />
  33. <el-table-column prop="startTime" label="开始时间" width="160" />
  34. <el-table-column prop="endTime" label="结束时间" width="160" />
  35. <el-table-column prop="duration" label="用时(秒)" width="100" />
  36. <el-table-column prop="operator" label="操作人" width="120"/>
  37. <el-table-column prop="status" label="状态" width="90">
  38. <template #default="scope">
  39. {{ {'success':'成功','running':'备份中','failed':'已失败'}[scope.row.status] || '' }}
  40. </template>
  41. </el-table-column>
  42. <el-table-column prop="note" label="备份文件" width="100" align="center">
  43. <template #default="scope">
  44. <el-button type="primary" plain size="small" v-if="scope.row.status=='success'" @click="dwnbackup(scope.row)">下载</el-button>
  45. </template>
  46. </el-table-column>
  47. </template>
  48. </CrudTable>
  49. </div>
  50. </div>
  51. </template>
  52. <script setup>
  53. import {reactive,ref,onMounted,toRaw} from 'vue'
  54. import CrudTable from "../../components/crudtable/CrudTable.vue"
  55. import {ElMessageBox,ElMessage} from 'element-plus'
  56. import api from "../../api/dbBackup.js"
  57. const crudTable=ref(null)
  58. const isQuerying=ref(false)
  59. const queryForm = reactive({
  60. tabsort: null,
  61. dataTime:null
  62. })
  63. const backupTargets=ref([])
  64. const queryHandle=()=>{
  65. isQuerying.value=true
  66. let formdata=toRaw(queryForm)
  67. let [startTime,endTime]=formdata.dataTime||[]
  68. formdata['startTime']=startTime
  69. formdata['endTime']=endTime
  70. crudTable.value.query(formdata).then(resp=>{
  71. isQuerying.value=false
  72. })
  73. }
  74. onMounted(()=>{
  75. load()
  76. })
  77. const load=()=>{
  78. api.getBackupTarget().then(resp=>{
  79. if(resp.code!=0){
  80. ElMessage.error(resp.msg || '加载数据失败')
  81. }
  82. else{
  83. backupTargets.value=respProcess(resp.data)
  84. }
  85. }).catch(err=>{
  86. console.log(err)
  87. ElMessage.error('加载数据出错')
  88. })
  89. }
  90. const respProcess=(datas)=>{
  91. let sortary=[],sortidx={}
  92. datas.forEach(data=>{
  93. if(!sortidx[data.tagCode]){
  94. sortary.push({sort:data.tagCode,name:data.tagName})
  95. sortidx[data.tagCode]=true
  96. }
  97. })
  98. let defaultBack={sort:'glb',name:'全库表结构'}
  99. return [defaultBack,...sortary]
  100. }
  101. const dwnbackup=(record)=>{
  102. api.downloadBackup(record.backupId).then(resp=>{
  103. //console.log(resp)
  104. const fileReader = new FileReader();
  105. fileReader.readAsText(resp.data)
  106. fileReader.onload = (event) => {
  107. try{
  108. const data = JSON.parse(event.target.result)
  109. if(data.code!=0){
  110. ElMessage.error(data.msg || '下载文件失败')
  111. }
  112. }
  113. catch(err){
  114. parseDownloadFile(resp)
  115. }
  116. }
  117. }).catch(err=>{
  118. console.log(err)
  119. ElMessage.error('下载文件出现网络错误')
  120. })
  121. }
  122. const parseDownloadFile=(res)=>{
  123. const fileName = decodeURI(res.headers['content-disposition']).replace(/\w+;filename=(.*)/, '$1')
  124. //console.log(fileName)
  125. const blob = new Blob([res.data], { type: "application/octet-stream"})
  126. const fileUrl = window.URL.createObjectURL(blob)
  127. let link = document.createElement('a')
  128. link.href = fileUrl
  129. link.download = decodeURI(fileName) //设置下载的文件名
  130. link.style.display = 'none'
  131. document.body.appendChild(link)
  132. link.click()
  133. document.body.removeChild(link)
  134. window.URL.revokeObjectURL(fileUrl)
  135. }
  136. </script>
  137. <style scoped>
  138. @import url('../../assets/css/qpage.css');
  139. .edit-form-item{
  140. width:260px;
  141. }
  142. </style>