使用原始流,登录功能修改
This commit is contained in:
parent
fa50b581e0
commit
d3296797ce
|
|
@ -10,7 +10,7 @@ export const GetRedisInfoService = (Data) => {
|
|||
let request1 = getRequest();
|
||||
return request1.post('/tool/get_redis', params,{
|
||||
headers: {
|
||||
'token': Data.token, // 闁诲繐楠忛幏锟<EFBFBD> token 闂佸搫娲︾€笛冪暦閸欏鈻旈柣鎴灻禍鍫曟煟閵娿儱顏ч柟韬插€濋幃褏浠︾憴锝呬壕闁跨噦鎷<E599A6>
|
||||
'token': Data.token, // 闂佽绻愭蹇涘箯閿燂拷 token 闂備礁鎼ú锔锯偓绗涘啰鏆﹂柛娆忣槺閳绘棃鏌i幋鐏活亝绂嶉崼鏇熺厽闁靛ǹ鍎遍褔鏌熼煬鎻掆偓婵嬪箖瑜忔禒锔炬喆閿濆懍澹曢梺璺ㄥ櫐閹凤拷
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ function getRequest() {
|
|||
|
||||
export const UploadFileService = (formData,token) => {
|
||||
//let request1 = getRequest();
|
||||
return request2.post('/tool/upload', formData,{
|
||||
return request.post('/tool/upload', formData,{
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
'token': token,
|
||||
|
|
@ -41,7 +41,7 @@ export const GetFileInfoByMd5Service = (Data) => {
|
|||
params.append(key, Data[key])
|
||||
}
|
||||
//let request1 = getRequest();
|
||||
return request2.post('/tool/file_list', params,{
|
||||
return request.post('/tool/file_list', params,{
|
||||
headers: {
|
||||
'token': Data.token,
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 6.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 69 KiB |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 144.08 128.61"><title>资源 82</title><path d="M72.23 128.61c-7.1-.23-11.51-3.72-14.76-9.36C48 102.87 38.43 86.59 29.1 70.16a36 36 0 0 1-4.47-11.35A14.61 14.61 0 0 1 34 42.51c7.49-2.71 15.71-.21 19.67 6.43 7.52 12.56 14.77 25.27 22.12 37.92 3 5.17 5.89 10.43 9 15.51 5 8 3.45 18-4.22 23.31-2.3 1.62-5.52 1.99-8.34 2.93z" fill="#2ef2e9"/><path d="M72.66.33c6-.57 10.39 2.6 13.51 8C95.61 24.69 105 41.1 114.52 57.4c3.9 6.65-.28 17.13-6.39 20.44-8.93 4.83-17.88 1.28-21.86-5.62C76.82 55.86 67.14 39.62 58.11 23 52.06 12 59.61.24 72.66.33z" fill="#fa6663"/><path d="M144.08 15.83c-.58 8.62-6.73 15.57-15.51 15.66-9.31.09-16.87-7-16.95-15.62S119 0 127.87 0c9.13.09 16.22 7 16.21 15.83z" fill="#fbb355"/><path d="M16.24 31.5C7 31.33-.19 24.42 0 15.8.19 7.5 7.19-.06 14.64 0c10.53.08 18.27 6.73 17.61 15.9-.64 8.96-6.25 15.28-16.01 15.6z" fill="#8a56c2"/></svg>
|
||||
|
After Width: | Height: | Size: 918 B |
Binary file not shown.
|
After Width: | Height: | Size: 37 KiB |
|
|
@ -27,7 +27,7 @@ export default {
|
|||
methods: {
|
||||
initWebSocket() {
|
||||
let socketUrl =
|
||||
"wss://vps.ljsea.top/tool/video_real_time?device_id=" + //wss://gep.ljsea.top/device/get_real_time_image?device_id=
|
||||
"wss://gep.ljsea.top/device/get_real_time_image?device_id=" + //wss://gep.ljsea.top/device/get_real_time_image?device_id= wss://vps.ljsea.top/tool/video_real_time?device_id=
|
||||
this.device_id +
|
||||
"&token=" +
|
||||
this.tokenData.token;
|
||||
|
|
|
|||
|
|
@ -1,376 +1,211 @@
|
|||
<template>
|
||||
<el-row class="loginPage">
|
||||
<!-- element-plus login form -->
|
||||
<el-form
|
||||
ref="form"
|
||||
size="large"
|
||||
autocomplete="false"
|
||||
:model="loginData"
|
||||
:rules="rules"
|
||||
v-if="isLogin === true"
|
||||
>
|
||||
<el-form-item>
|
||||
<h1>登录</h1>
|
||||
</el-form-item>
|
||||
<el-form-item prop="username">
|
||||
<el-input
|
||||
placeholder="请输入用户名或邮箱"
|
||||
v-model="loginData.username"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input
|
||||
placeholder="请输入密码"
|
||||
type="password"
|
||||
v-model="loginData.password"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
class="button"
|
||||
type="primary"
|
||||
auto-insert-space
|
||||
@click="login"
|
||||
>登录</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item class="flex">
|
||||
<el-link @click="isLogin = false"> 注册 </el-link>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- element-plus register form -->
|
||||
<el-form
|
||||
ref="form"
|
||||
size="large"
|
||||
autocomplete="false"
|
||||
:model="registerData"
|
||||
:rules="rules"
|
||||
v-if="isLogin === false"
|
||||
>
|
||||
<el-form-item>
|
||||
<h1>注册</h1>
|
||||
</el-form-item>
|
||||
<el-form-item prop="username">
|
||||
<el-input
|
||||
placeholder="请输入用户名"
|
||||
v-model="registerData.username"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="email">
|
||||
<el-input
|
||||
placeholder="请输入邮箱"
|
||||
v-model="registerData.email"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input
|
||||
placeholder="请输入密码"
|
||||
type="password"
|
||||
v-model="registerData.password"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input
|
||||
placeholder="请再次输入密码"
|
||||
type="password"
|
||||
v-model="registerData.repassword"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onRegister" auto-insert-space
|
||||
>注册</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item class="flex">
|
||||
<el-link @click="isLogin = true"> 返回 </el-link>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
<div>
|
||||
<div>二维码状态: {{ qr_status }}</div>
|
||||
<canvas ref="qrCodeCanvas"></canvas>
|
||||
<div class="login-bg">
|
||||
<div class="login-container">
|
||||
<div class="login-header">
|
||||
<img class="logo mr10" src="../assets/img/logo.svg" alt="" />
|
||||
<div class="login-title">综合系统</div>
|
||||
</div>
|
||||
<el-form :model="param" :rules="rules" ref="login" size="large">
|
||||
<el-form-item prop="username">
|
||||
<el-input v-model="param.username" placeholder="用户名或邮箱">
|
||||
<template #prepend>
|
||||
<el-icon>
|
||||
<User />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input
|
||||
type="password"
|
||||
placeholder="密码"
|
||||
v-model="param.password"
|
||||
@keyup.enter="submitForm(login)"
|
||||
>
|
||||
<template #prepend>
|
||||
<el-icon>
|
||||
<Lock />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<!-- <div class="pwd-tips">
|
||||
<el-checkbox class="pwd-checkbox" v-model="checked" label="记住密码" />
|
||||
<el-link type="primary" @click="$router.push('/reset-pwd')">忘记密码</el-link>
|
||||
</div> -->
|
||||
<el-button class="login-btn" type="primary" size="large" @click="onLogin">登录</el-button>
|
||||
<!-- <p class="login-text">
|
||||
没有账号?<el-link type="primary" @click="$router.push('/register')">立即注册</el-link>
|
||||
</p> -->
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, inject, onUnmounted } from "vue";
|
||||
import axios from "axios";
|
||||
import {
|
||||
getQRService,
|
||||
getUUIDService,
|
||||
loginService,
|
||||
registerService,
|
||||
} from "@/api/user.js";
|
||||
import { ref, reactive,inject } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import {loginService} from "@/api/user.js";
|
||||
import {GetUserInfoService} from "@/api/user.js";
|
||||
import router from "@/router/index.js";
|
||||
import VueQr from "vue-qr"; // 确保你已经注册了这个组件
|
||||
import { ElMessage } from "element-plus";
|
||||
import QRCode from "qrcode";
|
||||
|
||||
const isLogin = ref(true);
|
||||
const qrCodeCanvas = ref(null);
|
||||
|
||||
// 从本地存储获取登录参数
|
||||
const lgStr = localStorage.getItem('login-param');
|
||||
const defParam = lgStr ? JSON.parse(lgStr) : null;
|
||||
const globalData = inject("globalData");
|
||||
// 记住密码状态
|
||||
const checked = ref(lgStr ? true : false);
|
||||
|
||||
// 创建一个响应式引用来存储定时器ID
|
||||
const intervalId = ref(null);
|
||||
var uuid = "";
|
||||
const router = useRouter();
|
||||
// 登录表单数据
|
||||
const param = reactive({
|
||||
username: defParam ? defParam.username : '',
|
||||
password: defParam ? defParam.password : ''
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const rules = {
|
||||
username: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入用户名',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入密码',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
};
|
||||
// 表单引用
|
||||
const login = ref(null);
|
||||
|
||||
const qr_status = ref("未被扫描");
|
||||
//表单数据
|
||||
var loginData = ref({
|
||||
username: "",
|
||||
email: "",
|
||||
password: "",
|
||||
ip: "",
|
||||
username: "",
|
||||
email: "",
|
||||
password: "",
|
||||
ip: "",
|
||||
});
|
||||
|
||||
const registerData = ref({
|
||||
username: "",
|
||||
email: "",
|
||||
password: "",
|
||||
repassword: "",
|
||||
});
|
||||
|
||||
//表单校验规则
|
||||
const rules = {
|
||||
password: [
|
||||
{ required: true, message: "请输入密码", trigger: "blur" },
|
||||
{
|
||||
min: 6,
|
||||
max: 20,
|
||||
message: "密码长度在 6 到 20 个字符",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
username: [
|
||||
{ required: true, message: "请输入用户名", trigger: "blur" },
|
||||
{
|
||||
min: 5,
|
||||
max: 20,
|
||||
message: "用户名长度在 6 到 20 个字符",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
email: [{}],
|
||||
};
|
||||
onMounted(() => {
|
||||
init();
|
||||
startInterval();
|
||||
const token = localStorage.getItem("token");
|
||||
if (token !== null) {
|
||||
isLogin.value = true; // 更新登录状态
|
||||
router.push("/videoList"); // 跳转到视频列表页面
|
||||
// 你可以在这里获取 UID 并更新 uid.value
|
||||
}
|
||||
});
|
||||
onUnmounted(() => {
|
||||
stopInterval();
|
||||
});
|
||||
|
||||
// 开启定时器
|
||||
const startInterval = () => {
|
||||
if (intervalId.value) {
|
||||
// 如果定时器已经开启,则不执行任何操作
|
||||
return;
|
||||
}
|
||||
intervalId.value = setInterval(getQRStatus, 2000);
|
||||
};
|
||||
|
||||
// 关闭定时器
|
||||
const stopInterval = () => {
|
||||
if (intervalId.value) {
|
||||
clearInterval(intervalId.value);
|
||||
intervalId.value = null; // 清除引用中的定时器ID
|
||||
}
|
||||
};
|
||||
|
||||
const creatQrCode = async () => {
|
||||
console.log("creatQrCode:", uuid);
|
||||
var qrcode = new qrcode(this.$refs.qrCodeUrl, {
|
||||
text: uuid, // 需要转换为二维码的内容
|
||||
width: 100,
|
||||
height: 100,
|
||||
colorDark: "#000000",
|
||||
colorLight: "#ffffff",
|
||||
correctLevel: QRCode.CorrectLevel.H,
|
||||
});
|
||||
};
|
||||
|
||||
//登录接口调用
|
||||
const login = async () => {
|
||||
let result = await loginService(loginData);
|
||||
if (result.data == null) {
|
||||
//alert(result.message);
|
||||
ElMessage.error("登录失败!用户名或密码错误");
|
||||
}
|
||||
globalData.token = result.data;
|
||||
localStorage.setItem("token", result.data.token);
|
||||
localStorage.setItem("userId", result.data.id);
|
||||
localStorage.setItem("username", result.data.username);
|
||||
let now = new Date();
|
||||
localStorage.setItem("end_time", now.setDate(now.getHours() + 12)); //过期时间
|
||||
await getMyUserInfo(result.data.id);
|
||||
//token.value= result.data;
|
||||
router.push("/user");
|
||||
const onLogin = async () => {
|
||||
console.log("params:",param)
|
||||
|
||||
loginData.value.username = param.username;
|
||||
loginData.value.password = param.password;
|
||||
let result = await loginService(loginData);
|
||||
console.log("login result:", result);
|
||||
if (result.code !== 0) {
|
||||
//alert(result.message);
|
||||
ElMessage.error("登录失败!用户名或密码错误");
|
||||
return
|
||||
}
|
||||
globalData.token = result.data;
|
||||
localStorage.setItem("token", result.data.token);
|
||||
localStorage.setItem("userId", result.data.id);
|
||||
localStorage.setItem("username", result.data.username);
|
||||
let now = new Date();
|
||||
localStorage.setItem("end_time", now.setDate(now.getHours() + 12)); //过期时间
|
||||
await getMyUserInfo(result.data.id);
|
||||
//token.value= result.data;
|
||||
router.push("/user");
|
||||
};
|
||||
|
||||
//注册接口调用
|
||||
const onRegister = async () => {
|
||||
//校验密码是否一致
|
||||
if (registerData.value.password !== registerData.value.repassword) {
|
||||
//alert("两次密码不一致");
|
||||
ElMessage.error("两次密码不一致");
|
||||
return;
|
||||
}
|
||||
//校验邮箱是否合法
|
||||
let email = registerData.value.email;
|
||||
let reg = /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/;
|
||||
if (!reg.test(email)) {
|
||||
//alert("邮箱格式不正确");
|
||||
ElMessage.error("邮箱格式不正确");
|
||||
return;
|
||||
}
|
||||
|
||||
let result = await registerService(registerData);
|
||||
if (result !== null) {
|
||||
globalData.token = result.data;
|
||||
localStorage.setItem("token", result.data.token);
|
||||
localStorage.setItem("userId", result.data.id);
|
||||
localStorage.setItem("username", result.data.username);
|
||||
let now = new Date();
|
||||
localStorage.setItem("end_time", now.setDate(now.getHours() + 12)); //过期时间
|
||||
//token.value= result.data;
|
||||
await getMyUserInfo(result.data.id);
|
||||
router.push("/user");
|
||||
}
|
||||
};
|
||||
|
||||
const generateQRCode = () => {
|
||||
// 假设我们有一个数据字符串要转换为二维码
|
||||
const data = uuid;
|
||||
// 确保 canvas 已经被渲染到 DOM 中
|
||||
if (qrCodeCanvas.value) {
|
||||
const canvas = qrCodeCanvas.value;
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
// 设置 canvas 的大小
|
||||
canvas.width = 256;
|
||||
canvas.height = 256;
|
||||
|
||||
// 使用 qrcode 库生成二维码
|
||||
QRCode.toCanvas(
|
||||
canvas,
|
||||
data,
|
||||
{
|
||||
width: 256,
|
||||
height: 256,
|
||||
color: {
|
||||
dark: "#000000",
|
||||
light: "#ffffff",
|
||||
},
|
||||
},
|
||||
function (error) {
|
||||
if (error) console.error(error);
|
||||
console.log("二维码已生成");
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const getUUID = async () => {
|
||||
try {
|
||||
const response = await getUUIDService({
|
||||
device: "windows",
|
||||
address: localStorage.getItem("address"),
|
||||
ip: localStorage.getItem("ip"),
|
||||
});
|
||||
uuid = response.data.toString();
|
||||
let uid = uuid.toString();
|
||||
//await creatQrCode(uid);
|
||||
generateQRCode(uuid);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
const getQRStatus = async () => {
|
||||
let result = await getQRService({ uuid: uuid });
|
||||
if (result.code === 0) {
|
||||
if (result.data === "0") {
|
||||
} else if (result.data === "1") {
|
||||
qr_status.value = "等待确认";
|
||||
} else {
|
||||
globalData.token = result.data;
|
||||
localStorage.setItem("token", result.data.token);
|
||||
localStorage.setItem("userId", result.data.id);
|
||||
localStorage.setItem("username", result.data.username);
|
||||
let now = new Date();
|
||||
localStorage.setItem("end_time", now.setDate(now.getHours() + 12)); //过期时间
|
||||
//token.value= result.data;
|
||||
router.push("/user");
|
||||
}
|
||||
} else {
|
||||
//alert(result.message);
|
||||
ElMessage.error(result.message);
|
||||
}
|
||||
};
|
||||
|
||||
const getIpClient = async () => {
|
||||
try {
|
||||
const response = await axios.get("https://ip.zxinc.org/api.php?type=json");
|
||||
loginData.value.ip = response.data.data.myip;
|
||||
localStorage.setItem("ip", response.data.data.myip);
|
||||
localStorage.setItem("city", response.data.data.country);
|
||||
localStorage.setItem("address", response.data.data.location);
|
||||
// console.log("ip:",response.data.ip);
|
||||
// console.log("login ip:",loginData.ip);
|
||||
// console.log(response.data);
|
||||
// console.log(loginData);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
const getMyUserInfo = async (id) => {
|
||||
let result = {};
|
||||
try {
|
||||
let tokenData ={
|
||||
token: localStorage.getItem("token"),
|
||||
id: id,
|
||||
}
|
||||
result = await GetUserInfoService(tokenData);
|
||||
if (result.code === 0) {
|
||||
//console.log("token data:",this.tokenData)
|
||||
localStorage.setItem("video_func", result.data.VideoFunc);
|
||||
localStorage.setItem("device_func", result.data.DeviceFunc);
|
||||
localStorage.setItem("cid_func", result.data.CIDFunc);
|
||||
localStorage.setItem("role", result.data.Role);
|
||||
|
||||
//alert("video_func:" + localStorage.getItem("video_func")+" type:" +typeof(localStorage.getItem("video_func")));
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
let result = {};
|
||||
try {
|
||||
let tokenData ={
|
||||
token: localStorage.getItem("token"),
|
||||
id: id,
|
||||
}
|
||||
};
|
||||
|
||||
const init = async () => {
|
||||
getIpClient();
|
||||
await getUUID();
|
||||
};
|
||||
const register = async () => {
|
||||
let result = registerService(registerData.value);
|
||||
result = await GetUserInfoService(tokenData);
|
||||
if (result.code === 0) {
|
||||
//alert(result.message);
|
||||
ElMessage.success(result.message);
|
||||
} else {
|
||||
//alert(result.message);
|
||||
ElMessage.error(result.message);
|
||||
//console.log("token data:",this.tokenData)
|
||||
localStorage.setItem("video_func", result.data.VideoFunc);
|
||||
localStorage.setItem("device_func", result.data.DeviceFunc);
|
||||
localStorage.setItem("cid_func", result.data.CIDFunc);
|
||||
localStorage.setItem("role", result.data.Role);
|
||||
|
||||
//alert("video_func:" + localStorage.getItem("video_func")+" type:" +typeof(localStorage.getItem("video_func")));
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
canvas {
|
||||
border: 1px solid #000;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
</style>
|
||||
};
|
||||
|
||||
// 获取标签存储并清空标签
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.login-bg {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
/* background: url(../assets/img/login-bg.jpg) center/cover no-repeat; */
|
||||
}
|
||||
|
||||
.login-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 35px;
|
||||
}
|
||||
|
||||
.login-title {
|
||||
font-size: 22px;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.login-container {
|
||||
width: 450px;
|
||||
border-radius: 5px;
|
||||
background: #fff;
|
||||
padding: 40px 50px 50px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.pwd-tips {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
margin: -10px 0 10px;
|
||||
color: #787878;
|
||||
}
|
||||
|
||||
.pwd-checkbox {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.login-tips {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.login-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 20px;
|
||||
font-size: 14px;
|
||||
color: #787878;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -265,7 +265,7 @@ export default {
|
|||
let resp_data = result.data;
|
||||
|
||||
//console.log("resp:",resp_data);
|
||||
let url = "https://gep.ljsea.top/tool/file/"+resp_data.FileStoreName;
|
||||
let url = "https://tx.ljsea.top/tool/file/"+resp_data.FileStoreName;
|
||||
|
||||
this.UserUpdateForm.avatar = url;
|
||||
//更新用户信息
|
||||
|
|
|
|||
Loading…
Reference in New Issue