提交 8ed1a74a 作者: 毛细亚

合并分支 '6.8' 到 'release'

6.8

查看合并请求 !17
.DS_Store .DS_Store
node_modules node_modules
/dist /dist
/company_app /company_app/
# local env files # local env files
......
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0"><meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9"/><title>企微侧边栏</title><script src="https://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"></script><script defer="defer" src="static/js/runtime.2425ceee.js"></script><script defer="defer" src="static/js/chunk-elementUI.d0bcf3c3.js"></script><script defer="defer" src="static/js/chunk-libs.c6681081.js"></script><script defer="defer" src="static/js/app.e6abe9ca.js"></script><link href="static/css/chunk-elementUI.dd5abb38.css" rel="stylesheet"><link href="static/css/app.d9cea248.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but company_app doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
\ No newline at end of file
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
"vconsole": "^3.15.1", "vconsole": "^3.15.1",
"vue": "^2.6.14", "vue": "^2.6.14",
"vue-router": "^3.5.1", "vue-router": "^3.5.1",
"autoprefixer": "^10.4.0",
"tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.2.17",
"vuex": "^3.6.2" "vuex": "^3.6.2"
}, },
"devDependencies": { "devDependencies": {
......
/*
* @Author: maoxiya 937667504@qq.com
* @Date: 2025-08-30 10:58:38
* @LastEditors: maoxiya 937667504@qq.com
* @LastEditTime: 2025-08-30 10:58:43
* @FilePath: /company_app/postcss.config.js
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
module.exports = {
plugins: [
require('tailwindcss'),
require('autoprefixer')
]
}
\ No newline at end of file
import request from '@/utils/request' import request from '@/utils/request';
import store from '@/store/index' import store from '@/store/index';
// 所属分组下拉 // 所属分组下拉
function returnApi(api){ function returnApi(api) {
return '/sidebar' + api return '/sidebar' + api;
} }
export function procedure_group(data) { export function procedure_group(data) {
return request({ return request({
url: returnApi('/procedure_group/index'), url: returnApi('/procedure_group/index'),
method: 'post', method: 'post',
data data,
}) });
} }
// 话术列表 // 话术列表
export function procedureList(data) { export function procedureList(data) {
return request({ return request({
url: returnApi('/procedure/index'), url: returnApi('/procedure/index'),
method: 'post', method: 'post',
data data,
}) });
} }
// 删除话术 // 删除话术
...@@ -25,8 +25,8 @@ export function proceduredel(data) { ...@@ -25,8 +25,8 @@ export function proceduredel(data) {
return request({ return request({
url: returnApi('/procedure/del'), url: returnApi('/procedure/del'),
method: 'post', method: 'post',
data data,
}) });
} }
// 批量移动 // 批量移动
...@@ -34,8 +34,8 @@ export function proceduremove(data) { ...@@ -34,8 +34,8 @@ export function proceduremove(data) {
return request({ return request({
url: returnApi('/procedure/move'), url: returnApi('/procedure/move'),
method: 'post', method: 'post',
data data,
}) });
} }
// 新增话术 // 新增话术
...@@ -43,8 +43,8 @@ export function procedureadd(data) { ...@@ -43,8 +43,8 @@ export function procedureadd(data) {
return request({ return request({
url: returnApi('/procedure/add'), url: returnApi('/procedure/add'),
method: 'post', method: 'post',
data data,
}) });
} }
// 分组添加/修改 // 分组添加/修改
...@@ -52,8 +52,8 @@ export function procedure_groupAdd(data) { ...@@ -52,8 +52,8 @@ export function procedure_groupAdd(data) {
return request({ return request({
url: returnApi('/procedure_group/add'), url: returnApi('/procedure_group/add'),
method: 'post', method: 'post',
data data,
}) });
} }
// 分组删除 // 分组删除
...@@ -61,8 +61,8 @@ export function procedure_groupDel(data) { ...@@ -61,8 +61,8 @@ export function procedure_groupDel(data) {
return request({ return request({
url: returnApi('/procedure_group/del'), url: returnApi('/procedure_group/del'),
method: 'post', method: 'post',
data data,
}) });
} }
// 个人话术移到企业库 // 个人话术移到企业库
...@@ -70,8 +70,8 @@ export function addCompany(data) { ...@@ -70,8 +70,8 @@ export function addCompany(data) {
return request({ return request({
url: returnApi('/procedure/addCompany'), url: returnApi('/procedure/addCompany'),
method: 'post', method: 'post',
data data,
}) });
} }
// 个人话术详情 // 个人话术详情
...@@ -79,8 +79,8 @@ export function procedureInfo(data) { ...@@ -79,8 +79,8 @@ export function procedureInfo(data) {
return request({ return request({
url: returnApi('/procedure/info'), url: returnApi('/procedure/info'),
method: 'post', method: 'post',
data data,
}) });
} }
// 个人话术排序 // 个人话术排序
...@@ -88,8 +88,8 @@ export function procedureSort(data) { ...@@ -88,8 +88,8 @@ export function procedureSort(data) {
return request({ return request({
url: returnApi('/procedure/sort'), url: returnApi('/procedure/sort'),
method: 'post', method: 'post',
data data,
}) });
} }
// 个人话术租排序 // 个人话术租排序
...@@ -97,8 +97,8 @@ export function procedureGroupSort(data) { ...@@ -97,8 +97,8 @@ export function procedureGroupSort(data) {
return request({ return request({
url: returnApi('/procedure_group/sort'), url: returnApi('/procedure_group/sort'),
method: 'post', method: 'post',
data data,
}) });
} }
// 企业话术增至个人 // 企业话术增至个人
...@@ -106,8 +106,8 @@ export function addToPersonal(data) { ...@@ -106,8 +106,8 @@ export function addToPersonal(data) {
return request({ return request({
url: returnApi('/procedure/addToPersonal'), url: returnApi('/procedure/addToPersonal'),
method: 'post', method: 'post',
data data,
}) });
} }
// 话术使用次数 // 话术使用次数
...@@ -115,8 +115,8 @@ export function skillQuote(data) { ...@@ -115,8 +115,8 @@ export function skillQuote(data) {
return request({ return request({
url: '/admin/procedure/quote', url: '/admin/procedure/quote',
method: 'post', method: 'post',
data data,
}) });
} }
/* ----------- 知识库的接口 ---------- */ /* ----------- 知识库的接口 ---------- */
...@@ -125,16 +125,16 @@ export function groupList(data) { ...@@ -125,16 +125,16 @@ export function groupList(data) {
return request({ return request({
url: returnApi('/knowledge_group/index'), url: returnApi('/knowledge_group/index'),
method: 'post', method: 'post',
data data,
}) });
} }
// 知识库分组下拉 // 知识库分组下拉
export function libraryIndex(data) { export function libraryIndex(data) {
return request({ return request({
url: returnApi('/knowledge_base/index'), url: returnApi('/knowledge_base/index'),
method: 'post', method: 'post',
data data,
}) });
} }
// 新增和编辑 // 新增和编辑
...@@ -142,8 +142,8 @@ export function groupHandle(data) { ...@@ -142,8 +142,8 @@ export function groupHandle(data) {
return request({ return request({
url: returnApi('/knowledge_group/add'), url: returnApi('/knowledge_group/add'),
method: 'post', method: 'post',
data data,
}) });
} }
// 删除分组 // 删除分组
...@@ -151,63 +151,63 @@ export function groupDel(data) { ...@@ -151,63 +151,63 @@ export function groupDel(data) {
return request({ return request({
url: returnApi('/knowledge_group/del'), url: returnApi('/knowledge_group/del'),
method: 'post', method: 'post',
data data,
}) });
} }
// 新增知识库任务 // 新增知识库任务
export function addLibraryTask(data) { export function addLibraryTask(data) {
return request({ return request({
url: returnApi('/knowledge_base/add'), url: returnApi('/knowledge_base/add'),
method: 'post', method: 'post',
data data,
}) });
} }
// 详情 // 详情
export function libraryTaskView(data) { export function libraryTaskView(data) {
return request({ return request({
url: returnApi('/knowledge_base/view'), url: returnApi('/knowledge_base/view'),
method: 'post', method: 'post',
data data,
}) });
} }
// 编辑 // 编辑
export function libraryTaskEdit(data) { export function libraryTaskEdit(data) {
return request({ return request({
url: returnApi('/knowledge_base/edit'), url: returnApi('/knowledge_base/edit'),
method: 'post', method: 'post',
data data,
}) });
} }
// 删除 // 删除
export function libraryTaskDel(data) { export function libraryTaskDel(data) {
return request({ return request({
url: returnApi('/knowledge_base/del'), url: returnApi('/knowledge_base/del'),
method: 'post', method: 'post',
data data,
}) });
} }
// 批量删除 // 批量删除
export function multipleDel(data) { export function multipleDel(data) {
return request({ return request({
url: returnApi('/knowledge_base/batchDel'), url: returnApi('/knowledge_base/batchDel'),
method: 'post', method: 'post',
data data,
}) });
} // 导入 } // 导入
export function importData(data) { export function importData(data) {
return request({ return request({
url: returnApi('/knowledge_base/importKnowledgeBase'), url: returnApi('/knowledge_base/importKnowledgeBase'),
method: 'post', method: 'post',
data data,
}) });
} }
// 知识库计数 // 知识库计数
export function logClickTime(data) { export function logClickTime(data) {
return request({ return request({
url: returnApi('/knowledge_base/logClickTime'), url: returnApi('/knowledge_base/logClickTime'),
method: 'post', method: 'post',
data data,
}) });
} }
// 问答模块 // 问答模块
...@@ -215,18 +215,17 @@ export function Aihistory(data) { ...@@ -215,18 +215,17 @@ export function Aihistory(data) {
return request({ return request({
url: returnApi('/corp_beta_question_log/history'), url: returnApi('/corp_beta_question_log/history'),
method: 'post', method: 'post',
data data,
}) });
} }
// 同步知识库 // 同步知识库
export function asyncKnowledge(data) { export function asyncKnowledge(data) {
return request({ return request({
url: returnApi('/knowledge_base/syncToCorp'), url: returnApi('/knowledge_base/syncToCorp'),
method: 'post', method: 'post',
data data,
}) });
} }
/* -------------------- 机器人知识库 ----------------------- */ /* -------------------- 机器人知识库 ----------------------- */
...@@ -235,8 +234,8 @@ export function corp_robot_knowledge_add(data) { ...@@ -235,8 +234,8 @@ export function corp_robot_knowledge_add(data) {
return request({ return request({
url: returnApi('/corp_robot_knowledge_base/add'), url: returnApi('/corp_robot_knowledge_base/add'),
method: 'post', method: 'post',
data data,
}) });
} }
// 机器人知识库列表 // 机器人知识库列表
...@@ -244,48 +243,48 @@ export function corp_robot_knowledge_list(data) { ...@@ -244,48 +243,48 @@ export function corp_robot_knowledge_list(data) {
return request({ return request({
url: returnApi('/corp_robot_knowledge_base/index'), url: returnApi('/corp_robot_knowledge_base/index'),
method: 'post', method: 'post',
data data,
}) });
} }
// 机器人知识库编辑 // 机器人知识库编辑
export function corp_robot_knowledge_edit(data) { export function corp_robot_knowledge_edit(data) {
return request({ return request({
url: returnApi('/corp_robot_knowledge_base/edit'), url: returnApi('/corp_robot_knowledge_base/edit'),
method: 'post', method: 'post',
data data,
}) });
} }
// 机器人知识库详情 // 机器人知识库详情
export function corp_robot_knowledge_view(data) { export function corp_robot_knowledge_view(data) {
return request({ return request({
url: returnApi('/corp_robot_knowledge_base/view'), url: returnApi('/corp_robot_knowledge_base/view'),
method: 'post', method: 'post',
data data,
}) });
} }
// 机器人知识库删除 // 机器人知识库删除
export function corp_robot_knowledge_del(data) { export function corp_robot_knowledge_del(data) {
return request({ return request({
url: returnApi('/corp_robot_knowledge_base/delete'), url: returnApi('/corp_robot_knowledge_base/delete'),
method: 'post', method: 'post',
data data,
}) });
} }
// 机器人知识库批量删除 // 机器人知识库批量删除
export function corp_robot_knowledge_batchDelete(data) { export function corp_robot_knowledge_batchDelete(data) {
return request({ return request({
url: returnApi('/corp_robot_knowledge_base/batchDelete'), url: returnApi('/corp_robot_knowledge_base/batchDelete'),
method: 'post', method: 'post',
data data,
}) });
} }
// 机器人知识库批量导入 // 机器人知识库批量导入
export function corp_robot_knowledge_import(data) { export function corp_robot_knowledge_import(data) {
return request({ return request({
url: returnApi('/corp_robot_knowledge_base/import'), url: returnApi('/corp_robot_knowledge_base/import'),
method: 'post', method: 'post',
data data,
}) });
} }
/* --------------------机器人知识库分组-----------------------*/ /* --------------------机器人知识库分组-----------------------*/
// 知识库分组列表 // 知识库分组列表
...@@ -293,32 +292,32 @@ export function corp_robot_knowledge_group_index(data) { ...@@ -293,32 +292,32 @@ export function corp_robot_knowledge_group_index(data) {
return request({ return request({
url: returnApi('/corp_robot_knowledge_group/index'), url: returnApi('/corp_robot_knowledge_group/index'),
method: 'post', method: 'post',
data data,
}) });
} }
// 知识库分组新增 // 知识库分组新增
export function corp_robot_knowledge_group_add(data) { export function corp_robot_knowledge_group_add(data) {
return request({ return request({
url: returnApi('/corp_robot_knowledge_group/add'), url: returnApi('/corp_robot_knowledge_group/add'),
method: 'post', method: 'post',
data data,
}) });
} }
// 知识库分组编辑 // 知识库分组编辑
export function corp_robot_knowledge_group_edit(data) { export function corp_robot_knowledge_group_edit(data) {
return request({ return request({
url: returnApi('/corp_robot_knowledge_group/edit'), url: returnApi('/corp_robot_knowledge_group/edit'),
method: 'post', method: 'post',
data data,
}) });
} }
// 知识库分组删除 // 知识库分组删除
export function corp_robot_knowledge_group_del(data) { export function corp_robot_knowledge_group_del(data) {
return request({ return request({
url: returnApi('/corp_robot_knowledge_group/delete'), url: returnApi('/corp_robot_knowledge_group/delete'),
method: 'post', method: 'post',
data data,
}) });
} }
// AI问答对列表 // AI问答对列表
...@@ -326,8 +325,8 @@ export function AI_list(data) { ...@@ -326,8 +325,8 @@ export function AI_list(data) {
return request({ return request({
url: returnApi('/corp_ai_question_answer/index'), url: returnApi('/corp_ai_question_answer/index'),
method: 'post', method: 'post',
data data,
}) });
} }
// 业务下拉 // 业务下拉
...@@ -335,8 +334,8 @@ export function search_condition(data) { ...@@ -335,8 +334,8 @@ export function search_condition(data) {
return request({ return request({
url: '/admin/search_condition', url: '/admin/search_condition',
method: 'post', method: 'post',
data data,
}) });
} }
// 智能体列表 // 智能体列表
...@@ -344,8 +343,8 @@ export function corp_beta_config(data) { ...@@ -344,8 +343,8 @@ export function corp_beta_config(data) {
return request({ return request({
url: '/admin/corp_beta_config/index', url: '/admin/corp_beta_config/index',
method: 'post', method: 'post',
data data,
}) });
} }
// 标记有用/无用 // 标记有用/无用
...@@ -353,22 +352,30 @@ export function markUseful(data) { ...@@ -353,22 +352,30 @@ export function markUseful(data) {
return request({ return request({
url: returnApi('/corp_ai_question_answer/markUseful'), url: returnApi('/corp_ai_question_answer/markUseful'),
method: 'post', method: 'post',
data data,
}) });
} }
// 跨主体分组列表 // 跨主体分组列表
export function cross_corp_robot_knowledge_group_index(data) { export function cross_corp_robot_knowledge_group_index(data) {
return request({ return request({
url: returnApi('/corp_cross_knowledge_group/index'), url: returnApi('/corp_cross_knowledge_group/index'),
method: 'post', method: 'post',
data data,
}) });
} }
// 跨主体知识库分组列表 // 跨主体知识库分组列表
export function cross_corp_robot_knowledge_group_getList(data) { export function cross_corp_robot_knowledge_group_getList(data) {
return request({ return request({
url: returnApi('/corp_cross_knowledge_base/getList'), url: returnApi('/corp_cross_knowledge_base/getList'),
method: 'post', method: 'post',
data data,
}) });
}
// 营销面板-话术生成
export function getGenerateProcedureApi(data) {
return request({
url: returnApi('/corp_activity_procedure/generateProcedure'),
method: 'post',
data,
});
} }
// 客户绑定掌游账号列表 // 客户绑定掌游账号列表
import request from '@/utils/request' import request from '@/utils/request';
function returnApi(api) { function returnApi(api) {
return '/sidebar' + api return '/sidebar' + api;
} }
// w 账号绑定列表 // w 账号绑定列表
export function zyouBindMember(data) { export function zyouBindMember(data) {
return request({ return request({
url: returnApi('/external_user/zyouBindMember'), url: returnApi('/external_user/zyouBindMember'),
method: 'post', method: 'post',
data data,
}) });
} }
// 检查账号绑定 // 检查账号绑定
export function checkZyouBind(data) { export function checkZyouBind(data) {
return request({ return request({
url: returnApi('/external_user/checkZyouBind'), url: returnApi('/external_user/checkZyouBind'),
method: 'post', method: 'post',
data data,
}) });
} }
// 绑定掌游账号 // 绑定掌游账号
// 绑定掌游账号 // 绑定掌游账号
...@@ -27,68 +27,67 @@ export function zyouBind(data) { ...@@ -27,68 +27,67 @@ export function zyouBind(data) {
return request({ return request({
url: returnApi('/external_user/zyouBind'), url: returnApi('/external_user/zyouBind'),
method: 'post', method: 'post',
data data,
}) });
} }
export function detailsInfoRequest(data) { export function detailsInfoRequest(data) {
return request({ return request({
url: returnApi('/external_user/info'), url: returnApi('/external_user/info'),
method: 'post', method: 'post',
data data,
}) });
} }
// 是否转端 // 是否转端
export function toTransfer(data) { export function toTransfer(data) {
return request({ return request({
url: returnApi('/external_user/toTransfer'), url: returnApi('/external_user/toTransfer'),
method: 'post', method: 'post',
data data,
}) });
} }
// 同步智能标签 // 同步智能标签
export function syncSessionIntelTag(data) { export function syncSessionIntelTag(data) {
return request({ return request({
url: '/sidebar/group_tag_detail/syncSessionIntelTag', url: '/sidebar/group_tag_detail/syncSessionIntelTag',
method: 'post', method: 'post',
data data,
}) });
} }
// 关联客服 // 关联客服
export function memberBindCser(data) { export function memberBindCser(data) {
return request({ return request({
url: returnApi('/external_user/memberBindCser'), url: returnApi('/external_user/memberBindCser'),
method: 'post', method: 'post',
data data,
}) });
} }
// 修改用户信息 // 修改用户信息
export function editUser(data) { export function editUser(data) {
return request({ return request({
url: returnApi('/external_user/edit'), url: returnApi('/external_user/edit'),
method: 'post', method: 'post',
data data,
}) });
} }
// 修改共享信息 // 修改共享信息
export function shareInfoUpsert(data) { export function shareInfoUpsert(data) {
return request({ return request({
url: returnApi('/external_user/shareInfoUpsert'), url: returnApi('/external_user/shareInfoUpsert'),
method: 'post', method: 'post',
data data,
}) });
} }
// 解绑掌游账号 // 解绑掌游账号
export function zyouUnBind(data) { export function zyouUnBind(data) {
return request({ return request({
url: returnApi('/external_user/zyouUnBind'), url: returnApi('/external_user/zyouUnBind'),
method: 'post', method: 'post',
data data,
}) });
} }
// 获取礼包码列表 // 获取礼包码列表
...@@ -96,16 +95,16 @@ export function getSendingCodeList(data) { ...@@ -96,16 +95,16 @@ export function getSendingCodeList(data) {
return request({ return request({
url: returnApi('/corp_gift_package_list/getSendingCodeList'), url: returnApi('/corp_gift_package_list/getSendingCodeList'),
method: 'post', method: 'post',
data data,
}) });
} }
// 标签 // 标签
export function searchTags(data) { export function searchTags(data) {
return request({ return request({
url: returnApi('/tag/index'), url: returnApi('/tag/index'),
method: 'post', method: 'post',
data data,
}) });
} }
// 通讯录 // 通讯录
...@@ -113,32 +112,32 @@ export function externalUserList(data) { ...@@ -113,32 +112,32 @@ export function externalUserList(data) {
return request({ return request({
url: returnApi('/corp_user/externalUserList'), url: returnApi('/corp_user/externalUserList'),
method: 'post', method: 'post',
data data,
}) });
} }
// 获取图片id // 获取图片id
export function getMediaId(data) { export function getMediaId(data) {
return request({ return request({
url: returnApi('/common/getMedia'), url: returnApi('/common/getMedia'),
method: 'post', method: 'post',
data data,
}) });
} }
// 通讯录红点 // 通讯录红点
export function mailRedTip(data) { export function mailRedTip(data) {
return request({ return request({
url: returnApi('/external_user/redTip'), url: returnApi('/external_user/redTip'),
method: 'post', method: 'post',
data data,
}) });
} }
// 同步通讯录 // 同步通讯录
export function refreshBindMail(data) { export function refreshBindMail(data) {
return request({ return request({
url: returnApi('/external_user/refreshBind'), url: returnApi('/external_user/refreshBind'),
method: 'post', method: 'post',
data data,
}) });
} }
// 搜索客户 // 搜索客户
...@@ -147,24 +146,24 @@ export function remarkSearchSelect(data) { ...@@ -147,24 +146,24 @@ export function remarkSearchSelect(data) {
return request({ return request({
url: returnApi('/follow_user/preview'), url: returnApi('/follow_user/preview'),
method: 'post', method: 'post',
data data,
}) });
} }
// 礼包可发送礼包 // 礼包可发送礼包
export function giftCodeList(data) { export function giftCodeList(data) {
return request({ return request({
url: returnApi('/corp_gift_package_list/getCanSendPackage'), url: returnApi('/corp_gift_package_list/getCanSendPackage'),
method: 'post', method: 'post',
data data,
}) });
} }
// 礼包码发送 // 礼包码发送
export function sendGiftCode(data) { export function sendGiftCode(data) {
return request({ return request({
url: returnApi('/corp_gift_package_list/sendGiftCode'), url: returnApi('/corp_gift_package_list/sendGiftCode'),
method: 'post', method: 'post',
data data,
}) });
} }
// 获取举报授权链接地址 // 获取举报授权链接地址
...@@ -172,8 +171,8 @@ export function getZyouAuthLink(data) { ...@@ -172,8 +171,8 @@ export function getZyouAuthLink(data) {
return request({ return request({
url: returnApi('/corp_zyou_bind/getZyouAuthLink'), url: returnApi('/corp_zyou_bind/getZyouAuthLink'),
method: 'post', method: 'post',
data data,
}) });
} }
// 转游最近发送的记录 5 条 // 转游最近发送的记录 5 条
...@@ -181,32 +180,32 @@ export function getRecentSendLog(data) { ...@@ -181,32 +180,32 @@ export function getRecentSendLog(data) {
return request({ return request({
url: returnApi('/corp_zyou_game_send_log/getRecentSendLog'), url: returnApi('/corp_zyou_game_send_log/getRecentSendLog'),
method: 'post', method: 'post',
data data,
}) });
} }
// 标记转端 // 标记转端
export function markTransScene(data) { export function markTransScene(data) {
return request({ return request({
url: returnApi('/external_user/markTransScene'), url: returnApi('/external_user/markTransScene'),
method: 'post', method: 'post',
data data,
}) });
} }
// 根据用户 id 获取掌权分组 // 根据用户 id 获取掌权分组
export function getZqCserGroup(data) { export function getZqCserGroup(data) {
return request({ return request({
url: returnApi('/common/getZqCserGroup'), url: returnApi('/common/getZqCserGroup'),
method: 'post', method: 'post',
data data,
}) });
} }
// 根据用户 id 获取掌权项目 // 根据用户 id 获取掌权项目
export function getZqCserWxBelong(data) { export function getZqCserWxBelong(data) {
return request({ return request({
url: returnApi('/common/getZqCserWxBelong'), url: returnApi('/common/getZqCserWxBelong'),
method: 'post', method: 'post',
data data,
}) });
} }
// 记录转游发送记录 // 记录转游发送记录
...@@ -214,16 +213,16 @@ export function send_log_add(data) { ...@@ -214,16 +213,16 @@ export function send_log_add(data) {
return request({ return request({
url: returnApi('/corp_zyou_game_send_log/add'), url: returnApi('/corp_zyou_game_send_log/add'),
method: 'post', method: 'post',
data data,
}) });
} }
// 发送渠道密码加密 // 发送渠道密码加密
export function zyouGetMemberLink(data) { export function zyouGetMemberLink(data) {
return request({ return request({
url: returnApi('/session/zyouGetMemberLink'), url: returnApi('/session/zyouGetMemberLink'),
method: 'post', method: 'post',
data data,
}) });
} }
// 我的任务获取红点数组 // 我的任务获取红点数组
...@@ -231,8 +230,8 @@ export function getTaskUnReadData(data) { ...@@ -231,8 +230,8 @@ export function getTaskUnReadData(data) {
return request({ return request({
url: returnApi('/corp_zyou_bind/getTaskUnReadData'), url: returnApi('/corp_zyou_bind/getTaskUnReadData'),
method: 'post', method: 'post',
data data,
}) });
} }
// 我的任务小时红点数字 // 我的任务小时红点数字
...@@ -240,24 +239,24 @@ export function clearTaskUnReadData(data) { ...@@ -240,24 +239,24 @@ export function clearTaskUnReadData(data) {
return request({ return request({
url: returnApi('/corp_zyou_bind/clearTaskUnReadData'), url: returnApi('/corp_zyou_bind/clearTaskUnReadData'),
method: 'post', method: 'post',
data data,
}) });
} }
// w账号绑定客户列表 // w账号绑定客户列表
export function memberBindExternalUser(data) { export function memberBindExternalUser(data) {
return request({ return request({
url: returnApi('/cser_receipt/memberBindExternalUser'), url: returnApi('/cser_receipt/memberBindExternalUser'),
method: 'post', method: 'post',
data data,
}) });
} }
// 删除共享信息 // 删除共享信息
export function shareInfoDel(data) { export function shareInfoDel(data) {
return request({ return request({
url: returnApi('/external_user/shareInfoDel'), url: returnApi('/external_user/shareInfoDel'),
method: 'post', method: 'post',
data data,
}) });
} }
// 跟进总结列表 // 跟进总结列表
...@@ -266,6 +265,14 @@ export function corp_follow_up_summary_index(data) { ...@@ -266,6 +265,14 @@ export function corp_follow_up_summary_index(data) {
return request({ return request({
url: returnApi('/corp_follow_up_summary/index'), url: returnApi('/corp_follow_up_summary/index'),
method: 'post', method: 'post',
data data,
}) });
}
// 话术生成复制
export function corp_activity_procedure_copyUsed(data) {
return request({
url: returnApi('/corp_activity_procedure/copyUsed'),
method: 'post',
data,
});
} }
<?xml version="1.0" encoding="UTF-8"?>
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 60.1 (88133) - https://sketch.com -->
<title>编辑</title>
<desc>Created with Sketch.</desc>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="工作台" transform="translate(-1881.000000, -278.000000)" fill-rule="nonzero">
<g id="编辑" transform="translate(1880.000000, 277.000000)">
<rect id="矩形" fill="#000000" opacity="0" x="0" y="0" width="20" height="20"></rect>
<path d="M18.0820312,8.68359375 C17.8125,8.68359375 17.59375,8.90234375 17.59375,9.171875 L17.59375,15.5546875 C17.59375,16.9003906 16.4980469,17.9960938 15.1523438,17.9960938 L4.7734375,17.9960938 C3.42773438,17.9960938 2.33203125,16.9003906 2.33203125,15.5546875 L2.33203125,4.67773438 C2.33203125,3.33203125 3.42773438,2.23632812 4.7734375,2.23632812 L11.15625,2.23632812 C11.4257813,2.23632812 11.6445313,2.01757812 11.6445313,1.74804688 C11.6445313,1.47851562 11.4257813,1.25976562 11.15625,1.25976562 L4.7734375,1.25976562 C2.88867188,1.25976562 1.35546875,2.79296875 1.35546875,4.67773438 L1.35546875,15.5527344 C1.35546875,17.4375 2.88867188,18.9707031 4.7734375,18.9707031 L15.1523438,18.9707031 C17.0371094,18.9707031 18.5703125,17.4375 18.5703125,15.5527344 L18.5703125,9.171875 C18.5703125,8.90234375 18.3515625,8.68359375 18.0820312,8.68359375 Z M18.6816406,3.65429687 L16.3417969,1.3984375 C16.2480469,1.30859375 16.1230469,1.25976562 15.9941406,1.26166234 C15.8652344,1.26367187 15.7421875,1.31835937 15.6523438,1.41015625 L14.359375,2.75195312 C14.3515625,2.7578125 14.3457031,2.765625 14.3378906,2.7734375 L6.95898438,10.421875 C6.9296875,10.453125 6.90429688,10.4863281 6.88476563,10.5214844 C6.85742188,10.5605469 6.8359375,10.6035156 6.82226563,10.6484375 L5.66015625,14.2382812 C5.6015625,14.4179687 5.65234375,14.6152344 5.7890625,14.7441406 C5.88085938,14.8300781 6.00195313,14.8769531 6.12304688,14.8769531 C6.18359375,14.8769531 6.24414063,14.8652344 6.30078125,14.84375 L9.73828125,13.4980469 C9.83398438,13.4804687 9.92773438,13.4335937 10,13.3574219 L17.3085937,5.78125 C17.3164062,5.77539062 17.3222656,5.76757812 17.3300781,5.76171875 L18.6953125,4.34570312 C18.8828125,4.15039062 18.8769531,3.84179687 18.6816406,3.65429687 Z M14.6484375,3.85546875 L16.2851562,5.43554688 L9.63671875,12.3300781 L8,10.75 L14.6484375,3.85546875 Z M6.90625,13.5585938 L7.51367188,11.6816406 L8.74609375,12.8378906 L6.90625,13.5585938 Z M17.0175781,4.67773438 L15.3808594,3.09765625 L16.0175781,2.4375 L17.6542969,4.01757813 L17.0175781,4.67773438 Z" id="形状" fill="#666666"></path>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<template>
<div class="expand_image">
<el-image ref="previewImage" class="image" v-if="url" v-bind="$attrs" style="height: 100%;width: 100%;" :src="url"
:preview-src-list="[url]">
<!-- 透传所有普通插槽 -->
<template v-for="(_, name) in $slots" v-slot:[name]>
<slot :name="name" />
</template>
</el-image>
<div class="expand_image_icon">
<div @click="handleLook">
<slot name="icon"></slot>
</div>
</div>
</div>
</template>
<script type="text/javascript">
export default {
name: 'ExpandImage',
inheritAttrs: false,
props:{
/**
* 图片的 URL 地址
* @type {string}
* @default ''
*/
url: {
type: String,
default: ''
},
},
data() {
return {
}
},
methods: {
handleLook() {
this.$nextTick(() => {
this.$refs.previewImage.clickHandler();
});
}
},
created() {
console.log(this.url,'++++++++++++++++');
},
}
</script>
<style lang="scss" scoped>
.expand_image {
position: relative;
&:hover::after {
content: '';
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #000;
opacity: .3;
cursor: pointer;
}
.expand_image_icon {
visibility: hidden;
position: absolute;
display: flex;
top: 0;
left: 0;
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
z-index: 1;
}
&:hover .expand_image_icon {
visibility: visible;
cursor: pointer;
}
}
</style>
\ No newline at end of file
<!--
# getRoleList 传入 member_id 获取角色列表
-->
<template>
<el-select v-model="selectedValue" placeholder="请选择" clearable size="small" :style="{ width: width || '100%' }"
v-bind="$attrs" :clearable="false" filterable remote :remote-method="remoteMethod" @clear="handleClear"
v-on="$listeners" @change="handleChange" @visible-change="handleVisibleChange">
<div class="select-dropdown" @scroll="handleScroll">
<el-option v-for="item in RuleList" :key="item.value" :label="item.label" :value="item.value"></el-option>
<div v-if="loading" v-loading="true" class="loading-more">
加载中...
</div>
</div>
</el-select>
</template>
<script lang="jsx">
import { getRoleHoLo } from '@/api/game'
import { debounce } from '@/utils'
export default {
name: 'getRoleList',
props: {
member_id: {
type: [String, Number],
default: ''
},
value: {
type: [String, Number],
default: ''
},
width: {
type: [String, Number],
default: ''
}
},
data() {
return {
RuleList: [],
loading: false,
currentPage: 1,
hasMore: true,
searchQuery: '',
selectedValue: this.value,
_debouncedRemote: null
}
},
watch: {
value(newVal) {
this.selectedValue = newVal
},
member_id(newVal) {
this.getRuleList()
}
},
created() {
this.getRuleList()
},
methods: {
async getRuleList(isLoadMore = false, query) {
// 仅在加载更多时受 hasMore 限制;新检索应始终允许
if (this.loading || (isLoadMore && !this.hasMore)) return
try {
this.loading = true
const keyword = typeof query === 'string' ? query : this.searchQuery
if (!isLoadMore) {
// 新检索时记录关键字
this.searchQuery = keyword || ''
}
const res = await getRoleHoLo({
page: isLoadMore ? this.currentPage + 1 : 1,
page_size: 20,
role_name: keyword,
search_type: 'list',
member_id: this.member_id
})
if (res.status_code === 1 && res.data && res.data.data) {
res.data.data.forEach(item => {
item.server_name ? item.label = `${item.role_name} - ${item.server_name}` : item.label = item.role_name
item.value = item.role_id
})
if (isLoadMore) {
this.RuleList = [...this.RuleList, ...res.data.data]
this.currentPage++
} else {
this.RuleList = res.data.data
this.currentPage = 1
}
this.hasMore = res.data.data.length >= 20
} else {
this.$message.warning(res.data.msg)
}
} catch (error) {
this.$message.error('获取数据失败')
} finally {
this.loading = false
}
},
handleScroll(e) {
const { scrollTop, scrollHeight, clientHeight } = e.target
if (scrollHeight - scrollTop - clientHeight < 50 && this.hasMore) {
this.getRuleList(true, this.searchQuery)
}
},
handleClear() {
this.selectedValue = ''
this.searchQuery = ''
this.$emit('clear')
},
handleChange() {
const roleInfo = this.RuleList.find(item => item.value === this.selectedValue)
this.$emit('selectChange', roleInfo)
},
handleVisibleChange(visible) {
// if (visible) {
// this.getRuleList()
// }
},
remoteMethod(query) {
if (!this._debouncedRemote) {
this._debouncedRemote = debounce((q) => {
this.getRuleList(false, q)
}, 300)
}
this._debouncedRemote(query)
}
}
}
</script>
<style lang="scss" scoped>
.select-dropdown {
max-height: 300px;
overflow-y: auto;
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-thumb {
background-color: #e4e7ed;
border-radius: 3px;
}
}
.loading-more {
text-align: center;
padding: 5px 0;
}
</style>
\ No newline at end of file
...@@ -13,6 +13,7 @@ Vue.use(ElementUI); ...@@ -13,6 +13,7 @@ Vue.use(ElementUI);
// import '@/styles/element-theme-colors.css'; // import '@/styles/element-theme-colors.css';
import '@/styles/index.scss'; import '@/styles/index.scss';
import moment from 'moment' import moment from 'moment'
import '@/styles/tailwind.css'
import VConsole from 'vconsole'; import VConsole from 'vconsole';
import uploading from '@/utils/cos-upload' import uploading from '@/utils/cos-upload'
import errorHandle from '@/utils/errorHandle' import errorHandle from '@/utils/errorHandle'
......
...@@ -852,3 +852,8 @@ li { ...@@ -852,3 +852,8 @@ li {
.el-input__icon{ .el-input__icon{
line-height: 1; line-height: 1;
} }
//弹框内容超出显示滚动
.el-message-box__message {
max-height: 500px !important;
overflow-y: auto !important;
}
\ No newline at end of file
@tailwind base;
@tailwind components;
@tailwind utilities;
<template> <template>
<div class="violationRecord"> <div class="violationRecord">
<el-form <el-form v-loading="loading" class="violationRecordContent" label-width="90px">
v-loading="loading"
class="violationRecordContent"
label-width="90px"
>
<div v-if="violationList.length > 0"> <div v-if="violationList.length > 0">
<div <div v-for="(item, index) in violationList" :key="index" class="contentItem">
v-for="(item, index) in violationList"
:key="index"
class="contentItem"
>
<el-form-item label="违规时间:"> <el-form-item label="违规时间:">
<p>{{ item.violation_time }}</p> <p>{{ item.violation_time }}</p>
</el-form-item> </el-form-item>
...@@ -31,15 +23,9 @@ ...@@ -31,15 +23,9 @@
<el-form-item label="是否允许申诉:"> <el-form-item label="是否允许申诉:">
<p class="error">{{ item.appeal_name }}</p> <p class="error">{{ item.appeal_name }}</p>
</el-form-item> </el-form-item>
<el-form-item <el-form-item v-if="item.remake != ''" label="详情:">
v-if="item.remake != ''"
label="详情:"
>
<!-- AI自动封禁 --> <!-- AI自动封禁 -->
<div <div v-if="item.information_type === 6" class="remarkType">
v-if="item.information_type === 6"
class="remarkType"
>
<p> <p>
<span class="label">所属项目:</span><span>{{ item.newRemake.project || "" }}</span> <span class="label">所属项目:</span><span>{{ item.newRemake.project || "" }}</span>
</p> </p>
...@@ -66,29 +52,16 @@ ...@@ -66,29 +52,16 @@
</p> </p>
</div> </div>
<!-- 其他类型 --> <!-- 其他类型 -->
<div <div v-else class="remarkType">
v-else <div v-if="item.remake.indexOf('src=') !== -1" class="remakeImage">
class="remarkType"
>
<div
v-if="item.remake.indexOf('src=') !== -1"
class="remakeImage"
>
<p class="watchDetails"> <p class="watchDetails">
<el-button <el-button type="text" icon="el-icon-view" size="medium"
type="text"
icon="el-icon-view"
size="medium"
style="z-index: 1; position: relative; margin-left: 5px" style="z-index: 1; position: relative; margin-left: 5px"
@click="showRemake(item.remake)" @click="showRemake(item.remake)">查看大图</el-button>
>查看大图</el-button>
</p> </p>
<p class="remakeDetails" v-html="item.remake"></p> <p class="remakeDetails" v-html="item.remake"></p>
</div> </div>
<div <div v-else class="remakeImage">
v-else
class="remakeImage"
>
<p class="remakeDetails" v-html="item.remake"></p> <p class="remakeDetails" v-html="item.remake"></p>
</div> </div>
</div> </div>
...@@ -96,38 +69,14 @@ ...@@ -96,38 +69,14 @@
<!-- 命中统计表格 --> <!-- 命中统计表格 -->
<div v-if="item && item.newRemake && item.newRemake.hit"> <div v-if="item && item.newRemake && item.newRemake.hit">
<div <div class="title" style="font-weight: 600; margin-bottom: 10px">
class="title"
style="font-weight: 600; margin-bottom: 10px"
>
命中统计 命中统计
</div> </div>
<el-table <el-table :data="item.newRemake.hit" size="medium" style="width: 100%" class="hit-statistics-table">
:data="item.newRemake.hit" <el-table-column prop="content" label="文本内容" show-overflow-tooltip />
size="medium" <el-table-column prop="type" label="命中类型" width="120" />
style="width: 100%" <el-table-column prop="key" label="关键字" width="120" show-overflow-tooltip />
class="hit-statistics-table" <el-table-column label="时间" width="180">
>
<el-table-column
prop="content"
label="文本内容"
show-overflow-tooltip
/>
<el-table-column
prop="type"
label="命中类型"
width="120"
/>
<el-table-column
prop="key"
label="关键字"
width="120"
show-overflow-tooltip
/>
<el-table-column
label="时间"
width="180"
>
<template slot-scope="{ row }"> <template slot-scope="{ row }">
<span>{{ $moment(row.time).format("YYYY-MM-DD HH:mm:ss") }}</span> <span>{{ $moment(row.time).format("YYYY-MM-DD HH:mm:ss") }}</span>
</template> </template>
...@@ -138,27 +87,14 @@ ...@@ -138,27 +87,14 @@
</div> </div>
<!-- 无数据状态 --> <!-- 无数据状态 -->
<div <div v-if="!loading && violationList.length == 0" class="noContent rowFlex allCenter">
v-if="!loading && violationList.length == 0"
class="noContent rowFlex allCenter"
>
<noContent title="暂无数据" description="当前没有任何数据,请稍后再试或联系管理员" /> <noContent title="暂无数据" description="当前没有任何数据,请稍后再试或联系管理员" />
</div> </div>
</el-form> </el-form>
<!-- 查看大图弹窗 --> <!-- 查看大图弹窗 -->
<el-dialog <el-dialog title="查看大图" :visible.sync="imageLayer" width="320px" center append-to-body @close="imageLayer = false">
title="查看大图" <div v-html="imageSrc" class="layerImage"></div>
:visible.sync="imageLayer"
width="320px"
center
append-to-body
@close="imageLayer = false"
>
<div
v-html="imageSrc"
class="layerImage"
></div>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
...@@ -274,7 +210,8 @@ export default { ...@@ -274,7 +210,8 @@ export default {
border-bottom: 1px dashed #ebeef5; border-bottom: 1px dashed #ebeef5;
margin-bottom: 20px; margin-bottom: 20px;
padding-bottom: 20px; padding-bottom: 20px;
::v-deep .el-form-item__label{
::v-deep .el-form-item__label {
line-height: 40px; line-height: 40px;
} }
...@@ -362,6 +299,7 @@ export default { ...@@ -362,6 +299,7 @@ export default {
.remakeDetails { .remakeDetails {
word-break: break-all; word-break: break-all;
::v-deep img { ::v-deep img {
max-width: 200px; max-width: 200px;
max-height: 200px; max-height: 200px;
......
<!--
* @Author: maoxiya 937667504@qq.com
* @Date: 2025-06-25 16:46:39
* @LastEditors: maoxiya 937667504@qq.com
* @LastEditTime: 2025-09-02 15:38:31
* @FilePath: /company_app/src/views/applyRecord.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template> <template>
<div class="gift-tab-container-errorHanledle"> <div class="gift-tab-container-errorHanledle">
<el-tabs v-model="activeTab"> <el-tabs v-model="activeTab">
<el-tab-pane label="举报记录" name="report">
<report v-if="activeTab === 'report'" />
</el-tab-pane>
<el-tab-pane label="误操作" name="errorHandle"> <el-tab-pane label="误操作" name="errorHandle">
<errorHandle v-if="activeTab=='errorHandle'"></errorHandle> <errorHandle v-if="activeTab == 'errorHandle'"></errorHandle>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="转区申请" name="serve"> <el-tab-pane label="转区申请" name="serve">
<AreaTransferApply v-if="activeTab=='serve'" /> <AreaTransferApply v-if="activeTab == 'serve'" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="转端申请" name="terminal"> <el-tab-pane label="转端申请" name="terminal">
<TerminalTransfer v-if="activeTab=='terminal'" /> <TerminalTransfer v-if="activeTab == 'terminal'" />
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
...@@ -17,43 +28,51 @@ ...@@ -17,43 +28,51 @@
import AreaTransferApply from './components/ApplyRecords/AreaTransferApply.vue' import AreaTransferApply from './components/ApplyRecords/AreaTransferApply.vue'
import errorHandle from './components/ApplyRecords/errorHandle.vue' import errorHandle from './components/ApplyRecords/errorHandle.vue'
import TerminalTransfer from './components/ApplyRecords/TerminaTranfer.vue' import TerminalTransfer from './components/ApplyRecords/TerminaTranfer.vue'
import report from './components/roleInfo/report.vue'
export default { export default {
name: 'applyRecord', name: 'applyRecord',
components: { components: {
AreaTransferApply, AreaTransferApply,
errorHandle, errorHandle,
TerminalTransfer TerminalTransfer,
report
}, },
data() { data() {
return { return {
activeTab: 'errorHandle' activeTab: 'report'
} }
} }
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.gift-tab-container-errorHanledle { .gift-tab-container-errorHanledle {
//padding: 20px; //padding: 20px;
width: 100%; width: 100%;
height: 100%; height: 100%;
padding-top: 10px; padding-top: 10px;
background: #fff; background: #fff;
::v-deep .el-tabs{
::v-deep .el-tabs {
height: calc(100% - 40px); height: calc(100% - 40px);
} }
::v-deep .el-tabs__content{
::v-deep .el-tabs__content {
height: 100%; height: 100%;
} }
::v-deep .el-tab-pane{
::v-deep .el-tab-pane {
height: 100%; height: 100%;
} }
::v-deep .el-tabs .el-tabs__header{
::v-deep .el-tabs .el-tabs__header {
margin: 0; margin: 0;
// height: 60px; // height: 60px;
} }
::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;
} }
} }
</style> </style>
\ No newline at end of file \ No newline at end of file
...@@ -37,11 +37,12 @@ ...@@ -37,11 +37,12 @@
<div class="terminaItemRight columnFlex columnCenter"> <div class="terminaItemRight columnFlex columnCenter">
<el-button v-if="item.approval_status == 4 && item.related_request_id == 0" type="primary" size="mini" <el-button v-if="item.approval_status == 4 && item.related_request_id == 0" type="primary" size="mini"
style="margin-bottom:15px;" @click.stop="resubmitApproval(item)">重新提交</el-button> style="margin-bottom:15px;" @click.stop="resubmitApproval(item)">重新提交</el-button>
<img v-if="item.approval_status == 1" :src="shenpi1" class="icon" /> <!-- 改成 svg-icon 图标 -->
<img v-else-if="item.approval_status == 2" :src="shenpi2" class="icon" /> <svg-icon v-if="item.approval_status == 1" icon-class="shenpi1" class="icon" />
<img v-else-if="item.approval_status == 3" :src="shenpi3" class="icon" /> <svg-icon v-else-if="item.approval_status == 2" icon-class="shenpi2" class="icon" />
<img v-else-if="item.approval_status == 4" :src="shenpi4" class="icon" /> <svg-icon v-else-if="item.approval_status == 3" icon-class="shenpi3" class="icon" />
<img v-else-if="item.approval_status == 5" :src="shenpi5" class="icon" /> <svg-icon v-else-if="item.approval_status == 4" icon-class="shenpi4" class="icon" />
<svg-icon v-else-if="item.approval_status == 5" icon-class="shenpi5" class="icon" />
</div> </div>
</div> </div>
<!-- 审批进度 --> <!-- 审批进度 -->
......
<template> <template>
<el-drawer <el-drawer title="新增关联账号" :visible="show" size="360px" :append-to-body="true" @close="close">
title="新增关联账号"
:visible="show"
size="360px"
:append-to-body="true"
@close="close"
>
<div class="content"> <div class="content">
<el-form <el-form ref="form" :model="form" label-position="top" :rules="rules" label-width="120px">
ref="form"
:model="form"
label-position="top"
:rules="rules"
label-width="120px"
>
<div class="inputContent"> <div class="inputContent">
<el-form-item <el-form-item label="请输入w账号" prop="username">
label="请输入w账号" <el-input v-model.trim="form.username" placeholder="请输入w账号" class="input-with-select">
prop="username"
>
<el-input
v-model.trim="form.username"
placeholder="请输入w账号"
class="input-with-select"
>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item <el-form-item label="请输入主游戏名" prop="main_game_id">
label="请输入主游戏名" <el-select v-model="form.main_game_id" filterable remote clearable reserve-keyword placeholder="请输入主游戏名"
prop="main_game_id" style="width: 100%;" :remote-method="remoteMethod" :loading="loading" @focus="gameNameList = optionsList">
> <el-option v-for="item in gameNameList" :key="item.value" :label="item.label" :value="item.value">
<el-select
v-model="form.main_game_id"
filterable
remote
clearable
reserve-keyword
placeholder="请输入主游戏名"
style="width: 100%;"
:remote-method="remoteMethod"
:loading="loading"
@focus="gameNameList=optionsList"
>
<el-option
v-for="item in gameNameList"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item <el-form-item label="请输入区服" prop="server_info">
label="请输入区服" <el-select v-model.trim="form.server_info" filterable remote :disabled="form.main_game_id == ''" clearable
prop="server_info" style="width: 100%;" reserve-keyword placeholder="请先选择主游戏" :remote-method="remoteMethodServer"
> :loading="loading">
<el-select <el-option v-for="item in serverNameList" :key="item.id" :label="item.label" :value="item.value">
v-model.trim="form.server_info"
filterable
remote
:disabled="form.main_game_id==''"
clearable
style="width: 100%;"
reserve-keyword
placeholder="请先选择主游戏"
:remote-method="remoteMethodServer"
:loading="loading"
>
<el-option
v-for="item in serverNameList"
:key="item.id"
:label="item.label"
:value="item.value"
>
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item <el-form-item label="请输入角色名" prop="role_name">
label="请输入角色名" <el-input v-model.trim="form.role_name" placeholder="请输入角色" class="input-with-select">
prop="role_name"
>
<el-input
v-model.trim="form.role_name"
placeholder="请输入角色"
class="input-with-select"
>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button <el-button type="primary" size="small" @click="onSubmit">搜索</el-button>
type="primary"
size="small"
@click="onSubmit"
>搜索</el-button>
</el-form-item> </el-form-item>
</div> </div>
</el-form> </el-form>
...@@ -100,24 +35,16 @@ ...@@ -100,24 +35,16 @@
<div class="bind-account-title"> <div class="bind-account-title">
账号列表 账号列表
</div> </div>
<userTable <userTable :list="tableList" @checkedTag="checkedTag" />
:list="tableList"
@checkedTag="checkedTag"
/>
</div> </div>
<!-- <div class="line"></div> w92865226508--> <!-- <div class="line"></div> w92865226508-->
<div <div v-if="userDetails.username" class="account_select_userInfo">
v-if="userDetails.username"
class="account_select_userInfo"
>
<div class="bind-account-title" style="margin-top: 20px;"> <div class="bind-account-title" style="margin-top: 20px;">
账号详情 账号详情
</div> </div>
<div class="item rowFlex columnCenter"><span class="label">账号</span> <div class="item rowFlex columnCenter"><span class="label">账号</span>
<p class="text">{{ userDetails.username }}</p> <span <p class="text">{{ userDetails.username }}</p> <span v-if="userDetails.account_type == 2"
v-if="userDetails.account_type==2" class="account_type"></span>
class="account_type"
></span>
</div> </div>
<div class="item rowFlex columnCenter"><span class="label">获客渠道</span> <div class="item rowFlex columnCenter"><span class="label">获客渠道</span>
<p class="text">{{ userDetails.channel_name }}</p> <p class="text">{{ userDetails.channel_name }}</p>
...@@ -141,10 +68,10 @@ ...@@ -141,10 +68,10 @@
<p class="text">{{ userDetails.mobile }}</p> <p class="text">{{ userDetails.mobile }}</p>
</div> </div>
<div class="item rowFlex columnCenter"><span class="label">染色时间</span> <div class="item rowFlex columnCenter"><span class="label">染色时间</span>
<p class="text">{{ moment( userDetails.seq_time * 1000).format('YYYY-MM-DD') }}</p> <p class="text">{{ moment(userDetails.seq_time * 1000).format('YYYY-MM-DD') }}</p>
</div> </div>
<div class="item rowFlex columnCenter"><span class="label">注册时间</span> <div class="item rowFlex columnCenter"><span class="label">注册时间</span>
<p class="text">{{ moment( userDetails.reg_time * 1000).format('YYYY-MM-DD') }}</p> <p class="text">{{ moment(userDetails.reg_time * 1000).format('YYYY-MM-DD') }}</p>
</div> </div>
<div class="item rowFlex columnCenter"><span class="label">登录系统</span> <div class="item rowFlex columnCenter"><span class="label">登录系统</span>
<p class="text">{{ userDetails.last_login_os }}</p> <p class="text">{{ userDetails.last_login_os }}</p>
...@@ -157,29 +84,16 @@ ...@@ -157,29 +84,16 @@
</div> </div>
</div> </div>
</div> </div>
<page <page class="pageInfo" :page-info="pageInfo" @requestNextPage="requestNextPage" />
class="pageInfo"
:page-info="pageInfo"
@requestNextPage="requestNextPage"
/>
<span class="dialog-footer rowFlex"> <span class="dialog-footer rowFlex">
<el-button <el-button class="btn" type="primary" size="small" :disabled="!userDetails.id" @click="confirmSubmit">
class="btn" </el-button>
type="primary" <el-button class="btn" size="small" @click="close">取 消</el-button>
size="small"
:disabled="!userDetails.id"
@click="confirmSubmit"
>确 定</el-button>
<el-button
class="btn"
size="small"
@click="close"
>取 消</el-button>
</span> </span>
</el-drawer> </el-drawer>
</template> </template>
<script type="text/javascript"> <script type="text/javascript">
import moment from 'moment' import moment from 'moment'
import userTable from './userTable.vue' import userTable from './userTable.vue'
import { getRoleHoLo, memberView, selectSearch } from '@/api/game' import { getRoleHoLo, memberView, selectSearch } from '@/api/game'
...@@ -419,32 +333,37 @@ ...@@ -419,32 +333,37 @@
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
::v-deep .el-drawer { ::v-deep .el-drawer {
height: 100%; height: 100%;
overflow: auto; overflow: auto;
} }
.bind-account-title{
.bind-account-title {
font-size: 16px; font-size: 16px;
font-family: PingFangSC-Regular, PingFang SC; font-family: PingFangSC-Regular, PingFang SC;
font-weight: 600; font-weight: 600;
color: #333333; color: #333333;
text-align: left; text-align: left;
margin-bottom: 10px; margin-bottom: 10px;
} }
.content {
.content {
width: 100%; width: 100%;
height: 100%; height: 100%;
overflow: auto; overflow: auto;
padding-bottom: 200px; padding-bottom: 200px;
padding: 0 10px; padding: 0 10px;
.inputContent { .inputContent {
width: 100%; width: 100%;
} }
.info { .info {
width: 100%; width: 100%;
margin-top: 30px; margin-top: 30px;
overflow: auto; overflow: auto;
.table { .table {
width: 100%; width: 100%;
min-width: 500px; min-width: 500px;
...@@ -460,15 +379,18 @@ ...@@ -460,15 +379,18 @@
height: 70%; height: 70%;
border-right: 1px dashed #e0e0e0; border-right: 1px dashed #e0e0e0;
} }
.account_select_userInfo { .account_select_userInfo {
width: 100%; width: 100%;
height: auto; height: auto;
padding-left: 20px; padding-left: 20px;
margin-top: -20px; margin-top: -20px;
margin-bottom: 150px; margin-bottom: 150px;
.item { .item {
width: 100%; width: 100%;
margin-top: 20px; margin-top: 20px;
.label { .label {
width: 30%; width: 30%;
font-size: 14px; font-size: 14px;
...@@ -478,6 +400,7 @@ ...@@ -478,6 +400,7 @@
text-align: left; text-align: left;
margin-right: 20px; margin-right: 20px;
} }
.text { .text {
font-size: 14px; font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC; font-family: PingFangSC-Regular, PingFang SC;
...@@ -488,29 +411,33 @@ ...@@ -488,29 +411,33 @@
} }
} }
} }
.account_table{
.account_table {
width: 100%; width: 100%;
height: auto; height: auto;
overflow: auto; overflow: auto;
} }
.account_type {
.account_type {
color: #f56c6c; color: #f56c6c;
font-weight: bold; font-weight: bold;
margin-left: 5px; margin-left: 5px;
background: #f7eded; background: #f7eded;
padding: 2px 5px; padding: 2px 5px;
border-radius: 3px; border-radius: 3px;
} }
.pageInfo {
.pageInfo {
width: calc(100% - 20px); width: calc(100% - 20px);
height: 82px; height: 82px;
position: absolute; position: absolute;
right: 20px; right: 20px;
bottom: 60px; bottom: 60px;
background: #fff; background: #fff;
} }
.dialog-footer {
.dialog-footer {
width: calc(100% - 20px); width: calc(100% - 20px);
position: absolute; position: absolute;
right: 20px; right: 20px;
...@@ -521,16 +448,15 @@ ...@@ -521,16 +448,15 @@
justify-content: flex-end; justify-content: flex-end;
background: #fff; background: #fff;
z-index: 10; z-index: 10;
.btn { .btn {
width: 84px; width: 84px;
height: 32px; height: 32px;
} }
} }
</style> </style>
<style> <style>
::v-deep .el-select-dropdown { ::v-deep .el-select-dropdown {
min-width: 210px !important; min-width: 210px !important;
} }
</style> </style>
\ No newline at end of file
\ No newline at end of file
...@@ -3,10 +3,14 @@ ...@@ -3,10 +3,14 @@
<div ref="giftList" class="gift-list" @scroll="handleScroll"> <div ref="giftList" class="gift-list" @scroll="handleScroll">
<div v-for="item in giftList" :key="item._id" class="gift-item"> <div v-for="item in giftList" :key="item._id" class="gift-item">
<div class="gift-info"> <div class="gift-info">
<div v-if="item.gift_package_group_name ">分组: {{ item.gift_package_group_name }}</div> <div v-if="item.gift_package_group_name">分组: {{ item.gift_package_group_name }}</div>
<div>礼包名称: {{ item.gift_package_name }}</div> <div>礼包名称: {{ item.gift_package_name }}</div>
<div>发送时间: {{ item.send_time }}</div> <div>发送时间: {{ item.send_time }}</div>
<div>礼包码: {{ item.code }}</div> <div>礼包码: {{ item.code }}</div>
<div>领取角色: <span v-if="item.role_name && item.role_name != 0">{{ item.role_name }}</span> <span
v-else>-</span>
</div>
<div>W 账号: {{ item.username || '-' }}</div>
<div class="rowFlex spaceBetween columnCenter gift-sender"> <div class="rowFlex spaceBetween columnCenter gift-sender">
<div>发送客服: {{ item.cser_name }}</div> <div>发送客服: {{ item.cser_name }}</div>
<i class="el-icon-document-copy" style="cursor: pointer;" @click="handleCopy(item.code)"></i> <i class="el-icon-document-copy" style="cursor: pointer;" @click="handleCopy(item.code)"></i>
...@@ -16,18 +20,17 @@ ...@@ -16,18 +20,17 @@
<div v-if="loading" class="loading-more">加载中...</div> <div v-if="loading" class="loading-more">加载中...</div>
<div v-if="!hasMore && giftList.length > 0" class="no-more">没有更多数据了</div> <div v-if="!hasMore && giftList.length > 0" class="no-more">没有更多数据了</div>
<div v-if="giftList.length == 0" class="noContent rowFlex allCenter"> <div v-if="giftList.length == 0" class="noContent rowFlex allCenter">
<noContent/> <noContent />
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script>
<script>
import Clipboard from 'clipboard' import Clipboard from 'clipboard'
import { getSendingCodeList } from '@/api/works' import { getSendingCodeList } from '@/api/works'
import { debounce,copyText,sendChatMessage } from '@/utils/index' import { debounce, copyText, sendChatMessage } from '@/utils/index'
import { mapState } from 'vuex' import { mapState } from 'vuex'
export default { export default {
name: 'wxGift', name: 'wxGift',
data() { data() {
return { return {
...@@ -69,7 +72,7 @@ import Clipboard from 'clipboard' ...@@ -69,7 +72,7 @@ import Clipboard from 'clipboard'
this.loading = false this.loading = false
} }
}, },
handleScroll: debounce(function(e) { handleScroll: debounce(function (e) {
const { scrollHeight, scrollTop, clientHeight } = e.target const { scrollHeight, scrollTop, clientHeight } = e.target
if (scrollHeight - scrollTop - clientHeight < 50) { if (scrollHeight - scrollTop - clientHeight < 50) {
this.fetchGiftList() this.fetchGiftList()
...@@ -87,11 +90,11 @@ import Clipboard from 'clipboard' ...@@ -87,11 +90,11 @@ import Clipboard from 'clipboard'
// }) // })
} }
} }
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.wx-gift-container { .wx-gift-container {
height: 100%; height: 100%;
width: 100%; width: 100%;
background-color: #fff; background-color: #fff;
...@@ -106,11 +109,13 @@ import Clipboard from 'clipboard' ...@@ -106,11 +109,13 @@ import Clipboard from 'clipboard'
background: #F7F8FA; background: #F7F8FA;
border-radius: 12px; border-radius: 12px;
border: 1px solid #E5E6EB; border: 1px solid #E5E6EB;
margin-bottom:12px; margin-bottom: 12px;
.gift-info { .gift-info {
div{ div {
line-height: 26px; line-height: 26px;
} }
.gift-name { .gift-name {
font-weight: 400; font-weight: 400;
font-size: 14px; font-size: 14px;
...@@ -118,6 +123,7 @@ import Clipboard from 'clipboard' ...@@ -118,6 +123,7 @@ import Clipboard from 'clipboard'
text-align: left; text-align: left;
font-style: normal; font-style: normal;
} }
.gift-code { .gift-code {
display: flex; display: flex;
align-items: center; align-items: center;
...@@ -129,6 +135,7 @@ import Clipboard from 'clipboard' ...@@ -129,6 +135,7 @@ import Clipboard from 'clipboard'
color: #323335; color: #323335;
text-align: justify; text-align: justify;
font-style: normal; font-style: normal;
span { span {
color: #323335; color: #323335;
font-size: 14px; font-size: 14px;
...@@ -158,7 +165,8 @@ import Clipboard from 'clipboard' ...@@ -158,7 +165,8 @@ import Clipboard from 'clipboard'
line-height: 18px; line-height: 18px;
text-align: justify; text-align: justify;
font-style: normal; font-style: normal;
i{
i {
color: #00BF8A; color: #00BF8A;
font-size: 14px; font-size: 14px;
} }
...@@ -175,5 +183,5 @@ import Clipboard from 'clipboard' ...@@ -175,5 +183,5 @@ import Clipboard from 'clipboard'
font-size: 13px; font-size: 13px;
} }
} }
} }
</style> </style>
\ No newline at end of file \ No newline at end of file
<template> <template>
<el-select <el-select v-model="resulte" v-loadmore="loadMoreList" filterable remote :disabled="disabled"
v-model="resulte" :remote-method="remoteMethod" :placeholder="placeholder" :clearable='false' reserve-keyword :loading="loading"
v-loadmore="loadMoreList" @change="selectChange">
filterable <el-option v-for="(item, index) in searchUserOption" :key="index" :value="item?.role_id || item.id"
remote :label="item.role_name" style="height:50px;">
:disabled="disabled"
:remote-method="remoteMethod"
:placeholder="placeholder"
:clearable='false'
reserve-keyword
:loading="loading"
@change="selectChange"
>
<el-option
v-for="(item,index) in searchUserOption"
:key="index"
:value="item.role_id || item.id"
:label="item.role_name"
style="height:50px;"
>
<div class="rowFlex columnCenter selectItem"> <div class="rowFlex columnCenter selectItem">
<!-- 没有头像 --> <!-- 没有头像 -->
<!-- <el-image v-if="item.avata" fit="fill" :src="item.avatar" class="tableImage "></el-image> --> <!-- <el-image v-if="item.avata" fit="fill" :src="item.avatar" class="tableImage "></el-image> -->
<div class="infoSpan columnFlex rowCenter"> <div class="infoSpan columnFlex rowCenter">
<p class="hidden">{{ item.role_name &&item.role_name!=''?item.game_name+' - '+item.server_name+' - '+item.role_name:'' }}</p> <p class="hidden">
<p class="rowFlex columnCenter">角色名:<label class="hidden" style="max-width:120px;">{{ item.role_name }}</label></p> {{ item.role_name && item.role_name != '' ? item.game_name + ' - ' + item.server_name + ' -
'+item.role_name:'' }}
</p>
<p class="rowFlex columnCenter">角色名:<label class="hidden" style="max-width:120px;">
{{ item.role_name }}
</label>
</p>
</div> </div>
</div> </div>
</el-option> </el-option>
</el-select> </el-select>
</template> </template>
<script> <script>
import { roleList } from '@/api/game' import { roleList } from '@/api/game'
import { mapState } from 'vuex' import { mapState } from 'vuex'
export default { export default {
...@@ -128,28 +119,33 @@ ...@@ -128,28 +119,33 @@
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.selectItem{ .selectItem {
height: 50px; height: 50px;
} }
.infoSpan{
.infoSpan {
font-size: 12px; font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC; font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400; font-weight: 400;
max-width: 250px; max-width: 250px;
height: 50px; height: 50px;
p{
font-size:12px;max-width:100%; p {
font-size: 12px;
max-width: 100%;
line-height: 20px; line-height: 20px;
} }
span{
color:#FFA81D; span {
} color: #FFA81D;
} }
.tableImage{ }
width:30px;height:30px;
.tableImage {
width: 30px;
height: 30px;
border-radius: 30px; border-radius: 30px;
margin-right: 10px; margin-right: 10px;
} }
</style> </style>
\ No newline at end of file
\ No newline at end of file
<!--
* @Author: maoxiya 937667504@qq.com
* @Date: 2025-08-28 15:59:46
* @LastEditors: maoxiya 937667504@qq.com
* @LastEditTime: 2025-09-02 09:51:24
* @FilePath: /company_wx_frontend/src/views/works/component/chat/giftCodeDialog.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
<el-dialog title="请确认发放的角色" :visible="dialogVisible" class="giftCodeDialogForm" width="360px" @close="closeDialog">
<p class="font12 mb-[10px] mt-[-10px]">即将发送召回礼包<span v-if="gameName" style="color: #00BF8A;"> ({{ gameName
}})</span>,发送后可在礼包记录中查看</p>
<el-form :model="form" ref="giftCodeDialogForm" label-width="80px" :rules="rules">
<el-form-item label="账号ID:" prop="member_id">
<el-select style="width: 320px;" :clearable="false" @change="handleMemberIdChange"
v-model="form.member_id" placeholder="请选择账号ID">
<el-option v-for="item in bindGameUserList" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="角色ID:" prop="role_id">
<getRoleList v-model="form.role_id" width="320px" placeholder="请选择角色" :member_id="form.member_id"
@selectChange="handleSelectionChange" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button size="mini" @click="closeDialog">取消</el-button>
<el-button type="primary" size="mini" @click="getGiftCodeSubmit('send')">确定</el-button>
<el-button type="text" size="mini" @click="getGiftCodeSubmit('copy')">仅复制</el-button>
</div>
</el-dialog>
</template>
<script>
import getRoleList from '@/components/getRoleList.vue'
import { getRoleHoLo } from '@/api/game'
import { mapState } from 'vuex'
export default {
props: {
dialogVisible: {
type: Boolean,
default: false
},
gameName: {
type: String,
default: ''
}
},
components: {
getRoleList
},
data() {
return {
form: {
member_id: '',
username: '',
role_id: '',
role_name: '',
},
rules: {
member_id: [{ required: true, message: '请选择账号ID', trigger: 'change' }],
role_id: [{ required: true, message: '请选择角色ID', trigger: 'change' }]
},
getRoleHoLo: getRoleHoLo,
gift_code: [],
roleList: [],
pageInfo: {
page: 1,
page_size: 10
},
loading: false
}
},
mounted() {
this.form.member_id = this.accountSelect
this.form.username = this.bindGameUserList.find(item => item.member_id === this.accountSelect).username
},
computed: {
...mapState('game', ['accountSelect', 'bindGameUserList'])
},
methods: {
handleMemberIdChange(value) {
this.form.role_id = ''
this.form.role_name = ''
const userInfo = this.bindGameUserList.find(item => item.value === value)
this.form.username = userInfo.label || userInfo.username
this.form.member_id = value
},
handleSelectionChange(roleInfo) {
console.log(roleInfo, 'roleInfo')
this.form.role_name = roleInfo.label || ''
},
closeDialog() {
this.$emit('update:dialogVisible', false)
},
getGiftCodeSubmit(type) {
this.$refs.giftCodeDialogForm.validate((valid) => {
if (valid) {
this.$emit('update:dialogVisible', false)
this.$emit('result', this.form, type)
}
})
}
}
}
</script>
<style lang="scss" scoped>
.giftCodeDialogForm {
.dialog-footer {
border: none;
padding: 0;
}
::v-deep .el-input__inner {
font-size: 14px;
width: 240px;
}
::v-deep .el-form-item__label {
line-height: 40px;
}
}
</style>
\ No newline at end of file
...@@ -12,14 +12,15 @@ ...@@ -12,14 +12,15 @@
<!-- 转端 --> <!-- 转端 -->
<el-collapse v-if="activeName == '1' && conversionGameList.length > 0" :disabled="disabled" <el-collapse v-if="activeName == '1' && conversionGameList.length > 0" :disabled="disabled"
@change="conversionChangeOld"> @change="conversionChangeOld">
<el-collapse-item v-for="(item, index) in conversionGameList" :key="index" :name="item.game_type"> <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">
<img v-if="item.game_type == 1" src="@/assets/icon/svg/wxgame.svg" class="game-icon" alt="微信小游戏"> <svg-icon v-if="item.game_type == 1" icon-class="wxgame" class="game-icon" />
<img v-else-if="item.game_type == 5" src="@/assets/icon/svg/douyin.svg" class="game-icon" alt="抖音小游戏"> <svg-icon v-else-if="item.game_type == 5" icon-class="douyin" class="game-icon" />
<img v-else-if="item.game_type == 3" src="@/assets/icon/svg/Android.svg" class="game-icon" alt="安卓游戏"> <svg-icon v-else-if="item.game_type == 3" icon-class="Android" class="game-icon" />
<img v-else-if="item.game_type == 4" src="@/assets/icon/svg/IOS.svg" class="game-icon" alt="IOS游戏"> <svg-icon v-else-if="item.game_type == 4" icon-class="IOS" class="game-icon" />
<img v-else-if="item.game_type == 2" src="@/assets/icon/svg/H5.svg" class="game-icon" alt="H5游戏"> <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>
...@@ -62,11 +63,11 @@ ...@@ -62,11 +63,11 @@
<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">
<img v-if="item.game_type == 1" src="@/assets/icon/svg/wxgame.svg" class="game-icon" alt="微信小游戏"> <svg-icon v-if="item.game_type == 1" icon-class="wxgame" class="game-icon" />
<img v-else-if="item.game_type == 5" src="@/assets/icon/svg/douyin.svg" class="game-icon" alt="抖音小游戏"> <svg-icon v-else-if="item.game_type == 5" icon-class="douyin" class="game-icon" />
<img v-else-if="item.game_type == 3" src="@/assets/icon/svg/Android.svg" class="game-icon" alt="安卓游戏"> <svg-icon v-else-if="item.game_type == 3" icon-class="Android" class="game-icon" />
<img v-else-if="item.game_type == 4" src="@/assets/icon/svg/IOS.svg" class="game-icon" alt="IOS游戏"> <svg-icon v-else-if="item.game_type == 4" icon-class="IOS" class="game-icon" />
<img v-else-if="item.game_type == 2" src="@/assets/icon/svg/H5.svg" class="game-icon" alt="H5游戏"> <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>
...@@ -106,17 +107,14 @@ ...@@ -106,17 +107,14 @@
<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">
<img v-if="item.label.includes('微信')" src="@/assets/icon/svg/wxgame.svg" class="game-icon" <svg-icon v-if="item.label.includes('微信')" icon-class="wxgame" class="game-icon" />
alt="微信小游戏"> <svg-icon v-else-if="item.label.includes('抖音')" icon-class="douyin" class="game-icon" />
<img v-else-if="item.label.includes('抖音')" src="@/assets/icon/svg/douyin.svg" class="game-icon" <svg-icon v-else-if="item.label.includes('安卓')" icon-class="Android" class="game-icon" />
alt="抖音小游戏"> <svg-icon
<img v-else-if="item.label.includes('安卓')" src="@/assets/icon/svg/Android.svg" class="game-icon"
alt="安卓游戏">
<img
v-else-if="item.label.includes('IOS') || item.label.includes('iOS') || item.label.includes('ios')" v-else-if="item.label.includes('IOS') || item.label.includes('iOS') || item.label.includes('ios')"
src="@/assets/icon/svg/IOS.svg" class="game-icon" alt="IOS游戏"> icon-class="IOS" class="game-icon" />
<img v-else-if="item.label.includes('H5') || item.label.includes('h5')" src="@/assets/icon/svg/H5.svg" <svg-icon v-else-if="item.label.includes('H5') || item.label.includes('h5')" icon-class="H5"
class="game-icon" alt="H5游戏"> class="game-icon" />
{{ item.label }} {{ item.label }}
</div> </div>
</template> </template>
......
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
</el-popover> </el-popover>
</p> </p>
<el-button size="mini" type="primary" :loading="loading" <el-button size="mini" type="primary" :loading="loading"
@click="sendGameCode(items)">发送礼包码</el-button> @click="sendGameCodeCopyDialog(items)">发送礼包码</el-button>
</div> </div>
</div> </div>
</div> </div>
...@@ -58,12 +58,15 @@ ...@@ -58,12 +58,15 @@
</el-collapse> </el-collapse>
</el-collapse-transition> </el-collapse-transition>
</div> </div>
<giftCodeDialog v-if="dialogVisible" :game-name="game_name" :dialogVisible.sync="dialogVisible"
@result="getGiftCodeSubmit" />
</div> </div>
</template> </template>
<script> <script>
import { mapState, mapMutations } from 'vuex' import { mapState, mapMutations } from 'vuex'
import { passwardEncryption, createVipUrl } from '@/api/game' import { passwardEncryption, createVipUrl } from '@/api/game'
import { giftCodeList, sendGiftCode, getZyouAuthLink } from '@/api/works' import { giftCodeList, sendGiftCode, getZyouAuthLink } from '@/api/works'
import giftCodeDialog from './giftCodeDialog.vue'
export default { export default {
name: 'vipTools', name: 'vipTools',
data() { data() {
...@@ -71,12 +74,33 @@ export default { ...@@ -71,12 +74,33 @@ export default {
disabled: true, disabled: true,
showGameCode: false, showGameCode: false,
giftCodeGame: [], giftCodeGame: [],
dialogVisible: false,
game_name: '',
giftCodeForm: {
member_id: '',
username: '',
role_name: '',
role_id: '',
gift_package_id: '',
},
loading: false loading: false
} }
}, },
components: {
giftCodeDialog
},
mounted() { mounted() {
this.requestGiftCode() this.requestGiftCode()
}, },
destroyed() {
this.giftCodeForm = {
member_id: '',
username: '',
role_name: '',
role_id: '',
gift_package_id: ''
}
},
computed: { computed: {
...mapState('game', ['accountSelect', 'bindGameUserList', 'chatUserInfo']), ...mapState('game', ['accountSelect', 'bindGameUserList', 'chatUserInfo']),
...mapState('user', ['userid']), ...mapState('user', ['userid']),
...@@ -94,6 +118,16 @@ export default { ...@@ -94,6 +118,16 @@ export default {
} }
}, },
methods: { methods: {
initGiftCodeForm() {
const username = this.bindGameUserList.find(item => item.member_id === this.accountSelect).username
this.giftCodeForm = {
member_id: this.accountSelect,
username: username,
role_name: '',
role_id: '',
gift_package_id: '',
}
},
sendVipGift() { sendVipGift() {
if (this.bindGameUserList.length > 0) { if (this.bindGameUserList.length > 0) {
createVipUrl({ member_id: this.accountSelect }).then(res => { createVipUrl({ member_id: this.accountSelect }).then(res => {
...@@ -107,6 +141,7 @@ export default { ...@@ -107,6 +141,7 @@ export default {
this.$message.warning('请先关联游戏账号') this.$message.warning('请先关联游戏账号')
} }
}, },
sendChatMessage(content, type) { sendChatMessage(content, type) {
let message = {} let message = {}
if (type == 'text') { if (type == 'text') {
...@@ -192,14 +227,36 @@ export default { ...@@ -192,14 +227,36 @@ export default {
item.group_name = item.gift_package_group_name item.group_name = item.gift_package_group_name
}) })
}, },
// 发送渠道 // 确定提交
getGiftCodeSubmit(form) {
const { member_id, role_id, username, role_name } = form
this.giftCodeForm.username = username
this.giftCodeForm.role_name = role_name
this.giftCodeForm.member_id = member_id
this.giftCodeForm.role_id = role_id
this.sendGameCode()
},
sendGameCodeCopyDialog(items) {
this.game_name = items.name
this.initGiftCodeForm()
this.giftCodeForm.gift_package_id = items.id
if (items.package_type == 3) {
this.dialogVisible = true
} else {
this.sendGameCode()
}
},
// 发送礼包码
async sendGameCode(items) { async sendGameCode(items) {
this.loading = true this.loading = true
const data = { const data = {
userid: this.chatUserInfo.userid, userid: this.chatUserInfo.userid,
external_userid: this.chatUserInfo.external_userid, external_userid: this.chatUserInfo.external_userid,
member_id: this.accountSelect, member_id: this.giftCodeForm.member_id,
gift_package_id: items.id, username: this.giftCodeForm.username,
role_name: this.giftCodeForm.role_name,
role_id: this.giftCodeForm.role_id,
gift_package_id: this.giftCodeForm.gift_package_id,
user_type: 1 user_type: 1
} }
const res = await sendGiftCode(data) const res = await sendGiftCode(data)
......
...@@ -75,11 +75,11 @@ ...@@ -75,11 +75,11 @@
size="mini" style="margin-bottom:15px;" @click.stop="handleReport(item)">撤销</el-button> size="mini" style="margin-bottom:15px;" @click.stop="handleReport(item)">撤销</el-button>
<el-button v-else-if="item.approval_status == 4" type="primary" size="mini" style="margin-bottom:15px;" <el-button v-else-if="item.approval_status == 4" type="primary" size="mini" style="margin-bottom:15px;"
@click.stop="resubmitApproval(item)">重新提交</el-button> @click.stop="resubmitApproval(item)">重新提交</el-button>
<img v-if="item.approval_status == 1" :src="shenpi1" class="icon" /> <svg-icon v-if="item.approval_status == 1" icon-class="shenpi1" class="icon" />
<img v-else-if="item.approval_status == 2" :src="shenpi2" class="icon" /> <svg-icon v-else-if="item.approval_status == 2" icon-class="shenpi2" class="icon" />
<img v-else-if="item.approval_status == 3" :src="shenpi3" class="icon" /> <svg-icon v-else-if="item.approval_status == 3" icon-class="shenpi3" class="icon" />
<img v-else-if="item.approval_status == 4" :src="shenpi4" class="icon" /> <svg-icon v-else-if="item.approval_status == 4" icon-class="shenpi4" class="icon" />
<img v-else-if="item.approval_status == 5" :src="shenpi5" class="icon" /> <svg-icon v-else-if="item.approval_status == 5" icon-class="shenpi5" class="icon" />
</div> </div>
</div> </div>
<!-- 审批进度 --> <!-- 审批进度 -->
......
import { getRoleRecentActivityNotPushNumApi } from '@/api/game';
// 账号近期要开活动数
let roleRecentActivityNotPushNum = null;
let cacheMemberId = null; //缓存请求id
const computedMap = new Map([]); //观察者列表
// 观察者收集
export function roleRecentActivitySubscription(fn, key) {
computedMap.set(key, fn);
}
//通知所有观察者
function roleRecentActivityRelease() {
computedMap.forEach((fn) => {
fn(roleRecentActivityNotPushNum);
});
}
function setCacheMemberId(member_id) {
cacheMemberId = member_id;
}
//获取数据
export async function queryRoleRecentActivityNotPushNum(
member_id = cacheMemberId
) {
const { data } = await getRoleRecentActivityNotPushNumApi({
member_id: member_id,
});
roleRecentActivityNotPushNum = data.data;
roleRecentActivityRelease();
}
function validate(v) {
if (!roleRecentActivityNotPushNum)
console.log(new Error(`执行${v},但是数据为空`));
}
//获取总数量
export function getTotalNum() {
validate('getTotalNum');
return roleRecentActivityNotPushNum?.totalNum || null;
}
//获取列表
export function getRoleNum() {
validate('getRoleNum');
return roleRecentActivityNotPushNum?.roleNum;
}
//销毁
export function destroy() {
roleRecentActivityNotPushNum = null;
cacheMemberId = null;
computedMap.clear();
}
//初始化
export async function createRoleRecentActivityNotPushNum(member_id) {
if (member_id && member_id !== cacheMemberId) {
setCacheMemberId(member_id);
await queryRoleRecentActivityNotPushNum(member_id);
}
return {
roleRecentActivitySubscription,
queryRoleRecentActivityNotPushNum,
getTotalNum,
getRoleNum,
destroy,
};
}
<template>
<div v-loading="loading">
<div class="px-[20px] h-full space-y-[8px] rounded-[4px] overflow-y-auto">
<template v-if="list.length">
<div
class="bg-[#F7F8FA] min-h-[99px] p-[8px]"
v-for="item in list"
:key="item.id"
>
<div
class="text-[#131920] pb-[8px] text-[14px] border-b-[1px] border-solid border-[#E5E5E6]"
>
<div>{{ item.name }}活动</div>
<div class="text-[#86909C] text-[12px]">
主服 {{ item.main_server_day }} 天开启
</div>
</div>
<div class="text-[13px] flex pt-[8px]">
<!-- <div class="text-[#6D7176] mr-[16px] flex-shrink-0">活动详情</div> -->
<div class="text-[#131920]">{{ item.detail }}</div>
</div>
</div>
</template>
<svg-icon v-else icon-class="noContent" class="text-[280px]" />
</div>
</div>
</template>
<script>
import { mapState } from 'vuex';
import { getRecentActivityListApi } from '@/api/game';
export default {
name: 'ActivityConfigurationList',
components: {},
props: ['role_id'],
data() {
return {
list: [],
loading: false,
};
},
computed: {
...mapState('game', ['gameUserInfo']),
},
methods: {
async getRecentActivityList() {
try {
this.loading = true;
const { data } = await getRecentActivityListApi({
role_id: this.role_id,
main_game_id: this.gameUserInfo.main_game_id,
weixin_blongs_id: this.gameUserInfo.weixin_blongs_id,
});
this.list = data.data;
} catch (error) {
} finally {
this.loading = false;
}
},
},
created() {
this.getRecentActivityList();
},
};
</script>
<style lang="scss" scoped></style>
<!--
* @Author: maoxiya 937667504@qq.com
* @Date: 2025-09-03 14:05:20
* @LastEditors: maoxiya 937667504@qq.com
* @LastEditTime: 2025-09-05 16:35:19
* @FilePath: /company_app/src/views/popup/RecentActivitiesPopup/components/RecentActivitiesList.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
<div v-loading="loading">
<div class="px-[20px] h-full gap-y-[8px] overflow-y-auto">
<template v-if="list.length">
<RecentActivities @handleUpdate="query" :item="item" v-for="item in list" :key="item.activity_rule_id" />
</template>
<svg-icon v-else icon-class="noContent" class="text-[280px]" />
</div>
</div>
</template>
<script>
import RecentActivities from '@/views/popup/RecentActivitiesPopup/templates/RecentActivities.vue';
import { getRoleRecentActivityListApi } from '@/api/game';
export default {
name: 'RecentActivitiesList',
components: { RecentActivities },
props: ['role_id'],
data() {
return {
list: [],
loading: false,
};
},
methods: {
async query() {
try {
this.loading = true;
const { data } = await getRoleRecentActivityListApi({
role_id: this.role_id,
});
this.list = data.data.reverse()
} catch (error) {
} finally {
this.loading = false;
}
},
},
created() {
this.query();
},
};
</script>
<style lang="scss" scoped></style>
// utils/componentHelper.js 或 useCreatePlayerDetails.js
import Vue from 'vue'
import RecentActivitiesPopup from './index.vue'
import store from '@/store' // 导入你的 Vuex store
export function createDetails(propsData = {}) {
const ComponentConstructor = Vue.extend(RecentActivitiesPopup)
const instance = new ComponentConstructor({
propsData,
// 手动注入 store
store
})
const mountNode = document.createElement('div')
document.querySelector('#recentActivitiesPopup').appendChild(mountNode)
instance.$mount(mountNode)
return {
instance,
destroy: () => {
instance.$destroy()
if (instance.$el && instance.$el.parentNode) {
instance.$el.parentNode.removeChild(instance.$el)
}
}
}
}
\ No newline at end of file
<template>
<div class="absolute z-10 top-0 left-0 h-full w-full bg-white" v-if="show">
<div
class="h-[60px] relative px-[18px] flex items-center border-b-[1px] border-solid border-[#e5e6eb]"
>
<i
class="el-icon-arrow-left text-[25px] hover:cursor-pointer"
@click="close"
></i>
<span
class="absolute left-1/2 top-1/2 transform -translate-x-1/2 -translate-y-1/2 text-[#323335] font-bold"
>{{ title }}</span
>
</div>
<el-tabs class="h-[40px]" v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="近期要开" name="0"> </el-tab-pane>
<el-tab-pane label="活动配置" name="1"> </el-tab-pane>
</el-tabs>
<RecentActivitiesList v-if="activeName === '0'" :role_id="role_id" />
<ActivityConfigurationList v-if="activeName === '1'" :role_id="role_id" />
</div>
</template>
<script>
import RecentActivitiesList from './components/RecentActivitiesList.vue';
import ActivityConfigurationList from './components/ActivityConfigurationList.vue';
export default {
name: 'RecentActivitiesPopup',
components: { RecentActivitiesList, ActivityConfigurationList },
data() {
return {
show: false,
activeName: '0',
role_id: '',
title: '',
};
},
methods: {
open(role_id, title) {
this.show = true;
this.role_id = role_id;
this.title = title;
},
handleClick() {},
close() {
this.show = false;
this.activeName = '0';
},
},
created() {},
};
</script>
<style lang="scss" scoped>
::v-deep .el-tabs__item {
padding: 0 20px !important;
}
</style>
<template>
<div
class="space-y-[12px] mt-[10px] !p-[8px] bg-[#F7F8FA] rounded-[4px] item"
>
<div>
<span class="label">近期要开:</span>
<el-popover
placement="top-start"
width="250"
trigger="hover"
:content="item.activity_rule_detail"
>
<span slot="reference">{{ item.activity_rule_name }}</span>
</el-popover>
</div>
<div>
<span class="label">开启时间:</span
><span>{{ item.open_activity_time }}</span>
</div>
<div>
<span class="label">关联客服:</span><span>{{ item.cser_name }}</span>
</div>
<div class="group flex items-center">
<span class="label flex-shrink-0">备注:</span
><span v-show="!editShow">{{ item.remark }}</span>
<el-input
@blur="updated"
v-show="editShow"
type="textarea"
:rows="2"
placeholder="请输入内容"
v-model.trim="textarea"
>
</el-input>
<svg-icon
icon-class="edit"
class="icon invisible group-hover:visible"
style="font-size: 14px"
@click="editRemark"
/>
</div>
<div class="flex items-center">
<span class="label flex-shrink-0">推送状态:</span>
<span v-if="item.is_push === '2'">已推送</span>
<el-select
v-else
class="w-[70px]"
:clearable="false"
:value="item.is_push"
@change="handleChange"
>
<el-option label="未推送" value="1"> </el-option>
<el-option label="已推送" value="2"> </el-option>
</el-select>
</div>
<div class="flex items-center">
<span class="label flex-shrink-0">推送话术:</span>
<span
class="group flex-1 w-0 flex items-center"
v-if="pushLanguageTechnique"
>
<el-popover
placement="bottom"
class="flex-1 flex w-0 speak"
width="250"
trigger="click"
>
<p class="max-h-[300px] overflow-y-auto">
{{ pushLanguageTechnique }}
</p>
<span class="truncate flex-1" slot="reference">{{
pushLanguageTechnique
}}</span>
</el-popover>
<i
class="el-icon-refresh mr-[8px] refreshList invisible group-hover:visible"
:class="isRefresh ? 'refreshListActive' : ''"
@click="refreshTag"
></i>
<svg-icon
icon-class="fuzhi"
class="icon invisible group-hover:visible"
style="font-size: 14px"
@click="copyText"
/>
</span>
<el-button
v-else
size="mini"
@click="queryGenerateProcedure(0)"
:loading="isRefresh"
>生成话术</el-button
>
</div>
<slot></slot>
</div>
</template>
<script>
import { getRoleRecentActivityEditApi } from '@/api/game.js';
import { getGenerateProcedureApi } from '@/api/skill';
import { mapState } from 'vuex';
import { queryRoleRecentActivityNotPushNum } from '@/views/hooks/useGetCount';
import { corp_activity_procedure_copyUsed } from '@/api/works';
const UpdateType = {
PUSH: 1, //修改推送
REMARK: 2, //修改备注
};
export default {
name: 'RecentActivitiesTemplate',
emits: ['handleUpdate'],
components: {},
props: ['item'],
data() {
return {
editShow: false,
textarea: '',
isRefresh: false,
pushLanguageTechnique: '', //推送话术
};
},
computed: {
...mapState('user', ['cser_id', 'cser_name']),
...mapState('game', ['accountSelect', 'bindGameUserList']),
nowGameUserInfo() {
return {
member_id: this.accountSelect,
username: this.bindGameUserList.find(
(item) => item.member_id == this.accountSelect
)?.username,
};
},
},
methods: {
editRemark() {
this.editShow = true;
this.textarea = this.item.remark;
},
async updated() {
this.editShow = false;
if (this.textarea === this.item.remark) return;
this.edit(UpdateType.REMARK);
},
handleChange() {
this.edit(UpdateType.PUSH);
},
async edit(type) {
try {
await getRoleRecentActivityEditApi({
type,
role_id: this.item.role_id,
open_activity_time: this.item.open_activity_time,
remark: this.textarea,
activity_rule_id: this.item.activity_rule_id,
is_push: 2,
user_id: this.cser_id,
user_name: this.cser_name,
});
this.$message.success('修改成功');
queryRoleRecentActivityNotPushNum(this.accountSelect);
this.$emit('handleUpdate');
} catch (error) {
this.$message.error(error);
}
},
async queryGenerateProcedure(is_regenerate) {
try {
this.isRefresh = true;
const { data } = await getGenerateProcedureApi({
...this.item,
...this.nowGameUserInfo,
is_regenerate,
});
this.pushLanguageTechnique = data.content;
this._id = data._id;
} catch (error) {
} finally {
this.isRefresh = false;
}
},
async copyText() {
try {
corp_activity_procedure_copyUsed({ _id: this._id });
await navigator.clipboard.writeText(this.pushLanguageTechnique);
this.$message.success('复制成功');
} catch (err) {
console.error('复制失败:', err);
}
},
refreshTag() {
this.queryGenerateProcedure(1);
},
},
created() {
console.log(this.nowGameUserInfo, 1111111);
},
};
</script>
<style lang="scss" scoped>
.item {
width: 100%;
height: auto;
font-size: 14px;
font-weight: 400;
color: #333333;
transition: all 0.5s;
position: relative;
cursor: pointer;
.label {
font-size: 14px;
color: #999999;
font-weight: 500;
margin-right: 8px;
}
.tag-icon {
cursor: pointer;
font-size: 14px;
color: #333333;
margin-right: 8px;
}
}
.refreshListActive {
animation: rotate 0.5s linear infinite;
}
.refreshList {
color: #3491fa;
cursor: pointer;
font-size: 18px;
}
::v-deep .el-input__inner {
background-color: transparent;
border: 0;
box-shadow: none;
padding: 0;
}
::v-deep .el-select .el-input.is-focus .el-input__inner {
border-color: transparent !important;
box-shadow: none;
}
::v-deep .speak .el-popover__reference-wrapper {
display: flex;
flex: 1;
width: 0;
}
</style>
<!--
* @Author: maoxiya 937667504@qq.com
* @Date: 2025-06-25 16:46:39
* @LastEditors: maoxiya 937667504@qq.com
* @LastEditTime: 2025-09-02 14:16:38
* @FilePath: /company_app/src/views/roleInfo.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template> <template>
<div class="roleTab"> <div class="roleTab">
<el-tabs v-model="roleActive"> <el-tabs v-model="roleActive">
<el-tab-pane label="角色信息" name="roleInfo"> <el-tab-pane label="角色信息" name="roleInfo">
<roleInfoPanel v-if="roleActive === 'roleInfo'" :chatUserDetails="chatUserInfo" /> <roleInfoPanel
</el-tab-pane> v-if="roleActive === 'roleInfo'"
<el-tab-pane label="举报信息" name="report"> :chatUserDetails="chatUserInfo"
<report v-if="roleActive === 'report'" /> />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="申诉记录" name="approval"> <el-tab-pane label="申诉记录" name="approval">
<approval v-if="roleActive === 'approval'" /> <approval v-if="roleActive === 'approval'" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="违规记录" name="violation">
<violationRecord v-if="roleActive === 'violation'" />
</el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
</template> </template>
<script> <script>
import roleInfoPanel from './components/roleInfo/roleInfoPanel.vue' import roleInfoPanel from './components/roleInfo/roleInfoPanel.vue';
import report from './components/roleInfo/report.vue' import approval from './components/roleInfo/approval.vue';
import approval from './components/roleInfo/approval.vue' import { mapState } from 'vuex';
import { mapState } from 'vuex' import violationRecord from '@/views/ViolationRecord.vue';
export default { export default {
name: 'roleInfo', name: 'roleInfo',
components: { components: {
roleInfoPanel, roleInfoPanel,
approval, approval,
report violationRecord,
}, },
computed: { computed: {
...mapState('game', ['chatUserInfo']) ...mapState('game', ['chatUserInfo']),
}, },
props: { props: {
// report_is_send: { // report_is_send: {
...@@ -37,16 +49,13 @@ export default { ...@@ -37,16 +49,13 @@ export default {
}, },
data() { data() {
return { return {
roleActive: 'roleInfo' roleActive: 'roleInfo',
};
}
}, },
methods: { methods: {
handleClick(value) { handleClick(value) {},
},
} };
}
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.roleTab { .roleTab {
...@@ -70,12 +79,12 @@ export default { ...@@ -70,12 +79,12 @@ export default {
color: #333333; color: #333333;
&.is-active { &.is-active {
color: #3491FA; color: #3491fa;
} }
} }
.el-tabs__active-bar { .el-tabs__active-bar {
background-color: #3491FA; background-color: #3491fa;
height: 3px; height: 3px;
border-radius: 1.5px; border-radius: 1.5px;
} }
...@@ -92,7 +101,7 @@ export default { ...@@ -92,7 +101,7 @@ export default {
.el-tabs__content { .el-tabs__content {
height: calc(100% - 40px); height: calc(100% - 40px);
padding: 15px; padding: 0 5px 5px;
} }
} }
} }
......
<template>
<!-- 营销面板组件 -->
<div class="item">
<div class="rowFlex columnCenter">
<span class="label">营销面板:</span>
<i
v-if="recentInfo.role_id"
:class="['el-icon-arrow-' + (active ? 'down' : 'right'), 'tag-icon']"
@click="handleClick"
></i>
</div>
<RecentActivities
v-if="recentInfo.role_id"
:item="recentInfo"
v-show="active"
@handleUpdate="getRoleData"
>
<el-button
type="text"
size="mini"
@click="
() =>
recentActivitiesPopupInstance.instance.open(
recentInfo.role_id,
popupTitle
)
"
>
查看更多 >
</el-button>
</RecentActivities>
</div>
</template>
<script>
import RecentActivities from '@/views/popup/RecentActivitiesPopup/templates/RecentActivities.vue';
import { createDetails } from '@/views/popup/RecentActivitiesPopup/index.js';
import { getRoleRecentActivityOneApi } from '@/api/game';
import { getRoleHoLo } from '@/api/game';
import { mapState } from 'vuex';
export default {
name: 'MarketingPanel',
components: { RecentActivities },
data() {
return {
active: true,
recentActivitiesPopupInstance: null, //近期要开模块弹框
recentInfo: {},
roleInfoList: [],
};
},
computed: {
...mapState('game', ['accountSelect']),
popupTitle() {
const findItem = this.roleInfoList.find(
(item) => item.role_id == this.recentInfo.role_id
);
if (findItem) {
return `${findItem.role_name}-${findItem.server_name}-${findItem.recharge_total}元`;
}
return;
},
},
methods: {
async queryGetRoleHoLo() {
const { data } = await getRoleHoLo({
page_size: 100,
page: 1,
member_id: this.accountSelect,
search_type: 'list',
});
this.roleInfoList = data.data;
},
handleClick() {
this.active = !this.active;
},
async getRoleData() {
const { data } = await getRoleRecentActivityOneApi({
member_id: this.accountSelect,
});
this.recentInfo = data.data;
},
},
created() {
this.getRoleData();
this.queryGetRoleHoLo();
},
mounted() {
this.recentActivitiesPopupInstance = createDetails({
gameUserInfoInject: this.gameUserInfoInject,
});
},
beforeDestroy() {
this.recentActivitiesPopupInstance.destroy();
},
};
</script>
<style lang="scss" scoped>
.item {
width: 100%;
height: auto;
font-size: 14px;
padding: 16px;
font-weight: 400;
color: #333333;
padding: 10px 0;
transition: all 0.5s;
position: relative;
cursor: pointer;
.label {
font-size: 14px;
color: #999999;
font-weight: 500;
margin-right: 8px;
}
.tag-icon {
cursor: pointer;
font-size: 14px;
color: #333333;
margin-right: 8px;
}
}
.refreshListActive {
animation: rotate 0.5s linear infinite;
}
.refreshList {
color: #3491fa;
cursor: pointer;
font-size: 18px;
}
</style>
<template> <template>
<div class="userInfo-content"> <div class="userInfo-content relative" id="recentActivitiesPopup">
<el-tabs v-model="activeTab" class="user-tabs"> <el-tabs v-model="activeTab" class="user-tabs">
<el-tab-pane label="客户信息" name="info"> <el-tab-pane label="客户信息" name="info">
<Info :chatUserDetails="chatUserInfo"/> <Info :chatUserDetails="chatUserInfo" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="角色信息" name="role"> <el-tab-pane label="角色信息" name="role">
<template #label v-if="totalNum">
<el-badge :value="totalNum" class="text-center">
<p>角色信息</p>
</el-badge>
</template>
<roleInfo v-if="activeTab === 'role'" /> <roleInfo v-if="activeTab === 'role'" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="订单信息" name="order"> <el-tab-pane label="订单信息" name="order">
<orderList v-if="activeTab === 'order'" /> <orderList v-if="activeTab === 'order'" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="违规记录" name="violation">
<violationRecord v-if="activeTab === 'violation'" />
</el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
</template> </template>
<script> <script>
import Info from './components/Info.vue' import Info from './components/Info.vue';
import roleInfo from '@/views/roleInfo.vue' import roleInfo from '@/views/roleInfo.vue';
import orderList from '@/views/orderList.vue' import orderList from '@/views/orderList.vue';
import violationRecord from '@/views/ViolationRecord.vue' import { mapState, mapMutations } from 'vuex';
import { mapState, mapMutations } from 'vuex' import { createRoleRecentActivityNotPushNum } from '@/views/hooks/useGetCount';
import Cookies from 'js-cookie' import Cookies from 'js-cookie';
export default { export default {
name: 'userInfo', name: 'userInfo',
components: { components: {
Info, Info,
roleInfo, roleInfo,
orderList, orderList,
violationRecord
}, },
mounted() { watch: {
async accountSelect(newVal) {
await this.initInstance();
},
}, },
data() { data() {
return { return {
activeTab: 'info' activeTab: 'info',
} instance: null,
totalNum: 0,
};
}, },
computed: { computed: {
...mapState('game', ['chatUserInfo']), ...mapState('game', ['chatUserInfo', 'accountSelect']),
}, },
created() { created() {
// 初始化 vuex 中的值 // 初始化 vuex 中的值
this.initInstance();
}, },
mounted() { mounted() {
this.$nextTick(() => { this.$nextTick(() => {
this.initVuexValue() this.initVuexValue();
}) });
}, },
methods: { methods: {
...mapMutations('user', ['set_userInfo']), ...mapMutations('user', ['set_userInfo']),
initVuexValue(){ async initInstance() {
this.instance = await createRoleRecentActivityNotPushNum(
this.accountSelect
);
this.totalNum = this.instance.getTotalNum();
this.instance.roleRecentActivitySubscription(() => {
this.totalNum = this.instance.getTotalNum();
}, this);
},
initVuexValue() {
const userinfo = { const userinfo = {
cser_id: Cookies.get('cser_id'), cser_id: Cookies.get('cser_id'),
cser_name: Cookies.get('cser_name'), cser_name: Cookies.get('cser_name'),
username: Cookies.get('cser_name'), username: Cookies.get('cser_name'),
id: Cookies.get('cser_id'), id: Cookies.get('cser_id'),
} };
this.set_userInfo(userinfo) this.set_userInfo(userinfo);
} },
},
} beforeDestroy() {
} this.instance && this.instance.destroy();
},
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
...@@ -99,4 +118,9 @@ export default { ...@@ -99,4 +118,9 @@ export default {
} }
} }
} }
::v-deep .el-badge__content.is-fixed {
top: 8px;
right: 6px;
}
</style> </style>
/*
* @Author: maoxiya 937667504@qq.com
* @Date: 2025-08-30 10:54:21
* @LastEditors: maoxiya 937667504@qq.com
* @LastEditTime: 2025-08-30 10:54:29
* @FilePath: /company_app/tailwind.config.js
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
module.exports = {
mode: 'jit', // 关键配置
purge: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
darkMode: false,
theme: {
extend: {}
},
variants: {
extend: {}
},
plugins: [
function({ addUtilities }) {
const newUtilities = {
'.truncate-2': {
display: '-webkit-box',
'-webkit-box-orient': 'vertical',
'-webkit-line-clamp': '2',
'overflow': 'hidden',
'text-overflow': 'ellipsis',
'word-wrap': 'break-word',
'word-break': 'break-word',
},
'.truncate-3': {
display: '-webkit-box',
'-webkit-box-orient': 'vertical',
'-webkit-line-clamp': '3',
'overflow': 'hidden',
'text-overflow': 'ellipsis',
'word-wrap': 'break-word',
'word-break': 'break-word',
}
}
addUtilities(newUtilities, ['responsive', 'hover'])
}
],
corePlugins: {
container: false // 禁用默认的 container
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论