提交 cf8be353 作者: 毛细亚

合并分支 'release' 到 'master'

增加开发模式

查看合并请求 !3
<!DOCTYPE html> <!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>company_app</title><script src="https://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"></script><script defer="defer" src="static/js/chunk-vendors.c5338b55.js"></script><script defer="defer" src="static/js/app.493a4164.js"></script><link href="static/css/chunk-vendors.34a02360.css" rel="stylesheet"><link href="static/css/app.da449827.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but company_app doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
<html lang=""> \ No newline at end of file
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="favicon.ico">
<title>company_app</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 defer src="static/js/chunk-vendors.js"></script><script defer src="static/js/app.js"></script></head>
<body>
<noscript>
<strong>We're sorry but company_app doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
</body>
</html>
<template> <template>
<div id="app" class="mobile-app-wrapper"> <div id="app" class="mobile-app-wrapper">
<Debug />
<div class="mobile-menu-bar" v-if="token && external_userid && showMemberId"> <div class="mobile-menu-bar" v-if="token && external_userid && showMemberId">
<!-- 临时调试信息 --> <!-- 临时调试信息 -->
<el-menu <el-menu :default-active="selectedPath" mode="horizontal" class="mobile-el-menu" background-color="#fff" router
:default-active="selectedPath" @select="handleSelect">
mode="horizontal"
class="mobile-el-menu"
background-color="#fff"
router
@select="handleSelect"
>
<el-menu-item v-for="item in menuList" :key="item.path" :index="item.path" class="mobile-menu-item"> <el-menu-item v-for="item in menuList" :key="item.path" :index="item.path" class="mobile-menu-item">
{{ item.label }} {{ item.label }}
</el-menu-item> </el-menu-item>
</el-menu> </el-menu>
<!-- 绑定的 w 账号 --> <!-- 绑定的 w 账号 -->
<bindUserList /> <bindUserList />
</div> </div>
<div class="mobile-content"> <div class="mobile-content">
<router-view></router-view> <router-view></router-view>
...@@ -26,12 +20,15 @@ ...@@ -26,12 +20,15 @@
<script> <script>
import bindUserList from '@/views/components/bindGameAccount/bindUserList.vue' import bindUserList from '@/views/components/bindGameAccount/bindUserList.vue'
import { getToken } from '@/utils/auth' import { getToken } from '@/utils/auth'
import { mapState } from 'vuex' import { mapState, mapMutations } from 'vuex'
import Cookies from 'js-cookie' import Cookies from 'js-cookie'
import { getParams } from '@/utils/index'
import Debug from '@/components/debug.vue'
export default { export default {
name: 'App', name: 'App',
components: { components: {
bindUserList bindUserList,
Debug
}, },
data() { data() {
return { return {
...@@ -61,12 +58,12 @@ export default { ...@@ -61,12 +58,12 @@ export default {
// path: '/addressBook' // path: '/addressBook'
// }, // },
], ],
selectedPath: '/userInfo', selectedPath: '/userInfo',
showMemberId: false, showMemberId: false,
} }
}, },
computed:{ computed: {
...mapState('user',['external_userid','token']), ...mapState('user', ['external_userid', 'token']),
}, },
watch: { watch: {
'$route.path'(val) { '$route.path'(val) {
...@@ -84,7 +81,7 @@ export default { ...@@ -84,7 +81,7 @@ export default {
if (newVal) { if (newVal) {
this.$nextTick(() => { this.$nextTick(() => {
this.showMemberId = true this.showMemberId = true
console.log('external_userid 已设置:', newVal, window.location.href, this.token,Cookies.get('token')) console.log('external_userid 已设置:', newVal, window.location.href, this.token, Cookies.get('token'))
// 强制更新组件 // 强制更新组件
this.$forceUpdate() this.$forceUpdate()
}) })
...@@ -93,7 +90,15 @@ export default { ...@@ -93,7 +90,15 @@ export default {
immediate: true immediate: true
} }
}, },
created() {
const urlParams = getParams();
// 每次进入页面都缓存corp_id
if (urlParams.corp_id) {
this.cacheCorp_id(urlParams.corp_id) // 缓存 corp_id
}
},
mounted() { mounted() {
this.initVuexValue()
// 初始化时处理路径 // 初始化时处理路径
const currentPath = this.$route.path const currentPath = this.$route.path
if (currentPath === '/' || currentPath === '' || currentPath === '/index.html') { if (currentPath === '/' || currentPath === '' || currentPath === '/index.html') {
...@@ -103,20 +108,43 @@ export default { ...@@ -103,20 +108,43 @@ export default {
} }
console.log('创建时路径:', currentPath, '选中路径:', this.selectedPath) console.log('创建时路径:', currentPath, '选中路径:', this.selectedPath)
}, },
methods:{ methods: {
...mapMutations('user', ['set_userid', 'set_corp_id', 'set_token', 'set_cser_info', 'set_cser_id', 'set_cser_name', 'set_userInfo']),
// 设置缓存
cacheCorp_id(corp_id) {
Cookies.set('corp_id', corp_id, { expires: 7 })
this.set_corp_id(corp_id)
},
initVuexValue() {
this.set_userid(Cookies.get('userid'))
this.set_corp_id(Cookies.get('corp_id'))
this.set_token(Cookies.get('token'))
this.set_cser_id(Cookies.get('cser_id'))
this.set_cser_name(Cookies.get('cser_name'))
const userinfo = {
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)
const cser_info = Cookies.get('cser_info')
cser_info ? this.set_cser_info(JSON.parse(cser_info)) : this.set_cser_info({})
},
handleSelect(key, keyPath) { handleSelect(key, keyPath) {
console.log('菜单选择:', key, keyPath, window.location.href) console.log('菜单选择:', key, keyPath, window.location.href)
} }
} },
} }
</script> </script>
<style scoped> <style scoped>
#app{ #app {
width: 100%; width: 100%;
height: 100%; height: 100%;
background: #fff; background: #fff;
} }
.mobile-app-wrapper { .mobile-app-wrapper {
width: 100%; width: 100%;
margin: 0 auto; margin: 0 auto;
...@@ -124,14 +152,16 @@ export default { ...@@ -124,14 +152,16 @@ export default {
min-height: 100vh; min-height: 100vh;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
box-shadow: 0 0 12px rgba(0,0,0,0.04); box-shadow: 0 0 12px rgba(0, 0, 0, 0.04);
} }
.mobile-menu-bar { .mobile-menu-bar {
background: #fff; background: #fff;
border-bottom: 1px solid #f0f0f0; border-bottom: 1px solid #f0f0f0;
box-shadow: 0 2px 8px #f0f1f2; box-shadow: 0 2px 8px #f0f1f2;
z-index: 10; z-index: 10;
} }
.mobile-el-menu { .mobile-el-menu {
border: none; border: none;
background: #fff; background: #fff;
...@@ -139,8 +169,9 @@ export default { ...@@ -139,8 +169,9 @@ export default {
justify-content: flex-start; justify-content: flex-start;
padding-left: 16px; padding-left: 16px;
} }
.mobile-menu-item { .mobile-menu-item {
font-size: 14px ; font-size: 14px;
padding: 0 16px !important; padding: 0 16px !important;
min-width: 0; min-width: 0;
flex: none; flex: none;
...@@ -150,23 +181,28 @@ export default { ...@@ -150,23 +181,28 @@ export default {
margin-right: 8px; margin-right: 8px;
transition: all 0.3s ease; transition: all 0.3s ease;
} }
.mobile-el-menu .el-menu-item.is-active { .mobile-el-menu .el-menu-item.is-active {
font-weight: bold; font-weight: bold;
} }
.mobile-content { .mobile-content {
flex: 1; flex: 1;
overflow-y: auto; overflow-y: auto;
} }
.mobile-content > div {
.mobile-content>div {
background: #fff; background: #fff;
border-radius: 8px; border-radius: 8px;
min-height: 60vh; min-height: 60vh;
padding: 10px; padding: 10px;
} }
.el-menu--horizontal>.el-menu-item{
.el-menu--horizontal>.el-menu-item {
height: 50px; height: 50px;
line-height: 50px; line-height: 50px;
} }
body { body {
background: #f0f2f5; background: #f0f2f5;
} }
......
<template>
<!-- 开发模式触发区域 - 隐藏的点击区域 -->
<div class="dev-mode-trigger" @click="handleDevModeClick" title="开发模式触发区域"></div>
</template>
<script>
import devModeManager from '@/utils/devMode'
export default {
name: 'Debug',
methods: {
handleDevModeClick() {
devModeManager.handleClick()
}
}
}
</script>
<style lang="scss" scoped>
/* 开发模式触发区域 */
.dev-mode-trigger {
position: absolute;
top: 5px;
left: 5px;
width: 50px;
height: 50px;
background: transparent;
cursor: pointer;
z-index: 999;
user-select: none;
}
/* 开发环境下显示边框提示 */
.dev-mode-trigger:hover {
background: rgba(0, 191, 138, 0.1);
border-radius: 4px;
}
</style>
\ No newline at end of file
...@@ -11,7 +11,7 @@ import 'lib-flexible/flexible.js' ...@@ -11,7 +11,7 @@ import 'lib-flexible/flexible.js'
// import '@/styles/element-theme-colors.css'; // import '@/styles/element-theme-colors.css';
import '@/styles/index.scss'; import '@/styles/index.scss';
import moment from 'moment' import moment from 'moment'
import VConsole from 'vconsole'; // import VConsole from 'vconsole'; // 注释掉,使用 devMode.js 统一管理
// import 'bi-element-ui/lib/bi-element-ui.css' // import 'bi-element-ui/lib/bi-element-ui.css'
import Element from 'bi-eleme' import Element from 'bi-eleme'
// import 'bi-eleme/lib/theme-chalk/index.css' // import 'bi-eleme/lib/theme-chalk/index.css'
...@@ -19,10 +19,9 @@ import BiElementUi from 'bi-element-ui' ...@@ -19,10 +19,9 @@ import BiElementUi from 'bi-element-ui'
// import 'bi-element-ui/lib/bi-element-ui.css' // import 'bi-element-ui/lib/bi-element-ui.css'
import uploading from '@/utils/cos-upload' import uploading from '@/utils/cos-upload'
import 'element-ui/lib/theme-chalk/index.css'; import 'element-ui/lib/theme-chalk/index.css';
// 导入 VConsole 清理工具
if(process.env.NODE_ENV !== 'production'){ import '@/utils/vconsoleCleanup'
new VConsole(); // new VConsole();
}
// 测试一下 // 测试一下
Vue.use(uploading) Vue.use(uploading)
Vue.use(BiElementUi, { Vue.use(BiElementUi, {
......
import VConsole from 'vconsole'
class DevModeManager {
constructor() {
this.vConsole = null
this.clickCount = 0
this.clickTimer = null
this.maxClicks = 7 // 连续点击7次开启
this.resetTime = 3000 // 3秒内无点击则重置
this.isDevMode = this.getDevModeFromStorage()
this.isDestroyingVConsole = false // 标记VConsole正在销毁中
// 自动初始化逻辑
this.autoInit()
}
// 自动初始化逻辑
autoInit() {
const isDevEnv = process.env.NODE_ENV !== 'production'
// 如果是开发环境或特定公司ID,或者之前开启过开发模式,则自动启用
if (isDevEnv || this.isDevMode) {
this.enableDevMode()
}
}
// 从 localStorage 获取开发模式状态
getDevModeFromStorage() {
try {
return localStorage.getItem('dev_mode_enabled') === 'true'
} catch (error) {
console.warn('无法读取开发模式状态:', error)
return false
}
}
// 保存开发模式状态到 localStorage
saveDevModeToStorage(enabled) {
try {
localStorage.setItem('dev_mode_enabled', enabled.toString())
} catch (error) {
console.warn('无法保存开发模式状态:', error)
}
}
// 处理点击事件
handleClick() {
// 如果正在销毁VConsole,忽略点击事件
if (this.isDestroyingVConsole) {
console.log('VConsole正在关闭中,请稍候...')
return
}
this.clickCount++
console.log(`开发模式激活进度: ${this.clickCount}/${this.maxClicks}`)
// 清除之前的定时器
if (this.clickTimer) {
clearTimeout(this.clickTimer)
}
// 如果达到指定次数,切换开发模式
if (this.clickCount >= this.maxClicks) {
this.toggleDevMode()
this.resetClickCount()
return
}
// 设置重置定时器
this.clickTimer = setTimeout(() => {
if (this.clickCount > 0) {
console.log('开发模式激活超时,重置计数')
this.resetClickCount()
}
}, this.resetTime)
}
// 重置点击计数
resetClickCount() {
this.clickCount = 0
if (this.clickTimer) {
clearTimeout(this.clickTimer)
this.clickTimer = null
}
}
// 切换开发模式
toggleDevMode() {
if (this.isDevMode) {
this.disableDevMode()
} else {
this.enableDevMode()
}
}
// 开启开发模式
enableDevMode() {
try {
// 防止重复初始化
if (!this.vConsole) {
// 如果上次销毁未完成,等待一段时间
if (this.isDestroyingVConsole) {
console.log('正在等待上次的VConsole销毁完成...')
setTimeout(() => this.enableDevMode(), 500)
return
}
this.vConsole = new VConsole()
console.log('🎉 开发模式已开启!')
console.log('💡 提示:再次连续点击7次可关闭开发模式')
this.isDevMode = true
this.saveDevModeToStorage(true)
} else {
console.log('📱 开发模式已经处于开启状态')
}
} catch (error) {
console.error('开启开发模式失败:', error)
this.vConsole = null
this.isDevMode = false
this.isDestroyingVConsole = false
}
}
// 关闭开发模式
disableDevMode() {
try {
if (this.vConsole) {
// 设置标志,表示正在销毁
this.isDestroyingVConsole = true
// 在销毁前保存引用
const vConsoleInstance = this.vConsole;
// 先将实例引用设置为null,防止后续调用
this.vConsole = null;
// 使用setTimeout延迟一点点销毁操作,以确保事件循环中的其他任务已完成
setTimeout(() => {
// 使用try-catch单独包装destroy调用,防止异常影响状态设置
try {
vConsoleInstance.destroy();
} catch (destroyError) {
console.error('VConsole销毁时出错:', destroyError);
}
// 销毁完成后,清除标志
this.isDestroyingVConsole = false;
console.log('👋 开发模式已关闭!');
}, 100);
this.isDevMode = false;
this.saveDevModeToStorage(false);
} else {
this.isDevMode = false;
this.isDestroyingVConsole = false;
this.saveDevModeToStorage(false);
}
} catch (error) {
console.error('关闭开发模式失败:', error);
// 强制重置状态
this.vConsole = null;
this.isDevMode = false;
this.isDestroyingVConsole = false;
}
}
// 检查是否为开发环境
isDevEnvironment() {
return process.env.NODE_ENV === 'development'
}
// 获取当前开发模式状态
getDevModeStatus() {
return {
enabled: this.isDevMode,
environment: process.env.NODE_ENV,
clickCount: this.clickCount,
maxClicks: this.maxClicks,
hasVConsole: !!this.vConsole,
isDestroyingVConsole: this.isDestroyingVConsole
}
}
// 安全销毁方法
destroy() {
this.resetClickCount()
this.disableDevMode()
}
}
// 创建全局实例
const devModeManager = new DevModeManager()
// 添加到 window 对象,方便控制台操作
if (typeof window !== 'undefined') {
window.devMode = {
toggle: () => devModeManager.toggleDevMode(),
enable: () => devModeManager.enableDevMode(),
disable: () => devModeManager.disableDevMode(),
status: () => devModeManager.getDevModeStatus(),
reset: () => devModeManager.resetClickCount(),
destroy: () => devModeManager.destroy()
}
// 监听页面卸载,清理资源
window.addEventListener('beforeunload', () => {
try {
devModeManager.destroy()
} catch (error) {
console.warn('清理开发模式资源时出错:', error)
}
})
}
export default devModeManager
\ No newline at end of file
...@@ -37,7 +37,7 @@ service.interceptors.request.use( ...@@ -37,7 +37,7 @@ service.interceptors.request.use(
if (authToken) { if (authToken) {
config.headers['Authtoken'] = authToken config.headers['Authtoken'] = authToken
} }
const corp_id = store.state.user.corp_id || Cookies.get('corp_id') const corp_id = Cookies.get('corp_id') || store.state.user.corp_id
const userid = Cookies.get('userid') const userid = Cookies.get('userid')
if (corp_id) { if (corp_id) {
config.headers['Corp-Id'] = corp_id config.headers['Corp-Id'] = corp_id
......
// VConsole 清理工具
// 用于清理可能存在的重复实例和状态问题
const VConsoleCleanup = {
// 清理所有可能的 VConsole 实例
cleanup() {
try {
// 清理全局 VConsole 引用
if (window.VConsole) {
delete window.VConsole
}
// 清理可能存在的 vConsole 实例
if (window.vConsole && typeof window.vConsole.destroy === 'function') {
window.vConsole.destroy()
delete window.vConsole
}
// 清理 DOM 中的 VConsole 元素
const vcElements = document.querySelectorAll('[class*="vc-"], [id*="__vconsole"]')
vcElements.forEach(el => {
try {
el.remove()
} catch (e) {
console.warn('移除 VConsole 元素失败:', e)
}
})
// 清理可能的事件监听器
this.removeEventListeners()
// 清理 localStorage 中的 VConsole 相关数据
this.cleanupStorage()
console.log('✅ VConsole 清理完成')
} catch (error) {
console.error('❌ VConsole 清理过程中出错:', error)
}
},
// 移除可能的事件监听器
removeEventListeners() {
try {
// VConsole 常用的事件类型
const eventTypes = ['resize', 'orientationchange', 'scroll', 'touchstart', 'touchmove', 'touchend']
// 移除可能由 VConsole 添加的事件监听器(这里只能尝试移除一些通用的)
eventTypes.forEach(type => {
// 注意:这里无法准确移除所有 VConsole 的监听器,只是一个清理尝试
document.removeEventListener(type, this.dummyHandler, true)
window.removeEventListener(type, this.dummyHandler, true)
})
} catch (error) {
console.warn('清理事件监听器时出错:', error)
}
},
// 空的事件处理器
dummyHandler() {},
// 清理存储
cleanupStorage() {
try {
const keysToRemove = []
// 检查 localStorage 中是否有 VConsole 相关的键
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i)
if (key && (key.includes('vconsole') || key.includes('vConsole'))) {
keysToRemove.push(key)
}
}
// 移除找到的键(保留我们自定义的 dev_mode_enabled)
keysToRemove.forEach(key => {
if (key !== 'dev_mode_enabled') {
localStorage.removeItem(key)
}
})
} catch (error) {
console.warn('清理存储时出错:', error)
}
},
// 检查当前状态
checkStatus() {
const status = {
hasWindowVConsole: !!window.VConsole,
hasWindowVconsole: !!window.vConsole,
vcElements: document.querySelectorAll('[class*="vc-"], [id*="__vconsole"]').length,
devModeStatus: window.devMode ? window.devMode.status() : null
}
console.table(status)
return status
},
// 强制重启开发模式
forceRestart() {
try {
this.cleanup()
// 等待清理完成后重新启动
setTimeout(() => {
if (window.devMode) {
window.devMode.enable()
console.log('🔄 开发模式已重新启动')
}
}, 500)
} catch (error) {
console.error('强制重启失败:', error)
}
}
}
// 添加到全局,方便控制台调用
if (typeof window !== 'undefined') {
window.VConsoleCleanup = VConsoleCleanup
// 在控制台提供快捷命令
window.cleanVConsole = () => VConsoleCleanup.cleanup()
window.checkVConsole = () => VConsoleCleanup.checkStatus()
window.restartVConsole = () => VConsoleCleanup.forceRestart()
}
export default VConsoleCleanup
\ No newline at end of file
...@@ -219,7 +219,7 @@ ...@@ -219,7 +219,7 @@
} }
}, },
computed: { computed: {
...mapState('game', ['chatUserInfo']), ...mapState('game', ['chatUserInfo','userid','external_userid']),
}, },
watch: { watch: {
show(newVal, oldVal) { show(newVal, oldVal) {
...@@ -369,8 +369,8 @@ ...@@ -369,8 +369,8 @@
}, },
submit() { submit() {
const data = { const data = {
userid: this.chatUserInfo.userid, userid: this.chatUserInfo.userid || this.userid,
external_userid: this.chatUserInfo.external_userid, external_userid: this.chatUserInfo.external_userid || this.external_userid,
member_id: this.userDetails.id && this.userDetails.id != '' ? this.userDetails.id : this.checkoutUser.member_id, member_id: this.userDetails.id && this.userDetails.id != '' ? this.userDetails.id : this.checkoutUser.member_id,
username: this.userDetails.username, username: this.userDetails.username,
reg_game_id: this.userDetails.reg_game_id, reg_game_id: this.userDetails.reg_game_id,
......
...@@ -3,57 +3,49 @@ ...@@ -3,57 +3,49 @@
<div class="loginContent"> <div class="loginContent">
<div v-if="!token"> <div v-if="!token">
<div> <div>
当前组织:<span class="current-org">{{ currentOrg.name }}</span> 当前选中组织:<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>
<div class="qr-contain" > <div class="qr-contain">
<div id="dingTalkLoginContainer" > <div id="dingTalkLoginContainer">
</div> </div>
<div class="refresh"> <div class="refresh">
<i <i class="el-icon-refresh-right " @click="refreshDingTalkQRCode"></i>
class="el-icon-refresh-right "
@click="refreshDingTalkQRCode"
></i>
</div> </div>
<!-- 生二维码的时候加一个 loading --> <!-- 生二维码的时候加一个 loading -->
<div class="loading" v-if="qrLoading"> <div class="loading" v-if="qrLoading">
<span class="loading-spinner"></span> <span class="loading-spinner"></span>
</div> </div>
</div> </div>
</div>
<!-- 组织切换弹窗 --> <!-- 组织切换弹窗 -->
<el-dialog :visible.sync="showOrgDialog" width="300px" title="选择组织"> <el-dialog :visible.sync="showOrgDialog" width="300px" title="选择组织">
<ul style="list-style:none;padding:0;margin-top: -20px;"> <ul style="list-style:none;padding:0;margin-top: -20px;">
<li v-for="org in orgList" :key="org.app_key" <li v-for="org in orgList" :key="org.app_key" @click="switchOrg(org)" :style="{
@click="switchOrg(org)" padding: '8px 16px',
:style="{ cursor: 'pointer',
padding: '8px 16px', background: org.app_key === currentOrg.app_key ? '#e6f7ff' : '',
cursor: 'pointer', color: org.app_key === currentOrg.app_key ? '#1890ff' : '',
background: org.app_key === currentOrg.app_key ? '#e6f7ff' : '', fontWeight: org.app_key === currentOrg.app_key ? 'bold' : 'normal',
color: org.app_key === currentOrg.app_key ? '#1890ff' : '', borderRadius: '4px',
fontWeight: org.app_key === currentOrg.app_key ? 'bold' : 'normal', marginBottom: '4px',
borderRadius: '4px', transition: 'background 0.2s'
marginBottom: '4px', }" @mouseover="hoveredOrg = org.app_key" @mouseleave="hoveredOrg = null">
transition: 'background 0.2s'
}"
@mouseover="hoveredOrg = org.app_key"
@mouseleave="hoveredOrg = null"
>
{{ org.name }} {{ org.name }}
<span v-if="org.app_key === currentOrg.app_key" style="margin-left:8px;">(当前)</span> <span v-if="org.app_key === currentOrg.app_key" style="margin-left:8px;">(当前)</span>
</li> </li>
</ul> </ul>
</el-dialog> </el-dialog>
</div>
</div> </div>
</template> </template>
<script> <script>
import * as ww from '@wecom/jssdk' import * as ww from '@wecom/jssdk'
import { getOrganization,getAuthUser,getSignature } from '@/api/user' import { getOrganization, getAuthUser, getSignature } from '@/api/user'
import Cookies from 'js-cookie' import Cookies from 'js-cookie'
import { getParams } from '@/utils/index' import { getParams } from '@/utils/index'
import { mapMutations,mapState } from 'vuex' import { mapMutations, mapState } from 'vuex'
import { getToken,setToken } from '@/utils/auth' import { getToken, setToken } from '@/utils/auth'
import jsApiList from '@/utils/jsApiList' import jsApiList from '@/utils/jsApiList'
export default { export default {
data() { data() {
...@@ -63,83 +55,79 @@ export default { ...@@ -63,83 +55,79 @@ export default {
signData: null, // 企微签名数据 signData: null, // 企微签名数据
orgList: [], orgList: [],
organizationNum: 5, organizationNum: 5,
urlParams:{}, urlParams: {},
currentOrg: {}, currentOrg: {},
showOrgDialog: false, showOrgDialog: false,
hoveredOrg: null, hoveredOrg: null,
showRefresh: false, // 控制刷新按钮显示 showRefresh: false, // 控制刷新按钮显示
qrLoading: false, // 控制二维码 loading 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', 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:'', DDTestUrl: '',
token:getToken() token: getToken()
} }
}, },
async mounted() { async mounted() {
console.log(1231321321,'1231321321')
this.$nextTick(() => { this.$nextTick(() => {
this.initLogin() this.initLogin()
}) })
}, },
computed:{ computed: {
...mapState('user',['corp_id']) ...mapState('user', ['corp_id'])
}, },
methods: { 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(){ async initLogin() {
await this.initOrganization();
const urlParams = getParams(); const urlParams = getParams();
await this.initOrganization();
const userid = Cookies.get('userid'); const userid = Cookies.get('userid');
// 如果是钉钉扫码回调页面 // 如果是钉钉扫码回调页面
if ( urlParams.type && urlParams.type === 'ding') {// 钉钉回调 if (urlParams.type && urlParams.type === 'ding') {// 钉钉回调
console.log(1) console.log(1)
this.handleDingCallback(); this.handleDingCallback();
}else if(this.token){ // 已经钉钉扫码过 重新获取授权 获取签名 注册企微js-sdk } else if (this.token && userid) { // 已经钉钉扫码过 重新获取授权 获取签名 注册企微js-sdk
console.log(2) console.log(2)
await this.getSignature(); await this.getSignature();
}else { } else {
console.log(3) console.log(3)
if(!userid){ //没有企微授权过 并且 钉钉扫码成功 开始微信授权 if (!userid) { //没有企微授权过 并且 钉钉扫码成功 开始微信授权
console.log(4) console.log(4)
await this.startWeComSilentAuth(); await this.startWeComSilentAuth();
}else{ } else {
console.log(5) console.log(5)
this.initDingTalkLogin(); // 始化钉钉扫码 this.initDingTalkLogin(); // 始化钉钉扫码
} }
} }
// 每次进入页面都缓存corp_id
if(urlParams.corp_id){
this.cacheCorp_id(urlParams.corp_id) // 缓存 corp_id
}
}, },
// 设置缓存 // 设置缓存
cacheCorp_id(corp_id){ cacheCorp_id(corp_id) {
Cookies.set('corp_id',corp_id, { expires: 7 }) Cookies.set('corp_id', corp_id, { expires: 7 })
this.set_corp_id(corp_id) this.set_corp_id(corp_id)
}, },
cacheuserid(userid){ cacheuserid(userid) {
Cookies.set('userid',userid, { expires: 7 }) Cookies.set('userid', userid, { expires: 7 })
this.set_userid(userid) this.set_userid(userid)
}, },
cacheCser(cser_id,cser_name){ cacheCser(cser_id, cser_name) {
Cookies.set('cser_id',cser_id, { expires: 7 }) Cookies.set('cser_id', cser_id, { expires: 7 })
Cookies.set('cser_name',cser_name, { expires: 7 }) Cookies.set('cser_name', cser_name, { expires: 7 })
this.set_cser_info({ this.set_cser_info({
cser_id:cser_id, cser_id: cser_id,
cser_name:cser_name cser_name: cser_name
}) })
this.set_cser_id(cser_id) this.set_cser_id(cser_id)
this.set_cser_name(cser_name) this.set_cser_name(cser_name)
}, },
cacheSignData(signData){ cacheSignData(signData) {
Cookies.set('signData',JSON.stringify(signData), { expires: 7 }) Cookies.set('signData', JSON.stringify(signData), { expires: 7 })
this.set_signData(signData) this.set_signData(signData)
}, },
// 进入的页面地址是 https://companywx.jianshuwenhua.com/company_app/index.html?corp_id=wweaefe716636df3d1 // 进入的页面地址是 https://companywx.jianshuwenhua.com/company_app/index.html?corp_id=wweaefe716636df3d1
// 1. 企微静默授权 // 1. 企微静默授权
async startWeComSilentAuth() { async startWeComSilentAuth() {
this.urlParams = getParams(); this.urlParams = getParams();
const corp_id = this.urlParams.corp_id const corp_id = Cookies.get('corp_id') || this.urlParams.corp_id
if(!corp_id){ if (!corp_id) {
this.$message.error('当前客服号信息异常,请切换会话后重试') this.$message.error('当前客服号信息异常,请切换会话后重试')
return return
} }
...@@ -152,82 +140,87 @@ export default { ...@@ -152,82 +140,87 @@ export default {
return; return;
} }
// 用code // 用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.status_code === 1) {
this.cacheuserid(res.data.userid) if(res.data.userid){
this.initDingTalkLogin(); // 初始化钉钉扫码 this.cacheuserid(res.data.userid)
this.initDingTalkLogin(); // 初始化钉钉扫码
}else{
this.$message.error('获取用户id失败')
return
}
} else { } else {
console.log('获取useid失败',res) console.log('获取useid失败', res)
// 错误处理 // 错误处理
} }
}, },
async getSignature(){ async getSignature() {
console.log('获取签名',window.location.href) console.log('获取签名', window.location.href)
const corp_id = Cookies.get('corp_id') const corp_id = Cookies.get('corp_id')
try{ 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){ if (res.status_code === 1) {
this.signData = res.data this.signData = res.data
this.cacheSignData(res.data) this.cacheSignData(res.data)
try{ try {
this.registerWeComSDK(); this.registerWeComSDK();
}catch(err){ } catch (err) {
console.log(err,'初始化sdk 失败') console.log(err, '初始化sdk 失败')
} }
} }
}catch(err){ } catch (err) {
console.log(err,'获取签名失败') console.log(err, '获取签名失败')
window.location.href = window.location.origin +'/company_app/index.html?corp_id='+corp_id+'&msg=signerror' window.location.href = window.location.origin + '/company_app/index.html?corp_id=' + corp_id + '&msg=signerror'
} }
}, },
getCurExternalContact() { getCurExternalContact() {
ww.getCurExternalContact({ ww.getCurExternalContact({
success: (res) => { success: (res) => {
if (res.err_msg === "getCurExternalContact:ok") { if (res.err_msg === "getCurExternalContact:ok") {
console.log(res,'重新进入获取企微外部联系人') console.log(res, '重新进入获取企微外部联系人')
this.set_external_userid(res.userId) this.set_external_userid(res.userId)
// 确保 Vuex 状态更新后再跳转 // 确保 Vuex 状态更新后再跳转
this.$nextTick(() => { this.$nextTick(() => {
this.$router.replace('/') this.$router.replace('/')
console.log(window.location.href,'window.location.hrefuserInfo') console.log(window.location.href, 'window.location.hrefuserInfo')
}) })
} }
}, },
fail: (err) => { fail: (err) => {
console.log(err,'获取企微外部联系人失败') console.log(err, '获取企微外部联系人失败')
// 错误处理 // 错误处理
} }
}); });
}, },
// 2. 注册企微JS-SDK // 2. 注册企微JS-SDK
registerWeComSDK() { registerWeComSDK() {
console.log('删除企业签名',1231) console.log('删除企业签名', 1231)
ww.register({ ww.register({
corpId: Cookies.get('corp_id'), corpId: Cookies.get('corp_id'),
agentId: this.signData.agent_id, agentId: this.signData.agent_id,
jsApiList: jsApiList, jsApiList: jsApiList,
// getConfigSignature: () => Promise.resolve({ // getConfigSignature: () => Promise.resolve({
// nonceStr: this.signData.nonce_str, // nonceStr: this.signData.nonce_str,
// timestamp: this.signData.signature_time, // timestamp: this.signData.signature_time,
// signature: this.signData.corp_signature, // signature: this.signData.corp_signature,
// }), // }),
// 只用到应用的 api 可以只进行应用的签名 // 只用到应用的 api 可以只进行应用的签名
getAgentConfigSignature: () => Promise.resolve({ getAgentConfigSignature: () => Promise.resolve({
nonceStr: this.signData.nonce_str, nonceStr: this.signData.nonce_str,
timestamp: this.signData.signature_time, timestamp: this.signData.signature_time,
signature: this.signData.agent_signature, signature: this.signData.agent_signature,
}), }),
onAgentConfigSuccess: (res) => { onAgentConfigSuccess: (res) => {
console.log('注册成功可以调用企微 js-sdk',res) console.log('注册成功可以调用企微 js-sdk', res)
// 注册成功后不立即获取外部联系人,等钉钉扫码后再获取 // 注册成功后不立即获取外部联系人,等钉钉扫码后再获取
this.getCurExternalContact() this.getCurExternalContact()
}, },
onAgentConfigFail: (err) => { onAgentConfigFail: (err) => {
console.log('注册失败不能使用企微js-sdk',err) console.log('注册失败不能使用企微js-sdk', err)
// 错误处理123 // 错误处理123
} }
}); });
}, },
// 3. 获取组织列表并选取默认组织 // 3. 获取组织列表并选取默认组织
...@@ -249,7 +242,7 @@ export default { ...@@ -249,7 +242,7 @@ export default {
// 4. 初始化钉钉扫码 // 4. 初始化钉钉扫码
initDingTalkLogin() { initDingTalkLogin() {
this.qrLoading = true; this.qrLoading = true;
console.log('进入初始化钉钉',this.currentOrg) console.log('进入初始化钉钉', this.currentOrg)
if (!this.currentOrg.app_key) return; if (!this.currentOrg.app_key) return;
const appid = this.currentOrg.app_key; const appid = this.currentOrg.app_key;
// 清空二维码容器,防止切换组织后二维码不刷新 // 清空二维码容器,防止切换组织后二维码不刷新
...@@ -296,7 +289,7 @@ export default { ...@@ -296,7 +289,7 @@ export default {
const appid = this.currentOrg.app_key; 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}`; 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') console.log(url, '回调 url')
this.DDTestUrl = url this.DDTestUrl = url
window.location.href = url; window.location.href = url;
}, },
...@@ -306,32 +299,32 @@ export default { ...@@ -306,32 +299,32 @@ export default {
console.log('扫码成功') console.log('扫码成功')
const ddParams = getParams(); const ddParams = getParams();
const corp_id = Cookies.get('corp_id') const corp_id = Cookies.get('corp_id')
if(ddParams.code=='error' && ddParams.msg){ if (ddParams.code == 'error' && ddParams.msg) {
this.$message.error(ddParams.msg) this.$message.error(ddParams.msg)
setTimeout(() => { setTimeout(() => {
window.location.href = window.location.origin +'/company_app/index.html?corp_id='+corp_id+'&msg=error' window.location.href = window.location.origin + '/company_app/index.html?corp_id=' + corp_id + '&msg=error'
}, 5000) }, 5000)
return return
} }
if(ddParams.token && ddParams.token!='undefined'){ if (ddParams.token && ddParams.token != 'undefined') {
setToken(ddParams.token) setToken(ddParams.token)
this.set_token(ddParams.token) this.set_token(ddParams.token)
// 获取签名 // 获取签名
await this.getSignature(); await this.getSignature();
}else{ } else {
console.log('没有token') console.log('没有token')
window.location.href = window.location.origin +'/company_app/index.html?corp_id='+corp_id+'&msg=notoken' window.location.href = window.location.origin + '/company_app/index.html?corp_id=' + corp_id + '&msg=notoken'
} }
if(ddParams.cser_id){ if (ddParams.cser_id) {
this.cacheCser(ddParams.cser_id,ddParams.cser_name) this.cacheCser(ddParams.cser_id, ddParams.cser_name)
} }
}, },
refreshDingTalkQRCode() { refreshDingTalkQRCode() {
this.initDingTalkLogin(); this.initDingTalkLogin();
}, },
}, },
} }
</script> </script>
...@@ -342,51 +335,52 @@ export default { ...@@ -342,51 +335,52 @@ export default {
margin-right: 5px; margin-right: 5px;
} }
.loginContent{ .loginContent {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
.qr-contain { .qr-contain {
margin: 0 auto; margin: 0 auto;
/* margin-top: 20px; */ /* margin-top: 20px; */
width: 260px; width: 260px;
height: 260px; height: 260px;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
#dingTalkLoginContainer {
padding: 15px;
position: absolute;
left: 10px;
bottom: 0;
}
.refresh {
display: none;
text-align: center;
position: absolute;
width: 40px;
background: #fff;
height: 40px;
transform: translate(-50%,-50%);
left: 50%;
top: 50%;
i {
line-height: 40px;
font-size: 26px;
color: #3491FA ;
cursor: pointer;
}
}
&:hover { #dingTalkLoginContainer {
.refresh { padding: 15px;
display: block; position: absolute;
} left: 10px;
} bottom: 0;
} }
.refresh {
display: none;
text-align: center;
position: absolute;
width: 40px;
background: #fff;
height: 40px;
transform: translate(-50%, -50%);
left: 50%;
top: 50%;
i {
line-height: 40px;
font-size: 26px;
color: #3491FA;
cursor: pointer;
}
}
&:hover {
.refresh {
display: block;
}
}
}
.loading { .loading {
position: absolute; position: absolute;
...@@ -394,23 +388,30 @@ export default { ...@@ -394,23 +388,30 @@ export default {
top: 0; top: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
background: rgba(255,255,255,0.7); background: rgba(255, 255, 255, 0.7);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
z-index: 20; z-index: 20;
transition: opacity 0.3s; transition: opacity 0.3s;
} }
.loading-spinner { .loading-spinner {
width: 40px; width: 40px;
height: 40px; height: 40px;
border: 4px solid #e0e0e0; border: 4px solid #e0e0e0;
border-top: 4px solid #3491FA ; border-top: 4px solid #3491FA;
border-radius: 50%; border-radius: 50%;
animation: spin 1s linear infinite; animation: spin 1s linear infinite;
} }
@keyframes spin { @keyframes spin {
0% { transform: rotate(0deg); } 0% {
100% { transform: rotate(360deg); } transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
} }
</style> </style>
\ No newline at end of file
...@@ -53,30 +53,10 @@ export default { ...@@ -53,30 +53,10 @@ export default {
}, },
created(){ created(){
// 初始化 vuex 中的值 // 初始化 vuex 中的值
this.initVuexValue()
}, },
methods:{ methods:{
...mapMutations('game',['set_chatUserInfo']), ...mapMutations('game',['set_chatUserInfo']),
...mapMutations('user',['set_userid','set_corp_id','set_token','set_cser_info','set_cser_id','set_cser_name','set_userInfo']),
initVuexValue(){
this.set_userid(Cookies.get('userid'))
this.set_corp_id(Cookies.get('corp_id'))
this.set_token(Cookies.get('token'))
this.set_cser_id(Cookies.get('cser_id'))
this.set_cser_name(Cookies.get('cser_name'))
const userinfo = {
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)
const cser_info = Cookies.get('cser_info')
console.log(Cookies.get('cser_id'),'cser_info',Cookies.get('cser_name'))
cser_info?this.set_cser_info(JSON.parse(cser_info)):this.set_cser_info({})
}
} }
} }
</script> </script>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论