Commit 0409a5c2 by zhaopanyu

zpy10.10

parent e6d3e9ae
...@@ -28,4 +28,9 @@ npm run build:stage ...@@ -28,4 +28,9 @@ npm run build:stage
# 构建生产环境 # 构建生产环境
npm run build:prod npm run build:prod
``` ```
\ No newline at end of file #开发环境
在index页面,打开created中 this.csToken()
#生产环境
在index页面,打开created中 this.getCode()
...@@ -12,7 +12,6 @@ import directive from "./directive"; // directive ...@@ -12,7 +12,6 @@ import directive from "./directive"; // directive
import plugins from "./plugins"; // plugins import plugins from "./plugins"; // plugins
import { download } from "@/utils/request"; import { download } from "@/utils/request";
import moment from "moment"; import moment from "moment";
import "./assets/icons"; // icon import "./assets/icons"; // icon
import "./permission"; // permission control import "./permission"; // permission control
import { getDicts } from "@/api/system/dict/data"; import { getDicts } from "@/api/system/dict/data";
......
...@@ -57,6 +57,11 @@ export const constantRoutes = [ ...@@ -57,6 +57,11 @@ export const constantRoutes = [
hidden: true, hidden: true,
}, },
{ {
path: "/dd",
component: () => import("@/views/whitePage"),
hidden: true,
},
{
path: "/register", path: "/register",
component: () => import("@/views/register"), component: () => import("@/views/register"),
hidden: true, hidden: true,
...@@ -71,7 +76,7 @@ export const constantRoutes = [ ...@@ -71,7 +76,7 @@ export const constantRoutes = [
component: () => import("@/views/error/401"), component: () => import("@/views/error/401"),
hidden: true, hidden: true,
}, },
{ {
path: "", path: "",
component: Layout, component: Layout,
......
import {login, logout, getInfo} from '@/api/login' import { login, logout, getInfo } from "@/api/login";
import {getToken, setToken, removeToken} from '@/utils/auth' import { getToken, setToken, removeToken } from "@/utils/auth";
const user = { const user = {
state: { state: {
token: getToken(), token: getToken(),
name: '', name: "",
employeeType: '', employeeType: "",
avatar: '', avatar: "",
sign: '', sign: "",
roles: [], roles: [],
permissions: [], permissions: [],
roleKey: '', roleKey: "",
roleId: '', roleId: "",
deptId: '', deptId: "",
userId: '', userId: "",
teacher: {}, teacher: {},
education: '', education: "",
sex: "", sex: "",
}, },
mutations: { mutations: {
SET_TOKEN: (state, token) => { SET_TOKEN: (state, token) => {
state.token = token state.token = token;
}, },
SET_NAME: (state, name) => { SET_NAME: (state, name) => {
state.name = name state.name = name;
}, },
SET_EDUCATION: (state, education) => { SET_EDUCATION: (state, education) => {
state.education = education state.education = education;
}, },
SET_EMPLOYEETYPE: (state, employeeType) => { SET_EMPLOYEETYPE: (state, employeeType) => {
state.employeeType = employeeType state.employeeType = employeeType;
}, },
SET_AVATAR: (state, avatar) => { SET_AVATAR: (state, avatar) => {
state.avatar = avatar state.avatar = avatar;
}, },
SET_SIGN: (state, sign) => { SET_SIGN: (state, sign) => {
state.sign = sign state.sign = sign;
}, },
SET_ROLES: (state, roles) => { SET_ROLES: (state, roles) => {
state.roles = roles state.roles = roles;
}, },
SET_PERMISSIONS: (state, permissions) => { SET_PERMISSIONS: (state, permissions) => {
state.permissions = permissions state.permissions = permissions;
}, },
SET_USER: (state, info) => { SET_USER: (state, info) => {
...@@ -56,92 +56,105 @@ const user = { ...@@ -56,92 +56,105 @@ const user = {
}, },
SET_SEX: (state, sex) => { SET_SEX: (state, sex) => {
state.sex = sex; state.sex = sex;
} },
}, },
actions: { actions: {
// 登录 // 登录
Login({commit}, userInfo) { Login({ commit }, userInfo) {
// const username = userInfo.username.trim() // const username = userInfo.username.trim()
const phonenumber = userInfo.phonenumber.trim() const phonenumber = userInfo.phonenumber.trim();
const password = userInfo.password const password = userInfo.password;
const code = userInfo.code const code = userInfo.code;
const uuid = userInfo.uuid const uuid = userInfo.uuid;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
login(phonenumber, password, code, uuid).then(res => { login(phonenumber, password, code, uuid)
setToken(res.token) .then((res) => {
commit('SET_TOKEN', res.token) setToken(res.token);
resolve() commit("SET_TOKEN", res.token);
}).catch(error => { resolve();
reject(error) })
}) .catch((error) => {
}) reject(error);
});
});
}, },
// 获取用户信息 // 获取用户信息
GetInfo({commit, state}) { GetInfo({ commit, state }) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
getInfo().then(res => { getInfo()
// console.log(res, 81) .then((res) => {
const user = res.user console.log("getInfo", res);
const teacher = res.teacher const user = res.user;
const avatar = (user.avatar == "" || user.avatar == null) ? require("@/assets/images/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatar; const teacher = res.teacher;
const sign = (user.sign == "" || user.sign == null) ? require("@/assets/images/profile.jpg") : process.env.VUE_APP_BASE_API + user.sign; const avatar =
if (res.roles &&/* */ res.roles.length > 0) { // 验证返回的roles是否是一个非空数组 user.avatar == "" || user.avatar == null
commit('SET_ROLES', res.roles) ? require("@/assets/images/profile.jpg")
commit('SET_PERMISSIONS', res.permissions) : process.env.VUE_APP_BASE_API + user.avatar;
} else { const sign =
commit('SET_ROLES', ['ROLE_DEFAULT']) user.sign == "" || user.sign == null
} ? require("@/assets/images/profile.jpg")
commit('SET_SEX', user.sex) : process.env.VUE_APP_BASE_API + user.sign;
commit('SET_NAME', user.userName) if (res.roles && /* */ res.roles.length > 0) {
commit('SET_EDUCATION', teacher.education) // 验证返回的roles是否是一个非空数组
commit('SET_EMPLOYEETYPE', user.employeeType) commit("SET_ROLES", res.roles);
commit("SET_PERMISSIONS", res.permissions);
} else {
commit("SET_ROLES", ["ROLE_DEFAULT"]);
}
commit("SET_SEX", user.sex);
commit("SET_NAME", user.userName);
commit("SET_EDUCATION", teacher.education);
commit("SET_EMPLOYEETYPE", user.employeeType);
commit('SET_AVATAR', avatar) commit("SET_AVATAR", avatar);
commit('SET_SIGN', sign) commit("SET_SIGN", sign);
commit('SET_USER', { commit("SET_USER", {
deptId: user.deptId, deptId: user.deptId,
roleId: user.roles[0] && user.roles[0].roleId, roleId: user.roles[0] && user.roles[0].roleId,
userId: user.userId, userId: user.userId,
roleKey: res.roles[0] roleKey: res.roles[0],
}) });
commit('SET_TEACHER', { commit("SET_TEACHER", {
...res.teacher, ...res.teacher,
deptName: user.dept.deptName, deptName: user.dept.deptName,
roles: user.roles.map(item => item.roleName).join('、') roles: user.roles.map((item) => item.roleName).join("、"),
});
resolve(res);
}) })
resolve(res) .catch((error) => {
}).catch(error => { reject(error);
reject(error) });
}) });
})
}, },
// 退出系统 // 退出系统
LogOut({commit, state}) { LogOut({ commit, state }) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
logout(state.token).then(() => { logout(state.token)
commit('SET_TOKEN', '') .then(() => {
commit('SET_ROLES', []) commit("SET_TOKEN", "");
commit('SET_PERMISSIONS', []) commit("SET_ROLES", []);
removeToken() commit("SET_PERMISSIONS", []);
resolve() removeToken();
}).catch(error => { resolve();
reject(error) })
}) .catch((error) => {
}) reject(error);
});
});
}, },
// 前端 登出 // 前端 登出
FedLogOut({commit}) { FedLogOut({ commit }) {
return new Promise(resolve => { return new Promise((resolve) => {
commit('SET_TOKEN', '') commit("SET_TOKEN", "");
removeToken() removeToken();
resolve() resolve();
}) });
} },
} },
} };
export default user export default user;
...@@ -404,8 +404,7 @@ import { getUser } from '@/api/system/user' ...@@ -404,8 +404,7 @@ import { getUser } from '@/api/system/user'
// 任务模块 // 任务模块
// import { taskList } from "@/api/smartSchool/studentManage/studentLeave"; // import { taskList } from "@/api/smartSchool/studentManage/studentLeave";
import { listPic } from '@/api/smartSchool/schoolManage/introduce/pic' import { listPic } from '@/api/smartSchool/schoolManage/introduce/pic'
import router from "../router";
import Cookies from "js-cookie"; import Cookies from "js-cookie";
import * as dd from 'dingtalk-jsapi'; import * as dd from 'dingtalk-jsapi';
import { getToken, setToken, removeToken } from '@/utils/auth' import { getToken, setToken, removeToken } from '@/utils/auth'
...@@ -530,7 +529,6 @@ export default { ...@@ -530,7 +529,6 @@ export default {
}, },
methods: { methods: {
// 获取code // 获取code
getCode() { getCode() {
dd.getAuthCode({ dd.getAuthCode({
...@@ -577,32 +575,18 @@ export default { ...@@ -577,32 +575,18 @@ export default {
// 测试token // 测试token
csToken() { csToken() {
getCode(123).then(res => { if (getToken()) {
console.log('res', res.token); console.log('getToken', getToken());
if (res.token) { this.init()
setToken(res.token) } else {
this.$store.commit('SET_TOKEN', res.token) this.$router.push({ path: '/login' });
// this.$router.push({ path: '/index' }); }
// 判断当前用户是否已拉取完user_info信息
this.$store.dispatch('GetInfo').then((res) => {
this.$store.dispatch('GenerateRoutes').then(accessRoutes => {
// 根据roles权限生成可访问的路由表
router.addRoutes(accessRoutes) // 动态添加可访问路由表
this.init()
})
})
} else {
this.$message.error(res.message)
}
})
}, },
//从后端获取任务数量 //从后端获取任务数量
taskNum() { taskNum() {
getTaskNum().then(res => { getTaskNum().then(res => {
console.log('taskNumList', res) // console.log('taskNumList', res)
this.taskNumList = res.data this.taskNumList = res.data
}) })
}, },
...@@ -683,6 +667,7 @@ export default { ...@@ -683,6 +667,7 @@ export default {
// 获取用户信息 // 获取用户信息
getUserInfo() { getUserInfo() {
this.userInfo = this.$store.state.user.teacher this.userInfo = this.$store.state.user.teacher
console.log('this.userInfo', this.$store.state.user.teacher);
}, },
// 获取通知公告信息 // 获取通知公告信息
......
<template> <template>
<button @click="getCode">123</button>
<!--<div class="login-container">--> <!--<div class="login-container">-->
<!--<div class="login-page login-cover">--> <!--<div class="login-page login-cover">-->
<!-- <div class="cover-container">--> <!-- <div class="cover-container">-->
...@@ -18,13 +17,13 @@ ...@@ -18,13 +17,13 @@
<!-- </div>--> <!-- </div>-->
<!--</div>--> <!--</div>-->
<!--</div>--> <!--</div>-->
<!-- <div class="login"> <div class="login">
<div class="login-card-container"> <div class="login-card-container">
<div class="login-card-left"> <div class="login-card-left">
<el-image style="width: 600px;" :src="require('@/assets/images/login.png')" lazy></el-image> --> <el-image style="width: 600px;" :src="require('@/assets/images/login.png')" lazy></el-image>
<!-- :src="require('@/assets/images/logo-login.gif')"--> <!-- :src="require('@/assets/images/logo-login.gif')"-->
<!-- </div> --> </div>
<!-- <div class="login-card-right"> <div class="login-card-right">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form"> <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
<h3 class="title">智慧校园管理系统</h3> <h3 class="title">智慧校园管理系统</h3>
<el-form-item prop="phonenumber"> <el-form-item prop="phonenumber">
...@@ -37,22 +36,22 @@ ...@@ -37,22 +36,22 @@
auto-complete="off" placeholder="密码" @keyup.enter.native="handleLogin"> auto-complete="off" placeholder="密码" @keyup.enter.native="handleLogin">
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" /> <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
</el-input> </el-input>
</el-form-item> --> </el-form-item>
<!-- <el-form-item prop="code" v-if="captchaEnabled">--> <!-- <el-form-item prop="code" v-if="captchaEnabled">-->
<!-- <el-input--> <!-- <el-input-->
<!-- v-model="loginForm.code"--> <!-- v-model="loginForm.code"-->
<!-- auto-complete="off"--> <!-- auto-complete="off"-->
<!-- placeholder="验证码"--> <!-- placeholder="验证码"-->
<!-- style="width: 63%"--> <!-- style="width: 63%"-->
<!-- @keyup.enter.native="handleLogin"--> <!-- @keyup.enter.native="handleLogin"-->
<!-- >--> <!-- >-->
<!-- <svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />--> <!-- <svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />-->
<!-- </el-input>--> <!-- </el-input>-->
<!-- <div class="login-code">--> <!-- <div class="login-code">-->
<!-- <img :src="codeUrl" @click="getCode" class="login-code-img"/>--> <!-- <img :src="codeUrl" @click="getCode" class="login-code-img"/>-->
<!-- </div>--> <!-- </div>-->
<!-- </el-form-item>--> <!-- </el-form-item>-->
<!-- <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox> <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>
<el-form-item style="width:100%;"> <el-form-item style="width:100%;">
<el-button :loading="loading" size="medium" type="primary" style="width:100%;" <el-button :loading="loading" size="medium" type="primary" style="width:100%;"
@click.native.prevent="handleLogin"> @click.native.prevent="handleLogin">
...@@ -65,14 +64,16 @@ ...@@ -65,14 +64,16 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
</div> --> </div>
<!-- 底部 --> <!-- 底部 -->
<!-- <div class="el-login-footer"> <div class="el-login-footer">
<span>© 2021 zhimin Copyright </span> <span>© 2021 zhimin Copyright </span>
</div> </div>
</div> --> </div>
</template> </template>
<script> <script>
import { getCodeImg } from "@/api/login"; import { getCodeImg } from "@/api/login";
import Cookies from "js-cookie"; import Cookies from "js-cookie";
...@@ -86,13 +87,8 @@ export default { ...@@ -86,13 +87,8 @@ export default {
name: "Login", name: "Login",
data() { data() {
return { return {
code: null, code: null,
token: null, token: null,
authCodeTimestamp: 0, // 用于存储免登码的时间戳
authCodeExpiration: 5 * 60 * 1000, // 免登码有效期(假设为5分钟)
codeUrl: "", codeUrl: "",
loginForm: { loginForm: {
// username: "admin", // username: "admin",
...@@ -137,7 +133,7 @@ export default { ...@@ -137,7 +133,7 @@ export default {
}, },
mounted() { mounted() {
// this.getCode(); // this.getCode();
// this.getCookie(); this.getCookie();
}, },
methods: { methods: {
// 获取code // 获取code
...@@ -199,59 +195,55 @@ export default { ...@@ -199,59 +195,55 @@ export default {
// // console.error('登录失败', error); // // console.error('登录失败', error);
// } // }
// } // }
getCode() {
getCodeImg().then(res => {
this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled;
// getCode() { if (this.captchaEnabled) {
this.codeUrl = "data:image/gif;base64," + res.img;
// getCodeImg().then(res => { this.loginForm.uuid = res.uuid;
// this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled; }
// if (this.captchaEnabled) { });
// this.codeUrl = "data:image/gif;base64," + res.img; },
// this.loginForm.uuid = res.uuid; getCookie() {
// } // const username = Cookies.get("username");
// }); // 获取手机号码
// }, const phonenumber = Cookies.get("phonenumber");
// getCookie() { const password = Cookies.get("password");
// // const username = Cookies.get("username"); const rememberMe = Cookies.get('rememberMe')
// // 获取手机号码 this.loginForm = {
// const phonenumber = Cookies.get("phonenumber"); // username: username === undefined ? this.loginForm.username : username,
// const password = Cookies.get("password"); phonenumber: phonenumber === undefined ? this.loginForm.phonenumber : phonenumber,
// const rememberMe = Cookies.get('rememberMe') password: password === undefined ? this.loginForm.password : decrypt(password),
// this.loginForm = { rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
// // username: username === undefined ? this.loginForm.username : username, };
// phonenumber: phonenumber === undefined ? this.loginForm.phonenumber : phonenumber, },
// password: password === undefined ? this.loginForm.password : decrypt(password), handleLogin() {
// rememberMe: rememberMe === undefined ? false : Boolean(rememberMe) this.$refs.loginForm.validate(valid => {
// }; if (valid) {
// }, this.loading = true;
// handleLogin() { if (this.loginForm.rememberMe) {
// this.$refs.loginForm.validate(valid => { // Cookies.set("username", this.loginForm.username, { expires: 30 });
// if (valid) { Cookies.set("phonenumber", this.loginForm.phonenumber, { expires: 30 });
// this.loading = true; Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 });
// if (this.loginForm.rememberMe) { Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 });
// // Cookies.set("username", this.loginForm.username, { expires: 30 }); } else {
// Cookies.set("phonenumber", this.loginForm.phonenumber, { expires: 30 }); // Cookies.remove("username");
// Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 }); Cookies.remove("phonenumber");
// Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 }); Cookies.remove("password");
// } else { Cookies.remove('rememberMe');
// // Cookies.remove("username"); }
// Cookies.remove("phonenumber"); this.$store.dispatch("Login", this.loginForm).then(() => {
// Cookies.remove("password"); this.$router.push({ path: this.redirect || "/" }).catch(() => {
// Cookies.remove('rememberMe'); });
// } }).catch(() => {
// this.$store.dispatch("Login", this.loginForm).then(() => { this.loading = false;
// this.$router.push({ path: this.redirect || "/" }).catch(() => { if (this.captchaEnabled) {
// }); this.getCode();
// }).catch(() => { }
// this.loading = false; });
// if (this.captchaEnabled) { }
// this.getCode(); });
// } }
// });
// }
// });
// }
} }
......
...@@ -92,6 +92,7 @@ ...@@ -92,6 +92,7 @@
<el-link :href="`${baseUrl}${file.accessoryUrl}`" :underline="false" target="_blank"> <el-link :href="`${baseUrl}${file.accessoryUrl}`" :underline="false" target="_blank">
<span class="el-icon-document"> {{ file.accessoryName }} </span> <span class="el-icon-document"> {{ file.accessoryName }} </span>
</el-link> </el-link>
</li> </li>
</el-form-item> </el-form-item>
</el-col> </el-col>
...@@ -217,7 +218,7 @@ export default { ...@@ -217,7 +218,7 @@ export default {
}, },
/** 提交按钮 */ /** 提交按钮 */
submitForm: function () { submitForm: function () {
this.$refs["form"].validate((valid) => { this.$refs["form"].validate((valid) => {
if (valid) { if (valid) {
if (this.schoolAccessoryList.length > 0) { if (this.schoolAccessoryList.length > 0) {
......
<template> <template>
<div> <div>
<button @click="getAuthCode">获取钉钉授权码</button> <button @click="csToken">获取钉钉授权码</button>
</div> </div>
</template> </template>
<script> <script>
import * as dd from 'dingtalk-jsapi'; import * as dd from 'dingtalk-jsapi';
import { getCode } from "@/api/ddLogin"; import { getCode } from "@/api/ddLogin";
import router from "../router";
import { getToken, setToken, removeToken } from '@/utils/auth'
export default { export default {
data() { data() {
...@@ -14,31 +16,29 @@ export default { ...@@ -14,31 +16,29 @@ export default {
redirect: "/index", // 这里假设要跳转到首页 redirect: "/index", // 这里假设要跳转到首页
code: null, code: null,
token: null, token: null,
authCodeTimestamp: 0, // 用于存储免登码的时间戳
authCodeExpiration: 5 * 60 * 1000, // 免登码有效期(假设为5分钟)
}; };
}, },
created() {
// 钉钉code码,正式时打开
// this.getCode()
// token,测试用
this.csToken()
},
methods: { methods: {
getAuthCode() { // 获取code
// 检查是否有有效的免登码 getCode() {
const currentTime = Date.now();
console.log(currentTime);
if (this.code && currentTime - this.authCodeTimestamp < this.authCodeExpiration) {
// 使用存储的免登码
console.log('使用缓存的免登码', this.code);
this.loginWithAuthCode(this.code);
return;
}
// 获取新的免登码
dd.getAuthCode({ dd.getAuthCode({
corpId: 'dingaa3937ff8b7dd267f2c783f7214b6d69', corpId: 'dingaa3937ff8b7dd267f2c783f7214b6d69',
success: (res) => { success: (res) => {
console.log('获取新的免登码成功', res); console.log('获取新的免登码成功', res);
const { code } = res; const code = res.code
// 存储新的免登码和时间戳 // this.code = code;
this.code = code; // this.authCodeTimestamp = currentTime;
this.authCodeTimestamp = currentTime; // console.log('this.authCodeTimestamp', this.authCodeTimestamp);
console.log('code', code);
this.getToken(code)
// console.log('loginResponse', loginResponse);
}, },
fail: (res) => { fail: (res) => {
console.log('获取免登码失败', res); console.log('获取免登码失败', res);
...@@ -46,25 +46,51 @@ export default { ...@@ -46,25 +46,51 @@ export default {
complete: () => { }, complete: () => { },
}); });
}, },
async loginWithAuthCode(code) { // 获取token
console.log('code', code); getToken(code) {
try { getCode(code).then(res => {
// 向后端发送请求,使用免登码进行登录 console.log('res', res.token);
const loginResponse = await getCode({ code }); if (res.token) {
console.log('code', code); setToken(res.token)
console.log('跳转页面'); this.$store.commit('SET_TOKEN', res.token)
// 处理登录成功的情况,可能需要保存用户信息或者跳转到其他页面 // this.$router.push({ path: '/index' });
console.log('用户登录成功', loginResponse); // 判断当前用户是否已拉取完user_info信息
const { token } = loginResponse.data; // 假设返回的数据中包含 token 字段 this.$store.dispatch('GetInfo').then((res) => {
console.log('用户 Token:', token); // 打印返回的 Token this.$store.dispatch('GenerateRoutes').then(accessRoutes => {
this.$router.push({ path: "/index" }) // 根据roles权限生成可访问的路由表
router.addRoutes(accessRoutes) // 动态添加可访问路由表
// this.init()
})
})
} else {
this.$message.error(res.message)
}
} })
catch (error) { },
// 处理登录失败的情况 // 测试token
// console.error('登录失败', error); csToken() {
} getCode(123).then(res => {
} console.log('res', res.token);
if (res.token) {
setToken(res.token)
this.$store.commit('SET_TOKEN', res.token)
this.$router.push({ path: '/index' });
// 判断当前用户是否已拉取完user_info信息
this.$store.dispatch('GetInfo').then((res) => {
this.$store.dispatch('GenerateRoutes').then(accessRoutes => {
// 根据roles权限生成可访问的路由表
router.addRoutes(accessRoutes) // 动态添加可访问路由表
this.init()
})
})
} else {
this.$message.error(res.message)
}
})
},
}, },
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment