online-chat
This commit is contained in:
@ -13,7 +13,7 @@
|
||||
<!-- <span>微信扫码</span> -->
|
||||
<p style="margin-top: 10px; margin-bottom: 0; text-align: center;">
|
||||
<!-- <img src="/images/dz.png" style="width: 150px;"></img> -->
|
||||
<img src="./JoinCKACommunity.jpeg" style="width: 150px; padding: 10px;"></img>
|
||||
<img src="./JoinCKACommunity.jpeg" style="width: 150px; padding: 10px;"/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
<main class="page" style="padding-top: 2rem;">
|
||||
<Content class="theme-default-content" style="padding-top: 0; margin-top: 0; padding-bottom: 1rem;"/>
|
||||
<PageVssue style="max-width: 1000px; margin: auto; padding: 0 2.5rem;"></PageVssue>
|
||||
<OnlineChat></OnlineChat>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
@ -41,9 +42,10 @@ import Navbar from '@theme/components/Navbar.vue'
|
||||
import Page from '@theme/components/Page.vue'
|
||||
import Sidebar from '@theme/components/Sidebar.vue'
|
||||
import { resolveSidebarItems } from '../theme/util'
|
||||
import OnlineChat from '../theme/components/OnlineChat.vue'
|
||||
|
||||
export default {
|
||||
components: { Home, Page, Sidebar, Navbar },
|
||||
components: { Home, Page, Sidebar, Navbar, OnlineChat },
|
||||
|
||||
data () {
|
||||
return {
|
||||
|
||||
@ -11,15 +11,14 @@
|
||||
<div style="text-align: center; font-size: 18px; weight: 500;">
|
||||
<div style="background-color: rgb(236, 245, 255); padding: 10px 10px 10px 10px; margin-bottom: 10px; border: solid 1px #007af5;">
|
||||
<a href="https://github.com/eip-work/kuboard-press" target="_blank" @click="linkToStar">
|
||||
给一个 Github Star
|
||||
一个 Github Star
|
||||
<OutboundLink/>
|
||||
</a>
|
||||
就可以鼓励作者尽快完成
|
||||
<span style="color: red; font-weight: 500;">剩下的 {{$themeConfig.incompleteRatio}}% </span>
|
||||
是您对 Kuboard 最大的鼓励
|
||||
</div>
|
||||
<a href="https://github.com/eip-work/kuboard-press" target="_blank" @click="linkToStar">
|
||||
<div style="border: solid 1px #ddd;">
|
||||
<img src="./star.png" style="max-width: 100%; opacity: 0.6;">
|
||||
<img src="./star.png" style="max-width: 100%; opacity: 0.8;">
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 133 KiB |
@ -4,7 +4,26 @@ module.exports = {
|
||||
// configureWebpack: () => ({
|
||||
// devtool: 'source-map'
|
||||
// }),
|
||||
host: 'kuboard-develop',
|
||||
port: 8000,
|
||||
devServer: {
|
||||
proxy: {
|
||||
'/uc-api/': {
|
||||
target: 'http://kuboard-develop:8080',
|
||||
changeOrigin: true,
|
||||
pathRewrite: {
|
||||
'^/uc-api': '/'
|
||||
}
|
||||
},
|
||||
// '/uc-api/': {
|
||||
// target: 'https://uc-v3.kuboard.cn',
|
||||
// changeOrigin: true,
|
||||
// pathRewrite: {
|
||||
// '^/uc-api': '/api'
|
||||
// }
|
||||
// },
|
||||
},
|
||||
},
|
||||
modules: ['bootstrap-vue/nuxt'],
|
||||
title: 'Kuboard',
|
||||
description: '一款Kubernetes_Dashboard_简化Kubernetes的学习和使用_帮助您快速落地Kubernetes_提供_Kubernetes_免费中文教程_国内安装文档',
|
||||
|
||||
@ -13,6 +13,7 @@ import Container from './grid/Container'
|
||||
import Grid from './grid/Grid'
|
||||
import GridItem from './grid/GridItem'
|
||||
import defaults from './grid/utils/defaults'
|
||||
import './login-manager.js'
|
||||
|
||||
import Comp from './comp/index'
|
||||
|
||||
|
||||
23
.vuepress/login-manager.js
Normal file
23
.vuepress/login-manager.js
Normal file
@ -0,0 +1,23 @@
|
||||
import Vue from 'vue'
|
||||
import Cookies from 'js-cookie'
|
||||
|
||||
let TOKEN_KEY = 'kb-user-center-token'
|
||||
|
||||
window.KbUcloginStatus = {
|
||||
status: Cookies.get(TOKEN_KEY) !== null && Cookies.get(TOKEN_KEY) !== undefined,
|
||||
user: undefined
|
||||
}
|
||||
|
||||
Vue.prototype.$login = function (token) {
|
||||
// axios.defaults.headers.common['Authorization'] = token;
|
||||
// localStorage.setItem(TOKEN_KEY, token)
|
||||
Cookies.set(TOKEN_KEY, token, { path: '/' })
|
||||
window.KbUcloginStatus.status = true
|
||||
}
|
||||
|
||||
Vue.prototype.$logout = function () {
|
||||
window.KbUcloginStatus.status = false
|
||||
// localStorage.removeItem(TOKEN_KEY)
|
||||
Cookies.remove(TOKEN_KEY, { path: '/' })
|
||||
// delete (axios.defaults.headers.common['Authorization'])
|
||||
}
|
||||
3
.vuepress/public/chat/axios.min.js
vendored
Normal file
3
.vuepress/public/chat/axios.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
.vuepress/public/chat/icon-mq-round@2x.png
Normal file
BIN
.vuepress/public/chat/icon-mq-round@2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
192
.vuepress/public/chat/index.html
Normal file
192
.vuepress/public/chat/index.html
Normal file
@ -0,0 +1,192 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<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, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<title>Kuboard 在线支持</title>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script src="./axios.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function getCookie(cname) {
|
||||
var name = cname + "=";
|
||||
var ca = document.cookie.split(';');
|
||||
for(var i=0; i<ca.length; i++)
|
||||
{
|
||||
var c = ca[i].trim();
|
||||
if (c.indexOf(name)==0) return c.substring(name.length,c.length);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
Date.prototype.format = function(fmt) {
|
||||
var o = {
|
||||
"M+" : this.getMonth()+1, //月份
|
||||
"d+" : this.getDate(), //日
|
||||
"h+" : this.getHours(), //小时
|
||||
"m+" : this.getMinutes(), //分
|
||||
"s+" : this.getSeconds(), //秒
|
||||
"q+" : Math.floor((this.getMonth()+3)/3), //季度
|
||||
"S" : this.getMilliseconds() //毫秒
|
||||
};
|
||||
if(/(y+)/.test(fmt)) {
|
||||
fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
|
||||
}
|
||||
for(var k in o) {
|
||||
if(new RegExp("("+ k +")").test(fmt)){
|
||||
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
|
||||
}
|
||||
}
|
||||
return fmt;
|
||||
}
|
||||
let TOKEN_KEY = 'kb-user-center-token'
|
||||
function parse(query) {
|
||||
var qs = {};
|
||||
var i = query.indexOf('?');
|
||||
if (i < 0 && query.indexOf('=') < 0) {
|
||||
return qs;
|
||||
} else if (i >= 0) {
|
||||
query = query.substring(i + 1);
|
||||
}
|
||||
var parts = query.split('&');
|
||||
for (var n = 0; n < parts.length; n++) {
|
||||
var part = parts[n];
|
||||
var key = part.split('=')[0];
|
||||
var val = part.split('=')[1];
|
||||
key = key.toLowerCase();
|
||||
if (typeof qs[key] === 'undefined') {
|
||||
qs[key] = decodeURIComponent(val);
|
||||
} else if (typeof qs[key] === 'string') {
|
||||
var arr = [qs[key], decodeURIComponent(val)];
|
||||
qs[key] = arr;
|
||||
} else {
|
||||
qs[key].push(decodeURIComponent(val));
|
||||
}
|
||||
}
|
||||
return qs;
|
||||
}
|
||||
async function init() {
|
||||
(function (m, ei, q, i, a, j, s) {
|
||||
m[i] =
|
||||
m[i] ||
|
||||
function () {
|
||||
(m[i].a = m[i].a || []).push(arguments);
|
||||
};
|
||||
(j = ei.createElement(q)), (s = ei.getElementsByTagName(q)[0]);
|
||||
j.async = true;
|
||||
j.charset = 'UTF-8';
|
||||
j.src = 'https://static.meiqia.com/widget/loader.js';
|
||||
s.parentNode.insertBefore(j, s);
|
||||
})(window, document, 'script', '_MEIQIA');
|
||||
var data = parse(window.location.search);
|
||||
var entId = data.entid || data.eid;
|
||||
if (Object.prototype.toString.call(entId) === '[object Array]') {
|
||||
entId = +entId[0];
|
||||
} else {
|
||||
entId = +entId;
|
||||
}
|
||||
_MEIQIA('entId', '961dff7f89ddc015ac1f8e193bf774d0' || entId);
|
||||
_MEIQIA('standalone', function (config) {
|
||||
if (config.color) {
|
||||
document.body.style['background-color'] = '#' + config.color;
|
||||
}
|
||||
if (config.url) {
|
||||
document.body.style['background-image'] = 'url(' + config.url + ')';
|
||||
document.body.style['background-repeat'] = 'no-repeat';
|
||||
document.body.style['background-size'] = '100% 100%';
|
||||
}
|
||||
});
|
||||
_MEIQIA('withoutBtn');
|
||||
|
||||
if (!getCookie(TOKEN_KEY)) {
|
||||
window.alert('请先登录')
|
||||
window.location.href = '/support/?showLogin=true'
|
||||
}
|
||||
|
||||
// Kuboard Logic
|
||||
let ax = axios.create({
|
||||
baseURL: '/uc-api',
|
||||
})
|
||||
let orders = []
|
||||
let user = undefined
|
||||
await ax.get(`/orders/list`, {params: {
|
||||
status: 'PAID',
|
||||
pageNum: 1,
|
||||
pageSize: 1000
|
||||
}}).then(resp => {
|
||||
orders = resp.data.items
|
||||
}).catch(e => {
|
||||
console.log(e)
|
||||
})
|
||||
await ax.get('/users/selfInfo').then(resp => {
|
||||
user = resp.data.data
|
||||
}).catch(e => {
|
||||
console.log(e)
|
||||
})
|
||||
|
||||
data.clientid = user.id
|
||||
|
||||
let totalAmount = 0
|
||||
for (let order of orders) {
|
||||
totalAmount += order.totalPrice
|
||||
}
|
||||
totalAmount = Math.round(totalAmount)
|
||||
|
||||
data.metadata = {
|
||||
name: user.name, // 美洽默认字段
|
||||
email: user.email,
|
||||
tel: user.mobile,
|
||||
Count: orders.length,
|
||||
Amount: totalAmount,
|
||||
uc_id: user.id,
|
||||
}
|
||||
for (let i in orders) {
|
||||
let order = orders[i]
|
||||
let prefix = 'r' + (parseInt(i) + 1)
|
||||
if (i >= 5) {
|
||||
break
|
||||
}
|
||||
data.metadata[prefix + '_id'] = order.id //`${order.id} -- ${order.description} -- ${format(order.createTime, 'YYYY-MM-DD HH:mm')}`
|
||||
data.metadata[prefix + '_desc'] = order.description
|
||||
data.metadata[prefix + '_time'] = new Date(order.createTime).format("yyyy-MM-dd hh:mm") //format(order.createTime, 'YYYY-MM-DD HH:mm')
|
||||
}
|
||||
// Kuboard Logic
|
||||
|
||||
|
||||
if (data.metadata) {
|
||||
try {
|
||||
_MEIQIA('metadata', metadata);
|
||||
} catch (e) { }
|
||||
}
|
||||
if (data.language) {
|
||||
_MEIQIA('language', data.language);
|
||||
}
|
||||
if (data.fallback) {
|
||||
_MEIQIA('fallback', +data.fallback);
|
||||
}
|
||||
if (data.clientid) {
|
||||
_MEIQIA('clientId', data.clientid);
|
||||
}
|
||||
if (data.agentid || data.groupid) {
|
||||
_MEIQIA('assign', { agentToken: data.agentid || null, groupToken: data.groupid || null });
|
||||
}
|
||||
_MEIQIA('showPanel', {
|
||||
greeting: data.greeting || '',
|
||||
agentToken: data.agentid || null,
|
||||
groupToken: data.groupid || null
|
||||
});
|
||||
}
|
||||
init();
|
||||
</script>
|
||||
</body >
|
||||
</html >
|
||||
168
.vuepress/theme/components/OnlineChat.vue
Normal file
168
.vuepress/theme/components/OnlineChat.vue
Normal file
@ -0,0 +1,168 @@
|
||||
<template>
|
||||
<div v-if="isdebugging">
|
||||
<OnlineChatLogin ref="loginWindow" @loginSuccess="loginSuccess"></OnlineChatLogin>
|
||||
<b-button variant="outline-primary" size="sm" class="logout" v-if="showLogout" @click="logout">退出登录</b-button>
|
||||
<b-button variant="primary" size="sm" class="openChatWindow" v-if="showLogout" @click="openChatWindow">打开单独的聊天窗口</b-button>
|
||||
<div class="frameButton" @click="showChat">
|
||||
<span class="ecMDHC"></span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import OnlineChatLogin from './OnlineChatLogin.vue'
|
||||
import axios from 'axios'
|
||||
import {format} from 'date-fns'
|
||||
import Cookies from 'js-cookie'
|
||||
|
||||
(function(a, b, c, d, e, j, s) {
|
||||
a[d] = a[d] || function() {
|
||||
(a[d].a = a[d].a || []).push(arguments)
|
||||
};
|
||||
j = b.createElement(c),
|
||||
s = b.getElementsByTagName(c)[0];
|
||||
j.async = true;
|
||||
j.charset = 'UTF-8';
|
||||
j.src = 'https://static.meiqia.com/widget/loader.js';
|
||||
s.parentNode.insertBefore(j, s);
|
||||
})(window, document, 'script', '_MEIQIA');
|
||||
_MEIQIA('entId', '961dff7f89ddc015ac1f8e193bf774d0');
|
||||
_MEIQIA('manualInit');
|
||||
_MEIQIA('withoutBtn');
|
||||
|
||||
let TOKEN_KEY = 'kb-user-center-token'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showLogout: false,
|
||||
isdebugging: location.search === '?showLogin=true'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
components: { OnlineChatLogin },
|
||||
mounted () {
|
||||
},
|
||||
methods: {
|
||||
showChat () {
|
||||
console.log(Cookies.get(TOKEN_KEY))
|
||||
if (Cookies.get(TOKEN_KEY)) {
|
||||
this.loginSuccess()
|
||||
// _MEIQIA('showPanel');
|
||||
} else {
|
||||
this.$refs.loginWindow.show()
|
||||
}
|
||||
},
|
||||
async loginSuccess () {
|
||||
this.showLogout = true
|
||||
let ax = axios.create({
|
||||
baseURL: '/uc-api',
|
||||
// headers: {
|
||||
// common: {
|
||||
// Authorization: localStorage.getItem(TOKEN_KEY)
|
||||
// }
|
||||
// }
|
||||
})
|
||||
let orders = []
|
||||
let user = undefined
|
||||
await ax.get(`/orders/list`, {params: {
|
||||
status: 'PAID',
|
||||
pageNum: 1,
|
||||
pageSize: 1000
|
||||
}}).then(resp => {
|
||||
orders = resp.data.items
|
||||
}).catch(e => {
|
||||
console.log(e)
|
||||
})
|
||||
await ax.get('/users/selfInfo').then(resp => {
|
||||
user = resp.data.data
|
||||
}).catch(e => {
|
||||
console.log(e)
|
||||
})
|
||||
|
||||
_MEIQIA('clientId', user.id)
|
||||
|
||||
let totalAmount = 0
|
||||
for (let order of orders) {
|
||||
totalAmount += order.totalPrice
|
||||
}
|
||||
totalAmount = Math.round(totalAmount)
|
||||
|
||||
let metadata = {
|
||||
name: user.name, // 美洽默认字段
|
||||
email: user.email,
|
||||
tel: user.mobile,
|
||||
Count: orders.length,
|
||||
Amount: totalAmount,
|
||||
uc_id: user.id,
|
||||
}
|
||||
for (let i in orders) {
|
||||
let order = orders[i]
|
||||
let prefix = 'r' + (parseInt(i) + 1)
|
||||
if (i >= 5) {
|
||||
break
|
||||
}
|
||||
metadata[prefix + '_id'] = order.id //`${order.id} -- ${order.description} -- ${format(order.createTime, 'YYYY-MM-DD HH:mm')}`
|
||||
metadata[prefix + '_desc'] = order.description
|
||||
metadata[prefix + '_time'] = format(order.createTime, 'YYYY-MM-DD HH:mm')
|
||||
}
|
||||
|
||||
_MEIQIA('metadata', metadata);
|
||||
_MEIQIA('init');
|
||||
_MEIQIA('showPanel')
|
||||
},
|
||||
openChatWindow () {
|
||||
let url = '/chat/index.html'
|
||||
let a = document.createElement('a')
|
||||
document.body.appendChild(a)
|
||||
a.setAttribute('href', url)
|
||||
a.setAttribute('target', '_blank')
|
||||
a.click()
|
||||
document.body.removeChild(a)
|
||||
_MEIQIA('hidePanel')
|
||||
this.showLogout = false
|
||||
},
|
||||
logout () {
|
||||
this.showLogout = false
|
||||
_MEIQIA('hidePanel')
|
||||
localStorage.removeItem(TOKEN_KEY)
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="stylus">
|
||||
.ecMDHC {
|
||||
vertical-align: middle;
|
||||
padding-right: 32px;
|
||||
margin-top: 18px;
|
||||
height: 32px;
|
||||
display: inline-block;
|
||||
background: url(/chat/icon-mq-round@2x.png) 0px -355px / 64px no-repeat;
|
||||
}
|
||||
.frameButton {
|
||||
height: 60px;
|
||||
width: 60px;
|
||||
background-color: rgb(0, 122, 255);
|
||||
border-radius: 50%;
|
||||
box-shadow: rgb(0 0 0 / 16%) 0px 5px 14px;
|
||||
position: fixed;
|
||||
bottom: 100px;
|
||||
right: 25px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
.logout {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
right: 492px;
|
||||
}
|
||||
.openChatWindow {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
right: 340px
|
||||
}
|
||||
</style>
|
||||
218
.vuepress/theme/components/OnlineChatLogin.vue
Normal file
218
.vuepress/theme/components/OnlineChatLogin.vue
Normal file
@ -0,0 +1,218 @@
|
||||
<template>
|
||||
<b-modal ref="loginModel" id="login-model" title="付费用户专属答疑/技术支持通道" centered>
|
||||
<div shadow="none" class="login" style="font-size: 14px;">
|
||||
<div class="thanks">
|
||||
感谢大家的支持和认可,Kuboard 已经在超过三千家企业的生产环境中投产。随着用户量的扩大,微信群、QQ群的免费答疑已经不能很好的满足许多用户的诉求。为了更好的为付费用户提供支持,开通了专属于付费用户的在线答疑、技术支持通道。
|
||||
</div>
|
||||
<div class="thanks2">
|
||||
如果您已付费,请继续登录;如果您尚未付费,也可以登录后咨询付费方式。
|
||||
<router-link to="/support/#订阅">查看定价</router-link>
|
||||
</div>
|
||||
<b-form label-position="left" label-width="100px" :model="form" :rules="rules" size="large">
|
||||
<b-form-group label="手机号" prop="mobile">
|
||||
<b-form-input placeholder="请输入您的手机号" v-model="form.mobile"></b-form-input>
|
||||
</b-form-group>
|
||||
<b-form-group label="验证码" prop="capture">
|
||||
<div style="display: flex;">
|
||||
<b-form-input placeholder="请输入图片验证码" v-model="form.capture" style="width: calc(100% - 190px)"></b-form-input>
|
||||
<img v-if="showCapture" class="capture" :src="captureUrl" @click="loadCapture"/>
|
||||
</div>
|
||||
</b-form-group>
|
||||
<b-form-group label="短信验证码" prop="smsCode" required>
|
||||
<div style="display: flex;">
|
||||
<b-form-input placeholder="请输入短信验证码" v-model="form.smsCode" style="width: calc(100% - 190px)"></b-form-input>
|
||||
<b-button variant="primary" style="margin-left: 10px; width: 180px;" @click="getSmsCode"
|
||||
:loading="smsLoading"
|
||||
:disabled="countDown > 0 || !form.capture || !form.mobile">
|
||||
<span v-if="countDown" style="color: red;">{{countDown}}</span> 获取短信验证码
|
||||
</b-button>
|
||||
</div>
|
||||
</b-form-group>
|
||||
<b-alert :closable="false" show>如果您的手机号未曾注册过,将直接为您创建账号。</b-alert>
|
||||
</b-form>
|
||||
</div>
|
||||
<div slot="modal-footer">
|
||||
<div style="text-align: center; width: 100%; display: flex">
|
||||
<div style="margin-top: 8px; margin-right: 20px;">
|
||||
<b-form-checkbox v-model="goStandAlone">
|
||||
进入单独的聊天窗口
|
||||
</b-form-checkbox>
|
||||
</div>
|
||||
<b-button variant="primary" :disabled="!form.smsCode || !smsCodeId" size="large" :loading="loginLoading"
|
||||
@click="login" icon="el-icon-thumb" style="width: 180px;">
|
||||
登 录</b-button>
|
||||
</div>
|
||||
</div>
|
||||
</b-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ax from 'axios'
|
||||
|
||||
let axios = ax.create({ baseURL: '/uc-api' })
|
||||
|
||||
function guid() {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
|
||||
return v.toString(16);
|
||||
});
|
||||
}
|
||||
|
||||
export default {
|
||||
props: {
|
||||
},
|
||||
data () {
|
||||
let _this = this
|
||||
return {
|
||||
code: undefined,
|
||||
form: {
|
||||
mobile: undefined,
|
||||
capture: undefined,
|
||||
smsCode: undefined,
|
||||
},
|
||||
goStandAlone: false,
|
||||
smsCodeId: undefined,
|
||||
loginLoading: false,
|
||||
smsLoading: false,
|
||||
captureId: undefined,
|
||||
showCapture: false,
|
||||
countDown: 0,
|
||||
rules: {
|
||||
mobile: [
|
||||
{ required: true, message: '请输入手机号码', trigger: 'blur'},
|
||||
{ validator: (rule, value, callback) => {
|
||||
let pattern = /^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/;
|
||||
console.log(value, pattern.test(value))
|
||||
if (pattern.test(value)) {
|
||||
callback()
|
||||
} else {
|
||||
callback(new Error('手机号码格式不正确'))
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
capture: [
|
||||
{ required: true, message: '请输入图片验证码', trigger: 'blur' },
|
||||
{ validator: (rule, value, callback) => {
|
||||
axios.get(`/capture/validate/${_this.captureId}/${value}`).then(resp => {
|
||||
if (resp.data.data === 'OK') {
|
||||
callback()
|
||||
} else {
|
||||
callback(new Error(resp.data.message))
|
||||
}
|
||||
}).catch(e => {
|
||||
callback(new Error('验证出错: ' + e))
|
||||
})
|
||||
}, trigger: 'blur'}
|
||||
],
|
||||
smsCode: [
|
||||
{ required: true, message: '请输入短信验证码', trigger: 'blur' },
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
captureUrl () {
|
||||
return `/uc-api/capture/genVerifyCode?id=${this.captureId}`
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
// console.log(location)
|
||||
if (location.search === '?showLogin=true') {
|
||||
this.goStandAlone = true
|
||||
this.show()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
show () {
|
||||
this.loadCapture()
|
||||
this.$refs.loginModel.show()
|
||||
},
|
||||
loadCapture() {
|
||||
this.showCapture = false
|
||||
setTimeout(_ => {
|
||||
this.captureId = guid()
|
||||
this.showCapture = true
|
||||
}, 100)
|
||||
},
|
||||
getSmsCode () {
|
||||
this.smsLoading = true
|
||||
axios.post('/smscodes', {
|
||||
mobile: this.form.mobile,
|
||||
type: 'REGISTER/LOGIN',
|
||||
captureId: this.captureId,
|
||||
captureCode: this.form.capture,
|
||||
}).then(resp => {
|
||||
console.log(resp.data)
|
||||
this.$bvToast.toast('短信验证码已经发送到您的手机,请查收。', {title: '发送成功', variant: 'success', solid: true})
|
||||
this.smsLoading = false
|
||||
this.smsCodeId = resp.data.data
|
||||
this.countDown = 60
|
||||
let interval = setInterval(_ => {
|
||||
this.countDown = this.countDown - 1
|
||||
if (this.countDown === 0) {
|
||||
clearInterval(interval)
|
||||
}
|
||||
}, 1000)
|
||||
}).catch(e => {
|
||||
this.smsLoading = false
|
||||
this.$bvToast.toast('发送短信验证码失败: ' + (e.response ? e.response.data.message : e.message), {title: '发送失败', variant: 'danger', solid: true})
|
||||
})
|
||||
},
|
||||
login () {
|
||||
this.loginLoading = true
|
||||
axios.post(`/users/loginBySmsCode`, {
|
||||
smsCodeId: this.smsCodeId,
|
||||
smsCode: this.form.smsCode,
|
||||
}).then(resp => {
|
||||
this.$refs.loginModel.hide()
|
||||
this.$login(resp.data.data)
|
||||
this.loginLoading = false
|
||||
console.log(this.goStandAlone)
|
||||
if (this.goStandAlone) {
|
||||
window.location.href = '/chat/'
|
||||
} else {
|
||||
this.$emit('loginSuccess')
|
||||
}
|
||||
}).catch(e => {
|
||||
this.$bvToast.toast('登录失败: ' + e, {variant: 'danger', solid: true})
|
||||
this.loginLoading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.login {
|
||||
width: 450px;
|
||||
margin: auto;
|
||||
}
|
||||
.capture {
|
||||
width: 178px;
|
||||
height: 38px;
|
||||
vertical-align: bottom;
|
||||
border: 1px solid rgb(206, 212, 218);
|
||||
margin-left: 10px;
|
||||
border-radius: 4px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
.thanks {
|
||||
font-size: 13px;
|
||||
margin-bottom: 10px;
|
||||
color: #333;
|
||||
}
|
||||
.thanks2 {
|
||||
font-size: 13px;
|
||||
margin-bottom: 20px;
|
||||
color: red;
|
||||
}
|
||||
.thanks3 {
|
||||
color: green;
|
||||
margin-left: 20px;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
@ -58,6 +58,7 @@
|
||||
<LazyLoad :noAdsOnSharing="true">
|
||||
<AdSenseRightSide v-show="!$isSharing"/>
|
||||
</LazyLoad>
|
||||
<OnlineChat></OnlineChat>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
@ -65,9 +66,10 @@
|
||||
import PageEdit from '@theme/components/PageEdit.vue'
|
||||
import PageNav from '@theme/components/PageNav.vue'
|
||||
import JoinCommunity from './JoinCommunity'
|
||||
import OnlineChat from './OnlineChat.vue'
|
||||
|
||||
export default {
|
||||
components: { PageEdit, PageNav, JoinCommunity },
|
||||
components: { PageEdit, PageNav, JoinCommunity, OnlineChat },
|
||||
props: ['sidebarItems'],
|
||||
data () {
|
||||
return {
|
||||
|
||||
@ -7,6 +7,14 @@ server {
|
||||
expires 1d;
|
||||
}
|
||||
|
||||
location /uc-api/ {
|
||||
proxy_pass http://svc-user-center-v3:8080/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_pass_header Authorization;
|
||||
gzip on;
|
||||
expires -1;
|
||||
}
|
||||
|
||||
error_page 404 500 502 503 504 /404.html;
|
||||
location /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
@ -101,7 +101,6 @@ Kuboard,是一款免费的 Kubernetes 图形化管理工具,Kuboard 力图
|
||||
<b-card style="height: 100%; color: #2c3e50; line-height: 1.7;" shadow="hover">
|
||||
<p>
|
||||
<KuboardDemo suffix="install" label="在线体验 Kuboard" color="#007af5"/>
|
||||
|
||||
</p>
|
||||
<p>
|
||||
为保证环境的稳定性,在线 Demo 中只提供只读权限。<span style="color: #F56C6C; font-weight: 500;">(请在PC浏览器中打开)</span>
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
"animated-number-vue": "^1.0.0",
|
||||
"aos": "^2.3.4",
|
||||
"axios": "^0.19.2",
|
||||
"js-cookie": "^2.2.1",
|
||||
"babel-plugin-component": "^1.1.1",
|
||||
"bootstrap": "^4.6.0",
|
||||
"bootstrap-vue": "^2.21.2",
|
||||
|
||||
@ -4475,6 +4475,11 @@ javascript-stringify@^2.0.1:
|
||||
resolved "https://registry.npm.taobao.org/javascript-stringify/download/javascript-stringify-2.0.1.tgz#6ef358035310e35d667c675ed63d3eb7c1aa19e5"
|
||||
integrity sha1-bvNYA1MQ411mfGde1j0+t8GqGeU=
|
||||
|
||||
js-cookie@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8"
|
||||
integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==
|
||||
|
||||
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npm.taobao.org/js-tokens/download/js-tokens-4.0.0.tgz?cache=0&sync_timestamp=1586796305651&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjs-tokens%2Fdownload%2Fjs-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||
|
||||
Reference in New Issue
Block a user