提交 82a41625 作者: 施汉文

客户资料样式修改

上级 f8a92a1f
......@@ -16,7 +16,7 @@
<title>企微侧边栏</title>
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0,shrink-to-fit=no,user-scalable=no"> -->
<script src="https://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"></script>
<script src="https://lf1-cdn-tos.bytegoofy.com/obj/iconpark/svg_27278_173.e64d61edfe0d4824e2eeb0b7f478e568.js"></script>
<script src="https://lf1-cdn-tos.bytegoofy.com/obj/iconpark/svg_27278_174.7c507957486002617642b36b416498d5.js"></script>
</head>
<body>
<noscript>
......
......@@ -69,10 +69,10 @@
>
<el-badge is-dot :type="csStatusInfo.type">
<!-- <span>{{ item.label }}</span> -->
<iconpark-icon
class="w-[14px] h-[14px]"
:name="item.icon"
></iconpark-icon>
<svg-icon
class="text-[14px]"
:svgName="item.icon"
></svg-icon>
</el-badge>
</div>
</el-tooltip>
......@@ -86,23 +86,15 @@
:content="item.label"
placement="left"
>
<iconpark-icon
class="w-[14px] h-[14px]"
:name="item.icon"
></iconpark-icon>
<svg-icon
class="w-[14px] text-red h-[14px] text-[14px]"
:svgName="item.icon"
></svg-icon>
</el-tooltip>
</div>
</el-menu-item>
</el-menu>
</div>
<<<<<<< HEAD =======
<!-- 绑定的 w 账号 -->
<bindUserList />
</div>
<div class="mobile-content">
<router-view></router-view>
>>>>>>> release
</div>
</div>
</template>
......@@ -185,7 +177,7 @@ export default {
{
label: "用户待办",
path: "/userToDo",
hasRedDot: false, // 红点状态
icon: "yonghudaiban",
},
{
label: "微言助手",
......@@ -546,7 +538,7 @@ body {
}
.agent-status-management {
::v-deep .el-badge__content.is-dot {
top: 38px !important;
/* top: 38px !important; */
right: 2px !important;
}
}
......@@ -562,4 +554,7 @@ body {
.p-common {
padding: 0 10px;
}
::v-deep .el-badge__content.is-fixed {
z-index: 1;
}
</style>
......@@ -9,11 +9,11 @@
>
<template #title>
<div class="flex items-center">
<iconpark-icon
<svg-icon
@click="$emit('close')"
name="icon-fanhui"
svgName="icon-fanhui"
class="mr-[8px] w-[20px] text-[20px] cursor-pointer"
></iconpark-icon>
></svg-icon>
<span class="text-[13px] text-[#131920] leading-[13px]">{{
title
}}</span>
......
<template>
<div class="w-full h-full flex items-center justify-center">
<div class="flex flex-col justify-center">
<iconpark-icon name="Empty-2" class="text-[80px]"></iconpark-icon>
<div class="flex flex-col items-center justify-center">
<svg-icon svgName="Empty-2" class="text-[80px]"></svg-icon>
<slot></slot>
</div>
</div>
......
<template>
<div class="relative w-full group flex items-center">
<template v-if="show">
<el-input
v-model="value"
class="showInputRemarkInput"
:type="isInput ? 'text' : 'textarea'"
></el-input>
<div class="absolute bottom-[6px] right-[10px] text-[16px] flex">
<svg-icon
svgName="icon-quxiao"
class="text-[#B0B2B5] cursor-pointer"
@click="close"
></svg-icon>
<svg-icon
svgName="icon-queding"
class="text-[#267EF0] cursor-pointer ml-[6px]"
@click="confirm"
></svg-icon>
</div>
</template>
<template v-else>
<slot></slot>
<svg-icon
svgName="ziliao-bianji"
class="group-hover:visible ml-[6px] text-primary invisible cursor-pointer text-[16px]"
@click="editRemark"
></svg-icon>
</template>
</div>
</template>
<script>
export default {
name: "CommonModificationBox",
props: {
text: {
type: String,
default: "",
},
isInput: {
type: Boolean,
default: false,
},
},
data() {
return {
value: "",
show: false,
};
},
created() {
// 初始化value为text的初始值
this.value = this.text;
},
watch: {
text(newVal) {
this.value = newVal;
},
},
methods: {
editRemark() {
this.show = true;
},
close() {
this.show = false;
this.value = this.text;
},
confirm() {
this.$emit("confirm", this.value);
this.show = false;
},
},
};
</script>
<style></style>
......@@ -31,10 +31,10 @@
:loading="logoutLoading"
>
<div class="flex items-center justify-center">
<iconpark-icon
name="kefucaozuo-xiaxian"
<svg-icon
svgName="kefucaozuo-xiaxian"
class="mr-[8px] text-[14px]"
></iconpark-icon>
></svg-icon>
下线
</div>
</el-button>
......@@ -51,10 +51,10 @@
:loading="startRestLoading"
>
<div class="flex items-center justify-center">
<iconpark-icon
name="kefucaozuo-xiuxi"
<svg-icon
svgName="kefucaozuo-xiuxi"
class="mr-[8px] text-[14px]"
></iconpark-icon>
></svg-icon>
开始休息
</div>
</el-button>
......@@ -67,10 +67,10 @@
:loading="finishRestLoading"
>
<div class="flex items-center justify-center">
<iconpark-icon
name="kefucaozuo-xiuxi"
<svg-icon
svgName="kefucaozuo-xiuxi"
class="mr-[8px] font-bold text-[14px]"
></iconpark-icon>
></svg-icon>
结束休息
</div>
</el-button>
......@@ -81,10 +81,10 @@
:loading="sendCommentLoading"
>
<div class="flex items-center justify-center">
<iconpark-icon
name="kefucaozuo-pingjia"
<svg-icon
svgName="kefucaozuo-pingjia"
class="mr-[8px] text-[14px]"
></iconpark-icon>
></svg-icon>
发送评价
</div>
</el-button>
......
......@@ -7,7 +7,7 @@
:okDisabled="!checkoutUser.member_id"
@ok="confirmSubmit"
>
<div class="w-full h-full py-[10px]">
<div class="w-full h-full flex flex-col py-[10px]" v-loading="loading">
<div class="flex items-center px-[12px]">
<el-input
v-model.trim="inputValue"
......@@ -93,7 +93,7 @@
</el-button>
</el-popover>
</div>
<div class="mt-[12px] content">
<div class="mt-[12px] content" v-if="tableList.length !== 0">
<div
class="cursor-pointer hover:bg-[#F5F6F7]"
v-for="item in tableList"
......@@ -217,6 +217,12 @@
</div>
</div>
</div>
<Empty v-else class="flex-1 pb-[30%]">
<div class="text-[#6D7176] text-[12px]">暂无数据</div>
<div class="text-[#B0B2B5] mt-[4px] text-[12px]">
请点击搜索框或筛选按钮查询
</div>
</Empty>
</div>
<!-- <div class="content">
......@@ -395,12 +401,14 @@ import { mapMutations, mapActions, mapState } from "vuex";
import page from "@/components/page/pageNum.vue";
import Drawer from "@/components/common/Drawer.vue";
import { debounce } from "@/utils/index";
import Empty from "@/components/common/Empty.vue";
export default {
name: "addUser",
components: {
userTable,
page,
Drawer,
Empty,
},
props: ["show"],
data() {
......@@ -446,6 +454,7 @@ export default {
...mapActions("game", ["gameBindUser"]),
...mapMutations("game", ["set_accountSelect"]),
requestRoleList() {
this.loading = true;
const data = {
member_id: this.form.member_id,
username: this.form.username.trim(),
......@@ -457,17 +466,21 @@ export default {
search_type: "bind",
...this.pageInfo,
};
getRoleHoLo(data).then((res) => {
if (res.status_code == 1) {
if (res.data.data.length == 0) {
this.tableList = [];
this.$message.warning("暂无数据");
} else {
this.tableList = res.data.data;
this.pageInfo = res.data.page_info;
getRoleHoLo(data)
.then((res) => {
if (res.status_code == 1) {
if (res.data.data.length == 0) {
this.tableList = [];
this.$message.warning("暂无数据");
} else {
this.tableList = res.data.data;
this.pageInfo = res.data.page_info;
}
}
}
});
})
.finally(() => {
this.loading = false;
});
},
// S181.啊呸¤可瑞 八荒181服
......@@ -478,6 +491,8 @@ export default {
},
remoteMethodServer(query) {
if (query !== "") {
console.log(this.loading);
this.loading = true;
const data = {
type: "server_info",
......@@ -485,6 +500,7 @@ export default {
main_game_ids: this.form.main_game_id,
};
selectSearch(data).then((res) => {
console.log(this.loading);
this.loading = false;
if (res.status_code == 1) {
this.serverNameList = res.data.data;
......
......@@ -4,13 +4,18 @@
<div v-if="!token">
<div>
当前选中组织:<span class="current-org">{{ currentOrg.name }}</span>
<el-button type="text" @click="showOrgDialog = true">切换组织</el-button>
<el-button type="text" @click="showOrgDialog = true"
>切换组织</el-button
>
</div>
<div class="qr-contain">
<div id="dingTalkLoginContainer">
</div>
<div id="dingTalkLoginContainer"></div>
<div class="refresh">
<i class="el-icon-refresh-right " @click="refreshDingTalkQRCode"></i>
<!-- <i class="el-icon-refresh-right " @click="refreshDingTalkQRCode"></i> -->
<svg-icon
svgName="icon-zhongxinshengcheng"
@click="refreshDingTalkQRCode"
/>
</div>
<!-- 生二维码的时候加一个 loading -->
<div class="loading" v-if="qrLoading">
......@@ -19,10 +24,14 @@
</div>
<!-- 新增手机号验证码登录功能 -->
</div>
<!-- 组织切换弹窗 -->
<el-dialog :visible.sync="showOrgDialog" width="300px" title="选择组织">
<ul style="list-style:none;padding:0;margin-top: -20px;">
<li v-for="org in orgList" :key="org.app_key" @click="switchOrg(org)" :style="{
<!-- 组织切换弹窗 -->
<el-dialog :visible.sync="showOrgDialog" width="300px" title="选择组织">
<ul style="list-style: none; padding: 0; margin-top: -20px">
<li
v-for="org in orgList"
:key="org.app_key"
@click="switchOrg(org)"
:style="{
padding: '8px 16px',
cursor: 'pointer',
background: org.app_key === currentOrg.app_key ? '#e6f7ff' : '',
......@@ -30,33 +39,39 @@
fontWeight: org.app_key === currentOrg.app_key ? 'bold' : 'normal',
borderRadius: '4px',
marginBottom: '4px',
transition: 'background 0.2s'
}" @mouseover="hoveredOrg = org.app_key" @mouseleave="hoveredOrg = null">
{{ org.name }}
<span v-if="org.app_key === currentOrg.app_key" style="margin-left:8px;">(当前)</span>
</li>
</ul>
</el-dialog>
transition: 'background 0.2s',
}"
@mouseover="hoveredOrg = org.app_key"
@mouseleave="hoveredOrg = null"
>
{{ org.name }}
<span
v-if="org.app_key === currentOrg.app_key"
style="margin-left: 8px"
>(当前)</span
>
</li>
</ul>
</el-dialog>
</div>
</template>
<script>
import * as ww from '@wecom/jssdk'
import { getOrganization, getAuthUser, getSignature } from '@/api/user'
import Cookies from 'js-cookie'
import { getParams } from '@/utils/index'
import { mapMutations, mapState } from 'vuex'
import { getToken, setToken } from '@/utils/auth'
import jsApiList from '@/utils/jsApiList'
import * as ww from "@wecom/jssdk";
import { getOrganization, getAuthUser, getSignature } from "@/api/user";
import Cookies from "js-cookie";
import { getParams } from "@/utils/index";
import { mapMutations, mapState } from "vuex";
import { getToken, setToken } from "@/utils/auth";
import jsApiList from "@/utils/jsApiList";
export default {
name: 'login',
components: {
},
name: "login",
components: {},
data() {
return {
wecomUserInfo: null, // 企微用户信息
dingUserInfo: null, // 钉钉用户信息
signData: null, // 企微签名数据
wecomUserInfo: null, // 企微用户信息
dingUserInfo: null, // 钉钉用户信息
signData: null, // 企微签名数据
orgList: [],
organizationNum: 5,
urlParams: {},
......@@ -65,75 +80,90 @@ export default {
hoveredOrg: null,
showRefresh: false, // 控制刷新按钮显示
qrLoading: false, // 控制二维码 loading
redirectUri: process.env.NODE_ENV === 'production' ? 'https://companywx.zwnet.cn/api/api/sidebar_login/ding' : 'https://companywx.zwwlkj03.top/api/api/sidebar_login/ding',
DDTestUrl: '',
token: getToken()
}
redirectUri:
process.env.NODE_ENV === "production"
? "https://companywx.zwnet.cn/api/api/sidebar_login/ding"
: "https://companywx.zwwlkj03.top/api/api/sidebar_login/ding",
DDTestUrl: "",
token: getToken(),
};
},
async mounted() {
this.$nextTick(() => {
this.initLogin()
})
this.initLogin();
});
},
computed: {
...mapState('user', ['corp_id'])
...mapState("user", ["corp_id"]),
},
methods: {
...mapMutations('user', ['set_corp_id', 'set_userid', 'set_userInfo', 'set_token', 'set_cser_info', 'set_signData', 'set_cser_id', 'set_cser_name', 'set_external_userid']),
...mapMutations("user", [
"set_corp_id",
"set_userid",
"set_userInfo",
"set_token",
"set_cser_info",
"set_signData",
"set_cser_id",
"set_cser_name",
"set_external_userid",
]),
async initLogin() {
const urlParams = getParams();
await this.initOrganization();
const userid = Cookies.get('userid');
const userid = Cookies.get("userid");
// 如果是钉钉扫码回调页面
if (urlParams.type && urlParams.type === 'ding') {// 钉钉回调
console.log(1)
if (urlParams.type && urlParams.type === "ding") {
// 钉钉回调
console.log(1);
this.handleDingCallback();
} else if (this.token && userid) { // 已经钉钉扫码过 重新获取授权 获取签名 注册企微js-sdk
console.log(2)
} else if (this.token && userid) {
// 已经钉钉扫码过 重新获取授权 获取签名 注册企微js-sdk
console.log(2);
await this.getSignature();
} else {
console.log(3)
if (!userid) { //没有企微授权过 并且 钉钉扫码成功 开始微信授权
console.log(4)
console.log(3);
if (!userid) {
//没有企微授权过 并且 钉钉扫码成功 开始微信授权
console.log(4);
await this.startWeComSilentAuth();
} else {
console.log(5)
console.log(5);
this.initDingTalkLogin(); // 始化钉钉扫码
}
}
},
// 设置缓存
cacheCorp_id(corp_id) {
Cookies.set('corp_id', corp_id, { expires: 30 })
this.set_corp_id(corp_id)
Cookies.set("corp_id", corp_id, { expires: 30 });
this.set_corp_id(corp_id);
},
cacheuserid(userid) {
Cookies.set('userid', userid, { expires: 30 })
this.set_userid(userid)
Cookies.set("userid", userid, { expires: 30 });
this.set_userid(userid);
},
cacheCser(cser_id, cser_name) {
Cookies.set('cser_id', cser_id, { expires: 30 })
Cookies.set('cser_name', cser_name, { expires: 30 })
Cookies.set("cser_id", cser_id, { expires: 30 });
Cookies.set("cser_name", cser_name, { expires: 30 });
this.set_cser_info({
cser_id: cser_id,
cser_name: cser_name
})
this.set_cser_id(cser_id)
this.set_cser_name(cser_name)
cser_name: cser_name,
});
this.set_cser_id(cser_id);
this.set_cser_name(cser_name);
},
cacheSignData(signData) {
Cookies.set('signData', JSON.stringify(signData), { expires: 30 })
this.set_signData(signData)
Cookies.set("signData", JSON.stringify(signData), { expires: 30 });
this.set_signData(signData);
},
// 进入的页面地址是 https://companywx.jianshuwenhua.com/company_app/index.html?corp_id=wweaefe716636df3d1
// 1. 企微静默授权
async startWeComSilentAuth() {
this.urlParams = getParams();
const corp_id = Cookies.get('corp_id') || this.urlParams.corp_id
const corp_id = Cookies.get("corp_id") || this.urlParams.corp_id;
if (!corp_id) {
this.$message.error('当前客服号信息异常,请切换会话后重试')
return
this.$message.error("当前客服号信息异常,请切换会话后重试");
return;
}
// 确定是第一次进入页面 没有 code 和 state
if (!this.urlParams.code && !this.urlParams.state) {
......@@ -144,63 +174,74 @@ export default {
return;
}
// 用code
const res = await getAuthUser({ code: this.urlParams.code, url: window.location.href, corp_id: corp_id });
const res = await getAuthUser({
code: this.urlParams.code,
url: window.location.href,
corp_id: corp_id,
});
if (res.status_code === 1) {
if(res.data.userid){
this.cacheuserid(res.data.userid)
if (res.data.userid) {
this.cacheuserid(res.data.userid);
this.initDingTalkLogin(); // 初始化钉钉扫码
}else{
this.$message.error('获取用户id失败')
return
} else {
this.$message.error("获取用户id失败");
return;
}
} else {
console.log('获取useid失败', res)
console.log("获取useid失败", res);
// 错误处理
}
},
async getSignature() {
console.log('获取签名', window.location.href)
const corp_id = Cookies.get('corp_id')
console.log("获取签名", window.location.href);
const corp_id = Cookies.get("corp_id");
try {
const res = await getSignature({ corp_id: corp_id, path: window.location.href });
const res = await getSignature({
corp_id: corp_id,
path: window.location.href,
});
if (res.status_code === 1) {
this.signData = res.data
this.cacheSignData(res.data)
this.signData = res.data;
this.cacheSignData(res.data);
try {
this.registerWeComSDK();
} catch (err) {
console.log(err, '初始化sdk 失败')
console.log(err, "初始化sdk 失败");
}
}
} catch (err) {
console.log(err, '获取签名失败')
window.location.href = window.location.origin + '/company_app/index.html?corp_id=' + corp_id + '&msg=signerror'
console.log(err, "获取签名失败");
window.location.href =
window.location.origin +
"/company_app/index.html?corp_id=" +
corp_id +
"&msg=signerror";
}
},
getCurExternalContact() {
this.$ww.getCurExternalContact({
success: (res) => {
if (res.err_msg === "getCurExternalContact:ok") {
console.log(res, '重新进入获取企微外部联系人')
this.set_external_userid(res.userId)
console.log(res, "重新进入获取企微外部联系人");
this.set_external_userid(res.userId);
// 确保 Vuex 状态更新后再跳转
this.$nextTick(() => {
this.$router.replace('/')
console.log(window.location.href, 'window.location.hrefuserInfo')
})
this.$router.replace("/");
console.log(window.location.href, "window.location.hrefuserInfo");
});
}
},
fail: (err) => {
console.log(err, '获取企微外部联系人失败')
console.log(err, "获取企微外部联系人失败");
// 错误处理
}
},
});
},
// 2. 注册企微JS-SDK
registerWeComSDK() {
console.log('删除企业签名', 1231)
console.log("删除企业签名", 1231);
this.$ww.register({
corpId: Cookies.get('corp_id'),
corpId: Cookies.get("corp_id"),
agentId: this.signData.agent_id,
jsApiList: jsApiList,
// getConfigSignature: () => Promise.resolve({
......@@ -209,55 +250,58 @@ export default {
// signature: this.signData.corp_signature,
// }),
// 只用到应用的 api 可以只进行应用的签名
getAgentConfigSignature: () => Promise.resolve({
nonceStr: this.signData.nonce_str,
timestamp: this.signData.signature_time,
signature: this.signData.agent_signature,
}),
getAgentConfigSignature: () =>
Promise.resolve({
nonceStr: this.signData.nonce_str,
timestamp: this.signData.signature_time,
signature: this.signData.agent_signature,
}),
onAgentConfigSuccess: (res) => {
console.log('注册成功可以调用企微 js-sdk', res)
console.log("注册成功可以调用企微 js-sdk", res);
// 注册成功后不立即获取外部联系人,等钉钉扫码后再获取
this.getCurExternalContact()
this.getCurExternalContact();
},
onAgentConfigFail: (err) => {
console.log('注册失败不能使用企微js-sdk', err)
console.log("注册失败不能使用企微js-sdk", err);
// 错误处理123
}
},
});
},
// 3. 获取组织列表并选取默认组织
async initOrganization() {
const res = await getOrganization();
if (res.data.status_code === 1) {
this.orgList = res.data.data.data.filter(item => item.id <= this.organizationNum)
this.orgList = res.data.data.data.filter(
(item) => item.id <= this.organizationNum,
);
// 默认组织逻辑:可根据业务自定义
this.initCurrentApp();
}
},
initCurrentApp() {
const currentApp = this.orgList.find(
(item) => item.app_key === "dingjigp0ksn9nbljdli"
(item) => item.app_key === "dingjigp0ksn9nbljdli",
);
this.$set(this, "currentOrg", currentApp);
},
// 4. 初始化钉钉扫码
initDingTalkLogin() {
this.qrLoading = true;
console.log('进入初始化钉钉', this.currentOrg)
console.log("进入初始化钉钉", this.currentOrg);
if (!this.currentOrg.app_key) return;
const appid = this.currentOrg.app_key;
// 清空二维码容器,防止切换组织后二维码不刷新
const container = document.getElementById('dingTalkLoginContainer');
if (container) container.innerHTML = '';
const container = document.getElementById("dingTalkLoginContainer");
if (container) container.innerHTML = "";
DDLogin({
id: 'dingTalkLoginContainer',
goto: encodeURIComponent(`https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=${appid}&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=${this.redirectUri}`),
style: 'border:none;background-color:#FFFFFF;margin:0',
width: '210',
height: '250'
id: "dingTalkLoginContainer",
goto: encodeURIComponent(
`https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=${appid}&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=${this.redirectUri}`,
),
style: "border:none;background-color:#FFFFFF;margin:0",
width: "210",
height: "250",
});
// 二维码生成后,短暂延迟后隐藏 loading(二维码生成是同步的,但页面渲染有延迟)
this.$nextTick(() => {
......@@ -266,11 +310,11 @@ export default {
}, 1000); // 500ms 平滑过渡
});
window.addEventListener('message', this.handleDingTalkLogin, false);
if (typeof window.addEventListener !== 'undefined') {
window.addEventListener('message', this.handleDingTalkLogin, false)
} else if (typeof window.attachEvent !== 'undefined') {
window.attachEvent('onmessage', this.handleDingTalkLogin)
window.addEventListener("message", this.handleDingTalkLogin, false);
if (typeof window.addEventListener !== "undefined") {
window.addEventListener("message", this.handleDingTalkLogin, false);
} else if (typeof window.attachEvent !== "undefined") {
window.attachEvent("onmessage", this.handleDingTalkLogin);
}
},
// https://companywx.jianshuwenhua.com/company_app/login?code=success&cser_id=4090&cser_name=%E6%AF%9B%E7%BB%86%E4%BA%9A&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOjQwOTAsImRhdGEiOnsiY3Nlcl9pZCI6NDA5MCwiY3Nlcl9uYW1lIjoi5q-b57uG5LqaIn0sImlhdCI6MTc0Nzk5MDM0MiwiZXhwIjoxNzUwNTgyMzQyLCJuYmYiOjE3NDc5OTAzNDIsInN1YiI6InRva2Vu6K6k6K-BIiwianRpIjoiYzYzYTM4NGYzMTFmODVlMGQ2Nzg2ZmJiMTdhNjQzN2EifQ.5ADPtqISjxOqbrDOzlKkCpfTr78Sv0Sdi-_Y1RRiMH0&type=ding
......@@ -284,53 +328,60 @@ export default {
},
// 6. 钉钉扫码回调
async handleDingTalkLogin(event) {
console.log('收到扫码回调')
const corp_id = Cookies.get('corp_id')
const userid = Cookies.get('userid')
if (event.origin !== 'https://login.dingtalk.com') return;
console.log("收到扫码回调");
const corp_id = Cookies.get("corp_id");
const userid = Cookies.get("userid");
if (event.origin !== "https://login.dingtalk.com") return;
const loginTmpCode = event.data;
// 跳转到后端,后端用loginTmpCode换取钉钉用户信息
const appid = this.currentOrg.app_key;
const state = encodeURIComponent(`${this.currentOrg.app_key}$${this.currentOrg.template_code}$${corp_id}$${userid}`)
const state = encodeURIComponent(
`${this.currentOrg.app_key}$${this.currentOrg.template_code}$${corp_id}$${userid}`,
);
const url = `https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=${appid}&response_type=code&scope=snsapi_login&state=${state}&redirect_uri=${this.redirectUri}&loginTmpCode=${loginTmpCode}`;
console.log(url, '回调 url')
this.DDTestUrl = url
console.log(url, "回调 url");
this.DDTestUrl = url;
window.location.href = url;
},
// 7. 钉钉扫码回调页面处理
async handleDingCallback() {
// 在这里处理钉钉扫码成功的回调
console.log('扫码成功')
console.log("扫码成功");
const ddParams = getParams();
const corp_id = Cookies.get('corp_id')
if (ddParams.code == 'error' && ddParams.msg) {
this.$message.error(ddParams.msg)
const corp_id = Cookies.get("corp_id");
if (ddParams.code == "error" && ddParams.msg) {
this.$message.error(ddParams.msg);
setTimeout(() => {
window.location.href = window.location.origin + '/company_app/index.html?corp_id=' + corp_id + '&msg=error'
}, 5000)
return
window.location.href =
window.location.origin +
"/company_app/index.html?corp_id=" +
corp_id +
"&msg=error";
}, 5000);
return;
}
if (ddParams.token && ddParams.token != 'undefined') {
setToken(ddParams.token)
this.set_token(ddParams.token)
if (ddParams.token && ddParams.token != "undefined") {
setToken(ddParams.token);
this.set_token(ddParams.token);
// 获取签名
await this.getSignature();
} else {
console.log('没有token')
window.location.href = window.location.origin + '/company_app/index.html?corp_id=' + corp_id + '&msg=notoken'
console.log("没有token");
window.location.href =
window.location.origin +
"/company_app/index.html?corp_id=" +
corp_id +
"&msg=notoken";
}
if (ddParams.cser_id) {
this.cacheCser(ddParams.cser_id, ddParams.cser_name)
this.cacheCser(ddParams.cser_id, ddParams.cser_name);
}
},
refreshDingTalkQRCode() {
this.initDingTalkLogin();
},
},
}
};
</script>
<style lang="scss" scoped>
......@@ -374,7 +425,7 @@ export default {
i {
line-height: 40px;
font-size: 26px;
color: #3491FA;
color: #3491fa;
cursor: pointer;
}
}
......@@ -404,7 +455,7 @@ export default {
width: 40px;
height: 40px;
border: 4px solid #e0e0e0;
border-top: 4px solid #3491FA;
border-top: 4px solid #3491fa;
border-radius: 50%;
animation: spin 1s linear infinite;
}
......@@ -418,4 +469,4 @@ export default {
transform: rotate(360deg);
}
}
</style>
\ No newline at end of file
</style>
......@@ -2,11 +2,11 @@
<div>
<div class="flex justify-between leading-[22px] font-medium">
<div class="text-[#363E49] text-[13px]">已选择标签</div>
<iconpark-icon
<svg-icon
@click="clear"
name="icon-qingkong"
svgName="icon-qingkong"
class="text-[16px] text-[#B0B2B5] hover:text-primary cursor-pointer"
></iconpark-icon>
></svg-icon>
</div>
<div
class="flex flex-wrap content-start gap-[8px] mt-[8px] pb-[12px] border-b-[1px] border-dashed border-b-[#E5E5E6] h-[112px] overflow-y-auto"
......@@ -63,7 +63,7 @@ export default {
remove(item) {
this.$emit(
"input",
this.value.filter((i) => i !== item)
this.value.filter((i) => i !== item),
);
this.$emit("change");
},
......@@ -71,8 +71,8 @@ export default {
this.$emit(
"input",
this.value.filter((i) =>
this.checkedIds.includes(i[this.options.value])
)
this.checkedIds.includes(i[this.options.value]),
),
);
this.$emit("change");
},
......
......@@ -78,6 +78,12 @@
@click="refreshTag"
></i>
<svg-icon
svgName="icon-zhongxinshengcheng"
@click="refreshTag"
:class="isRefresh ? 'refreshListActive' : ''"
class="mr-[8px] refreshList invisible group-hover:visible"
/>
<svg-icon
icon-class="fuzhi"
class="icon invisible group-hover:visible"
style="font-size: 14px"
......@@ -97,36 +103,36 @@
</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';
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'],
name: "RecentActivitiesTemplate",
emits: ["handleUpdate"],
components: {},
props: ['item'],
props: ["item"],
data() {
return {
editShow: false,
textarea: '',
textarea: "",
isRefresh: false,
pushLanguageTechnique: '', //推送话术
pushLanguageTechnique: "", //推送话术
};
},
computed: {
...mapState('user', ['cser_id', 'cser_name']),
...mapState('game', ['accountSelect', 'bindGameUserList']),
...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
(item) => item.member_id == this.accountSelect,
)?.username,
};
},
......@@ -156,10 +162,10 @@ export default {
user_id: this.cser_id,
user_name: this.cser_name,
});
this.$message.success('修改成功');
this.$message.success("修改成功");
queryRoleRecentActivityNotPushNum(this.accountSelect);
this.$emit('handleUpdate');
this.$emit("handleUpdate");
} catch (error) {
this.$message.error(error);
}
......@@ -183,9 +189,9 @@ export default {
try {
corp_activity_procedure_copyUsed({ _id: this._id });
await navigator.clipboard.writeText(this.pushLanguageTechnique);
this.$message.success('复制成功');
this.$message.success("复制成功");
} catch (err) {
console.error('复制失败:', err);
console.error("复制失败:", err);
}
},
......
......@@ -2,86 +2,146 @@
<div class="info-tab-content">
<div class="userDetailsPanel columnFlex">
<div class="content px-[10px]" v-loading="viewLoading">
<div v-if="chatUserDetails.is_phishing_account == 1" class="warnText">
<p>高风险玩家,请立即通知组长!!!!</p>
<p>
①千万不能推转游!!不要发送违禁词汇!!不要发送礼包和告知任何礼包信息!!
</p>
<p>②不能以任何形式推送APP/网页链接,也不可承认有APP/网页端口!!</p>
<div
v-if="chatUserDetails.is_phishing_account == 1"
class="warnText flex"
>
<div>
<svg-icon
class="text-[16px] mt-[4px] mr-[4px] text-[#FF7D00]"
svgName="weiguitongzhi"
></svg-icon>
</div>
<div>
<p class="text-[13px]">高风险玩家,请立即通知组长!!!!</p>
<p class="text-[12px]">
①千万不能推转游!!不要发送违禁词汇!!不要发送礼包和告知任何礼包信息!!
</p>
<p class="text-[12px]">
②不能以任何形式推送APP/网页链接,也不可承认有APP/网页端口!!
</p>
</div>
</div>
<div v-if="change_appraisal" class="warnText">
<div v-if="change_appraisal" class="warnText flex">
<div>
<svg-icon
class="text-[16px] mt-[4px] mr-[4px] text-[#FF7D00]"
svgName="weiguitongzhi"
></svg-icon>
</div>
<p>钓鱼号 禁止转端通知组长!</p>
</div>
<div v-else-if="gameUserInfo.exp_ip" class="warnText">
<div v-else-if="gameUserInfo.exp_ip" class="warnText flex">
<div>
<svg-icon
class="text-[16px] mt-[4px] mr-[4px] text-[#FF7D00]"
svgName="weiguitongzhi"
></svg-icon>
</div>
<p>高风险用户,禁止转端 !!!</p>
</div>
<!-- 会话内容存档状态 -->
<div
class="archive-status"
class="archive-status flex"
v-if="agreeStatus !== 'Agree' || !hasPermit"
>
<p v-if="agreeStatus !== 'Agree'">当前微信用户未开启会话内容存档</p>
<p v-if="!hasPermit">当前客服号未授权开启会话内容存档</p>
<i
class="el-icon-info text-[16px] pt-[6px] mr-[4px] text-[#909399]"
></i>
<div class="text-[#909399]">
<p v-if="agreeStatus !== 'Agree'" class="!text-[#909399]">
当前微信用户未开启会话内容存档
</p>
<p v-if="!hasPermit" class="!text-[#909399]">
当前客服号未授权开启会话内容存档
</p>
</div>
</div>
<div class="item rowFlex">
<div
class="item rowFlex justify-between pb-[12px] border-b-[1px] border-solid border-[#EBEDF0]"
>
<!-- 公共的信息 -->
<el-image
fit="fill"
draggable="false"
style="-webkit-user-drag: none"
:src="chatUserDetails.avatar"
class="tableImage"
></el-image>
<div class="columnFlex">
<div class="rowFlex" style="margin-bottom: 3px">
<p class="text" style="font-weight: 600">
{{ chatUserDetails.name }}
</p>
<span
v-if="chatUserDetails.add_way_text"
style="color: #09b159; margin-left: 10px"
>@{{ chatUserDetails.add_way_text }}</span
<div class="flex">
<el-image
fit="fill"
draggable="false"
style="-webkit-user-drag: none"
:src="chatUserDetails.avatar"
class="tableImage"
></el-image>
<div class="columnFlex">
<div class="rowFlex" style="margin-bottom: 3px">
<p class="text" style="font-weight: 600">
{{ chatUserDetails.name }}
</p>
<span
v-if="chatUserDetails.add_way_text"
style="color: #09b159; margin-left: 10px"
>@{{ chatUserDetails.add_way_text }}</span
>
</div>
<!-- 游戏模块特有 -->
<div
v-if="accountSelect && accountSelect !== ''"
class="rowFlex columnCenter"
style="margin-top: 3px"
>
<vipLevel :gameUserInfo="gameUserInfo" />
<!-- <el-button-group>
<el-button type="text" @click="zyouUnBindConfirm"
>解绑</el-button
>
<el-button
v-if="!chatUserDetails.bind_cser"
type="text"
@click="relationKfh"
>关联客服</el-button
>
<el-button type="text" v-if="false" @click="errorHandle"
>误操作</el-button
>
</el-button-group> -->
</div>
</div>
<!-- 游戏模块特有 -->
</div>
<el-dropdown trigger="click" class="h-[16px]">
<div
v-if="accountSelect && accountSelect !== ''"
class="rowFlex columnCenter"
style="margin-top: 3px"
class="cursor-pointer h-[16px] w-[16px] font-bold self-center flex items-center"
>
<vipLevel :gameUserInfo="gameUserInfo" />
<el-button-group>
<el-button type="text" @click="zyouUnBindConfirm"
>解绑</el-button
>
<!-- <el-button type="text" size="mini" @click="autoResetPassword">修改密码</el-button>
<el-button type="text" size="mini" @click="changePhoneClick">修改手机号</el-button> -->
<el-button
v-if="!chatUserDetails.bind_cser"
type="text"
@click="relationKfh"
>关联客服</el-button
>
<el-button type="text" v-if="false" @click="errorHandle"
>误操作</el-button
>
</el-button-group>
<i class="text-[16px] el-icon-more"></i>
</div>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>
<span @click="zyouUnBindConfirm"> 解绑 </span>
</el-dropdown-item>
<el-dropdown-item v-if="!chatUserDetails.bind_cser">
<span @click="relationKfh"> 关联客服 </span>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
<div class="item rowFlex columnCenter">
<div class="rowFlex columnCenter">
<span class="label" style="min-width: 45px">备注:</span>
<p v-if="!showInputRemark" class="text" style="max-width: 170px">
{{
chatUserDetails.remark && chatUserDetails.remark != ""
<ModificationBox
:text="
chatUserDetails.remark && chatUserDetails.remark != ''
? chatUserDetails.remark
: chatUserDetails.name
}}
</p>
"
@confirm="handleInputRemark"
>
<p v-if="!showInputRemark" class="text" style="max-width: 170px">
{{
chatUserDetails.remark && chatUserDetails.remark != ""
? chatUserDetails.remark
: chatUserDetails.name
}}
</p>
</ModificationBox>
</div>
<el-input
<!-- <el-input
v-if="showInputRemark"
v-model="showInputRemarkValue"
class="showInputRemarkInput"
......@@ -93,7 +153,7 @@
class="el-icon-edit icon"
style="font-size: 14px"
@click="editRemark"
></i>
></i> -->
</div>
<div class="item rowFlex columnCenter" v-if="lastTime">
<div class="rowFlex columnCenter">
......@@ -206,11 +266,11 @@
>+{{ chatUserDetails.tag_group.length - 1 }}
</el-button>
</el-tooltip>
<iconpark-icon
name="ziliao-tianjia-jb82dh2k"
<svg-icon
svgName="ziliao-tianjia-jb82dh2k"
class="group-hover:visible invisible text-primary text-[14px] ml-[6px]"
@click="editTags"
></iconpark-icon>
></svg-icon>
</div>
</div>
</div>
......@@ -270,6 +330,8 @@ import { sendChatMessage } from "@/utils/index.js";
import { getToken, removeToken } from "@/utils/auth";
import vipLevel from "./gameInfo/vipLevel.vue";
import Cookies from "js-cookie";
import ModificationBox from "@/components/common/ModificationBox.vue";
export default {
name: "info",
components: {
......@@ -278,6 +340,7 @@ export default {
shareInfo,
selectTag,
vipLevel,
ModificationBox,
},
props: {
// 用户详情
......@@ -560,6 +623,7 @@ export default {
// 处理备注输入
handleInputRemark(val) {
this.showInputRemark = false;
this.showInputRemarkValue = val;
this.chatUserDetails.remark = this.showInputRemarkValue;
const data = {
userid: this.chatUserDetails.userid,
......@@ -641,31 +705,35 @@ export default {
height: 100%;
background-color: #fff;
border-radius: 4px;
overflow: hidden;
.warnText {
width: 100%;
padding-top: 10px !important;
border-radius: 0 !important;
color: #ff7d00;
background: #fffbf5;
width: calc(100% + 20px) !important;
margin-bottom: 0 !important;
margin-left: -10px;
height: auto;
font-weight: 600;
font-size: 18px;
p {
color: #f56c6c;
line-height: 25px;
}
font-size: 13px;
padding: 4px 10px;
}
.archive-status {
margin-bottom: 15px;
padding: 8px;
padding: 4px 10px;
background-color: #f8f8f8;
border-radius: 4px;
font-size: 14px;
line-height: 20px;
// border-radius: 4px;
font-size: 12px;
width: calc(100% + 20px);
margin-left: -10px;
p {
margin: 5px 0;
color: #f56c6c;
font-weight: 600;
}
}
......@@ -688,7 +756,6 @@ export default {
margin-bottom: 10px;
p {
color: #f56c6c;
line-height: 25px;
}
}
......
......@@ -57,12 +57,12 @@
</el-button>
</el-tooltip>
</div>
<iconpark-icon
name="ziliao-tianjia-jb82dh2k"
<svg-icon
svgName="ziliao-tianjia-jb82dh2k"
class="invisible text-primary text-[14px] ml-[6px]"
:class="{ 'group-hover:visible': item.label_type == 2 }"
@click="addTag(item.label)"
></iconpark-icon>
></svg-icon>
</div>
<Empty />
</div>
......@@ -250,7 +250,7 @@ export default {
this.loading = true;
try {
const weixin_blongs_id = this.weixin_blongs_id_list.map(
(item) => item.value
(item) => item.value,
);
const res = await roleGetRoleLabel({
member_id: this.accountSelect,
......@@ -309,7 +309,7 @@ export default {
async searchLabel(query) {
try {
const weixin_blongs_id = this.weixin_blongs_id_list.map(
(item) => item.value
(item) => item.value,
);
const res = await roleLabelSearch({
label_name: query.trim() || "",
......@@ -346,7 +346,7 @@ export default {
? this.searchValue
: [];
const hasSelectedInThisGroup = group.children.some((child) =>
selectedIds.includes(child.label_id)
selectedIds.includes(child.label_id),
);
if (hasSelectedInThisGroup) {
......@@ -436,7 +436,7 @@ export default {
if (value && Array.isArray(value) && value.length > 0) {
// 获取当前标签组的标签
const currentGroupLabels = this.roleLabelList.find(
(item) => Number(item.label_type) === 2
(item) => Number(item.label_type) === 2,
).label;
// 获取所有选中标签的信息
......@@ -446,13 +446,13 @@ export default {
this.searchOptions.forEach((group) => {
// 找出该组中被选中的标签
const selectedInGroup = group.children.filter((child) =>
value.includes(child.label_id)
value.includes(child.label_id),
);
// 如果是单选标签组且选中了多个,只保留第一个
if (group.select_type === 1 && selectedInGroup.length > 1) {
this.$message.warning(
`标签组"${group.label_name}"为单选,只能选择一个标签`
`标签组"${group.label_name}"为单选,只能选择一个标签`,
);
// 只添加第一个选中的标签
selectedLabels.push(selectedInGroup[0]);
......@@ -470,11 +470,11 @@ export default {
// 检查selectedLabels中的标签组是否与currentGroupLabels中的标签组重复
if (currentGroupLabels && currentGroupLabels.length > 0) {
const existingGroupIds = currentGroupLabels.map(
(label) => label.label_group_id
(label) => label.label_group_id,
);
const hasConflict = selectedLabels.some((label) =>
existingGroupIds.includes(label.label_group_id)
existingGroupIds.includes(label.label_group_id),
);
if (hasConflict) {
......@@ -507,7 +507,7 @@ export default {
// 找出所有单选标签组
const singleSelectGroups = this.searchOptions.filter(
(group) => group.select_type === 1
(group) => group.select_type === 1,
);
// 检查单选标签组是否有全选操作
......@@ -517,14 +517,14 @@ export default {
// 检查当前组中选中的标签数量
const selectedInThisGroup = groupLabelIds.filter((id) =>
value.includes(id)
value.includes(id),
);
// 如果选中的标签数量大于1,说明可能是全选操作
if (selectedInThisGroup.length > 1) {
// 提示用户只能选择一个标签
this.$message.warning(
`标签组"${group.label_name}"为单选,只能选择一个标签`
`标签组"${group.label_name}"为单选,只能选择一个标签`,
);
// 清空该组的选择
......
......@@ -18,12 +18,19 @@
trigger="hover"
content="手动更新当前用户的智能标签,每个用户半个小时仅能更新一次"
>
<i
<!-- <i
slot="reference"
class="el-icon-refresh refreshList"
:class="isRefresh ? 'refreshListActive' : ''"
@click="refreshTag"
></i> -->
<svg-icon
svgName="icon-zhongxinshengcheng"
slot="reference"
@click="refreshTag"
></i>
class="refreshList text-[16px]"
:class="isRefresh ? 'refreshListActive' : ''"
/>
</el-popover>
</div>
<ZyouTag :game-user-info="gameUserInfo" :account-select="accountSelect" />
......@@ -62,12 +69,13 @@
>
<!-- changeUser -->
<div slot="reference" class="rowFlex columnCenter changeUser">
<p>
<svg-icon svgName="ziliao-qiehuan" />
<!-- <p>
<i class="el-icon-sort-down"></i>
</p>
<p>
<i class="el-icon-sort-up"></i>
</p>
</p> -->
</div>
</el-popconfirm>
</div>
......@@ -84,12 +92,13 @@
@confirm="changeNameFn"
>
<div slot="reference" class="rowFlex columnCenter changeUser">
<p>
<svg-icon svgName="ziliao-qiehuan" />
<!-- <p>
<i class="el-icon-sort-down"></i>
</p>
<p>
<i class="el-icon-sort-up"></i>
</p>
</p> -->
</div>
</el-popconfirm>
</div>
......@@ -110,12 +119,13 @@
slot="reference"
class="rowFlex columnCenter changeUser"
>
<p>
<svg-icon svgName="ziliao-qiehuan" />
<!-- <p>
<i class="el-icon-sort-down"></i>
</p>
<p>
<i class="el-icon-sort-up"></i>
</p>
</p> -->
</div>
</el-popconfirm>
</div>
......@@ -169,35 +179,53 @@
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">是否愿意转端:</span>
<p class="text">
<el-radio-group
<p class="text flex items-center">
{{ chatUserDetails.transferred == 0 ? "是" : "否" }}
<svg-icon
svgName="ziliao-qiehuan"
class="text-primary text-[18px] ml-[6px]"
@click="
toTransfer(
chatUserDetails.transferred == 0
? (chatUserDetails.transferred = 1)
: (chatUserDetails.transferred = 0),
)
"
/>
<!-- <el-radio-group
v-model="chatUserDetails.transferred"
@change="toTransfer"
>
<el-radio :label="0"></el-radio>
<el-radio :label="1"></el-radio>
</el-radio-group>
</el-radio-group> -->
</p>
</div>
</div>
<div class="item rowFlex columnCenter">
<div class="rowFlex columnCenter">
<span class="label">手机号:</span>
<p v-if="!showUserMobile" class="text">{{ gameUserInfo.mobile }}</p>
<span class="label flex-shrink-0">手机号:</span>
<ModificationBox
:text="gameUserInfo.mobile"
:isInput="true"
@confirm="changeUserMobile"
>
<p v-if="!showUserMobile" class="text">{{ gameUserInfo.mobile }}</p>
</ModificationBox>
</div>
<el-input
<!-- <el-input
v-if="showUserMobile"
v-model="newMobileValue"
style="width: 120px; margin-left: 10px"
@change="changeUserMobile"
@blur="showUserMobile = false"
></el-input>
></el-input> -->
<!-- 暂时禁止用户修改手机号 -->
<i
<!-- <i
class="el-icon-edit icon"
style="font-size: 14px"
@click="editUserMobile"
></i>
></i> -->
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
......@@ -311,6 +339,7 @@ import moment from "moment";
import ZyouTag from "./ZyouTag.vue";
import { debounce } from "@/utils";
import LastLogin from "@/views/components/quickSendGame/sendGame/lastLogin.vue";
import ModificationBox from "@/components/common/ModificationBox.vue";
export default {
name: "gameUserInfo",
......@@ -318,6 +347,7 @@ export default {
ZyouTag,
MarketingPanel,
LastLogin,
ModificationBox,
},
props: ["gameUserInfo", "chatUserDetails"],
data() {
......@@ -467,7 +497,7 @@ export default {
});
},
// 修改用户手机号
changeUserMobile() {
changeUserMobile(v) {
if (
!/^1((3[0-9])|(4[1579])|(5[0-9])|(6[6])|(7[0-9])|(8[0-9])|(9[0-9]))\d{8}$/.test(
this.newMobileValue,
......@@ -476,6 +506,7 @@ export default {
this.$message.warning("请填写正确的手机号");
return false;
}
this.newMobileValue = v;
this.gameUserInfo.mobile =
this.newMobileValue.substr(0, 3) +
"****" +
......@@ -533,7 +564,7 @@ export default {
}
.changeUser {
font-size: 18px;
transform: rotate(90deg);
// transform: rotate(90deg);
color: #3491fa;
margin-left: 10px;
margin-top: -5px;
......@@ -633,6 +664,9 @@ export default {
cursor: pointer;
font-size: 18px;
margin-left: 20px;
&:focus {
outline: none;
}
}
.refreshListActive {
animation: rotate 0.5s linear infinite;
......
<template>
<div class="newPage">
<!-- 共享信息 -->
<div v-if="userList.length > 0" class="item rowFlex columnCenter">
<!-- <div class="rowFlex columnCenter">
<div class="newPage">
<!-- 共享信息 -->
<div v-if="userList.length > 0" class="item rowFlex columnCenter">
<!-- <div class="rowFlex columnCenter">
<span class="label">共享信息:</span>
<i style="margin-left: 10px; font-size: 20px; color: #0ac358; cursor: pointer" class="el-icon-circle-plus-outline" type="primary" @click="addGroupText"></i>
</div> -->
<!-- 显示第一个用户的共享信息 -->
<div v-if="userList.length > 0" class="userList rowFlex">
<p class="label hidden">{{ userList[0].zq_user_name }} -- {{ userList[0].name }}</p>
<div style="margin-bottom:10px;" class="columnFlex ">
<div v-for="(item,index) in userList[0].text" :key="index+'1'" class="keyWordsItem rowFlex columnCenter">
<el-input v-model="item.text" type="textarea" :disabled="chatUserDetails.userid !== userList[0].userid || userList[0].zq_user_id!== userInfo.id" placeholder="请输入共享信息" @change="inputBlur(0,index)"> </el-input>
<div v-if="chatUserDetails.userid == userList[0].userid && userList[0].zq_user_id=== userInfo.id">
<i v-if="index==0" style="margin-left:10px;font-size:20px;color:#0AC358;cursor: pointer;" class="el-icon-circle-plus-outline" type="primary" @click="addInputItem(0,index)"></i>
<i v-else style="margin-left:10px;font-size:20px;color:#0AC358;cursor: pointer;" class="el-icon-remove-outline" type="primary" @click="removeInput(0,index)"></i>
</div>
<!-- 显示第一个用户的共享信息 -->
<div v-if="userList.length > 0" class="userList rowFlex">
<div class="label flex">
{{ userList[0].zq_user_name }}
<el-tooltip effect="dark" content="共享信息" placement="top">
<svg-icon
svgName="icon-gongxiangxinxi"
class="text-[18px] mx-[6px]"
/>
</el-tooltip>
{{ userList[0].name }}
</div>
<div style="margin-bottom: 10px" class="columnFlex">
<div
v-for="(item, index) in userList[0].text"
:key="index + '1'"
class="keyWordsItem rowFlex columnCenter"
>
<el-input
v-model="item.text"
type="textarea"
:disabled="
chatUserDetails.userid !== userList[0].userid ||
userList[0].zq_user_id !== userInfo.id
"
placeholder="请输入共享信息"
@change="inputBlur(0, index)"
>
</el-input>
<div
v-if="
chatUserDetails.userid == userList[0].userid &&
userList[0].zq_user_id === userInfo.id
"
>
<i
v-if="index == 0"
style="
margin-left: 10px;
font-size: 20px;
color: #0ac358;
cursor: pointer;
"
class="el-icon-circle-plus-outline"
type="primary"
@click="addInputItem(0, index)"
></i>
<i
v-else
style="
margin-left: 10px;
font-size: 20px;
color: #0ac358;
cursor: pointer;
"
class="el-icon-remove-outline"
type="primary"
@click="removeInput(0, index)"
></i>
</div>
</div>
</div>
<!-- 如果有多个用户,显示+n -->
<el-popover
v-if="userList.length > 1"
placement="bottom"
trigger="hover"
popper-class="share-info-popover"
</div>
<!-- 如果有多个用户,显示+n -->
<el-popover
v-if="userList.length > 1"
placement="bottom"
trigger="hover"
popper-class="share-info-popover"
>
<div
class="share-info-popover-content"
style="max-height: 600px; overflow-y: auto"
>
<div class="share-info-popover-content" style="max-height: 600px; overflow-y: auto;">
<div v-for="(user, userIndex) in userList.slice(1)" :key="userIndex" class="share-info-user">
<p class="share-info-username">{{ user.zq_user_name }} -- {{ user.name }}</p>
<div class="share-info-items">
<div v-for="(item, itemIndex) in user.text" :key="itemIndex" class="share-info-item">
<el-input
v-model="item.text"
type="textarea"
:disabled="chatUserDetails.userid !== user.userid || user.zq_user_id !== userInfo.id"
placeholder="请输入共享信息"
@change="inputBlur(userIndex + 1, itemIndex)"
></el-input>
<div v-if="chatUserDetails.userid == user.userid && user.zq_user_id === userInfo.id">
<i v-if="itemIndex==0" style="margin-left:10px;font-size:20px;color:#0AC358;cursor: pointer;" class="el-icon-circle-plus-outline" @click="addInputItem(userIndex + 1, itemIndex)"></i>
<i v-else style="margin-left:10px;font-size:20px;color:#0AC358;cursor: pointer;" class="el-icon-remove-outline" @click="removeInput(userIndex + 1, itemIndex)"></i>
</div>
<div
v-for="(user, userIndex) in userList.slice(1)"
:key="userIndex"
class="share-info-user"
>
<div class="share-info-username flex">
{{ user.zq_user_name }}
<el-tooltip effect="dark" content="共享信息" placement="top">
<svg-icon
svgName="icon-gongxiangxinxi"
class="text-[18px] mx-[6px]"
/>
</el-tooltip>
{{ user.name }}
</div>
<div class="share-info-items">
<div
v-for="(item, itemIndex) in user.text"
:key="itemIndex"
class="share-info-item"
>
<el-input
v-model="item.text"
type="textarea"
:disabled="
chatUserDetails.userid !== user.userid ||
user.zq_user_id !== userInfo.id
"
placeholder="请输入共享信息"
@change="inputBlur(userIndex + 1, itemIndex)"
></el-input>
<div
v-if="
chatUserDetails.userid == user.userid &&
user.zq_user_id === userInfo.id
"
>
<!-- <i
v-if="itemIndex == 0"
style="
margin-left: 10px;
font-size: 20px;
color: #0ac358;
cursor: pointer;
"
class="el-icon-circle-plus-outline"
@click="addInputItem(userIndex + 1, itemIndex)"
></i> -->
<svg-icon
@click="addInputItem(userIndex + 1, itemIndex)"
v-if="itemIndex == 0"
svgName="tianjia"
class="text-[20px] cursor-pointer text-primary ml-[10px]"
/>
<svg-icon
@click="removeInput(userIndex + 1, itemIndex)"
v-else
svgName="shanchu"
class="text-[20px] cursor-pointer text-[#F53F3F] ml-[10px]"
/>
<!-- <i
v-else
style="
margin-left: 10px;
font-size: 20px;
color: #0ac358;
cursor: pointer;
"
class="el-icon-remove-outline"
@click="removeInput(userIndex + 1, itemIndex)"
></i> -->
</div>
</div>
</div>
</div>
<div slot="reference" class="more-users-button">+{{ userList.length - 1 }}</div>
</el-popover>
</div>
</div>
<div slot="reference" class="more-users-button">
+{{ userList.length - 1 }}
</div>
</el-popover>
</div>
</template>
<script>
import { shareInfoUpsert, shareInfoDel } from '@/api/works'
import { mapState } from 'vuex'
export default {
name: 'shareInfo',
props: ['chatUserDetails'],
data() {
return {
inputList: [],
userList: []
}
},
computed: {
...mapState('user', ['userInfo'])
</div>
</template>
<script>
import { shareInfoUpsert, shareInfoDel } from "@/api/works";
import { mapState } from "vuex";
export default {
name: "shareInfo",
props: ["chatUserDetails"],
data() {
return {
inputList: [],
userList: [],
};
},
computed: {
...mapState("user", ["userInfo"]),
},
watch: {
chatUserDetails(newVal, oldVal) {
this.handleUserList();
},
watch: {
chatUserDetails(newVal, oldVal) {
this.handleUserList()
}
},
mounted() {
this.handleUserList()
},
methods: {
handleUserList() {
if (this.chatUserDetails.share_info && this.chatUserDetails.share_info.length > 0) {
const item = this.chatUserDetails.share_info.find(item => item.userid === this.chatUserDetails.userid && item.zq_user_id === this.userInfo.id)
if (!item) {
this.userList = [...this.chatUserDetails.share_info, { zq_user_name: this.userInfo.username, zq_user_id: this.userInfo.id, userid: this.chatUserDetails.userid, name: this.chatUserDetails?.user?.name || '', text: [{ id: '', text: '' }] }]
} else {
this.userList = this.chatUserDetails.share_info
}
},
mounted() {
this.handleUserList();
},
methods: {
handleUserList() {
if (
this.chatUserDetails.share_info &&
this.chatUserDetails.share_info.length > 0
) {
const item = this.chatUserDetails.share_info.find(
(item) =>
item.userid === this.chatUserDetails.userid &&
item.zq_user_id === this.userInfo.id,
);
if (!item) {
this.userList = [
...this.chatUserDetails.share_info,
{
zq_user_name: this.userInfo.username,
zq_user_id: this.userInfo.id,
userid: this.chatUserDetails.userid,
name: this.chatUserDetails?.user?.name || "",
text: [{ id: "", text: "" }],
},
];
} else {
this.userList = [{ zq_user_name: this.userInfo.username, zq_user_id: this.userInfo.id, userid: this.chatUserDetails.userid, name: this.chatUserDetails?.user?.name || '', text: [{ id: '', text: '' }] }]
this.userList = this.chatUserDetails.share_info;
}
},
addGroupText() {
if (this.userList.length > 0) {
const user = this.userList.find(item => {
if (this.chatUserDetails.user.name === item.zq_user_name) {
return item
}
})
if (user !== -1) {
this.$message.warning(user.zq_user_name + '共享信息已存在')
} else {
this.userList.push({ zq_user_name: this.chatUserDetails.user.name, text: [{ _id: '', text: '' }] })
} else {
this.userList = [
{
zq_user_name: this.userInfo.username,
zq_user_id: this.userInfo.id,
userid: this.chatUserDetails.userid,
name: this.chatUserDetails?.user?.name || "",
text: [{ id: "", text: "" }],
},
];
}
},
addGroupText() {
if (this.userList.length > 0) {
const user = this.userList.find((item) => {
if (this.chatUserDetails.user.name === item.zq_user_name) {
return item;
}
});
if (user !== -1) {
this.$message.warning(user.zq_user_name + "共享信息已存在");
} else {
this.userList.push({ zq_user_name: this.chatUserDetails.user.name, text: [{ _id: '', text: '' }] })
this.userList.push({
zq_user_name: this.chatUserDetails.user.name,
text: [{ _id: "", text: "" }],
});
}
},
shareInfoUpsert(_id, text) {
if (text && text.trim() == '') {
this.$message.warning('请输入内容')
return false
} else {
this.userList.push({
zq_user_name: this.chatUserDetails.user.name,
text: [{ _id: "", text: "" }],
});
}
},
shareInfoUpsert(_id, text) {
if (text && text.trim() == "") {
this.$message.warning("请输入内容");
return false;
}
const data = {
_id: _id || "",
userid: this.chatUserDetails.userid,
external_userid: this.chatUserDetails.external_userid,
text: text.trim(),
};
shareInfoUpsert(data).then((res) => {
if (res.status_code == 1) {
this.$message.success("保存成功");
}
const data = {
_id: _id || '',
});
},
inputBlur(k, index) {
// 修改信息
this.shareInfoUpsert(
this.userList[k]?.text[index]._id,
this.userList[k]?.text[index].text,
);
},
removeInput(k, index) {
if (this.userList[k]?.text[index]?._id !== "") {
this.shareInfoDel({
_id: this.userList[k].text[index]._id,
userid: this.chatUserDetails.userid,
external_userid: this.chatUserDetails.external_userid,
text: text.trim()
}
shareInfoUpsert(data).then(res => {
if (res.status_code == 1) {
this.$message.success('保存成功')
}
})
},
inputBlur(k, index) {
// 修改信息
this.shareInfoUpsert(this.userList[k]?.text[index]._id, this.userList[k]?.text[index].text)
},
removeInput(k, index) {
if (this.userList[k]?.text[index]?._id !== '') {
this.shareInfoDel({ _id: this.userList[k].text[index]._id, userid: this.chatUserDetails.userid })
// 请求删除接口
} else {
}
this.userList[k].text.splice(index, 1)
},
// 删除共享信息
shareInfoDel(data) {
shareInfoDel(data).then(res => {
if (res.status_code == 1) {
this.$message.success(res.msg)
}
})
},
// 添加时间点
addInputItem(index) {
this.userList[index].text.push({ _id: '', text: '' })
this.inputList.push({ text: '' })
});
// 请求删除接口
} else {
}
}
}
</script>
<style lang="scss" scoped>
.newPage {
this.userList[k].text.splice(index, 1);
},
// 删除共享信息
shareInfoDel(data) {
shareInfoDel(data).then((res) => {
if (res.status_code == 1) {
this.$message.success(res.msg);
}
});
},
// 添加时间点
addInputItem(index) {
this.userList[index].text.push({ _id: "", text: "" });
this.inputList.push({ text: "" });
},
},
};
</script>
<style lang="scss" scoped>
.newPage {
width: 100%;
height: auto;
.item {
width: 100%;
height: auto;
.item {
width: 100%;
height: auto;
font-size: 14px;
font-weight: 400;
font-size: 14px;
font-weight: 400;
color: #333333;
padding: 10px 0;
transition: all 0.5s;
position: relative;
cursor: pointer;
.tableImage {
width: 40px;
height: 40px;
border-radius: 6px;
margin-right: 10px;
}
.showInputRemarkInput {
width: 200px;
margin-left: 10px;
}
.label {
color: #999999;
width: 120px;
}
.text {
color: #333333;
padding: 10px 0;
transition: all 0.5s;
position: relative;
margin-left: 10px;
word-break: break-all;
max-width: 100%;
}
.icon {
display: none;
position: absolute;
right: 0;
top: 12px;
}
.noBind {
width: 44px;
height: 22px;
border-radius: 4px;
border: 1px solid #3491fa;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #3491fa;
margin-left: 30px;
cursor: pointer;
.tableImage {
width: 40px;
height: 40px;
border-radius: 6px;
margin-right: 10px;
}
.showInputRemarkInput {
width: 200px;
margin-left: 10px;
}
.label {
color: #999999;
width: 120px;
}
.text {
color: #333333;
margin-left: 10px;
word-break: break-all;
max-width: 100%;
}
.icon {
display: none;
position: absolute;
right: 0;
top: 12px;
}
.tags {
width: 250px;
margin-left: 10px;
.tagsItem {
width: 250px;
}
.noBind {
width: 44px;
.tag {
height: 22px;
line-height: 22px;
padding: 0 8px;
background: #ffffff;
border-radius: 4px;
border: 1px solid #3491FA ;
border: 1px solid rgba(0, 0, 0, 0.2);
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #3491FA ;
margin-left: 30px;
cursor: pointer;
}
.tags {
width: 250px;
margin-left: 10px;
.tagsItem {
width: 250px;
}
.tag {
height: 22px;
line-height: 22px;
padding: 0 8px;
background: #ffffff;
border-radius: 4px;
border: 1px solid rgba(0, 0, 0, 0.2);
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #333333;
margin-right: 10px;
margin-bottom: 10px;
}
}
}
.item:hover .icon {
display: block;
}
.userList{
height: auto;
margin-top: 20px;
.label{
color: #333333;
margin-right: 10px;
margin-top: 8px;
}
.keyWordsItem{
margin-bottom: 20px;
}
}
.more-users-button {
display: inline-block;
background-color: #E8F7FF;
color: #3491FA;
padding: 4px 8px;
border-radius: 4px;
margin-top: 10px;
margin-left: 16px;
font-size: 13px;
cursor: pointer;
transition: all 0.3s;
&:hover {
background-color: #d0edff;
margin-bottom: 10px;
}
}
}
</style>
<style>
.share-info-popover {
min-width: 300px;
max-width: 360px;
}
.share-info-popover-content .share-info-user {
margin-bottom: 15px;
padding-bottom: 15px;
border-bottom: 1px dashed #eee;
}
.share-info-popover-content .share-info-user:last-child {
margin-bottom: 0;
padding-bottom: 0;
border-bottom: none;
}
.share-info-popover-content .share-info-username {
font-weight: bold;
margin-bottom: 8px;
color: #333;
.item:hover .icon {
display: block;
}
.share-info-popover-content .share-info-item {
display: flex;
align-items: center;
margin-bottom: 10px;
.userList {
height: auto;
margin-top: 20px;
.label {
margin-right: 10px;
margin-top: 8px;
}
.keyWordsItem {
margin-bottom: 20px;
}
}
.share-info-popover-content .share-info-item:last-child {
margin-bottom: 0;
.more-users-button {
display: inline-block;
background-color: #e8f7ff;
color: #3491fa;
padding: 4px 8px;
border-radius: 4px;
margin-top: 10px;
margin-left: 16px;
font-size: 13px;
cursor: pointer;
transition: all 0.3s;
&:hover {
background-color: #d0edff;
}
}
</style>
\ No newline at end of file
}
</style>
<style>
.share-info-popover {
min-width: 300px;
max-width: 360px;
}
.share-info-popover-content .share-info-user {
margin-bottom: 15px;
padding-bottom: 15px;
border-bottom: 1px dashed #eee;
}
.share-info-popover-content .share-info-user:last-child {
margin-bottom: 0;
padding-bottom: 0;
border-bottom: none;
}
.share-info-popover-content .share-info-username {
font-weight: bold;
margin-bottom: 8px;
color: #333;
}
.share-info-popover-content .share-info-item {
display: flex;
align-items: center;
margin-bottom: 10px;
}
.share-info-popover-content .share-info-item:last-child {
margin-bottom: 0;
}
</style>
......@@ -19,14 +19,14 @@
</div>
</template>
<script>
import Info from './components/Info.vue';
import roleInfo from '@/views/roleInfo.vue';
import orderList from '@/views/orderList.vue';
import { mapState, mapMutations } from 'vuex';
import { createRoleRecentActivityNotPushNum } from '@/views/hooks/useGetCount';
import Cookies from 'js-cookie';
import Info from "./components/Info.vue";
import roleInfo from "@/views/roleInfo.vue";
import orderList from "@/views/orderList.vue";
import { mapState, mapMutations } from "vuex";
import { createRoleRecentActivityNotPushNum } from "@/views/hooks/useGetCount";
import Cookies from "js-cookie";
export default {
name: 'userInfo',
name: "userInfo",
components: {
Info,
roleInfo,
......@@ -39,13 +39,13 @@ export default {
},
data() {
return {
activeTab: 'info',
activeTab: "info",
instance: null,
totalNum: 0,
};
},
computed: {
...mapState('game', ['chatUserInfo', 'accountSelect']),
...mapState("game", ["chatUserInfo", "accountSelect"]),
},
created() {
// 初始化 vuex 中的值
......@@ -57,10 +57,10 @@ export default {
});
},
methods: {
...mapMutations('user', ['set_userInfo']),
...mapMutations("user", ["set_userInfo"]),
async initInstance() {
this.instance = await createRoleRecentActivityNotPushNum(
this.accountSelect
this.accountSelect,
);
this.totalNum = this.instance.getTotalNum();
......@@ -70,10 +70,10 @@ export default {
},
initVuexValue() {
const userinfo = {
cser_id: Cookies.get('cser_id'),
cser_name: Cookies.get('cser_name'),
username: Cookies.get('cser_name'),
id: Cookies.get('cser_id'),
cser_id: Cookies.get("cser_id"),
cser_name: Cookies.get("cser_name"),
username: Cookies.get("cser_name"),
id: Cookies.get("cser_id"),
};
this.set_userInfo(userinfo);
},
......@@ -95,7 +95,7 @@ export default {
width: 100%;
::v-deep .el-tabs__header {
margin-bottom: 15px;
margin-bottom: 0;
padding: 0 10px;
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论