增加基本的api请求代码

This commit is contained in:
zhl 2022-01-20 14:50:19 +08:00
parent 0362a15d4a
commit da9e681fa5
10 changed files with 380 additions and 5 deletions

59
package-lock.json generated
View File

@ -3423,6 +3423,14 @@
}
}
},
"async-validator": {
"version": "1.8.5",
"resolved": "https://registry.npmmirror.com/async-validator/download/async-validator-1.8.5.tgz",
"integrity": "sha1-3D4I7B/Q3dtn5ghC8CwM0c7G1/A=",
"requires": {
"babel-runtime": "6.x"
}
},
"asynckit": {
"version": "0.4.0",
"resolved": "http://registry.npm.taobao.org/asynckit/download/asynckit-0.4.0.tgz",
@ -3479,6 +3487,14 @@
"resolved": "https://registry.npm.taobao.org/aws4/download/aws4-1.11.0.tgz?cache=0&sync_timestamp=1604101385256&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faws4%2Fdownload%2Faws4-1.11.0.tgz",
"integrity": "sha1-1h9G2DslGSUOJ4Ta9bCUeai0HFk="
},
"axios": {
"version": "0.21.4",
"resolved": "https://registry.npmmirror.com/axios/download/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"requires": {
"follow-redirects": "^1.14.0"
}
},
"babel-code-frame": {
"version": "6.26.0",
"resolved": "http://registry.npm.taobao.org/babel-code-frame/download/babel-code-frame-6.26.0.tgz",
@ -3538,6 +3554,11 @@
}
}
},
"babel-helper-vue-jsx-merge-props": {
"version": "2.0.3",
"resolved": "https://registry.npmmirror.com/babel-helper-vue-jsx-merge-props/download/babel-helper-vue-jsx-merge-props-2.0.3.tgz",
"integrity": "sha1-Iq69OzOQIyjlEyk6jkmSs4T58bY="
},
"babel-loader": {
"version": "8.2.3",
"resolved": "https://registry.npmmirror.com/babel-loader/download/babel-loader-8.2.3.tgz",
@ -6035,6 +6056,26 @@
"resolved": "https://registry.npmmirror.com/electron-to-chromium/download/electron-to-chromium-1.4.27.tgz",
"integrity": "sha512-uZ95szi3zUbzRDx1zx/xnsCG+2xgZyy57pDOeaeO4r8zx5Dqe8Jv1ti8cunvBwJHVI5LzPuw8umKwZb3WKYxSQ=="
},
"element-ui": {
"version": "2.15.6",
"resolved": "https://registry.npmmirror.com/element-ui/download/element-ui-2.15.6.tgz",
"integrity": "sha512-rcYXEKd/j2G0AgficAOk1Zd1AsnHRkhmrK4yLHmNOiimU2JfsywgfKUjMoFuT6pQx0luhovj8lFjpE4Fnt58Iw==",
"requires": {
"async-validator": "~1.8.1",
"babel-helper-vue-jsx-merge-props": "^2.0.0",
"deepmerge": "^1.2.0",
"normalize-wheel": "^1.0.1",
"resize-observer-polyfill": "^1.5.0",
"throttle-debounce": "^1.0.1"
},
"dependencies": {
"deepmerge": {
"version": "1.5.2",
"resolved": "https://registry.npmmirror.com/deepmerge/download/deepmerge-1.5.2.tgz",
"integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ=="
}
}
},
"elliptic": {
"version": "6.5.4",
"resolved": "https://registry.npm.taobao.org/elliptic/download/elliptic-6.5.4.tgz?cache=0&sync_timestamp=1612291311722&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Felliptic%2Fdownload%2Felliptic-6.5.4.tgz",
@ -7901,8 +7942,7 @@
"follow-redirects": {
"version": "1.14.6",
"resolved": "https://registry.npmmirror.com/follow-redirects/download/follow-redirects-1.14.6.tgz",
"integrity": "sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==",
"dev": true
"integrity": "sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A=="
},
"for-in": {
"version": "1.0.2",
@ -11142,6 +11182,11 @@
"integrity": "sha1-suHE3E98bVd0PfczpPWXjRhlBVk=",
"dev": true
},
"normalize-wheel": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/normalize-wheel/download/normalize-wheel-1.0.1.tgz",
"integrity": "sha1-rsiGr/2wRQcNhWRH32Ls+GFG7EU="
},
"npm-run-path": {
"version": "2.0.2",
"resolved": "https://registry.npmmirror.com/npm-run-path/download/npm-run-path-2.0.2.tgz",
@ -13155,6 +13200,11 @@
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
"dev": true
},
"resize-observer-polyfill": {
"version": "1.5.1",
"resolved": "https://registry.npmmirror.com/resize-observer-polyfill/download/resize-observer-polyfill-1.5.1.tgz",
"integrity": "sha1-DpAg3T0hAkRY1OvSfiPkAmmBBGQ="
},
"resolve": {
"version": "1.20.0",
"resolved": "https://registry.nlark.com/resolve/download/resolve-1.20.0.tgz",
@ -14812,6 +14862,11 @@
"neo-async": "^2.6.0"
}
},
"throttle-debounce": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/throttle-debounce/download/throttle-debounce-1.1.0.tgz",
"integrity": "sha1-UYU9o3vmihVctugns1FKPEIuic0="
},
"through": {
"version": "2.3.8",
"resolved": "http://registry.npm.taobao.org/through/download/through-2.3.8.tgz",

View File

@ -9,7 +9,9 @@
},
"dependencies": {
"@walletconnect/web3-provider": "^1.7.1",
"axios": "^0.21.0",
"core-js": "^3.6.5",
"element-ui": "^2.15.6",
"js-cookie": "^2.2.1",
"videojs-contrib-hls": "^5.15.0",
"vue": "^2.6.11",

View File

@ -4,14 +4,16 @@
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
import { Component } from 'vue-property-decorator'
import ResizeMixin from '@/utils/resize'
import { mixins } from 'vue-class-component'
@Component({
name: 'App',
components: {
}
})
export default class extends Vue {
export default class extends mixins(ResizeMixin) {
created() {
console.log('main app created')
}

53
src/api/User.ts Normal file
View File

@ -0,0 +1,53 @@
import request from '@/utils/request'
export interface IUser {
id: string
username: string
showname: string
comment: string
locked: boolean
avatar: string
password: string
}
export const defaultUser: IUser = {
id: '',
username: '',
showname: '',
comment: '',
locked: false,
password: '',
avatar: ''
}
export const getUserInfo = (data: any) =>
request({
url: '/api/user/info',
method: 'post',
data
})
export const login = (data: any) =>
request({
url: '/api/user/login',
method: 'post',
data
})
export const logout = () =>
request({
url: '/api/user/logout',
method: 'post'
})
export const changePass = (params: any) =>
request({
url: '/api/user/passwd',
method: 'post',
data: params
})
export const changeInfo = (params: any) =>
request({
url: '/api/user/update_info',
method: 'post',
data: params
})

View File

@ -51,7 +51,7 @@ import TopUserInfo from '@/components/market/TopUserInfo.vue'
components: { TopUserInfo }
})
export default class extends Vue {
walletCollected = true;
walletCollected = false;
infoPanelShow = false
}
</script>

View File

@ -1,9 +1,12 @@
import Vue from 'vue'
import App from './App.vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import router from './router'
import store from './store'
import 'video.js/dist/video-js.css'
Vue.use(ElementUI)
Vue.config.productionTip = false
new Vue({

View File

@ -1,11 +1,13 @@
import Vue from 'vue'
import Vuex from 'vuex'
import { IAppState } from './modules/app'
import { IUserState } from './modules/user'
Vue.use(Vuex)
export interface IRootState {
app: IAppState
user: IUserState
}
// Declare empty store first, dynamically register all modules later.

139
src/store/modules/user.ts Normal file
View File

@ -0,0 +1,139 @@
import {
Action,
getModule,
Module,
Mutation,
VuexModule
} from 'vuex-module-decorators'
import { getToken, removeToken, setToken } from '@/utils/cookies'
import { getUserInfo, login, logout } from '@/api/User'
import store from '@/store'
export interface IUserState {
token: string
name: string
avatar: string
introduction: string
roles: string[]
email: string
permissions: string[][]
level: number
sex?: string
}
@Module({ dynamic: true, store, name: 'user' })
class User extends VuexModule implements IUserState {
public token = getToken() || ''
public name = ''
public avatar = ''
public introduction = ''
public roles: string[] = []
public permissions: string[][] = []
public email = ''
public level = 999
public sex = '0'
@Action
public async Login(userInfo: { username: string, password: string }) {
let { username, password } = userInfo
username = username.trim()
const { data } = await login({ username, password })
setToken(data.token)
this.SET_TOKEN(data.token)
}
@Action
public ResetToken() {
removeToken()
this.SET_TOKEN('')
this.SET_ROLES([])
this.SET_PERMISSIONS([])
}
@Action
public async GetUserInfo() {
if (this.token === '') {
throw Error('GetUserInfo: token is undefined!')
}
const { data } = await getUserInfo({ /* Your params here */ })
if (!data) {
throw Error('Verification failed, please Login again.')
}
const { showname, avatar, introduction, permissions, level } = data
this.SET_NAME(showname)
this.SET_AVATAR(avatar)
this.SET_INTRODUCTION(introduction)
this.SET_PERMISSIONS(permissions)
this.SET_LEVEL(level)
}
@Action
public async UpdateInfo(data: any) {
const { showname, avatar } = data
this.SET_NAME(showname)
this.SET_AVATAR(avatar)
}
@Action
public async LogOut() {
if (this.token === '') {
throw Error('LogOut: token is undefined!')
}
await logout()
removeToken()
this.SET_TOKEN('')
this.SET_ROLES([])
this.SET_PERMISSIONS([])
}
@Mutation
private SET_TOKEN(token: string) {
this.token = token
}
@Action
public async updatePageToken(token: string) {
this.SET_TOKEN(token)
}
@Mutation
private SET_NAME(name: string) {
this.name = name
}
@Mutation
private SET_AVATAR(avatar: string) {
this.avatar = avatar
}
@Mutation
private SET_INTRODUCTION(introduction: string) {
this.introduction = introduction
}
@Mutation
private SET_ROLES(roles: string[]) {
this.roles = roles
}
@Mutation
private SET_LEVEL(level: number) {
this.level = level
}
@Mutation
private SET_PERMISSIONS(permissions: string[]) {
const results: string[][] = []
for (const permission of permissions) {
if (permission === '*') {
results.push(['*', '*'])
} else {
results.push(permission.split(':'))
}
}
this.permissions = results
}
}
export const UserModule = getModule(User)

72
src/utils/request.ts Normal file
View File

@ -0,0 +1,72 @@
import axios from 'axios'
import { Message, MessageBox } from 'element-ui'
import { UserModule } from '@/store/modules/user'
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
timeout: 5000
})
// Request interceptors
service.interceptors.request.use(
(config) => {
// Add X-Access-Token header to every request, you can add other custom headers here
if (UserModule.token) {
config.headers.authorization = 'Bearer ' + UserModule.token
}
config.headers['Content-Type'] = 'application/json'
return config
},
(error) => {
Promise.reject(error)
}
)
// Response interceptors
service.interceptors.response.use(
(response) => {
// Some example codes here:
// code == 0: success
// code == 50001: invalid access token
// code == 50002: already login in other place
// code == 50003: access token expired
// code == 50004: invalid user (user not exist)
// code == 10: username or password is incorrect
// You can change this part for your own usage.
const res = response.data
if (res.code) {
Message({
message: res.msg || 'Error',
type: 'error',
duration: 5 * 1000
})
if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
MessageBox.confirm(
'You have been logged out, try to login again.',
'Log out',
{
confirmButtonText: 'Relogin',
cancelButtonText: 'Cancel',
type: 'warning'
}
).then(() => {
UserModule.ResetToken()
location.reload() // To prevent bugs from vue-router
})
}
return Promise.reject(new Error(res.msg || 'Error'))
} else {
return response.data
}
},
(error) => {
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
export default service

47
src/utils/resize.ts Normal file
View File

@ -0,0 +1,47 @@
import { Component, Vue, Watch } from 'vue-property-decorator'
import { AppModule, DeviceType } from '@/store/modules/app'
const WIDTH = 992 // refer to Bootstrap's responsive design
@Component({
name: 'ResizeMixin'
})
export default class extends Vue {
get device() {
return AppModule.device
}
@Watch('$route')
private onRouteChange() {
console.log('route change: ', this.$route?.fullPath)
}
beforeMount() {
window.addEventListener('resize', this.resizeHandler)
}
mounted() {
const isMobile = this.isMobile()
if (isMobile) {
AppModule.ToggleDevice(DeviceType.Mobile)
}
}
beforeDestroy() {
window.removeEventListener('resize', this.resizeHandler)
}
private isMobile() {
const rect = document.body.getBoundingClientRect()
return rect.width - 1 < WIDTH
}
private resizeHandler() {
if (!document.hidden) {
const isMobile = this.isMobile()
AppModule.ToggleDevice(isMobile ? DeviceType.Mobile : DeviceType.Desktop)
if (isMobile) {
}
}
}
}