提交 5e642f8d 作者: 施汉文

Merge branch 'release' into shw-feat-style

...@@ -1467,3 +1467,45 @@ export function sendEmail(data) { ...@@ -1467,3 +1467,45 @@ export function sendEmail(data) {
}) })
}) })
} }
// 获取开/合服天数
export function getServerDayApi(data) {
return new Promise((resolve, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/role/getServerDay',
params: data
}).then((res) => {
resolve(res)
}).catch((error) => {
reject(error)
})
})
}
// 项目-视频分类
export function teachingVideoCategoryListApi(data) {
return new Promise((resolve, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/teaching_video/categoryList',
params: data
}).then((res) => {
resolve(res)
}).catch((error) => {
reject(error)
})
})
}
// 视频列表
export function teachingVideoVideoListApi(data) {
return new Promise((resolve, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/teaching_video/videoList',
params: data
}).then((res) => {
resolve(res)
}).catch((error) => {
reject(error)
})
})
}
\ No newline at end of file
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#a)"><mask id="b" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="14" height="14"><path d="M14 0H0v14h14z" fill="#fff"/></mask><g mask="url(#b)" stroke="#267ef0" stroke-width=".875" stroke-linecap="round" stroke-linejoin="round"><path d="M9.333 7.525v2.45c0 2.042-.816 2.858-2.858 2.858h-2.45c-2.042 0-2.858-.816-2.858-2.858v-2.45c0-2.042.816-2.858 2.858-2.858h2.45c2.042 0 2.858.816 2.858 2.858"/><path d="M12.833 4.025v2.45c0 2.042-.816 2.858-2.858 2.858h-.642V7.525c0-2.042-.816-2.858-2.858-2.858H4.667v-.642c0-2.042.816-2.858 2.858-2.858h2.45c2.042 0 2.858.816 2.858 2.858"/></g></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h14v14H0z"/></clipPath></defs></svg>
\ No newline at end of file
import Vue from 'vue'
{/* <iconpark-icon name="icon-fuzhi"></iconpark-icon> */}
const copy = {
// 当被绑定的元素插入到DOM中时
inserted: function(el, binding) {
// 创建复制图标元素
const copyIcon = document.createElement('iconpark-icon')
// const copyIcon = document.createElement('div')
// copyIcon.setAttribute('icon-class', 'copy')
copyIcon.name='icon-fuzhi'
copyIcon.style.cursor = 'pointer'
copyIcon.style.marginLeft = '8px'
copyIcon.style.fontSize = '16px'
copyIcon.title = '点击复制'
copyIcon.innerHTML='<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#a)"><mask id="b" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="14" height="14"><path d="M14 0H0v14h14z" fill="#fff"/></mask><g mask="url(#b)" stroke="#267ef0" stroke-width=".875" stroke-linecap="round" stroke-linejoin="round"><path d="M9.333 7.525v2.45c0 2.042-.816 2.858-2.858 2.858h-2.45c-2.042 0-2.858-.816-2.858-2.858v-2.45c0-2.042.816-2.858 2.858-2.858h2.45c2.042 0 2.858.816 2.858 2.858"/><path d="M12.833 4.025v2.45c0 2.042-.816 2.858-2.858 2.858h-.642V7.525c0-2.042-.816-2.858-2.858-2.858H4.667v-.642c0-2.042.816-2.858 2.858-2.858h2.45c2.042 0 2.858.816 2.858 2.858"/></g></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h14v14H0z"/></clipPath></defs></svg>'
// 设置元素的position为relative,确保图标的absolute定位正确
if (getComputedStyle(el).position === 'static') {
el.style.position = 'relative'
}
// 添加复制图标到元素后面
el.insertBefore(copyIcon, el.nextSibling)
// 复制功能实现
copyIcon.addEventListener('click', async function(e) {
// 阻止事件冒泡
e.stopPropagation()
try {
// 获取要复制的内容
const textToCopy = binding.value || ''
if (!textToCopy) {
Vue.prototype.$message.warning('没有可复制的内容')
return
}
// 使用现代的剪贴板API
if (navigator.clipboard && window.isSecureContext) {
await navigator.clipboard.writeText(textToCopy)
} else {
// 兼容旧版浏览器
const textArea = document.createElement('textarea')
textArea.value = textToCopy
textArea.style.position = 'fixed'
textArea.style.left = '-999999px'
textArea.style.top = '-999999px'
document.body.appendChild(textArea)
textArea.focus()
textArea.select()
// 执行复制命令
const success = document.execCommand('copy')
document.body.removeChild(textArea)
if (!success) {
throw new Error('复制失败')
}
}
// 显示复制成功的提示
Vue.prototype.$message.success('复制成功')
} catch (error) {
console.error('复制失败:', error)
Vue.prototype.$message.error('复制失败,请手动复制')
}
})
// 存储图标引用,以便在组件卸载时清理
el.__copyIcon = copyIcon
},
// 当指令与元素解绑时
unbind: function(el) {
// 清理事件监听器和元素
if (el.__copyIcon) {
el.__copyIcon.removeEventListener('click', null)
el.parentNode.removeChild(el.__copyIcon)
delete el.__copyIcon
}
}
}
export default copy
\ No newline at end of file
import copy from './copy.js'
const install = function(Vue) {
Vue.directive('copy', copy)
}
if (window.Vue) {
window.copy = copy
Vue.use(install); // eslint-disable-line
}
copy.install = install
export default copy
...@@ -15,6 +15,7 @@ import '@/styles/index.scss'; ...@@ -15,6 +15,7 @@ import '@/styles/index.scss';
import moment from 'moment' import moment from 'moment'
import '@/styles/tailwind.css' import '@/styles/tailwind.css'
import VConsole from 'vconsole'; import VConsole from 'vconsole';
import copy from './directive/copy'
import uploading from '@/utils/cos-upload' import uploading from '@/utils/cos-upload'
import errorHandle from '@/utils/errorHandle' import errorHandle from '@/utils/errorHandle'
import { getParams,deepClone } from '@/utils/index' import { getParams,deepClone } from '@/utils/index'
...@@ -24,7 +25,7 @@ import loadmore from '@/directive/loadmore/index.js' // 加载更多 ...@@ -24,7 +25,7 @@ import loadmore from '@/directive/loadmore/index.js' // 加载更多
import clickagain from './directive/clickagain' import clickagain from './directive/clickagain'
import permission from '@/directive/permission/index.js' // 权限判断指令 import permission from '@/directive/permission/index.js' // 权限判断指令
import scroll from '@/directive/scroll' // 下拉加载更多指令 import scroll from '@/directive/scroll' // 下拉加载更多指令
Vue.use(globalComponent).use(permission).use(clickagain).use(loadmore).use(scroll) Vue.use(globalComponent).use(permission).use(clickagain).use(loadmore).use(scroll).use(copy)
// 导入 VConsole 清理工具 // 导入 VConsole 清理工具
import '@/utils/vconsoleCleanup' import '@/utils/vconsoleCleanup'
......
...@@ -16,6 +16,7 @@ const state = { ...@@ -16,6 +16,7 @@ const state = {
}, },
avatar:'',//客服头像 avatar:'',//客服头像
userid:Cookies.get('userid'), userid:Cookies.get('userid'),
weixin_blongs_id:localStorage.getItem('weixin_blongs_id'),//客服号项目id
corp_id:'', corp_id:'',
external_userid:'', external_userid:'',
token:'', token:'',
...@@ -39,6 +40,12 @@ const state = { ...@@ -39,6 +40,12 @@ const state = {
} }
const mutations = { const mutations = {
set_weixin_blongs_id(state,weixin_blongs_id){
state.weixin_blongs_id = weixin_blongs_id
// Cookies.set('weixin_blongs_id', weixin_blongs_id)
localStorage.setItem('weixin_blongs_id', weixin_blongs_id)
},
set_userInfo(state,userInfo){ set_userInfo(state,userInfo){
state.userInfo = userInfo state.userInfo = userInfo
}, },
......
...@@ -564,6 +564,10 @@ li { ...@@ -564,6 +564,10 @@ li {
height: 100%; height: 100%;
font-size: 300px; font-size: 300px;
} }
.el-loading-spinner{
display: flex;
justify-content: center;
}
.el-loading-spinner .circular { .el-loading-spinner .circular {
width: 60px !important; width: 60px !important;
......
<template>
<div class="h-full flex flex-col">
<el-input
placeholder="请输入内容"
prefix-icon="el-icon-search"
v-model.trim="searchText"
@input="debouncedGetVideoList"
>
</el-input>
<el-cascader
class="w-full mt-[8px]"
v-model="categoryValue"
:props="{ emitPath: false, expandTrigger: 'click' }"
:options="categoryList"
@change="debouncedGetVideoList"
></el-cascader>
<div
class="mt-[2px] space-y-[8px] flex-1 overflow-auto pb-[10px]"
v-loading="loading"
>
<div
v-for="item in videoList"
:key="item.id"
class="flex justify-between items-center py-[3px] px-[8px] bottom-[1px] border border-[#E5E7EB] rounded-[4px]"
>
<div class="text-[14px]">{{ item.video_name }}</div>
<div class="flex items-center">
<el-button
type="text"
size="small"
class="text-[12px] button-color-hover"
@click="previewVideo(item)"
>
<div class="flex items-center">
<iconpark-icon
name="xiaoxicaozuo-chakan"
class="mr-[4px] text-[14px]"
></iconpark-icon>
预览
</div>
</el-button>
<div
@click="sendVideo(item)"
class="h-[24px] ml-[8px] cursor-pointer hover:bg-[#E7F1FD] text-[12px] w-[58px] p-0 flex justify-center items-center rounded-full bg-[#F7F8FA] text-[#267EF0]"
>
<iconpark-icon
name="icon-fasonghuashu"
class="text-[14px] mr-[4px]"
></iconpark-icon>
<span> 发送</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import {
teachingVideoVideoListApi,
teachingVideoCategoryListApi,
} from "@/api/game";
import { mapMutations, mapState } from "vuex";
import { sendChatMessage } from "@/utils/index";
import { debounce } from "@/utils";
export default {
name: "InstructionalVideo",
data() {
return {
searchText: "",
categoryValue: {},
categoryList: [],
videoList: [],
debouncedGetVideoList: () => {},
loading: false,
};
},
mounted() {
this.getCategoryList();
// 初始化防抖函数,延迟300ms执行
this.debouncedGetVideoList = debounce(() => {
this.loading = true;
this.getVideoList().finally(() => {
this.loading = false;
});
}, 300);
},
computed: {
...mapState("user", ["userInfo", "weixin_blongs_id"]),
},
methods: {
...mapMutations("common", ["set_sendSkillMessage"]),
// 视频分类
async getCategoryList() {
// return;
const { data } = await teachingVideoCategoryListApi({
weixin_blongs_id: this.weixin_blongs_id,
});
this.categoryList = this.formatCategoryList(data);
},
formatCategoryList(data) {
return data.map((item) => {
return {
value: item,
label: item.main_game_name,
children: item.category.map((item) => ({
value: item,
label: item.category_name,
})),
};
});
},
// 视频列表
async getVideoList() {
if (!this.categoryValue.id) {
return;
}
const { data } = await teachingVideoVideoListApi({
weixin_blongs_id:
this.categoryValue.weixin_blongs_id || this.weixin_blongs_id,
main_game_id: this.categoryValue.main_game_id,
video_type: this.categoryValue.id,
video_name: this.searchText,
page: 1,
page_size: 200,
});
this.videoList = data.data;
},
sendVideo(item) {
try {
const link = {
title: item.video_name,
imgUrl: item.cover_url || "",
desc: "点击观看教学视频",
link: item.video_url,
};
sendChatMessage(link, "link");
} catch (error) {
console.error("发送视频链接失败:", error);
this.$message({ message: "发送视频链接失败", type: "error" });
}
},
previewVideo(item) {
window.open(item.video_url);
},
},
};
</script>
<style scoped>
.button-color-hover.el-button--text:hover {
color: #267ef0 !important;
}
.button-color-hover.el-button--text {
color: #86909c;
}
</style>
<template> <template>
<div class="detailsGiftApply columnFlex"> <div class="detailsGiftApply columnFlex">
<div class="detailsGiftApplyContent" v-scroll="requestemailGiftList" v-loading="listLoading" > <div
class="detailsGiftApplyContent"
v-scroll="requestemailGiftList"
v-loading="listLoading"
>
<div class="detailsGiftApplyTitle rowFlex spaceBetween columnCenter"> <div class="detailsGiftApplyTitle rowFlex spaceBetween columnCenter">
<!-- <p>充值礼包</p> --> <!-- <p>充值礼包</p> -->
<span></span> <span></span>
<el-button type="primary" size="small" @click="showApplyGift = true">礼包申请</el-button> <el-button type="primary" size="small" @click="showApplyGift = true"
>礼包申请</el-button
>
</div> </div>
<!-- 过滤条件 --> <!-- 过滤条件 -->
<el-form class="filterList" label-position="top" :class="{ 'collapsed-form': isCollapsed }"> <el-form
<div class="filter-header"> class="filterList"
<span class="filter-title">筛选条件</span> label-position="top"
<i :class="isCollapsed ? 'el-icon-arrow-down' : 'el-icon-arrow-up'" class="collapse-icon" :class="{ 'collapsed-form': isCollapsed }"
@click="toggleCollapse"></i> >
</div> <div class="filter-header">
<el-form-item label="主游戏"> <span class="filter-title">筛选条件</span>
<el-select v-model.trim="form.main_game_id" filterable remote clearable reserve-keyword <i
placeholder="请输入主游戏名" style="width:100%;" :remote-method="remoteMethod" :loading="loading" :class="isCollapsed ? 'el-icon-arrow-down' : 'el-icon-arrow-up'"
@change="searchInput" @focus="gameNameList = optionsList"> class="collapse-icon"
<el-option v-for="item in gameNameList" :key="item.value" :label="item.label" :value="item.value"> @click="toggleCollapse"
</el-option> ></i>
</el-select> </div>
</el-form-item> <el-form-item label="主游戏">
<el-form-item label="区服"> <el-select
<el-select v-model.trim="form.zyou_server_id" filterable remote multiple reserve-keyword style="width:100%;" v-model.trim="form.main_game_id"
placeholder="请先选择主游戏" :remote-method="remoteMethodServer" :loading="loading" @change="searchInput"> filterable
<el-option v-for="item in serverNameList" :key="item.id" :label="item.label" :value="item.value"> remote
</el-option> clearable
</el-select> reserve-keyword
</el-form-item> placeholder="请输入主游戏名"
<el-form-item label="svip权益"> style="width: 100%"
<el-select v-model.trim="form.right_type" filterable style="width:100%;" :remote-method="remoteMethod"
placeholder="请选择svip权益" @change="searchInput"> :loading="loading"
<el-option v-for="item in benefitOptions" :key="item.value" :label="item.label" :value="item.value"> @change="searchInput"
</el-option> @focus="gameNameList = optionsList"
</el-select> >
</el-form-item> <el-option
<el-form-item label="角色名称"> v-for="item in gameNameList"
<el-input v-model="form.role_name_or_cp_id" placeholder="请输入角色名称" style="width:100%;" :key="item.value"
@change="searchInput"></el-input> :label="item.label"
</el-form-item> :value="item.value"
<el-form-item label="礼包标题"> >
<el-input v-model="form.active_title" placeholder="请输入礼包名称" style="width:100%;" </el-option>
@change="searchInput"></el-input> </el-select>
</el-form-item> </el-form-item>
</el-form> <el-form-item label="区服">
<el-tabs v-model="form.gift_type" class="tabStyle" @tab-click="tabChange"> <el-select
<el-tab-pane v-for="(item, index) in giftTypeList" :key="index" :label="item.label" v-model.trim="form.zyou_server_id"
:name="item.value"></el-tab-pane> filterable
</el-tabs> remote
<!-- 订单列表 --> multiple
<div reserve-keyword
class="email-gift-main-scroll"> style="width: 100%"
<div v-if="emailGiftList.length > 0" style="height:auto;"> placeholder="请先选择主游戏"
<div v-for="(item, index) in emailGiftList" :key="index" class="orderDetails"> :remote-method="remoteMethodServer"
<div class="orderDetailsTitle"> :loading="loading"
<div class="rowFlex spaceBetween columnCenter"> @change="searchInput"
<div> >
<p class="text"><label>角色信息:</label> {{ `${item.role_name} - ${item.server_name}` }}</p> <el-option
<p class="text hidden"><label>礼包标题:</label> {{ item.active_title }}</p> v-for="item in serverNameList"
<p class="text hidden"><label>充值金额:</label> ¥{{ item.amount }}</p> :key="item.id"
<p class="text hidden"><label>充值日期:</label> {{ item.apply_recharge_date }}</p> :label="item.label"
</div> :value="item.value"
<i v-if="item.showDetails" class="el-icon-arrow-down iconStyle" @click="closePage(item, index)"></i> >
<i v-else class="el-icon-arrow-right iconStyle" @click="openPage(item, index)"></i> </el-option>
</el-select>
</el-form-item>
<el-form-item label="svip权益">
<el-select
v-model.trim="form.right_type"
filterable
style="width: 100%"
placeholder="请选择svip权益"
@change="searchInput"
>
<el-option
v-for="item in benefitOptions"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="角色名称">
<el-input
v-model="form.role_name_or_cp_id"
placeholder="请输入角色名称"
style="width: 100%"
@change="searchInput"
></el-input>
</el-form-item>
<el-form-item label="礼包标题">
<el-input
v-model="form.active_title"
placeholder="请输入礼包名称"
style="width: 100%"
@change="searchInput"
></el-input>
</el-form-item>
</el-form>
<el-tabs v-model="form.gift_type" class="tabStyle" @tab-click="tabChange">
<el-tab-pane
v-for="(item, index) in giftTypeList"
:key="`${item.active_title}-${index}`"
:label="item.label"
:name="item.value"
></el-tab-pane>
</el-tabs>
<!-- 订单列表 -->
<div class="email-gift-main-scroll">
<div v-if="emailGiftList.length > 0" style="height: auto">
<div
v-for="(item, index) in emailGiftList"
:key="index"
class="orderDetails"
>
<div class="orderDetailsTitle">
<div class="rowFlex spaceBetween columnCenter">
<div>
<p class="text">
<label>角色信息:</label>
{{ `${item.role_name} - ${item.server_name}` }}
</p>
<p class="text hidden">
<label>礼包标题:</label> {{ item.active_title }}
</p>
<p class="text hidden">
<label>充值金额:</label> ¥{{ item.amount }}
</p>
<p class="text hidden">
<label>充值日期:</label> {{ item.apply_recharge_date }}
</p>
</div> </div>
<el-collapse-transition> <i
<div v-if="item.showDetails"> v-if="item.showDetails"
<p class="text hidden"><label>svip权益:</label> {{ item.right_type_name || '-'}}</p> class="el-icon-arrow-down iconStyle"
<p v-if="item.status == '待提交'" class="text"><label>状态:</label> <span class="noSend">{{ item.status @click="closePage(item, index)"
}}</span> </p> ></i>
<p v-else-if="item.status == '已提交'" class="text"><label>状态:</label> <span class="sended">{{ <i
item.status }}</span> </p> v-else
<p v-else-if="item.status == '已驳回'" class="text"><label>状态:</label> <span class="sendFail">{{ class="el-icon-arrow-right iconStyle"
item.status }}</span> </p> @click="openPage(item, index)"
<p class="text"><label>申请时间:</label> {{ item.create_time }} </p> ></i>
<p class="text"><label>提交时间:</label> {{ item.confirm_time }} </p> </div>
<label style="margin-right:10px;margin-top:3px;" class="text"> <label>奖品信息:</label> </label> <el-collapse-transition>
<div v-for="items in item.level_attribute" :key="items.rule_id" class="columnCenter userInfoStyle" <div v-if="item.showDetails">
style="border-top: 1px solid rgb(196 205 226);margin-top: 5px;"> <p class="text hidden">
<div class="contentConfirmItem rowFlex spaceBetween" style="padding-left:0;margin-top:10px;"> <label>svip权益:</label> {{ item.right_type_name || "-" }}
<p class="title">{{ items.prize_level_name }}</p> </p>
<p v-if="items.compare_amount"> <p v-if="item.status == '待提交'" class="text">
{{ items.compare_amount ? Number(items.compare_amount) / 100 + <label>状态:</label>
(item.exchange_score_status == 1 ? '积分' : '金额') : items.compare_amount }}<span> * {{ items.apply_num <span class="noSend">{{ item.status }}</span>
}} </p>
</span></p> <p v-else-if="item.status == '已提交'" class="text">
</div> <label>状态:</label>
<!-- 固定奖 --> <span class="sended">{{ item.status }}</span>
<div v-if="items.prize_default"> </p>
<div class="contentConfirmItem"> <p v-else-if="item.status == '已驳回'" class="text">
<p class="title">固定奖 <span v-if="item.exchange_score_status == 1">{{ items.apply_num ? '*' + <label>状态:</label>
items.apply_num : '' }}</span></p> <span class="sendFail">{{ item.status }}</span>
<div v-for="(prize, prizeIndex) in items.prize_default" :key="prizeIndex" </p>
class="contentConfirmItem rowFlex "> <p class="text">
<p class="info"> {{ prize.name }}</p> <label>申请时间:</label> {{ item.create_time }}
<p class="info" style="margin-left:40px;">ID: {{ prize.prize_id }}</p> </p>
</div> <p class="text">
<label>提交时间:</label> {{ item.confirm_time }}
</p>
<label
style="margin-right: 10px; margin-top: 3px"
class="text"
>
<label>奖品信息:</label>
</label>
<div
v-for="items in item.level_attribute"
:key="items.rule_id"
class="columnCenter userInfoStyle"
style="
border-top: 1px solid rgb(196 205 226);
margin-top: 5px;
"
>
<div
class="contentConfirmItem rowFlex spaceBetween"
style="padding-left: 0; margin-top: 10px"
>
<p class="title">{{ items.prize_level_name }}</p>
<p v-if="items.compare_amount">
{{
items.compare_amount
? Number(items.compare_amount) / 100 +
(item.exchange_score_status == 1
? "积分"
: "金额")
: items.compare_amount
}}<span> * {{ items.apply_num }} </span>
</p>
</div>
<!-- 固定奖 -->
<div v-if="items.prize_default">
<div class="contentConfirmItem">
<p class="title">
固定奖
<span v-if="item.exchange_score_status == 1">{{
items.apply_num ? "*" + items.apply_num : ""
}}</span>
</p>
<div
v-for="(prize, prizeIndex) in items.prize_default"
:key="prizeIndex"
class="contentConfirmItem rowFlex"
>
<p class="info">{{ prize.name }}</p>
<p class="info" style="margin-left: 40px">
ID: {{ prize.prize_id }}
</p>
</div> </div>
</div> </div>
</div>
<!-- 自选奖 --> <!-- 自选奖 -->
<div v-if="items.prize_auto" class="contentConfirmItem"> <div v-if="items.prize_auto" class="contentConfirmItem">
<p class="title">自选奖 ({{ items.prize_auto.length }}{{ items.prize_auto_num }})</p> <p class="title">
<div v-for="(prize, prizeIndex) in items.prize_auto" :key="prizeIndex" 自选奖 ({{ items.prize_auto.length }}{{
class="contentConfirmItem "> items.prize_auto_num
<div v-for="(auto, autoIndex) in prize.group" :key="autoIndex"> }})
<div v-if="prize.apply_num > 0" class="rowFlex spaceBetween"> </p>
<span>{{ auto.name }}</span> <div
<span> ID:{{ auto.prize_id }}</span> v-for="(prize, prizeIndex) in items.prize_auto"
<div>*{{ prize.apply_num }}</div> :key="prizeIndex"
</div> class="contentConfirmItem"
>
<div
v-for="(auto, autoIndex) in prize.group"
:key="autoIndex"
>
<div
v-if="prize.apply_num > 0"
class="rowFlex spaceBetween"
>
<span>{{ auto.name }}</span>
<span> ID:{{ auto.prize_id }}</span>
<div>*{{ prize.apply_num }}</div>
</div> </div>
</div> </div>
</div> </div>
<!-- 返利 -->
<div v-if="item.rebate_ratio_amount" class="contentConfirmItem">
<p class="rowFlex spaceBetween"> <span>返利:¥ {{ item.rebate_ratio_amount }}</span> <span>1:{{
items.rebate_ratio_rate }}</span> </p>
</div>
</div> </div>
<div v-if="item.prize && item.prize.length > 0"> <!-- 返利 -->
<div v-for="(prize, prizeIndex) in item.prize" :key="prizeIndex" <div
class="contentConfirmItem rowFlex "> v-if="item.rebate_ratio_amount"
<p class="info"> {{ prize.name }}</p> class="contentConfirmItem"
<p class="info" style="margin-left:40px;">ID: {{ prize.prize_id }}</p> >
</div> <p class="rowFlex spaceBetween">
<span>返利:¥ {{ item.rebate_ratio_amount }}</span>
<span>1:{{ items.rebate_ratio_rate }}</span>
</p>
</div> </div>
</div> </div>
</el-collapse-transition> <div v-if="item.prize && item.prize.length > 0">
</div> <div
v-for="(prize, prizeIndex) in item.prize"
:key="prizeIndex"
class="contentConfirmItem rowFlex"
>
<p class="info">{{ prize.name }}</p>
<p class="info" style="margin-left: 40px">
ID: {{ prize.prize_id }}
</p>
</div>
</div>
</div>
</el-collapse-transition>
</div> </div>
</div> </div>
<div v-else-if="!listLoading && emailGiftList.length == 0" class="noContent rowFlex allCenter"> </div>
<noContent /> <div
</div> v-else-if="!listLoading && emailGiftList.length == 0"
class="noContent rowFlex allCenter"
>
<noContent />
</div> </div>
</div> </div>
</div>
<!-- 申请礼包 --> <!-- 申请礼包 -->
<applyGift v-if="showApplyGift" :show.sync="showApplyGift" title="礼包申请" @requestData="requestData" /> <applyGift
v-if="showApplyGift"
:show.sync="showApplyGift"
title="礼包申请"
@requestData="requestData"
/>
</div> </div>
</template> </template>
<script> <script>
import { emailGiftList, memberView, completionOrder, selectSearch } from '@/api/game' import {
import { mapMutations, mapActions, mapState } from 'vuex' emailGiftList,
import { removeDp, debounce } from '@/utils/index' memberView,
completionOrder,
selectSearch,
} from "@/api/game";
import { mapMutations, mapActions, mapState } from "vuex";
import { debounce } from "@/utils/index";
// import { roleList, memberView, zyouBind, selectSearch } from '@/api/game' // import { roleList, memberView, zyouBind, selectSearch } from '@/api/game'
import applyGift from './applyGift.vue' import applyGift from "./applyGift.vue";
import selectDate from '@/components/selectDate.vue' import selectDate from "@/components/selectDate.vue";
export default { export default {
name: 'emailGift', name: "emailGift",
components: { components: {
selectDate, selectDate,
applyGift applyGift,
}, },
data() { data() {
return { return {
isloadMore: true, isloadMore: true,
showApplyGift: false, showApplyGift: false,
collapseValue: ['1'], collapseValue: ["1"],
emailGiftList: [], emailGiftList: [],
optionsList: [], optionsList: [],
gameNameList: [], gameNameList: [],
...@@ -168,188 +329,219 @@ export default { ...@@ -168,188 +329,219 @@ export default {
serverNameList: [], serverNameList: [],
giftTypeList: [], giftTypeList: [],
form: { form: {
main_game_id: '', main_game_id: "",
zyou_server_id: [], zyou_server_id: [],
role_name_or_cp_id: '', role_name_or_cp_id: "",
member_id: '', member_id: "",
active_title: '', active_title: "",
gift_type: '', gift_type: "",
right_type: '', right_type: "",
}, },
benefitOptions: [], benefitOptions: [],
inputValue: '', inputValue: "",
pageInfo: { pageInfo: {
page: 0, page: 0,
page_size: 20, page_size: 20,
total: 0 total: 0,
}, },
isCollapsed: false isCollapsed: false,
} };
}, },
computed: { computed: {
...mapState('game', ['accountSelect']), ...mapState("game", ["accountSelect"]),
}, },
watch: { watch: {
accountSelect(newVal, oldVal) { accountSelect(newVal, oldVal) {
if (newVal && newVal !== '') { if (newVal && newVal !== "") {
this.pageInfo = { this.pageInfo = {
page: 0, page: 0,
page_size: 20, page_size: 20,
total: 0 total: 0,
} };
this.emailGiftList = [] this.emailGiftList = [];
this.isloadMore = true this.isloadMore = true;
this.requestemailGiftList() this.requestemailGiftList();
} }
} },
}, },
mounted() { mounted() {
this.requestGameList() this.requestGameList();
this.requestGiftType() this.requestGiftType();
this.getBenefitOptions() this.getBenefitOptions();
}, },
methods: { methods: {
// 重新拉去数据 // 重新拉去数据
requestData() { requestData() {
this.emailGiftList = [] this.emailGiftList = [];
this.isloadMore = true this.isloadMore = true;
this.requestemailGiftList() this.requestemailGiftList();
}, },
tabChange: debounce(function () { tabChange: debounce(function () {
this.pageInfo.page = 0 this.pageInfo.page = 0;
this.emailGiftList = [] this.emailGiftList = [];
this.isloadMore = true this.isloadMore = true;
this.requestemailGiftList() this.requestemailGiftList();
}, 1000), }, 1000),
async requestGiftType() { async requestGiftType() {
const data = { const data = {
field_name: 'gift_type', field_name: "gift_type",
table_name: 'role_gift_bag', table_name: "role_gift_bag",
type: 'dictionaries' type: "dictionaries",
} };
const res = await selectSearch(data) const res = await selectSearch(data);
if (res.status_code === 1) { if (res.status_code === 1) {
res.data.data.map(item => { res.data.data.map((item) => {
item.value = item.value.toString() item.value = item.value.toString();
}) });
this.giftTypeList = res.data.data this.giftTypeList = res.data.data;
this.giftTypeList.unshift({ this.giftTypeList.unshift({
value: '', value: "",
label: '全部' label: "全部",
}) });
} }
}, },
requestGameList() { requestGameList() {
const data = { const data = {
type: 'mainGameList', type: "mainGameList",
value: '', value: "",
weixin_blong_id: '' weixin_blong_id: "",
} };
selectSearch(data).then(res => { selectSearch(data).then((res) => {
this.loading = false this.loading = false;
if (res.status_code == 1) { if (res.status_code == 1) {
this.gameNameList = this.optionsList = res.data.data this.gameNameList = this.optionsList = res.data.data;
} }
}) });
}, },
closePage(item, index) { closePage(item, index) {
this.$set(this.emailGiftList[index], 'showDetails', false) this.$set(this.emailGiftList[index], "showDetails", false);
}, },
openPage(item, index) { openPage(item, index) {
this.$set(this.emailGiftList[index], 'showDetails', true) this.$set(this.emailGiftList[index], "showDetails", true);
}, },
remoteMethodServer(query) { remoteMethodServer(query) {
if (query !== '') { if (query !== "") {
this.loading = true this.loading = true;
const data = { const data = {
type: 'server_info', type: "server_info",
value: query, value: query,
main_game_ids: this.form.main_game_id main_game_ids: this.form.main_game_id,
} };
selectSearch(data).then(res => { selectSearch(data).then((res) => {
this.loading = false this.loading = false;
if (res.status_code == 1) { if (res.status_code == 1) {
this.serverNameList = res.data.data this.serverNameList = res.data.data;
} }
}) });
} }
}, },
remoteMethod(query) { remoteMethod(query) {
if (query !== '') { if (query !== "") {
this.gameNameList = this.optionsList.filter(item => { this.gameNameList = this.optionsList.filter((item) => {
return item.label.toLowerCase() return item.label.toLowerCase().indexOf(query.toLowerCase()) > -1;
.indexOf(query.toLowerCase()) > -1 });
})
} else { } else {
this.gameNameList = [] this.gameNameList = [];
} }
}, },
searchInput(value) { searchInput(value) {
console.log(value) console.log(value);
this.pageInfo = { this.pageInfo = {
page: 0, page: 0,
page_size: 20, page_size: 20,
total: 0 total: 0,
} };
this.isloadMore = true this.isloadMore = true;
this.emailGiftList = [] this.emailGiftList = [];
this.requestemailGiftList() this.requestemailGiftList();
}, },
async getBenefitOptions() { async getBenefitOptions() {
try { try {
const data = { const data = {
type: 'svip_right', type: "svip_right",
} };
const res = await selectSearch(data) const res = await selectSearch(data);
if (res.status_code === 1 && res.data && res.data.data && res.data.data.length > 0) { if (
const showList = ['转生石福利','月核心玩家礼包','超R生日福利礼包','超R行会专属礼包'] res.status_code === 1 &&
this.benefitOptions = res.data.data.filter((item, index) => { res.data &&
return showList.includes(item.label) res.data.data &&
}).map(item => ({ res.data.data.length > 0
) {
const showList = [
"转生石福利",
"月核心玩家礼包",
"超R生日福利礼包",
"超R行会专属礼包",
];
this.benefitOptions = res.data.data
.filter((item, index) => {
return showList.includes(item.label);
})
.map((item) => ({
...item, ...item,
value: item.value || item.id // 确保每个选项都有value属性,优先使用value,不存在则使用id value: item.value || item.id, // 确保每个选项都有value属性,优先使用value,不存在则使用id
})); }));
console.log(this.benefitOptions) console.log(this.benefitOptions);
} }
} catch (error) { } catch (error) {
console.error('获取权益选项失败:', error) console.error("获取权益选项失败:", error);
} }
}, },
requestemailGiftList() { requestemailGiftList() {
this.listLoading = true this.listLoading = true;
if (this.accountSelect == '') { if (this.accountSelect == "") {
this.$message.warning('暂无关联的账号,请先去关联账号!') this.$message.warning("暂无关联的账号,请先去关联账号!");
return false return false;
} }
if (!this.isloadMore) { if (!this.isloadMore) {
console.log('没有更多数据了') console.log("没有更多数据了");
this.listLoading = false this.listLoading = false;
return false return false;
} }
this.pageInfo.page += 1 this.pageInfo.page += 1;
this.form.member_id = this.accountSelect this.form.member_id = this.accountSelect;
emailGiftList({ ...this.form, ...this.pageInfo }).then(res => { emailGiftList({ ...this.form, ...this.pageInfo }).then(
this.listLoading = false (res) => {
if (res.data.data && res.data.data.length < 20) { this.listLoading = false;
this.isloadMore = false if (res.data.data && res.data.data.length < 20) {
this.isloadMore = false;
}
res.data.data.map((item, index) => {
item.showDetails = false;
});
this.emailGiftList = this.removeDp(
this.emailGiftList,
res.data.data,
"id"
);
},
(err) => {
this.listLoading = false;
} }
res.data.data.map((item, index) => { );
item.showDetails = false
})
this.emailGiftList = removeDp(res.data.data, this.emailGiftList, 'id')
}, err => {
this.listLoading = false
})
}, },
toggleCollapse() { toggleCollapse() {
this.isCollapsed = !this.isCollapsed this.isCollapsed = !this.isCollapsed;
} },
} removeDp(arr1, arr2, id) {
} console.log(arr1, arr2, "合并");
let arr;
arr2 ? (arr = arr1.concat(arr2)) : (arr = arr1);
const obj = {};
console.log(arr, "合并前");
const newArray = arr.reduce((pre, cur) => {
if (!obj[cur[id]]) {
obj[cur[id]] = true;
pre.push(cur);
}
return pre;
}, []);
return newArray;
},
},
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.detailsGiftApply { .detailsGiftApply {
...@@ -382,14 +574,14 @@ export default { ...@@ -382,14 +574,14 @@ export default {
padding: 0 10px; padding: 0 10px;
overflow: auto; overflow: auto;
overflow-x: hidden; overflow-x: hidden;
::v-deep .el-tabs__content{ ::v-deep .el-tabs__content {
height: auto; height: auto;
} }
::v-deep .el-tabs{ ::v-deep .el-tabs {
height: auto; height: auto;
} }
.noContent{ .noContent {
margin-top: 50px; margin-top: 50px;
} }
...@@ -439,7 +631,7 @@ export default { ...@@ -439,7 +631,7 @@ export default {
display: inline-block; display: inline-block;
width: 8px; width: 8px;
height: 8px; height: 8px;
background: #409EFF; background: #409eff;
border-radius: 5px; border-radius: 5px;
} }
...@@ -472,7 +664,7 @@ export default { ...@@ -472,7 +664,7 @@ export default {
p { p {
font-size: 22px; font-size: 22px;
color: #409EFF; color: #409eff;
} }
} }
} }
...@@ -480,7 +672,7 @@ export default { ...@@ -480,7 +672,7 @@ export default {
.filterList { .filterList {
margin-bottom: 10px; margin-bottom: 10px;
position: relative; position: relative;
border: 1px solid #EBEEF5; border: 1px solid #ebeef5;
border-radius: 4px; border-radius: 4px;
padding: 10px; padding: 10px;
transition: all 0.3s; transition: all 0.3s;
...@@ -491,7 +683,7 @@ export default { ...@@ -491,7 +683,7 @@ export default {
align-items: center; align-items: center;
margin-bottom: 10px; margin-bottom: 10px;
padding-bottom: 5px; padding-bottom: 5px;
border-bottom: 1px dashed #EBEEF5; border-bottom: 1px dashed #ebeef5;
} }
.filter-title { .filter-title {
...@@ -502,7 +694,7 @@ export default { ...@@ -502,7 +694,7 @@ export default {
.collapse-icon { .collapse-icon {
cursor: pointer; cursor: pointer;
color: #409EFF; color: #409eff;
font-size: 16px; font-size: 16px;
padding: 5px; padding: 5px;
transition: all 0.3s; transition: all 0.3s;
...@@ -585,7 +777,7 @@ export default { ...@@ -585,7 +777,7 @@ export default {
.iconStyle { .iconStyle {
font-size: 18px; font-size: 18px;
cursor: pointer; cursor: pointer;
color: #409EFF; color: #409eff;
} }
.money { .money {
...@@ -621,7 +813,7 @@ export default { ...@@ -621,7 +813,7 @@ export default {
background: #e1fff0; background: #e1fff0;
font-family: PingFangSC-Regular, PingFang SC; font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400; font-weight: 400;
color: #409EFF; color: #409eff;
border: none; border: none;
} }
} }
...@@ -661,7 +853,6 @@ export default { ...@@ -661,7 +853,6 @@ export default {
} }
} }
} }
} }
.tabStyle { .tabStyle {
...@@ -743,4 +934,4 @@ export default { ...@@ -743,4 +934,4 @@ export default {
transform: translateX(-50%); transform: translateX(-50%);
bottom: 80px; bottom: 80px;
} }
</style> </style>
\ No newline at end of file
...@@ -308,6 +308,9 @@ export default { ...@@ -308,6 +308,9 @@ export default {
showConfirmLayer: false showConfirmLayer: false
} }
}, },
computed: {
...mapState('user', ['cser_name'])
},
watch: { watch: {
show(newVal, oldVal) { show(newVal, oldVal) {
if (newVal) { if (newVal) {
...@@ -432,7 +435,6 @@ export default { ...@@ -432,7 +435,6 @@ export default {
} }
} catch (error) { } catch (error) {
console.error('处理礼包等级属性时出错:', error) console.error('处理礼包等级属性时出错:', error)
// 出错时保持level_attribute为空数组
} }
// 构建规则数据 // 构建规则数据
const rule = [{ level_attribute, id: activeInfo.id }] const rule = [{ level_attribute, id: activeInfo.id }]
...@@ -440,7 +442,7 @@ export default { ...@@ -440,7 +442,7 @@ export default {
role_id:role_id, role_id:role_id,
recharge_date:'', recharge_date:'',
remark: this.remark, remark: this.remark,
create_user: this.name, create_user: this.cser_name,
task_id: this.task_id || null, task_id: this.task_id || null,
right_type: this.activeInfo.right_type || '', right_type: this.activeInfo.right_type || '',
select_type:this.activeInfo.gift_type==7?2:'', select_type:this.activeInfo.gift_type==7?2:'',
......
...@@ -3,51 +3,114 @@ ...@@ -3,51 +3,114 @@
<div v-if="!disabled && bindGameUserList.length > 0" class="btnRelease"> <div v-if="!disabled && bindGameUserList.length > 0" class="btnRelease">
<div class="btntab"> <div class="btntab">
<el-radio-group size="small" v-model="activeName" class="radio-group"> <el-radio-group size="small" v-model="activeName" class="radio-group">
<el-radio-button border label="1" @click.native="activeName = '1'">转端</el-radio-button> <el-radio-button border label="1" @click.native="activeName = '1'"
<el-radio-button border label="3" @click.native="recallTabChange">召回</el-radio-button> >转端</el-radio-button
<el-radio-button border label="2" @click.native="requestRegGameList">转游</el-radio-button> >
<el-radio-button border label="3" @click.native="recallTabChange"
>召回</el-radio-button
>
<el-radio-button border label="2" @click.native="requestRegGameList"
>转游</el-radio-button
>
</el-radio-group> </el-radio-group>
</div> </div>
<div v-loading="contentLoading" class="gameList"> <div v-loading="contentLoading" class="gameList">
<!-- 转端 --> <!-- 转端 -->
<el-collapse v-if="activeName == '1' && conversionGameList.length > 0" :disabled="disabled" <el-collapse
@change="conversionChangeOld"> v-if="activeName == '1' && conversionGameList.length > 0"
<el-collapse-item class="mb-[10px]" v-for="(item, index) in conversionGameList" :key="index" :disabled="disabled"
:name="item.game_type"> @change="conversionChangeOld"
>
<el-collapse-item
class="mb-[10px]"
v-for="(item, index) in conversionGameList"
:key="index"
:name="item.game_type"
>
<template slot="title"> <template slot="title">
<div class="title-with-icon"> <div class="title-with-icon">
<svg-icon v-if="item.game_type == 1" icon-class="wxgame" class="game-icon" /> <svg-icon
<svg-icon v-else-if="item.game_type == 5" icon-class="douyin" class="game-icon" /> v-if="item.game_type == 1"
<svg-icon v-else-if="item.game_type == 3" icon-class="Android" class="game-icon" /> icon-class="wxgame"
<svg-icon v-else-if="item.game_type == 4" icon-class="IOS" class="game-icon" /> class="game-icon"
<svg-icon v-else-if="item.game_type == 2" icon-class="H5" class="game-icon" /> />
<svg-icon
v-else-if="item.game_type == 5"
icon-class="douyin"
class="game-icon"
/>
<svg-icon
v-else-if="item.game_type == 3"
icon-class="Android"
class="game-icon"
/>
<svg-icon
v-else-if="item.game_type == 4"
icon-class="IOS"
class="game-icon"
/>
<svg-icon
v-else-if="item.game_type == 2"
icon-class="H5"
class="game-icon"
/>
{{ item.game_text }} {{ item.game_text }}
</div> </div>
</template> </template>
<div v-if="item.children && item.children.length > 0"> <div v-if="item.children && item.children.length > 0">
<div v-for="(items, indexs) in item.children" :key="indexs" <div
class="gameListItem rowFlex columnCenter spaceBetween"> v-for="(items, indexs) in item.children"
<p>{{ items.game_name + '/' + items.game_id }}</p> :key="indexs"
class="gameListItem rowFlex columnCenter spaceBetween"
>
<p>{{ items.game_name + "/" + items.game_id }}</p>
<el-popover placement="top" width="160" trigger="hover"> <el-popover placement="top" width="160" trigger="hover">
<div> <div>
<p class="sendLink" @click="sendLink(items, item.game_type)"> <p
class="sendLink"
@click="sendLink(items, item.game_type)"
>
仅发送链接 仅发送链接
</p> </p>
<p class="sendLink" @click="sendPassword(items, item.game_type)"> <p
class="sendLink"
@click="sendPassword(items, item.game_type)"
>
仅发送账号密码 仅发送账号密码
</p> </p>
<p class="sendLink" @click="sendMessage(items, item.game_type)"> <p
class="sendLink"
@click="sendMessage(items, item.game_type)"
>
发送链接和账号密码 发送链接和账号密码
</p> </p>
<p class="sendLink" @click="sendDownLoadPage(items, item.game_type, index)"> <p
class="sendLink"
@click="sendDownLoadPage(items, item.game_type, index)"
>
发送落地页 发送落地页
</p> </p>
<p
class="sendLink"
v-if="[3, 4].includes(item.game_type)"
@click="sendDownLoadQrCode(items, item.game_type, index)"
>
下载二维码
</p>
</div> </div>
<el-button slot="reference" size="mini" :disabled="accountSelect == ''">发送</el-button> <el-button
slot="reference"
size="mini"
:disabled="accountSelect == ''"
>发送</el-button
>
</el-popover> </el-popover>
</div> </div>
</div> </div>
<div v-else-if="gameLoding" class="channelLoading rowFlex allCenter"> <div
v-else-if="gameLoding"
class="channelLoading rowFlex allCenter"
>
<i class="el-icon-loading"></i> <i class="el-icon-loading"></i>
<el-button type="text">加载中</el-button> <el-button type="text">加载中</el-button>
</div> </div>
...@@ -55,31 +118,75 @@ ...@@ -55,31 +118,75 @@
</el-collapse-item> </el-collapse-item>
</el-collapse> </el-collapse>
<!-- 召回 --> <!-- 召回 -->
<div v-else-if="activeName == '3' && recallGameList.length > 0" class="collapseContent"> <div
v-else-if="activeName == '3' && recallGameList.length > 0"
class="collapseContent"
>
<!-- v-if="chatUser.task_type && chatUser.task_type == 7"--> <!-- v-if="chatUser.task_type && chatUser.task_type == 7"-->
<el-button v-if='false' type="primary" style="margin-left:50px;" :loading="sendLoading" <el-button
@click="sendTaskChannel">根据任务一键发送链接</el-button> v-if="false"
type="primary"
style="margin-left: 50px"
:loading="sendLoading"
@click="sendTaskChannel"
>根据任务一键发送链接</el-button
>
<el-collapse :disabled="disabled" @change="recallChange"> <el-collapse :disabled="disabled" @change="recallChange">
<el-collapse-item v-for="(item, index) in recallGameList" :key="index" :name="item.game_type"> <el-collapse-item
v-for="(item, index) in recallGameList"
:key="index"
:name="item.game_type"
>
<template slot="title"> <template slot="title">
<div class="title-with-icon"> <div class="title-with-icon">
<svg-icon v-if="item.game_type == 1" icon-class="wxgame" class="game-icon" /> <svg-icon
<svg-icon v-else-if="item.game_type == 5" icon-class="douyin" class="game-icon" /> v-if="item.game_type == 1"
<svg-icon v-else-if="item.game_type == 3" icon-class="Android" class="game-icon" /> icon-class="wxgame"
<svg-icon v-else-if="item.game_type == 4" icon-class="IOS" class="game-icon" /> class="game-icon"
<svg-icon v-else-if="item.game_type == 2" icon-class="H5" class="game-icon" /> />
<svg-icon
v-else-if="item.game_type == 5"
icon-class="douyin"
class="game-icon"
/>
<svg-icon
v-else-if="item.game_type == 3"
icon-class="Android"
class="game-icon"
/>
<svg-icon
v-else-if="item.game_type == 4"
icon-class="IOS"
class="game-icon"
/>
<svg-icon
v-else-if="item.game_type == 2"
icon-class="H5"
class="game-icon"
/>
{{ item.game_text }} {{ item.game_text }}
</div> </div>
</template> </template>
<div v-if="item.children && item.children.length > 0"> <div v-if="item.children && item.children.length > 0">
<div v-for="(items, indexs) in item.children" :key="indexs" <div
class="gameListItem rowFlex columnCenter spaceBetween"> v-for="(items, indexs) in item.children"
<p>{{ items.game_name + '/' + items.game_id }}</p> :key="indexs"
<el-button slot="reference" size="mini" :disabled="accountSelect == ''" class="gameListItem rowFlex columnCenter spaceBetween"
@click="sendChannel(items)">发送</el-button> >
<p>{{ items.game_name + "/" + items.game_id }}</p>
<el-button
slot="reference"
size="mini"
:disabled="accountSelect == ''"
@click="sendChannel(items)"
>发送</el-button
>
</div> </div>
</div> </div>
<div v-else-if="gameLoding" class="channelLoading rowFlex allCenter"> <div
v-else-if="gameLoding"
class="channelLoading rowFlex allCenter"
>
<i class="el-icon-loading"></i> <i class="el-icon-loading"></i>
<el-button type="text">加载中</el-button> <el-button type="text">加载中</el-button>
</div> </div>
...@@ -89,7 +196,12 @@ ...@@ -89,7 +196,12 @@
</el-collapse> </el-collapse>
<div class="createChannel rowFlex allCenter"> <div class="createChannel rowFlex allCenter">
<span class="label">找不到对应游戏的链接点此</span> <span class="label">找不到对应游戏的链接点此</span>
<el-button type="text" size="medium" @click="showCreateChannel = true">新建渠道链接</el-button> <el-button
type="text"
size="medium"
@click="showCreateChannel = true"
>新建渠道链接</el-button
>
</div> </div>
</div> </div>
<!-- <!--
...@@ -100,21 +212,53 @@ ...@@ -100,21 +212,53 @@
--> -->
<div v-else-if="activeName == '2'"> <div v-else-if="activeName == '2'">
<el-collapse :disabled="disabled"> <el-collapse :disabled="disabled">
<el-input v-model="filterGameText" placeholder="请输入游戏名 按回车搜索" style="margin-top: 10px" <el-input
@keydown.enter.native="changeGameText" @blur="changeGameText"> v-model="filterGameText"
placeholder="请输入游戏名 按回车搜索"
style="margin-top: 10px"
@keydown.enter.native="changeGameText"
@blur="changeGameText"
>
<i slot="prefix" class="el-input__icon el-icon-search"></i> <i slot="prefix" class="el-input__icon el-icon-search"></i>
</el-input> </el-input>
<el-collapse-item v-for="(item, index) in regGameList" :key="index" :name="item.label"> <el-collapse-item
v-for="(item, index) in regGameList"
:key="index"
:name="item.label"
>
<template slot="title"> <template slot="title">
<div class="title-with-icon"> <div class="title-with-icon">
<svg-icon v-if="item.label.includes('微信')" icon-class="wxgame" class="game-icon" />
<svg-icon v-else-if="item.label.includes('抖音')" icon-class="douyin" class="game-icon" />
<svg-icon v-else-if="item.label.includes('安卓')" icon-class="Android" class="game-icon" />
<svg-icon <svg-icon
v-else-if="item.label.includes('IOS') || item.label.includes('iOS') || item.label.includes('ios')" v-if="item.label.includes('微信')"
icon-class="IOS" class="game-icon" /> icon-class="wxgame"
<svg-icon v-else-if="item.label.includes('H5') || item.label.includes('h5')" icon-class="H5" class="game-icon"
class="game-icon" /> />
<svg-icon
v-else-if="item.label.includes('抖音')"
icon-class="douyin"
class="game-icon"
/>
<svg-icon
v-else-if="item.label.includes('安卓')"
icon-class="Android"
class="game-icon"
/>
<svg-icon
v-else-if="
item.label.includes('IOS') ||
item.label.includes('iOS') ||
item.label.includes('ios')
"
icon-class="IOS"
class="game-icon"
/>
<svg-icon
v-else-if="
item.label.includes('H5') || item.label.includes('h5')
"
icon-class="H5"
class="game-icon"
/>
{{ item.label }} {{ item.label }}
</div> </div>
</template> </template>
...@@ -127,39 +271,64 @@ ...@@ -127,39 +271,64 @@
H5游戏 item.game_type == 2 icon 是 H5.svg H5游戏 item.game_type == 2 icon 是 H5.svg
--> -->
<div v-if="regGameList.length > 0"> <div v-if="regGameList.length > 0">
<div v-for="(items, indexs) in item.children" :key="indexs" <div
class="gameListItem rowFlex columnCenter spaceBetween"> v-for="(items, indexs) in item.children"
:key="indexs"
class="gameListItem rowFlex columnCenter spaceBetween"
>
<p>{{ items.label + "/" + items.id }}</p> <p>{{ items.label + "/" + items.id }}</p>
<!--game_type: 1 微信小游戏 2 H5 游戏 3 安卓游戏 4 IOS 游戏 5 抖音小游戏 --> <!--game_type: 1 微信小游戏 2 H5 游戏 3 安卓游戏 4 IOS 游戏 5 抖音小游戏 -->
<!-- 微信小游戏 安卓游戏 IOS游戏 处理逻辑 --> <!-- 微信小游戏 安卓游戏 IOS游戏 处理逻辑 -->
<el-popover v-if="items.game_type == 1 || items.game_type == 3 || items.game_type == 4" <el-popover
placement="top" trigger="click"> v-if="
items.game_type == 1 ||
items.game_type == 3 ||
items.game_type == 4
"
placement="top"
trigger="click"
>
<p class="sendLink" @click="sendChannelGame(items, item)"> <p class="sendLink" @click="sendChannelGame(items, item)">
发送链接/渠道二维码 发送链接/渠道二维码
</p> </p>
<p class="sendLink" @click="handleGameType(items, item, item.game_type, index)"> <p
class="sendLink"
@click="
handleGameType(items, item, item.game_type, index)
"
>
发送落地页 发送落地页
</p> </p>
<div v-if="items.game_type == 1"> <div v-if="items.game_type == 1">
<!-- 发送 H5 安卓分身包 --> <!-- 发送 H5 安卓分身包 -->
<p <p
class="sendLink" class="sendLink"
@click="sendH5CloneGame(items,'android')" @click="sendH5CloneGame(items, 'android')"
> >
发送H5-安卓分身包 发送H5-安卓分身包
</p> </p>
<!-- 发送 H5 IOS 分身包 --> <!-- 发送 H5 IOS 分身包 -->
<p <p
class="sendLink" class="sendLink"
@click="sendH5CloneGame(items,'ios')" @click="sendH5CloneGame(items, 'ios')"
> >
发送H5-IOS分身包 发送H5-IOS分身包
</p> </p>
</div> </div>
<el-button slot="reference" size="mini" :disabled="accountSelect == ''">发送</el-button> <el-button
slot="reference"
size="mini"
:disabled="accountSelect == ''"
>发送</el-button
>
</el-popover> </el-popover>
<el-button v-else size="mini" :disabled="accountSelect == ''" <el-button
@click="noH5AndroidIOSGame(items, item)">发送</el-button> v-else
size="mini"
:disabled="accountSelect == ''"
@click="noH5AndroidIOSGame(items, item)"
>发送</el-button
>
</div> </div>
</div> </div>
<!-- <div <!-- <div
...@@ -170,12 +339,16 @@ ...@@ -170,12 +339,16 @@
<el-button type="text">加载中</el-button> <el-button type="text">加载中</el-button>
</div> --> </div> -->
<div v-else class="rowFlex allCenter">暂无游戏</div> <div v-else class="rowFlex allCenter">暂无游戏</div>
</el-collapse-item> </el-collapse-item>
</el-collapse> </el-collapse>
<div class="createChannel rowFlex allCenter"> <div class="createChannel rowFlex allCenter">
<span class="label">找不到对应游戏的链接点此</span> <span class="label">找不到对应游戏的链接点此</span>
<el-button type="text" size="medium" @click="showCreateChannel = true">新建渠道链接</el-button> <el-button
type="text"
size="medium"
@click="showCreateChannel = true"
>新建渠道链接</el-button
>
</div> </div>
</div> </div>
</div> </div>
...@@ -184,23 +357,62 @@ ...@@ -184,23 +357,62 @@
<p>暂未绑定关联账号,请先去绑定账号</p> <p>暂未绑定关联账号,请先去绑定账号</p>
</div> </div>
<!-- 新建渠道链接 --> <!-- 新建渠道链接 -->
<createChannel v-if="showCreateChannel" :type="activeName" :show="showCreateChannel" :game-user-info="gameUserInfo" <createChannel
@close="showCreateChannel = false" /> v-if="showCreateChannel"
<sendPage v-if="showSendPage" :show.sync="showSendPage" :game-list="conversionGameList" @confirm="startSendPage" /> :type="activeName"
:show="showCreateChannel"
:game-user-info="gameUserInfo"
@close="showCreateChannel = false"
/>
<sendPage
v-if="showSendPage"
:show.sync="showSendPage"
:game-list="conversionGameList"
@confirm="startSendPage"
/>
<!-- 小游戏转游判断 --> <!-- 小游戏转游判断 -->
<SendTransWxGame v-if="showWxGameDrawer" :show.sync="showWxGameDrawer" :game-list="selectedWxGameList" <SendTransWxGame
:chat-user-info="chatUserInfo" @close="SendTransWxGameClose" @confirm="handleWxGameConfirm" /> v-if="showWxGameDrawer"
<SendTransAppGame v-if="showAppGameDrawer" :show.sync="showAppGameDrawer" :game-list="selectedAppGameList" :show.sync="showWxGameDrawer"
:chat-user-info="chatUserInfo" @close="SendTransAppGameClose" @confirm="handleAppGameConfirm" /> :game-list="selectedWxGameList"
:chat-user-info="chatUserInfo"
@close="SendTransWxGameClose"
@confirm="handleWxGameConfirm"
/>
<SendTransAppGame
v-if="showAppGameDrawer"
:show.sync="showAppGameDrawer"
:game-list="selectedAppGameList"
:chat-user-info="chatUserInfo"
@close="SendTransAppGameClose"
@confirm="handleAppGameConfirm"
/>
<!-- 选择发送渠道 --> <!-- 选择发送渠道 -->
<selectChannel v-if="showLayer" :show.sync="showLayer" :chat-user="chatUserInfo" <selectChannel
:channel-info-list="channelInfoList" /> v-if="showLayer"
:show.sync="showLayer"
:chat-user="chatUserInfo"
:channel-info-list="channelInfoList"
/>
<!-- 如果选择发送的渠道链接只有一个 直接发送 --> <!-- 如果选择发送的渠道链接只有一个 直接发送 -->
<sendSelectChannel :show.sync="showSendChannel" :chat-user="chatUserInfo" :channel-info-list="channelInfoList" /> <sendSelectChannel
:show.sync="showSendChannel"
:chat-user="chatUserInfo"
:channel-info-list="channelInfoList"
/>
<!-- 二维码生成组件 (隐藏) -->
<div v-show="false" class="qrcode-container">
<qrcode-vue
ref="qrcode"
:value="qrCodeValue"
:size="qrCodeSize"
level="H"
></qrcode-vue>
</div>
</div> </div>
</template> </template>
<script> <script>
import { mapState, mapMutations, mapActions } from 'vuex' import { mapState, mapMutations, mapActions } from "vuex";
import { import {
memberExtensionGameList, memberExtensionGameList,
passwardEncryption, passwardEncryption,
...@@ -213,21 +425,29 @@ import { ...@@ -213,21 +425,29 @@ import {
getLandingPageMemberLink, getLandingPageMemberLink,
getClonePackageLink, getClonePackageLink,
getLandingPageConfig, getLandingPageConfig,
getMemberTransStatus getMemberTransStatus,
} from '@/api/game' } from "@/api/game";
import { getRecentSendLog, markTransScene, getZqCserGroup, getZqCserWxBelong, getMediaId, send_log_add } from '@/api/works' import {
import { companyviewConfig } from '@/api/user' getRecentSendLog,
import { throttle, throttleStart } from '@/utils/index' markTransScene,
import createChannel from './sendGame/createChannel' getZqCserGroup,
import sendPage from './sendGame/SendTransPage.vue' getZqCserWxBelong,
import SendTransWxGame from './sendGame/SendTransWxGame.vue' getMediaId,
import SendTransAppGame from './sendGame/SendTransAppGame.vue' send_log_add,
import selectChannel from './sendGame/selectChannel.vue' } from "@/api/works";
import sendSelectChannel from './sendGame/sendSelectChannel.vue' import { companyviewConfig } from "@/api/user";
import gameLogMixin from '@/mixins/gameLogMixin' import { throttle, throttleStart } from "@/utils/index";
import { sendChatMessage } from '@/utils/index' import createChannel from "./sendGame/createChannel";
import sendPage from "./sendGame/SendTransPage.vue";
import SendTransWxGame from "./sendGame/SendTransWxGame.vue";
import SendTransAppGame from "./sendGame/SendTransAppGame.vue";
import selectChannel from "./sendGame/selectChannel.vue";
import sendSelectChannel from "./sendGame/sendSelectChannel.vue";
import gameLogMixin from "@/mixins/gameLogMixin";
import { sendChatMessage } from "@/utils/index";
import QrcodeVue from "qrcode.vue";
export default { export default {
name: 'sendGame', name: "sendGame",
mixins: [gameLogMixin], mixins: [gameLogMixin],
components: { components: {
createChannel, createChannel,
...@@ -235,7 +455,8 @@ export default { ...@@ -235,7 +455,8 @@ export default {
SendTransWxGame, SendTransWxGame,
SendTransAppGame, SendTransAppGame,
selectChannel, selectChannel,
sendSelectChannel sendSelectChannel,
QrcodeVue,
}, },
data() { data() {
return { return {
...@@ -250,15 +471,15 @@ export default { ...@@ -250,15 +471,15 @@ export default {
weixin_blongs_id: [], weixin_blongs_id: [],
regGameList: [], regGameList: [],
allRegGameList: [], allRegGameList: [],
filterGameText: '', filterGameText: "",
channelselectList: [], channelselectList: [],
webForm: { webForm: {
channel_id: '' channel_id: "",
}, },
sendLoading: false, sendLoading: false,
belongList: [], // 项目列表 belongList: [], // 项目列表
activeName: '1', // 转端 1 转游 2 召回 3 activeName: "1", // 转端 1 转游 2 召回 3
sendType: '', // 1 进发送链接 2 仅发送账号密码 3 发送链接和账号密码 sendType: "", // 1 进发送链接 2 仅发送账号密码 3 发送链接和账号密码
showCreateChannel: false, showCreateChannel: false,
showImageComposer: false, showImageComposer: false,
showWxGameDrawer: false, showWxGameDrawer: false,
...@@ -270,206 +491,227 @@ export default { ...@@ -270,206 +491,227 @@ export default {
showLayer: false, showLayer: false,
showSendChannel: false, showSendChannel: false,
channelInfoList: {}, channelInfoList: {},
transMemberStatus: true transMemberStatus: true,
} qrCodeValue: "", // 二维码内容
qrCodeSize: 200, // 二维码大小
};
}, },
mounted() { mounted() {
this.initDisable() this.initDisable();
this.sendGameInfo() this.sendGameInfo();
}, },
computed: { computed: {
...mapState('game', ['accountSelect', 'bindGameUserList', 'chatUserInfo', 'gameUserInfo', 'send_game_log']), ...mapState("game", [
...mapState('user', ['userInfo', 'corp_id']) "accountSelect",
"bindGameUserList",
"chatUserInfo",
"gameUserInfo",
"send_game_log",
]),
...mapState("user", ["userInfo", "corp_id"]),
}, },
// props: [ 'chatUserInfo', 'chatUser'], // props: [ 'chatUserInfo', 'chatUser'],
watch: { watch: {
accountSelect(newVal, oldVal) { accountSelect(newVal, oldVal) {
// 切换 w 账号的时候清空 conversionGameList 数据 // 切换 w 账号的时候清空 conversionGameList 数据
this.conversionGameList = [] this.conversionGameList = [];
this.getMemberTransStatus() this.getMemberTransStatus();
if (newVal && newVal !== '' && this.bindGameUserList.length > 0) { if (newVal && newVal !== "" && this.bindGameUserList.length > 0) {
this.disabled = false this.disabled = false;
} else { } else {
this.disabled = true this.disabled = true;
} }
}, },
activeName(newVal, oldVal) { activeName(newVal, oldVal) {
if (newVal) { if (newVal) {
} }
} },
}, },
methods: { methods: {
...mapMutations('game', ['set_send_game_log']), ...mapMutations("game", ["set_send_game_log"]),
initDisable() { initDisable() {
// 切换 w 账号的时候清空 conversionGameList 数据 // 切换 w 账号的时候清空 conversionGameList 数据
this.conversionGameList = [] this.conversionGameList = [];
this.getMemberTransStatus() this.getMemberTransStatus();
if (this.accountSelect && this.accountSelect !== '' && this.bindGameUserList.length > 0) { if (
this.disabled = false this.accountSelect &&
this.accountSelect !== "" &&
this.bindGameUserList.length > 0
) {
this.disabled = false;
} else { } else {
this.disabled = true this.disabled = true;
} }
}, },
channelInfo(info) { channelInfo(info) {
this.channelInfoList = info this.channelInfoList = info;
// 只有 1 个渠道的时候 直接发送不出现弹窗 // 只有 1 个渠道的时候 直接发送不出现弹窗
if (info.channelList.length === 1) { if (info.channelList.length === 1) {
this.showSendChannel = true this.showSendChannel = true;
} else { } else {
this.showLayer = true this.showLayer = true;
} }
}, },
async sendH5CloneGame(items, type) { async sendH5CloneGame(items, type) {
const res = await getClonePackageLink({ mini_game_id: items.id }) const res = await getClonePackageLink({ mini_game_id: items.id });
if (res.status_code == 1 ) { if (res.status_code == 1) {
if(type == 'android' && !res?.data?.data?.android_download_url){ if (type == "android" && !res?.data?.data?.android_download_url) {
this.$message.warning('安卓分身包链接不存在,请联系掌游配置') this.$message.warning("安卓分身包链接不存在,请联系掌游配置");
return return;
}else if(type == 'ios' && !res?.data?.data?.ios_download_url){ } else if (type == "ios" && !res?.data?.data?.ios_download_url) {
this.$message.warning('IOS分身包链接不存在,请联系掌游配置') this.$message.warning("IOS分身包链接不存在,请联系掌游配置");
return return;
} }
let srt = '' let srt = "";
if(type == 'android'){ if (type == "android") {
srt = '安卓分身包链接: '+res.data.data.android_download_url srt = "安卓分身包链接: " + res.data.data.android_download_url;
}else{ } else {
srt = 'IOS分身包链接: '+res.data.data.ios_download_url srt = "IOS分身包链接: " + res.data.data.ios_download_url;
} }
sendChatMessage(srt,'text') sendChatMessage(srt, "text");
}else{ } else {
this.$message.warning(res.msg) this.$message.warning(res.msg);
} }
}, },
requestConfig() { requestConfig() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
companyviewConfig({ corp_id: this.corp_id }).then((res) => { companyviewConfig({ corp_id: this.corp_id }).then((res) => {
this.weixin_blongs_id = res.data.weixin_blongs_id this.weixin_blongs_id = res.data.weixin_blongs_id;
resolve() resolve();
}) });
}) });
}, },
// 请求当前 W 账号是否符合转端条件 如果不符合 提示 当前w账号不满足转端要求,请联系组长处理 // 请求当前 W 账号是否符合转端条件 如果不符合 提示 当前w账号不满足转端要求,请联系组长处理
async getMemberTransStatus() { async getMemberTransStatus() {
if (this.accountSelect && this.accountSelect !== '') { if (this.accountSelect && this.accountSelect !== "") {
const res = await getMemberTransStatus({ member_id: this.accountSelect }) const res = await getMemberTransStatus({
member_id: this.accountSelect,
});
if (res.status_code == 1) { if (res.status_code == 1) {
this.transMemberStatus = res.data.data.allow_trans || false this.transMemberStatus = res.data.data.allow_trans || false;
} }
} else { } else {
this.transMemberStatus = false this.transMemberStatus = false;
} }
}, },
recallTabChange() { recallTabChange() {
this.activeName = '3' this.activeName = "3";
this.sendGameRecallList() this.sendGameRecallList();
}, },
async requestGameSendLog() { async requestGameSendLog() {
this.filterGameText = '' this.filterGameText = "";
const res = await getRecentSendLog() const res = await getRecentSendLog();
if (res.status_code == 1) { if (res.status_code == 1) {
if (res.status_code == 1 && res.data.length > 0) { if (res.status_code == 1 && res.data.length > 0) {
res.data.map((item) => { res.data.map((item) => {
item.label = item.game_name item.label = item.game_name;
item.id = item.game_id item.id = item.game_id;
}) });
} }
// 检查是否已经存在"最近发送"项 // 检查是否已经存在"最近发送"项
const recentSendIndex = this.regGameList.findIndex(item => item.label === '最近发送') const recentSendIndex = this.regGameList.findIndex(
(item) => item.label === "最近发送"
);
if (recentSendIndex !== -1) { if (recentSendIndex !== -1) {
// 如果已存在,更新它 // 如果已存在,更新它
this.$set(this.regGameList[recentSendIndex], 'children', res.data) this.$set(this.regGameList[recentSendIndex], "children", res.data);
} else { } else {
// 如果不存在,添加它 // 如果不存在,添加它
this.regGameList.unshift({ this.regGameList.unshift({
label: '最近发送', label: "最近发送",
children: res.data children: res.data,
}) });
} }
} }
}, },
async sendGameInfo() { async sendGameInfo() {
this.activeName = '1' this.activeName = "1";
this.conversionGameList = [] this.conversionGameList = [];
this.recallGameList = [] this.recallGameList = [];
this.getMemberTransStatus() this.getMemberTransStatus();
await this.requestConfig() await this.requestConfig();
this.sendGameList() this.sendGameList();
}, },
requestRegGameList() { requestRegGameList() {
this.activeName = '2' this.activeName = "2";
if (this.gameUserInfo.main_game_id || this.gameUserInfo.main_game_id == 0) { if (
this.contentLoading = true this.gameUserInfo.main_game_id ||
this.gameUserInfo.main_game_id == 0
) {
this.contentLoading = true;
const data = { const data = {
type: 'gameListWithType', type: "gameListWithType",
value: '', value: "",
use_type: 2, use_type: 2,
game_id: this.gameUserInfo.main_game_id, game_id: this.gameUserInfo.main_game_id,
use_user_id: this.userInfo.id, use_user_id: this.userInfo.id,
weixin_blongs_id: this.weixin_blongs_id weixin_blongs_id: this.weixin_blongs_id,
} };
selectSearch(data).then((res) => { selectSearch(data).then((res) => {
this.contentLoading = false this.contentLoading = false;
if (res.status_code == 1) { if (res.status_code == 1) {
// 暂时隐藏快手小游戏 // 暂时隐藏快手小游戏
const ksGameIndex = res.data.data.findIndex(item => item.label === '快手小游戏') const ksGameIndex = res.data.data.findIndex(
(item) => item.label === "快手小游戏"
);
if (ksGameIndex !== -1) { if (ksGameIndex !== -1) {
res.data.data.splice(ksGameIndex, 1) res.data.data.splice(ksGameIndex, 1);
} }
this.regGameList = res.data.data this.regGameList = res.data.data;
this.allRegGameList = this.regGameList this.allRegGameList = this.regGameList;
} }
this.requestGameSendLog() this.requestGameSendLog();
setTimeout(() => { setTimeout(() => {
this.contentLoading = false this.contentLoading = false;
}, 2000) }, 2000);
}) });
} else { } else {
} }
}, },
onConfirm() { }, onConfirm() {},
// 召回发送渠道 // 召回发送渠道
sendChannel(items, type) { sendChannel(items, type) {
items.type = 3 items.type = 3;
type ? this.sendType = type : '' type ? (this.sendType = type) : "";
this.channelList(items) this.channelList(items);
}, },
// 转游发送渠道 // 转游发送渠道
sendChannelGame(items, item, type) { sendChannelGame(items, item, type) {
console.log(items, 'items', item) console.log(items, "items", item);
type ? this.sendType = type : '' type ? (this.sendType = type) : "";
const gameInfo = this.$clone(items) const gameInfo = this.$clone(items);
gameInfo.type = 2 gameInfo.type = 2;
this.channelList(gameInfo) this.channelList(gameInfo);
}, },
changeGameText() { changeGameText() {
console.log(this.filterGameText) console.log(this.filterGameText);
if (this.filterGameText.trim() === '') { if (this.filterGameText.trim() === "") {
this.regGameList = this.allRegGameList this.regGameList = this.allRegGameList;
} else { } else {
const list = JSON.parse(JSON.stringify(this.allRegGameList)) const list = JSON.parse(JSON.stringify(this.allRegGameList));
list.map((item, index) => { list.map((item, index) => {
item.children = item.children.filter( item.children = item.children.filter(
(items) => items.label.indexOf(this.filterGameText) !== -1 (items) => items.label.indexOf(this.filterGameText) !== -1
) );
}) });
this.regGameList = list this.regGameList = list;
} }
}, },
// 获取渠道列表 // 获取渠道列表
channelList(items) { channelList(items) {
console.log(items, 'items') console.log(items, "items");
const data = { const data = {
game_id: items.game_id || items.id, game_id: items.game_id || items.id,
page_size: 200, page_size: 200,
page: 1, page: 1,
zq_user_id: this.userInfo.id, zq_user_id: this.userInfo.id,
weixin_blongs_id: items.weixin_blongs_id ? [items.weixin_blongs_id] : this.weixin_blongs_id, weixin_blongs_id: items.weixin_blongs_id
request_system: 'company_wx', ? [items.weixin_blongs_id]
: this.weixin_blongs_id,
request_system: "company_wx",
member_id: this.accountSelect, member_id: this.accountSelect,
use_type: this.activeName use_type: this.activeName,
} };
channelList(data).then((res) => { channelList(data).then((res) => {
if (res?.data?.data?.data?.length > 0) { if (res?.data?.data?.data?.length > 0) {
// 只有一个的时候自动发送渠道链接 // 只有一个的时候自动发送渠道链接
...@@ -477,89 +719,94 @@ export default { ...@@ -477,89 +719,94 @@ export default {
game_id: items.game_id || items.id, game_id: items.game_id || items.id,
use_type: this.activeName, use_type: this.activeName,
sendType: this.sendType, sendType: this.sendType,
channelList: res.data.data.data channelList: res.data.data.data,
} };
// 只有 1 个渠道的时候 直接发送不出现弹窗 // 只有 1 个渠道的时候 直接发送不出现弹窗
if (this.channelInfoList.channelList.length === 1) { if (this.channelInfoList.channelList.length === 1) {
this.showSendChannel = true this.showSendChannel = true;
} else { } else {
this.showLayer = true this.showLayer = true;
} }
this.sendGameLog(items) this.sendGameLog(items);
} else { } else {
this.$message.warning('请到掌游创建运营渠道') this.$message.warning("请到掌游创建运营渠道");
} }
}) });
}, },
showSendGameLayer() { showSendGameLayer() {
this.showLayer = true this.showLayer = true;
}, },
async sendGameList() { async sendGameList() {
if (this.conversionGameList.length == 0) { if (this.conversionGameList.length == 0) {
this.contentLoading = true this.contentLoading = true;
// 获取召回转端的游戏列表 user_type: 1 转端 3 召回 // 获取召回转端的游戏列表 user_type: 1 转端 3 召回
const res = await getGameConfig({ use_type: 1 }) const res = await getGameConfig({ use_type: 1 });
this.contentLoading = false this.contentLoading = false;
if (res.status_code === 1 && res.data.data.length > 0) { if (res.status_code === 1 && res.data.data.length > 0) {
const ksGameIndex = res.data.data.findIndex(item => item.game_type == 6) const ksGameIndex = res.data.data.findIndex(
(item) => item.game_type == 6
);
if (ksGameIndex != -1) { if (ksGameIndex != -1) {
res.data.data.splice(ksGameIndex, 1) res.data.data.splice(ksGameIndex, 1);
this.conversionGameList = res.data.data this.conversionGameList = res.data.data;
} else { } else {
this.conversionGameList = res.data.data this.conversionGameList = res.data.data;
} }
} }
setTimeout(() => { setTimeout(() => {
this.contentLoading = false this.contentLoading = false;
}, 2000) }, 2000);
} }
}, },
async conversionChangeOld(value) { async conversionChangeOld(value) {
console.log('请求数据', this.conversionGameList) console.log("请求数据", this.conversionGameList);
if (this.isReqeustData) { if (this.isReqeustData) {
return return;
} }
try { try {
this.isReqeustData = true this.isReqeustData = true;
this.gameLoding = true this.gameLoding = true;
// 使用 Promise.all 并发请求游戏列表数据 // 使用 Promise.all 并发请求游戏列表数据
const promiseList = this.conversionGameList.map(async (item, index) => { const promiseList = this.conversionGameList.map(async (item, index) => {
// 如果已有子项数据则跳过 // 如果已有子项数据则跳过
if (this.conversionGameList[index].children?.length > 0) { if (this.conversionGameList[index].children?.length > 0) {
return return;
} }
try { try {
const params = { const params = {
member_id: this.accountSelect, member_id: this.accountSelect,
type: item.game_type type: item.game_type,
} };
const reslist = await memberExtensionGameList(params) const reslist = await memberExtensionGameList(params);
if (reslist.status_code === 1) { if (reslist.status_code === 1) {
// 使用解构赋值简化数据设置 // 使用解构赋值简化数据设置
const updates = { const updates = {
children: reslist.data?.length > 0 ? reslist.data : [], children: reslist.data?.length > 0 ? reslist.data : [],
send_trans_page_id: '', // 转端要发送的游戏 ID send_trans_page_id: "", // 转端要发送的游戏 ID
isReqeustData: true isReqeustData: true,
} };
Object.entries(updates).forEach(([key, value]) => { Object.entries(updates).forEach(([key, value]) => {
this.$set(this.conversionGameList[index], key, value) this.$set(this.conversionGameList[index], key, value);
}) });
} }
} catch (error) { } catch (error) {
console.error(`Failed to fetch game list for index ${index}:`, error) console.error(
`Failed to fetch game list for index ${index}:`,
error
);
// 设置空数组作为默认值 // 设置空数组作为默认值
this.$set(this.conversionGameList[index], 'children', []) this.$set(this.conversionGameList[index], "children", []);
} }
}) });
await Promise.all(promiseList) await Promise.all(promiseList);
this.handleConversionGameList() this.handleConversionGameList();
} catch (error) { } catch (error) {
console.error('Failed to fetch conversion game lists:', error) console.error("Failed to fetch conversion game lists:", error);
} finally { } finally {
this.gameLoding = false this.gameLoding = false;
this.isReqeustData = false this.isReqeustData = false;
} }
}, },
// 处理转端数据 之前王鑫和冯渊说要隐藏破日开天游戏 至于什么时候放开 没说 // 处理转端数据 之前王鑫和冯渊说要隐藏破日开天游戏 至于什么时候放开 没说
...@@ -567,38 +814,72 @@ export default { ...@@ -567,38 +814,72 @@ export default {
if (this.conversionGameList.length > 0) { if (this.conversionGameList.length > 0) {
this.conversionGameList.forEach((item, index) => { this.conversionGameList.forEach((item, index) => {
// 隐藏 h5的游戏 912:神权之战 784:荣耀时刻 // 隐藏 h5的游戏 912:神权之战 784:荣耀时刻
if (item.game_type === 2 && item.children && item.children.length > 0) { if (
const filteredChildren = item.children.filter(child => { item.game_type === 2 &&
return child.game_id !== '912' && child.game_id != '784' item.children &&
}) item.children.length > 0
this.$set(this.conversionGameList[index], 'children', filteredChildren) ) {
const filteredChildren = item.children.filter((child) => {
return child.game_id !== "912" && child.game_id != "784";
});
this.$set(
this.conversionGameList[index],
"children",
filteredChildren
);
} }
// 隐藏安卓游戏 安卓游戏 game_type: 3 // 隐藏安卓游戏 安卓游戏 game_type: 3
if (item.game_type === 3 && item.children && item.children.length > 0) { if (
item.game_type === 3 &&
item.children &&
item.children.length > 0
) {
// 过滤掉 game_name 为"破日开天"的数据 // 过滤掉 game_name 为"破日开天"的数据
const filteredChildren = item.children.filter(child => { const filteredChildren = item.children.filter((child) => {
return child.game_name !== '破日开天' && child.game_name !== '英雄霸业' && child.game_id !== '741' && child.game_id !== '912' return (
}) child.game_name !== "破日开天" &&
this.$set(this.conversionGameList[index], 'children', filteredChildren) child.game_name !== "英雄霸业" &&
child.game_id !== "741" &&
child.game_id !== "912"
);
});
this.$set(
this.conversionGameList[index],
"children",
filteredChildren
);
} }
// 隐藏 IOS 游戏 雄霸天下 有两个包 1 个是 691 一个是 819 王鑫说 暂时先隐藏 691 的功能 // 隐藏 IOS 游戏 雄霸天下 有两个包 1 个是 691 一个是 819 王鑫说 暂时先隐藏 691 的功能
if (item.game_type === 4 && item.children && item.children.length > 0) { if (
const filteredChildren = item.children.filter(child => { item.game_type === 4 &&
return Number(child.game_id) !== 691 item.children &&
}) item.children.length > 0
this.$set(this.conversionGameList[index], 'children', filteredChildren) ) {
const filteredChildren = item.children.filter((child) => {
return Number(child.game_id) !== 691;
});
this.$set(
this.conversionGameList[index],
"children",
filteredChildren
);
} }
}) });
console.log(this.conversionGameList, 'conversionGameList') console.log(this.conversionGameList, "conversionGameList");
} }
}, },
// 转端展开 // 转端展开
async conversionChange(value) { async conversionChange(value) {
if (value && value.length > 0) { if (value && value.length > 0) {
const gameType = value[value.length - 1] const gameType = value[value.length - 1];
const gameIndex = this.conversionGameList.findIndex(item => item.game_type === gameType) const gameIndex = this.conversionGameList.findIndex(
if (!this.conversionGameList[gameIndex].children || this.conversionGameList[gameIndex].children.length == 0) { (item) => item.game_type === gameType
this.gameLoding = true );
if (
!this.conversionGameList[gameIndex].children ||
this.conversionGameList[gameIndex].children.length == 0
) {
this.gameLoding = true;
const params = { const params = {
page_size: 200, page_size: 200,
page: 1, page: 1,
...@@ -606,50 +887,60 @@ export default { ...@@ -606,50 +887,60 @@ export default {
weixin_blongs_id: this.weixin_blongs_id, weixin_blongs_id: this.weixin_blongs_id,
use_type: 1, use_type: 1,
member_id: this.accountSelect, member_id: this.accountSelect,
type: this.conversionGameList[gameIndex].game_type type: this.conversionGameList[gameIndex].game_type,
} };
const reslist = await getTransferRecallGameList(params) const reslist = await getTransferRecallGameList(params);
this.gameLoding = false this.gameLoding = false;
if (reslist.status_code === 1 && reslist.data.data.length > 0) { if (reslist.status_code === 1 && reslist.data.data.length > 0) {
this.$set(this.conversionGameList[gameIndex], 'children', reslist.data.data) this.$set(
this.conversionGameList[gameIndex],
"children",
reslist.data.data
);
} else { } else {
this.$set(this.conversionGameList[gameIndex], 'children', []) this.$set(this.conversionGameList[gameIndex], "children", []);
} }
setTimeout(() => { setTimeout(() => {
this.gameLoding = false this.gameLoding = false;
}, 2000) }, 2000);
} else { } else {
} }
} }
}, },
// 召回的游戏列表 // 召回的游戏列表
async sendGameRecallList() { async sendGameRecallList() {
if (this.recallGameList.length == 0) { if (this.recallGameList.length == 0) {
this.contentLoading = true this.contentLoading = true;
const res = await getGameConfig({ use_type: 3 }) const res = await getGameConfig({ use_type: 3 });
this.contentLoading = false this.contentLoading = false;
if (res.status_code === 1 && res.data.data.length > 0) { if (res.status_code === 1 && res.data.data.length > 0) {
const ksGameIndex = res.data.data.findIndex(item => item.game_type == 6) const ksGameIndex = res.data.data.findIndex(
(item) => item.game_type == 6
);
if (ksGameIndex !== -1) { if (ksGameIndex !== -1) {
res.data.data.splice(ksGameIndex, 1) res.data.data.splice(ksGameIndex, 1);
this.recallGameList = res.data.data this.recallGameList = res.data.data;
} else { } else {
this.recallGameList = res.data.data this.recallGameList = res.data.data;
} }
} }
setTimeout(() => { setTimeout(() => {
this.contentLoading = false this.contentLoading = false;
}, 2000) }, 2000);
} }
}, },
// 召回展开 // 召回展开
async recallChange(value) { async recallChange(value) {
if (value && value.length > 0) { if (value && value.length > 0) {
const gameType = value[value.length - 1] const gameType = value[value.length - 1];
const gameIndex = this.recallGameList.findIndex(item => item.game_type === gameType) const gameIndex = this.recallGameList.findIndex(
if (!this.recallGameList[gameIndex].children || this.recallGameList[gameIndex].children.length == 0) { (item) => item.game_type === gameType
this.gameLoding = true );
if (
!this.recallGameList[gameIndex].children ||
this.recallGameList[gameIndex].children.length == 0
) {
this.gameLoding = true;
const params = { const params = {
// type: 2, // type: 2,
page_size: 200, page_size: 200,
...@@ -658,86 +949,90 @@ export default { ...@@ -658,86 +949,90 @@ export default {
weixin_blongs_id: this.weixin_blongs_id, weixin_blongs_id: this.weixin_blongs_id,
use_type: 3, use_type: 3,
member_id: this.accountSelect, member_id: this.accountSelect,
type: this.recallGameList[gameIndex].game_type type: this.recallGameList[gameIndex].game_type,
} };
const reslist = await getTransferRecallGameList(params) const reslist = await getTransferRecallGameList(params);
this.gameLoding = false this.gameLoding = false;
if (reslist.status_code === 1 && reslist.data.data.length > 0) { if (reslist.status_code === 1 && reslist.data.data.length > 0) {
this.$set(this.recallGameList[gameIndex], 'children', reslist.data.data) this.$set(
this.recallGameList[gameIndex],
"children",
reslist.data.data
);
} else { } else {
this.$set(this.recallGameList[gameIndex], 'children', []) this.$set(this.recallGameList[gameIndex], "children", []);
} }
setTimeout(() => { setTimeout(() => {
this.gameLoding = false this.gameLoding = false;
}, 2000) }, 2000);
} else { } else {
console.log('之前请求过了') console.log("之前请求过了");
} }
} }
}, },
showPopover() { showPopover() {
this.showCreateChannel = false this.showCreateChannel = false;
this.isReqeustData = false this.isReqeustData = false;
}, },
handlePopover() { handlePopover() {
this.showCreateChannel = false this.showCreateChannel = false;
}, },
handleAccount() { handleAccount() {
if (this.bindGameUserList.length > 0) { if (this.bindGameUserList.length > 0) {
const account = this.bindGameUserList.find( const account = this.bindGameUserList.find(
(item) => item.member_id == this.accountSelect (item) => item.member_id == this.accountSelect
) );
if (account) { if (account) {
return true return true;
} else { } else {
return false return false;
} }
} else { } else {
return false return false;
} }
}, },
sendLink: throttle(function (item, type) { sendLink: throttle(function (item, type) {
if (!this.transMemberStatus) { if (!this.transMemberStatus) {
this.$message.warning('当前w账号不满足转端要求,请联系组长处理') this.$message.warning("当前w账号不满足转端要求,请联系组长处理");
return return;
} }
console.log(item, '转端发送仅发送链接') console.log(item, "转端发送仅发送链接");
const result = this.handleAccount() const result = this.handleAccount();
if (!result) { if (!result) {
this.$message.warning('请稍后再试') this.$message.warning("请稍后再试");
return false return false;
} }
let str = '' let str = "";
if (type == 2) { if (type == 2) {
str = '网页游戏链接:' str = "网页游戏链接:";
} else if (type == 3) { } else if (type == 3) {
str = '安卓游戏链接:' str = "安卓游戏链接:";
} else if (type == 4) { } else if (type == 4) {
str = 'IOS游戏链接:' str = "IOS游戏链接:";
} else { } else {
} }
// const list = [ // const list = [
// { msgtype: 'text', text: { content: `${str}${item.url}` }} // { msgtype: 'text', text: { content: `${str}${item.url}` }}
// ] // ]
this.sendChatMessage(`${str}${item.url}`, 'text') this.sendChatMessage(`${str}${item.url}`, "text");
this.markTransScene(type) this.markTransScene(type);
item.type = 1 item.type = 1;
this.sendGameLog(item) this.sendGameLog(item);
}, 500), }, 500),
sendPassword: throttle(function (item, type) { sendPassword: throttle(function (item, type) {
if (!this.transMemberStatus) { if (!this.transMemberStatus) {
this.$message.warning('当前w账号不满足转端要求,请联系组长处理') this.$message.warning("当前w账号不满足转端要求,请联系组长处理");
return return;
} }
console.log(item, '转端仅发送账号密码') console.log(item, "转端仅发送账号密码");
const result = this.handleAccount() const result = this.handleAccount();
if (!result) { if (!result) {
this.$message.warning('请稍后再试') this.$message.warning("请稍后再试");
return false return false;
} }
const username = this.bindGameUserList.find( const username = this.bindGameUserList.find(
(items) => items.member_id == this.accountSelect (items) => items.member_id == this.accountSelect
).username ).username;
passwardEncryption({ member_id: this.accountSelect }) passwardEncryption({ member_id: this.accountSelect })
.then((res) => { .then((res) => {
// const list = [ // const list = [
...@@ -747,132 +1042,239 @@ export default { ...@@ -747,132 +1042,239 @@ export default {
// } // }
// ] // ]
// this.set_sendSkillMessage(list) // this.set_sendSkillMessage(list)
this.sendChatMessage(`账号:${username} \n密码:${res.data.password}`, 'text') this.sendChatMessage(
this.markTransScene(type) `账号:${username} \n密码:${res.data.password}`,
this.sendGameLog(item) "text"
);
this.markTransScene(type);
this.sendGameLog(item);
}) })
.catch((err) => { .catch((err) => {
const list = [ const list = [
{ msgtype: 'text', text: { content: `账号:${username}` } } { msgtype: "text", text: { content: `账号:${username}` } },
] ];
// this.set_sendSkillMessage(list) // this.set_sendSkillMessage(list)
this.sendChatMessage(`账号:${username}`, 'text') this.sendChatMessage(`账号:${username}`, "text");
item.type = 1 item.type = 1;
this.sendGameLog(item) this.sendGameLog(item);
console.log(err) console.log(err);
}) });
}, 500), }, 500),
sendMessage: throttle(function (item, type) { sendMessage: throttle(function (item, type) {
if (!this.transMemberStatus) { if (!this.transMemberStatus) {
this.$message.warning('当前w账号不满足转端要求,请联系组长处理') this.$message.warning("当前w账号不满足转端要求,请联系组长处理");
return return;
} }
const result = this.handleAccount() const result = this.handleAccount();
if (!result) { if (!result) {
this.$message.warning('请稍后再试') this.$message.warning("请稍后再试");
return false return false;
} }
let str = '' let str = "";
if (type == 2) { if (type == 2) {
str = '网页游戏链接:' str = "网页游戏链接:";
} else if (type == 3) { } else if (type == 3) {
str = '安卓游戏链接:' str = "安卓游戏链接:";
} else if (type == 4) { } else if (type == 4) {
str = 'IOS游戏链接:' str = "IOS游戏链接:";
} else { } else {
} }
const username = this.bindGameUserList.find( const username = this.bindGameUserList.find(
(items) => items.member_id == this.accountSelect (items) => items.member_id == this.accountSelect
).username ).username;
passwardEncryption({ member_id: this.accountSelect }) passwardEncryption({ member_id: this.accountSelect })
.then((res) => { .then((res) => {
const list = [ const list = [
{ {
msgtype: 'text', msgtype: "text",
text: { text: {
content: `${str}${item.url} \n账号:${username} \n密码:${res.data.password}`, content: `${str}${item.url} \n账号:${username} \n密码:${res.data.password}`,
key: res.data.key, iv: res.data.iv key: res.data.key,
} iv: res.data.iv,
} },
] },
];
// this.set_sendSkillMessage(list) // this.set_sendSkillMessage(list)
this.sendChatMessage(`${str}${item.url} \n账号:${username} \n密码:${res.data.password}`, 'text') this.sendChatMessage(
this.markTransScene(type) `${str}${item.url} \n账号:${username} \n密码:${res.data.password}`,
item.type = 1 "text"
this.sendGameLog(item) );
this.markTransScene(type);
item.type = 1;
this.sendGameLog(item);
}) })
.catch((err) => { .catch((err) => {
const list = [ const list = [
{ {
msgtype: 'text', msgtype: "text",
text: { content: `${str}${item.url} \n账号:${username}` } text: { content: `${str}${item.url} \n账号:${username}` },
} },
] ];
// this.set_sendSkillMessage(list) // this.set_sendSkillMessage(list)
this.sendChatMessage(`${str}${item.url} \n账号:${username}`, 'text') this.sendChatMessage(`${str}${item.url} \n账号:${username}`, "text");
this.sendGameLog(item) this.sendGameLog(item);
console.log(err) console.log(err);
}) });
}, 500), }, 500),
// 发送游戏落地页 // 发送游戏落地页
startSendPage(value) { startSendPage(value) {
console.log(value, 'value') console.log(value, "value");
// this.set_sendSkillMessage(list) // this.set_sendSkillMessage(list)
this.getMediaId(value, 'image') this.getMediaId(value, "image");
}, },
// 转端发送落地页面 // 转端发送落地页面
sendDownLoadPage: throttleStart(function (items, type, index) { sendDownLoadPage: throttleStart(function (items, type, index) {
if (!this.transMemberStatus) { if (!this.transMemberStatus) {
this.$message.warning('当前w账号不满足转端要求,请联系组长处理') this.$message.warning("当前w账号不满足转端要求,请联系组长处理");
return return;
}
this.$set(
this.conversionGameList[index],
"send_trans_page_id",
items.game_id
);
this.showSendPage = true;
}, 500),
// 转端发送游戏二维码
sendDownLoadQrCode: throttleStart(async function (items, type, index) {
if (!this.transMemberStatus) {
this.$message.warning("当前w账号不满足转端要求,请联系组长处理");
return;
}
const result = this.handleAccount();
if (!result) {
this.$message.warning("请稍后再试");
return false;
}
try {
this.sendLoading = true;
// 获取游戏落地页链接
let landingPageUrl = "";
if (items.url) {
landingPageUrl = items.url;
}
if (!landingPageUrl) {
this.$message.error("没有有效的链接可生成二维码");
return;
}
// 设置二维码内容
this.qrCodeValue = landingPageUrl;
// 等待DOM更新,确保二维码已生成
await this.$nextTick();
// 获取二维码canvas并转换为Blob
const canvas = this.$refs.qrcode.$el.querySelector("canvas");
if (!canvas) {
throw new Error("获取二维码canvas失败");
}
const blob = await new Promise((resolve) => {
canvas.toBlob((blob) => {
resolve(blob);
}, "image/png");
});
// 创建File对象
blob.name = "qrcode.png";
// 上传图片
const uploadConfig = {
dir: "/company_wx/service/avatars/",
};
const uploadResult = await this.uploading(blob, uploadConfig);
debugger;
if (uploadResult.data) {
// 发送上传后的链接
// const list = [
// {
// msgtype: "image",
// image: {
// picurl: uploadResult.data,
// },
// },
// ];
// const image = {
// picurl: uploadResult.data,
// };
// console.log(image, 12312321);
this.sendChatMessage(uploadResult.data, "image");
this.markTransScene(type);
items.type = 1;
this.sendGameLog(items);
this.$message.success("二维码发送成功");
} else {
throw new Error("上传失败");
}
} catch (error) {
console.error("发送二维码失败:", error);
this.$message.error("发送二维码失败,请重试");
} finally {
this.sendLoading = false;
} }
this.$set(this.conversionGameList[index], 'send_trans_page_id', items.game_id)
this.showSendPage = true
}, 500), }, 500),
// 转端标记 // 转端标记
async markTransScene(type) { async markTransScene(type) {
const data = { const data = {
external_userid: this.chatUserInfo.external_userid, external_userid: this.chatUserInfo.external_userid,
trans_scene: type trans_scene: type,
} };
const res = await markTransScene(data) const res = await markTransScene(data);
if (res.status_code == 1) { if (res.status_code == 1) {
console.log('标记转端成功') console.log("标记转端成功");
if (this.chatUserInfo.trans_scene && this.chatUserInfo.trans_scene !== '' && this.chatUserInfo.trans_scene != type) { if (
this.chatUserInfo.trans_scene = type this.chatUserInfo.trans_scene &&
this.chatUserInfo.trans_scene !== "" &&
this.chatUserInfo.trans_scene != type
) {
this.chatUserInfo.trans_scene = type;
} }
} }
}, },
getZqCserWxBelong() { getZqCserWxBelong() {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
const data = { const data = {
zq_user_id: Number(this.userInfo.id) zq_user_id: Number(this.userInfo.id),
} };
const res = await getZqCserWxBelong(data) const res = await getZqCserWxBelong(data);
if (res.status_code === 1 && res.data.data) { if (res.status_code === 1 && res.data.data) {
this.belongList = res.data.data.map(item => { this.belongList = res.data.data.map((item) => {
return { return {
value: item.value, value: item.value,
label: item.label && item.label.split('-')[0] ? item.label.split('-')[0] : '' label:
} item.label && item.label.split("-")[0]
}) ? item.label.split("-")[0]
resolve(this.belongList) : "",
};
});
resolve(this.belongList);
} else { } else {
this.$message.warning('暂无绑定项目,请先绑定项目') this.$message.warning("暂无绑定项目,请先绑定项目");
reject(null) reject(null);
} }
}) });
}, },
// 一键发送任务链接 // 一键发送任务链接
async sendTaskChannel() { async sendTaskChannel() {
let groupItem = {} let groupItem = {};
let belonsList = {} let belonsList = {};
const group = await getZqCserGroup({ zq_user_id: Number(this.userInfo.id) }) const group = await getZqCserGroup({
belonsList = await this.getZqCserWxBelong() zq_user_id: Number(this.userInfo.id),
if (group.status_code == 1 && group.data.data.length > 0 && belonsList && belonsList.length > 0) { });
groupItem = group.data.data[0] belonsList = await this.getZqCserWxBelong();
const group_name_list = groupItem.label.split('-') if (
group.status_code == 1 &&
group.data.data.length > 0 &&
belonsList &&
belonsList.length > 0
) {
groupItem = group.data.data[0];
const group_name_list = groupItem.label.split("-");
const data = { const data = {
blongs_name: belonsList[0].label, blongs_name: belonsList[0].label,
member_id: this.accountSelect, member_id: this.accountSelect,
...@@ -880,27 +1282,27 @@ export default { ...@@ -880,27 +1282,27 @@ export default {
use_user_name: this.userInfo.username, use_user_name: this.userInfo.username,
group_id: groupItem.value, group_id: groupItem.value,
group_name: group_name_list[group_name_list.length - 1], group_name: group_name_list[group_name_list.length - 1],
game_type: this.chatUserInfo.trans_scene || '' game_type: this.chatUserInfo.trans_scene || "",
} };
this.sendLoading = true this.sendLoading = true;
try { try {
setTimeout(() => { setTimeout(() => {
this.sendLoading = false this.sendLoading = false;
}, 3000) }, 3000);
const res = await quickRecallChannelLink(data) const res = await quickRecallChannelLink(data);
this.sendLoading = false this.sendLoading = false;
if (res.status_code == 1) { if (res.status_code == 1) {
this.sendGameInfoSave = res.data.data this.sendGameInfoSave = res.data.data;
this.handleSendType(res.data.data) this.handleSendType(res.data.data);
this.$message.success(res.msg) this.$message.success(res.msg);
} }
} catch (error) { } catch (error) {
this.$message.error('获取召回链接失败,请重新再试') this.$message.error("获取召回链接失败,请重新再试");
this.sendLoading = false this.sendLoading = false;
} }
} else { } else {
this.$message.error('获取分组失败,请到掌权添加分组') this.$message.error("获取分组失败,请到掌权添加分组");
return return;
} }
}, },
/** /**
...@@ -908,25 +1310,26 @@ export default { ...@@ -908,25 +1310,26 @@ export default {
* @param {Object} item 游戏信息 * @param {Object} item 游戏信息
* 1.send_log_add方法是发送游戏日志的接口 * 1.send_log_add方法是发送游戏日志的接口
* 2.set_send_game_log 是储存在vuex中的需要发送的时候调用的 信息 也就是 send_log_add 中需要的信息 * 2.set_send_game_log 是储存在vuex中的需要发送的时候调用的 信息 也就是 send_log_add 中需要的信息
* 3.每次调用 sendGameLog 方法 或者 set_send_game_log方法 的时候都需要记录 send_game_log 的信息 然后 监听 send_game_log 变量的变化 然后调用 send_log_add 方法 * 3.每次调用 sendGameLog 方法 或者 set_send_game_log方法 的时候都需要记录 send_game_log 的信息 然后 监听 send_game_log 变量的变化 然后调用 send_log_add 方法
* 4.你需要 查看 ./sendGame/*.vue 所有的 vue 文件 查看是否文件中有 sendGameLog 方法 如果有 你需要帮我自动完成日志的记录功能 需要的步骤如下 * 4.你需要 查看 ./sendGame/*.vue 所有的 vue 文件 查看是否文件中有 sendGameLog 方法 如果有 你需要帮我自动完成日志的记录功能 需要的步骤如下
* 5.你需要 在 vuex 中 引入 send_game_log 变量 然后 监听 send_game_log 如果 新值存在 那么就调用 send_log_add * 5.你需要 在 vuex 中 引入 send_game_log 变量 然后 监听 send_game_log 如果 新值存在 那么就调用 send_log_add
* 6.请你仔细查看 ./sendGame/*.vue 的所有 vue 文件 帮我 自动完成 send_log_add 的日志收集功能 如果需要特殊处理 的地方你需要仔细查看逻辑 并且 自动处理 * 6.请你仔细查看 ./sendGame/*.vue 的所有 vue 文件 帮我 自动完成 send_log_add 的日志收集功能 如果需要特殊处理 的地方你需要仔细查看逻辑 并且 自动处理
* 7.你可以封装成一个 minix 或者你有更好的处理逻辑 来完成 发送游戏日志的收集工作 * 7.你可以封装成一个 minix 或者你有更好的处理逻辑 来完成 发送游戏日志的收集工作
* 8.总结:每次调用 set_send_game_log 方法的时候 是在 vuex 中记录 需要发送的日志信息 你要监听 send_game_log 变量的变化 然后调用 send_log_add 方法 完成日志的收集工作 你需要帮我选一个最佳的方案来完成这个功能 尽量保证不出问题 * 8.总结:每次调用 set_send_game_log 方法的时候 是在 vuex 中记录 需要发送的日志信息 你要监听 send_game_log 变量的变化 然后调用 send_log_add 方法 完成日志的收集工作 你需要帮我选一个最佳的方案来完成这个功能 尽量保证不出问题
*/ */
handleSendType(data) { handleSendType(data) {
console.log(data, '获取一键发送的信息') console.log(data, "获取一键发送的信息");
// 转端发送优先逻辑 不需要了 现在发送当前会话框选中的账号对应的注册游戏 // 转端发送优先逻辑 不需要了 现在发送当前会话框选中的账号对应的注册游戏
data?.game_data?.game_type ? this.chatUserInfo.trans_scene = data.game_data.game_type : '' data?.game_data?.game_type
? (this.chatUserInfo.trans_scene = data.game_data.game_type)
: "";
if (this.chatUserInfo.trans_scene && this.chatUserInfo.trans_scene != 1) { if (this.chatUserInfo.trans_scene && this.chatUserInfo.trans_scene != 1) {
this.sendCreateChannel(data.game_data, data.game_data.game_type) this.sendCreateChannel(data.game_data, data.game_data.game_type);
} else { } else {
// 没有转端标记过,发送小程序链接 判断标题和封面是否存在 存在发小程序卡片 不存在发二维码 // 没有转端标记过,发送小程序链接 判断标题和封面是否存在 存在发小程序卡片 不存在发二维码
if (data.share_data.share_title && data.share_data.share_img) { if (data.share_data.share_title && data.share_data.share_img) {
const miniprogramInfo = const miniprogramInfo = {
{
appid: data.share_data.app_id, appid: data.share_data.app_id,
rawid: data.share_data.raw_id, rawid: data.share_data.raw_id,
channle_id: data.share_data.channel_key, channle_id: data.share_data.channel_key,
...@@ -934,182 +1337,210 @@ export default { ...@@ -934,182 +1337,210 @@ export default {
title: data.share_data.share_title, title: data.share_data.share_title,
platform: 27, platform: 27,
page: data.share_data.page, page: data.share_data.page,
imgUrl: data.share_data.share_img imgUrl: data.share_data.share_img,
} };
// this.set_sendSkillMessage(list) // this.set_sendSkillMessage(list)
this.sendChatMessage(miniprogramInfo, 'miniprogram') this.sendChatMessage(miniprogramInfo, "miniprogram");
const game_data = this.$clone(data.game_data) const game_data = this.$clone(data.game_data);
game_data.type = 3 game_data.type = 3;
console.log(game_data, 'data----------') console.log(game_data, "data----------");
this.sendGameLog(game_data) this.sendGameLog(game_data);
} else { } else {
// this.set_sendSkillMessage(list) // this.set_sendSkillMessage(list)
this.getMediaId(data.game_data.game_url, 'image') this.getMediaId(data.game_data.game_url, "image");
this.sendGameLog(data.game_data) this.sendGameLog(data.game_data);
} }
} }
this.recallChannelSeq(data) this.recallChannelSeq(data);
}, },
// 召回染色 // 召回染色
async recallChannelSeq(data) { async recallChannelSeq(data) {
const param = { const param = {
game_id: data.game_data.game_id, game_id: data.game_data.game_id,
member_id: this.accountSelect, member_id: this.accountSelect,
key: data.game_data.channel_key || data.share_data.channel_key key: data.game_data.channel_key || data.share_data.channel_key,
} };
const res = await recallChannelSeq(param) const res = await recallChannelSeq(param);
}, },
sendCreateChannel: throttle(function (item, type) { sendCreateChannel: throttle(function (item, type) {
const result = this.handleAccount() const result = this.handleAccount();
if (!result) { if (!result) {
this.$message.warning('请稍后再试') this.$message.warning("请稍后再试");
return false return false;
} }
let str = '' let str = "";
if (type == 2) { if (type == 2) {
str = '网页游戏链接:' str = "网页游戏链接:";
} else if (type == 3) { } else if (type == 3) {
str = '安卓游戏链接:' str = "安卓游戏链接:";
} else if (type == 4) { } else if (type == 4) {
str = 'IOS游戏链接:' str = "IOS游戏链接:";
} else { } else {
} }
const username = this.bindGameUserList.find( const username = this.bindGameUserList.find(
(items) => items.member_id == this.accountSelect (items) => items.member_id == this.accountSelect
).username ).username;
passwardEncryption({ member_id: this.accountSelect }) passwardEncryption({ member_id: this.accountSelect }).then((res) => {
.then((res) => { const list = [
const list = [ {
{ msgtype: "text",
msgtype: 'text', // 一键发送渠道任务相关的参数
// 一键发送渠道任务相关的参数 taskInfo: {
taskInfo: { task_id: this.chatUser.task_id,
task_id: this.chatUser.task_id, game_id: item.game_id,
game_id: item.game_id, member_id: this.accountSelect,
member_id: this.accountSelect, channel_key: item.channel_key,
channel_key: item.channel_key },
}, text: {
text: { content: `${str}${item.game_url} \n账号:${username} \n密码:${res.data.password}`,
content: `${str}${item.game_url} \n账号:${username} \n密码:${res.data.password}`, key: res.data.key,
key: res.data.key, iv: res.data.iv iv: res.data.iv,
} },
} },
] ];
// 这里需要特殊处理,因为有taskInfo参数 // 这里需要特殊处理,因为有taskInfo参数
// this.set_sendSkillMessage(list) // this.set_sendSkillMessage(list)
this.sendChatMessage(`${str}${item.game_url} \n账号:${username} \n密码:${res.data.password}`, 'text') this.sendChatMessage(
item.type = 3 `${str}${item.game_url} \n账号:${username} \n密码:${res.data.password}`,
this.sendGameLog(item) "text"
}) );
item.type = 3;
this.sendGameLog(item);
});
}, 500), }, 500),
async getLandingPageConfig(items, item) { async getLandingPageConfig(items, item) {
try { try {
const params = { const params = {
main_game_id: items.main_game_id, main_game_id: items.main_game_id,
weixin_blongs_id: items.weixin_blongs_id, weixin_blongs_id: items.weixin_blongs_id,
type: items.game_type == 1 ? 2 : items.game_type == 3 || items.game_type == 4 ? 1 : '' type:
} items.game_type == 1
const res = await getLandingPageConfig(params) ? 2
: items.game_type == 3 || items.game_type == 4
? 1
: "",
};
const res = await getLandingPageConfig(params);
if (res.status_code === 1 && res.data) { if (res.status_code === 1 && res.data) {
return { return {
data: res.data, data: res.data,
game_type: items.game_type game_type: items.game_type,
} };
} else { } else {
return null return null;
} }
} catch (error) { } catch (error) {}
}
}, },
// 处理微信小程序游戏 // 处理微信小程序游戏
handleWechatMiniGame(items, item, index) { handleWechatMiniGame(items, item, index) {
try { try {
this.selectedWxGameList = [] this.selectedWxGameList = [];
// 直接替换微信小游戏列表(单选) // 直接替换微信小游戏列表(单选)
this.selectedWxGameList = [item] this.selectedWxGameList = [item];
this.selectedWxGameList[0].send_trans_game_id = items.id this.selectedWxGameList[0].send_trans_game_id = items.id;
this.selectedWxGameList[0].send_trans_game_info = items this.selectedWxGameList[0].send_trans_game_info = items;
this.showWxGameDrawer = true this.showWxGameDrawer = true;
return true return true;
} catch (error) { } catch (error) {
console.error('处理微信小游戏失败:', error) console.error("处理微信小游戏失败:", error);
return false return false;
} }
}, },
// 过滤游戏列表的公共方法 // 过滤游戏列表的公共方法
filterGameList(sourceGame, targetList) { filterGameList(sourceGame, targetList) {
if (!sourceGame || !targetList?.length) return [] if (!sourceGame || !targetList?.length) return [];
return targetList.filter(game => return targetList.filter(
game.weixin_blongs_id === sourceGame.weixin_blongs_id && (game) =>
game.main_game_id === sourceGame.main_game_id game.weixin_blongs_id === sourceGame.weixin_blongs_id &&
) game.main_game_id === sourceGame.main_game_id
);
}, },
handleAndroidList(items, item) { handleAndroidList(items, item) {
const androidGameList = this.regGameList.find(item => item.label.includes('安卓')) const androidGameList = this.regGameList.find((item) =>
if (androidGameList && androidGameList.children && androidGameList.children.length > 0) { item.label.includes("安卓")
androidGameList.children = this.filterGameList(items, androidGameList.children) );
if (
androidGameList &&
androidGameList.children &&
androidGameList.children.length > 0
) {
androidGameList.children = this.filterGameList(
items,
androidGameList.children
);
} else { } else {
androidGameList.children = [] androidGameList.children = [];
} }
androidGameList.game_type = 3 androidGameList.game_type = 3;
if (items.game_type == 3) { if (items.game_type == 3) {
androidGameList.android_game_id = items.id androidGameList.android_game_id = items.id;
androidGameList.android_game_info = items androidGameList.android_game_info = items;
} }
return androidGameList return androidGameList;
}, },
handleIosList(items, item) { handleIosList(items, item) {
const IOSGameList = this.regGameList.find(item => item.label.includes('IOS' || 'ios')) const IOSGameList = this.regGameList.find((item) =>
IOSGameList.game_type = 4 item.label.includes("IOS" || "ios")
if (IOSGameList && IOSGameList.children && IOSGameList.children.length > 0) { );
IOSGameList.children = this.filterGameList(items, IOSGameList.children) IOSGameList.game_type = 4;
if (
IOSGameList &&
IOSGameList.children &&
IOSGameList.children.length > 0
) {
IOSGameList.children = this.filterGameList(items, IOSGameList.children);
} else { } else {
IOSGameList.children = [] IOSGameList.children = [];
} }
if (items.game_type == 4) { if (items.game_type == 4) {
IOSGameList.ios_game_id = items.id IOSGameList.ios_game_id = items.id;
IOSGameList.ios_game_info = items IOSGameList.ios_game_info = items;
} }
return IOSGameList return IOSGameList;
}, },
// 处理安卓 IOS 游戏 // 处理安卓 IOS 游戏
handleAppGameList(items, item, index) { handleAppGameList(items, item, index) {
this.showAppGameDrawer = true this.showAppGameDrawer = true;
const androidGameList = this.handleAndroidList(items, item) const androidGameList = this.handleAndroidList(items, item);
const IOSGameList = this.handleIosList(items, item) const IOSGameList = this.handleIosList(items, item);
androidGameList ? this.selectedAppGameList.push(androidGameList) : '' androidGameList ? this.selectedAppGameList.push(androidGameList) : "";
IOSGameList ? this.selectedAppGameList.push(IOSGameList) : '' IOSGameList ? this.selectedAppGameList.push(IOSGameList) : "";
console.log(this.selectedAppGameList, 'selectedAppGameList') console.log(this.selectedAppGameList, "selectedAppGameList");
}, },
// 主方法 // 主方法
async handleGameType(items, item, type, index) { async handleGameType(items, item, type, index) {
if ((items.game_type == 1 || items.game_type == 3 || items.game_type == 4) && items.main_game_id && items.weixin_blongs_id) { if (
const result = await this.getLandingPageConfig(items, item) (items.game_type == 1 ||
items.game_type == 3 ||
items.game_type == 4) &&
items.main_game_id &&
items.weixin_blongs_id
) {
const result = await this.getLandingPageConfig(items, item);
if (result && result.data?.data?.tag) { if (result && result.data?.data?.tag) {
if (items.game_type == 1) { if (items.game_type == 1) {
// 处理微信小程序游戏 // 处理微信小程序游戏
this.handleWechatMiniGame(items, item, index) this.handleWechatMiniGame(items, item, index);
} else { } else {
// 处理安卓/iOS游戏 // 处理安卓/iOS游戏
this.handleAppGameList(items, item, index) this.handleAppGameList(items, item, index);
} }
} else { } else {
this.sendChannelGame(items, item) this.sendChannelGame(items, item);
} }
} else { } else {
this.sendChannelGame(items, item) this.sendChannelGame(items, item);
} }
}, },
// 不是小游戏 安卓 IOS 游戏处理 // 不是小游戏 安卓 IOS 游戏处理
noH5AndroidIOSGame(items, item) { noH5AndroidIOSGame(items, item) {
this.sendChannelGame(items, item) this.sendChannelGame(items, item);
}, },
// 小游戏游戏确认 // 小游戏游戏确认
async handleWxGameConfirm(value) { async handleWxGameConfirm(value) {
console.log(value, 'value') console.log(value, "value");
// const list = [ // const list = [
// { // {
// msgtype: 'image', // msgtype: 'image',
...@@ -1119,17 +1550,17 @@ export default { ...@@ -1119,17 +1550,17 @@ export default {
// } // }
// ] // ]
// this.set_sendSkillMessage(list) // this.set_sendSkillMessage(list)
this.getMediaId(value, 'image') this.getMediaId(value, "image");
}, },
SendTransAppGameClose() { SendTransAppGameClose() {
this.selectedAppGameList = [] this.selectedAppGameList = [];
}, },
SendTransWxGameClose() { SendTransWxGameClose() {
this.selectedWxGameList = [] this.selectedWxGameList = [];
}, },
// 安卓或者 IOS 游戏处理 // 安卓或者 IOS 游戏处理
handleAppGameConfirm(data) { handleAppGameConfirm(data) {
this.selectedAppGameList = [] this.selectedAppGameList = [];
// const list = [ // const list = [
// { // {
// msgtype: 'text', // msgtype: 'text',
...@@ -1139,20 +1570,23 @@ export default { ...@@ -1139,20 +1570,23 @@ export default {
// } // }
// ] // ]
// this.set_sendSkillMessage(list) // this.set_sendSkillMessage(list)
this.sendChatMessage(`游戏地址:${data.landing_page_url} \n账号:${data.username} \n密码:${data.password}`, 'text') this.sendChatMessage(
`游戏地址:${data.landing_page_url} \n账号:${data.username} \n密码:${data.password}`,
"text"
);
}, },
async getMediaId(picurl) { async getMediaId(picurl) {
// 发送图片作为链接消息 // 发送图片作为链接消息
if (picurl) { if (picurl) {
this.sendChatMessage(picurl, 'image') this.sendChatMessage(picurl, "image");
} else { } else {
// 如果没有图片URL,提示用户 // 如果没有图片URL,提示用户
this.$message.error('图片链接不存在,无法发送') this.$message.error("图片链接不存在,无法发送");
} }
}, },
} },
} };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.sendGameContent { .sendGameContent {
...@@ -1181,7 +1615,7 @@ export default { ...@@ -1181,7 +1615,7 @@ export default {
} }
.channelLoading { .channelLoading {
color: #3491FA; color: #3491fa;
font-size: 16px; font-size: 16px;
text-align: center; text-align: center;
padding: 20px; padding: 20px;
...@@ -1246,8 +1680,8 @@ export default { ...@@ -1246,8 +1680,8 @@ export default {
} }
::v-deep .el-button { ::v-deep .el-button {
background: #3491FA; background: #3491fa;
border-color: #3491FA; border-color: #3491fa;
color: #fff; color: #fff;
font-size: 14px; font-size: 14px;
height: 32px; height: 32px;
...@@ -1268,8 +1702,8 @@ export default { ...@@ -1268,8 +1702,8 @@ export default {
::v-deep .el-popover__reference { ::v-deep .el-popover__reference {
.el-button { .el-button {
background: #3491FA; background: #3491fa;
border-color: #3491FA; border-color: #3491fa;
color: #fff; color: #fff;
&:hover { &:hover {
...@@ -1296,7 +1730,7 @@ export default { ...@@ -1296,7 +1730,7 @@ export default {
font-size: 14px; font-size: 14px;
&:focus { &:focus {
border-color: #3491FA; border-color: #3491fa;
} }
} }
...@@ -1317,20 +1751,20 @@ export default { ...@@ -1317,20 +1751,20 @@ export default {
/* 当转端按钮处于激活状态时保持自定义样式 */ /* 当转端按钮处于激活状态时保持自定义样式 */
::v-deep .el-radio-button.is-active { ::v-deep .el-radio-button.is-active {
.el-radio-button__inner { .el-radio-button__inner {
background: #E8F7FF; background: #e8f7ff;
border-color: #3491FA; border-color: #3491fa;
border: 1px solid #3491FA; border: 1px solid #3491fa;
color: #3491FA; color: #3491fa;
box-shadow: none; box-shadow: none;
} }
} }
/* 统一collapse样式 */ /* 统一collapse样式 */
::v-deep .el-collapse-item__header { ::v-deep .el-collapse-item__header {
background-color: #F7F8FA; background-color: #f7f8fa;
.el-collapse-item__arrow { .el-collapse-item__arrow {
color: #3491FA; color: #3491fa;
} }
} }
} }
...@@ -1345,7 +1779,7 @@ export default { ...@@ -1345,7 +1779,7 @@ export default {
} }
.sendLink:hover { .sendLink:hover {
color: #3491FA; color: #3491fa;
background-color: #f5f7fa; background-color: #f5f7fa;
} }
</style> </style>
\ No newline at end of file
...@@ -6,23 +6,69 @@ ...@@ -6,23 +6,69 @@
<p class="textInfo"> <p class="textInfo">
角色充值金额信息会有5-10分钟延迟,请以订单信息为准 角色充值金额信息会有5-10分钟延迟,请以订单信息为准
</p> </p>
<el-button type="primary" size="small" class="h-[30px]" @click.stop="appealLayer()">申诉</el-button> <el-button
type="primary"
size="small"
class="h-[30px]"
@click.stop="appealLayer()"
>申诉</el-button
>
</div> </div>
<el-collapse v-model="collapseActive" @change="handleChange"> <el-collapse v-model="collapseActive">
<div v-for="(items, indexs) in roleList" :key="indexs" class="contentItem mb-[10px]"> <div
v-for="(items, indexs) in roleList"
:key="indexs"
class="contentItem"
>
<div class="title"></div> <div class="title"></div>
<el-collapse-item :name="items.id"> <el-collapse-item :name="items.role_id">
<template slot="title"> <template slot="title">
<!-- <div class="collapseTitle rowFlex columnCenter spaceBetween"> <div
<p class="hidden"> class="grid grid-cols-7 w-[100%] leading-[24px] gap-[8px] py-[12px]"
{{ items.role_name }} - {{ items.server_name }} - {{ >
items.recharge_total ? items.recharge_total + '元' : '0元' }} <div class="col-span-3">
</p> <div
<el-button type="primary" size="mini" class="collapseTitleBtn" class="text-[#323335] text-[16px] font-medium group hover:text-[#409EFF]"
@click.stop="appealLayer(items)">申诉</el-button> >
</div> --> <span class="flex items-center"
<div class="flex w-[100%] justify-between"> >{{ items.role_name
<div class="py-[10px]"> }}<i
class="group-hover:visible invisible"
v-copy="
`${items.role_name}-${items.server_name}-${
items.recharge_total || 0
}元`
"
></i>
</span>
</div>
<div class="text-[#4E5969] text-[14px]">
<span>区服:</span><span>{{ items.server_name }}</span>
</div>
</div>
<div class="col-span-2">
<div class="text-[#4E5969] text-[14px]">充值金额</div>
<div class="text-[#4E5969] text-[16px]">
<!-- <span>{{ items.recharge_total ? items.recharge_total + '元' : '0元' }}</span> -->
<span>{{ items.recharge_total || 0 }}</span>
</div>
</div>
<div
class="col-span-2"
@click.stop="
() =>
recentActivitiesPopupInstance.instance.open(
items.role_id,
`${items.role_name}-${items.server_name}-${items.recharge_total}元`
)
"
>
<div class="text-[#4E5969] text-[14px]">近期要开</div>
<el-button type="text" class="text-[16px] font-medium">{{
getNumRoleIdList(items.role_id)
}}</el-button>
</div>
<!-- <div class="py-[10px]">
<div class="leading-[25px]"> <div class="leading-[25px]">
<span>角色名:</span><span>{{ items.role_name }}</span> <span>角色名:</span><span>{{ items.role_name }}</span>
</div> </div>
...@@ -30,129 +76,140 @@ ...@@ -30,129 +76,140 @@
<span>区服:</span><span>{{ items.server_name }}</span> <span>区服:</span><span>{{ items.server_name }}</span>
</div> </div>
<div class="leading-[25px]"> <div class="leading-[25px]">
<span>充值金额:</span><span>{{ <span>充值金额:</span><span>{{ items.recharge_total ? items.recharge_total + '元' : '0元' }}</span>
items.recharge_total
? items.recharge_total + '元'
: '0元'
}}</span>
<vip-level :role-info="items" /> <vip-level :role-info="items" />
</div> </div>
</div> </div>
<div class="flex-1 h-0 flex justify-end items-start pt-[10px]"> <div class="flex-1 h-0 flex justify-end items-start pt-[10px]">
<el-badge :value="getNumRoleIdList(items.role_id)" class="text-center leading-[0] ml-[8px]"> <el-badge :value="getNumRoleIdList(items.role_id)" class="text-center leading-[0] ml-[8px]">
<el-button type="primary" size="mini" @click.stop=" <el-button type="primary" size="mini" @click.stop="() => recentActivitiesPopupInstance.instance.open(items.role_id, `${items.role_name}-${items.server_name}-${items.recharge_total}元`)">近期要开</el-button>
() =>
recentActivitiesPopupInstance.instance.open(
items.role_id,
`${items.role_name}-${items.server_name}-${items.recharge_total}元`
)
">
近期要开</el-button>
</el-badge> </el-badge>
</div> </div> -->
</div> </div>
</template> </template>
<div class="item rowFlex columnCenter spaceBetween"> <div
class="w-full border-t-[1px] border-t-[#E5E7EB] border-dashed"
>
<!-- <div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter"> <div class="rowFlex columnCenter">
<span class="label">区服:</span> <span class="label">区服:</span>
<p class="text">{{ items.server_name }}</p> <p class="text">{{ items.server_name }}</p>
</div> </div>
</div> </div> -->
<div class="item rowFlex columnCenter spaceBetween"> <div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter"> <div class="rowFlex columnCenter">
<span class="label">合区区服:</span> <span class="label">合区区服:</span>
<p class="text">{{ items.merge_server_name }}</p> <p class="text">{{ items.merge_server_name }}</p>
</div>
</div> </div>
</div> <!-- <div class="item rowFlex columnCenter spaceBetween">
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter"> <div class="rowFlex columnCenter">
<span class="label">角色名称:</span> <span class="label">角色名称:</span>
<p class="text">{{ items.role_name }}</p> <p class="text">{{ items.role_name }}</p>
</div> </div>
</div> </div> -->
<div class="item rowFlex columnCenter spaceBetween"> <div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter"> <div class="rowFlex columnCenter">
<span class="label">等级:</span> <span class="label">等级:</span>
<p class="text">{{ items.role_level }}</p> <p class="text">{{ items.role_level }}</p>
</div>
</div> </div>
</div> <div class="item rowFlex columnCenter spaceBetween">
<div class="item rowFlex columnCenter spaceBetween"> <div class="rowFlex columnCenter">
<div class="rowFlex columnCenter"> <span class="label">战力:</span>
<span class="label">战力:</span> <p class="text">{{ items.combat_num }}</p>
<p class="text">{{ items.combat_num }}</p> </div>
</div> </div>
</div> <!-- <div class="item rowFlex columnCenter spaceBetween">
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter"> <div class="rowFlex columnCenter">
<span class="label">充值金额:</span> <span class="label">充值金额:</span>
<p class="text">{{ items.recharge_total }}</p> <p class="text">{{ items.recharge_total }}</p>
</div> </div>
</div> </div> -->
<div class="item rowFlex columnCenter spaceBetween"> <div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter"> <div class="rowFlex columnCenter">
<span class="label">转端审核:</span> <span class="label">转端审核:</span>
<p class="text">{{ items.trans_status_name || '无' }}</p> <p class="text">{{ items.trans_status_name || "无" }}</p>
</div>
</div> </div>
</div> <div class="item rowFlex columnCenter spaceBetween">
<div class="item rowFlex columnCenter spaceBetween"> <div class="rowFlex columnCenter">
<div class="rowFlex columnCenter"> <span class="label">CP角色ID:</span>
<span class="label">CP角色ID:</span> <p class="text">{{ items.cp_role_id }}</p>
<p class="text">{{ items.cp_role_id }}</p> </div>
</div> </div>
</div> <div class="item rowFlex columnCenter spaceBetween">
<div class="item rowFlex columnCenter spaceBetween"> <div class="rowFlex columnCenter">
<div class="rowFlex columnCenter"> <span class="label">最近活跃时间:</span>
<span class="label">最近活跃时间:</span> <p class="text">
<p class="text"> {{
{{ $moment(items.last_login_time * 1000).format(
$moment(items.last_login_time * 1000).format( "YYYY-MM-DD HH:mm:ss"
'YYYY-MM-DD HH:mm:ss' )
) }}
}} </p>
</p> </div>
</div> </div>
</div> <div class="item rowFlex columnCenter spaceBetween">
<div class="item rowFlex columnCenter spaceBetween"> <div class="rowFlex columnCenter">
<div class="rowFlex columnCenter"> <span class="label">创建时间:</span>
<span class="label">创建时间:</span> <p class="text">
<p class="text"> {{
{{ $moment(items.create_time * 1000).format(
$moment(items.create_time * 1000).format( "YYYY-MM-DD HH:mm:ss"
'YYYY-MM-DD HH:mm:ss' )
) }}
}} </p>
</p> </div>
</div> </div>
</div> <div class="item rowFlex columnCenter spaceBetween">
<div class="item rowFlex columnCenter spaceBetween"> <div class="rowFlex columnCenter">
<div class="rowFlex columnCenter"> <span class="label">创角天数:</span>
<span class="label">创角天数:</span> <p class="text">{{ items.create_role_day }}天</p>
<p class="text">{{ items.create_role_day }}天</p> </div>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">开/合服天数:</span>
<p class="text" v-if="items.server_day">
{{ items?.server_day }}天
</p>
</div>
</div> </div>
</div> </div>
</el-collapse-item> </el-collapse-item>
</div> </div>
</el-collapse> </el-collapse>
</div> </div>
<div v-else-if="!loading && roleList.length == 0" class="noContent rowFlex allCenter"> <div
<noContent title="暂无数据" description="当前没有任何数据,请稍后再试或联系管理员" /> v-else-if="!loading && roleList.length == 0"
class="noContent rowFlex allCenter"
>
<noContent
title="暂无数据"
description="当前没有任何数据,请稍后再试或联系管理员"
/>
</div> </div>
</div> </div>
<appeal v-if="showAppeal" :show.sync="showAppeal" :appeal-info="appealInfo" /> <appeal
v-if="showAppeal"
:show.sync="showAppeal"
:appeal-info="appealInfo"
/>
</div> </div>
</template> </template>
<script> <script>
import { mapState, mapMutations, mapActions } from 'vuex'; import { mapState, mapMutations, mapActions } from "vuex";
import { getRoleHoLo,marketingRoleGrade } from '@/api/game'; import { getRoleHoLo, marketingRoleGrade, getServerDayApi } from "@/api/game";
import noContent from '@/components/noContent.vue'; import noContent from "@/components/noContent.vue";
import appeal from './layer/appeal.vue'; import appeal from "./layer/appeal.vue";
import watchMember from '@/mixins/watchMember'; import watchMember from "@/mixins/watchMember";
import { createDetails } from '@/views/popup/RecentActivitiesPopup/index.js'; import { createDetails } from "@/views/popup/RecentActivitiesPopup/index.js";
import { createRoleRecentActivityNotPushNum } from '@/views/hooks/useGetCount.js'; import { createRoleRecentActivityNotPushNum } from "@/views/hooks/useGetCount.js";
import vipLevel from '@/views/userInfo/components/gameInfo/vipLevel.vue'; import vipLevel from "@/views/userInfo/components/gameInfo/vipLevel.vue";
export default { export default {
name: 'roleInfo', name: "roleInfo",
components: { components: {
noContent, noContent,
appeal, appeal,
...@@ -162,7 +219,7 @@ export default { ...@@ -162,7 +219,7 @@ export default {
return { return {
collapseActive: [], collapseActive: [],
roleList: [], roleList: [],
nowTime: '', nowTime: "",
loading: false, loading: false,
showAppeal: false, showAppeal: false,
appealInfo: {}, appealInfo: {},
...@@ -178,7 +235,14 @@ export default { ...@@ -178,7 +235,14 @@ export default {
}; };
}, },
computed: { computed: {
...mapState('game', ['accountSelect']), ...mapState("game", ["accountSelect"]),
},
watch: {
collapseActive(newVal, oldVal) {
if (newVal.length > 0) {
this.handleChange(newVal.filter((item) => !oldVal.includes(item)));
}
},
}, },
mixins: [watchMember], mixins: [watchMember],
mounted() { mounted() {
...@@ -208,29 +272,42 @@ export default { ...@@ -208,29 +272,42 @@ export default {
this this
); );
}, },
async handleRoleListLevel(roleList){ async handleRoleListLevel(roleList) {
try { try {
const role_id_list = roleList.map((item) => item.role_id) const role_id_list = roleList.map((item) => item.role_id);
const res = await marketingRoleGrade({role_id:role_id_list}) const res = await marketingRoleGrade({ role_id: role_id_list });
if(res.status_code == 1 && res?.data?.data?.length > 0){ if (res.status_code == 1 && res?.data?.data?.length > 0) {
const levelList = res.data.data const levelList = res.data.data;
roleList.forEach((item) => { roleList.forEach((item) => {
const levelItem = levelList.find((level) => level.role_id == item.role_id) const levelItem = levelList.find(
if(levelItem){ (level) => level.role_id == item.role_id
item.vip_level = levelItem.vip_level );
} if (levelItem) {
}) item.vip_level = levelItem.vip_level;
}
});
}
} catch (error) {
console.log(error);
} finally {
this.roleList = roleList.sort((a, b) => {
return Number(b.recharge_total) - Number(a.recharge_total);
});
} }
} catch (error) {
console.log(error)
} finally {
this.roleList = roleList.sort((a, b) => {
return Number(b.recharge_total) - Number(a.recharge_total)
})
}
}, },
handleChange() { }, async handleChange(v) {
const index = this.roleList.findIndex(
(item) => v.includes(item.role_id) && !item.server_day
);
if (index !== -1) {
const res = await getServerDayApi({
role_id: this.roleList[index].role_id,
});
this.roleList[index].server_day = res.data.data?.server_day;
this.roleList = [...this.roleList];
}
},
memberChange() { memberChange() {
this.requestRoleList(); this.requestRoleList();
}, },
...@@ -240,15 +317,15 @@ export default { ...@@ -240,15 +317,15 @@ export default {
this.showAppeal = true; this.showAppeal = true;
}, },
requestRoleList() { requestRoleList() {
if (this.accountSelect === '') { if (this.accountSelect === "") {
this.$message.warning('暂无关联的账号,请先去关联账号!'); this.$message.warning("暂无关联的账号,请先去关联账号!");
return false; return false;
} }
this.loading = true; this.loading = true;
const data = { const data = {
api_search_name: '', api_search_name: "",
member_id: this.accountSelect, member_id: this.accountSelect,
search_type: 'list', search_type: "list",
...this.pageInfo, ...this.pageInfo,
}; };
getRoleHoLo(data).then( getRoleHoLo(data).then(
...@@ -256,7 +333,7 @@ export default { ...@@ -256,7 +333,7 @@ export default {
this.loading = false; this.loading = false;
if (res.status_code == 1) { if (res.status_code == 1) {
if (res.data.data.length > 0) { if (res.data.data.length > 0) {
this.handleRoleListLevel(res.data.data) this.handleRoleListLevel(res.data.data);
} else { } else {
this.roleList = []; this.roleList = [];
} }
...@@ -396,11 +473,12 @@ export default { ...@@ -396,11 +473,12 @@ export default {
} }
::v-deep .el-collapse-item { ::v-deep .el-collapse-item {
margin-bottom: 20px; margin-bottom: 1px;
} }
::v-deep .el-collapse-item__content { ::v-deep .el-collapse-item__content {
padding-bottom: 10px; // padding-bottom: 10px;
padding: 0 0 10px 0;
} }
::v-deep .el-collapse { ::v-deep .el-collapse {
...@@ -408,13 +486,17 @@ export default { ...@@ -408,13 +486,17 @@ export default {
} }
::v-deep .el-collapse-item__header { ::v-deep .el-collapse-item__header {
flex-direction: row-reverse;
width: 100%; width: 100%;
height: auto; height: auto;
background: #f9faff; background: transparent;
color: #333333; color: #333333;
padding-left: 10px; padding-left: 10px;
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;
&:hover {
background: #f7f8fa;
}
} }
::v-deep .el-collapse .el-collapse-item__header .el-collapse-item__arrow { ::v-deep .el-collapse .el-collapse-item__header .el-collapse-item__arrow {
...@@ -428,7 +510,15 @@ export default { ...@@ -428,7 +510,15 @@ export default {
::v-deep .el-card__header, ::v-deep .el-card__header,
::v-deep .el-collapse, ::v-deep .el-collapse,
::v-deep .el-collapse-item__header { ::v-deep .el-collapse-item__header {
border: 0 !important; // border: 0 !important;
}
::v-deep .el-collapse-item__arrow {
color: #b1b3b8 !important;
margin-right: 10px !important;
}
::v-deep .el-collapse-item__wrap {
background-color: transparent !important;
border-bottom: 1px solid #ebeef5 !important;
} }
/* 已移除局部 el-collapse 样式,使用全局样式 */ /* 已移除局部 el-collapse 样式,使用全局样式 */
......
...@@ -312,14 +312,14 @@ ...@@ -312,14 +312,14 @@
taskDetails, taskDetails,
taskTrack, taskTrack,
} from '@/api/game' } from '@/api/game'
import { memberBindExternalUser } from '@/api/works' import { memberBindExternalUser,clientSessionBindTaskApi } from '@/api/works'
import layer from '@/components/dialog.vue' import layer from '@/components/dialog.vue'
import SendEmailDialog from './SendEmailDialog.vue' import SendEmailDialog from './SendEmailDialog.vue'
import applyGift from '@/views/components/giftRecord/applyGift.vue' import applyGift from '@/views/components/giftRecord/applyGift.vue'
export default { export default {
computed: { computed: {
...mapState('game', ['taskDetails']), ...mapState('game', ['taskDetails']),
...mapState('user', ['userInfo']) ...mapState('user', ['userInfo','userid'])
}, },
components: { components: {
layer, layer,
......
...@@ -188,6 +188,7 @@ export default { ...@@ -188,6 +188,7 @@ export default {
"set_cser_id", "set_cser_id",
"set_cser_name", "set_cser_name",
"set_external_userid", "set_external_userid",
"set_weixin_blongs_id",
]), ]),
async initLogin() { async initLogin() {
const urlParams = getParams(); const urlParams = getParams();
...@@ -327,6 +328,7 @@ export default { ...@@ -327,6 +328,7 @@ export default {
if (res.data.userid) { if (res.data.userid) {
this.cacheuserid(res.data.userid); this.cacheuserid(res.data.userid);
this.getUserList(res.data.userid); this.getUserList(res.data.userid);
this.set_weixin_blongs_id(res.data.weixin_blongs_id);
} else { } else {
this.$message.error("获取用户id失败"); this.$message.error("获取用户id失败");
return; return;
......
...@@ -2,87 +2,81 @@ ...@@ -2,87 +2,81 @@
<div class="details columnFlex"> <div class="details columnFlex">
<div class="content search-form"> <div class="content search-form">
<el-tabs v-model="activeName"> <el-tabs v-model="activeName">
<el-tab-pane <el-tab-pane label="个人话术" name="personal">
label="个人话术"
name="personal"
>
<skillPersonal <skillPersonal
v-if="activeName === 'personal'" v-if="activeName === 'personal'"
:active-name="activeName" :active-name="activeName"
/> />
</el-tab-pane> </el-tab-pane>
<el-tab-pane <el-tab-pane label="企业话术" name="company">
label="企业话术" <skillCompany :active-name="activeName" />
name="company"
>
<skillCompany
:active-name="activeName"
/>
</el-tab-pane> </el-tab-pane>
<el-tab-pane <el-tab-pane label="知识库" name="library">
label="知识库"
name="library"
>
<skillLibrary <skillLibrary
v-if="activeName === 'library'" v-if="activeName === 'library'"
:active-name="activeName" :active-name="activeName"
/> />
</el-tab-pane> </el-tab-pane>
<el-tab-pane <el-tab-pane label="跨主体知识库" name="robotLibrary">
label="跨主体知识库"
name="robotLibrary"
>
<crossLibrary <crossLibrary
v-if="activeName === 'robotLibrary'" v-if="activeName === 'robotLibrary'"
:active-name="activeName" :active-name="activeName"
/> />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="教学视频" name="instructionalVideo">
<InstructionalVideo
v-if="activeName === 'instructionalVideo'"
:active-name="activeName"
/>
</el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import skillCompany from './components/skill/skillCompany.vue' import skillCompany from "./components/skill/skillCompany.vue";
import skillPersonal from './components/skill/skillPersonal.vue' import skillPersonal from "./components/skill/skillPersonal.vue";
import skillLibrary from './components/skill/skillLibrary.vue' import skillLibrary from "./components/skill/skillLibrary.vue";
import crossLibrary from './components/skill/crossLibrary.vue' import crossLibrary from "./components/skill/crossLibrary.vue";
import { mapActions } from 'vuex' import InstructionalVideo from "./components/InstructionalVideo/index.vue";
import { mapActions } from "vuex";
export default { export default {
name: 'quickReply', name: "quickReply",
components: { components: {
skillCompany, skillCompany,
skillPersonal, skillPersonal,
skillLibrary, skillLibrary,
crossLibrary crossLibrary,
InstructionalVideo,
}, },
data() { data() {
return { return {
activeName: 'personal' activeName: "personal",
} };
},
created() {
}, },
created() {},
mounted() { mounted() {
this.initializeWecom() this.initializeWecom();
}, },
methods: { methods: {
...mapActions('user', ['initWecom']), ...mapActions("user", ["initWecom"]),
async initializeWecom() { async initializeWecom() {
try { try {
console.log('🚀 开始初始化企业微信 SDK') console.log("🚀 开始初始化企业微信 SDK");
const result = await this.initWecom() const result = await this.initWecom();
console.log('✅ 企业微信 SDK 初始化成功', result) console.log("✅ 企业微信 SDK 初始化成功", result);
} catch (error) { } catch (error) {
console.error('❌ 企业微信 SDK 初始化失败:', error) console.error("❌ 企业微信 SDK 初始化失败:", error);
} }
}, },
} },
} };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.details { .details {
::v-deep .el-tabs__nav-next,::v-deep .el-tabs__nav-prev{ ::v-deep .el-tabs__nav-next,
::v-deep .el-tabs__nav-prev {
line-height: 50px; line-height: 50px;
} }
width: 100%; width: 100%;
......
<!-- <!--
* @Author: maoxiya 937667504@qq.com * @Author: maoxiya 937667504@qq.com
* @Date: 2025-09-13 14:05:01 * @Date: 2025-09-13 14:05:01
* @LastEditors: maoxiya 937667504@qq.com * @LastEditors: 金多虾 937667504@qq.com
* @LastEditTime: 2025-10-31 17:01:13 * @LastEditTime: 2025-12-05 17:03:24
* @FilePath: /company_wx_frontend/src/views/works/component/gameInfo/vipLevel.vue * @FilePath: /company_wx_frontend/src/views/works/component/gameInfo/vipLevel.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
--> -->
...@@ -25,6 +25,9 @@ ...@@ -25,6 +25,9 @@
<div class="vipLevelItem rowFlex columnCenter" v-for="(item,index) in vipLevelBenefit" :key="index"> <div class="vipLevelItem rowFlex columnCenter" v-for="(item,index) in vipLevelBenefit" :key="index">
<p class="vipLevelItemRow" v-if="item.num" :style="{color: item.target ? '#333333' : '#c9cdd4'}" > <p class="vipLevelItemRow" v-if="item.num" :style="{color: item.target ? '#333333' : '#c9cdd4'}" >
<span v-if="item.name" class="label">{{item.name}} </span> <span v-if="item.name" class="label">{{item.name}} </span>
<span v-if="item.num && item.type!=8" :style="{color: item.target ? '#00bf8a' : '#c9cdd4'}" class="value">
{{item.remain_num || item.num }}/{{item.num}} {{item.unit || '次'}}
</span>
<!-- 人工权益显示使用按钮 --> <!-- 人工权益显示使用按钮 -->
<div v-if="item.monitor_type === 2" class="benefit-actions"> <div v-if="item.monitor_type === 2" class="benefit-actions">
<el-button <el-button
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论