Files
im_manager/web/src/views/imAppRelease/index.vue
T

243 lines
7.5 KiB
Vue

<template>
<div>
<div class="n-layout-page-header">
<n-card :bordered="false" title="IM版本更新" />
</div>
<n-card :bordered="false" class="proCard">
<BasicForm
ref="searchFormRef"
@register="register"
@submit="reloadTable"
@reset="handleReset"
@keyup.enter="reloadTable"
/>
<BasicTable
ref="actionRef"
:columns="columns"
:request="loadDataTable"
:row-key="(row) => row.tenantId + '-' + row.platform + '-' + row.channel"
:actionColumn="actionColumn"
:scroll-x="scrollX"
:resizeHeightOffset="-10000"
>
<template #tableTitle>
<n-button
type="primary"
:disabled="!hasPermission(['/imAppRelease/edit']) || !currentTenantReady"
@click="handleCreate"
>
新增策略
</n-button>
</template>
</BasicTable>
</n-card>
<n-modal
v-model:show="showModal"
preset="dialog"
:show-icon="false"
:title="formValue.id > 0 ? '编辑版本策略' : '新增版本策略'"
:style="{ width: dialogWidth }"
>
<n-form
ref="formRef"
:model="formValue"
:rules="rules"
label-placement="left"
label-width="112"
>
<n-form-item label="平台" path="platform">
<n-select
v-model:value="formValue.platform"
:disabled="formValue.id > 0"
:options="platformOptions"
placeholder="请选择平台"
/>
</n-form-item>
<n-form-item label="渠道" path="channel">
<n-input
v-model:value="formValue.channel"
:disabled="formValue.id > 0"
placeholder="请输入渠道"
/>
</n-form-item>
<n-form-item label="最新版本" path="latestVersion">
<n-input v-model:value="formValue.latestVersion" placeholder="请输入最新版本" />
</n-form-item>
<n-form-item label="最低支持版本" path="minSupportedVersion">
<n-input v-model:value="formValue.minSupportedVersion" placeholder="请输入最低支持版本" />
</n-form-item>
<n-form-item label="更新类型" path="updateType">
<n-select
v-model:value="formValue.updateType"
:options="updateTypeOptions"
placeholder="请选择更新类型"
/>
</n-form-item>
<n-form-item label="再次提醒秒数">
<n-input-number v-model:value="formValue.remindAfterSeconds" :min="0" />
</n-form-item>
<n-form-item label="商店地址">
<n-input v-model:value="formValue.storeUrl" placeholder="请输入商店地址" />
</n-form-item>
<n-form-item label="安装包地址">
<n-input v-model:value="formValue.packageUrl" placeholder="请输入安装包地址" />
</n-form-item>
<n-form-item label="校验值">
<n-input v-model:value="formValue.checksum" placeholder="请输入安装包校验值" />
</n-form-item>
<n-form-item label="更新说明">
<n-input
v-model:value="formValue.releaseNotes"
type="textarea"
:autosize="{ minRows: 4, maxRows: 8 }"
placeholder="请输入更新说明"
/>
</n-form-item>
</n-form>
<template #action>
<n-space>
<n-button @click="showModal = false">取消</n-button>
<n-button type="primary" :loading="submitLoading" @click="handleSubmit">保存</n-button>
</n-space>
</template>
</n-modal>
</div>
</template>
<script lang="ts" setup>
import { computed, h, onMounted, reactive, ref } from 'vue';
import { useMessage } from 'naive-ui';
import { useDictStore } from '@/store/modules/dict';
import { BasicForm, useForm } from '@/components/Form/index';
import { BasicTable, TableAction } from '@/components/Table';
import { usePermission } from '@/hooks/web/usePermission';
import { useUserStore } from '@/store/modules/user';
import { Edit, List } from '@/api/imAppRelease';
import { adaModalWidth, adaTableScrollX } from '@/utils/hotgo';
import {
columns,
loadOptions,
loadTenantOptions,
newState,
rules,
schemas,
State,
tenantOptions,
} from './model';
const dict = useDictStore();
const message = useMessage();
const { hasPermission } = usePermission();
const userStore = useUserStore();
const isPlatformAdmin = computed(() => userStore.isCompanyDept);
const actionRef = ref();
const searchFormRef = ref<any>({});
const formRef = ref();
const showModal = ref(false);
const submitLoading = ref(false);
const formValue = ref<State>(newState(null));
const dialogWidth = computed(() => adaModalWidth(720));
const platformOptions = dict.getOption('ImAppPlatformOptions');
const updateTypeOptions = dict.getOption('ImAppUpdateTypeOptions');
const currentTenantReady = computed(
() => !isPlatformAdmin.value || !!searchFormRef.value?.formModel?.tenantId
);
const tenantSchema = schemas.value.find((item) => item.field === 'tenantId');
if (tenantSchema) {
tenantSchema.ifShow = () => isPlatformAdmin.value;
}
const actionColumn = reactive({
width: 100,
title: '操作',
key: 'action',
fixed: 'right',
render(record: State) {
return h(TableAction as any, {
style: 'button',
actions: [
{
label: '编辑',
auth: ['/imAppRelease/edit'],
onClick: () => handleEdit(record),
},
],
});
},
});
const scrollX = computed(() => adaTableScrollX(columns, actionColumn.width));
const [register, { setFieldsValue }] = useForm({
gridProps: { cols: '1 s:1 m:2 l:3 xl:4 2xl:4' },
labelWidth: 90,
schemas,
});
const loadDataTable = async (res) => {
const params = { ...searchFormRef.value?.formModel, ...res };
if (isPlatformAdmin.value && !params.tenantId)
return { list: [], page: 1, pageCount: 0, totalCount: 0 };
return await List(params);
};
function reloadTable() {
actionRef.value?.reload();
}
async function handleReset() {
const defaults: Recordable = {};
if (isPlatformAdmin.value && tenantOptions.value.length > 0)
defaults.tenantId = tenantOptions.value[0].value;
await setFieldsValue(defaults);
reloadTable();
}
function handleCreate() {
formValue.value = newState({
tenantId: searchFormRef.value?.formModel?.tenantId || 0,
platform: 'android',
channel: 'stable',
latestVersion: '1.0.0',
minSupportedVersion: '1.0.0',
updateType: 'none',
remindAfterSeconds: 0,
});
showModal.value = true;
}
function handleEdit(record: State) {
formValue.value = newState(record);
showModal.value = true;
}
async function handleSubmit() {
submitLoading.value = true;
try {
await formRef.value?.validate();
await Edit({ ...formValue.value });
message.success('操作成功');
showModal.value = false;
reloadTable();
} catch (e: any) {
message.error(e.message || '操作失败');
} finally {
submitLoading.value = false;
}
}
onMounted(async () => {
loadOptions();
if (isPlatformAdmin.value) {
await loadTenantOptions();
if (tenantOptions.value.length > 0) {
await setFieldsValue({ tenantId: tenantOptions.value[0].value });
} else {
message.warning('暂无可用租户');
}
}
reloadTable();
});
</script>