feat(electron): 实现系统托盘和关闭行为配置功能

- 添加系统托盘创建和销毁逻辑- 实现窗口关闭行为配置(退出/最小化/托盘)
- 添加配置文件读写功能
- 实现下载取消和清理功能
- 添加待更新文件检查机制
- 优化文件下载进度和错误处理
- 添加自动更新配置选项- 实现平滑滚动动画效果
- 添加试用期过期类型检查
-优化VIP状态刷新逻辑
This commit is contained in:
2025-10-17 14:17:47 +08:00
parent 6e1b4d00de
commit 07e34c35c8
19 changed files with 1545 additions and 467 deletions

View File

@@ -1,10 +1,15 @@
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { ref, computed, onMounted, defineAsyncComponent, inject } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { zebraApi, type ZebraOrder, type BanmaAccount } from '../../api/zebra'
import AccountManager from '../common/AccountManager.vue'
import { batchConvertImages } from '../../utils/imageProxy'
import { handlePlatformFileExport } from '../../utils/settings'
import { getUsernameFromToken } from '../../utils/token'
const TrialExpiredDialog = defineAsyncComponent(() => import('../common/TrialExpiredDialog.vue'))
const refreshVipStatus = inject<() => Promise<boolean>>('refreshVipStatus')
// 接收VIP状态
const props = defineProps<{
@@ -35,6 +40,12 @@ const fetchCurrentPage = ref(1)
const fetchTotalPages = ref(0)
const fetchTotalItems = ref(0)
const isFetching = ref(false)
// 试用期过期弹框
const showTrialExpiredDialog = ref(false)
const trialExpiredType = ref<'device' | 'account' | 'both'>('account')
const checkExpiredType = inject<() => 'device' | 'account' | 'both'>('checkExpiredType')
function selectAccount(id: number) {
accountId.value = id
loadShops()
@@ -68,7 +79,8 @@ async function loadShops() {
async function loadAccounts() {
try {
const res = await zebraApi.getAccounts()
const username = getUsernameFromToken()
const res = await zebraApi.getAccounts(username)
const list = (res as any)?.data ?? res
accounts.value = Array.isArray(list) ? list : []
const def = accounts.value.find(a => a.isDefault === 1) || accounts.value[0]
@@ -91,19 +103,13 @@ function handleCurrentChange(page: number) {
async function fetchData() {
if (isFetching.value) return
// 刷新VIP状态
if (refreshVipStatus) await refreshVipStatus()
// VIP检查
if (!props.isVip) {
try {
await ElMessageBox.confirm(
'VIP已过期数据采集功能受限。请联系管理员续费后继续使用。',
'VIP功能限制',
{
confirmButtonText: '我知道了',
showCancelButton: false,
type: 'warning'
}
)
} catch {}
if (checkExpiredType) trialExpiredType.value = checkExpiredType()
showTrialExpiredDialog.value = true
return
}
@@ -318,7 +324,8 @@ async function submitAccount() {
status: accountForm.value.status || 1,
}
try {
const res = await zebraApi.saveAccount(payload)
const username = getUsernameFromToken()
const res = await zebraApi.saveAccount(payload, username)
const id = (res as any)?.data?.id || (res as any)?.id
if (!id) throw new Error((res as any)?.msg || '保存失败')
accountDialogVisible.value = false
@@ -368,7 +375,6 @@ async function removeCurrentAccount() {
<span :class="['status-dot', a.status === 1 ? 'on' : 'off']"></span>
<img class="avatar" src="/image/img_v3_02qd_052605f0-4be3-44db-9691-35ee5ff6201g.jpg" alt="avatar" />
<span class="acct-text">{{ a.name || a.username }}</span>
<span v-if="a.isDefault===1" class="tag">默认</span>
<span v-if="accountId === a.id" class="acct-check"></span>
</span>
</div>
@@ -544,6 +550,10 @@ async function removeCurrentAccount() {
<el-button type="primary" class="btn-blue" style="width: 100%" @click="submitAccount">登录</el-button>
</template>
</el-dialog>
<!-- 试用期过期弹框 -->
<TrialExpiredDialog v-model="showTrialExpiredDialog" :expired-type="trialExpiredType" />
<AccountManager ref="accountManagerRef" v-model="managerVisible" platform="zebra" @add="openAddAccount" @refresh="loadAccounts" />
</div>
</template>