index.vue 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. <template>
  2. <el-container>
  3. <el-dialog v-model="updateVisible" :close-on-click-modal="false" :title="$t('header.softwareDownload')">
  4. <div class="desc line-30 fs-16">{{updateResult.desc}}</div>
  5. </el-dialog>
  6. <el-dialog v-model="detailVisible" :title="$t('ota.versionDetail')" width="600px">
  7. <div v-html="currentVersionDetail" class="version-detail-content te-l"></div>
  8. </el-dialog>
  9. <el-main>
  10. <div class="version-check-container">
  11. <el-card class="current-version-card fs-14 te-l">
  12. <p>{{ $t('ota.currentVersion') }}<span class="fs-14"> {{ currentVersion }}</span></p>
  13. <div class="flex left">
  14. <p >{{ $t('ota.status') }} <span :class="{ 'text-green': isLatest, 'text-red': !isLatest }">{{ isLatest ? $t('ota.latest') : $t('ota.newVersion') }}</span></p>
  15. <p class="mar-left-10" v-if="!isLatest"> {{ latest.version }}</p>
  16. <el-button v-if="!isLatest" class="mar-left-20" type="primary" @click="downloadUpdate">{{ $t('ota.downloadUpdate') }}</el-button>
  17. </div>
  18. <p>{{ $t('ota.changelog') }}</p>
  19. <div v-html="latest.detail"></div>
  20. </el-card>
  21. <el-card class="history-versions-card mar-top-10">
  22. <h3>{{ $t('ota.historyVersions') }}</h3>
  23. <el-table :data="paginatedVersions" border>
  24. <el-table-column prop="version" :label="$t('ota.versionNumber')" width="70"></el-table-column>
  25. <el-table-column prop="release_date" :label="$t('ota.releaseDate')" width="100">
  26. <template #default="{ row }">{{row.release_date.substr(0,10)}}</template>
  27. </el-table-column>
  28. <el-table-column :label="$t('ota.description')">
  29. <template #default="{ row }">{{row.overview}}</template>
  30. </el-table-column>
  31. <el-table-column :label="$t('ota.operation')" width="180">
  32. <template #default="{ row }">
  33. <el-button style="width: 70px;" size="small" @click="downloadSpecificVersion(row.attachment)">{{ $t('common.download') }}</el-button>
  34. <el-button style="width: 70px;" size="small" type="info" @click="showDetail(row)">{{ $t('ota.versionDetail') }}</el-button>
  35. </template>
  36. </el-table-column>
  37. </el-table>
  38. <el-pagination layout="prev, pager, next" :total="totalItems" :page-size="pageSize" v-model:current-page="currentPage" @current-change="handlePageChange" style="margin-top: 15px;" />
  39. </el-card>
  40. </div>
  41. </el-main>
  42. </el-container>
  43. </template>
  44. <script setup>
  45. import { ref, onMounted, computed } from 'vue';
  46. import { useI18n } from 'vue-i18n';
  47. import { ElMessage } from 'element-plus';
  48. import client from "@/stores/modules/client";
  49. import icpList from '@/utils/ipc';
  50. import UpdateDialog from '@/components/UpdateDialog'
  51. import { getVersionByRoleType } from '@/apis/other'
  52. const { t } = useI18n()
  53. const currentVersion = ref('0.0.0');
  54. const latest = ref({});
  55. const isLatest = ref(true);
  56. const versions = ref([]);
  57. const currentPage = ref(1);
  58. const pageSize = ref(20);
  59. const totalItems = ref(0);
  60. const paginatedVersions = computed(() => {
  61. const start = (currentPage.value - 1) * pageSize.value;
  62. return (versions.value || []).slice(start, start + pageSize.value);
  63. });
  64. const fetchVersions = async () => {
  65. try {
  66. const { data } = await getVersionByRoleType({ role_type: 6 })
  67. versions.value = data;
  68. if (data.length > 0) {
  69. latest.value = data[0];
  70. isLatest.value = compareVersions(currentVersion.value, latest.value.version) >= 0;
  71. }
  72. totalItems.value = versions.value.length;
  73. } catch (error) {
  74. ElMessage.error(t('ota.downloadFailed'));
  75. }
  76. };
  77. const compareVersions = (v1, v2) => {
  78. const parts1 = v1.split('.').map(Number); const parts2 = v2.split('.').map(Number);
  79. for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
  80. const num1 = parts1[i] || 0; const num2 = parts2[i] || 0;
  81. if (num1 > num2) return 1; if (num1 < num2) return -1;
  82. }
  83. return 0;
  84. };
  85. const downloadUpdate = () => { downloadSpecificVersion(versions.value[0].attachment) };
  86. const updateVisible = ref(false)
  87. const updateResult = ref({})
  88. const detailVisible = ref(false)
  89. const currentVersionDetail = ref('')
  90. const clientStore = client();
  91. const downloadSpecificVersion = (url) => {
  92. const urlWithTimestamp = url + (url.includes('?') ? '&' : '?') + '_t=' + new Date().getTime();
  93. clientStore.ipc.removeAllListeners('app.updater');
  94. clientStore.ipc.removeAllListeners(icpList.ota.updateVersion);
  95. clientStore.ipc.send(icpList.ota.updateVersion, urlWithTimestamp);
  96. clientStore.ipc.on('app.updater', async (event, result) => {
  97. try {
  98. let res = JSON.parse(result)
  99. if([1,3,4].includes(res.status)){ updateResult.value = res; updateVisible.value = true }
  100. else { updateVisible.value = false; ElMessage.error(t('ota.downloadFailed')) }
  101. }catch (e) {}
  102. });
  103. };
  104. const handlePageChange = (page) => { currentPage.value = page; };
  105. const showDetail = (row) => { currentVersionDetail.value = row.detail || t('ota.noDetail'); detailVisible.value = true; };
  106. onMounted(async () => {
  107. currentVersion.value = '1.0.0' // version from package.json
  108. fetchVersions();
  109. });
  110. </script>
  111. <style scoped>
  112. .version-detail-content { max-height: 400px; overflow-y: auto; line-height: 1.6; }
  113. </style>