134 lines
10 KiB
Vue
134 lines
10 KiB
Vue
<template>
|
||
<div>
|
||
<div v-if="!userId" class="kra-search-box">
|
||
<el-form :inline="true" :model="query" @submit.prevent="search">
|
||
<el-form-item label="所属平台"><el-select v-model="query.sourceDb" multiple clearable placeholder="全部平台" style="width: 220px"><el-option v-for="(label, value) in platforms" :key="value" :value="value" :label="label" /></el-select></el-form-item>
|
||
<el-form-item label="游戏商务账号"><el-input v-model="query.platformBusierAccount" clearable /></el-form-item>
|
||
<el-form-item label="审核状态"><el-select v-model="query.status" clearable style="width: 130px"><el-option v-for="(label, value) in statuses" :key="value" :value="value" :label="label" /></el-select></el-form-item>
|
||
<el-form-item><el-button type="primary" icon="search" native-type="submit">查询</el-button><el-button icon="refresh" @click="reset">重置</el-button></el-form-item>
|
||
</el-form>
|
||
</div>
|
||
<div class="kra-table-box">
|
||
<div v-if="!userId && canBind" class="kra-btn-list"><el-button type="primary" icon="plus" @click="openBind">绑定游戏商务</el-button></div>
|
||
<el-table v-loading="loading" :data="rows" :row-key="rowKey">
|
||
<el-table-column label="所属平台" min-width="80"><template #default="{ row }"><el-button v-if="userId && canPortrait && row.status === '0'" type="primary" link @click="showPortrait(row)">{{ row.platformName }}</el-button><span v-else>{{ row.platformName }}</span></template></el-table-column>
|
||
<el-table-column v-if="userId" prop="platformBusierId" label="ID" min-width="90" />
|
||
<el-table-column prop="platformBusierAccount" label="游戏商务账号" min-width="140" />
|
||
<el-table-column v-if="!userId" prop="bindUserName" label="绑定商务" min-width="140" />
|
||
<el-table-column v-if="!userId" label="旗下渠道数" min-width="110"><template #default="{ row }"><span v-if="row.promoteCount === null" class="text-gray-400">未接入</span><el-button v-else type="primary" link aria-label="查看旗下渠道" :disabled="row.status !== '0'" @click="showChannels(row)">{{ row.promoteCount }}</el-button></template></el-table-column>
|
||
<el-table-column label="审核状态" width="110"><template #default="{ row }"><el-tag :type="row.status === '0' ? 'success' : row.status === '2' ? 'danger' : 'warning'">{{ statuses[row.status] || row.status }}</el-tag></template></el-table-column>
|
||
<el-table-column prop="createTime" label="绑定时间" min-width="130"><template #default="{ row }">{{ row.createTime?.slice(0, 10) }}</template></el-table-column>
|
||
<el-table-column v-if="!userId" label="操作" width="145" fixed="right">
|
||
<template #default="{ row }">
|
||
<template v-if="row.status === '0'"><el-button v-if="canPortrait" link type="primary" @click="showPortrait(row)">画像</el-button><el-button v-if="canBind && row.userId === user.userInfo.ID" link type="danger" @click="remove(row)">解绑</el-button></template>
|
||
<el-button v-else-if="row.status === '2'" link type="primary" @click="showReject(row)">查看驳回</el-button>
|
||
<span v-else>—</span>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
<div v-if="!userId" class="kra-pagination"><el-pagination v-model:current-page="query.pageNum" v-model:page-size="query.pageSize" :total="total" :page-sizes="[10, 20, 50, 100]" layout="total, sizes, prev, pager, next, jumper" @size-change="search" @current-change="load" /></div>
|
||
</div>
|
||
<el-drawer append-to-body v-model="channelsDrawer" title="旗下渠道" size="520px" destroy-on-close><business-channels v-if="selectedChannel" :user-id="selectedChannel.userId" :source-db="selectedChannel.sourceDb" :platform-busier-id="selectedChannel.platformBusierId" /></el-drawer>
|
||
<business-profile-drawer v-model="portraitOpen" :user-id="portraitRow?.userId || userId" :source-db="portraitRow?.sourceDb || ''" :platform-busier-id="portraitRow?.platformBusierId || 0" :name="portraitRow?.platformBusierAccount || ''" />
|
||
<el-drawer append-to-body v-model="dialog" title="绑定游戏商务" size="460px" destroy-on-close>
|
||
<el-alert title="验证成功后提交 OA 审核,审核通过后可查看对应渠道数据。" type="info" :closable="false" class="mb-4" />
|
||
<el-form ref="formRef" :model="form" :rules="rules" label-position="top">
|
||
<el-form-item label="所属平台" prop="sourceDb"><el-select v-model="form.sourceDb"><el-option v-for="(label, value) in platforms" :key="value" :value="value" :label="label" /></el-select></el-form-item>
|
||
<el-form-item label="游戏商务账号" prop="account"><el-input v-model="form.account" maxlength="30" autocomplete="off" /></el-form-item>
|
||
<el-form-item label="游戏商务密码" prop="password"><el-input v-model="form.password" type="password" show-password autocomplete="new-password" /></el-form-item>
|
||
</el-form>
|
||
<template #footer><el-button @click="dialog = false">取消</el-button><el-button type="primary" :loading="saving" @click="submit">验证并提交</el-button></template>
|
||
</el-drawer>
|
||
<el-drawer append-to-body v-model="rejectDrawer" title="审核详情" size="420px" destroy-on-close>
|
||
<el-descriptions v-if="selectedRow" :column="1" border>
|
||
<el-descriptions-item label="申请商务">{{ selectedRow.bindUserName || '—' }}</el-descriptions-item>
|
||
<el-descriptions-item label="所属平台">{{ selectedRow.platformName }}</el-descriptions-item>
|
||
<el-descriptions-item label="游戏商务账号">{{ selectedRow.platformBusierAccount }}</el-descriptions-item>
|
||
<el-descriptions-item label="当前状态">{{ statuses[selectedRow.status] }}</el-descriptions-item>
|
||
<el-descriptions-item label="申请时间">{{ selectedRow.createTime || '—' }}</el-descriptions-item>
|
||
<el-descriptions-item label="审核时间">{{ selectedRow.reviewTime || '—' }}</el-descriptions-item>
|
||
<el-descriptions-item label="审核人">{{ selectedRow.reviewAccount || '—' }}</el-descriptions-item>
|
||
<el-descriptions-item label="审核意见">{{ selectedRow.rejectReason || '—' }}</el-descriptions-item>
|
||
</el-descriptions>
|
||
<template #footer><el-button @click="rejectDrawer = false">关闭</el-button></template>
|
||
</el-drawer>
|
||
<el-drawer append-to-body v-model="unbindDrawer" title="解除绑定确认" size="420px" destroy-on-close>
|
||
<p>确认解除游戏SDK商务「{{ selectedRow?.platformBusierAccount }}」(平台:{{ selectedRow?.platformName }})的绑定吗?</p>
|
||
<p class="mt-4 text-gray-500">解除后该商务将从列表移除,其名下渠道数据将不再可查询。</p>
|
||
<template #footer><el-button @click="unbindDrawer = false">取消</el-button><el-button type="danger" :loading="saving" @click="confirmUnbind">确认解除</el-button></template>
|
||
</el-drawer>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { computed, reactive, ref, watch } from 'vue'
|
||
import { ElMessage } from 'element-plus'
|
||
import { useUserStore } from '@/pinia/modules/user'
|
||
import { useBtnAuth } from '@/utils/btnAuth'
|
||
import { listBusinessBindings, listUserBindings, bindPlatform, unbindPlatform } from '@/api/business'
|
||
import BusinessChannels from './BusinessChannels.vue'
|
||
import BusinessProfileDrawer from './BusinessProfileDrawer.vue'
|
||
|
||
defineOptions({ name: 'SwBusinessBindings' })
|
||
const props = defineProps({ userId: { type: Number, default: 0 } })
|
||
const emit = defineEmits(['changed'])
|
||
const user = useUserStore()
|
||
const buttons = useBtnAuth()
|
||
const canPortrait = computed(() => Number(user.userInfo.authorityId) === 888 || !!buttons['sw:business:query'])
|
||
const portraitOpen = ref(false)
|
||
const portraitRow = ref(null)
|
||
const showPortrait = row => { portraitRow.value = row; portraitOpen.value = true }
|
||
const canBind = computed(() => !props.userId && Number(user.userInfo.level) === 3 && Boolean(buttons['sw:business:bind']))
|
||
const platforms = { lx: '龙翔', hw: '汇玩', yq: '游趣' }
|
||
const statuses = { 0: '正常', 2: '已驳回', 3: '待审核' }
|
||
const query = reactive({ pageNum: 1, pageSize: 10, sourceDb: [], platformBusierAccount: '', status: '' })
|
||
const rows = ref([])
|
||
const total = ref(0)
|
||
const loading = ref(false)
|
||
const dialog = ref(false)
|
||
const rejectDrawer = ref(false)
|
||
const unbindDrawer = ref(false)
|
||
const selectedRow = ref(null)
|
||
const channelsDrawer = ref(false)
|
||
const selectedChannel = ref(null)
|
||
const showChannels = (row) => { selectedChannel.value = row; channelsDrawer.value = true }
|
||
const showReject = (row) => { selectedRow.value = row; rejectDrawer.value = true }
|
||
const saving = ref(false)
|
||
const formRef = ref()
|
||
const form = ref({})
|
||
const rules = Object.fromEntries(['sourceDb', 'account', 'password'].map((key) => [key, [{ required: true, message: '请填写完整信息', trigger: 'blur' }]]))
|
||
const rowKey = (row) => `${row.userId}:${row.sourceDb}:${row.platformBusierId}`
|
||
const load = async () => {
|
||
loading.value = true
|
||
try {
|
||
const res = props.userId ? await listUserBindings(props.userId) : await listBusinessBindings({ ...query, sourceDb: query.sourceDb.join(',') })
|
||
if (res.code === 0) {
|
||
rows.value = props.userId ? res.data : res.data.rows
|
||
total.value = props.userId ? rows.value.length : res.data.total
|
||
}
|
||
} finally { loading.value = false }
|
||
}
|
||
const search = () => { query.pageNum = 1; return load() }
|
||
const reset = () => { Object.assign(query, { sourceDb: [], platformBusierAccount: '', status: '' }); return search() }
|
||
const openBind = () => { form.value = { sourceDb: 'lx', account: '', password: '' }; dialog.value = true }
|
||
const submit = async () => {
|
||
if (!await formRef.value.validate().catch(() => false)) return
|
||
saving.value = true
|
||
try {
|
||
const res = await bindPlatform(form.value)
|
||
if (res.code === 0) { ElMessage.success('已提交,请等待 OA 审核'); dialog.value = false; form.value.password = ''; emit('changed'); await load() }
|
||
} finally { saving.value = false }
|
||
}
|
||
const remove = (row) => { selectedRow.value = row; unbindDrawer.value = true }
|
||
const confirmUnbind = async () => {
|
||
const row = selectedRow.value
|
||
if (!row || !canBind.value || row.status !== '0' || row.userId !== user.userInfo.ID) return
|
||
saving.value = true
|
||
try {
|
||
const res = await unbindPlatform({ sourceDb: row.sourceDb, platformBusierId: row.platformBusierId })
|
||
if (res.code === 0) { ElMessage.success('解绑成功'); unbindDrawer.value = false; emit('changed'); await load() }
|
||
} finally { saving.value = false }
|
||
}
|
||
watch(() => props.userId, load, { immediate: true })
|
||
</script>
|