提交 01abd744 作者: 施汉文

新增举报功能,包含举报弹窗组件及相关逻辑,更新用户信息和游戏API接口

上级 34000873
......@@ -211,13 +211,13 @@ export default {
// 页面刷新时从 Cookie 恢复 token 到 store
// Cookies.set(
// "token",
// "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOjQwOTAsImRhdGEiOnsiY3Nlcl9pZCI6NDA5MCwiY3Nlcl9uYW1lIjoi5q-b57uG5LqaIn0sImlhdCI6MTc2ODU0Mjk0MiwiZXhwIjoxNzcxMTM0OTQyLCJuYmYiOjE3Njg1NDI5NDIsInN1YiI6InRva2Vu6K6k6K-BIiwianRpIjoiMjU0Zjg3OGQ3NzMyNWUyMzMyNDAwZTEwZWJkMjFkY2YifQ.3hHc6iQP-Xkz9Q5rMIOFENDdh5P-NSaRs4Y4ffbJcMg"
// "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOjEyMzg2LCJkYXRhIjp7ImNzZXJfaWQiOjEyMzg2LCJjc2VyX25hbWUiOiLlvKDlpo3lpo0ifSwiaWF0IjoxNzc2OTk3MTgzLCJleHAiOjE3Nzk1ODkxODMsIm5iZiI6MTc3Njk5NzE4Mywic3ViIjoidG9rZW7orqTor4EiLCJqdGkiOiIxM2I3ODk0MjJjMThiOTUzNzFmOWVjZmYzZGMzNzY1NCJ9.2_8gCTzSrnR8q7i9_Pus1xT8NMY9-cXJim_FElSsa5A"
// );
// Cookies.set("corp_id", "wweaefe716636df3d1");
// Cookies.set("userid", "maoxiya");
// Cookies.set("cser_name", "毛细亚");
// Cookies.set("external_userid", "wm5rUgMgAAG_vfF4AHClsrS1S6MImVsQ");
// Cookies.set("cser_id", 4090);
// Cookies.set("userid", "ShanYi");
// Cookies.set("cser_name", "张妍妍");
// Cookies.set("external_userid", "wm5rUgMgAAj_YnkyHU1lVfYDT7QACqWg");
// Cookies.set("cser_id", 12386);
// Cookies.set("weixin_blongs_id", 2862);
const cookieToken = Cookies.get("token");
if (cookieToken && !this.token) {
......
......@@ -689,7 +689,20 @@ export function reportAdd(data) {
});
});
}
// 获取当前合服生态运营人员
export function currUserList(data) {
return new Promise((resolve, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/server/currUserList',
params: data
}).then((res) => {
resolve(res)
}).catch((error) => {
reject(error)
})
})
}
// 申诉列表
export function appealList(data) {
data.zw_user_id = getZwUserId();
......
<template>
<div class="violationRecord">
<el-form v-loading="loading" class="violationRecordContent" label-width="90px">
<el-button type="primary" size="small" @click="reportPopupShow = true">举报</el-button>
<div v-if="violationList.length > 0">
<div v-for="(item, index) in violationList" :key="index" class="contentItem">
<el-form-item label="违规时间:">
......@@ -96,6 +97,7 @@
<el-dialog title="查看大图" :visible.sync="imageLayer" width="320px" center append-to-body @close="imageLayer = false">
<div v-html="imageSrc" class="layerImage"></div>
</el-dialog>
<reportPopup :show.sync="reportPopupShow" />
</div>
</template>
......@@ -105,11 +107,12 @@ import { violationList } from "@/api/game";
import noContent from "@/components/noContent.vue";
import { debounce } from '@/utils'
import watchMember from '@/mixins/watchMember'
import reportPopup from '@/views/popup/reportPopup/index.vue'
export default {
name: 'ViolationRecord',
components: {
noContent,
reportPopup,
},
mixins: [watchMember],
data() {
......@@ -118,6 +121,7 @@ export default {
violationList: [],
loading: false,
imageLayer: false,
reportPopupShow: false,
};
},
computed: {
......
<template>
<el-drawer
:lock-scroll="true"
title="举报申请"
:visible="show"
size="400px"
:append-to-body="true"
@close="close"
>
<div class="drawer-content-main">
<div class="drawer-content">
<el-form
ref="reportForm"
:model="reportForm"
:rules="reportRules"
:validate-on-rule-change="false"
label-position="top"
class="reportForm"
label-width="80px"
>
<el-form-item label="主游戏" prop="main_game_id">
<mainGameSelect
label=""
:default-value="reportForm.main_game_id"
style="width: 100%"
width="100%"
@result="mainGameResult"
/>
</el-form-item>
<el-form-item label="">
<el-radio-group v-model="reportForm.report_role_id_type">
<el-radio label="cp_role_id">CP角色ID</el-radio>
<el-radio label="role_id">掌游角色ID</el-radio>
</el-radio-group>
</el-form-item>
<!--被举报人 -->
<inputTags
:input-select-list.sync="reportForm.cp_role_id"
label-text="被举报人CP角色ID"
placeholder="请输入被举报人"
:disabled="reportForm.main_game_id === ''"
rule-prop="cp_role_id"
@inputChange="inputChange"
/>
<inputTags
:input-select-list.sync="reportForm.role_name"
label-text="被举报人角色名"
placeholder="输入CP角色ID后自动获取"
:disabled="true"
rule-prop="role_name"
/>
<inputTags
:input-select-list.sync="reportForm.server_name"
label-text="被举报人区服"
placeholder="输入CP角色ID后自动获取"
:disabled="true"
rule-prop="server_name"
/>
<!-- 仅 currUserList 有生态运营数据时展示 -->
<template v-if="hasEcoUserData">
<el-form-item label="被举报人生态运营" prop="eco_user">
<el-input
:value="ecoUserNamesDisplay"
style="width: 100%"
type="input"
disabled
/>
</el-form-item>
</template>
<el-form-item label="">
<el-radio-group v-model="reportForm.role_id_type">
<el-radio label="cp_role_id">CP角色ID</el-radio>
<el-radio label="role_id">掌游角色ID</el-radio>
</el-radio-group>
</el-form-item>
<!-- 举报人 -->
<el-form-item label="举报人CP角色ID" prop="report_cp_role_id">
<el-input
v-model="reportForm.report_cp_role_id"
style="width: 100%"
placeholder="请输入举报人"
@change="change_report_role_id"
></el-input>
</el-form-item>
<el-form-item label="举报人角色名" prop="report_role_name">
<el-input
v-model="reportForm.report_role_name"
style="width: 100%"
placeholder="输入CP角色ID后自动获取"
disabled
></el-input>
</el-form-item>
<el-form-item label="举报人区服" prop="report_server_name">
<el-input
v-model="reportForm.report_server_name"
placeholder="输入CP角色ID后自动获取"
style="width: 100%"
disabled
></el-input>
</el-form-item>
<template v-if="hasEcoUserData">
<el-form-item label="是否有生态运营" prop="is_negotiation">
<el-radio-group v-model="reportForm.is_negotiation">
<el-radio :label="1"></el-radio>
<el-radio :label="2"></el-radio>
</el-radio-group>
</el-form-item>
</template>
<el-form-item label="违规操作" prop="violation_type">
<el-select
v-model="reportForm.violation_type"
style="width: 100%"
clearable
placeholder="请选择"
>
<el-option
v-for="item in violation_type_list"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="详情" prop="remark">
<textEditor
:remark.sync="reportForm.remark"
domid="report_content"
style="width: 100%; margin-bottom: 60px"
:contenteditable="true"
@resultReamrk="resultReamrk"
/>
</el-form-item>
</el-form>
</div>
<span class="dialog-footer rowFlex">
<el-button
class="btn"
type="primary"
:loading="loading"
@click="submit"
>确 定</el-button>
<el-button class="btn" @click="close">取 消</el-button>
</span>
</div>
</el-drawer>
</template>
<script type="text/javascript">
import mainGameSelect from '@/components/mainGame.vue'
import textEditor from '@/components/textEditor.vue'
import { searchcondition, reportAdd,currUserList } from '@/api/game'
import { mapState } from 'vuex'
import inputTags from '@/components/inputTags/index.vue'
export default {
components: {
mainGameSelect,
textEditor,
inputTags
},
computed: {
...mapState('game', ['accountSelect']),
...mapState('user', ['userInfo']),
/**
* 生态运营展示文案:有列表时拼接全部 user_name;无列表时回显表单已有值(如编辑态)
*/
ecoUserNamesDisplay() {
if (this.eco_user_list && this.eco_user_list.length > 0) {
return this.eco_user_list
.map((item) => item.user_name || item.name)
.filter(Boolean)
.join('、')
}
return this.reportForm.eco_user || ''
},
/**
* 生态运营接口有返回列表数据时才展示相关表单项并参与校验
*/
hasEcoUserData() {
return Array.isArray(this.eco_user_list) && this.eco_user_list.length > 0
},
/**
* 无生态运营数据时不校验 eco_user、is_negotiation
*/
reportRules() {
const rules = {
main_game_id: [
{ required: true, message: '请选择主游戏', trigger: 'change' }
],
cp_role_id: [
{
required: true,
message: '请选择被举报人cp角色id',
trigger: 'change'
}
],
role_id: [
{ required: true, message: '请选择角色名', trigger: 'change' }
],
server_name: [
{ required: true, message: '请选择区服', trigger: 'change' }
],
violation_type: [
{ required: true, message: '请选择违规操作', trigger: 'change' }
],
remark: [{ required: true, message: '请填写详情', trigger: 'change' }]
}
if (this.hasEcoUserData) {
rules.eco_user = [
{
required: true,
message: '被举报人生态运营',
trigger: 'change'
}
]
rules.is_negotiation = [
{
required: true,
message: '请选择是否有生态运营',
trigger: 'change'
}
]
}
return rules
}
},
props: {
show: {
type: Boolean,
default: false
},
reportInfo: {
type: Object,
default: () => {
return {}
}
}
},
data() {
return {
reportForm: {
main_game_id: '',
report_role_id_type: 'cp_role_id',
role_id_type: 'cp_role_id',
cp_role_id: [],
role_id: [],
role_name: [],
server_name: [],
violation_type: '',
report_cp_role_id: '',
report_role_id: '',
report_role_name: '',
report_server_name: '',
eco_user: '',
is_negotiation: '',
remark: ''
},
zyou_server_id_list: [], // 存储被举报人的区服ID列表
violation_type_list: [
{
label: '减轻处罚',
value: 1
},
{
label: '解除禁言',
value: 2
},
{
label: '解除封禁',
value: 3
}
],
loading: false,
cp_role_id_loading: false,
serverNameList: [],
searchUserOption: [],
eco_user_list: [] // 生态运营人员列表
}
},
watch: {
show(newVal, oldVal) {
if (newVal) {
console.log('显示弹窗')
}
// 重新提交:抽屉再次打开时重新拉取生态运营(组件未销毁、仅 show 切换的场景)
if (newVal === true && oldVal === false && this.reportInfo && this.reportInfo.id) {
this.$nextTick(() => {
this.refreshEcoUserForResubmit()
})
}
},
/**
* 生态运营区块隐藏时清除这两项校验状态,避免残留红字
*/
hasEcoUserData(val) {
if (!val && this.$refs.reportForm) {
this.$nextTick(() => {
this.$refs.reportForm.clearValidate(['eco_user', 'is_negotiation'])
})
}
}
},
mounted() {
this.searchcondition()
if (this.reportInfo && this.reportInfo.id) {
const info = this.reportInfo
const {
main_game_id = 1,
cp_role_id = [],
role_id = [],
role_name = [],
server_name = [],
violation_type = '',
report_cp_role_id = '',
report_role_id = '',
report_role_name = '',
report_server_name = '',
eco_user = '',
is_negotiation = '',
remark = ''
} = info
this.reportForm = {
main_game_id: Number(main_game_id),
cp_role_id: Array.isArray(cp_role_id) ? cp_role_id : cp_role_id != '' ? [cp_role_id] : [],
role_id: Array.isArray(role_id) ? role_id : role_id !== '' ? [role_id] : [],
role_name: Array.isArray(role_name) ? role_name : role_name !== '' ? [role_name] : [],
server_name: Array.isArray(server_name) ? server_name : server_name !== '' ? [server_name] : [],
violation_type: Number(violation_type),
report_cp_role_id,
report_role_id_type: this.normalizeRoleIdType(
this.pickReportInfoField(info, 'report_role_id_type', 'reportRoleIdType')
),
role_id_type: this.normalizeRoleIdType(
this.pickReportInfoField(info, 'role_id_type', 'roleIdType')
),
report_role_id,
report_role_name,
report_server_name,
eco_user,
is_negotiation: Number(is_negotiation) || '',
remark
}
this.$nextTick(() => {
this.refreshEcoUserForResubmit()
})
}
},
methods: {
/**
* 从举报详情中取字段,兼容下划线 / 驼峰(列表接口字段名可能不一致)
*/
pickReportInfoField(info, snakeKey, camelKey) {
const a = info[snakeKey]
if (a !== undefined && a !== null && String(a).trim() !== '') return a
const b = info[camelKey]
if (b !== undefined && b !== null && String(b).trim() !== '') return b
return undefined
},
/**
* 与 el-radio 的 label 对齐,仅允许 cp_role_id / role_id,缺省或非法时默认 CP 角色 ID
*/
normalizeRoleIdType(val) {
if (val === undefined || val === null) return 'cp_role_id'
if (val === 1 || val === '1') return 'cp_role_id'
if (val === 2 || val === '2') return 'role_id'
const s = String(val).trim()
if (s === '') return 'cp_role_id'
if (s === 'cp_role_id' || s === 'role_id') return s
const lower = s.toLowerCase()
if (lower === 'cp_role_id' || lower === 'role_id') return lower
return 'cp_role_id'
},
// inputTag 返回的值
inputChange(value) {
this.reportForm.cp_role_id = value
this.change_cp_role_id()
},
async change_cp_role_id() {
if (this.reportForm.main_game_id == '') {
this.$message.warning('请先选择主游戏')
return
}
if (this.reportForm.cp_role_id.length == 0) {
this.$message.warning('请按回车键确定CP角色ID')
return
}
this.cp_role_id_loading = true
this.$message.warning('查询中,请稍等')
const res = await searchcondition({
type: 'role',
cp_role_id: this.reportForm.cp_role_id,
main_game_id: this.reportForm.main_game_id
})
this.cp_role_id_loading = false
if (res.status_code == 1 && res.data.data.length > 0) {
this.reportForm.role_id = res.data.data.map((item) => item.value)
this.reportForm.role_name = res.data.data.map((item) => item.label)
this.reportForm.server_name = res.data.data.map(
(item) => item.server_name
)
// 收集被举报人的区服ID(优先使用被举报人的区服ID)
this.zyou_server_id_list = res.data.data
.map((item) => item.zyou_server_id)
.filter((id) => id !== undefined && id !== null && id !== '')
// 加载生态运营人员列表
this.loadEcoUserList()
} else {
this.$message.warning('角色信息不存在')
this.zyou_server_id_list = []
this.eco_user_list = []
this.reportForm.eco_user = ''
}
},
async change_report_role_id() {
if (
!!this.reportForm.report_cp_role_id &&
!!this.reportForm.main_game_id
) {
const res = await searchcondition({
type: 'role',
cp_role_id: this.reportForm.report_cp_role_id,
main_game_id: this.reportForm.main_game_id
})
if (res.status_code == 1 && res.data.data.length > 0) {
this.reportForm.report_role_id = res.data.data[0]
? res.data.data[0].value
: ''
this.reportForm.report_role_name = res.data.data[0]
? res.data.data[0].label
: ''
this.reportForm.report_server_name = res.data.data[0]
? res.data.data[0].server_name
: ''
// 收集所有的 zyou_server_id
this.zyou_server_id_list = res.data.data
.map((item) => item.zyou_server_id)
.filter((id) => id !== undefined && id !== null && id !== '')
// 加载生态运营人员列表
this.loadEcoUserList()
} else {
this.$message.warning('角色信息不存在')
this.zyou_server_id_list = []
this.eco_user_list = []
this.reportForm.eco_user = ''
}
} else {
this.$message.warning('请先选择主游戏')
this.reportForm.cp_role_id = ''
this.zyou_server_id_list = []
this.eco_user_list = []
this.reportForm.eco_user = ''
}
},
searchcondition() {
const data = {
type: 'dictionaries',
table_name: 'zs_violation',
field_name: 'violation_type'
}
searchcondition(data).then((res) => {
this.violation_type_list = res.data.data
})
},
resultReamrk(text) {
// console.log(text, '最后编辑器的内容')
},
/**
* 根据 eco_user_list 同步提交字段 eco_user(全部姓名用顿号拼接)
*/
syncEcoUserFromList() {
if (!this.eco_user_list || this.eco_user_list.length === 0) {
this.reportForm.eco_user = ''
return
}
this.reportForm.eco_user = this.eco_user_list
.map((item) => item.user_name || item.name)
.filter(Boolean)
.join('、')
},
/**
* 重新提交(reportInfo.id 存在)时:用表单里的角色信息补全 zyou_server_id,再请求生态运营列表
*/
async refreshEcoUserForResubmit() {
if (!(this.reportInfo && this.reportInfo.id)) return
const mainGameId = this.reportForm.main_game_id
if (!mainGameId) return
try {
const cpIds = Array.isArray(this.reportForm.cp_role_id)
? this.reportForm.cp_role_id.filter(Boolean)
: this.reportForm.cp_role_id
? [this.reportForm.cp_role_id]
: []
if (cpIds.length > 0) {
const res = await searchcondition({
type: 'role',
cp_role_id: cpIds,
main_game_id: mainGameId
})
if (res.status_code == 1 && res.data.data && res.data.data.length > 0) {
this.zyou_server_id_list = res.data.data
.map((item) => item.zyou_server_id)
.filter((id) => id !== undefined && id !== null && id !== '')
await this.loadEcoUserList()
return
}
}
if (this.reportForm.report_cp_role_id) {
const res = await searchcondition({
type: 'role',
cp_role_id: this.reportForm.report_cp_role_id,
main_game_id: mainGameId
})
if (res.status_code == 1 && res.data.data && res.data.data.length > 0) {
this.zyou_server_id_list = res.data.data
.map((item) => item.zyou_server_id)
.filter((id) => id !== undefined && id !== null && id !== '')
await this.loadEcoUserList()
return
}
}
this.zyou_server_id_list = []
this.eco_user_list = []
this.syncEcoUserFromList()
} catch (e) {
console.error('重新提交态刷新生态运营失败:', e)
}
},
/**
* 加载生态运营人员列表(currUserList)
*/
async loadEcoUserList() {
// 检查是否有区服ID列表
if (!this.zyou_server_id_list || this.zyou_server_id_list.length === 0) {
this.eco_user_list = []
this.syncEcoUserFromList()
return
}
try {
const res = await currUserList({
zyou_server_id: this.zyou_server_id_list,
settle_state: 1
})
console.log('currUserList 接口返回数据:', res)
if (res.status_code === 1 && res.data) {
// 处理返回的数据结构:{ "29_22_7q_73528": [...] },key 是动态的
// 将动态 key 替换成 data,统一处理
let ecoUserList = []
// 遍历 res.data 的所有 key,提取数组数据
Object.keys(res.data).forEach((key) => {
if (Array.isArray(res.data[key])) {
// 将动态 key 的值提取出来,统一处理
const items = res.data[key].map((item) => ({
...item,
eco_user: key, // 使用动态 key 作为 eco_user(用于提交)
data: res.data[key] // 添加 data 字段,值为该 key 对应的数组
}))
ecoUserList = ecoUserList.concat(items)
}
})
// 将数据结构转换为 { data: [...] } 格式
const transformedData = {
data: ecoUserList
}
console.log('转换后的数据结构(key 替换为 data):', transformedData)
// 如果 res.data.data 存在,优先使用(兼容其他数据结构)
if (res.data.data && Array.isArray(res.data.data) && res.data.data.length > 0) {
this.eco_user_list = res.data.data
} else if (ecoUserList.length > 0) {
this.eco_user_list = ecoUserList
} else {
this.eco_user_list = []
}
console.log('处理后的生态运营人员列表:', this.eco_user_list)
this.syncEcoUserFromList()
} else {
this.eco_user_list = []
this.syncEcoUserFromList()
}
} catch (error) {
console.error('查询生态运营人员失败:', error)
this.eco_user_list = []
this.syncEcoUserFromList()
this.$message.error('查询生态运营人员失败,请稍后重试')
}
},
/**
* 主游戏变更:清空角色与生态运营相关数据
*/
mainGameResult(data) {
this.reportForm.main_game_id = data
this.reportForm.cp_role_id = []
this.reportForm.role_id = []
this.reportForm.role_name = []
this.reportForm.server_name = []
this.zyou_server_id_list = []
this.eco_user_list = []
this.reportForm.eco_user = ''
// 规则变化或 model 清空时避免误触全表/其它项校验;并清掉已重置字段的红字
this.$nextTick(() => {
if (this.$refs.reportForm) {
this.$refs.reportForm.clearValidate([
'main_game_id',
'cp_role_id',
'role_name',
'server_name',
'eco_user',
'is_negotiation',
'violation_type',
'remark'
])
}
})
},
close() {
this.$emit('update:show', false)
},
async submit() {
console.log(this.userInfo, 'reportForm')
if (this.reportForm.role_id === '') {
this.$message.error('请选择角色')
return
}
if (this.reportForm.violation_type === '') {
this.$message.error('请选择违规操作')
return
}
if (
this.hasEcoUserData &&
(!this.reportForm.eco_user || this.reportForm.eco_user.trim() === '')
) {
this.$message.error('请匹配角色后自动获取生态运营信息')
return
}
if (this.reportForm.remark === '') {
this.$message.error('请填写详情')
return
}
this.loading = true
const data = {
main_game_id: this.reportForm.main_game_id,
role_id: this.reportForm.role_id,
cp_role_id: this.reportForm.cp_role_id,
report_cp_role_id: this.reportForm.report_cp_role_id,
role_id_type: this.reportForm.role_id_type,
report_role_id_type: this.reportForm.report_role_id_type,
report_role_id: this.reportForm.report_role_id || 0,
violation_type: this.reportForm.violation_type,
remark: this.reportForm.remark,
eco_user: this.hasEcoUserData ? this.reportForm.eco_user || '' : '',
is_negotiation: this.hasEcoUserData
? this.reportForm.is_negotiation || 1
: 2,
user_id: this.userInfo.id,
user_name: this.userInfo.username
}
setTimeout(() => {
this.loading = false
}, 2000)
try {
const res = await reportAdd(data)
this.loading = false
if (res.status_code === 1) {
this.$message.success('提交成功')
this.close()
if (this.reportInfo && this.reportInfo.id) {
this.$emit('updateReportList')
}
}
} catch (error) {
this.loading = false
}
}
}
}
</script>
<style lang="scss" scoped>
// ::v-deep .el-drawer {
// height: 100%;
// }
.drawer-content-main {
width: 100%;
height: 100%;
overflow: auto;
}
.drawer-content {
width: 100%;
height: auto;
padding: 20px;
padding-top: 0;
}
.selectItem {
height: 50px;
}
.infoSpan {
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
max-width: 250px;
height: 50px;
p {
font-size: 12px;
max-width: 100%;
line-height: 20px;
}
span {
color: #ffa81d;
}
}
.tableImage {
width: 30px;
height: 30px;
border-radius: 30px;
margin-right: 10px;
}
.dialog-footer {
width: 100%;
height: auto;
position: absolute;
right: 0px;
bottom: 0px;
padding-right: 10px;
padding-top: 20px;
padding-bottom: 20px;
border-top: 1px solid rgba(0, 0, 0, 0.06);
justify-content: flex-end;
background: #fff;
.btn {
width: 84px;
height: 32px;
}
}
</style>
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论