Merge branch fix/app-version-batch
This commit is contained in:
commit
18234ebd5b
2 files changed
+253
-58
No files matched your search
@@ -49,6 +49,10 @@ export const createAppVersionApi = (data: AppVersionSaveData) => {
|
|||||||
return request.post<string>({ url: '/admin/app-versions', data })
|
return request.post<string>({ url: '/admin/app-versions', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const batchCreateAppVersionsApi = (data: AppVersionSaveData[]) => {
|
||||||
|
return request.post<string[]>({ url: '/admin/app-versions/batch', data })
|
||||||
|
}
|
||||||
|
|
||||||
export const updateAppVersionApi = (id: string | number, data: AppVersionSaveData) => {
|
export const updateAppVersionApi = (id: string | number, data: AppVersionSaveData) => {
|
||||||
return request.post<void>({ url: `/admin/app-versions/${id}`, data })
|
return request.post<void>({ url: `/admin/app-versions/${id}`, data })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import PageHeading from '@/views/components/PageHeading.vue'
|
|||||||
import { AppIcons } from '@/constants/icons'
|
import { AppIcons } from '@/constants/icons'
|
||||||
import { dateCell } from '@/utils/format'
|
import { dateCell } from '@/utils/format'
|
||||||
import {
|
import {
|
||||||
|
batchCreateAppVersionsApi,
|
||||||
createAppVersionApi,
|
createAppVersionApi,
|
||||||
deleteAppVersionApi,
|
deleteAppVersionApi,
|
||||||
listAppVersionsApi,
|
listAppVersionsApi,
|
||||||
@@ -43,16 +44,23 @@ const formLoading = ref(false)
|
|||||||
const editingId = ref<string | null>(null)
|
const editingId = ref<string | null>(null)
|
||||||
const formRef = ref<FormInstance>()
|
const formRef = ref<FormInstance>()
|
||||||
|
|
||||||
const emptyForm: AppVersionSaveData = {
|
/** 新建时两个平台一起配(各自可启停),编辑时用单份。 */
|
||||||
platform: 'ANDROID',
|
interface PlatformBlock {
|
||||||
|
enabled: boolean
|
||||||
|
data: AppVersionSaveData
|
||||||
|
}
|
||||||
|
const emptyPlatform = (platform: 'ANDROID' | 'IOS'): AppVersionSaveData => ({
|
||||||
|
platform,
|
||||||
versionCode: 0,
|
versionCode: 0,
|
||||||
versionName: '',
|
versionName: '',
|
||||||
downloadUrl: '',
|
downloadUrl: '',
|
||||||
updateContent: '',
|
updateContent: '',
|
||||||
forceUpdate: 0,
|
forceUpdate: 0,
|
||||||
minSupportedCode: 0
|
minSupportedCode: 0
|
||||||
}
|
})
|
||||||
const form = ref<AppVersionSaveData>({ ...emptyForm })
|
const androidBlock = ref<PlatformBlock>({ enabled: true, data: emptyPlatform('ANDROID') })
|
||||||
|
const iosBlock = ref<PlatformBlock>({ enabled: true, data: emptyPlatform('IOS') })
|
||||||
|
const editForm = ref<AppVersionSaveData>(emptyPlatform('ANDROID'))
|
||||||
|
|
||||||
const rules: FormRules = {
|
const rules: FormRules = {
|
||||||
platform: [{ required: true, message: '请选择平台', trigger: 'change' }],
|
platform: [{ required: true, message: '请选择平台', trigger: 'change' }],
|
||||||
@@ -91,13 +99,14 @@ async function fetchList() {
|
|||||||
|
|
||||||
function openCreate() {
|
function openCreate() {
|
||||||
editingId.value = null
|
editingId.value = null
|
||||||
form.value = { ...emptyForm }
|
androidBlock.value = { enabled: true, data: emptyPlatform('ANDROID') }
|
||||||
|
iosBlock.value = { enabled: true, data: emptyPlatform('IOS') }
|
||||||
dialogOpen.value = true
|
dialogOpen.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
function openEdit(row: AppVersionItem) {
|
function openEdit(row: AppVersionItem) {
|
||||||
editingId.value = row.id
|
editingId.value = row.id
|
||||||
form.value = {
|
editForm.value = {
|
||||||
platform: row.platform,
|
platform: row.platform,
|
||||||
versionCode: row.versionCode,
|
versionCode: row.versionCode,
|
||||||
versionName: row.versionName,
|
versionName: row.versionName,
|
||||||
@@ -110,26 +119,29 @@ function openEdit(row: AppVersionItem) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function submit() {
|
async function submit() {
|
||||||
if (!formRef.value) return
|
formLoading.value = true
|
||||||
await formRef.value.validate(async (valid) => {
|
try {
|
||||||
if (!valid) return
|
if (editingId.value) {
|
||||||
formLoading.value = true
|
await updateAppVersionApi(editingId.value, editForm.value)
|
||||||
try {
|
ElMessage.success('已更新')
|
||||||
if (editingId.value) {
|
} else {
|
||||||
await updateAppVersionApi(editingId.value, form.value)
|
const toCreate: AppVersionSaveData[] = []
|
||||||
ElMessage.success('已更新')
|
if (androidBlock.value.enabled) toCreate.push(androidBlock.value.data)
|
||||||
} else {
|
if (iosBlock.value.enabled) toCreate.push(iosBlock.value.data)
|
||||||
await createAppVersionApi(form.value)
|
if (toCreate.length === 0) {
|
||||||
ElMessage.success('已创建')
|
ElMessage.warning('至少启用一个平台')
|
||||||
|
return
|
||||||
}
|
}
|
||||||
dialogOpen.value = false
|
await batchCreateAppVersionsApi(toCreate)
|
||||||
await fetchList()
|
ElMessage.success(`已创建 ${toCreate.length} 条版本`)
|
||||||
} catch {
|
|
||||||
/* axios interceptor 已弹消息 */
|
|
||||||
} finally {
|
|
||||||
formLoading.value = false
|
|
||||||
}
|
}
|
||||||
})
|
dialogOpen.value = false
|
||||||
|
await fetchList()
|
||||||
|
} catch {
|
||||||
|
/* axios interceptor 已弹消息 */
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function toggleStatus(row: AppVersionItem) {
|
async function toggleStatus(row: AppVersionItem) {
|
||||||
@@ -241,23 +253,23 @@ const forceText = computed(() => (v: number) => (v === 1 ? '强制' : '可选升
|
|||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="dialogOpen"
|
v-model="dialogOpen"
|
||||||
:title="editingId ? '编辑版本' : '新建版本'"
|
:title="editingId ? '编辑版本' : '新建版本'"
|
||||||
width="640px"
|
width="820px"
|
||||||
@close="() => formRef?.resetFields()"
|
@close="() => formRef?.resetFields()"
|
||||||
>
|
>
|
||||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px" v-loading="formLoading">
|
<!-- 编辑模式:单平台 -->
|
||||||
|
<el-form
|
||||||
|
v-if="editingId"
|
||||||
|
ref="formRef"
|
||||||
|
:model="editForm"
|
||||||
|
:rules="rules"
|
||||||
|
label-width="120px"
|
||||||
|
v-loading="formLoading"
|
||||||
|
>
|
||||||
<el-row :gutter="12">
|
<el-row :gutter="12">
|
||||||
<el-col :span="12">
|
<el-col :span="8">
|
||||||
<el-form-item label="平台" prop="platform">
|
|
||||||
<el-radio-group v-model="form.platform">
|
|
||||||
<el-radio-button value="ANDROID">Android</el-radio-button>
|
|
||||||
<el-radio-button value="IOS">iOS</el-radio-button>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="6">
|
|
||||||
<el-form-item label="整数版本" prop="versionCode">
|
<el-form-item label="整数版本" prop="versionCode">
|
||||||
<el-input-number
|
<el-input-number
|
||||||
v-model="form.versionCode"
|
v-model="editForm.versionCode"
|
||||||
:min="1"
|
:min="1"
|
||||||
:max="999999"
|
:max="999999"
|
||||||
controls-position="right"
|
controls-position="right"
|
||||||
@@ -265,39 +277,196 @@ const forceText = computed(() => (v: number) => (v === 1 ? '强制' : '可选升
|
|||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="16">
|
||||||
<el-form-item label="展示版本" prop="versionName">
|
<el-form-item label="展示版本" prop="versionName">
|
||||||
<el-input v-model="form.versionName" placeholder="如 1.2.0" />
|
<el-input v-model="editForm.versionName" placeholder="如 1.2.0" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-form-item label="下载地址" prop="downloadUrl">
|
<el-form-item label="下载地址" prop="downloadUrl">
|
||||||
<el-input v-model="form.downloadUrl" placeholder="Android apk / iOS App Store 链接" />
|
<el-input v-model="editForm.downloadUrl" placeholder="Android apk / iOS App Store 链接" />
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="强制升级">
|
|
||||||
<el-switch
|
|
||||||
v-model="form.forceUpdate"
|
|
||||||
:active-value="1"
|
|
||||||
:inactive-value="0"
|
|
||||||
active-text="强制"
|
|
||||||
inactive-text="可选"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="兜底最低版本">
|
|
||||||
<el-input-number v-model="form.minSupportedCode" :min="0" controls-position="right" />
|
|
||||||
<span class="hint">低于此版本的客户端一律强制升级,0=不开启</span>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-row :gutter="12">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="强制升级">
|
||||||
|
<el-switch
|
||||||
|
v-model="editForm.forceUpdate"
|
||||||
|
:active-value="1"
|
||||||
|
:inactive-value="0"
|
||||||
|
active-text="强制"
|
||||||
|
inactive-text="可选"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="兜底最低版本">
|
||||||
|
<el-input-number
|
||||||
|
v-model="editForm.minSupportedCode"
|
||||||
|
:min="0"
|
||||||
|
controls-position="right"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
<el-form-item label="更新说明">
|
<el-form-item label="更新说明">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="form.updateContent"
|
v-model="editForm.updateContent"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
:rows="4"
|
:rows="3"
|
||||||
placeholder="换行分隔多条更新内容"
|
placeholder="换行分隔多条更新内容"
|
||||||
maxlength="2000"
|
maxlength="2000"
|
||||||
show-word-limit
|
show-word-limit
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
|
<!-- 新建模式:Android + iOS 两块 -->
|
||||||
|
<div v-else class="dual-blocks" v-loading="formLoading">
|
||||||
|
<div class="platform-block" :class="{ disabled: !androidBlock.enabled }">
|
||||||
|
<header>
|
||||||
|
<span class="platform-title">Android</span>
|
||||||
|
<el-switch
|
||||||
|
v-model="androidBlock.enabled"
|
||||||
|
active-text="启用"
|
||||||
|
inactive-text="跳过"
|
||||||
|
inline-prompt
|
||||||
|
/>
|
||||||
|
</header>
|
||||||
|
<el-form
|
||||||
|
:model="androidBlock.data"
|
||||||
|
:rules="rules"
|
||||||
|
label-width="120px"
|
||||||
|
:disabled="!androidBlock.enabled"
|
||||||
|
>
|
||||||
|
<el-row :gutter="12">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="整数版本" prop="versionCode">
|
||||||
|
<el-input-number
|
||||||
|
v-model="androidBlock.data.versionCode"
|
||||||
|
:min="1"
|
||||||
|
:max="999999"
|
||||||
|
controls-position="right"
|
||||||
|
class="w-full"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="16">
|
||||||
|
<el-form-item label="展示版本" prop="versionName">
|
||||||
|
<el-input v-model="androidBlock.data.versionName" placeholder="如 1.2.0" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-form-item label="下载地址" prop="downloadUrl">
|
||||||
|
<el-input v-model="androidBlock.data.downloadUrl" placeholder="apk 下载链接" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-row :gutter="12">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="强制升级">
|
||||||
|
<el-switch
|
||||||
|
v-model="androidBlock.data.forceUpdate"
|
||||||
|
:active-value="1"
|
||||||
|
:inactive-value="0"
|
||||||
|
active-text="强制"
|
||||||
|
inactive-text="可选"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="兜底最低">
|
||||||
|
<el-input-number
|
||||||
|
v-model="androidBlock.data.minSupportedCode"
|
||||||
|
:min="0"
|
||||||
|
controls-position="right"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-form-item label="更新说明">
|
||||||
|
<el-input
|
||||||
|
v-model="androidBlock.data.updateContent"
|
||||||
|
type="textarea"
|
||||||
|
:rows="3"
|
||||||
|
placeholder="换行分隔多条"
|
||||||
|
maxlength="2000"
|
||||||
|
show-word-limit
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="platform-block" :class="{ disabled: !iosBlock.enabled }">
|
||||||
|
<header>
|
||||||
|
<span class="platform-title">iOS</span>
|
||||||
|
<el-switch
|
||||||
|
v-model="iosBlock.enabled"
|
||||||
|
active-text="启用"
|
||||||
|
inactive-text="跳过"
|
||||||
|
inline-prompt
|
||||||
|
/>
|
||||||
|
</header>
|
||||||
|
<el-form
|
||||||
|
:model="iosBlock.data"
|
||||||
|
:rules="rules"
|
||||||
|
label-width="120px"
|
||||||
|
:disabled="!iosBlock.enabled"
|
||||||
|
>
|
||||||
|
<el-row :gutter="12">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="整数版本" prop="versionCode">
|
||||||
|
<el-input-number
|
||||||
|
v-model="iosBlock.data.versionCode"
|
||||||
|
:min="1"
|
||||||
|
:max="999999"
|
||||||
|
controls-position="right"
|
||||||
|
class="w-full"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="16">
|
||||||
|
<el-form-item label="展示版本" prop="versionName">
|
||||||
|
<el-input v-model="iosBlock.data.versionName" placeholder="如 1.2.0" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-form-item label="下载地址" prop="downloadUrl">
|
||||||
|
<el-input v-model="iosBlock.data.downloadUrl" placeholder="App Store 链接" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-row :gutter="12">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="强制升级">
|
||||||
|
<el-switch
|
||||||
|
v-model="iosBlock.data.forceUpdate"
|
||||||
|
:active-value="1"
|
||||||
|
:inactive-value="0"
|
||||||
|
active-text="强制"
|
||||||
|
inactive-text="可选"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="兜底最低">
|
||||||
|
<el-input-number
|
||||||
|
v-model="iosBlock.data.minSupportedCode"
|
||||||
|
:min="0"
|
||||||
|
controls-position="right"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-form-item label="更新说明">
|
||||||
|
<el-input
|
||||||
|
v-model="iosBlock.data.updateContent"
|
||||||
|
type="textarea"
|
||||||
|
:rows="3"
|
||||||
|
placeholder="换行分隔多条"
|
||||||
|
maxlength="2000"
|
||||||
|
show-word-limit
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="dialogOpen = false">取消</el-button>
|
<el-button @click="dialogOpen = false">取消</el-button>
|
||||||
<el-button type="primary" :loading="formLoading" @click="submit">
|
<el-button type="primary" :loading="formLoading" @click="submit">
|
||||||
@@ -315,9 +484,31 @@ const forceText = computed(() => (v: number) => (v === 1 ? '强制' : '可选升
|
|||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
.hint {
|
.dual-blocks {
|
||||||
margin-left: 8px;
|
display: flex;
|
||||||
font-size: 12px;
|
flex-direction: column;
|
||||||
color: var(--el-text-color-secondary);
|
gap: 16px;
|
||||||
|
}
|
||||||
|
.platform-block {
|
||||||
|
border: 1px solid var(--el-border-color-lighter);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 14px 16px 4px;
|
||||||
|
background: var(--el-fill-color-blank);
|
||||||
|
header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px solid var(--el-border-color-lighter);
|
||||||
|
}
|
||||||
|
.platform-title {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
&.disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
border-style: dashed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
Reference in new issue
Block a user