396 lines
15 KiB
Vue
396 lines
15 KiB
Vue
<template>
|
||
<div class="p-2 h-full flex flex-col">
|
||
<pageheader></pageheader>
|
||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||
<div v-show="showSearch" class="mb-[10px]">
|
||
<el-card shadow="hover">
|
||
<el-form ref="queryFormRef" :inline="true" :model="queryParams">
|
||
<el-form-item label="应用名称" prop="channel">
|
||
<el-select v-model="queryParams.channel" placeholder="请选择">
|
||
<el-option v-for="(item, index) in com_app_list" :key="index" :label="item.label" :value="item.value"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="应用类型" prop="platform">
|
||
<el-select v-model="queryParams.platform" placeholder="请选择">
|
||
<el-option label="iOS" value="ios"></el-option>
|
||
<el-option label="Android" value="android"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="版本号" prop="versionCode">
|
||
<el-input v-model.trim="queryParams.versionCode" clearable maxlength="20" placeholder="请输入版本号" @keyup.enter="handleQuery" />
|
||
</el-form-item>
|
||
<el-form-item label="版本名称" prop="versionName">
|
||
<el-input v-model.trim="queryParams.versionName" clearable maxlength="20" placeholder="请输入版本名称" @keyup.enter="handleQuery" />
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button icon="Search" type="primary" @click="handleQuery">搜索</el-button>
|
||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
</el-card>
|
||
</div>
|
||
</transition>
|
||
|
||
<el-card class="flex-1" shadow="never">
|
||
<template #header>
|
||
<el-row :gutter="10" class="mb8">
|
||
<el-col :span="1.5">
|
||
<el-button v-has-permi="['system:version:add']" icon="Plus" plain type="primary" @click="handleAdd">新增</el-button>
|
||
</el-col>
|
||
</el-row>
|
||
</template>
|
||
|
||
<el-table
|
||
v-loading="loading"
|
||
:data="versionList"
|
||
:default-sort="{ prop: 'versionCode', order: 'descending' }"
|
||
border
|
||
@selection-change="handleSelectionChange"
|
||
>
|
||
<el-table-column align="center" type="selection" width="55" />
|
||
<el-table-column align="center" label="应用名称" prop="appChannel" sortable>
|
||
<template #default="scope">
|
||
<dict-tag :options="com_app_list" :value="scope.row.appChannel"></dict-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column align="center" label="版本类型" prop="platform">
|
||
<template #default="scope">
|
||
<el-tag v-if="scope.row.platform === 'ios'" type="success">ios</el-tag>
|
||
<el-tag v-else type="primary">android</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column align="center" label="更新渠道" prop="channel" sortable />
|
||
<el-table-column align="center" label="版本号" prop="versionCode" sortable />
|
||
<el-table-column align="center" label="版本名称" prop="versionName" sortable />
|
||
<el-table-column align="center" label="最低支持版本" prop="minVersionName" sortable />
|
||
<el-table-column align="center" label="下载地址" prop="downloadUrl" />
|
||
<el-table-column align="center" label="更新日志" prop="releaseNotes" />
|
||
<el-table-column align="center" label="停用/启用" prop="status">
|
||
<template #default="scope">
|
||
<el-switch
|
||
v-model="scope.row.status"
|
||
active-value="1"
|
||
inactive-value="0"
|
||
@change="(val: string) => switchVersion(scope.row.id, val)"
|
||
></el-switch>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column align="center" label="上传时间" prop="createTime" />
|
||
</el-table>
|
||
<pagination v-show="total > 0" v-model:limit="queryParams.pageSize" v-model:page="queryParams.pageNum" :total="total" @pagination="getList" />
|
||
</el-card>
|
||
<!-- 添加或修改对话框 -->
|
||
<el-dialog v-model="dialog.visible" :title="dialog.title" append-to-body width="650px">
|
||
<el-form ref="versionFormRef" :model="form" :rules="rules" label-width="130px">
|
||
<el-form-item label="App端" prop="appChannel">
|
||
<el-select v-model="form.appChannel" placeholder="请选择" @change="handleGetVersionlast">
|
||
<el-option v-for="(item, index) in com_app_list" :key="index" :label="item.label" :value="item.value"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="App类型" prop="platform">
|
||
<el-radio-group v-model="form.platform" @change="handleChangePlatform">
|
||
<el-radio :value="appType.android">Android</el-radio>
|
||
<el-radio :value="appType.ios">ios</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
<el-form-item label="版本名称" prop="versionName">
|
||
<el-input v-model.trim="form.versionName" maxlength="20" placeholder="请输入版本名称例如:1.2.0" />
|
||
</el-form-item>
|
||
<el-form-item label="最低支持版本" prop="minVersionCode">
|
||
<el-select v-if="getlastVersionlist.length > 0" v-model="form.minVersionCode" placeholder="请输入最低支持版本">
|
||
<el-option v-for="(item, index) in getlastVersionlist" :key="index" :label="item.versionName" :value="item.versionCode"></el-option>
|
||
</el-select>
|
||
<el-select v-else v-model="form.minVersionCode" placeholder="请输入最低支持版本">
|
||
<el-option label="1.0.0" value="1"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="渠道" prop="channel">
|
||
<el-radio-group v-model="form.channel" @change="handleChangeChannel">
|
||
<el-radio v-if="form.platform !== appType.ios" value="huawei">华为</el-radio>
|
||
<el-radio v-if="form.platform !== appType.ios" value="xiaomi">小米</el-radio>
|
||
<el-radio v-if="form.platform !== appType.ios" value="oppo">oppo</el-radio>
|
||
<el-radio v-if="form.platform !== appType.ios" value="vivo">vivo</el-radio>
|
||
<el-radio v-if="form.platform !== appType.ios" value="yyb">应用宝</el-radio>
|
||
<el-radio v-if="form.platform !== appType.ios" value="honor">荣耀</el-radio>
|
||
<el-radio v-else value="ios">ios</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="更新日志" prop="releaseNotes">
|
||
<el-input v-model="form.releaseNotes" :rows="5" maxlength="200" placeholder="请输入内容" show-word-limit type="textarea" />
|
||
</el-form-item>
|
||
<!-- <el-form-item label="低版本强制更新">-->
|
||
<!-- <div>-->
|
||
<!-- <el-switch-->
|
||
<!-- v-model="form.updateType"-->
|
||
<!-- :active-value="updateType.force"-->
|
||
<!-- active-text="开启"-->
|
||
<!-- :inactive-value="updateType.optional"-->
|
||
<!-- inactive-text="停止"-->
|
||
<!-- ></el-switch>-->
|
||
<!-- <p class="tips">-->
|
||
<!-- <strong style="color: #000">配合最低支持版本使用</strong> 开启后: <br />低于最低版→启用强制(无取消,不更退出 APP);<br />高于最低版→普通弹窗可选取消。-->
|
||
<!-- </p>-->
|
||
<!-- </div>-->
|
||
<!-- </el-form-item>-->
|
||
<!-- <el-form-item label="更新地址" prop="downloadUrl" v-if="form.platform === appType.ios">-->
|
||
<!-- <el-input v-model="form.downloadUrl" placeholder="请输入App Store 链接" />-->
|
||
<!-- </el-form-item>-->
|
||
<!-- <div v-else-if="form.platform === appType.android">-->
|
||
<!-- <el-form-item label="更新类型">-->
|
||
<!-- <el-radio-group v-model="form.method">-->
|
||
<!-- <el-radio-button :value="updatePackageType.apk">整包更新(apk)</el-radio-button>-->
|
||
<!-- <el-radio-button :value="updatePackageType.wgt">热更新(wgt)</el-radio-button>-->
|
||
<!-- </el-radio-group>-->
|
||
<!-- </el-form-item>-->
|
||
<el-form-item label="上传安装包地址" prop="downloadUrl">
|
||
<el-input v-model.trim="form.downloadUrl" maxlength="20" placeholder="请输入更新地址" />
|
||
</el-form-item>
|
||
<!-- </div>-->
|
||
</el-form>
|
||
<template #footer>
|
||
<div class="dialog-footer">
|
||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||
<el-button @click="cancel">取 消</el-button>
|
||
</div>
|
||
</template>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script lang="ts" name="Version" setup>
|
||
import { listVersion, addVersion, getPastVersion, switchVersion } from '@/api/system/version';
|
||
import { VersionVO, VersionQuery, VersionForm } from '@/api/system/version/type';
|
||
|
||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||
const { com_app_list } = toRefs<any>(proxy?.useDict('com_app_list'));
|
||
const versionList = ref<VersionVO[]>([]);
|
||
const buttonLoading = ref(false);
|
||
const loading = ref(true);
|
||
const showSearch = ref(true);
|
||
const ids = ref<Array<string | number>>([]);
|
||
const single = ref(true);
|
||
const multiple = ref(true);
|
||
const total = ref(0);
|
||
|
||
const queryFormRef = ref<ElFormInstance>();
|
||
const versionFormRef = ref<ElFormInstance>();
|
||
|
||
const dialog = reactive<DialogOption>({
|
||
visible: false,
|
||
title: ''
|
||
});
|
||
|
||
const initFormData: VersionForm = {
|
||
id: undefined,
|
||
platform: 'android',
|
||
versionCode: undefined,
|
||
versionName: undefined,
|
||
minVersionCode: '1.0.0',
|
||
updateType: undefined,
|
||
method: 'apk',
|
||
downloadUrl: undefined,
|
||
releaseNotes: undefined,
|
||
fileSize: undefined,
|
||
appChannel: 'resident',
|
||
status: undefined,
|
||
channel: undefined
|
||
};
|
||
const data = reactive<PageData<VersionForm, VersionQuery>>({
|
||
form: { ...initFormData },
|
||
queryParams: {
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
platform: undefined,
|
||
versionCode: undefined,
|
||
versionName: undefined,
|
||
appChannel: undefined
|
||
},
|
||
rules: {
|
||
channel: [{ required: true, message: 'App渠道不能为空', trigger: 'blur' }],
|
||
platform: [{ required: true, message: 'App类型不能为空', trigger: 'blur' }],
|
||
versionCode: [{ required: true, message: '版本号不能为空', trigger: 'blur' }],
|
||
versionName: [{ required: true, message: '版本名称不能为空', trigger: 'blur' }],
|
||
downloadUrl: [{ required: true, message: '安装包地址不能为空', trigger: 'blur' }]
|
||
}
|
||
});
|
||
|
||
const { queryParams, form, rules } = toRefs(data);
|
||
enum appType {
|
||
/** ios */
|
||
ios = 'ios',
|
||
/** android */
|
||
android = 'android'
|
||
}
|
||
/** 更新包类型 */
|
||
enum updatePackageType {
|
||
/** 整包更新 */
|
||
apk = 'apk'
|
||
/** 热更新 */
|
||
// wgt = 'wgt'
|
||
}
|
||
enum updateType {
|
||
/** 强制更新 */
|
||
// force = '0',
|
||
/** 可选更新 */
|
||
optional = '1'
|
||
}
|
||
const getlastVersionlist = ref([]);
|
||
|
||
/**
|
||
* 判断当前版本是否需要更新到最新版本。
|
||
* 比较逻辑为:如果当前版本号小于或等于最新版本号,则认为需要更新。
|
||
*
|
||
* @param {string} current - 当前版本号字符串,格式为点分十进制(如 "1.2.3")
|
||
* @param {string} latest - 最新版本号字符串,格式为点分十进制(如 "1.2.4")
|
||
* @returns {boolean} 如果当前版本小于或等于最新版本,返回 true;否则返回 false
|
||
*/
|
||
// function needUpdate(current: string, latest: string) {
|
||
// // 将版本号字符串分割并转换为数字数组
|
||
// const c = current.split('.').map(Number);
|
||
// const l = latest.split('.').map(Number);
|
||
// const max = Math.max(c.length, l.length);
|
||
//
|
||
// // 逐段比较版本号,若当前段小于最新段则需更新,大于则无需更新
|
||
// for (let i = 0; i < max; i++) {
|
||
// const cv = c[i] || 0;
|
||
// const lv = l[i] || 0;
|
||
// if (cv <= lv) return true;
|
||
// if (cv > lv) return false;
|
||
// }
|
||
// return false;
|
||
// }
|
||
|
||
/** 查询【请填写功能名称】列表 */
|
||
const getList = async () => {
|
||
loading.value = true;
|
||
const res = await listVersion(queryParams.value);
|
||
versionList.value = res.rows;
|
||
total.value = res.total;
|
||
loading.value = false;
|
||
};
|
||
|
||
/** 取消按钮 */
|
||
const cancel = () => {
|
||
reset();
|
||
dialog.visible = false;
|
||
};
|
||
|
||
/** 表单重置 */
|
||
const reset = () => {
|
||
form.value = { ...initFormData };
|
||
versionFormRef.value?.resetFields();
|
||
};
|
||
|
||
/** 搜索按钮操作 */
|
||
const handleQuery = () => {
|
||
queryParams.value.pageNum = 1;
|
||
getList();
|
||
};
|
||
|
||
/** 重置按钮操作 */
|
||
const resetQuery = () => {
|
||
form.value = { ...initFormData };
|
||
queryFormRef.value?.resetFields();
|
||
handleQuery();
|
||
};
|
||
|
||
/** 多选框选中数据 */
|
||
const handleSelectionChange = (selection: VersionVO[]) => {
|
||
ids.value = selection.map((item) => item.id);
|
||
single.value = selection.length != 1;
|
||
multiple.value = !selection.length;
|
||
};
|
||
|
||
/** 新增按钮操作 */
|
||
const handleAdd = () => {
|
||
reset();
|
||
dialog.visible = true;
|
||
dialog.title = '添加版本';
|
||
};
|
||
|
||
function handleChangePlatform() {
|
||
form.value.minVersionCode = '1.0.0';
|
||
form.value.updateType = updateType.optional;
|
||
form.value.method = updatePackageType.apk;
|
||
form.value.downloadUrl = '';
|
||
form.value.channel = '';
|
||
if (form.value.platform === 'ios') {
|
||
form.value.channel = 'ios';
|
||
handleChangeChannel(form.value.channel);
|
||
}
|
||
handleGetVersionlast();
|
||
}
|
||
|
||
function handleGetVersionlast() {
|
||
getPastVersion(form.value.platform, form.value.appChannel).then((res) => {
|
||
getlastVersionlist.value = res.data;
|
||
form.value.minVersionCode = getlastVersionlist.value[getlastVersionlist.value.length - 1]
|
||
? getlastVersionlist.value[getlastVersionlist.value.length - 1].versionCode
|
||
: null;
|
||
});
|
||
}
|
||
|
||
const channelUrl = {
|
||
'huawei': 'tappmarket://details?id=',
|
||
'xiaomi': 'mimarket://details?id=',
|
||
'oppo': 'oppomarket://details?packagename=',
|
||
'vivo': 'vivomarket://details?id=',
|
||
'honor': 'market://details?id=',
|
||
'yyb': 'tmast://appdetails?pname=',
|
||
'ios': 'itms-apps://apps.apple.com/cn/app/id'
|
||
};
|
||
function handleChangeChannel(val: string) {
|
||
form.value.downloadUrl = channelUrl[val];
|
||
}
|
||
/** 提交按钮 */
|
||
const submitForm = () => {
|
||
if (!form.value.minVersionCode) {
|
||
ElMessage.error('请选择最低支持版本');
|
||
return;
|
||
}
|
||
|
||
versionFormRef.value?.validate(async (valid: boolean) => {
|
||
if (valid) {
|
||
buttonLoading.value = true;
|
||
await addVersion(form.value).finally(() => (buttonLoading.value = false));
|
||
proxy?.$modal.msgSuccess('操作成功');
|
||
dialog.visible = false;
|
||
await getList();
|
||
}
|
||
});
|
||
};
|
||
|
||
onMounted(() => {
|
||
getList();
|
||
});
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.el-table {
|
||
height: calc(100% - 80px);
|
||
}
|
||
|
||
.uploadFileBox {
|
||
width: 100px;
|
||
height: 100px;
|
||
border-radius: 4px 4px 4px 4px;
|
||
background-color: rgba(255, 255, 255, 1);
|
||
color: rgba(16, 16, 16, 1);
|
||
border: 1px solid #ccc;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
cursor: pointer;
|
||
&:hover {
|
||
border: 1px solid #409eff;
|
||
color: #409eff;
|
||
}
|
||
}
|
||
|
||
.tips {
|
||
color: #ccc;
|
||
font-size: 12px;
|
||
}
|
||
</style>
|