refactor(app): 将许可证文件功能替换为配置文件功能
- 替换 LicenseFileCrypto 为 ConfigFileCrypto 加密类 - 将 /license-file 相关接口重命名为 /config-file - 修改数据库实体中的 licenseFileContent 字段为 configFileContent - 更新前端 API 调用从 downloadLicenseFile 改为 downloadConfigFile - 将安全中心的 License 文件解析功能改为 Config 文件解析 - 更新文件扩展名从 .xuqmlicense 改为 .xuqmconfig - 修改后端服务方法 ensureLicenseFile 为 ensureConfigFile - 调整加密解密逻辑以支持新的配置文件格式
这个提交包含在:
父节点
62966dcf20
当前提交
348c04ba72
@ -196,17 +196,17 @@ export const appApi = {
|
|||||||
resetSecret: (appKey: string, code: string) =>
|
resetSecret: (appKey: string, code: string) =>
|
||||||
client.post<{ data: { appSecret: string } }>(`/apps/${appKey}/reset-secret`, { code }),
|
client.post<{ data: { appSecret: string } }>(`/apps/${appKey}/reset-secret`, { code }),
|
||||||
|
|
||||||
downloadLicenseFile: (appKey: string) =>
|
downloadConfigFile: (appKey: string) =>
|
||||||
client.get<Blob>(`/apps/${appKey}/license-file`, { responseType: 'blob' }),
|
client.get<Blob>(`/apps/${appKey}/config-file`, { responseType: 'blob' }),
|
||||||
|
|
||||||
requestActivation: (appKey: string, serviceType: 'IM' | 'PUSH' | 'UPDATE' | 'LICENSE', reason: string) =>
|
requestActivation: (appKey: string, serviceType: 'IM' | 'PUSH' | 'UPDATE' | 'LICENSE', reason: string) =>
|
||||||
client.post<{ data: null }>(`/apps/${appKey}/services/request-activation`, null, {
|
client.post<{ data: null }>(`/apps/${appKey}/services/request-activation`, null, {
|
||||||
params: { platform: 'ANDROID', serviceType, applyReason: reason },
|
params: { platform: 'ANDROID', serviceType, applyReason: reason },
|
||||||
}),
|
}),
|
||||||
|
|
||||||
parseLicenseFile: (content: string) =>
|
parseConfigFile: (content: string) =>
|
||||||
client.post<{ data: { appKey: string; appName: string; packageName: string; iosBundleId: string; harmonyBundleName: string; baseUrl: string; serverUrl: string } }>(
|
client.post<{ data: { appKey: string; appName: string; packageName: string; iosBundleId: string; harmonyBundleName: string; baseUrl: string; serverUrl: string } }>(
|
||||||
'/apps/license/parse',
|
'/apps/config/parse',
|
||||||
{ content },
|
{ content },
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,8 +23,8 @@
|
|||||||
<el-button link type="warning" @click="openVerifyDialog('RESET_SECRET')">重置</el-button>
|
<el-button link type="warning" @click="openVerifyDialog('RESET_SECRET')">重置</el-button>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="简述" :span="2">{{ app.description ?? '-' }}</el-descriptions-item>
|
<el-descriptions-item label="简述" :span="2">{{ app.description ?? '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="License 文件">
|
<el-descriptions-item label="Config 文件">
|
||||||
<el-button size="small" type="primary" plain @click="downloadLicenseFile">下载</el-button>
|
<el-button size="small" type="primary" plain @click="downloadConfigFile">下载</el-button>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</el-card>
|
</el-card>
|
||||||
@ -353,12 +353,12 @@ async function submitVerify() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function downloadLicenseFile() {
|
async function downloadConfigFile() {
|
||||||
const current = app.value
|
const current = app.value
|
||||||
if (!current) return
|
if (!current) return
|
||||||
const res = await appApi.downloadLicenseFile(current.appKey)
|
const res = await appApi.downloadConfigFile(current.appKey)
|
||||||
const disposition = res.headers['content-disposition'] as string | undefined
|
const disposition = res.headers['content-disposition'] as string | undefined
|
||||||
const filename = parseFilename(disposition) ?? `${current.name || current.appKey}.xuqmlicense`
|
const filename = parseFilename(disposition) ?? `${current.name || current.appKey}.xuqmconfig`
|
||||||
const url = URL.createObjectURL(res.data)
|
const url = URL.createObjectURL(res.data)
|
||||||
const link = document.createElement('a')
|
const link = document.createElement('a')
|
||||||
link.href = url
|
link.href = url
|
||||||
|
|||||||
@ -67,40 +67,40 @@
|
|||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- License 文件解析 -->
|
<!-- Config 文件解析 -->
|
||||||
<el-card style="margin-bottom: 16px">
|
<el-card style="margin-bottom: 16px">
|
||||||
<template #header>License 文件解析</template>
|
<template #header>Config 文件解析</template>
|
||||||
<p style="color: #606266; margin: 0 0 16px;">
|
<p style="color: #606266; margin: 0 0 16px;">
|
||||||
上传已下载的 License 文件(.xuqmlicense),解析并验证文件内容。
|
上传已下载的 Config 文件(.xuqmconfig),解析并验证文件内容。
|
||||||
</p>
|
</p>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="licenseFileContent"
|
v-model="configFileContent"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
:rows="4"
|
:rows="4"
|
||||||
placeholder="将 License 文件内容粘贴到此处,或点击上传文件"
|
placeholder="将 Config 文件内容粘贴到此处,或点击上传文件"
|
||||||
style="margin-bottom: 12px"
|
style="margin-bottom: 12px"
|
||||||
/>
|
/>
|
||||||
<div style="display: flex; gap: 12px; flex-wrap: wrap; align-items: center;">
|
<div style="display: flex; gap: 12px; flex-wrap: wrap; align-items: center;">
|
||||||
<el-upload
|
<el-upload
|
||||||
ref="licenseUploadRef"
|
ref="configUploadRef"
|
||||||
action="#"
|
action="#"
|
||||||
:auto-upload="false"
|
:auto-upload="false"
|
||||||
:on-change="handleLicenseFileChange"
|
:on-change="handleConfigFileChange"
|
||||||
:show-file-list="false"
|
:show-file-list="false"
|
||||||
accept=".xuqmlicense"
|
accept=".xuqmconfig"
|
||||||
>
|
>
|
||||||
<el-button type="primary" plain>选择 License 文件</el-button>
|
<el-button type="primary" plain>选择 Config 文件</el-button>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
<el-button :loading="parsingLicense" @click="parseLicense">解析</el-button>
|
<el-button :loading="parsingConfig" @click="parseConfig">解析</el-button>
|
||||||
<el-button v-if="licenseParseResult" @click="clearLicenseParse">清除</el-button>
|
<el-button v-if="configParseResult" @click="clearConfigParse">清除</el-button>
|
||||||
</div>
|
</div>
|
||||||
<el-descriptions v-if="licenseParseResult" :column="isMobile ? 1 : 2" border style="margin-top: 16px">
|
<el-descriptions v-if="configParseResult" :column="isMobile ? 1 : 2" border style="margin-top: 16px">
|
||||||
<el-descriptions-item label="AppKey">{{ licenseParseResult.appKey }}</el-descriptions-item>
|
<el-descriptions-item label="AppKey">{{ configParseResult.appKey }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="应用名称">{{ licenseParseResult.appName || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="应用名称">{{ configParseResult.appName || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="Android 包名">{{ licenseParseResult.packageName || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="Android 包名">{{ configParseResult.packageName || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="iOS BundleId">{{ licenseParseResult.iosBundleId || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="iOS BundleId">{{ configParseResult.iosBundleId || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="鸿蒙 BundleName">{{ licenseParseResult.harmonyBundleName || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="鸿蒙 BundleName">{{ configParseResult.harmonyBundleName || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="服务地址">{{ licenseParseResult.serverUrl || licenseParseResult.baseUrl || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="服务地址">{{ configParseResult.serverUrl || configParseResult.baseUrl || '-' }}</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
@ -286,10 +286,10 @@ const selectedApp = ref<App | null>(null)
|
|||||||
const dialogMode = ref<'REVEAL_SECRET' | 'RESET_SECRET'>('REVEAL_SECRET')
|
const dialogMode = ref<'REVEAL_SECRET' | 'RESET_SECRET'>('REVEAL_SECRET')
|
||||||
const secretResult = ref('')
|
const secretResult = ref('')
|
||||||
|
|
||||||
// License file parse
|
// Config file parse
|
||||||
const licenseFileContent = ref('')
|
const configFileContent = ref('')
|
||||||
const parsingLicense = ref(false)
|
const parsingConfig = ref(false)
|
||||||
const licenseParseResult = ref<{
|
const configParseResult = ref<{
|
||||||
appKey: string
|
appKey: string
|
||||||
appName: string
|
appName: string
|
||||||
packageName: string
|
packageName: string
|
||||||
@ -298,42 +298,42 @@ const licenseParseResult = ref<{
|
|||||||
baseUrl: string
|
baseUrl: string
|
||||||
serverUrl: string
|
serverUrl: string
|
||||||
} | null>(null)
|
} | null>(null)
|
||||||
const licenseUploadRef = ref<any>(null)
|
const configUploadRef = ref<any>(null)
|
||||||
const isMobile = ref(false)
|
const isMobile = ref(false)
|
||||||
function updateViewport() {
|
function updateViewport() {
|
||||||
isMobile.value = window.innerWidth < 768
|
isMobile.value = window.innerWidth < 768
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleLicenseFileChange(file: any) {
|
function handleConfigFileChange(file: any) {
|
||||||
const reader = new FileReader()
|
const reader = new FileReader()
|
||||||
reader.onload = (e) => {
|
reader.onload = (e) => {
|
||||||
licenseFileContent.value = (e.target?.result as string) || ''
|
configFileContent.value = (e.target?.result as string) || ''
|
||||||
}
|
}
|
||||||
reader.readAsText(file.raw)
|
reader.readAsText(file.raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function parseLicense() {
|
async function parseConfig() {
|
||||||
if (!licenseFileContent.value.trim()) {
|
if (!configFileContent.value.trim()) {
|
||||||
ElMessage.warning('请输入或上传 License 文件内容')
|
ElMessage.warning('请输入或上传 Config 文件内容')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
parsingLicense.value = true
|
parsingConfig.value = true
|
||||||
try {
|
try {
|
||||||
const res = await appApi.parseLicenseFile(licenseFileContent.value.trim())
|
const res = await appApi.parseConfigFile(configFileContent.value.trim())
|
||||||
licenseParseResult.value = res.data.data
|
configParseResult.value = res.data.data
|
||||||
ElMessage.success('解析成功')
|
ElMessage.success('解析成功')
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
ElMessage.error(e?.response?.data?.message || '解析失败,请检查文件内容')
|
ElMessage.error(e?.response?.data?.message || '解析失败,请检查文件内容')
|
||||||
} finally {
|
} finally {
|
||||||
parsingLicense.value = false
|
parsingConfig.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearLicenseParse() {
|
function clearConfigParse() {
|
||||||
licenseFileContent.value = ''
|
configFileContent.value = ''
|
||||||
licenseParseResult.value = null
|
configParseResult.value = null
|
||||||
if (licenseUploadRef.value) {
|
if (configUploadRef.value) {
|
||||||
licenseUploadRef.value.clearFiles()
|
configUploadRef.value.clearFiles()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
正在加载...
在新工单中引用
屏蔽一个用户