├── backend
├── README.md
├── settings.js
├── my-database.db
├── package.json
├── accountRouter.js
├── app.js
├── tweetRouter.js
└── db.js
├── front
├── public
│ ├── favicon.ico
│ └── index.html
├── babel.config.js
├── src
│ ├── assets
│ │ ├── CRUD.png
│ │ ├── logo.png
│ │ ├── background.png
│ │ ├── registerImg.png
│ │ └── assets.css
│ ├── App.vue
│ ├── store
│ │ └── index.js
│ ├── main.js
│ ├── router
│ │ └── index.js
│ ├── views
│ │ ├── Home.vue
│ │ ├── Register.vue
│ │ └── Skill.vue
│ └── client.js
├── README.md
└── package.json
├── README.md
└── .gitignore
/backend/README.md:
--------------------------------------------------------------------------------
1 | 所需安装包
2 | express
3 | md5-node
4 | jsonwebtoken
5 | sqlite3
6 | body-parser
7 |
8 |
--------------------------------------------------------------------------------
/backend/settings.js:
--------------------------------------------------------------------------------
1 | //令牌加密规则,随便写
2 | module.exports = {
3 | accessTokenSecret: "qeocsajchsacsavd"
4 | }
--------------------------------------------------------------------------------
/backend/my-database.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaoxian521/vue-node-sqlite3/HEAD/backend/my-database.db
--------------------------------------------------------------------------------
/front/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaoxian521/vue-node-sqlite3/HEAD/front/public/favicon.ico
--------------------------------------------------------------------------------
/front/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/front/src/assets/CRUD.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaoxian521/vue-node-sqlite3/HEAD/front/src/assets/CRUD.png
--------------------------------------------------------------------------------
/front/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaoxian521/vue-node-sqlite3/HEAD/front/src/assets/logo.png
--------------------------------------------------------------------------------
/front/src/assets/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaoxian521/vue-node-sqlite3/HEAD/front/src/assets/background.png
--------------------------------------------------------------------------------
/front/src/assets/registerImg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaoxian521/vue-node-sqlite3/HEAD/front/src/assets/registerImg.png
--------------------------------------------------------------------------------
/front/src/assets/assets.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | width: 100%;
4 | height: 100%;
5 | margin: 0;
6 | padding: 0;
7 | }
--------------------------------------------------------------------------------
/front/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue-node-sqlite3
2 | vue+node+sqlite3实现增删改查
3 |
4 | backend 后端文件
5 |
6 | front 前端文件
7 |
8 | 整体实现登录注册(jwt)
9 | 增删改查都需携带token
10 |
11 | 网上vue+node+sqlite3完整的实现这一套功能还是很少的,期待你的Star
--------------------------------------------------------------------------------
/front/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 |
4 | Vue.use(Vuex)
5 |
6 | export default new Vuex.Store({
7 | state: {},
8 | mutations: {},
9 | getters: {},
10 | actions: {},
11 | modules: {}
12 | })
--------------------------------------------------------------------------------
/front/README.md:
--------------------------------------------------------------------------------
1 | # crud
2 |
3 | ## Project setup
4 | ```
5 | yarn install
6 | ```
7 |
8 | ### Compiles and hot-reloads for development
9 | ```
10 | yarn serve
11 | ```
12 |
13 | ### Compiles and minifies for production
14 | ```
15 | yarn build
16 | ```
17 |
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw?
22 |
--------------------------------------------------------------------------------
/backend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tutorial-03",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "body-parser": "^1.19.0",
14 | "express": "^4.17.1",
15 | "jsonwebtoken": "^8.5.1",
16 | "md5-node": "^1.0.1",
17 | "sqlite3": "^4.1.0"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/front/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import router from './router'
4 | import store from './store'
5 | //引入公共样式
6 | import './assets/assets.css'
7 | //引入ViewUI
8 | import ViewUI from 'view-design';
9 | import 'view-design/dist/styles/iview.css';
10 | Vue.use(ViewUI);
11 | //引入ElementUI
12 | import ElementUI from 'element-ui';
13 | import 'element-ui/lib/theme-chalk/index.css';
14 | Vue.use(ElementUI);
15 |
16 | Vue.config.productionTip = false
17 |
18 | new Vue({
19 | router,
20 | store,
21 | render: h => h(App)
22 | }).$mount('#app')
--------------------------------------------------------------------------------
/front/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | crud
10 |
11 |
12 |
13 |
17 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/front/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueRouter from 'vue-router'
3 |
4 | Vue.use(VueRouter)
5 |
6 | //路由懒加载
7 | function resolveView(view) {
8 | return () => import(`@/views/${view}`)
9 | }
10 |
11 | const routes = [{
12 | path: '/',
13 | name: 'home',
14 | component: resolveView('Home')
15 | }, {
16 | path: '/Register',
17 | name: 'register',
18 | component: resolveView('Register')
19 | },
20 | {
21 | path: '/Skill',
22 | name: 'skill',
23 | component: resolveView('Skill')
24 | }
25 | ]
26 |
27 | const router = new VueRouter({
28 | mode: 'history',
29 | base: process.env.BASE_URL,
30 | routes
31 | })
32 |
33 | export default router
--------------------------------------------------------------------------------
/front/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "crud",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build"
8 | },
9 | "dependencies": {
10 | "axios": "^0.19.0",
11 | "core-js": "^3.3.2",
12 | "element-ui": "^2.12.0",
13 | "iview": "^1.0.1",
14 | "jwt-decode": "^2.2.0",
15 | "view-design": "^4.0.2",
16 | "vue": "^2.6.10",
17 | "vue-router": "^3.1.3",
18 | "vuex": "^3.0.1"
19 | },
20 | "devDependencies": {
21 | "@vue/cli-plugin-babel": "^4.0.0",
22 | "@vue/cli-plugin-router": "^4.0.0",
23 | "@vue/cli-plugin-vuex": "^4.0.0",
24 | "@vue/cli-service": "^4.0.0",
25 | "sass": "^1.19.0",
26 | "sass-loader": "^8.0.0",
27 | "vue-template-compiler": "^2.6.10"
28 | },
29 | "postcss": {
30 | "plugins": {
31 | "autoprefixer": {}
32 | }
33 | },
34 | "browserslist": [
35 | "> 1%",
36 | "last 2 versions"
37 | ]
38 | }
39 |
--------------------------------------------------------------------------------
/backend/accountRouter.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const db = require('./db')
3 | const md5 = require('md5-node')
4 |
5 | const router = express.Router()
6 |
7 | //添加用户信息
8 | router.post("/", function(request, response){
9 | // 接收前端传过来的用户信息(解构赋值)
10 | const { username, password, passwordRepeat, email } = request.body
11 | //在后台定义用户注册时间才是符合规范的
12 | const creationTime = new Date().toLocaleString()
13 | if(
14 | typeof username != "string" ||
15 | typeof password != "string" ||
16 | typeof passwordRepeat != "string" ||
17 | typeof email != "string" ||
18 | typeof creationTime != "string"
19 | ){
20 | response.status(422).end()
21 | return
22 | }
23 | //这里对用户所有密码都进行了加密
24 | db.createAccount(username, md5(password), md5(passwordRepeat), email, creationTime, function(error, id){
25 | if(error){
26 | if(error.message == "SQLITE_CONSTRAINT: UNIQUE constraint failed: accounts.username"){
27 | response.status(400).json(["usernameTaken"])
28 | }else{
29 | response.status(500).end()
30 | }
31 | }else{
32 | response.setHeader("Location", "/accounts/"+id)
33 | response.status(201).end()
34 | }
35 | })
36 |
37 | })
38 |
39 | module.exports = router
--------------------------------------------------------------------------------
/backend/app.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const bodyParser = require('body-parser')
3 | const jwt = require('jsonwebtoken')
4 | const settings = require('./settings')
5 | const db = require('./db')
6 | const accountRouter = require('./accountRouter')
7 | const tweetRouter = require('./tweetRouter')
8 | const md5 = require('md5-node')
9 |
10 | const app = express()
11 |
12 | //解决跨域问题
13 | app.use(function (request, response, next) {
14 | response.setHeader("Access-Control-Allow-Origin", "*")
15 | response.setHeader("Access-Control-Allow-Methods", "*")
16 | response.setHeader("Access-Control-Allow-Headers", "*")
17 | response.setHeader("Access-Control-Expose-Headers", "*")
18 | next()
19 | })
20 |
21 | //对POST请求过来的数据进行解析
22 | app.use(bodyParser.json())
23 | app.use(bodyParser.urlencoded({
24 | extended: false
25 | }))
26 |
27 | //使得accounts接口可用
28 | app.use("/accounts", accountRouter)
29 | //使得tweets接口可用
30 | app.use("/tweets", tweetRouter)
31 |
32 | // 用户登录并设置token令牌
33 | app.post("/tokens", function (request, response) {
34 | // 将前端传来的用户信息进行解构,直接获取里面的值
35 | const { grant_type, username, password } = request.body
36 | db.getAccountByUsername(username, function (error, account) {
37 | if (error) {
38 | response.status(500).end()
39 | } else if (!account || account.password != md5(password)) {
40 | response.status(400).json({ error: "invalid_client" })
41 | } else {
42 | //生成jwt(token令牌) {expiresIn:3600}为token的过期时间,这里设置的是1小时
43 | const accessToken = jwt.sign({
44 | accountId: account.id
45 | }, settings.accessTokenSecret, { expiresIn: 3600 })
46 | const idToken = jwt.sign({
47 | sub: account.id,
48 | preferred_username: account.username
49 | }, "some secret that doesn't matter")
50 | //返回token
51 | response.status(200).json({
52 | access_token: accessToken,
53 | id_token: idToken
54 | })
55 | }
56 | })
57 | })
58 |
59 | app.listen(3000, err => {
60 | if (!err) console.log('Successful Connection! Please Start Your Operation! The Port 3000')
61 | })
62 |
63 |
64 | // Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. 头部
65 | // eyJhY2NvdW50SWQiOjEsImlhdCI6MTU3MjU5OTQ3MSwiZXhwIjoxNTcyNTk5NDgxfQ. 载荷
66 | // 01kCpXKp4qQqrofs9LEtssgb6k3V8ZWl_tqsuvRfXeM 签名
--------------------------------------------------------------------------------
/backend/tweetRouter.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const db = require('./db')
3 | const settings = require('./settings')
4 | const jwt = require('jsonwebtoken')
5 |
6 | const router = express.Router()
7 |
8 | //获取所有tweets信息
9 | router.get("/", function(request, response){
10 | db.getAllTweets(function(error, tweets){
11 | if(error){
12 | response.status(500).end()
13 | }else{
14 | response.status(200).json(tweets)
15 | }
16 | })
17 | })
18 |
19 | //根据ID获取Tweet信息
20 | router.get("/:id", function(request, response){
21 | const id = request.params.id
22 | db.getTweetById(id, function(error, tweet){
23 | if(error){
24 | response.status(500).end()
25 | }else if(tweet){
26 | response.status(200).json(tweet)
27 | }else{
28 | response.status(404).end()
29 | }
30 | })
31 | })
32 |
33 | //根据ID对tweets信息进行
34 | router.delete("/:id", function(request, response){
35 | const id = request.params.id
36 | db.deleteTweetById(id, function(error, tweet){
37 | if(error){
38 | response.status(500).end()
39 | }else if(tweet){
40 | response.status(200).json(tweet)
41 | }else{
42 | response.status(404).end()
43 | }
44 | })
45 | })
46 |
47 | //添加tweets信息
48 | router.post("/", function(request, response){
49 | let payload = null
50 | try{
51 | const authorizationHeader = request.get("Authorization")
52 | const accessToken = authorizationHeader.substr("Bearer ".length)
53 | payload = jwt.verify(accessToken, settings.accessTokenSecret)
54 | }catch(error){
55 | response.status(401).end()
56 | return
57 | }
58 | const { accountId, message, createdAt, orders, payMethod,} = request.body
59 | if(payload == null || payload.accountId != accountId){
60 | response.status(401).end()
61 | return
62 | }
63 | const errors = []
64 | if(0 < errors.length){
65 | response.status(400).json(errors)
66 | return
67 | }
68 | db.createTweet(accountId, message, createdAt, orders, payMethod, function(error, id){
69 | if(error){
70 | if(error.message == "SQLITE_CONSTRAINT: FOREIGN KEY constraint failed"){
71 | response.status(400).json(["accountDoesNotExist"])
72 | }else{
73 | response.status(500).end()
74 | }
75 | }else{
76 | response.setHeader("Location", "/tweets/"+id)
77 | response.status(201).end()
78 | }
79 | })
80 | })
81 |
82 | //根据ID修改tweets信息
83 | router.put("/:id", function(request, response){
84 | const id = request.params.id
85 | const updatedAccountId = request.body.accountId
86 | const updatedMessage = request.body.message
87 | const updateCreatedAt = request.body.createdAt
88 | const updatedOrders = request.body.orders
89 | const updatedPayMethod = request.body.payMethod
90 | db.updateTweetById(id, updatedAccountId, updatedMessage, updateCreatedAt, updatedOrders, updatedPayMethod, function(error){
91 | if(error){
92 | if(error.message == "SQLITE_CONSTRAINT: FOREIGN KEY constraint failed"){
93 | response.status(400).json(["accountDoesNotExist"])
94 | }else{
95 | response.status(500).end()
96 | }
97 | }else{
98 | response.status(204).end()
99 | }
100 | })
101 | })
102 |
103 | module.exports = router
--------------------------------------------------------------------------------
/backend/db.js:
--------------------------------------------------------------------------------
1 | const sqlite3 = require('sqlite3')
2 | const db = new sqlite3.Database("my-database.db")
3 |
4 | db.run("PRAGMA foreign_keys = ON")
5 |
6 | //CONSTRAINT unique_username UNIQUE(username) 对username做了唯一约束
7 | // 创建accounts用户表格的命令
8 | // CreationTime为创建时间
9 | db.run(`
10 | CREATE TABLE IF NOT EXISTS accounts (
11 | id INTEGER PRIMARY KEY AUTOINCREMENT,
12 | username TEXT,
13 | password TEXT,
14 | passwordRepeat TEXT,
15 | email TEXT,
16 | creationTime TEXT,
17 | CONSTRAINT unique_username UNIQUE(username)
18 | )
19 | `)
20 | // 创建Tweets表格的命令
21 | // id INTEGER主键自动递增
22 | db.run(`
23 | CREATE TABLE IF NOT EXISTS tweets (
24 | id INTEGER PRIMARY KEY AUTOINCREMENT,
25 | accountId INTEGER,
26 | message TEXT,
27 | createdAt INTEGER,
28 | orders TEXT,
29 | payMethod TEXT,
30 | FOREIGN KEY (accountId) REFERENCES accounts(id) ON DELETE CASCADE
31 | )
32 | `)
33 |
34 | //获取Tweet表格中的所有数据
35 | exports.getAllTweets = function(callback){
36 | const query = "SELECT * FROM tweets"
37 | db.all(query, function(error, tweets){
38 | callback(error, tweets)
39 | })
40 | }
41 |
42 | //通过ID来查看Tweet表格中的数据
43 | exports.getTweetById = function(id, callback){
44 | const query = "SELECT * FROM tweets WHERE id = ?"
45 | const values = [id]
46 | db.get(query, values, function(error, tweet){
47 | callback(error, tweet)
48 | })
49 | }
50 |
51 | //通过ID来删除Tweet表格中的数据
52 | exports.deleteTweetById = function(id, callback){
53 | const query = "DELETE FROM tweets WHERE id = ?"
54 | const values = [id]
55 | db.run(query, values, function(error){
56 | callback(error)
57 | })
58 | }
59 |
60 | //创建Tweet表格
61 | exports.createTweet = function(accountId, message, createdAt, orders, payMethod, callback){
62 | const query = "INSERT INTO tweets (accountId, message, createdAt, orders, payMethod) VALUES (?, ?, ?, ?, ?)"
63 | const values = [accountId, message, createdAt, orders, payMethod]
64 | db.run(query, values, function(error){
65 | callback(error, this.lastID)
66 | })
67 | }
68 |
69 | //通过ID来更新Tweet表格中的数据
70 | exports.updateTweetById = function(id, updatedAccountId, updatedMessage, updateCreatedAt, updatedOrders, updatedPayMethod, callback){
71 | const query = `
72 | UPDATE tweets SET
73 | accountId = ?,
74 | message = ?,
75 | createdAt = ?,
76 | orders = ?,
77 | payMethod = ?
78 | WHERE
79 | id = ?
80 | `
81 | const values = [updatedAccountId, updatedMessage, updateCreatedAt, updatedOrders, updatedPayMethod, id]
82 | db.run(query, values, function(error){
83 | callback(error)
84 | })
85 |
86 | }
87 |
88 | //将前端传过来的用户信息插入
89 | exports.createAccount = function(username, password, passwordRepeat, email, creationTime, callback){
90 | const query = "INSERT INTO accounts (username, password, passwordRepeat, email, creationTime) VALUES (?, ?, ?, ?, ?)"
91 | const values = [username,password,passwordRepeat,email,creationTime]
92 | db.run(query, values, function(error){
93 | callback(error, this.lastID)
94 | })
95 | }
96 |
97 | //通过姓名查找用户信息
98 | exports.getAccountByUsername = function(username, callback){
99 | const query = "SELECT * FROM accounts WHERE username = ?"
100 | const values = [username]
101 | db.get(query, values, function(error, account){
102 | callback(error, account)
103 | })
104 | }
--------------------------------------------------------------------------------
/front/src/views/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
43 |
44 |
45 |
125 |
126 |
--------------------------------------------------------------------------------
/front/src/views/Register.vue:
--------------------------------------------------------------------------------
1 |
2 |
54 |
55 |
56 |
154 |
155 |
--------------------------------------------------------------------------------
/front/src/client.js:
--------------------------------------------------------------------------------
1 | const jwtDecode = require('jwt-decode')
2 | let accessToken = null
3 |
4 | //获取所有tweets信息接口
5 | export const getAllTweets = function (callback) {
6 | const request = new XMLHttpRequest()
7 | request.open("GET", "http://localhost:3000/tweets")
8 | request.send()
9 | request.addEventListener("load", () => {
10 | const status = request.status
11 | switch (status) {
12 | case 200:
13 | const bodyAsString = request.responseText
14 | const tweets = JSON.parse(bodyAsString)
15 | callback([], tweets)
16 | global.console.log(tweets)
17 | break
18 | case 500:
19 | callback(["Server error"])
20 | break
21 | default:
22 | callback(["Server error"])
23 | }
24 | })
25 | }
26 |
27 | //根据ID搜索tweets信息接口
28 | export const getSearchTweets = function (searchId, callback) {
29 | const request = new XMLHttpRequest()
30 | request.open("GET", "http://localhost:3000/tweets/" + searchId)
31 | request.send()
32 | request.addEventListener("load", () => {
33 | const status = request.status
34 | switch (status) {
35 | case 200:
36 | const bodyAsString = request.responseText
37 | const tweets = JSON.parse(bodyAsString)
38 | callback([], tweets)
39 | break
40 | case 500:
41 | callback(["Server error"])
42 | break
43 | default:
44 | callback(["Server error"])
45 | }
46 | })
47 | }
48 |
49 | //根据ID对tweets信息进行删除
50 | export const getDelTweets = function (infoId, callback) {
51 | const request = new XMLHttpRequest()
52 | request.open("DELETE", "http://localhost:3000/tweets/" + infoId)
53 | request.send()
54 | request.addEventListener("load", () => {
55 | const status = request.status
56 | switch (status) {
57 | case 200:
58 | callback(["Delete success"])
59 | break
60 | case 500:
61 | callback(["Server error"])
62 | break
63 | default:
64 | callback(["Server error"])
65 | }
66 | })
67 | }
68 |
69 | //修改tweets信息接口
70 | export const modifyTweet = function (id, accountId, message, createdAt, orders, payMethod, callback) {
71 | const tweet = {
72 | id,
73 | accountId,
74 | message,
75 | createdAt,
76 | orders,
77 | payMethod
78 | }
79 | const request = new XMLHttpRequest()
80 | request.open("PUT", "http://localhost:3000/tweets/" + id)
81 | request.send(JSON.stringify(tweet))
82 | request.addEventListener("load", () => {
83 | const status = request.status
84 | switch (status) {
85 | case 201:
86 | const location = request.getResponseHeader("Location")
87 | callback([], location)
88 | break
89 | case 400:
90 | const errors = JSON.parse(request.responseText)
91 | callback(errors)
92 | break
93 | case 500:
94 | callback(["Unknown server error"])
95 | break
96 | default:
97 | callback(["Unknown server error"])
98 | }
99 | })
100 | }
101 |
102 | //添加tweets信息接口
103 | export const createTweet = function (accountId, message, orders, payMethod, callback) {
104 | const tweet = {
105 | accountId,
106 | message,
107 | orders,
108 | payMethod,
109 | createdAt: Date.now()
110 | }
111 | const request = new XMLHttpRequest()
112 | request.open("POST", "http://localhost:3000/tweets")
113 | request.setRequestHeader("Content-Type", "application/json")
114 | request.setRequestHeader("Authorization", "Bearer " + accessToken)
115 | request.send(JSON.stringify(tweet))
116 | global.console.log(JSON.stringify(tweet))
117 | request.addEventListener("load", () => {
118 | const status = request.status
119 | switch (status) {
120 | case 201:
121 | const location = request.getResponseHeader("Location")
122 | callback([], location)
123 | break
124 | case 400:
125 | const errors = JSON.parse(request.responseText)
126 | callback(errors)
127 | break
128 | case 401:
129 | callback(["unauthorired"])
130 | break
131 | case 500:
132 | callback(["Unknown server error"])
133 | break
134 | default:
135 | callback(["Unknown server error"])
136 | }
137 | })
138 | }
139 |
140 | //用户注册接口
141 | export const createAccount = function (username, password, passwordRepeat, email, callback) {
142 | const account = {
143 | username,
144 | password,
145 | passwordRepeat,
146 | email
147 | }
148 | const request = new XMLHttpRequest()
149 | request.open("POST", "http://localhost:3000/accounts")
150 | request.setRequestHeader("Content-Type", "application/json")
151 | request.send(JSON.stringify(account))
152 | global.console.log(account)
153 | request.addEventListener("load", () => {
154 | const status = request.status
155 | switch (status) {
156 | case 201:
157 | const location = request.getResponseHeader("Location")
158 | callback([], location)
159 | break
160 | case 400:
161 | const errors = JSON.parse(request.responseText)
162 | callback(errors)
163 | break
164 | case 500:
165 | callback(["Unknown server error"])
166 | break
167 | default:
168 | callback(["Unknown server error"])
169 | }
170 | })
171 | }
172 |
173 | //用户登录接口
174 | export const login = function (username, password, callback) {
175 | const request = new XMLHttpRequest()
176 | request.open("POST", "http://localhost:3000/tokens")
177 | request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
178 | request.send("grant_type=password&username=" + encodeURIComponent(username) + "&password=" + encodeURIComponent(password))
179 | request.addEventListener("load", () => {
180 | const status = request.status
181 | switch (status) {
182 | case 200:
183 | var body = JSON.parse(request.responseText)
184 | const idToken = body.id_token
185 | accessToken = body.access_token
186 | const userInfo = jwtDecode(idToken)
187 | const id = userInfo.sub
188 | const username = userInfo.preferred_username
189 | callback([], id, username)
190 | break
191 | case 400:
192 | var body = JSON.parse(request.responseText)
193 | callback([body.error])
194 | break
195 | case 500:
196 | callback(["Unknown server error"])
197 | break
198 | default:
199 | callback(["Unknown server error"])
200 | }
201 | })
202 | }
--------------------------------------------------------------------------------
/front/src/views/Skill.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{user}}
4 |
5 |
6 |
7 |
8 |
9 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | {{ row.message }}
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
59 |
60 |
61 |
62 |
63 |
272 |
273 |
--------------------------------------------------------------------------------