配合前后端

This commit is contained in:
橙子
2021-10-13 16:44:15 +08:00
parent e9bc71393c
commit 86ab52df57
22 changed files with 1319 additions and 6 deletions

View File

@@ -0,0 +1,90 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Yi.Framework.Common;
using Yi.Framework.Common.Models;
using Yi.Framework.Interface;
using Yi.Framework.Model.Models;
namespace Yi.Framework.ApiMicroservice.Controllers
{
[ApiController]
[Route("api/[controller]/[action]")]
public class AccountController : Controller
{
private readonly ILogger<UserController> _logger;
private IUserService _userService;
public AccountController(ILogger<UserController> logger, IUserService userService)
{
_logger = logger;
_userService = userService;
}
/// <summary>
/// 登录方法要返回data:{user,token} token先写123456789,不要有导航属性
/// </summary>
/// <param name="_user"></param>
/// <returns></returns>
[HttpPost]
public async Task<Result> Login(user _user)
{
}
/// <summary>
/// 不用写,单纯制作日志
/// </summary>
/// <returns></returns>
[HttpPost]
public Result Logout()
{
return Result.Success();
}
/// <summary>
/// code为验证码,判断一下,假装验证码都是对的
/// </summary>
/// <param name="_user"></param>
/// <param name="code"></param>
/// <returns></returns>
[HttpPost]
public async Task<Result> Register(user _user, string code)
{
}
/// <summary>
/// 传入邮箱需要先到数据库判断该邮箱是否被人注册过到userservice写mail_exist方法还有接口别忘了。这个接口不需要洞只需要完成userservice写mail_exist与接口即可
/// </summary>
/// <param name="emailAddress"></param>
/// <returns></returns>
[HttpPost]//邮箱验证
public async Task<Result> Email(string emailAddress)
{
emailAddress = emailAddress.Trim().ToLower();
//先判断邮箱是否被注册使用过,如果被使用过,便不让操作
if (!await _userService.mail_exist(emailAddress))
{
string code = RandomHelper.GenerateRandomLetter(6);
code = code.ToUpper();//全部转为大写
EmailHelper.sendMail(code, emailAddress);
//我要把邮箱和对应的code加进到数据库还有申请时间
//设置10分钟过期
//set不存在便添加如果存在便替换
//CacheHelper.SetCache<string>(emailAddress, code, TimeSpan.FromSeconds(10));
return Result.Success("发送邮件成功,请查看邮箱(可能在垃圾箱)");
}
else
{
return Result.Error("该邮箱已被注册");
}
// 邮箱和验证码都要被记住,然后注册时候比对邮箱和验证码是不是都和现在生成的一样
}
}
}

View File

@@ -7,6 +7,7 @@ using System.Threading.Tasks;
using Yi.Framework.Common.Models;
using Yi.Framework.Interface;
using Yi.Framework.Model.Models;
using Yi.Framework.WebCore;
namespace Yi.Framework.ApiMicroservice.Controllers
{
@@ -69,5 +70,15 @@ namespace Yi.Framework.ApiMicroservice.Controllers
await _userService.AddAsync(_user);
return Result.Success();
}
/// <summary>
/// 通过上下文对象获取user注意_user下只有userId返回值为该用户下所有的menu(注意子类递归)并且需要关联mould
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<Result> GetMenuMould()
{
var _user= this.HttpContext.GetCurrentUserInfo();
}
}
}

View File

@@ -0,0 +1,125 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Mail;
using System.Net.Sockets;
using System.Text;
namespace Yi.Framework.Common
{
public class EmailHelper
{
public static string fromMail { get; set; }
public static string pwdMail { get; set; }
public static string senderMail { get; set; }
public static string subjectMail { get; set; }
public static void Init(string fromMail,string pwdMail,string senderMail, string subjectMail)
{
EmailHelper.fromMail = fromMail;
EmailHelper.pwdMail = pwdMail;
EmailHelper.senderMail = senderMail;
EmailHelper.subjectMail = subjectMail;
}
public static bool sendMail(string body, string toMail)
{
try
{
//string fromMail = "454313500@qq.com";
//string pwdMail = "yvjioburildgbhdf";
MailMessage message = new MailMessage();
//设置发件人,发件人需要与设置的邮件发送服务器的邮箱一致
System.Net.Mail.MailAddress fromAddr = new System.Net.Mail.MailAddress(fromMail, EmailHelper.senderMail);
message.From = fromAddr;
//设置收件人,可添加多个,添加方法与下面的一样
message.To.Add(toMail);
//设置邮件标题
message.Subject = EmailHelper.subjectMail;
//设置邮件内容
message.Body = body;
//设置邮件发送服务器,服务器根据你使用的邮箱而不同,可以到相应的 邮箱管理后台查看,下面是QQ的
System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient("smtp.qq.com", 25)
;
//设置发送人的邮箱账号和密码POP3/SMTP服务要开启, 密码要是POP3/SMTP等服务的授权码
client.Credentials = new System.Net.NetworkCredential(fromMail, pwdMail);//vtirsfsthwuadjfe fhszmpegwoqnecja
//启用ssl,也就是安全发送
client.EnableSsl = true;
//发送邮件
client.Send(message);
return true;
}
catch
{
return false;
}
}
public static void ()
{
using (TcpClient client = new TcpClient("pop.qq.com", 110))
using (NetworkStream n = client.GetStream())
{
GetEmail.ReadLine(n); // Read the welcome message.
GetEmail.SendCommand(n, "USER 1040079213@qq.com");
GetEmail.SendCommand(n, "PASS odfaizoqdiupbfgi");
GetEmail.SendCommand(n, "LIST"); // Retrieve message IDs
List<int> messageIDs = new List<int>();
while (true)
{
string line = GetEmail.ReadLine(n); // e.g., "11876"
if (line == ".") break;
messageIDs.Add(int.Parse(line.Split(' ')[0])); // Message ID
}
foreach (int id in messageIDs) // Retrieve each message.
{
GetEmail.SendCommand(n, "RETR " + id);
string randomFile = Guid.NewGuid().ToString() + ".eml";
using (StreamWriter writer = File.CreateText(randomFile))
while (true)
{
string line = GetEmail.ReadLine(n); // Read next line of message.
if (line == ".") break; // Single dot = end of message.
if (line == "..") line = "."; // "Escape out" double dot.
writer.WriteLine(line); // Write to output file.
}
GetEmail.SendCommand(n, "DELE " + id); // Delete message off server.
}
GetEmail.SendCommand(n, "QUIT");
}
}
}
//接受邮件pop
public class GetEmail
{
public static void SendCommand(Stream stream, string line)
{
byte[] data = Encoding.UTF8.GetBytes(line + "\r\n");
stream.Write(data, 0, data.Length);
string response = ReadLine(stream);
if (!response.StartsWith("+OK"))
throw new Exception("POP Error: " + response);
}
public static string ReadLine(Stream s)
{
List<byte> lineBuffer = new List<byte>();
while (true)
{
int b = s.ReadByte();
if (b == 10 || b < 0) break;
if (b != 13) lineBuffer.Add((byte)b);
}
return Encoding.UTF8.GetString(lineBuffer.ToArray());
}
}
}

View File

@@ -0,0 +1,99 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace Yi.Framework.Common
{
public class RandomHelper
{
public static string replaceBianLiang(string content)
{
content = content.Replace("{当前时间}", DateTime.Now.TimeOfDay.ToString());
string[] bianliang = new string[] { "{随机字母}", "{随机数字}", "{随机汉字}" };
Regex r;
int count;
string readstr = "";
foreach (string str in bianliang)
{
count = (content.Length - content.Replace(str, "").Length) / str.Length;
if (str == "{随机汉字}") readstr = RandChina(count);
if (str == "{随机数字}") readstr = GenerateCheckCodeNum(count);
if (str == "{随机字母}") readstr = GenerateRandomLetter(count);
if (count > readstr.Length) count = readstr.Length;
r = new Regex(str.Replace("{", "\\{").Replace("}", "\\}"));
for (int i = 0; i < count; i++)
{
content = r.Replace(content, readstr.Substring(i, 1), 1);
}
}
return content;
}
/// <summary>
/// 随机生成字母
/// </summary>
/// <param name="Length"></param>
/// <returns></returns>
public static string GenerateRandomLetter(int Length)
{
char[] Pattern = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
string result = "";
int n = Pattern.Length;
Random random = new Random(~unchecked((int)DateTime.Now.Ticks));
for (int i = 0; i < Length; i++)
{
int rnd = random.Next(0, n);
result += Pattern[rnd];
}
return result;
}
/// <summary>
/// 随机生成数字
/// </summary>
/// <param name="codeCount"></param>
/// <returns></returns>
public static string GenerateCheckCodeNum(int codeCount)
{
int rep = 0;
string str = string.Empty;
long num2 = DateTime.Now.Ticks + rep;
rep++;
Random random = new Random(((int)(((ulong)num2) & 0xffffffffL)) | ((int)(num2 >> rep)));
for (int i = 0; i < codeCount; i++)
{
int num = random.Next();
str = str + ((char)(0x30 + ((ushort)(num % 10)))).ToString();
}
return str;
}
/// <summary>
/// 此函数为生成指定数目的汉字
/// </summary>
/// <param name="charLen">汉字数目</param>
/// <returns>所有汉字</returns>
public static string RandChina(int charLen)
{
int area, code;//汉字由区位和码位组成(都为0-94,其中区位16-55为一级汉字区,56-87为二级汉字区,1-9为特殊字符区)
StringBuilder strtem = new StringBuilder();
Random rand = new Random();
for (int i = 0; i < charLen; i++)
{
area = rand.Next(16, 88);
if (area == 55)//第55区只有89个字符
{
code = rand.Next(1, 90);
}
else
{
code = rand.Next(1, 94);
}
strtem.Append(Encoding.GetEncoding("GB2312").GetString(new byte[] { Convert.ToByte(area + 160), Convert.ToByte(code + 160) }));
}
return strtem.ToString();
}
}
}

View File

@@ -9026,6 +9026,11 @@
"resolved": "https://registry.npmmirror.com/vuetify/download/vuetify-2.5.9.tgz",
"integrity": "sha1-tubZ//ShaRhY80FezrKnXKcG0hE="
},
"vuetify-dialog": {
"version": "2.0.17",
"resolved": "https://registry.nlark.com/vuetify-dialog/download/vuetify-dialog-2.0.17.tgz",
"integrity": "sha1-vhmMGHkymnPXiRcIDqWX0BaSdz0="
},
"vuetify-loader": {
"version": "1.7.3",
"resolved": "https://registry.nlark.com/vuetify-loader/download/vuetify-loader-1.7.3.tgz?cache=0&sync_timestamp=1631946975383&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fvuetify-loader%2Fdownload%2Fvuetify-loader-1.7.3.tgz",
@@ -9080,6 +9085,11 @@
}
}
},
"vuex": {
"version": "3.6.2",
"resolved": "https://registry.nlark.com/vuex/download/vuex-3.6.2.tgz",
"integrity": "sha1-I2vAhqhww655lG8QfxbeWdWJXnE="
},
"watchpack": {
"version": "1.7.5",
"resolved": "https://registry.nlark.com/watchpack/download/watchpack-1.7.5.tgz",

View File

@@ -11,7 +11,9 @@
"vue": "^2.6.11",
"vue-chartist": "^2.3.1",
"vue-router": "^3.2.0",
"vuetify": "^2.4.0"
"vuetify": "^2.4.0",
"vuetify-dialog": "^2.0.17",
"vuex": "^3.6.2"
},
"devDependencies": {
"@vue/cli-plugin-router": "~4.5.0",

View File

@@ -0,0 +1,39 @@
import myaxios from '@/util/myaxios'
export default {
login(username, password) {
return myaxios({
url: '/Account/login',
method: 'post',
data: {
username,
password
}
})
},
logout() {
return myaxios({
url: '/Account/logout',
method: 'post',
})
},
logged() {
return myaxios({
url: '/Account/logged',
method: 'post',
})
},
register(username, password, email, code) {
return myaxios({
url: `/Account/register?code=${code}`,
method: 'post',
data: { username, password, email }
})
},
email(emailAddress) {
return myaxios({
url: `/Account/email?emailAddress=${emailAddress}`,
method: 'post',
})
}
}

View File

@@ -0,0 +1,30 @@
import myaxios from '@/util/myaxios'
export default {
getActions() {
return myaxios({
url: '/Action/getActions',
method: 'get'
})
},
addAction(action) {
return myaxios({
url: '/action/addAction',
method: 'post',
data: action
})
},
updateAction(action) {
return myaxios({
url: '/action/UpdateAction',
method: 'post',
data: action
})
},
delActionList(Ids) {
return myaxios({
url: '/action/DelAllAction',
method: 'post',
data: Ids
})
},
}

16
Yi.Vue/src/api/fileApi.js Normal file
View File

@@ -0,0 +1,16 @@
import myaxios from '@/util/myaxios'
export default {
OnPostUploadImage(file) {
return myaxios({
url: '/File/OnPostUploadImage',
method: 'post',
data: file
})
},
getLogs() {
return myaxios({
url: '/File/GetLogs',
method: 'get'
})
}
}

50
Yi.Vue/src/api/roleApi.js Normal file
View File

@@ -0,0 +1,50 @@
import myaxios from '@/util/myaxios'
export default {
getRoles() {
return myaxios({
url: '/Role/getRoles',
method: 'get'
})
},
AddRole(role) {
return myaxios({
url: '/Role/AddRole',
method: 'post',
data: role
})
},
delRole(roleId) {
return myaxios({
url: `/Role/DelRole?roleId=${roleId}`,
method: 'get'
})
},
updateRole(role) {
return myaxios({
url: '/role/updateRole',
method: 'post',
data: role
})
},
delRoleList(Ids) {
return myaxios({
url: '/role/delAllRole',
method: 'post',
data: Ids
})
},
setAction(Id, Ids) {
return myaxios({
url: '/role/setAction',
method: 'post',
data: { "Id": Id, "Ids": Ids }
})
},
GetActionByRoleId(roleId) {
return myaxios({
url: `/role/GetActionByRoleId?roleId=${roleId}`,
method: 'get'
})
}
}

101
Yi.Vue/src/api/userApi.js Normal file
View File

@@ -0,0 +1,101 @@
import myaxios from '@/util/myaxios'
export default {
getAllUser() {
return myaxios({
url: '/User/getAllUser',
method: 'get'
})
},
getUserByUserId(userId) {
if (userId == undefined) {
userId = 0;
}
return myaxios({
url: `/User/getUserByUserId?userId=${userId}`,
method: 'get'
})
},
addUser(user) {
return myaxios({
url: '/User/addUser',
method: 'post',
data: user
})
},
delUser(userId) {
return myaxios({
url: `/User/delUser?userId=${userId}`,
method: 'get'
})
},
updateUser(user) {
return myaxios({
url: '/User/updateUser',
method: 'post',
data: user
})
},
tryUpdateUser(form) {
return myaxios({
url: '/User/tryUpdateUser',
method: 'post',
data: form
})
},
delUserList(Ids) {
return myaxios({
url: '/User/delAllUser',
method: 'post',
data: Ids
})
},
setRole(Id, Ids) {
return myaxios({
url: '/User/setRole',
method: 'post',
data: { "Id": Id, "Ids": Ids }
})
},
setRoleList(userIds, roleIds) {
return myaxios({
url: '/User/setRoleList',
method: 'post',
data: { "userIds": userIds, "roleIds": roleIds }
})
},
getRoleByuserId(userId) {
if (userId == undefined) {
userId = 0;
}
return myaxios({
url: `/User/getRoleByuserId?userId=${userId}`,
method: 'get'
})
},
getSpecialAction(userId) {
return myaxios({
url: `/User/getSpecialAction?userId=${userId}`,
method: 'get'
})
},
setSpecialAction(Id, Ids) {
return myaxios({
url: '/User/setSpecialAction',
method: 'post',
data: { "Id": Id, "Ids": Ids }
})
},
getActionByUserId(userId) {
if (userId == undefined) {
userId = 0;
}
return myaxios({
url: `/User/getActionByUserId?userId=${userId}`,
method: 'get'
})
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -0,0 +1,65 @@
<template>
<v-app>
<v-container fluid class="grey lighten-5" v-bind:style="{ height: allDiv }">
<v-row v-bind:style="{ height: allDiv }">
<!-- -------------------------------公告----------------------------------- -->
<v-col
cols="0"
sm="4"
md="3"
class="white d-none d-sm-flex text-center"
>
<div style="width: 100%">
<h1 class="light-blue--text mt-8">{{title}} <br />维基 百科</h1>
<p class="my-4 title">Angstrong</p>
<p class="my-4 title">欢迎在这里我们无所不谈</p>
<a href="https://beian.miit.gov.cn">工信部备案号赣ICP备20008025号-2</a>
<v-img
src="../../assets/login.svg"
contain
v-bind:style="{ marginTop: imgDiv }"
style="width: 100%"
></v-img>
</div>
</v-col>
<!-- -------------------------------------------------------------------------- -->
<!-- ------------------------------表单-------------------------------- -->
<v-col cols="12" sm="8" md="9">
<v-container class="text-center align-center" fluid>
<div class="mt-15">
<router-view></router-view>
</div>
</v-container>
</v-col>
<!-- --------------------------------------------------------------- -->
</v-row>
</v-container>
</v-app>
</template>
<script>
// import settingApi from "@/api/settingApi";
export default {
created() {
this.initialize();
},
methods: {
initialize() {
// settingApi.getTitle().then((resp) => {
// this.title = resp.data;
// });
},
},
data: () => ({
title:"",
allDiv: document.documentElement.clientHeight + "px",
imgDiv: document.documentElement.clientHeight - 540 + "px",
// email: '',
// emailRules: [
// v => !!v || 'E-mail is required',
// v => /.+@.+\..+/.test(v) || 'E-mail must be valid',
// ],
}),
};
</script>

View File

@@ -3,6 +3,8 @@ import App from './App.vue'
import router from './router'
import vuetify from './plugins/vuetify'
import './plugins'
import './store/index'
Vue.config.productionTip = false
new Vue({

View File

@@ -1,5 +1,9 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
import LayoutLogin from '../layouts/login/LayoutLogin.vue'
import login from '../views/login.vue'
import register from '../views/register.vue'
import { trailingSlash } from '@/util/helpers'
import {
layout,
@@ -18,11 +22,29 @@ const router = new VueRouter({
return { x: 0, y: 0 }
},
routes: [layout('Default', [
route('Index'),
route('AdmUser', null, 'AdmUser'),
route('AdmRole', null, 'AdmRole'),
])]
routes: [{
path: '/layoutLogin',
name: 'layoutLogin',
component: LayoutLogin,
redirect: "/login",
children: [{
path: "/login",
name: "login",
component: login
},
{
path: '/register',
name: 'register',
component: register
}
]
},
layout('Default', [
route('Index'),
route('AdmUser', null, 'AdmUser'),
route('AdmRole', null, 'AdmRole'),
])
]
})
router.beforeEach((to, from, next) => {
return to.path.endsWith('/') ? next() : next(trailingSlash(to.path))

18
Yi.Vue/src/store/index.js Normal file
View File

@@ -0,0 +1,18 @@
import Vue from 'vue'
import Vuex from 'vuex'
import home from './modules/home'
import user from './modules/user'
import theme from './modules/theme'
import loader from './modules/loader'
Vue.use(Vuex);
//实例化
const store = new Vuex.Store({
modules: {
home,
user,
theme,
loader
}
})
export default store

View File

@@ -0,0 +1,42 @@
const state = { //状态
plateId: 0,
discussId: 0,
plateString: "",
}
const mutations = { //变化//载荷
SET_PLATEID(state, n) {
state.plateId = n
},
SET_DOSCUSSIDSTRING(state, n) {
state.plateString = n
},
SET_DOSCUSSID(state, n) {
state.discussId = n
},
}
//在action中可以配合axios进行权限判断
const actions = { //动作
set_plateId(context, n) {
context.commit('SET_PLATEID', n)
},
set_plateString(context, n) {
context.commit('SET_DOSCUSSIDSTRING', n)
},
set_discussId(context, n) {
context.commit('SET_DOSCUSSID', n)
}
}
// const getters = { //类似与计算属性 派生属性
// msg(state) {
// if (state.count > 80) {
// return "成绩优异"
// } else {
// return "成绩不合格"
// }
// }
// }
export default { state, mutations, actions }

View File

@@ -0,0 +1,34 @@
const state = { //状态
load: false
}
const mutations = { //变化//载荷
OPEN(state) {
state.load = true;
},
CLOSE(state) {
state.load = false;
},
}
//在action中可以配合axios进行权限判断
const actions = { //动作
openLoad(context) {
context.commit('OPEN')
},
closeLoad(context) {
context.commit('CLOSE')
}
}
// const getters = { //类似与计算属性 派生属性
// msg(state) {
// if (state.count > 80) {
// return "成绩优异"
// } else {
// return "成绩不合格"
// }
// }
// }
export default { state, mutations, actions }

View File

@@ -0,0 +1,33 @@
import vuetify from '../../plugins/vuetify';
const state = { //状态
light: {
primary: '#1976D2',
secondary: '#424242',
accent: '#82B1FF',
error: '#FF5252',
info: '#2196F3',
success: '#4CAF50',
warning: '#FFC107',
cyan: "#FAB2B1",
blue: "#2196F3"
},
dark: {}
}
const mutations = { //变化//载荷
SET_Light(state, n) {
state.light = n
vuetify.framework.theme.themes.light = n
},
}
//在action中可以配合axios进行权限判断
const actions = { //动作
set_light(context, n) {
context.commit('SET_Light', n)
},
}
export default { state, mutations, actions }

View File

@@ -0,0 +1,122 @@
import { getToken, setToken, getUser, setUser, removeToken } from '../../util/usertoken'
import accountApi from "@/api/accountApi"
//再导入axion请求
const state = { //状态
token: getToken(),
user: getUser()
}
const mutations = { //变化//载荷
SET_TOKEN(state, token) {
state.token = token
setToken(token)
},
SET_USER(state, user) {
state.user = user
setUser(user)
}
}
//在action中可以配合axios进行权限判断
const actions = { //动作
setIcon({ commit, state }, icon) {
state.user.icon = icon
commit('SET_USER', state.user)
},
setLevel({ commit, state }, level) {
commit('SET_USER', state.user)
},
// qqUpdate({ state }, openid) {
// return new Promise((resolv, reject) => {
// qqApi.qqupdate(openid, state.user.id).then(resp => {
// resolv(resp)
// }).catch(error => {
// reject(error)
// })
// })
// },
// qqLogin({ commit }, openid) {
// return new Promise((resolv, reject) => {
// qqApi.qqlogin(openid).then(resp => {
// if (resp.status) {
// commit('SET_TOKEN', resp.data.token)
// commit('SET_USER', resp.data.user)
// }
// resolv(resp)
// }).catch(error => {
// reject(error)
// })
// })
// },
Login({ commit }, form) {
return new Promise((resolv, reject) => {
accountApi.login(form.username.trim(), form.password.trim()).then(resp => {
if (resp.status) {
commit('SET_TOKEN', resp.data.token)
commit('SET_USER', resp.data.user)
}
resolv(resp)
}).catch(error => {
reject(error)
})
})
},
Register({ commit }, form) {
return new Promise((resolv, reject) => {
accountApi.register(form.username.trim(), form.password.trim(), form.email.trim(), form.code.trim()).then(resp => {
resolv(resp)
}).catch(error => {
reject(error)
})
})
},
Logged({ commit }) {
return new Promise((resolv, reject) => {
accountApi.logged().then(resp => {
resolv(resp)
}).catch(error => {
reject(error)
})
})
},
// GetUserInfo({ commit, state }) {
// return new Promise((resolv, reject) => {
// // getUserInfo(state.token).then(response => {
// // commit('SET_USER', response.data)
// // resolve(response)
// // }).catch(error=>{
// // reject(error)
// // })
// })
// },
Logout({ commit, state }) {
return new Promise((resolv, reject) => {
accountApi.logout().then(response => {
commit('SET_TOKEN', '')
commit('SET_USER', null)
removeToken()
resolv(response)
}).catch(error => {
reject(error)
})
})
}
}
export default { state, mutations, actions }

163
Yi.Vue/src/views/login.vue Normal file
View File

@@ -0,0 +1,163 @@
<template>
<v-card
class="px-6 py-4 mx-auto elevation-4 rounded-md"
style="height: 600px; width: 500px"
>
<div>
<h1 class="title my-2">Angstrong</h1>
<v-subheader>登入你的用户</v-subheader>
</div>
<v-form ref="form" v-model="valid" lazy-validation>
<v-text-field
v-model="user_name"
:rules="user_nameRules"
label="用户名"
outlined
clearable
required
:counter="20"
></v-text-field>
<v-text-field
v-model="password"
:rules="passwordRules"
label="密码"
outlined
clearable
required
type="password"
></v-text-field>
<v-row>
<v-col cols="6">
<v-checkbox
v-model="checkbox"
:rules="[(v) => !!v || '同意后才可进入']"
label="你同意协议吗?"
required
></v-checkbox
></v-col>
<v-col cols="6" class="text-right pt-8"
><router-link to="/register">前往注册</router-link></v-col
>
</v-row>
</v-form>
<v-btn
class="my-2 light-blue white--text"
@click="login"
large
style="width: 100%"
@keyup.enter="enterSearch"
:loading="loader"
:disabled="btn_dis"
>
登入
</v-btn>
<p class="my-2">或使用登录</p>
<v-btn class="my-2 cyan white--text" @click="qqlogin" large style="width: 100%" :loading="loader" :disabled="btn_dis">
<v-icon class="mx-2" > mdi-qqchat </v-icon>
QQ
</v-btn>
<v-btn class="cyan white--text" @click="yklogin" large style="width: 100%" :loading="loader" :disabled="btn_dis">
<v-icon class="mx-2"> mdi-message-text </v-icon>
临时游客
</v-btn>
</v-card>
</template>
<script>
export default {
data: () => ({
btn_dis:false,
loader: null,
valid: true,
user_name: "",
user_nameRules: [
(v) => !!v || "用户名不能为空",
(v) => (v && v.length <= 20) || "用户名必须小于20个字符",
],
password: "",
passwordRules: [
(v) => !!v || "密码不能为空",
(v) => (v && v.length <= 120) || "密码必须小于20个字符",
],
select: null,
checkbox: true,
}),
created() {
this.enterSearch();
},
methods: {
enterSearch() {
document.onkeydown = (e) => {
//13表示回车键baseURI是当前页面的地址为了更严谨也可以加别的可以打印e看一下
if (e.keyCode === 13 && e.target.baseURI.match("/")) {
//回车后执行搜索方法
this.login();
}
};
},
qqlogin() {
// QC.Login.showPopup(myqq.myqqLogin);
// window.close();
},
yklogin() {
this.loader = "true";
this.btn_dis=true;
this.$store
.dispatch("Login", {
username: "游客",
password: "",
})
.then((resp) => {
if (resp.status) {
this.$router.push("/");
} else {
this.loader=null;
this.btn_dis=false;
this.$dialog.notify.error(resp.msg, {
position: "top-right",
timeout: 5000,
});
}
});
},
login() {
if (this.$refs.form.validate()) {
this.loader = "true";
this.btn_dis=true;
this.$store
.dispatch("Login", {
username: this.user_name,
password: this.password,
})
.then((resp) => {
if (resp.status) {
this.$router.push("/");
} else {
this.loader = null;
this.btn_dis=false;
this.$dialog.notify.error(resp.msg, {
position: "top-right",
timeout: 5000,
});
}
});
} else {
this.$dialog.notify.error("请合理输入数据", {
position: "top-right",
timeout: 5000,
});
}
},
reset() {
this.$refs.form.reset();
},
resetValidation() {
this.$refs.form.resetValidation();
},
},
};
</script>

View File

@@ -0,0 +1,238 @@
<template>
<v-card
class="px-6 py-4 mx-auto elevation-4 rounded-md"
style=" height: 600px; width: 500px"
>
<div>
<h1 class="title my-2">Angstrong</h1>
<v-subheader>注册加入我们</v-subheader>
</div>
<v-form ref="form" v-model="valid" lazy-validation>
<v-text-field
v-model="user_name"
:rules="user_nameRules"
label="用户名"
outlined
clearable
required
:counter="20"
></v-text-field>
<v-text-field
ref="myemail"
v-model="email"
:rules="emailRules"
label="邮箱"
outlined
clearable
required
></v-text-field>
<v-row>
<v-col cols="6" md="8">
<v-text-field
v-model="code"
label="验证码"
outlined
clearable
required
:counter="20"
></v-text-field>
</v-col>
<v-col cols="2" md="1">
<v-progress-circular
class="mt-2"
size="40"
:rotate="360"
:value="value"
color="cyan"
>
{{ value }}
</v-progress-circular>
</v-col>
<v-col cols="4" md="3">
<v-btn class="mt-1" large :dark="!dis_mail" color="cyan" @click="sendMail"
:disabled="dis_mail"
>发送</v-btn
>
</v-col>
</v-row>
<v-text-field
v-model="password"
:rules="passwordRules"
label="密码"
outlined
clearable
required
type="password"
></v-text-field>
<v-row>
<v-col cols="6">
<v-checkbox
v-model="checkbox"
:rules="[(v) => !!v || '同意后才可进入']"
label="你同意协议吗?"
required
></v-checkbox
></v-col>
<v-col cols="6" class="text-right pt-8"
><router-link to="/login">返回</router-link></v-col
>
</v-row>
</v-form>
<v-btn
class="my-2 light-blue white--text"
@click="register"
large
style="width: 100%"
:loading="loader"
:disabled="btn_dis"
>
注册
</v-btn>
<!-- <p>或使用登录</p>
<v-btn dark class="my-2 cyan" @click="login" large style="width: 100%">
<v-icon class="mx-2"> mdi-message-text </v-icon>
QQ
</v-btn>
<v-btn dark class="cyan" @click="login" large style="width: 100%">
<v-icon class="mx-2"> mdi-message-text </v-icon>
微信
</v-btn> -->
</v-card>
</template>
<script>
import accountApi from "../api/accountApi.js";
export default {
data: () => ({
btn_dis:false,
loader: null,
dis_mail:false,
value:100,
code: "",
valid: true,
user_name: "",
user_nameRules: [
(v) => !!v || "用户名不能为空",
(v) => (v && v.length <= 20) || "用户名必须小于20个字符",
],
email: "",
emailRules: [
(v) => !!v || "邮箱不能为空",
(v) => /.+@.+\..+/.test(v) || "",
],
password: "",
passwordRules: [
(v) => !!v || "密码不能为空",
(v) => (v && v.length <= 120) || "密码必须小于120个字符",
(v) => (v && v.length >= 7) || "密码必须大于等于7个字符",
],
select: null,
checkbox: true,
}),
created()
{
setInterval(this.addValue,1000)
},
// watch:{
// value(val,old)
// {
// val+=1
// if (val==100)
// {
// this.dis_mail=false
// }
// else
// {
// this.dis_mail=true
// }
// }
// },
methods: {
addValue()
{
if(this.value<=99)
{
this.value+=1
}
if(this.value==100)
{
this.dis_mail=false
}
else
{
this.dis_mail=true
}
},
register() {
if (this.$refs.form.validate()) {
this.loader = "true";
this.btn_dis=true;
this.$store
.dispatch("Register", {
username: this.user_name,
password: this.password,
email: this.email,
code: this.code,
})
.then((resp) => {
if (resp.status) {
this.$dialog.notify.success(resp.msg, {
position: "top-right",
timeout: 5000,
});
this.$router.push("/login");
} else {
this.loader=null;
this.btn_dis=false;
this.$dialog.notify.error(resp.msg, {
position: "top-right",
timeout: 5000,
});
}
});
} else {
this.$dialog.notify.error("请合理输入数据", {
position: "top-right",
timeout: 5000,
});
}
},
reset() {
this.$refs.form.reset();
},
resetValidation() {
this.$refs.form.resetValidation();
},
sendMail() {
if (this.$refs.myemail.validate()) {
this.value=0
this.dis_mail=true
accountApi.email(this.email).then((resp) => {
if (resp.status) {
this.$dialog.notify.success(resp.msg, {
position: "top-right",
timeout: 5000,
});
} else {
this.$dialog.notify.error(resp.msg, {
position: "top-right",
timeout: 5000,
});
}
});
} else {
this.$dialog.notify.error("请合理输入邮箱", {
position: "top-right",
timeout: 5000,
});
}
},
},
};
</script>