feat: 增加调试登录功能;调整商业号、个人 WA 设置

2.0/email-builder
Jimmy Liow 11 months ago
parent 2383b1f3af
commit 85c089cf70

@ -1,13 +1,17 @@
# Global sales # Global sales
聊天式销售平台
销售平台 2.0
## 开发设置 ## 开发设置
所有命令都在 cmd 目录,
1. 安装组件npm install 1. 安装组件npm install
2. 运行开发环境npm run dev 或者 start.bat 2. 运行开发环境dev.bat
3. 打包代码:npm run build 或者 build.bat 3. 打包代码build.bat
## 版本设置 ## 版本设置
npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git] npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git]
npm version premajor --no-git-tag-version npm version premajor --no-git-tag-version
@ -22,5 +26,11 @@ npm version patch --no-git-tag-version
[聊天式销售平台需求文档](https://www.kdocs.cn/l/calaUjgmCmDA?from=docs&reqtype=kdocs&startTime=1703645330177&createDirect=true&newFile=true) [聊天式销售平台需求文档](https://www.kdocs.cn/l/calaUjgmCmDA?from=docs&reqtype=kdocs&startTime=1703645330177&createDirect=true&newFile=true)
## vonage语音视频 ## vonage语音视频
安装模块 npm i @vonage/client-sdk 安装模块 npm i @vonage/client-sdk
## 本机测试账号
GLOBAL_SALES_LOGIN_USER
{"userId":"383","userIdStr":"383,609","username":"廖一军","avatarUrl":"https://static-legacy.dingtalk.com/media/lALPBDDrhXr716HNAoDNAoA_640_640.png","mobile":"+86-18777396951","email":"lyj@hainatravel.com","openId":"iioljiPmZ4RPoOYpkFiSn7IKAiEiE","accountList":[{"OPI_SN":383,"OPI_Code":"LYJ","OPI_NameCN":"廖一军","OPI_DEI_SN":7,"OPI_NameEN":"Jimmy Liow"},{"OPI_SN":609,"OPI_Code":"LYJAH","OPI_NameCN":"廖一军ah","OPI_DEI_SN":28,"OPI_NameEN":"Jimmy Liow"}],"emailList":["lyj@hainatravel.com","lyj@asiahighlights.com","lyj@chinahighlights.net","lyj@globalhighlights.com"],"whatsappinfo": {"whatsapp_wa": "8617607730395","whatsapp_waba": "8618174165365"}}

@ -10,25 +10,78 @@ import {
List, List,
Result, Result,
Button, Button,
Image, Flex,
Select, Select,
Spin,
Form,
Typography,
QRCode,
} from 'antd' } from 'antd'
import { UserOutlined } from '@ant-design/icons' import {
UserOutlined,
InfoCircleOutlined,
CloseCircleFilled,
ReloadOutlined,
CheckCircleFilled,
} from '@ant-design/icons'
import useAuthStore from '@/stores/AuthStore' import useAuthStore from '@/stores/AuthStore'
function Profile() { function Profile() {
const loginUser = useAuthStore((state) => state.loginUser) const loginUser = useAuthStore((state) => state.loginUser)
useEffect(() => { useEffect(() => {
console.info(loginUser)
// //
// throw new Error('💥 CABOOM 💥') // throw new Error('💥 CABOOM 💥')
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []) }, [])
const customStatusRender = (info) => {
switch (info.status) {
case 'expired':
return (
<div>
<CloseCircleFilled
style={{
color: 'red',
}}
/>{' '}
{info.locale?.expired}
<p>
<Button type='link' onClick={info.onRefresh}>
<ReloadOutlined /> {info.locale?.refresh}
</Button>
</p>
</div>
)
case 'loading':
return (
<Space direction='vertical'>
<Spin />
<p>Loading...</p>
</Space>
)
case 'scanned':
return (
<div>
<CheckCircleFilled
style={{
color: 'green',
}}
/>{' '}
{info.locale?.scanned}
</div>
)
default:
return null
}
}
return ( return (
<> <>
<Row> <Row>
<Col span={12} offset={6}> <Col span={6} offset={6}>
<Descriptions title='个人资料' layout='vertical' column={2}> <Descriptions title='个人资料' layout='vertical' column={1}>
<Descriptions.Item label='名字'> <Descriptions.Item label='名字'>
<Space size='middle'> <Space size='middle'>
<Avatar src={loginUser.avatarUrl}> <Avatar src={loginUser.avatarUrl}>
@ -49,84 +102,90 @@ function Profile() {
) )
})} })}
</Descriptions.Item> </Descriptions.Item>
<Descriptions.Item label='手机'>
{loginUser.mobile}
</Descriptions.Item>
<Descriptions.Item label='商业号身份'> <Descriptions.Item label='商业号身份'>
<Space> <Form
<Select layout='vertical'
defaultValue='GH 顾问' // form={form}
style={{ >
width: 200, <Form.Item
}} tooltip={{
options={[ title: '你所属的业务部门',
{ icon: <InfoCircleOutlined />,
value: '18741256987', }}>
label: 'GH 顾问(18741256987)', <Select
}, defaultValue='8617607730395'
{ options={[
value: '13845214785', {
label: 'GH 客服(13845214785)', value: '8618174165365',
}, label: 'GH 客服(8618174165365)',
{ },
value: '191477856351', {
label: 'GH 客运(191477856351)', value: '8617607730395',
}, label: 'GH 顾问(8617607730395)',
{ },
value: '0', {
label: '国际事业部(无)', value: '191477856351',
disabled: true, label: 'GH 客运(191477856351)',
}, },
{ {
value: '0', value: '国际事业部',
label: 'CT 事业部(无)', label: '国际事业部(无)',
disabled: true, disabled: true,
}, },
{ {
value: '0', value: 'CT 事业部',
label: '花梨鹰事业部(无)', label: 'CT 事业部(无)',
disabled: true, disabled: true,
}, },
]} {
/> value: '花梨鹰事业部',
<Button type="primary">切换</Button> label: '花梨鹰事业部(无)',
</Space> disabled: true,
},
]}
/>
</Form.Item>
<Form.Item>
<Button type='primary'>保存</Button>
</Form.Item>
</Form>
</Descriptions.Item> </Descriptions.Item>
</Descriptions> </Descriptions>
</Col> </Col>
</Row> <Col span={6}>
<Divider orientation='left'></Divider>
<Row>
<Col span={6} offset={6}>
{/* {loginUser.email} */}
<List <List
header={<div>邮箱</div>} header={<div>邮箱</div>}
dataSource={[ dataSource={loginUser.emailList}
loginUser.email,
'christyluo@chinahighlights.com',
'christyluo@chinahighlights.net',
'christyluo@asiahighlights.com',
'christyluo@asiahighlights.net',
'christyluo@globalhighlights.com',
'christyluo@globalhighlights.net',
'christyluo@163.com',
]}
renderItem={(item) => <List.Item>{item}</List.Item>} renderItem={(item) => <List.Item>{item}</List.Item>}
/> />
</Col> </Col>
</Row>
<Divider orientation='left'></Divider>
<Row>
<Col span={6} offset={6}>
<Typography>
<Typography.Title level={2}>在系统上使用 WhatsApp</Typography.Title>
<Typography.Paragraph>
<ul>
<li>在手机上打开 WhatsApp</li>
<li>点击已关联的设备然后点击关联新设备</li>
<li>将手机对准屏幕扫描二维码</li>
</ul>
</Typography.Paragraph>
</Typography>
</Col>
<Col span={6}> <Col span={6}>
<Result <Flex gap="middle" vertical justify={'center'} align={'center'}>
icon={ <QRCode
<Image size={264}
preview={false} value={'https://web.whatsapp.com/'}
width={200} status='scanned'
src='https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png' statusRender={customStatusRender}
/> />
} WhatsApp8618754124786
title='登录成功' <Button type='primary'>登出</Button>
extra={<Button type='primary'>退出账号</Button>} </Flex>
/>
</Col> </Col>
</Row> </Row>
</> </>

@ -1,6 +1,6 @@
import useAuthStore from '@/stores/AuthStore' import useAuthStore from '@/stores/AuthStore'
import { Flex, Result, Spin, Typography } from 'antd' import { Flex, Input, Button, Typography } from 'antd'
import { useEffect, useState } from 'react' import { useEffect, useState, useRef } from 'react'
import { useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'
const { Title } = Typography const { Title } = Typography
@ -8,7 +8,6 @@ const { Title } = Typography
// https://open.dingtalk.com/document/orgapp/tutorial-obtaining-user-personal-information#title-qpi-0qv-anm // https://open.dingtalk.com/document/orgapp/tutorial-obtaining-user-personal-information#title-qpi-0qv-anm
function QRCode() { function QRCode() {
const navigate = useNavigate() const navigate = useNavigate()
const [result, setResult] = useState('') const [result, setResult] = useState('')
@ -16,16 +15,19 @@ function QRCode() {
// const loginStatus = useAuthStore((state) => state.loginStatus) // const loginStatus = useAuthStore((state) => state.loginStatus)
// const setLoginStatus = useAuthStore((state) => state.setLoginStatus) // const setLoginStatus = useAuthStore((state) => state.setLoginStatus)
// const loginUser = useAuthStore((state) => state.loginUser) // const loginUser = useAuthStore((state) => state.loginUser)
// const login = useAuthStore((state) => state.login) const login = useAuthStore((state) => state.login)
const codeRef = useRef()
useEffect(() => { useEffect(() => {
// if (loginUser.userId > 0) { // if (loginUser.userId > 0) {
// navigate('/') // navigate('/')
// } // }
}, []) }, [])
useEffect(() => { useEffect(() => {
import('https://g.alicdn.com/dingding/h5-dingtalk-login/0.21.0/ddlogin.js').then(() => { import(
'https://g.alicdn.com/dingding/h5-dingtalk-login/0.21.0/ddlogin.js'
).then(() => {
window.DTFrameLogin( window.DTFrameLogin(
{ {
id: 'qrCodeContainer', id: 'qrCodeContainer',
@ -33,7 +35,9 @@ function QRCode() {
height: 300, height: 300,
}, },
{ {
redirect_uri: encodeURIComponent('https://sales.mycht.cn/p/dingding/callback'), redirect_uri: encodeURIComponent(
'https://sales.mycht.cn/p/dingding/callback',
),
client_id: 'dingwgdx6emlxr3fcrg8', client_id: 'dingwgdx6emlxr3fcrg8',
scope: 'openid', scope: 'openid',
response_type: 'code', response_type: 'code',
@ -42,7 +46,6 @@ function QRCode() {
}, },
(loginResult) => { (loginResult) => {
const { authCode } = loginResult const { authCode } = loginResult
// login(authCode)
setResult(authCode) setResult(authCode)
}, },
(errorMsg) => { (errorMsg) => {
@ -56,10 +59,24 @@ function QRCode() {
return ( return (
<Flex justify='center' align='center' gap='middle' vertical> <Flex justify='center' align='center' gap='middle' vertical>
<Title level={4}>使用钉钉扫码</Title> <Title level={4}>使用钉钉扫码</Title>
<div id='qrCodeContainer' style={{ border: '12px solid rgba(5, 5, 5, 0.06)', borderRadius: '8px' }}></div> <div
id='qrCodeContainer'
style={{
border: '12px solid rgba(5, 5, 5, 0.06)',
borderRadius: '8px',
}}></div>
<span>钉钉 authCode: {result}</span> <span>钉钉 authCode: {result}</span>
<Input placeholder='placeholder' ref={codeRef} />
<Button
danger
onClick={() => {
console.info(codeRef.current.nativeElement.value)
login(codeRef.current.nativeElement.value)
}}>
登录
</Button>
</Flex> </Flex>
) )
} }
export default QRCode export default QRCode

Loading…
Cancel
Save