feat: 投诉工单页增加「投诉拦截提现」俱乐部开关
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,5 +1,27 @@
|
||||
<template>
|
||||
<div class="gongdan-page">
|
||||
<ClubScopeHint />
|
||||
<el-card shadow="never" class="config-card" v-loading="configLoading">
|
||||
<div class="config-row">
|
||||
<div class="config-main">
|
||||
<div class="config-title">投诉拦截提现</div>
|
||||
<div class="config-desc">
|
||||
开启后:当前俱乐部未结清投诉的被投诉人不可提现;管事被投诉时上级组长也牵连拦截。关闭后仅保留工单,不拦提现。
|
||||
</div>
|
||||
<div v-if="configClubId" class="config-club">当前俱乐部:{{ configClubId }}</div>
|
||||
</div>
|
||||
<el-switch
|
||||
v-model="withdrawBlock"
|
||||
:loading="configSaving"
|
||||
:disabled="configLoading || configSaving"
|
||||
inline-prompt
|
||||
active-text="开"
|
||||
inactive-text="关"
|
||||
@change="onToggleWithdrawBlock"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<div class="stat-row">
|
||||
<div class="stat-card danger" @click="quickFilter(1)">
|
||||
<div class="stat-label">待处理</div>
|
||||
@@ -35,6 +57,7 @@
|
||||
<el-option label="已处理" :value="2" />
|
||||
<el-option label="不满意" :value="3" />
|
||||
<el-option label="已关闭" :value="4" />
|
||||
<el-option label="协商中" :value="5" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="类型">
|
||||
@@ -44,6 +67,7 @@
|
||||
<el-option label="罚款投诉" :value="3" />
|
||||
<el-option label="管事投诉" :value="4" />
|
||||
<el-option label="被骗投诉" :value="5" />
|
||||
<el-option label="组长投诉" :value="6" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="关键词">
|
||||
@@ -82,6 +106,8 @@
|
||||
<div class="badge-row">
|
||||
<el-tag v-if="isPending(row)" type="danger" size="small" effect="dark">待处理</el-tag>
|
||||
<el-tag v-if="row.zhuangtai === 3" type="warning" size="small" effect="dark">不满意</el-tag>
|
||||
<el-tag v-if="row.zhuangtai === 5" type="warning" size="small" effect="plain">协商中</el-tag>
|
||||
<el-tag v-if="row.platform_intervened" type="primary" size="small" effect="dark">平台已介入</el-tag>
|
||||
<el-tag v-if="(row.shengji_cishu || 0) > 0" type="danger" size="small" effect="plain">
|
||||
第{{ (row.shengji_cishu || 0) + 1 }}次投诉
|
||||
</el-tag>
|
||||
@@ -103,20 +129,35 @@
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="申请人" width="130">
|
||||
<el-table-column label="申请人" width="150">
|
||||
<template #default="{ row }">
|
||||
<div class="id-cell">
|
||||
<span>{{ row.shenqingren_id || '-' }}</span>
|
||||
<span>{{ row.complainant_nicheng || row.shenqingren_id || '-' }}</span>
|
||||
<el-button
|
||||
v-if="row.shenqingren_id"
|
||||
type="primary"
|
||||
link
|
||||
size="small"
|
||||
@click.stop="copyText(row.shenqingren_id)"
|
||||
>复制</el-button>
|
||||
>复制UID</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="被投诉" width="140">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.target_nicheng || row.target_role_label || row.target_user_id || row.guanshi_id">
|
||||
<div>{{ row.target_role_label || '' }} {{ row.target_nicheng || '' }}</div>
|
||||
<el-button
|
||||
v-if="row.target_user_id || row.guanshi_id"
|
||||
type="primary"
|
||||
link
|
||||
size="small"
|
||||
@click.stop="copyText(row.target_user_id || row.guanshi_id)"
|
||||
>复制UID</el-button>
|
||||
</div>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="关联单号" min-width="180">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.order_id" class="id-cell">
|
||||
@@ -134,12 +175,7 @@
|
||||
<span class="mono">{{ row.fadan_id }}</span>
|
||||
<el-button type="primary" link size="small" @click.stop="copyText(row.fadan_id)">复制</el-button>
|
||||
</div>
|
||||
<div v-if="row.guanshi_id" class="id-cell">
|
||||
<span class="muted">管事</span>
|
||||
<span class="mono">{{ row.guanshi_id }}</span>
|
||||
<el-button type="primary" link size="small" @click.stop="copyText(row.guanshi_id)">复制</el-button>
|
||||
</div>
|
||||
<span v-if="!row.order_id && !row.chongzhi_id && !row.fadan_id && !row.guanshi_id">-</span>
|
||||
<span v-if="!row.order_id && !row.chongzhi_id && !row.fadan_id">-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="shuoming" label="说明" min-width="160" show-overflow-tooltip />
|
||||
@@ -202,13 +238,30 @@
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="label">申请人</span>
|
||||
<span class="value">{{ current.shenqingren_id }}</span>
|
||||
<span class="value">{{ current.complainant_nicheng || current.shenqingren_id || '-' }}</span>
|
||||
<el-button
|
||||
v-if="current.shenqingren_id"
|
||||
type="primary"
|
||||
link
|
||||
@click="copyText(current.shenqingren_id)"
|
||||
>复制</el-button>
|
||||
>复制UID</el-button>
|
||||
</div>
|
||||
<div v-if="current.target_nicheng || current.target_user_id || current.guanshi_id" class="detail-row">
|
||||
<span class="label">被投诉</span>
|
||||
<span class="value">
|
||||
{{ current.target_role_label || '' }}
|
||||
{{ current.target_nicheng || '' }}
|
||||
</span>
|
||||
<el-button
|
||||
v-if="current.target_user_id || current.guanshi_id"
|
||||
type="primary"
|
||||
link
|
||||
@click="copyText(current.target_user_id || current.guanshi_id)"
|
||||
>复制UID</el-button>
|
||||
</div>
|
||||
<div v-if="current.platform_intervened" class="detail-row">
|
||||
<span class="label">介入</span>
|
||||
<span class="value"><el-tag type="primary" effect="dark" size="small">平台已介入</el-tag></span>
|
||||
</div>
|
||||
<div v-if="current.order_id" class="detail-row">
|
||||
<span class="label">订单ID</span>
|
||||
@@ -225,11 +278,6 @@
|
||||
<span class="value mono">{{ current.fadan_id }}</span>
|
||||
<el-button type="primary" link @click="copyText(current.fadan_id)">复制</el-button>
|
||||
</div>
|
||||
<div v-if="current.guanshi_id" class="detail-row">
|
||||
<span class="label">管事ID</span>
|
||||
<span class="value mono">{{ current.guanshi_id }}</span>
|
||||
<el-button type="primary" link @click="copyText(current.guanshi_id)">复制</el-button>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="label">创建时间</span>
|
||||
<span class="value">{{ formatTime(current.CreateTime) }}</span>
|
||||
@@ -271,7 +319,7 @@
|
||||
<div class="block-title">处理信息</div>
|
||||
<div class="detail-row">
|
||||
<span class="label">处理人</span>
|
||||
<span class="value">{{ current.chuliren_name || current.chuliren_id || '尚未处理' }}</span>
|
||||
<span class="value">{{ current.chuliren_name || '尚未处理' }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="label">处理时间</span>
|
||||
@@ -287,6 +335,12 @@
|
||||
<div class="block-title">填写处理结果</div>
|
||||
<el-input v-model="jieguo" type="textarea" :rows="4" placeholder="填写处理结果(标记已处理时必填)" />
|
||||
<div class="actions">
|
||||
<el-button
|
||||
type="warning"
|
||||
:loading="saving"
|
||||
:disabled="!!current.platform_intervened"
|
||||
@click="handle('intervene')"
|
||||
>{{ current.platform_intervened ? '已介入' : '标记平台介入' }}</el-button>
|
||||
<el-button type="primary" :loading="saving" @click="handle('done')">标记已处理</el-button>
|
||||
<el-button :loading="saving" @click="handle('close')">关闭工单</el-button>
|
||||
</div>
|
||||
@@ -300,9 +354,14 @@
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import request from '@/utils/request'
|
||||
import ClubScopeHint from '@/components/ClubScopeHint.vue'
|
||||
|
||||
const loading = ref(false)
|
||||
const saving = ref(false)
|
||||
const configLoading = ref(false)
|
||||
const configSaving = ref(false)
|
||||
const withdrawBlock = ref(false)
|
||||
const configClubId = ref('')
|
||||
const list = ref([])
|
||||
const total = ref(0)
|
||||
const page = ref(1)
|
||||
@@ -324,11 +383,12 @@ const stats = reactive({
|
||||
})
|
||||
|
||||
function isPending(row) {
|
||||
return Number(row?.zhuangtai) === 1
|
||||
const z = Number(row?.zhuangtai)
|
||||
return z === 1 || z === 5
|
||||
}
|
||||
|
||||
function statusLabel(z) {
|
||||
return ({ 1: '处理中', 2: '已处理', 3: '不满意', 4: '已关闭' })[Number(z)] || String(z || '')
|
||||
return ({ 1: '处理中', 2: '已处理', 3: '不满意', 4: '已关闭', 5: '协商中' })[Number(z)] || String(z || '')
|
||||
}
|
||||
|
||||
function statusTagType(z) {
|
||||
@@ -337,13 +397,14 @@ function statusTagType(z) {
|
||||
if (n === 2) return 'success'
|
||||
if (n === 3) return 'warning'
|
||||
if (n === 4) return 'info'
|
||||
if (n === 5) return 'warning'
|
||||
return ''
|
||||
}
|
||||
|
||||
function rowClassName({ row }) {
|
||||
if (Number(row.zhuangtai) === 1) return 'row-pending'
|
||||
if (Number(row.zhuangtai) === 1 || Number(row.zhuangtai) === 5) return 'row-pending'
|
||||
if (Number(row.zhuangtai) === 3) return 'row-dissatisfied'
|
||||
if ((row.shengji_cishu || 0) > 0 && [1, 3].includes(Number(row.zhuangtai))) return 'row-escalate'
|
||||
if ((row.shengji_cishu || 0) > 0 && [1, 3, 5].includes(Number(row.zhuangtai))) return 'row-escalate'
|
||||
return ''
|
||||
}
|
||||
|
||||
@@ -509,10 +570,15 @@ async function handle(action) {
|
||||
gongdan_id: current.value.gongdan_id,
|
||||
action,
|
||||
chuli_jieguo: jieguo.value,
|
||||
intervene_reason: action === 'intervene' ? 'kefu' : '',
|
||||
})
|
||||
if (res.code === 200 || res.code === 0) {
|
||||
ElMessage.success('已保存')
|
||||
drawer.value = false
|
||||
ElMessage.success(action === 'intervene' ? '已标记平台介入' : '已保存')
|
||||
if (action === 'intervene' && res.data) {
|
||||
current.value = res.data
|
||||
} else {
|
||||
drawer.value = false
|
||||
}
|
||||
load(page.value)
|
||||
} else ElMessage.error(res.message || res.msg || '失败')
|
||||
} catch (e) {
|
||||
@@ -522,12 +588,81 @@ async function handle(action) {
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => load(1))
|
||||
async function loadClubConfig() {
|
||||
configLoading.value = true
|
||||
try {
|
||||
const res = await request.get('/gongdan/admin/club-config/')
|
||||
if (res.code === 200 || res.code === 0) {
|
||||
configClubId.value = res.data?.club_id || ''
|
||||
withdrawBlock.value = !!res.data?.complaint_withdraw_block
|
||||
}
|
||||
} catch (e) {
|
||||
// 旧后端无此接口时忽略
|
||||
} finally {
|
||||
configLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function onToggleWithdrawBlock(val) {
|
||||
configSaving.value = true
|
||||
try {
|
||||
const res = await request.post('/gongdan/admin/club-config/', {
|
||||
complaint_withdraw_block: !!val,
|
||||
})
|
||||
if (res.code === 200 || res.code === 0) {
|
||||
withdrawBlock.value = !!res.data?.complaint_withdraw_block
|
||||
configClubId.value = res.data?.club_id || configClubId.value
|
||||
ElMessage.success(val ? '已开启投诉拦截提现' : '已关闭投诉拦截提现')
|
||||
} else {
|
||||
withdrawBlock.value = !val
|
||||
ElMessage.error(res.message || res.msg || '保存失败')
|
||||
}
|
||||
} catch (e) {
|
||||
withdrawBlock.value = !val
|
||||
ElMessage.error('保存失败')
|
||||
} finally {
|
||||
configSaving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadClubConfig()
|
||||
load(1)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.gongdan-page { padding: 12px; color: #1f2937; }
|
||||
|
||||
.config-card {
|
||||
margin-bottom: 16px;
|
||||
background: rgba(6, 12, 20, 0.72);
|
||||
border: 1px solid rgba(0, 242, 255, 0.2);
|
||||
}
|
||||
.config-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
}
|
||||
.config-title {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #eef2ff;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.config-desc {
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
color: rgba(238, 242, 255, 0.72);
|
||||
max-width: 720px;
|
||||
}
|
||||
.config-club {
|
||||
margin-top: 8px;
|
||||
font-size: 12px;
|
||||
color: rgba(0, 242, 255, 0.85);
|
||||
}
|
||||
|
||||
.stat-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(6, minmax(0, 1fr));
|
||||
|
||||
Reference in New Issue
Block a user