提交 be3d5787 作者: 毛细亚

开始开发页面

上级 61dd95da
......@@ -4,7 +4,7 @@ globs:
alwaysApply: false
---
# 项目结构说明
这是一个 H5的移动端页面 这是一个 H5的移动端页面 最大宽度是 380px 最小宽度是 360px 样所以需要用到 css 自适应 弹性伸缩
本项目为基于 Vue.js 的前端应用,主要目录结构如下:
- [src/](mdc:src):主源码目录,包括:
......@@ -52,7 +52,7 @@ alwaysApply: false
- 懒加载实现
# UI 规范
因为 企业微信侧边栏 宽度有限 所以尽量使用 自适应的样式来进行开发
因为 企业微信侧边栏 宽度有限 而且是一个 H5 移动端的页面 最大宽度是 380px 最小宽度 是 360px 所以尽量使用 自适应的样式来进行开发
# 基于企业微信客户端开发 企业微信侧边栏网页应用
# 基于企业微信客户端开发 企业微信侧边栏H5 网页应用
基于企业微信客户端 开发侧边栏功能 企业微信的文档 [企业微信文档]([链接地址](https://developer.work.weixin.qq.com/document/path/94352) )
## 项目介绍
企微微信中内嵌掌微第三方页面 来支持开发企业微信侧边栏功能
这是一个 H5的移动端页面 这是一个 H5的移动端页面 最大宽度是 380px 最小宽度是 360px 样所以需要用到 css 自适应 弹性伸缩 企微微信中内嵌掌微第三方页面 来支持开发企业微信侧边栏功能
## 项目结构
- @src/:主源码目录,包括:
......
<template>
<div id="app">
<div id="app" class="mobile-app-wrapper">
<div class="mobile-menu-bar">
<el-menu
:default-active="selectedPath"
mode="horizontal"
class="mobile-el-menu"
background-color="#fff"
router
>
<el-menu-item v-for="item in menuList" :key="item.path" :index="item.path" class="mobile-menu-item">
{{ item.label }}
</el-menu-item>
</el-menu>
</div>
<div class="mobile-content ">
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
name: 'App',
created() {
},
data() {
return {
num:0
menuList: [
{
label: '客户信息',
path: '/userInfo'
},
{
label: '快捷回复',
path: '/quickReply'
},
{
label: '礼包记录',
path: '/giftRecord'
},
{
label: '申请记录',
path: '/applyRecord'
},
{
label: '快捷发送',
path: '/quickSend'
},
{
label: '通讯录',
path: '/addressBook'
},
],
selectedPath: '/userInfo',
}
},
computed: {
watch: {
'$route.path'(val) {
this.selectedPath = val
}
},
methods: {
created() {
if (this.$route.path === '/' || this.$route.path === '') {
this.$router.replace('/userInfo')
} else {
this.selectedPath = this.$route.path
}
},
}
</script>
<style>
<style scoped>
.mobile-app-wrapper {
max-width: 380px;
min-width: 360px;
margin: 0 auto;
background: #f0f2f5;
min-height: 100vh;
display: flex;
flex-direction: column;
box-shadow: 0 0 12px rgba(0,0,0,0.04);
}
.mobile-menu-bar {
background: #fff;
border-bottom: 1px solid #f0f0f0;
box-shadow: 0 2px 8px #f0f1f2;
z-index: 10;
}
.mobile-el-menu {
border: none;
background: #fff;
display: flex;
justify-content: space-between;
}
.mobile-menu-item {
font-size: 14px ;
padding: 0 8px !important;
min-width: 0;
flex: 1 1 0;
text-align: center;
}
.mobile-el-menu .el-menu-item.is-active {
font-weight: bold;
border-radius: 6px 6px 0 0;
}
.mobile-content {
flex: 1;
overflow-y: auto;
padding: 18px 10px 10px 10px;
background: #f0f2f5;
}
.mobile-content > div {
background: #fff;
border-radius: 8px;
min-height: 60vh;
box-shadow: 0 2px 8px #f0f1f2;
padding: 24px 10px;
}
.el-menu--horizontal>.el-menu-item{
height: 50px;
line-height: 50px;
}
body {
background: #f0f2f5;
}
</style>
......@@ -30,3 +30,5 @@
用 npm run build:stage 打包到正式环境的时候 用 npm run build:prod
# 5. 谨记 当打包上线到正式环境的时候 一定要 用npm run build:prod 重新打包一次 要不钉钉扫码登录会有问题 回调地址会有错误
# 6. 只用到企业微信应用的 api 的时候 可以只注册 企业微信应用的签名 当用到 企业的api 的时候 需要注册企业的签名 当用到什么 api 的时候 就用那个的签名 具体看官方文档
\ No newline at end of file
......@@ -6,6 +6,8 @@ import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import Cookies from 'js-cookie';
import _ from 'lodash';
import '@/styles/index.scss' // global css
Vue.use(ElementUI);
// import '@/styles/index.scss' // global css
Vue.config.productionTip = false
......
import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'
import userInfo from '../views/userInfo.vue'
import quickReply from '../views/quickReply.vue'
import giftRecord from '../views/giftRecord.vue'
import applyRecord from '../views/applyRecord.vue'
import quickSend from '../views/quickSend.vue'
import addressBook from '../views/addressBook.vue'
import Cookies from 'js-cookie'
Vue.use(VueRouter)
import { getParams } from '@/utils/index'
const routes = [
{
path: '/',
name: 'home',
component: HomeView
redirect: '/userInfo'
},
{
path: '/userInfo',
name: 'userInfo',
component: userInfo
},
{
path: '/quickReply',
name: 'quickReply',
component: quickReply
},
{
path: '/giftRecord',
name: 'giftRecord',
component: giftRecord
},
{
path: '/applyRecord',
name: 'applyRecord',
component: applyRecord
},
{
path: '/quickSend',
name: 'quickSend',
component: quickSend
},
{
path: '/addressBook',
name: 'addressBook',
component: addressBook
},
{
path: '/login',
name: 'login',
component: () => import('../views/login.vue')
},
{
path: '/about',
name: 'about',
component: () => import('../views/AboutView.vue')
},
// {
// path: '/ddLogin',
// name: 'ddLogin',
......@@ -49,19 +77,23 @@ router.beforeEach((to, from, next) => {
const needAuth = !['/login'].includes(to.path)
// 检查登录信息
const wecomUserId = Cookies.get('wx_userid')
const dingUserId = Cookies.get('ding_userid')
const cser_id = Cookies.get('cser_id')
const token = Cookies.get('token')
const urlParams = getParams();
if (needAuth) {
if (wecomUserId && dingUserId) {
if (wecomUserId && cser_id && token) {
// 登录信息齐全,允许进入
next()
} else {
// 缺少登录信息,跳转到登录页
// 跳转到 login 的时候带上当前 url 的参数
next({
path: '/login',
query: urlParams
})
// next({
// path: '/login',
// query: urlParams
// })
next()
}
} else {
// 登录页、回调页等不需要校验
......
......@@ -10,7 +10,21 @@ const state = {
},
userid:'userid',
corp_id:'',
externalUserId:'',
token:'',
cser_info:{
cser_id:'',
cser_name:''
},
signData:{
corp_id:'',
agent_signature:'',
corp_signature:'',
time:''
},
externalUserId:''
// 六子的 用户id wm5rUgMgAAjqjOcqp8i3lEhFZDQieWug
// 我的 wx_userid JinDuoXia cser_id 4090 corp_id wweaefe716636df3d1 cser_id 4090 token token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJpc3MiOjQwOTAsImlhdCI6MTc0NzgxMjMxMiwiZXhwIjoxNzQ4NDE3MTEyLCJuYmYiOjE3NDc4MTIzMTIsInN1YiI6InRva2Vu6K6k6K-BIiwianRpIjoiMjBkOTY3MDZiYzI1MDdmY2MxOWI2MjU1YTM0YWQ3M2YifQ.yX7E7QHV7x2ubpa8iK3Avy794EiHNCaW2CtB4A4UQWo
}
const mutations = {
set_userInfo(state,userInfo){
......@@ -24,7 +38,16 @@ const mutations = {
},
set_externalUserId(state,externalUserId){
state.externalUserId = externalUserId
}
},
set_token(state,token){
state.token = token
},
set_cser_info(state,cser_info){
state.cser_info = cser_info
},
set_signData(state,signData){
state.signData = signData
},
}
const actions = {
......
......@@ -9,7 +9,6 @@
// @tailwind base; // 重设的 css 代码
// @tailwind components;
@tailwind utilities;
body {
height: 100%;
-moz-osx-font-smoothing: grayscale;
......@@ -18,6 +17,8 @@ body {
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB,
Microsoft YaHei, Arial, sans-serif;
font-size: 14px;
margin: 0 ;
padding: 0;
}
label {
......
$themeColor: #00BF8A;
$sidebarWidthOpen: 190px;
$sidebarWidthClosed: 56px;
$navbarHeight: 50px;
:export {
themeColor: $themeColor;
sidebarWidthOpen: $sidebarWidthOpen;
sidebarWidthClosed: $sidebarWidthClosed;
navbarHeight: $navbarHeight;
}
// @import './ui-variables.scss';
@import './ui-variables.scss';
/* bi-ui-style */
// $appmainWidth
/*
......
......@@ -7,7 +7,11 @@ $green: #30b08f;
$tiffany: #4ab7bd;
$yellow: #fec171;
$panGreen: #30b08f;
$themeColor: #00BF8A;
$sidebarWidthOpen: 190px;
$sidebarWidthClosed: 56px;
$navbarHeight: 50px;
// sidebar
$menuText: #606266;
$menuActiveText: #00BF8A;
......@@ -30,6 +34,10 @@ $sideBarWidth: 190px;
menuBg: $menuBg;
menuHover: $menuHover;
subMenuBg: $subMenuBg;
themeColor: $themeColor;
sidebarWidthOpen: $sidebarWidthOpen;
sidebarWidthClosed: $sidebarWidthClosed;
navbarHeight: $navbarHeight;
subMenuHover: $subMenuHover;
sideBarWidth: $sideBarWidth;
}
\ No newline at end of file
import Cookies from 'js-cookie'
const TokenKey = 'authorization'
import store from '@/store/index'
const TokenKey = 'token'
const time = new Date(new Date().getTime() + 10 * 12 * 30 * 24 * 60 * 60 * 1000)
export function getToken() {
return Cookies.get(TokenKey)
return Cookies.get(TokenKey) || store.state.user.token
}
export function setToken(token) {
......@@ -11,5 +11,6 @@ export function setToken(token) {
}
export function removeToken() {
store.state.user.token = null
return Cookies.remove(TokenKey)
}
const jsApiList = [
'getCurExternalContact',
]
export default jsApiList
\ No newline at end of file
import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import store from '@/store/index'
import { getToken } from '@/utils/auth'
import { getToken,removeToken } from '@/utils/auth'
// 常量定义
const CancelToken = axios.CancelToken
const STATUS_CODE_SUCCESS = 1
const TOKEN_ERROR_CODES = [50008, 50012, 50014] // Illegal token, Other clients logged in, Token expired
import Cookies from 'js-cookie'
/**
......@@ -34,8 +34,12 @@ service.interceptors.request.use(
})
// 设置认证token
if (store.getters.token) {
config.headers['authToken'] = getToken()
if (store.state.user.token) {
config.headers['Authtoken'] = getToken()
}
console.log(store.state.user.corp_id,'store.state.user.corp_id')
if (store.state.user.corp_id) {
config.headers['Corp-Id'] = store.state.user.corp_id
}
return config
},
......@@ -63,25 +67,18 @@ service.interceptors.response.use(
// 如果状态码不是成功,则判断为错误
if (res.status_code !== STATUS_CODE_SUCCESS) {
// if (res.status_code === -1) {
// return res
// }
if (res.status_code === -1) {
// 登录 过期 重新去登录
// removeToken()
// window.location.href = window.location.origin +'/company_app/index.html?corp_id='+Cookies.get('corp_id')
return res
}
Message({
message: res.msg || 'Error',
type: 'error',
duration: 5 * 1000
})
// 处理token相关错误: 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
if (TOKEN_ERROR_CODES.includes(res.status_code)) {
// to re-login
MessageBox.confirm('登录过期,请重新登录', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
console.log('重新登录')
})
}
}
return res
},
......
<template>
<div class="home">
<h1 @click="$router.push('/about')">home</h1>
<h1>客服号userid:{{userInfo.userid}}</h1>
<h1>客户externalUserId:{{userInfo.externalUserId}}</h1>
</div>
</template>
<script>
import {mapState, mapActions} from 'vuex'
export default {
name: 'HomeView',
inject: ['authPromise'],
created() {
// 等待认证完成后执行 getAuthUser
this.authPromise.then(() => {
this.getAuthUser();
console.log('网页地址',window.location.href)
});
},
data() {
return {
}
},
computed: {
...mapState('user', ['userInfo'])
},
methods: {
getAuthUser() {
this.companyConfigInit()
},
//企业验证配置
companyConfigInit(data) {
console.log('进入companyConfigInit')
let that = this;
let { time, nonceStr, corp_signature,corp_id } = that.userInfo || {};
console.log(this.userInfo,'userInfo')
// eslint-disable-next-line
wx.config({
beta: true, // 必须这么写,否则wx.invoke调用形式的jsapi会有问题
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: corp_id, // 必填,企业微信的corpID
timestamp: time, // 必填,生成签名的时间戳
nonceStr: nonceStr, // 必填,生成签名的随机串
signature: corp_signature, // 必填,签名,见 附录-JS-SDK使用权限签名算法
jsApiList: ["getContext", "getCurExternalContact", "invoke"] //你要调用的sdk接口必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来
});
// eslint-disable-next-line
wx.ready(function (res) {
console.log('config成功了',res)
wx.checkJsApi({
jsApiList: ['agentConfig', 'getCurExternalContact'], // 需要检测的JS接口列表,所有JS接口列表见附录2,
success:function(res) {
console.log('checkJsApi成功了',res)
that.appAgentConfig();
},
})
});
// eslint-disable-next-line
wx.error(function (res) {
console.log('config失败了', res)
});
},
//应用验证配置
appAgentConfig(data) {
console.log('进入appAgentConfig')
console.log(this.userInfo,'userInfo')
let that = this;
let { time, nonceStr, agent_signature,corp_id } = that.userInfo || {};
wx.agentConfig({
corpid:corp_id,
agentid: 1000013,
timestamp: time,
nonceStr: nonceStr,
signature: agent_signature,
jsApiList: ["getContext", "getCurExternalContact", "invoke"],
success: function () {
// eslint-disable-next-line
wx.invoke('getCurExternalContact', {
}, function (res) {
console.log('invoke成功了', res)
if (res.err_msg == "getCurExternalContact:ok") {
localStorage.setItem('externalUserId', res.userId);
// this.$store.dispatch("common/setExternalUserId", res.userId);
that.externalUserId = res.userId; //返回当前外部联系人userId
// alert(that.externalUserId);
} else {
//错误处理
}
//查看相关接口是否可以调用
// that.checkJsApi();
});
},
fail: function (res) {
console.log('invoke失败了', res)
// alert('invoke失败了', res)
if (res.errMsg.indexOf("function not exist") > -1) {
alert("版本过低请升级");
}
}
});
},
}
}
</script>
<template>
<div class="addressBook-content">
通讯录
</div>
</template>
<script>
export default {
name: 'AddressBook',
}
</script>
<style lang="scss" scoped>
.addressBook-content{
width: 100%;
height: 100%;
background: #fff;
}
</style>
\ No newline at end of file
<template>
<div class="applyRecord-content">
申请记录
</div>
</template>
<script>
export default {
name: 'ApplyRecord',
}
</script>
<style lang="scss" scoped>
.applyRecord-content{
width: 100%;
height: 100%;
background: #fff;
}
</style>
\ No newline at end of file
<template>
<div class="DDlogin">
<h1 @click="about">钉钉扫码1231312</h1>
<div v-if="!organizationShow" class="contain-contain">
<div class="back">
<span style="font-size: 12px">当前组织:</span>
<span style="color: #3396fa; font-size: 14px">{{
currentApp.name
}}</span>
<el-tooltip
class="item"
effect="dark"
content="点此切换其他组织"
placement="top"
>
<i class="el-icon-arrow-up" @click="organizationShow = true"></i>
</el-tooltip>
</div>
</div>
<div id="login_container"></div>
</div>
</template>
<script>
import { getOrganization,getDingLogin } from "@/api/user";
export default {
name: "App",
components: {},
data() {
return {
organizationList: [],
currentApp: {},
organizationShow: false,
dingAppid: window.location.host === 'zq.wozhangwan.com' ? 'dingoafvrnicn48bydk92l' : 'dingoamtigagqd7h2mxawd',
dingRedirect_uri: process.env.NODE_ENV === 'production' ? encodeURIComponent(window.location.href) : 'https://companywx.zwwlkj03.top/api/api/sidebar_login/ding',
};
},
created() {
this.initOrganization();
},
mounted() {
this.$nextTick(() => {
// this.getDingLogin()
});
},
methods: {
about(){
this.$router.push('/about')
},
async initOrganization() {
this.organizationList = [];
const res = await getOrganization();
if (res.status_code === 1) {
this.organizationList = res.data.data
this.initCurrentApp();
}
},
initCurrentApp() {
const currentApp = this.organizationList.find(
(item) => item.app_key === "dingjigp0ksn9nbljdli"
);
this.$set(this, "currentApp", currentApp);
},
dingInit() {
const obj = DDLogin({
id: 'login_container',
// goto这里需要对url整体做一个urlencode编码
goto: encodeURIComponent(`https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=${this.currentApp.app_key}&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=${this.dingRedirect_uri}`),
style: 'border:none;background-color:#FFFFFF;margin:0',
width: '210',
height: '250'
})
const hanndleMessage = (event) => {
const origin = event.origin
// 判断是否来自ddLogin扫码事件
if (origin === 'https://login.dingtalk.com') {
const loginTmpCode = event.data
// 这里url不用进行urlencode编码
const urlparam = encodeURIComponent('dingjigp0ksn9nbljdli&corp_id=wweaefe716636df3d1&template_code=DING_CON_9KDF4N7GC&userid=JinDuoXia')
const url = 'https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=' + this.currentApp.app + `&response_type=code&scope=snsapi_login&state=${urlparam}&redirect_uri=` + this.dingRedirect_uri + '&loginTmpCode=' + loginTmpCode
window.location.href = url
}
}
if (typeof window.addEventListener !== 'undefined') {
window.addEventListener('message', hanndleMessage, false)
} else if (typeof window.attachEvent !== 'undefined') {
window.attachEvent('onmessage', hanndleMessage)
}
},
async getDingLogin() {
const data = {
corp_id:'wweaefe716636df3d1',
userid:'JinDuoXia',
template_code:'DING_CON_9KDF4N7GC',
state:'dingjigp0ksn9nbljdli',
code:'dfcdc6bb54db3bd4be9340772fcdc1d5'
}
const res = await getDingLogin(data);
if (res.status_code === 1) {
console.log(res)
}
}
},
};
</script>
<template>
<div class="giftRecord-content">
礼包记录
</div>
</template>
<script>
export default {
name: 'GiftRecord',
}
</script>
<style lang="scss" scoped>
.giftRecord-content{
width: 100%;
height: 100%;
background: #fff;
}
</style>
\ No newline at end of file
......@@ -59,7 +59,10 @@ import * as dd from 'dingtalk-jsapi'
import { getOrganization,getAuthUser,getDingLogin,getSignature } from '@/api/user'
import Cookies from 'js-cookie'
import { getParams } from '@/utils/index'
import { mapMutations } from 'vuex'
import { mapMutations,mapState } from 'vuex'
import { getToken,setToken } from '@/utils/auth'
import jsApiList from '@/utils/jsApiList'
console.log(jsApiList,'jsApiList')
export default {
data() {
return {
......@@ -87,7 +90,6 @@ export default {
// 如果是钉钉扫码回调页面
if ( urlParams.type && urlParams.type === 'ding') {// 钉钉回调
this.showQrCode = true
console.log('进入钉钉回调')
this.handleDingCallback();
}else{
if(!wx_userid){ // 没有静默授权过
......@@ -97,21 +99,49 @@ export default {
}
}
},
computed:{
...mapState('user',['corp_id'])
},
methods: {
...mapMutations('user',['set_corp_id','set_externalUserId','set_userInfo']),
...mapMutations('user',['set_corp_id','set_userid','set_externalUserId','set_userInfo','set_token','set_cser_info','set_signData']),
goDingding(){
window.location.href = this.DDTestUrl
},
// 设置缓存
cacheCorp_id(corp_id){
Cookies.set('corp_id',corp_id, { expires: 7 })
this.set_corp_id(corp_id)
},
cacheWx_userid(userid){
Cookies.set('wx_userid',userid, { expires: 7 })
this.set_userid(userid)
},
cacheWx_userinfo(userinfo){
Cookies.set('wx_userinfo',JSON.stringify(userinfo), { expires: 7 })
this.set_userInfo(userinfo)
},
cacheCser(cser_id,cser_name){
Cookies.set('cser_id',cser_id, { expires: 7 })
Cookies.set('cser_name',cser_name, { expires: 7 })
this.set_cser_info({
cser_id:cser_id,
cser_name:cser_name
})
},
cacheSignData(signData){
Cookies.set('signData',JSON.stringify(signData), { expires: 7 })
this.set_signData(signData)
},
// 进入的页面地址是 https://companywx.jianshuwenhua.com/company_app/index.html?corp_id=wweaefe716636df3d1
// 1. 企微静默授权
async startWeComSilentAuth() {
this.urlParams = getParams();
const appid = this.urlParams.corp_id
this.cacheCorp_id(appid) // 缓存 corp_id
// 确定是第一次进入页面 没有 code 和 state
if (!this.urlParams.code && !this.urlParams.state) {
// 跳转企微静默授权
const redirectUri = encodeURIComponent(window.location.href);
Cookies.set('corp_id',appid, { expires: 7 })
const authUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${redirectUri}&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect`;
window.location.href = authUrl;
return;
......@@ -119,48 +149,60 @@ export default {
// 用code
const res = await getAuthUser({ code: this.urlParams.code, url: window.location.href,corp_id:appid });
if (res.status_code === 1) {
Cookies.set('wx_userinfo',JSON.stringify(res.data.userInfo), { expires: 7 })
Cookies.set('wx_userid',res.data.userid, { expires: 7 })
this.cacheWx_userinfo(res.data)
this.cacheWx_userid(res.data.userid)
this.initDingTalkLogin();
} else {
// 错误处理
}
},
async getSignature(){
console.log('获取签名',window.location.href)
const corp_id = Cookies.get('corp_id')
this.set_corp_id(corp_id)
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)
try{
await this.registerWeComSDK();
this.$router.push('/')// 一切准备工作就绪
}catch(err){
console.log(err,'初始化sdk 失败')
}
}
},
// 2. 注册企微JS-SDK
registerWeComSDK() {
return new Promise((resolve,reject)=>{
ww.register({
corpId: this.signData.corp_id,
corpId: Cookies.get('corp_id'),
agentId: this.signData.agent_id,
jsApiList: ['getCurExternalContact'],
jsApiList: jsApiList,
// getConfigSignature: () => Promise.resolve({
// nonceStr: this.signData.nonceStr,
// timestamp: this.signData.timestamp,
// nonceStr: this.signData.nonce_str,
// timestamp: this.signData.signature_time,
// signature: this.signData.corp_signature,
// }),
// 只用到应用的 api 可以只进行应用的签名
getAgentConfigSignature: () => Promise.resolve({
nonceStr: this.signData.nonceStr,
timestamp: this.signData.timestamp,
nonceStr: this.signData.nonce_str,
timestamp: this.signData.signature_time,
signature: this.signData.agent_signature,
}),
onAgentConfigSuccess: (res) => {
resolve(res)
console.log('注册成功可以调用企微 js-sdk',res)
// 注册成功后不立即获取外部联系人,等钉钉扫码后再获取
},
onAgentConfigFail: (err) => {
console.log('注册失败',err)
console.log('注册失败不能使用企微js-sdk',err)
reject(err)
// 错误处理
}
});
})
},
// 3. 获取组织列表并选取默认组织
......@@ -232,15 +274,30 @@ export default {
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
// window.location.href = url;
window.location.href = url;
},
// 7. 钉钉扫码回调页面处理
async handleDingCallback() {
// 在这里处理钉钉扫码成功的回调
const ddParams = getParams();
console.log(ddParams,'ddParams')
if(ddParams.code=='error' && ddParams.msg){
this.$message.error(ddParams.msg)
return
}
if(ddParams.token && ddParams.token!='undefined'){
setToken(ddParams.token)
this.set_token(ddParams.token)
}else{
console.log('没有token')
window.location.href = window.location.origin +'/company_app/index.html?corp_id='+Cookies.get('corp_id')+'&msg=notoken'
}
if(ddParams.cser_id){
this.cacheCser(ddParams.cser_id,ddParams.cser_name)
}
await this.getSignature();
setTimeout(() => {
// 获取联系人
console.log('获取联系人')
this.getCurExternalContact();
}, 2000);
},
......@@ -255,6 +312,7 @@ export default {
}
},
fail: (err) => {
console.log(err,'获取企微外部联系人失败')
// 错误处理
}
});
......@@ -265,7 +323,7 @@ export default {
},
}
// https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=dingjigp0ksn9nbljdli&response_type=code&scope=snsapi_login&state=dingjigp0ksn9nbljdli%24DING_CON_9KDF4N7GC%24wweaefe716636df3d1%24JinDuoXia&redirect_uri=https://companywx.zwwlkj03.top/api/api/sidebar_login/ding&loginTmpCode=d4d8f3009f133dbeb41208e99806a00b
</script>
<style lang="scss" scoped>
......
<template>
<div class="quickReply-content">
快捷回复
</div>
</template>
<script>
export default {
name: 'QuickReply',
}
</script>
<style lang="scss" scoped>
.quickReply-content{
width: 100%;
height: 100%;
background: #fff;
}
</style>
\ No newline at end of file
<template>
<div class="quickSend-content">
快捷发送
</div>
</template>
<script>
export default {
name: 'QuickSend',
}
</script>
<style lang="scss" scoped>
.quickSend-content{
width: 100%;
height: 100%;
background: #fff;
}
</style>
\ No newline at end of file
{
"status_code": 1,
"msg": "操作成功",
"data": {
"_id": {
"oid": "6267d7e03c5d2012c56a43e8"
},
"userid": "JinDuoXia",
"name": "毛细亚",
"department": [
4
],
"position": "",
"mobile": "18236536168",
"gender": "1",
"email": "",
"avatar": "https://wework.qpic.cn/wwpic3az/139259_PMNrkYz3SXeS019_1704886075/0",
"status": 1,
"isleader": 0,
"extattr": {
"attrs": [
]
},
"telephone": "",
"enable": 1,
"hide_mobile": 0,
"order": [
0
],
"main_department": 4,
"qr_code": "https://open.work.weixin.qq.com/wwopen/userQRCode?vcode=vc78f27c823c0be068",
"alias": "123132",
"is_leader_in_dept": [
0
],
"thumb_avatar": "https://wework.qpic.cn/wwhead/duc2TvpEgSTUk5XcCXup4xOJsyGFXcvS9fNicPuAERuNELRicnFsEwvHcAF8jF18Gfziavv8CnZKWU/100",
"direct_leader": [
],
"biz_mail": "jinduoxia@hzjswhcbyxgs3.wecom.work",
"corp_id": "wweaefe716636df3d1",
"external_user_count": 10,
"online_status": "offline",
"is_follow_user": 1,
"is_kf_account": 1,
"shell_userid": "1688858370304431",
"self_defined_columns": [
{
"name": "1231"
},
{
"name": "测试"
},
{
"name": "冯源"
}
],
"created_at": 1650972640,
"updated_at": 1747812312,
"active_time": "1747289758",
"login_pc": "PC01-01",
"external_profile": {
"external_attr": [
{
"type": 0,
"name": "工作时间",
"text": {
"value": ""
}
},
{
"type": 1,
"name": "服务升级",
"web": {
"url": "",
"title": ""
}
},
{
"type": 1,
"name": "意见反馈",
"web": {
"url": "",
"title": ""
}
},
{
"type": 1,
"name": "百度一下",
"web": {
"url": "",
"title": ""
}
},
{
"type": 0,
"name": "验收文本",
"text": {
"value": "测试"
}
},
{
"type": 2,
"name": "测试跳转",
"miniprogram": {
"appid": "",
"pagepath": "",
"title": ""
}
}
]
},
"show_avatar": "http://zhangsheng-1300623068.cos.ap-guangzhou.myqcloud.com/zhangsheng/service/avatars/20231026/GdkmBnfAH83ASRe8naN2QFPexiD65yKs1698312096458.png",
"show_name": "哈哈哈1231",
"weixin_blongs_id": 2955,
"group_chat_count": 2,
"group_chat_member_count": 12,
"receipt_cser_id": 4090,
"receipt_cser_name": "毛细亚"
},
"extra": {
}
}
\ No newline at end of file
<template>
<div class="home">
<div class="userInfo-content">
</div>
</template>
<script>
import {mapState, mapActions} from 'vuex'
export default {
name: 'HomeView',
// inject: ['authPromise'],
name: '',
mounted() {
// this.authPromise.then(() => {
// this.getAuthUser();
// });
},
data() {
return {
......@@ -29,3 +25,11 @@ export default {
}
}
</script>
<style lang="scss" scoped>
.userInfo-content{
width: 100%;
height: 100%;
background: #fff;
}
</style>
......@@ -51,7 +51,7 @@ module.exports = defineConfig({
outputStyle: 'expanded'
},
additionalData: `
@import "@/styles/global.scss";
@use "@/styles/global.scss";
`
}
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论