<script setup lang="tsx">
|
import { ref } from 'vue'
|
import { useRouter } from 'vue-router'
|
import { useMessage } from 'naive-ui'
|
import type { UploadFileInfo, FormRules, FormInst } from 'naive-ui'
|
import { customUploadRequest, beforeUploadCheck } from '@/utils/upload'
|
import { releaseAppVersion } from '@/service/api/appVersion'
|
|
const router = useRouter()
|
const message = useMessage()
|
const formRef = ref<FormInst | null>(null)
|
|
const formModel = ref({
|
version: '',
|
androidFiles: [] as UploadFileInfo[],
|
iosFiles: [] as UploadFileInfo[],
|
updateNote: '',
|
isForceUpdate: false
|
})
|
|
const rules: FormRules = {
|
version: [
|
{ required: true, message: '请输入版本号', trigger: ['blur', 'input'] }
|
],
|
androidFiles: [
|
{ required: true, type: 'array', message: '请上传安卓安装包', trigger: ['blur', 'change'] }
|
],
|
iosFiles: [
|
{ required: true, type: 'array', message: '请上传 iOS 安装包', trigger: ['blur', 'change'] }
|
],
|
updateNote: [
|
{ required: true, message: '请输入更新说明', trigger: ['blur', 'input'] }
|
]
|
}
|
|
function beforeUploadApk(data: { file: UploadFileInfo; fileList: UploadFileInfo[] }) {
|
return beforeUploadCheck(data, { maxSize: 500, allowedTypes: [] })
|
}
|
|
function beforeUploadIpa(data: { file: UploadFileInfo; fileList: UploadFileInfo[] }) {
|
return beforeUploadCheck(data, { maxSize: 500, allowedTypes: [] })
|
}
|
|
async function customRequest(options: any) {
|
await customUploadRequest(options)
|
}
|
|
async function handleConfirm() {
|
await formRef.value?.validate(async (errors) => {
|
if (!errors) {
|
const params = {
|
version: formModel.value.version,
|
androidFile: formModel.value.androidFiles[0]?.url || '',
|
iosFile: formModel.value.iosFiles[0]?.url || '',
|
updateDescription: formModel.value.updateNote,
|
forceUpdateFlag: formModel.value.isForceUpdate ? 1 : 0
|
}
|
|
if (!params.androidFile || !params.iosFile) {
|
message.error('请等待文件上传完成')
|
return
|
}
|
|
const { isSuccess } = await releaseAppVersion(params)
|
if (isSuccess) {
|
message.success('发布成功')
|
router.back()
|
}
|
} else {
|
message.error('请完善必填信息')
|
}
|
})
|
}
|
|
function handleCancel() {
|
router.back()
|
}
|
</script>
|
|
<template>
|
<div class="h-full flex flex-col bg-white rounded-md">
|
<div class="flex items-center px-6 pt-6 mb-6">
|
<div class="flex items-center relative pl-3">
|
<div class="absolute left-0 top-1/2 -translate-y-1/2 w-1 h-4 bg-[#0068FF] rounded-sm"></div>
|
<span class="text-base font-bold text-[#1D2129] ml-2">新增APP版本号</span>
|
</div>
|
</div>
|
|
<div class="flex-1 overflow-y-auto px-6">
|
<n-form
|
ref="formRef"
|
:model="formModel"
|
:rules="rules"
|
label-placement="left"
|
inline
|
require-mark-placement="left"
|
:show-feedback="false"
|
class="max-w-4xl flex flex-col gap-16px"
|
>
|
<n-form-item label="版本号" path="version">
|
<n-input v-model:value="formModel.version" placeholder="请输入版本号" class="!w-[400px]" />
|
</n-form-item>
|
|
<n-form-item label="安卓文件" path="androidFiles">
|
<div class="flex flex-col gap-2">
|
<n-upload
|
v-model:file-list="formModel.androidFiles"
|
:max="1"
|
accept=".apk"
|
:on-before-upload="beforeUploadApk"
|
:custom-request="customRequest"
|
:show-file-list="false"
|
>
|
<n-button style="width: 100px">
|
<template #icon>
|
<icon-park-outline-upload />
|
</template>
|
{{ formModel.androidFiles.length > 0 ? '重新上传' : '点击上传' }}
|
</n-button>
|
</n-upload>
|
|
<div v-if="formModel.androidFiles.length > 0" class="flex items-center bg-[#F5F6F8] px-3 py-2 rounded w-fit gap-3">
|
<svg-icons-android-filled class="text-[#00B42A] text-lg" />
|
<span class="text-sm text-[#1D2129] max-w-[200px] truncate" :title="formModel.androidFiles[0].name">{{ formModel.androidFiles[0].name }}</span>
|
<icon-park-outline-close class="text-gray-400 cursor-pointer hover:text-gray-600" @click="formModel.androidFiles = []" />
|
</div>
|
</div>
|
</n-form-item>
|
|
<n-form-item label="iOS文件" path="iosFiles">
|
<div class="flex flex-col gap-2">
|
<n-upload
|
v-model:file-list="formModel.iosFiles"
|
:max="1"
|
accept=".ipa"
|
:on-before-upload="beforeUploadIpa"
|
:custom-request="customRequest"
|
:show-file-list="false"
|
>
|
<n-button style="width: 100px">
|
<template #icon>
|
<icon-park-outline-upload />
|
</template>
|
{{ formModel.iosFiles.length > 0 ? '重新上传' : '点击上传' }}
|
</n-button>
|
</n-upload>
|
|
<div v-if="formModel.iosFiles.length > 0" class="flex items-center bg-[#F5F6F8] px-3 py-2 rounded w-fit gap-3">
|
<ri-apple-fill class="text-black text-lg" />
|
<span class="text-sm text-[#1D2129] max-w-[200px] truncate" :title="formModel.iosFiles[0].name">{{ formModel.iosFiles[0].name }}</span>
|
<icon-park-outline-close class="text-gray-400 cursor-pointer hover:text-gray-600" @click="formModel.iosFiles = []" />
|
</div>
|
</div>
|
</n-form-item>
|
|
<n-form-item label="更新说明" path="updateNote" label-placement="top">
|
<n-input
|
v-model:value="formModel.updateNote"
|
type="textarea"
|
placeholder="请输入"
|
:autosize="{ minRows: 6, maxRows: 10 }"
|
show-count
|
style="width: 750px;"
|
:maxlength="200"
|
/>
|
</n-form-item>
|
|
<n-form-item label="强制更新" path="isForceUpdate" label-placement="left">
|
<n-switch v-model:value="formModel.isForceUpdate" />
|
</n-form-item>
|
</n-form>
|
</div>
|
|
<div class="flex justify-end gap-3 mt-auto px-6 py-4 border-t border-gray-100">
|
<n-button style="padding: 8px 29px;" @click="handleCancel">返回</n-button>
|
<n-button style="padding: 8px 29px;" type="primary" @click="handleConfirm">保存</n-button>
|
</div>
|
</div>
|
</template>
|
|
<style scoped>
|
</style>
|