提交 7af060b5 作者: 毛细亚

合并分支 '7.2' 到 'release'

7.2

查看合并请求 !49
...@@ -1538,3 +1538,61 @@ export function teachingVideoVideoListApi(data) { ...@@ -1538,3 +1538,61 @@ export function teachingVideoVideoListApi(data) {
}) })
}) })
} }
// 发送分身包
export function memberRegGameCloneLink(data) {
return new Promise((resolve, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/member/memberRegGameCloneLink',
params: data
}).then((res) => {
resolve(res)
}).catch((error) => {
reject(error)
})
})
}
// 带教记录列表
export function roleTeachingList(data) {
return new Promise((resolve, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/role/roleTeachingList',
params: data
}).then((res) => {
resolve(res)
}).catch((error) => {
reject(error)
})
})
}
// 新增带教
export function roleTeachingAdd(data) {
return new Promise((resolve, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/role/roleTeachingAdd',
params: data
}).then((res) => {
resolve(res)
}).catch((error) => {
reject(error)
})
})
}
// 获取带教次数
export function roleTeachingNum(data) {
return new Promise((resolve, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/role/roleTeachingNum',
params: data
}).then((res) => {
resolve(res)
}).catch((error) => {
reject(error)
})
})
}
<svg t="1765950660083" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5445" width="200" height="200"><path d="M512 938.666667C276.362667 938.666667 85.333333 747.637333 85.333333 512S276.362667 85.333333 512 85.333333s426.666667 191.029333 426.666667 426.666667-191.029333 426.666667-426.666667 426.666667z m0-64c200.298667 0 362.666667-162.368 362.666667-362.666667S712.298667 149.333333 512 149.333333 149.333333 311.701333 149.333333 512s162.368 362.666667 362.666667 362.666667z" p-id="5446"></path></svg>
\ No newline at end of file
...@@ -75,11 +75,29 @@ const copy = { ...@@ -75,11 +75,29 @@ const copy = {
unbind: function(el) { unbind: function(el) {
// 清理事件监听器和元素 // 清理事件监听器和元素
if (el.__copyIcon) { if (el.__copyIcon) {
el.__copyIcon.removeEventListener('click', null) try {
el.parentNode.removeChild(el.__copyIcon) // 移除事件监听器
const clickHandler = el.__copyIcon.__clickHandler
if (clickHandler) {
el.__copyIcon.removeEventListener('click', clickHandler)
delete el.__copyIcon.__clickHandler
}
// 安全地移除图标元素
if (el.__copyIcon && el.__copyIcon.parentNode) {
el.__copyIcon.parentNode.removeChild(el.__copyIcon)
} else if (el.__copyIcon && el.__copyIcon.remove) {
// 如果节点还在DOM中,使用 remove() 方法
el.__copyIcon.remove()
}
} catch (error) {
// 忽略移除节点时的错误,可能节点已经被移除了
console.warn('移除复制图标时出错:', error)
} finally {
delete el.__copyIcon delete el.__copyIcon
} }
} }
}
} }
export default copy export default copy
\ No newline at end of file
...@@ -97,6 +97,12 @@ ...@@ -97,6 +97,12 @@
> >
下载二维码 下载二维码
</p> </p>
<!-- h5 安卓游戏 IOS游戏 发送分身包 -->
<div v-if="[2].includes(item.game_type)">
<p class="sendLink" @click="sendTransferCloneGame(2,items)">发送分身包-H5</p>
<p class="sendLink" @click="sendTransferCloneGame(3,items)">发送分身包-安卓</p>
<p class="sendLink" @click="sendTransferCloneGame(4,items)">发送分身包-IOS</p>
</div>
</div> </div>
<el-button <el-button
slot="reference" slot="reference"
...@@ -279,48 +285,23 @@ ...@@ -279,48 +285,23 @@
<p>{{ items.label + "/" + items.id }}</p> <p>{{ items.label + "/" + items.id }}</p>
<!--game_type: 1 微信小游戏 2 H5 游戏 3 安卓游戏 4 IOS 游戏 5 抖音小游戏 --> <!--game_type: 1 微信小游戏 2 H5 游戏 3 安卓游戏 4 IOS 游戏 5 抖音小游戏 -->
<!-- 微信小游戏 安卓游戏 IOS游戏 处理逻辑 --> <!-- 微信小游戏 安卓游戏 IOS游戏 处理逻辑 -->
<el-popover <el-popover v-if="items.game_type == 1 || items.game_type == 3 || items.game_type == 4 || items.game_type == 5" placement="top" trigger="click">
v-if=" <div v-if="items.game_type!=5">
items.game_type == 1 || <p class="sendLink" @click="sendChannelGame(items, item)">发送链接/渠道二维码</p>
items.game_type == 3 || <p class="sendLink" @click="handleGameType(items, item, item.game_type, index)">发送落地页</p>
items.game_type == 4
"
placement="top"
trigger="click"
>
<p class="sendLink" @click="sendChannelGame(items, item)">
发送链接/渠道二维码
</p>
<p
class="sendLink"
@click="
handleGameType(items, item, item.game_type, index)
"
>
发送落地页
</p>
<div v-if="items.game_type == 1"> <div v-if="items.game_type == 1">
<!-- 发送 H5 安卓分身包 --> <!-- 发送 H5 安卓分身包 -->
<p <p class="sendLink" @click="sendH5CloneGame(items, 'android')">发送H5-安卓分身包</p>
class="sendLink"
@click="sendH5CloneGame(items, 'android')"
>
发送H5-安卓分身包
</p>
<!-- 发送 H5 IOS 分身包 --> <!-- 发送 H5 IOS 分身包 -->
<p <p class="sendLink" @click="sendH5CloneGame(items, 'ios')">发送H5-IOS分身包</p>
class="sendLink"
@click="sendH5CloneGame(items, 'ios')"
>
发送H5-IOS分身包
</p>
</div> </div>
<el-button </div>
slot="reference" <!-- 抖音小游戏发送落地页 -->
size="mini" <div v-else>
:disabled="accountSelect == ''" <p class="sendLink" @click="handleGameType(items, item, item.game_type, index)">发送落地页</p>
>发送</el-button </div>
> <el-button slot="reference" size="mini" :disabled="accountSelect == ''">发送</el-button>
</el-popover> </el-popover>
<el-button <el-button
v-else v-else
...@@ -426,6 +407,7 @@ import { ...@@ -426,6 +407,7 @@ import {
getClonePackageLink, getClonePackageLink,
getLandingPageConfig, getLandingPageConfig,
getMemberTransStatus, getMemberTransStatus,
memberRegGameCloneLink
} from "@/api/game"; } from "@/api/game";
import { import {
getRecentSendLog, getRecentSendLog,
...@@ -492,6 +474,7 @@ export default { ...@@ -492,6 +474,7 @@ export default {
showSendChannel: false, showSendChannel: false,
channelInfoList: {}, channelInfoList: {},
transMemberStatus: true, transMemberStatus: true,
h5CloneGameInfo: {},
qrCodeValue: "", // 二维码内容 qrCodeValue: "", // 二维码内容
qrCodeSize: 200, // 二维码大小 qrCodeSize: 200, // 二维码大小
}; };
...@@ -1035,13 +1018,6 @@ export default { ...@@ -1035,13 +1018,6 @@ export default {
).username; ).username;
passwardEncryption({ member_id: this.accountSelect }) passwardEncryption({ member_id: this.accountSelect })
.then((res) => { .then((res) => {
// const list = [
// {
// msgtype: 'text',
// text: { content: `账号:${username} \n密码:${res.data.password}`, key: res.data.key, iv: res.data.iv }
// }
// ]
// this.set_sendSkillMessage(list)
this.sendChatMessage( this.sendChatMessage(
`账号:${username} \n密码:${res.data.password}`, `账号:${username} \n密码:${res.data.password}`,
"text" "text"
...@@ -1053,7 +1029,6 @@ export default { ...@@ -1053,7 +1029,6 @@ export default {
const list = [ const list = [
{ msgtype: "text", text: { content: `账号:${username}` } }, { msgtype: "text", text: { content: `账号:${username}` } },
]; ];
// this.set_sendSkillMessage(list)
this.sendChatMessage(`账号:${username}`, "text"); this.sendChatMessage(`账号:${username}`, "text");
item.type = 1; item.type = 1;
this.sendGameLog(item); this.sendGameLog(item);
...@@ -1094,7 +1069,6 @@ export default { ...@@ -1094,7 +1069,6 @@ export default {
}, },
}, },
]; ];
// this.set_sendSkillMessage(list)
this.sendChatMessage( this.sendChatMessage(
`${str}${item.url} \n账号:${username} \n密码:${res.data.password}`, `${str}${item.url} \n账号:${username} \n密码:${res.data.password}`,
"text" "text"
...@@ -1110,7 +1084,6 @@ export default { ...@@ -1110,7 +1084,6 @@ export default {
text: { content: `${str}${item.url} \n账号:${username}` }, text: { content: `${str}${item.url} \n账号:${username}` },
}, },
]; ];
// this.set_sendSkillMessage(list)
this.sendChatMessage(`${str}${item.url} \n账号:${username}`, "text"); this.sendChatMessage(`${str}${item.url} \n账号:${username}`, "text");
this.sendGameLog(item); this.sendGameLog(item);
console.log(err); console.log(err);
...@@ -1119,7 +1092,6 @@ export default { ...@@ -1119,7 +1092,6 @@ export default {
// 发送游戏落地页 // 发送游戏落地页
startSendPage(value) { startSendPage(value) {
console.log(value, "value"); console.log(value, "value");
// this.set_sendSkillMessage(list)
this.getMediaId(value, "image"); this.getMediaId(value, "image");
}, },
// 转端发送落地页面 // 转端发送落地页面
...@@ -1135,6 +1107,53 @@ export default { ...@@ -1135,6 +1107,53 @@ export default {
); );
this.showSendPage = true; this.showSendPage = true;
}, 500), }, 500),
// 转端发送游戏分身包 h5 安卓游戏 IOS游戏 发送分身包
async sendTransferCloneGame(type,items) {
if(!this.h5CloneGameInfo?.data?.h5_download_url){
this.h5CloneGameInfo = await memberRegGameCloneLink({ member_id: this.accountSelect ,game_id:items.game_id}) || {}
}
if (this.h5CloneGameInfo?.status_code == 1) {
// 通过 type 判断 用 switch
switch (type) {
case 2:
if (!this.h5CloneGameInfo?.data?.h5_download_url) {
this.$message.warning('H5安卓分身包链接不存在,请联系掌游配置')
return
}
break
case 3:
if (!this.h5CloneGameInfo?.data?.android_download_url) {
this.$message.warning('安卓分身包链接不存在,请联系掌游配置')
return
}
break
case 4:
if (!this.h5CloneGameInfo?.data?.ios_download_url) {
this.$message.warning('IOS分身包链接不存在,请联系掌游配置')
return
}
break
default:
this.$message.warning('不支持的游戏类型')
return
}
let srt = ''
switch (type) {
case 2:
srt = 'H5分身包链接: ' + this.h5CloneGameInfo?.data?.h5_download_url
break
case 3:
srt = '安卓分身包链接: ' + this.h5CloneGameInfo?.data?.android_download_url
break
case 4:
srt = 'IOS分身包链接: ' + this.h5CloneGameInfo?.data?.ios_download_url
break
}
this.sendChatMessage(srt, "text");
} else {
this.$message.warning(this.h5CloneGameInfo?.msg)
}
},
// 转端发送游戏二维码 // 转端发送游戏二维码
sendDownLoadQrCode: throttleStart(async function (items, type, index) { sendDownLoadQrCode: throttleStart(async function (items, type, index) {
if (!this.transMemberStatus) { if (!this.transMemberStatus) {
...@@ -1339,14 +1358,12 @@ export default { ...@@ -1339,14 +1358,12 @@ export default {
page: data.share_data.page, page: data.share_data.page,
imgUrl: data.share_data.share_img, imgUrl: data.share_data.share_img,
}; };
// this.set_sendSkillMessage(list)
this.sendChatMessage(miniprogramInfo, "miniprogram"); this.sendChatMessage(miniprogramInfo, "miniprogram");
const game_data = this.$clone(data.game_data); const game_data = this.$clone(data.game_data);
game_data.type = 3; game_data.type = 3;
console.log(game_data, "data----------"); console.log(game_data, "data----------");
this.sendGameLog(game_data); this.sendGameLog(game_data);
} else { } else {
// this.set_sendSkillMessage(list)
this.getMediaId(data.game_data.game_url, "image"); this.getMediaId(data.game_data.game_url, "image");
this.sendGameLog(data.game_data); this.sendGameLog(data.game_data);
} }
...@@ -1399,8 +1416,6 @@ export default { ...@@ -1399,8 +1416,6 @@ export default {
}, },
}, },
]; ];
// 这里需要特殊处理,因为有taskInfo参数
// this.set_sendSkillMessage(list)
this.sendChatMessage( this.sendChatMessage(
`${str}${item.game_url} \n账号:${username} \n密码:${res.data.password}`, `${str}${item.game_url} \n账号:${username} \n密码:${res.data.password}`,
"text" "text"
...@@ -1414,12 +1429,7 @@ export default { ...@@ -1414,12 +1429,7 @@ export default {
const params = { const params = {
main_game_id: items.main_game_id, main_game_id: items.main_game_id,
weixin_blongs_id: items.weixin_blongs_id, weixin_blongs_id: items.weixin_blongs_id,
type: type: items.game_type == 1 || items.game_type == 5 ? 2 : items.game_type == 3 || items.game_type == 4 ? 1 : ''
items.game_type == 1
? 2
: items.game_type == 3 || items.game_type == 4
? 1
: "",
}; };
const res = await getLandingPageConfig(params); const res = await getLandingPageConfig(params);
if (res.status_code === 1 && res.data) { if (res.status_code === 1 && res.data) {
...@@ -1511,16 +1521,10 @@ export default { ...@@ -1511,16 +1521,10 @@ export default {
}, },
// 主方法 // 主方法
async handleGameType(items, item, type, index) { async handleGameType(items, item, type, index) {
if ( if ((items.game_type == 1 || items.game_type == 3 || items.game_type == 4 || items.game_type == 5) && items.main_game_id && items.weixin_blongs_id) {
(items.game_type == 1 ||
items.game_type == 3 ||
items.game_type == 4) &&
items.main_game_id &&
items.weixin_blongs_id
) {
const result = await this.getLandingPageConfig(items, item); const result = await this.getLandingPageConfig(items, item);
if (result && result.data?.data?.tag) { if (result && result.data?.data?.tag) {
if (items.game_type == 1) { if (items.game_type == 1 || items.game_type == 5) {
// 处理微信小程序游戏 // 处理微信小程序游戏
this.handleWechatMiniGame(items, item, index); this.handleWechatMiniGame(items, item, index);
} else { } else {
...@@ -1541,15 +1545,6 @@ export default { ...@@ -1541,15 +1545,6 @@ export default {
// 小游戏游戏确认 // 小游戏游戏确认
async handleWxGameConfirm(value) { async handleWxGameConfirm(value) {
console.log(value, "value"); console.log(value, "value");
// const list = [
// {
// msgtype: 'image',
// image: {
// picurl: value
// }
// }
// ]
// this.set_sendSkillMessage(list)
this.getMediaId(value, "image"); this.getMediaId(value, "image");
}, },
SendTransAppGameClose() { SendTransAppGameClose() {
...@@ -1561,15 +1556,6 @@ export default { ...@@ -1561,15 +1556,6 @@ export default {
// 安卓或者 IOS 游戏处理 // 安卓或者 IOS 游戏处理
handleAppGameConfirm(data) { handleAppGameConfirm(data) {
this.selectedAppGameList = []; this.selectedAppGameList = [];
// const list = [
// {
// msgtype: 'text',
// text: {
// content: `游戏地址:${data.landing_page_url} \n账号:${data.username} \n密码:${data.password}`
// }
// }
// ]
// this.set_sendSkillMessage(list)
this.sendChatMessage( this.sendChatMessage(
`游戏地址:${data.landing_page_url} \n账号:${data.username} \n密码:${data.password}`, `游戏地址:${data.landing_page_url} \n账号:${data.username} \n密码:${data.password}`,
"text" "text"
......
...@@ -326,6 +326,7 @@ ...@@ -326,6 +326,7 @@
this.$emit('confirm', res.data.data) this.$emit('confirm', res.data.data)
this.$message.success('发送成功') this.$message.success('发送成功')
} }
} catch (error) { } catch (error) {
this.loading = false this.loading = false
console.error('获取链接失败:', error) console.error('获取链接失败:', error)
......
...@@ -3,18 +3,20 @@ ...@@ -3,18 +3,20 @@
<el-drawer <el-drawer
title="选择游戏" title="选择游戏"
:visible="show" :visible="show"
size="360px" size="80%"
append-to-body
@close="close" @close="close"
> >
<div class="sendTransWxGame">
<el-form ref="wxGameForm" :model="wxGameForm" :rules="wxGameRules" label-position="top" class="game-select-container"> <el-form ref="wxGameForm" :model="wxGameForm" :rules="wxGameRules" label-position="top" class="game-select-container">
<!-- 微信小游戏 --> <!-- 微信/抖音小游戏 -->
<el-form-item label=""> <el-form-item label="">
<template slot="label"> <template slot="label">
<p class="formLabel">微信小游戏</p> <p class="formLabel">微信/抖音小游戏</p>
</template> </template>
<el-select <el-select
v-model="wxGameForm.wx_game_send_id" v-model="wxGameForm.wx_game_send_id"
placeholder="请选择微信小游戏" placeholder="请选择微信/抖音小游戏"
style="width: 100%" style="width: 100%"
disabled disabled
> >
...@@ -27,22 +29,71 @@ ...@@ -27,22 +29,71 @@
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label=""> <el-form-item label="选择渠道">
<el-select <el-select
v-model="wxGameForm.wx_game_channel" v-model="wxGameForm.wx_game_channel"
placeholder="请选择渠道" placeholder="请选择渠道"
style="width: 100%" style="width: 100%"
:clearable="true" :clearable="true"
@change="handleChannelChange"
> >
<el-option <el-option
v-for="(item,index) in wxGameChannelList" v-for="(item,index) in wxGameChannelList"
:key="index" :key="item.key"
:label="item.name" :label="item.name"
:value="item.key" :value="item.key"
> >
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 选择背景图 新增背景图的选项 -->
<el-form-item v-if="backgroundImgsList.length > 0" label="" style="margin-bottom: 100px;">
<template slot="label">
<p class="formLabel">
<span class="required-mark">*</span>
<span>背景图</span>
</p>
</template>
<el-radio-group v-model="wxGameForm.selectedBackgroundIndex" @change="handleBackgroundChange">
<div class="background-options">
<el-radio
v-for="(item, index) in backgroundImgsList"
:key="item.background_img"
:label="index"
class="background-radio-item"
>
<div class="background-card">
<div class="background-preview-wrapper">
<img
:ref="`bgImg_${index}`"
:src="item.background_img"
class="background-preview"
alt="背景图预览"
@load="handleBackgroundImageLoad(index, item)"
>
<!-- 二维码叠加显示 -->
<img
v-if="channelQrcode && item.qrStyle"
:src="channelQrcode"
class="background-qrcode"
:style="item.qrStyle"
alt="二维码"
>
</div>
<!-- 左上角小眼睛图标 -->
<div class="eye-icon" :class="{'eye-icon-checked': wxGameForm.selectedBackgroundIndex === index}" @click.stop="showPreview(item, index)">
<i class="el-icon-view"></i>
</div>
<!-- 右上角选中/未选中图标 -->
<div class="status-icon">
<i v-if="wxGameForm.selectedBackgroundIndex === index" class="el-icon-success status-icon-checked"></i>
<svg-icon v-else icon-class="uncheck" class="status-icon-unchecked"></svg-icon>
</div>
</div>
</el-radio>
</div>
</el-radio-group>
</el-form-item>
</el-form> </el-form>
<span class="dialog-footer rowFlex"> <span class="dialog-footer rowFlex">
<el-button class="btn" @click="close" size="small">取消</el-button> <el-button class="btn" @click="close" size="small">取消</el-button>
...@@ -75,6 +126,40 @@ ...@@ -75,6 +126,40 @@
> >
</div> </div>
</div> </div>
<!-- 大图预览弹窗 -->
<el-drawer
title="预览"
:visible.sync="previewVisible"
size="80%"
:modal="false"
:close-on-click-modal="false"
append-to-body
class="preview-dialog"
>
<div class="preview-content">
<div class="preview-wrapper" v-if="previewImageInfo">
<img
ref="previewBgImgDisplay"
:src="previewImageInfo.background_img"
class="preview-background"
alt="背景图"
@load="handlePreviewImageLoad"
>
<img
v-if="previewImageInfo.channel_qrcode"
ref="previewQrImgDisplay"
:src="previewImageInfo.channel_qrcode"
class="preview-qrcode"
:style="previewQrcodeStyle"
alt="二维码"
>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="previewVisible = false">关闭</el-button>
</span>
</el-drawer>
</div>
</el-drawer> </el-drawer>
</template> </template>
...@@ -119,14 +204,20 @@ ...@@ -119,14 +204,20 @@
wxGameForm: { wxGameForm: {
wx_game_send_id: '', wx_game_send_id: '',
wx_game_send_info: {}, wx_game_send_info: {},
wx_game_channel: '' wx_game_channel: '',
selectedBackgroundIndex: 0 // 选中的背景图索引
}, },
messageInfo: null, messageInfo: null,
handleConfirmWithDebounce: {}, handleConfirmWithDebounce: {},
wxGameChannelList: [], wxGameChannelList: [],
backgroundImgsList: [], // 背景图列表
channelQrcode: '', // 二维码链接
previewVisible: false, // 预览弹窗显示状态
previewImageInfo: null, // 预览图片信息(包含背景图和二维码)
previewQrcodeStyle: {}, // 预览二维码样式
wxGameRules: { wxGameRules: {
wx_game_send_id: [ wx_game_send_id: [
{ required: true, message: '请选择微信小游戏', trigger: 'change' } { required: true, message: '请选择微信/抖音小游戏', trigger: 'change' }
], ],
wx_game_channel: [ wx_game_channel: [
{ required: true, message: '请选择渠道', trigger: 'change' } { required: true, message: '请选择渠道', trigger: 'change' }
...@@ -150,6 +241,8 @@ ...@@ -150,6 +241,8 @@
wx_game_channel: '' wx_game_channel: ''
} }
this.wxGameChannelList = [] this.wxGameChannelList = []
this.backgroundImgsList = []
this.channelQrcode = ''
this.closeMessage() this.closeMessage()
this.loading = false this.loading = false
// 清理图片资源 // 清理图片资源
...@@ -320,6 +413,19 @@ ...@@ -320,6 +413,19 @@
} }
}) })
}, },
// 处理渠道选择变化
async handleChannelChange(value) {
if (!value) {
// 清空渠道时,清空背景图列表
this.backgroundImgsList = []
this.channelQrcode = ''
this.wxGameForm.selectedBackgroundIndex = 0
this.imageInfo = {}
return
}
// 选择渠道后自动请求接口
await this.handleWxGameChannel()
},
async uploadCos(File) { async uploadCos(File) {
const uploadConfig = { const uploadConfig = {
dir: '/company_wx/service/avatars/' dir: '/company_wx/service/avatars/'
...@@ -336,7 +442,30 @@ ...@@ -336,7 +442,30 @@
} }
}, },
handleConfirm() { handleConfirm() {
this.handleWxGameChannel() if (!this.imageInfo.background_img ) {
this.$message.warning('请先选择背景图')
return false
}
if (!this.imageInfo.channel_qrcode) {
this.$message.warning('渠道二维码图片不存在')
return false
}
// 检查是否选择了渠道
if (!this.wxGameForm.wx_game_channel) {
this.$message.warning('请选择渠道')
return
}
// 如果有背景图列表,直接合成图片
if (this.backgroundImgsList.length > 0) {
this.confirmAndCompose()
} else {
// 如果没有背景图列表,说明接口返回的是旧格式,直接合成
if (this.imageInfo.background_img) {
this.confirmAndCompose()
} else {
this.$message.warning('请先选择渠道')
}
}
}, },
// 保存微信小游戏的信息 // 保存微信小游戏的信息
...@@ -387,11 +516,37 @@ ...@@ -387,11 +516,37 @@
const linkRes = await getLandingPageMemberLink(params) const linkRes = await getLandingPageMemberLink(params)
console.log('获取到的落地页数据:', linkRes) console.log('获取到的落地页数据:', linkRes)
if (linkRes?.data?.data) { if (linkRes?.data?.data) {
// 检查返回的数据结构 const responseData = linkRes.data.data
console.log('设置前的imageInfo:', this.imageInfo) // 保存二维码链接
this.imageInfo = linkRes.data.data this.channelQrcode = responseData.channel_qrcode || ''
console.log('设置后的imageInfo:', this.imageInfo)
await this.composeImage() // 处理背景图列表
if (responseData.background_imgs && responseData.background_imgs.length > 0) {
// 如果有背景图列表,使用列表中的图片
// 初始化二维码样式
this.backgroundImgsList = responseData.background_imgs.map(item => ({
...item,
qrStyle: null // 等待图片加载后计算
}))
// 默认选中第一个
this.wxGameForm.selectedBackgroundIndex = 0
// 设置默认的 imageInfo
this.updateImageInfo(0)
// 不立即合成,等待用户选择后点击确认
this.loading = false
return
} else {
// 如果没有背景图列表,使用默认背景图(兼容旧逻辑)
this.backgroundImgsList = []
this.imageInfo = {
background_img: responseData.background_img || '',
channel_qrcode: this.channelQrcode,
'x-coordinate': responseData['x-coordinate'] || 0,
'y-coordinate': responseData['y-coordinate'] || 0
}
// 不立即合成,等待用户点击确认
this.loading = false
}
} else { } else {
throw new Error('获取落地页数据失败') throw new Error('获取落地页数据失败')
} }
...@@ -405,19 +560,179 @@ ...@@ -405,19 +560,179 @@
}, },
close() { close() {
this.closeMessage() this.closeMessage()
// 清理背景图相关数据
this.backgroundImgsList = []
this.channelQrcode = ''
this.wxGameForm.selectedBackgroundIndex = 0
this.imageInfo = {}
this.previewVisible = false
this.previewImageInfo = null
this.$emit('close') this.$emit('close')
this.$emit('update:show', false) this.$emit('update:show', false)
},
// 处理背景图选择变化
handleBackgroundChange(index) {
this.updateImageInfo(index)
},
// 更新 imageInfo
updateImageInfo(index) {
if (this.backgroundImgsList.length > 0 && this.backgroundImgsList[index]) {
const selectedBg = this.backgroundImgsList[index]
this.imageInfo = {
background_img: selectedBg.background_img,
channel_qrcode: this.channelQrcode,
'x-coordinate': selectedBg['x-coordinate'] || 0,
'y-coordinate': selectedBg['y-coordinate'] || 0
}
}
},
// 确认选择背景图后合成图片
async confirmAndCompose() {
if (this.backgroundImgsList.length === 0) {
// 如果没有背景图列表,直接合成(兼容旧逻辑)
await this.composeImage()
return
} }
// 确保 imageInfo 已设置
if (!this.imageInfo.background_img) {
this.updateImageInfo(this.wxGameForm.selectedBackgroundIndex)
} }
await this.composeImage()
},
// 显示大图预览
showPreview(item, index) {
// 构建预览图片信息
const previewInfo = {
background_img: item.background_img,
channel_qrcode: this.channelQrcode,
'x-coordinate': item['x-coordinate'] || 0,
'y-coordinate': item['y-coordinate'] || 0
}
this.previewImageInfo = previewInfo
this.previewVisible = true
// 重置二维码样式,等待图片加载后计算
this.previewQrcodeStyle = {}
// 等待 DOM 更新后,检查图片是否已加载
this.$nextTick(() => {
if (this.$refs.previewBgImgDisplay) {
const bgImg = this.$refs.previewBgImgDisplay
// 如果图片已经加载完成(complete 属性为 true),直接计算样式
if (bgImg.complete && bgImg.naturalWidth > 0) {
this.calculatePreviewQrcodeStyle()
} }
</script> }
})
},
// 处理预览背景图加载完成
handlePreviewImageLoad() {
this.calculatePreviewQrcodeStyle()
},
// 计算预览二维码样式
calculatePreviewQrcodeStyle() {
if (!this.previewImageInfo || !this.$refs.previewBgImgDisplay) {
return
}
const bgImg = this.$refs.previewBgImgDisplay
// 参考生成图片时的逻辑:背景图宽度固定为 750px
const bgOriginalWidth = 750 // 原始宽度(生成图片时的宽度)
// 等待下一帧,确保图片已渲染
this.$nextTick(() => {
// 获取背景图的实际显示尺寸(参考生成图片时的逻辑)
// 使用 getBoundingClientRect 获取实际渲染尺寸
const imgRect = bgImg.getBoundingClientRect()
const displayWidth = imgRect.width
const displayHeight = imgRect.height
// 如果图片还没有渲染完成,延迟重试
if (displayWidth === 0 || displayHeight === 0) {
setTimeout(() => {
this.calculatePreviewQrcodeStyle()
}, 100)
return
}
// 计算缩放比例(基于实际显示宽度与原始宽度的比例)
// 参考生成图片时:width = 750, height = (naturalHeight / naturalWidth) * width
const scale = displayWidth / bgOriginalWidth
// 计算二维码位置和尺寸(参考生成图片时的逻辑)
// x-coordinate 和 y-coordinate 是相对于 750px 宽度的绝对位置
// 二维码直接使用坐标值,相对于背景图容器定位
const qrSize = 180 * scale
const qrLeft = (this.previewImageInfo['x-coordinate'] || 0) * scale
const qrTop = (this.previewImageInfo['y-coordinate'] || 0) * scale
this.previewQrcodeStyle = {
position: 'absolute',
left: `${qrLeft}px`,
top: `${qrTop}px`,
width: `${qrSize}px`,
height: `${qrSize}px`
}
})
},
// 处理背景图列表中的图片加载完成
handleBackgroundImageLoad(index, item) {
const bgImgRef = this.$refs[`bgImg_${index}`]
// Vue 2 中,ref 可能是数组或单个元素
const bgImg = Array.isArray(bgImgRef) ? bgImgRef[0] : bgImgRef
if (!bgImg) {
return
}
// 参考生成图片时的逻辑:背景图宽度固定为 750px
const bgOriginalWidth = 750 // 原始宽度(生成图片时的宽度)
// 等待下一帧,确保图片已渲染
this.$nextTick(() => {
// 获取背景图的实际显示尺寸(参考生成图片时的逻辑)
// 使用 getBoundingClientRect 获取实际渲染尺寸
const imgRect = bgImg.getBoundingClientRect()
const displayWidth = imgRect.width
const displayHeight = imgRect.height
// 计算缩放比例(基于实际显示宽度与原始宽度的比例)
// 参考生成图片时:width = 750, height = (naturalHeight / naturalWidth) * width
const scale = displayWidth / bgOriginalWidth
// 计算二维码位置和尺寸(参考生成图片时的逻辑)
// x-coordinate 和 y-coordinate 是相对于 750px 宽度的绝对位置
// 二维码直接使用坐标值,相对于背景图容器定位
const qrSize = 180 * scale
const qrLeft = (item['x-coordinate'] || 0) * scale
const qrTop = (item['y-coordinate'] || 0) * scale
// 更新二维码样式
this.$set(this.backgroundImgsList[index], 'qrStyle', {
position: 'absolute',
left: `${qrLeft}px`,
top: `${qrTop}px`,
width: `${qrSize}px`,
height: `${qrSize}px`
})
})
}
}
}
</script>
<style scoped lang="scss"> <style scoped lang="scss">
.formLabel{ .formLabel{
font-size: 16px; font-size: 16px;
font-weight: 500; font-weight: 500;
} }
.dialog-footer{ .sendTransWxGame{
width: 100%;
height: 100%;
overflow: auto;
padding-bottom: 50px;
}
.dialog-footer{
width: calc(100%); width: calc(100%);
height: auto; height: auto;
position: absolute; position: absolute;
...@@ -432,8 +747,8 @@ ...@@ -432,8 +747,8 @@
width:84px ; width:84px ;
height: 32px; height: 32px;
} }
} }
.game-select-container { .game-select-container {
padding: 0 20px; padding: 0 20px;
::v-deep .el-icon-circle-close{ ::v-deep .el-icon-circle-close{
color: #C0C4CC !important; color: #C0C4CC !important;
...@@ -442,36 +757,190 @@ ...@@ -442,36 +757,190 @@
line-height: 32px; line-height: 32px;
padding: 3px; padding: 3px;
} }
} }
.compose-container { .compose-container {
position: fixed; position: fixed;
left: -9999px; left: -9999px;
top: -9999px; top: -9999px;
overflow: hidden; overflow: hidden;
z-index: -1; z-index: -1;
} }
.image-wrapper { .image-wrapper {
position: relative; position: relative;
display: none; display: none;
font-size: 0; font-size: 0;
width: 750px; /* 固定容器宽度 */ width: 750px; /* 固定容器宽度 */
} }
.background-img { .background-img {
display: block; display: block;
width: 750px !important; /* 固定宽度 */ width: 750px !important; /* 固定宽度 */
height: auto !important; /* 高度自适应 */ height: auto !important; /* 高度自适应 */
object-fit: contain; object-fit: contain;
} }
.qr-code { .qr-code {
position: absolute; position: absolute;
display: block; display: block;
width: 180px !important; width: 180px !important;
height: 180px !important; height: 180px !important;
object-fit: contain; object-fit: contain;
pointer-events: none; pointer-events: none;
}
.required-mark {
color: #f53f3f;
margin-right: 4px;
}
.background-options {
display: flex;
flex-wrap: wrap;
gap: 16px;
width: 100%;
}
.background-radio-item {
margin-right: 0 !important;
margin-bottom: 0 !important;
width: 120px;
::v-deep .el-radio__input {
display: none;
}
::v-deep .el-radio__label {
padding-left: 0;
cursor: pointer;
width: 100%;
} }
</style> }
.background-card {
position: relative;
width: 100%;
height: 200px;
background: #fff;
border: 1.5px solid #e5e7eb;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
transition: all 0.3s;
padding: 10px 30px;
}
.background-radio-item.is-checked .background-card {
border-color: #00bf8a;
}
.background-preview-wrapper {
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.background-preview {
width: 100%;
object-fit:100% 100%;
pointer-events: none;
border-radius: 5px;
}
.background-qrcode {
pointer-events: none;
object-fit: contain;
}
.eye-icon {
position: absolute;
left: 6.5px;
top: 6.5px;
width: 16px;
height: 16px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
z-index: 10;
i {
font-size: 16px;
color: #C9CDD4;
}
&:hover {
opacity: 0.8;
color: #00bf8a;
}
}
.eye-icon-checked {
i{
color: #00bf8a;
}
}
.status-icon {
position: absolute;
right: 6.5px;
top: 6.5px;
width: 16px;
height: 16px;
z-index: 10;
.status-icon-checked {
font-size: 14px;
color: #00bf8a;
width: 14px;
height: 14px;
display: flex;
align-items: center;
justify-content: center;
}
.status-icon-unchecked {
font-size: 14px;
color: #b1b2b4;
width: 14px;
height: 14px;
display: flex;
align-items: center;
justify-content: center;
}
}
.preview-dialog {
height: auto;
background: none;
}
.preview-content {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
min-height: 400px;
padding: 20px;
padding-top: 0;
}
.preview-wrapper {
position: relative;
display: flex;
justify-content: center;
}
.preview-background {
display: block;
border-radius: 10px;
max-width: 100%;
}
.preview-qrcode {
object-fit: contain;
pointer-events: none;
}
</style>
\ No newline at end of file
...@@ -147,7 +147,6 @@ export default { ...@@ -147,7 +147,6 @@ export default {
// list = [{ msgtype: 'text', text: { content: str }}] // list = [{ msgtype: 'text', text: { content: str }}]
this.sendChatMessage(str,'text') this.sendChatMessage(str,'text')
} }
// this.set_sendSkillMessage(list)
// 3:召回 召回的时候请求召回染色的接口 // 3:召回 召回的时候请求召回染色的接口
this.recallChannelSeq() this.recallChannelSeq()
} }
......
...@@ -37,9 +37,6 @@ export default { ...@@ -37,9 +37,6 @@ export default {
close() { close() {
this.$emit('update:show', false) this.$emit('update:show', false)
}, },
// const list = [{ msgtype: 'text', text: { content: `${str}${item.url}` }}]
// this.set_sendSkillMessage(list)
onConfirm() { onConfirm() {
if (this.webForm.channel_id === '') { if (this.webForm.channel_id === '') {
this.$message.warning('请选择渠道') this.$message.warning('请选择渠道')
...@@ -105,8 +102,6 @@ export default { ...@@ -105,8 +102,6 @@ export default {
// list = [{ msgtype: 'text', text: { content: str }}] // list = [{ msgtype: 'text', text: { content: str }}]
this.sendChatMessage(str,'text') this.sendChatMessage(str,'text')
} }
// this.set_sendSkillMessage(list)
// this.sendChatMessage(str,'text')
// 3:召回 召回的时候请求召回染色的接口 // 3:召回 召回的时候请求召回染色的接口
this.recallChannelSeq() this.recallChannelSeq()
} }
......
...@@ -286,7 +286,7 @@ export default { ...@@ -286,7 +286,7 @@ export default {
handleFlowerLinkSuccess(url) { handleFlowerLinkSuccess(url) {
if (url) { if (url) {
this.sendChatMessage(url, "text"); this.sendChatMessage(url, "text");
this.$message.success("发送成功"); this.$message.success('发送成功')
} }
}, },
// 发送举报申诉自助链接 // 发送举报申诉自助链接
......
...@@ -184,6 +184,17 @@ ...@@ -184,6 +184,17 @@
</p> </p>
</div> </div>
</div> </div>
<!-- 带教记录 -->
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">带教次数:</span>
<el-button
type="text"
style="cursor: pointer;z-index:10;"
@click.stop="openMentorRecordDrawer(items)"
>{{ items.teach_num || '-' }}次</el-button>
</div>
</div>
</div> </div>
</el-collapse-item> </el-collapse-item>
</div> </div>
...@@ -204,24 +215,39 @@ ...@@ -204,24 +215,39 @@
:show.sync="showAppeal" :show.sync="showAppeal"
:appeal-info="appealInfo" :appeal-info="appealInfo"
/> />
<!-- 带教记录弹窗 -->
<el-drawer
:visible.sync="showMentorRecord"
v-if="showMentorRecord"
:title="`${currentRoleName}带教记录`"
size="300px"
:append-to-body="true"
>
<mentorRecord
:role-id="currentRoleId"
@refresh="handleMentorRecordRefresh"
/>
</el-drawer>
</div> </div>
</template> </template>
<script> <script>
import { mapState, mapMutations, mapActions } from "vuex"; import { mapState, mapMutations, mapActions } from "vuex";
import { getRoleHoLo, marketingRoleGrade, getServerDayApi } from "@/api/game"; import { getRoleHoLo, marketingRoleGrade, getServerDayApi,roleTeachingNum } from "@/api/game";
import noContent from "@/components/noContent.vue"; import noContent from "@/components/noContent.vue";
import appeal from "./layer/appeal.vue"; import appeal from "./layer/appeal.vue";
import watchMember from "@/mixins/watchMember"; import watchMember from "@/mixins/watchMember";
import { createDetails } from "@/views/popup/RecentActivitiesPopup/index.js"; import { createDetails } from "@/views/popup/RecentActivitiesPopup/index.js";
import { createRoleRecentActivityNotPushNum } from "@/views/hooks/useGetCount.js"; import { createRoleRecentActivityNotPushNum } from "@/views/hooks/useGetCount.js";
import vipLevel from "@/views/userInfo/components/gameInfo/vipLevel.vue"; import vipLevel from "@/views/userInfo/components/gameInfo/vipLevel.vue";
import mentorRecord from "@/views/userInfo/components/gameInfo/mentorRecord.vue";
export default { export default {
name: "roleInfo", name: "roleInfo",
components: { components: {
noContent, noContent,
appeal, appeal,
vipLevel, vipLevel,
mentorRecord,
}, },
data() { data() {
return { return {
...@@ -240,6 +266,9 @@ export default { ...@@ -240,6 +266,9 @@ export default {
recentActivitiesPopupInstance: null, //近期要开模块弹框 recentActivitiesPopupInstance: null, //近期要开模块弹框
roleRecentActivityNotPushNumInstance: null, //侧边栏计数弹框 roleRecentActivityNotPushNumInstance: null, //侧边栏计数弹框
numRoleIdList: [], numRoleIdList: [],
showMentorRecord: false, // 带教记录弹窗显示状态
currentRoleId: null, // 当前查看带教记录的角色ID
currentRoleName: '' // 当前查看带教记录的角色名称
}; };
}, },
computed: { computed: {
...@@ -248,7 +277,11 @@ export default { ...@@ -248,7 +277,11 @@ export default {
watch: { watch: {
collapseActive(newVal, oldVal) { collapseActive(newVal, oldVal) {
if (newVal.length > 0) { if (newVal.length > 0) {
this.handleChange(newVal.filter((item) => !oldVal.includes(item))); const newOpenedItems = newVal.filter(item => !oldVal.includes(item))
this.handleChange(newOpenedItems)
// 处理带教次数获取
this.handleChangeRoleTeachingNum(newOpenedItems)
} }
}, },
}, },
...@@ -303,7 +336,6 @@ export default { ...@@ -303,7 +336,6 @@ export default {
}); });
} }
}, },
async handleChange(v) { async handleChange(v) {
const index = this.roleList.findIndex( const index = this.roleList.findIndex(
(item) => v.includes(item.role_id) && !item.server_day (item) => v.includes(item.role_id) && !item.server_day
...@@ -354,6 +386,67 @@ export default { ...@@ -354,6 +386,67 @@ export default {
} }
); );
}, },
/**
* 打开带教记录弹窗
*/
openMentorRecordDrawer(roleItem) {
console.log(roleItem, 'roleItem')
this.currentRoleId = roleItem.role_id
this.currentRoleName = `${roleItem.role_name}-${roleItem.server_name}`
this.showMentorRecord = true
},
/**
* 带教记录刷新后,更新角色列表中的带教次数
*/
async handleMentorRecordRefresh(roleId,teachingListLength) {
// 重新获取角色列表,更新带教次数
const index = this.roleList.findIndex(item => item.role_id === roleId)
if (index !== -1) {
this.$set(this.roleList[index], 'teach_num', teachingListLength)
}
this.roleList = this.roleList.concat([])
},
/**
* 处理角色展开时获取带教次数
* @param {Array} openedRoleIds - 新展开的角色ID数组
*/
handleChangeRoleTeachingNum(openedRoleIds) {
if (!openedRoleIds || openedRoleIds.length === 0) {
return
}
// 遍历新展开的角色,获取带教次数
openedRoleIds.forEach(roleId => {
const roleItem = this.roleList.find(item => item.role_id === roleId)
if (roleItem) {
// 如果已经存在 teach_num 字段,则不请求接口
if (roleItem.teach_num === undefined || roleItem.teach_num === null) {
this.getRoleTeachingNum(roleId)
}
}
})
},
/**
* 获取角色带教次数
* @param {String|Number} roleId - 角色ID
*/
async getRoleTeachingNum(roleId) {
try {
const res = await roleTeachingNum({
role_id: roleId
})
console.log(res,'res')
if (res.status_code === 1) {
// 更新对应角色的 teach_num 字段
const index = this.roleList.findIndex(item => item.role_id === roleId)
if (index !== -1) {
this.$set(this.roleList[index], 'teach_num', res.data.data?.role_teaching_num || 0)
this.roleList = [...this.roleList]
}
}
} catch (error) {
console.error('获取带教次数失败:', error)
}
}
}, },
beforeDestroy() { beforeDestroy() {
this.recentActivitiesPopupInstance.destroy(); this.recentActivitiesPopupInstance.destroy();
......
...@@ -140,7 +140,6 @@ export default { ...@@ -140,7 +140,6 @@ export default {
this.requestGroup() this.requestGroup()
}, },
methods: { methods: {
// ...mapMutations('common', ['set_sendSkillMessage', 'set_isEditSkill']),
sendMessage: debounce(function (item, id) { sendMessage: debounce(function (item, id) {
console.log(item, id, 'sendMessage') console.log(item, id, 'sendMessage')
}, 500), }, 500),
...@@ -150,11 +149,6 @@ export default { ...@@ -150,11 +149,6 @@ export default {
// 复制内容到粘贴板 // 复制内容到粘贴板
if (item.msgtype == 'text') { if (item.msgtype == 'text') {
if (item && item.text && item.text.content) { if (item && item.text && item.text.content) {
// copyToClipboard(
// item.text.content,
// (message) => this.$message.success(message),
// (message) => this.$message.error(message)
// )
this.sendChatMessage(item.text.content) this.sendChatMessage(item.text.content)
} }
} else if (item.msgtype == 'image' && item.image.picurl) { } else if (item.msgtype == 'image' && item.image.picurl) {
......
...@@ -389,7 +389,7 @@ export default { ...@@ -389,7 +389,7 @@ export default {
}, },
methods: { methods: {
...mapMutations('game', ['set_accountSelect', 'accountSelect']), ...mapMutations('game', ['set_accountSelect']),
...mapActions('user', ['initWecom']), ...mapActions('user', ['initWecom']),
// 初始化企业微信SDK // 初始化企业微信SDK
......
<!--
* @Author: 金多虾 937667504@qq.com
* @Date: 2025-12-11 11:01:15
* @LastEditors: 金多虾 937667504@qq.com
* @LastEditTime: 2025-12-20 11:25:56
* @FilePath: /company_wx_frontend/src/views/works/component/gameInfo/roleInfo/mentorRecord.vue
* @Description: 带教记录组件
-->
<template>
<div class="mentor-record-page">
<!-- 提示信息和添加按钮区域 -->
<div class="mentor-record-page__toolbar">
<el-button
v-if="teachingList.length < 5"
type="primary"
size="small"
@click="showAddForm = !showAddForm"
>添加记录</el-button>
</div>
<!-- 新增记录表单 -->
<div v-if="showAddForm && teachingList.length < 5" class="mentor-record-page__add-form">
<el-input
v-model="formData.content"
type="textarea"
:rows="3"
placeholder="请输入"
maxlength="500"
show-word-limit
class="mentor-record-page__add-form-input"
/>
<div class="mentor-record-page__add-form-buttons">
<el-button size="mini" @click="handleCancelAdd">取消</el-button>
<el-button type="primary" size="mini" :loading="submitLoading" @click="handleSubmitAdd">保存</el-button>
</div>
</div>
<!-- 带教记录列表 -->
<div class="mentor-record-page__list">
<div
v-for="(item, index) in teachingList"
:key="item.id || index"
class="mentor-record-page__list-item"
>
<p class="mentor-record-page__list-item-title">{{ item.teaching_num }}次带教</p>
<p class="mentor-record-page__list-item-content">{{ item.teaching_text }}</p>
<div class="mentor-record-page__list-item-footer">
<span class="mentor-record-page__list-item-creator">新增人:{{ item.update_user || '-' }}</span>
<span class="mentor-record-page__list-item-divider">|</span>
<span class="mentor-record-page__list-item-time">{{item.update_time }}</span>
</div>
</div>
<div v-if="teachingList.length === 0 && !loading" class="mentor-record-page__empty">
<svg-icon icon-class="noContent" />
<p>暂无带教记录</p>
</div>
</div>
</div>
</template>
<script>
import { roleTeachingList, roleTeachingAdd } from '@/api/game'
import { mapState } from 'vuex'
export default {
name: 'MentorRecord',
props: {
roleId: {
type: [String, Number],
required: true
},
},
data() {
return {
loading: false,
submitLoading: false,
showAddForm: false,
teachingList: [],
formData: {
content: ''
}
}
},
watch: {
roleId: {
immediate: true,
handler(newVal) {
if (newVal) {
this.getTeachingList()
}
}
}
},
computed: {
...mapState('user', ['userInfo'])
},
methods: {
/**
* 获取带教记录列表
*/
async getTeachingList() {
if (!this.roleId) {
return
}
try {
this.loading = true
const res = await roleTeachingList({
role_id: this.roleId
})
if (res.status_code === 1) {
this.teachingList = res.data.data || []
// 按teaching_num倒序排列
this.teachingList.sort((a, b) => {
return (b.teaching_num || 0) - (a.teaching_num || 0)
})
} else {
this.$message({
message: res.data.msg || '获取带教记录失败',
type: 'error'
})
}
} catch (error) {
console.error('获取带教记录失败:', error)
this.$message({
message: '获取带教记录失败,请稍后重试',
type: 'error'
})
} finally {
this.loading = false
}
},
/**
* 新增带教记录
*/
async handleSubmitAdd() {
if (!this.formData.content || !this.formData.content.trim()) {
this.$message({
message: '请输入带教记录内容',
type: 'warning'
})
return
}
try {
this.submitLoading = true
const res = await roleTeachingAdd({
role_id: this.roleId,
teaching_num: this.teachingList.length + 1,
teaching_text: this.formData.content.trim(),
create_user_id: this.userInfo.id,
create_user: this.userInfo.username
})
if (res.status_code === 1) {
this.$message({
message: res.data.msg || '添加成功',
type: 'success'
})
this.formData.content = ''
this.showAddForm = false
// 重新获取列表
await this.getTeachingList()
// 通知父组件更新带教次数
this.$emit('refresh',this.roleId,this.teachingList.length)
} else {
this.$message({
message: res.data.msg || '添加失败',
type: 'error'
})
}
} catch (error) {
console.error('新增带教记录失败:', error)
this.$message({
message: '添加失败,请稍后重试',
type: 'error'
})
} finally {
this.submitLoading = false
}
},
/**
* 取消新增
*/
handleCancelAdd() {
this.formData.content = ''
this.showAddForm = false
},
}
}
</script>
<style lang="scss" scoped>
.mentor-record-page {
width: 100%;
height: 100%;
padding: 12px;
padding-top: 0;
background: #fff;
border-right: 1px solid #ebedf0;
display: flex;
flex-direction: column;
overflow: hidden;
&__header {
display: flex;
align-items: center;
padding: 12px 0;
padding-top: 0;
border-bottom: 1px solid #ebedf0;
&-title {
font-family: PingFangSC-Medium, PingFang SC;
font-size: 14px;
font-weight: 500;
line-height: 22px;
color: #131920;
}
}
&__toolbar {
display: flex;
align-items: center;
justify-content: flex-end;
margin-bottom: 20px;
&-tip {
font-family: PingFangSC-Regular, PingFang SC;
font-size: 12px;
font-weight: 400;
line-height: 20px;
color: #909399;
}
}
&__add-form {
display: flex;
flex-direction: column;
gap: 8px;
margin-bottom: 12px;
&-input {
::v-deep .el-textarea__inner {
border: 1px solid #d6d9e0;
border-radius: 6px;
padding: 4px 6px;
font-size: 13px;
line-height: 22px;
color: #323335;
min-height: 60px;
resize: none;
&::placeholder {
color: #c9cdd4;
}
}
}
&-buttons {
display: flex;
gap: 8px;
justify-content: flex-end;
}
}
&__list {
flex: 1;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 12px;
&-item {
background: #fff;
border: 1px solid #ebedf0;
border-radius: 6px;
padding: 8px;
display: flex;
flex-direction: column;
gap: 4px;
&-title {
font-family: PingFangSC-Regular, PingFang SC;
font-size: 12px;
font-weight: 400;
line-height: 20px;
color: #6d7176;
}
&-content {
font-family: PingFangSC-Regular, PingFang SC;
font-size: 15px;
font-weight: 500;
line-height: 22px;
color: #131920;
word-break: break-all;
}
&-footer {
display: flex;
align-items: center;
gap: 4px;
}
&-creator,
&-time {
font-family: PingFangSC-Regular, PingFang SC;
font-size: 12px;
font-weight: 400;
line-height: 20px;
color: #b0b2b5;
}
&-divider {
color: #ebedf0;
font-size: 12px;
}
}
}
&__empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 40px 0;
color: #909399;
font-size: 14px;
p {
margin-top: 12px;
}
}
}
</style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论