feat: 打手详情赠送会员 UI,并改善后台错误提示
新增赠送会员送/改期/移除;请求失败优先展示后端 msg;考核官添加防重复提交。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -53,7 +53,7 @@ service.interceptors.response.use(
|
|||||||
ElMessage.error('没有权限')
|
ElMessage.error('没有权限')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ElMessage.error(error.response.data?.message || '请求失败')
|
ElMessage.error(error.response.data?.msg || error.response.data?.message || '请求失败')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ElMessage.error('网络错误')
|
ElMessage.error('网络错误')
|
||||||
|
|||||||
@@ -835,6 +835,10 @@ const confirmAddUser = async () => {
|
|||||||
ElMessage.warning('密码和二级密码至少6位')
|
ElMessage.warning('密码和二级密码至少6位')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (newUserRoleCodes.value.length === 0) {
|
||||||
|
ElMessage.warning('请至少选择一个角色')
|
||||||
|
return
|
||||||
|
}
|
||||||
addingUser.value = true
|
addingUser.value = true
|
||||||
try {
|
try {
|
||||||
const res = await request.post('/houtai/tjyhjs', {
|
const res = await request.post('/houtai/tjyhjs', {
|
||||||
|
|||||||
@@ -282,7 +282,7 @@ const saveChenghao = async () => {
|
|||||||
ElMessage.error(res.msg || '操作失败')
|
ElMessage.error(res.msg || '操作失败')
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ElMessage.error('网络错误')
|
ElMessage.error(e?.response?.data?.msg || e?.message || '网络错误')
|
||||||
} finally {
|
} finally {
|
||||||
saving.value = false
|
saving.value = false
|
||||||
}
|
}
|
||||||
@@ -311,7 +311,7 @@ const deleteChenghao = async () => {
|
|||||||
ElMessage.error(res.msg || '删除失败')
|
ElMessage.error(res.msg || '删除失败')
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ElMessage.error('网络错误')
|
ElMessage.error(e?.response?.data?.msg || e?.message || '网络错误')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -510,6 +510,7 @@ const closeAddDialog = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const submitAddExaminer = async () => {
|
const submitAddExaminer = async () => {
|
||||||
|
if (addSaving.value) return
|
||||||
const uid = (addForm.yonghuid || '').trim()
|
const uid = (addForm.yonghuid || '').trim()
|
||||||
if (!uid) {
|
if (!uid) {
|
||||||
ElMessage.warning('请输入用户ID')
|
ElMessage.warning('请输入用户ID')
|
||||||
@@ -535,7 +536,7 @@ const submitAddExaminer = async () => {
|
|||||||
ElMessage.error(res.msg || '添加失败')
|
ElMessage.error(res.msg || '添加失败')
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ElMessage.error('网络错误')
|
ElMessage.error(e?.response?.data?.msg || e?.message || '网络错误')
|
||||||
} finally {
|
} finally {
|
||||||
addSaving.value = false
|
addSaving.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -325,6 +325,46 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 赠送会员(免费接单,独立表) -->
|
||||||
|
<el-card class="info-card" shadow="hover">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span>🎁 赠送会员(免费接单)</span>
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
size="small"
|
||||||
|
@click="openGiftDialog()"
|
||||||
|
:disabled="!hasGiftPermission"
|
||||||
|
>送会员</el-button>
|
||||||
|
</div>
|
||||||
|
<div v-if="!hasGiftPermission" class="member-hint warn">需要打手基础管理或加积分权限</div>
|
||||||
|
<div v-else class="member-hint">与上方购买会员分开;仅用于抢单资格,不写购买表</div>
|
||||||
|
</template>
|
||||||
|
<div class="member-list">
|
||||||
|
<div v-for="gift in giftMemberList" :key="'g-' + gift.id" class="member-item gift-item">
|
||||||
|
<el-tag :type="gift.is_active ? 'success' : 'info'" effect="plain">
|
||||||
|
{{ gift.huiyuan_name }} 到期: {{ gift.daoqi_time || '--' }}
|
||||||
|
</el-tag>
|
||||||
|
<span class="gift-meta">赠送人 {{ gift.song_ren || '--' }} · {{ gift.song_time || '--' }}</span>
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
size="small"
|
||||||
|
link
|
||||||
|
@click="openGiftDialog(gift)"
|
||||||
|
:disabled="!hasGiftPermission"
|
||||||
|
>改期</el-button>
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
size="small"
|
||||||
|
link
|
||||||
|
@click="removeGiftMember(gift)"
|
||||||
|
:disabled="!hasGiftPermission"
|
||||||
|
>移除</el-button>
|
||||||
|
</div>
|
||||||
|
<div v-if="giftMemberList.length === 0" class="empty-message">暂无赠送会员</div>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
<!-- 其他信息卡片 -->
|
<!-- 其他信息卡片 -->
|
||||||
<el-card class="info-card" shadow="hover">
|
<el-card class="info-card" shadow="hover">
|
||||||
<template #header>
|
<template #header>
|
||||||
@@ -377,24 +417,64 @@
|
|||||||
|
|
||||||
<!-- 添加会员弹窗 -->
|
<!-- 添加会员弹窗 -->
|
||||||
<el-dialog v-model="memberDialogVisible" title="添加会员" width="400px">
|
<el-dialog v-model="memberDialogVisible" title="添加会员" width="400px">
|
||||||
<el-form :model="memberForm" label-width="80px">
|
<el-form label-width="90px">
|
||||||
<el-form-item label="会员类型" required>
|
<el-form-item label="会员类型" required>
|
||||||
<el-select v-model="memberForm.huiyuan_id" placeholder="请选择会员" style="width: 100%">
|
<el-select v-model="memberForm.huiyuan_id" placeholder="请选择" filterable style="width: 100%">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in allMembers"
|
v-for="m in allMembers"
|
||||||
:key="item.huiyuan_id"
|
:key="m.huiyuan_id"
|
||||||
:label="item.jieshao"
|
:label="`${m.jieshao} (${m.huiyuan_id})`"
|
||||||
:value="item.huiyuan_id"
|
:value="m.huiyuan_id"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="天数" required>
|
<el-form-item label="天数" required>
|
||||||
<el-input-number v-model="memberForm.days" :min="1" :step="1" style="width: 100%" />
|
<el-input-number v-model="memberForm.days" :min="1" :max="3650" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="memberDialogVisible = false">取消</el-button>
|
<el-button @click="memberDialogVisible = false">取消</el-button>
|
||||||
<el-button type="primary" @click="addMember" :loading="memberAdding">确认</el-button>
|
<el-button type="primary" :loading="memberAdding" @click="addMember">确认</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 赠送会员弹窗 -->
|
||||||
|
<el-dialog
|
||||||
|
v-model="giftDialogVisible"
|
||||||
|
:title="giftForm.id ? '修改赠送会员到期时间' : '送会员(免费接单)'"
|
||||||
|
width="420px"
|
||||||
|
>
|
||||||
|
<el-form label-width="100px">
|
||||||
|
<el-form-item label="会员类型" required>
|
||||||
|
<el-select
|
||||||
|
v-model="giftForm.huiyuan_id"
|
||||||
|
placeholder="请选择真实会员类型"
|
||||||
|
filterable
|
||||||
|
style="width: 100%"
|
||||||
|
:disabled="!!giftForm.id"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="m in allMembers"
|
||||||
|
:key="'g-' + m.huiyuan_id"
|
||||||
|
:label="`${m.jieshao} (${m.huiyuan_id})`"
|
||||||
|
:value="m.huiyuan_id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="到期日期" required>
|
||||||
|
<el-date-picker
|
||||||
|
v-model="giftForm.daoqi_time"
|
||||||
|
type="datetime"
|
||||||
|
placeholder="选择到期时间"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<div class="member-hint">赠送时若积分不是 10,将自动改成 10 并写入操作日志</div>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="giftDialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" :loading="giftSaving" @click="submitGiftMember">确认</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
@@ -418,6 +498,7 @@ const username = ref(localStorage.getItem('username') || '')
|
|||||||
const playerInfo = ref({})
|
const playerInfo = ref({})
|
||||||
const originalInfo = ref({})
|
const originalInfo = ref({})
|
||||||
const memberList = ref([])
|
const memberList = ref([])
|
||||||
|
const giftMemberList = ref([])
|
||||||
const allMembers = ref([])
|
const allMembers = ref([])
|
||||||
const isEditMode = ref(false)
|
const isEditMode = ref(false)
|
||||||
const editData = ref({})
|
const editData = ref({})
|
||||||
@@ -427,6 +508,11 @@ const memberDialogVisible = ref(false)
|
|||||||
const memberForm = reactive({ huiyuan_id: '', days: 30 })
|
const memberForm = reactive({ huiyuan_id: '', days: 30 })
|
||||||
const memberAdding = ref(false)
|
const memberAdding = ref(false)
|
||||||
|
|
||||||
|
// 赠送会员弹窗
|
||||||
|
const giftDialogVisible = ref(false)
|
||||||
|
const giftSaving = ref(false)
|
||||||
|
const giftForm = reactive({ id: null, huiyuan_id: '', daoqi_time: '' })
|
||||||
|
|
||||||
// 权限控制
|
// 权限控制
|
||||||
const userPermissions = ref([])
|
const userPermissions = ref([])
|
||||||
|
|
||||||
@@ -436,6 +522,14 @@ const hasMemberPermission = computed(() =>
|
|||||||
userPermissions.value.includes('001ff') ||
|
userPermissions.value.includes('001ff') ||
|
||||||
userPermissions.value.includes('001gg')
|
userPermissions.value.includes('001gg')
|
||||||
)
|
)
|
||||||
|
const hasGiftPermission = computed(() =>
|
||||||
|
userPermissions.value.includes('000001') ||
|
||||||
|
userPermissions.value.includes('001aa') ||
|
||||||
|
userPermissions.value.includes('001bb') ||
|
||||||
|
userPermissions.value.includes('001cc') ||
|
||||||
|
userPermissions.value.includes('001dd') ||
|
||||||
|
userPermissions.value.includes('001ee')
|
||||||
|
)
|
||||||
const hasChenghaoPermission = computed(() => userPermissions.value.includes('001hh'))
|
const hasChenghaoPermission = computed(() => userPermissions.value.includes('001hh'))
|
||||||
const canChangeInviter = computed(() => userPermissions.value.includes('001ee') || userPermissions.value.includes('000001'))
|
const canChangeInviter = computed(() => userPermissions.value.includes('001ee') || userPermissions.value.includes('000001'))
|
||||||
|
|
||||||
@@ -536,6 +630,7 @@ const fetchDetail = async () => {
|
|||||||
}
|
}
|
||||||
originalInfo.value = JSON.parse(JSON.stringify(playerInfo.value))
|
originalInfo.value = JSON.parse(JSON.stringify(playerInfo.value))
|
||||||
memberList.value = data.member_list || []
|
memberList.value = data.member_list || []
|
||||||
|
giftMemberList.value = data.gift_member_list || []
|
||||||
allMembers.value = data.all_members || []
|
allMembers.value = data.all_members || []
|
||||||
userPermissions.value = data.permissions || []
|
userPermissions.value = data.permissions || []
|
||||||
} else if (res.code === 403) {
|
} else if (res.code === 403) {
|
||||||
@@ -714,6 +809,82 @@ const removeMember = async (member) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 关键:从路由参数中获取 playerId(参数名必须为 playerId)
|
// 关键:从路由参数中获取 playerId(参数名必须为 playerId)
|
||||||
|
const openGiftDialog = (gift = null) => {
|
||||||
|
if (!hasGiftPermission.value) {
|
||||||
|
ElMessage.warning('无赠送会员权限')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (gift) {
|
||||||
|
giftForm.id = gift.id
|
||||||
|
giftForm.huiyuan_id = gift.huiyuan_id
|
||||||
|
giftForm.daoqi_time = gift.daoqi_time || ''
|
||||||
|
} else {
|
||||||
|
giftForm.id = null
|
||||||
|
giftForm.huiyuan_id = ''
|
||||||
|
giftForm.daoqi_time = ''
|
||||||
|
}
|
||||||
|
giftDialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const submitGiftMember = async () => {
|
||||||
|
if (!giftForm.huiyuan_id) {
|
||||||
|
ElMessage.warning('请选择会员类型')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!giftForm.daoqi_time) {
|
||||||
|
ElMessage.warning('请选择到期时间')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
giftSaving.value = true
|
||||||
|
try {
|
||||||
|
const payload = {
|
||||||
|
phone: username.value,
|
||||||
|
dashou_id: playerId.value,
|
||||||
|
huiyuan_id: giftForm.huiyuan_id,
|
||||||
|
daoqi_time: giftForm.daoqi_time,
|
||||||
|
}
|
||||||
|
if (giftForm.id) payload.id = giftForm.id
|
||||||
|
const res = await request.post('/houtai/dszsonghy', payload)
|
||||||
|
if (res.code === 0) {
|
||||||
|
ElMessage.success(res.msg || '操作成功')
|
||||||
|
giftDialogVisible.value = false
|
||||||
|
await fetchDetail()
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.msg || '操作失败')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
ElMessage.error(e?.response?.data?.msg || '操作失败')
|
||||||
|
} finally {
|
||||||
|
giftSaving.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const removeGiftMember = async (gift) => {
|
||||||
|
try {
|
||||||
|
await ElMessageBox.confirm(
|
||||||
|
`确定移除赠送会员“${gift.huiyuan_name}”吗?移除后将无法用该赠送资格抢单。`,
|
||||||
|
'提示',
|
||||||
|
{ type: 'warning' }
|
||||||
|
)
|
||||||
|
} catch { return }
|
||||||
|
try {
|
||||||
|
const res = await request.post('/houtai/dsycsonghy', {
|
||||||
|
phone: username.value,
|
||||||
|
dashou_id: playerId.value,
|
||||||
|
id: gift.id,
|
||||||
|
huiyuan_id: gift.huiyuan_id,
|
||||||
|
})
|
||||||
|
if (res.code === 0) {
|
||||||
|
ElMessage.success('移除成功')
|
||||||
|
await fetchDetail()
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.msg || '移除失败')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
ElMessage.error(e?.response?.data?.msg || '移除失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
playerId.value = route.params.playerId
|
playerId.value = route.params.playerId
|
||||||
if (!playerId.value) {
|
if (!playerId.value) {
|
||||||
@@ -737,6 +908,15 @@ onMounted(() => {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
}
|
}
|
||||||
|
.gift-item {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
.gift-meta {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #909399;
|
||||||
|
margin: 0 4px;
|
||||||
|
}
|
||||||
.member-item {
|
.member-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|||||||
Reference in New Issue
Block a user