Files
kra-new/web/src/view/sw/components/AddChannelDrawer.vue
T

59 lines
4.3 KiB
Vue

<template>
<el-drawer v-model="visible" append-to-body destroy-on-close title="添加渠道" size="min(520px, 100vw)" :close-on-click-modal="!saving" :close-on-press-escape="!saving" :show-close="!saving" @closed="reset">
<el-form ref="formRef" :model="form" :rules="rules" label-position="top" :disabled="saving">
<el-form-item label="所属平台" prop="sourceDb"><el-select v-model="form.sourceDb" placeholder="请选择所属平台" clearable @change="loadOptions"><el-option v-for="(label, value) in platforms" :key="value" :label="label" :value="value" /></el-select></el-form-item>
<el-form-item label="游戏商务" prop="platformBusierId"><el-select v-model="form.platformBusierId" placeholder="请选择游戏商务" filterable clearable :disabled="!form.sourceDb" :loading="optionsLoading"><el-option v-for="item in options" :key="item.id" :label="item.account" :value="item.id" /></el-select></el-form-item>
<el-form-item label="推广类型"><el-select v-model="form.registerType"><el-option label="个人" :value="0" /><el-option label="企业" :value="1" /></el-select></el-form-item>
<el-form-item label="渠道账号" prop="account"><el-input v-model="form.account" placeholder="中文/英文/数字,4-30位" maxlength="30" clearable /></el-form-item>
<el-form-item label="渠道密码" prop="password"><el-input v-model="form.password" type="password" show-password placeholder="6-15位" maxlength="15" autocomplete="new-password" /></el-form-item>
</el-form>
<el-alert type="info" :closable="false" title="创建后该渠道归属到所选游戏商务名下,由其拓展并管理玩家。" />
<template #footer><el-button :disabled="saving" @click="visible = false">取消</el-button><el-button type="primary" :loading="saving" @click="save">确认添加</el-button></template>
</el-drawer>
</template>
<script setup>
import { computed, ref } from 'vue'
import { ElMessage } from 'element-plus'
import { channelBindOptions, createChannel } from '@/api/channel'
const props = defineProps({ modelValue: Boolean })
const emit = defineEmits(['update:modelValue', 'success'])
const visible = computed({ get: () => props.modelValue, set: value => emit('update:modelValue', value) })
const platforms = { lx: '龙翔', hw: '汇玩', yq: '游趣' }
const initial = () => ({ sourceDb: '', platformBusierId: undefined, registerType: 0, account: '', password: '' })
const form = ref(initial())
const formRef = ref()
const options = ref([])
const optionsLoading = ref(false)
const saving = ref(false)
let optionVersion = 0
const rules = {
sourceDb: [{ required: true, message: '请选择所属平台', trigger: 'change' }],
platformBusierId: [{ required: true, message: '请选择游戏商务', trigger: 'change' }],
account: [{ required: true, message: '请输入渠道账号', trigger: 'blur' }, { validator: (_rule, value, callback) => /^[\u4e00-\u9fa5a-zA-Z0-9]{4,30}$/.test(value?.trim() || '') ? callback() : callback(new Error('支持中文、英文、数字;长度 4-30 位')), trigger: 'blur' }],
password: [{ required: true, message: '请输入渠道密码', trigger: 'blur' }, { min: 6, max: 15, message: '密码长度需在 6 到 15 位', trigger: 'blur' }]
}
const reset = () => { ++optionVersion; form.value = initial(); options.value = []; optionsLoading.value = false }
const loadOptions = async () => {
const version = ++optionVersion
form.value.platformBusierId = undefined
options.value = []
if (!form.value.sourceDb) { optionsLoading.value = false; return }
optionsLoading.value = true
try {
const res = await channelBindOptions(form.value.sourceDb)
if (version !== optionVersion || res.code !== 0) return
const unique = new Map(res.data.map(item => [item.platformBusierId, { id: item.platformBusierId, account: item.platformBusierAccount?.trim() || String(item.platformBusierId) }]))
options.value = [...unique.values()]
} finally { if (version === optionVersion) optionsLoading.value = false }
}
const save = async () => {
if (saving.value || !await formRef.value.validate().catch(() => false)) return
saving.value = true
try {
const res = await createChannel({ ...form.value, account: form.value.account.trim() })
if (res.code === 0) { ElMessage.success(res.msg || '添加成功,数据同步到列表可能有延迟'); visible.value = false; emit('success') }
} finally { saving.value = false }
}
</script>