change vue2 to vue3
This commit is contained in:
parent
82b64a4bb2
commit
c74c332e6a
3
go.mod
3
go.mod
@ -6,9 +6,10 @@ require (
|
||||
github.com/json-iterator/go v1.1.10
|
||||
github.com/urfave/cli/v2 v2.2.0
|
||||
github.com/veypi/OneBD v0.4.1
|
||||
github.com/veypi/utils v0.2.2
|
||||
github.com/veypi/utils v0.3.1
|
||||
gorm.io/driver/mysql v1.0.5
|
||||
gorm.io/driver/sqlite v1.1.4
|
||||
gorm.io/gorm v1.21.3
|
||||
)
|
||||
|
||||
replace github.com/veypi/OneBD v0.4.1 => ../OceanCurrent/OneBD
|
||||
|
||||
8
go.sum
8
go.sum
@ -43,11 +43,11 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4=
|
||||
github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
|
||||
github.com/veypi/OneBD v0.4.1 h1:IkuV2tqay3fyX+FsM9XrKiKS9N7pymUJnrscGx2T0mc=
|
||||
github.com/veypi/OneBD v0.4.1/go.mod h1:9IoMOBzwIGyv6IZGF7ZnTYwTcHltLKicDgcwha66G0U=
|
||||
github.com/veypi/utils v0.1.5/go.mod h1:oKcwTDfvE1qtuhJuCcDcfvGquv9bHdFaCGA42onVMC4=
|
||||
github.com/veypi/utils v0.2.2 h1:BRxu0mYJJpuubPjmIIrRVr0XEq9NMp//KUCrVTkFums=
|
||||
github.com/veypi/utils v0.2.2/go.mod h1:rAkC6Fbk5cBa3u+8pyCpsVcnXw74EhEQJGmPND9FvRg=
|
||||
github.com/veypi/utils v0.3.0 h1:vCi0jqMsAMBPblFCmneUw3Wet5y1XHZLA5ZP9c/2owI=
|
||||
github.com/veypi/utils v0.3.0/go.mod h1:rAkC6Fbk5cBa3u+8pyCpsVcnXw74EhEQJGmPND9FvRg=
|
||||
github.com/veypi/utils v0.3.1 h1:QL4Q/+iXNFXNVENiUeEttSwNwkeqrorSpTBpCs7fXBI=
|
||||
github.com/veypi/utils v0.3.1/go.mod h1:rAkC6Fbk5cBa3u+8pyCpsVcnXw74EhEQJGmPND9FvRg=
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
|
||||
@ -3,18 +3,7 @@ package token
|
||||
import (
|
||||
"OneAuth/libs/key"
|
||||
"OneAuth/models"
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
InvalidToken = errors.New("invalid token")
|
||||
ExpiredToken = errors.New("expired token")
|
||||
"github.com/veypi/utils/jwt"
|
||||
)
|
||||
|
||||
type simpleAuth struct {
|
||||
@ -26,10 +15,9 @@ type simpleAuth struct {
|
||||
|
||||
// TODO:: roles 是否会造成token过大 ?
|
||||
type PayLoad struct {
|
||||
jwt.Payload
|
||||
ID uint `json:"id"`
|
||||
AppID uint `json:"app_id"`
|
||||
Iat int64 `json:"iat"` //token time
|
||||
Exp int64 `json:"exp"`
|
||||
Auth map[uint]*simpleAuth `json:"auth"`
|
||||
}
|
||||
|
||||
@ -62,17 +50,9 @@ func (p *PayLoad) GetAuth(ResourceID string, ResourceUUID ...string) models.Auth
|
||||
}
|
||||
|
||||
func GetToken(u *models.User, appID uint) (string, error) {
|
||||
header := map[string]string{
|
||||
"typ": "JWT",
|
||||
"alg": "HS256",
|
||||
}
|
||||
//header := "{\"typ\": \"JWT\", \"alg\": \"HS256\"}"
|
||||
now := time.Now().Unix()
|
||||
payload := PayLoad{
|
||||
payload := &PayLoad{
|
||||
ID: u.ID,
|
||||
AppID: appID,
|
||||
Iat: now,
|
||||
Exp: now + 60*60*24,
|
||||
Auth: map[uint]*simpleAuth{},
|
||||
}
|
||||
for _, a := range u.GetAuths() {
|
||||
@ -84,44 +64,9 @@ func GetToken(u *models.User, appID uint) (string, error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
a, err := json.Marshal(header)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
b, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
A := base64.StdEncoding.EncodeToString(a)
|
||||
B := base64.StdEncoding.EncodeToString(b)
|
||||
hmacCipher := hmac.New(sha256.New, []byte(key.User(payload.ID, payload.AppID)))
|
||||
hmacCipher.Write([]byte(A + "." + B))
|
||||
C := hmacCipher.Sum(nil)
|
||||
return A + "." + B + "." + base64.StdEncoding.EncodeToString(C), nil
|
||||
return jwt.GetToken(payload, []byte(key.User(payload.ID, payload.AppID)))
|
||||
}
|
||||
|
||||
func ParseToken(token string, payload *PayLoad) (bool, error) {
|
||||
var A, B, C string
|
||||
if seqs := strings.Split(token, "."); len(seqs) == 3 {
|
||||
A, B, C = seqs[0], seqs[1], seqs[2]
|
||||
} else {
|
||||
return false, InvalidToken
|
||||
}
|
||||
tempPayload, err := base64.StdEncoding.DecodeString(B)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if err := json.Unmarshal(tempPayload, payload); err != nil {
|
||||
return false, err
|
||||
}
|
||||
hmacCipher := hmac.New(sha256.New, []byte(key.User(payload.ID, payload.AppID)))
|
||||
hmacCipher.Write([]byte(A + "." + B))
|
||||
tempC := hmacCipher.Sum(nil)
|
||||
if !hmac.Equal([]byte(C), []byte(base64.StdEncoding.EncodeToString(tempC))) {
|
||||
return false, nil
|
||||
}
|
||||
if time.Now().Unix() > payload.Exp {
|
||||
return false, ExpiredToken
|
||||
}
|
||||
return true, nil
|
||||
return jwt.ParseToken(token, payload, []byte(key.User(payload.ID, payload.AppID)))
|
||||
}
|
||||
|
||||
@ -29,14 +29,17 @@ type App struct {
|
||||
UserRefreshUrl string `json:"user_refresh_url"`
|
||||
// app 校验用户token时使用
|
||||
Key string `json:"-"`
|
||||
// 是否允许用户自主注册
|
||||
EnableRegister bool `json:"enable_register"`
|
||||
EnableUserKey bool `json:"enable_user_key"`
|
||||
EnableUser bool `json:"enable_user"`
|
||||
EnableWx bool `json:"enable_wx"`
|
||||
EnablePhone bool `json:"enable_phone"`
|
||||
EnableEmail bool `json:"enable_email"`
|
||||
Wx *Wechat `json:"wx" gorm:"foreignkey:AppID;references:ID"`
|
||||
// 是否允许用户自动加入应用
|
||||
EnableRegister bool `json:"enable_register"`
|
||||
//
|
||||
EnableUserKey bool `json:"enable_user_key"`
|
||||
UserKeyUrl string `json:"user_key_url"`
|
||||
// 允许登录方式
|
||||
EnableUser bool `json:"enable_user"`
|
||||
EnableWx bool `json:"enable_wx"`
|
||||
EnablePhone bool `json:"enable_phone"`
|
||||
EnableEmail bool `json:"enable_email"`
|
||||
Wx *Wechat `json:"wx" gorm:"foreignkey:AppID;references:ID"`
|
||||
}
|
||||
|
||||
type AppUser struct {
|
||||
|
||||
11
models/message.go
Normal file
11
models/message.go
Normal file
@ -0,0 +1,11 @@
|
||||
package models
|
||||
|
||||
type Message struct {
|
||||
BaseModel
|
||||
UserID uint `json:"user_id"`
|
||||
User *User `json:"user"`
|
||||
Title string `json:"title"`
|
||||
Redirect string `json:"redirect"`
|
||||
Content string `json:"content"`
|
||||
From string `json:"from"`
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
> 1%
|
||||
last 2 versions
|
||||
not dead
|
||||
@ -1,5 +0,0 @@
|
||||
[*.{js,jsx,ts,tsx,vue}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
@ -1 +0,0 @@
|
||||
src/libs/wwLogin.js
|
||||
@ -1,22 +0,0 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
node: true
|
||||
},
|
||||
extends: [
|
||||
'plugin:vue/essential',
|
||||
'@vue/standard',
|
||||
'@vue/typescript/recommended'
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: 2020
|
||||
},
|
||||
rules: {
|
||||
'object-curly-spacing': 0,
|
||||
'space-before-function-paren': 0,
|
||||
'@typescript-eslint/camelcase': 0,
|
||||
'@typescript-eslint/no-empty-function': 0,
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
|
||||
}
|
||||
}
|
||||
26
oaf/.gitignore
vendored
26
oaf/.gitignore
vendored
@ -1,23 +1,5 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
.DS_Store
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
3
oaf/.vscode/extensions.json
vendored
Normal file
3
oaf/.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"recommendations": ["johnsoncodehk.volar"]
|
||||
}
|
||||
@ -1,24 +1,11 @@
|
||||
# oaf
|
||||
# Vue 3 + Typescript + Vite
|
||||
|
||||
## Project setup
|
||||
```
|
||||
yarn install
|
||||
```
|
||||
This template should help get you started developing with Vue 3 and Typescript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
```
|
||||
yarn serve
|
||||
```
|
||||
## Recommended IDE Setup
|
||||
|
||||
### Compiles and minifies for production
|
||||
```
|
||||
yarn build
|
||||
```
|
||||
- [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar)
|
||||
|
||||
### Lints and fixes files
|
||||
```
|
||||
yarn lint
|
||||
```
|
||||
## Type Support For `.vue` Imports in TS
|
||||
|
||||
### Customize configuration
|
||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
||||
Since TypeScript cannot handle type information for `.vue` imports, they are shimmed to be a generic Vue component type by default. In most cases this is fine if you don't really care about component prop types outside of templates. However, if you wish to get actual prop types in `.vue` imports (for example to get props validation when using manual `h(...)` calls), you can enable Volar's `.vue` type support plugin by running `Volar: Switch TS Plugin on/off` from VSCode command palette.
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
]
|
||||
}
|
||||
13
oaf/index.html
Normal file
13
oaf/index.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite App</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
@ -1,49 +1,29 @@
|
||||
{
|
||||
"name": "oaf",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint"
|
||||
"dev": "vite",
|
||||
"build": "vue-tsc --noEmit && vite build",
|
||||
"serve": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@veypi/one-icon": "^1.0.1",
|
||||
"axios": "^0.21.1",
|
||||
"core-js": "^3.6.5",
|
||||
"js-base64": "^3.6.0",
|
||||
"vue": "^2.6.11",
|
||||
"vue-class-component": "^7.2.3",
|
||||
"vue-m-message": "^3.1.0",
|
||||
"vue-property-decorator": "^9.1.2",
|
||||
"vue-router": "^3.2.0",
|
||||
"vuetify": "^2.4.0",
|
||||
"vuex": "^3.4.0"
|
||||
"@veypi/one-icon": "2",
|
||||
"axios": "^0.24.0",
|
||||
"js-base64": "^3.7.2",
|
||||
"vue": "^3.2.16",
|
||||
"vue-router": "^4.0.12",
|
||||
"vuex": "^4.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^2.33.0",
|
||||
"@typescript-eslint/parser": "^2.33.0",
|
||||
"@vue/cli-plugin-babel": "~4.5.0",
|
||||
"@vue/cli-plugin-eslint": "~4.5.0",
|
||||
"@vue/cli-plugin-router": "~4.5.0",
|
||||
"@vue/cli-plugin-typescript": "~4.5.0",
|
||||
"@vue/cli-plugin-vuex": "~4.5.0",
|
||||
"@vue/cli-service": "~4.5.0",
|
||||
"@vue/eslint-config-standard": "^5.1.2",
|
||||
"@vue/eslint-config-typescript": "^5.0.2",
|
||||
"eslint": "^6.7.2",
|
||||
"eslint-plugin-import": "^2.20.2",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^4.0.0",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"less": "^3.0.4",
|
||||
"less-loader": "^5.0.0",
|
||||
"sass": "^1.32.0",
|
||||
"sass-loader": "^10.0.0",
|
||||
"typescript": "~3.9.3",
|
||||
"vue-cli-plugin-vuetify": "^2.2.2",
|
||||
"vue-template-compiler": "^2.6.11",
|
||||
"vuetify-loader": "^1.7.0"
|
||||
"@tailwindcss/postcss7-compat": "^2.1.0",
|
||||
"@vitejs/plugin-vue": "^1.9.3",
|
||||
"autoprefixer": "^9.8.8",
|
||||
"naive-ui": "^2.19.11",
|
||||
"postcss": "^7.0.39",
|
||||
"tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.2.17",
|
||||
"typescript": "^4.4.3",
|
||||
"vfonts": "^0.1.0",
|
||||
"vite": "^2.6.4",
|
||||
"vue-tsc": "^0.3.0"
|
||||
}
|
||||
}
|
||||
|
||||
1
oaf/public/icon.js
Normal file
1
oaf/public/icon.js
Normal file
File diff suppressed because one or more lines are too long
@ -1,20 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<!-- <link rel="icon" href="<%= BASE_URL %>favicon.ico">-->
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
|
||||
Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
||||
119
oaf/src/App.vue
119
oaf/src/App.vue
@ -1,39 +1,88 @@
|
||||
<template>
|
||||
<v-app>
|
||||
<v-app-bar
|
||||
app
|
||||
color="primary"
|
||||
dark
|
||||
>
|
||||
<div class="d-flex align-center">
|
||||
<one-icon style="color: aqua;font-size: 56px">glassdoor</one-icon>
|
||||
<span class="font-italic font-weight-bold" style="font-size: 20px">统一认证</span>
|
||||
</div>
|
||||
<v-spacer></v-spacer>
|
||||
</v-app-bar>
|
||||
<script setup lang="ts">
|
||||
// This starter template is using Vue 3 <script setup> SFCs
|
||||
import { onBeforeMount, ref} from 'vue'
|
||||
import util from './libs/util'
|
||||
import {store} from "./store";
|
||||
import {useOsTheme} from 'naive-ui'
|
||||
|
||||
<v-main>
|
||||
<router-view></router-view>
|
||||
</v-main>
|
||||
</v-app>
|
||||
</template>
|
||||
const osThemeRef = useOsTheme()
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue'
|
||||
import util from '@/libs/util'
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'App',
|
||||
|
||||
components: {},
|
||||
|
||||
data: () => ({
|
||||
//
|
||||
}),
|
||||
|
||||
beforeCreate() {
|
||||
util.title('统一认证')
|
||||
this.$store.dispatch('fetchSelf')
|
||||
}
|
||||
onBeforeMount(() => {
|
||||
util.title("统一认证")
|
||||
store.dispatch('fetchSelf')
|
||||
store.commit('setTheme', osThemeRef.value)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n-config-provider :theme="store.getters.GetTheme" class="h-full w-full">
|
||||
<n-layout class="h-full w-full font-sans select-none">
|
||||
<n-layout has-sider style="height: calc(100% - 24px)">
|
||||
<n-layout-sider
|
||||
class="h-full"
|
||||
collapse-mode="transform"
|
||||
:collapsed-width="0"
|
||||
:width="120"
|
||||
show-trigger="bar"
|
||||
content-style="padding: 24px;"
|
||||
bordered
|
||||
default-collapsed
|
||||
>
|
||||
-
|
||||
</n-layout-sider>
|
||||
<n-layout>
|
||||
<n-layout-header bordered style="height: 64px;line-height: 64px;">
|
||||
{{ osThemeRef }}
|
||||
<one-icon @click="store.dispatch('changeTheme')" class="float-right" style="font-size: 36px; margin: 14px">
|
||||
{{ store.getters.IsDark ? 'Daytimemode' : 'nightmode-fill' }}
|
||||
</one-icon>
|
||||
</n-layout-header>
|
||||
<n-layout style="height: calc(100% - 64px)">
|
||||
<router-view class="h-full w-full"></router-view>
|
||||
</n-layout>
|
||||
</n-layout>
|
||||
</n-layout>
|
||||
<n-layout-footer style="height: 24px;line-height: 24px" class="flex justify-around px-3 text-gray-500 text-xs">
|
||||
<span class="hover:text-black cursor-pointer">关于OA</span>
|
||||
<span class="hover:text-black cursor-pointer">使用须知</span>
|
||||
<span class="hover:text-black cursor-pointer">
|
||||
©2021 veypi
|
||||
</span>
|
||||
</n-layout-footer>
|
||||
</n-layout>
|
||||
</n-config-provider>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* 周围滑动留白 */
|
||||
html {
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow: auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#app {
|
||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
color: #2c3e50;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
display: none; /* Chrome Safari */
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,65 +1,66 @@
|
||||
// @ts-ignore
|
||||
import axios from 'axios'
|
||||
import store from '@/store'
|
||||
import {store} from '../store'
|
||||
|
||||
|
||||
function baseRequests(url: string, method: any = 'GET', query: any, data: any, success: any, fail?: Function) {
|
||||
return axios({
|
||||
url: url,
|
||||
params: query,
|
||||
data: data,
|
||||
method: method,
|
||||
headers: {
|
||||
auth_token: localStorage.auth_token
|
||||
}
|
||||
})
|
||||
.then((res: any) => {
|
||||
if ('auth_token' in res.headers) {
|
||||
localStorage.auth_token = res.headers.auth_token
|
||||
}
|
||||
if (method === 'HEAD') {
|
||||
success(res.headers)
|
||||
} else {
|
||||
success(res.data)
|
||||
}
|
||||
})
|
||||
.catch((e: any) => {
|
||||
if (e.response && e.response.status === 401) {
|
||||
console.log(e)
|
||||
store.dispatch('handleLogOut')
|
||||
return
|
||||
}
|
||||
console.log(e)
|
||||
if (e.response && e.response.status === 500) {
|
||||
return
|
||||
}
|
||||
if (typeof fail === 'function') {
|
||||
fail(e.response)
|
||||
} else if (e.response && e.response.status === 400) {
|
||||
console.log(400)
|
||||
} else {
|
||||
console.log(e.request)
|
||||
}
|
||||
})
|
||||
return axios({
|
||||
url: url,
|
||||
params: query,
|
||||
data: data,
|
||||
method: method,
|
||||
headers: {
|
||||
auth_token: localStorage.auth_token
|
||||
}
|
||||
}).then((res: any) => {
|
||||
if ('auth_token' in res.headers) {
|
||||
localStorage.auth_token = res.headers.auth_token
|
||||
}
|
||||
if (method === 'HEAD') {
|
||||
success(res.headers)
|
||||
} else {
|
||||
success(res.data)
|
||||
}
|
||||
})
|
||||
.catch((e: any) => {
|
||||
if (e.response && e.response.status === 401) {
|
||||
console.log(e)
|
||||
store.dispatch('handleLogout')
|
||||
return
|
||||
}
|
||||
console.log(e)
|
||||
if (e.response && e.response.status === 500) {
|
||||
return
|
||||
}
|
||||
if (typeof fail === 'function') {
|
||||
fail(e.response)
|
||||
} else if (e.response && e.response.status === 400) {
|
||||
console.log(400)
|
||||
} else {
|
||||
console.log(e.request)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const ajax = {
|
||||
get(url: '', data = {}, success = {}, fail?: Function) {
|
||||
return baseRequests(url, 'GET', data, {}, success, fail)
|
||||
},
|
||||
head(url: '', data = {}, success = {}, fail?: Function) {
|
||||
return baseRequests(url, 'HEAD', data, {}, success, fail)
|
||||
},
|
||||
delete(url: '', data = {}, success = {}, fail?: Function) {
|
||||
return baseRequests(url, 'DELETE', data, {}, success, fail)
|
||||
},
|
||||
post(url: '', data = {}, success = {}, fail?: Function) {
|
||||
return baseRequests(url, 'POST', {}, data, success, fail)
|
||||
},
|
||||
put(url: '', data = {}, success = {}, fail?: Function) {
|
||||
return baseRequests(url, 'PUT', {}, data, success, fail)
|
||||
},
|
||||
patch(url: '', data = {}, success = {}, fail?: Function) {
|
||||
return baseRequests(url, 'PATCH', {}, data, success, fail)
|
||||
}
|
||||
get(url: '', data = {}, success = {}, fail?: Function) {
|
||||
return baseRequests(url, 'GET', data, {}, success, fail)
|
||||
},
|
||||
head(url: '', data = {}, success = {}, fail?: Function) {
|
||||
return baseRequests(url, 'HEAD', data, {}, success, fail)
|
||||
},
|
||||
delete(url: '', data = {}, success = {}, fail?: Function) {
|
||||
return baseRequests(url, 'DELETE', data, {}, success, fail)
|
||||
},
|
||||
post(url: '', data = {}, success = {}, fail?: Function) {
|
||||
return baseRequests(url, 'POST', {}, data, success, fail)
|
||||
},
|
||||
put(url: '', data = {}, success = {}, fail?: Function) {
|
||||
return baseRequests(url, 'PUT', {}, data, success, fail)
|
||||
},
|
||||
patch(url: '', data = {}, success = {}, fail?: Function) {
|
||||
return baseRequests(url, 'PATCH', {}, data, success, fail)
|
||||
}
|
||||
}
|
||||
|
||||
export default ajax
|
||||
|
||||
@ -4,213 +4,107 @@
|
||||
* Distributed under terms of the MIT license.
|
||||
*/
|
||||
|
||||
import Vue from 'vue'
|
||||
import {Base64} from 'js-base64'
|
||||
import {App} from 'vue'
|
||||
import ajax from './ajax'
|
||||
import store from '@/store'
|
||||
import {store} from '../store'
|
||||
import {Base64} from 'js-base64'
|
||||
|
||||
|
||||
|
||||
export type SuccessFunction<T> = (e: any) => void;
|
||||
export type FailedFunction<T> = (e: any) => void;
|
||||
|
||||
const Code = {
|
||||
42011: '无操作权限',
|
||||
22031: '资源不存在 或 您无权操作该资源'
|
||||
42011: '无操作权限',
|
||||
22031: '资源不存在 或 您无权操作该资源'
|
||||
}
|
||||
|
||||
class Interface {
|
||||
private readonly method: Function
|
||||
private readonly api: string
|
||||
private readonly data: any
|
||||
private readonly method: Function
|
||||
private readonly api: string
|
||||
private readonly data: any
|
||||
|
||||
constructor(method: Function, api: string, data?: any) {
|
||||
this.method = method
|
||||
this.api = api
|
||||
this.data = data
|
||||
}
|
||||
|
||||
Start(success: SuccessFunction<any>, fail?: FailedFunction<any>) {
|
||||
const newFail = function (data: any) {
|
||||
if (data && data.code === 40001) {
|
||||
// no login
|
||||
store.dispatch('handleLogout')
|
||||
return
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
||||
// @ts-ignore
|
||||
if (data && data.code > 0 && Code[data.code]) {
|
||||
}
|
||||
if (fail) {
|
||||
fail(data)
|
||||
}
|
||||
constructor(method: Function, api: string, data?: any) {
|
||||
this.method = method
|
||||
this.api = api
|
||||
this.data = data
|
||||
}
|
||||
|
||||
const newSuccess = function (data: any) {
|
||||
if (Number(data.status) === 1) {
|
||||
if (success) {
|
||||
success(data.content)
|
||||
Start(success: SuccessFunction<any>, fail?: FailedFunction<any>) {
|
||||
const newFail = function (data: any) {
|
||||
if (data && data.code === 40001) {
|
||||
// no login
|
||||
store.dispatch('handleLogout')
|
||||
return
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
||||
// @ts-ignore
|
||||
if (data && data.code > 0 && Code[data.code]) {
|
||||
}
|
||||
if (fail) {
|
||||
fail(data)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
newFail(data)
|
||||
if (data.code === 41001) {
|
||||
store.dispatch('handleLogout')
|
||||
// bus.$emit('log_out')
|
||||
|
||||
const newSuccess = function (data: any) {
|
||||
if (Number(data.status) === 1) {
|
||||
if (success) {
|
||||
success(data.content)
|
||||
}
|
||||
} else {
|
||||
newFail(data)
|
||||
if (data.code === 41001) {
|
||||
store.dispatch('handleLogout')
|
||||
// bus.$emit('log_out')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.method(this.api, this.data, newSuccess, newFail)
|
||||
}
|
||||
this.method(this.api, this.data, newSuccess, newFail)
|
||||
}
|
||||
}
|
||||
|
||||
const message = {
|
||||
count() {
|
||||
return new Interface(ajax.get, '/api/message/', {
|
||||
count: true,
|
||||
status: 'UnRead'
|
||||
})
|
||||
},
|
||||
get_content(id: number) {
|
||||
return new Interface(ajax.get, '/api/message/' + Number(id))
|
||||
},
|
||||
list(status: string) {
|
||||
return new Interface(ajax.get, '/api/message/', {status})
|
||||
},
|
||||
update(id: number, status: string) {
|
||||
return new Interface(ajax.patch, '/api/message/' + Number(id), {status})
|
||||
}
|
||||
}
|
||||
|
||||
const role = {
|
||||
local: '/api/role/',
|
||||
get(id: number) {
|
||||
return new Interface(ajax.get, this.local + id)
|
||||
},
|
||||
list() {
|
||||
return new Interface(ajax.get, this.local)
|
||||
},
|
||||
update(id: number, props: any) {
|
||||
return new Interface(ajax.patch, this.local + id, props)
|
||||
},
|
||||
create(props: any) {
|
||||
return new Interface(ajax.post, this.local, props)
|
||||
},
|
||||
del(id: number) {
|
||||
return new Interface(ajax.delete, this.local + id)
|
||||
},
|
||||
bind(id: number, aid: number) {
|
||||
return new Interface(ajax.get, this.local + id + '/bind/' + aid)
|
||||
},
|
||||
unbind(id: number, aid: number) {
|
||||
return new Interface(ajax.get, this.local + id + '/unbind/' + aid)
|
||||
}
|
||||
}
|
||||
|
||||
const app = {
|
||||
local: '/api/app/',
|
||||
self() {
|
||||
return new Interface(ajax.get, this.local, {is_self: true})
|
||||
},
|
||||
get(id: string) {
|
||||
return new Interface(ajax.get, this.local + id)
|
||||
},
|
||||
list() {
|
||||
return new Interface(ajax.get, this.local)
|
||||
}
|
||||
local: '/api/app/',
|
||||
self() {
|
||||
return new Interface(ajax.get, this.local, {is_self: true})
|
||||
},
|
||||
get(id: string) {
|
||||
return new Interface(ajax.get, this.local + id)
|
||||
},
|
||||
list() {
|
||||
return new Interface(ajax.get, this.local)
|
||||
}
|
||||
}
|
||||
|
||||
const user = {
|
||||
local: '/api/user/',
|
||||
register(username: string, password: string, uuid: string, prop?: any) {
|
||||
const data = Object.assign({
|
||||
username: username,
|
||||
uuid: uuid,
|
||||
password: Base64.encode(password)
|
||||
}, prop)
|
||||
return new Interface(ajax.post, this.local, data)
|
||||
},
|
||||
login(username: string, password: string, uuid: string) {
|
||||
return new Interface(ajax.head, this.local + username, {
|
||||
uid_type: 'username',
|
||||
uuid: uuid,
|
||||
password: Base64.encode(password)
|
||||
})
|
||||
}
|
||||
local: '/api/user/',
|
||||
register(username: string, password: string, uuid: string, prop?: any) {
|
||||
const data = Object.assign({
|
||||
username: username,
|
||||
uuid: uuid,
|
||||
password: Base64.encode(password)
|
||||
}, prop)
|
||||
return new Interface(ajax.post, this.local, data)
|
||||
},
|
||||
login(username: string, password: string, uuid: string) {
|
||||
return new Interface(ajax.head, this.local + username, {
|
||||
uid_type: 'username',
|
||||
uuid: uuid,
|
||||
password: Base64.encode(password)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const api = {
|
||||
role: role,
|
||||
app: app,
|
||||
user: user,
|
||||
admin: {
|
||||
auths() {
|
||||
return new Interface(ajax.get, '/api/auth/')
|
||||
},
|
||||
user: {
|
||||
create(props: any) {
|
||||
const p = Object.assign({}, props)
|
||||
p.password = Base64.encode(props.password)
|
||||
return new Interface(ajax.post, '/api/user/', p)
|
||||
},
|
||||
update(user_id: number, props: any) {
|
||||
return new Interface(ajax.patch, '/api/user/' + user_id, props)
|
||||
},
|
||||
enable(user_id: number) {
|
||||
return new Interface(ajax.patch, '/api/user/' + user_id, {
|
||||
status: 'ok'
|
||||
})
|
||||
},
|
||||
disable(user_id: number) {
|
||||
return new Interface(ajax.patch, '/api/user/' + user_id, {
|
||||
status: 'disabled'
|
||||
})
|
||||
},
|
||||
attach_role(user_id: number, props: any) {
|
||||
return new Interface(ajax.post, '/api/user/' + user_id + '/role/', props)
|
||||
},
|
||||
detach_role(user_id: number, id: any) {
|
||||
return new Interface(ajax.delete, '/api/user/' + user_id + '/role/' + id)
|
||||
},
|
||||
reset_pass(user_id: number, password: string) {
|
||||
return new Interface(ajax.patch, '/api/user/' + user_id, {password})
|
||||
}
|
||||
}
|
||||
},
|
||||
auth: {
|
||||
event() {
|
||||
return {
|
||||
local: '/api/user/event/',
|
||||
list() {
|
||||
return new Interface(ajax.get, this.local)
|
||||
},
|
||||
create(title: string, tag: string, start_date: any, end_date: any) {
|
||||
return new Interface(ajax.post, this.local, {title, tag, start_date, end_date})
|
||||
},
|
||||
del(id: number) {
|
||||
return new Interface(ajax.delete, this.local + id)
|
||||
}
|
||||
}
|
||||
},
|
||||
favorite(name: string, tag: string, ok: boolean) {
|
||||
if (ok) {
|
||||
return new Interface(ajax.post, '/api/user/favorite', {name, tag})
|
||||
}
|
||||
return new Interface(ajax.delete, '/api/user/favorite', {name, tag})
|
||||
},
|
||||
get(id: number) {
|
||||
return new Interface(ajax.get, '/api/user/' + id)
|
||||
},
|
||||
search(username: string) {
|
||||
return new Interface(ajax.get, '/api/user/', {
|
||||
username
|
||||
})
|
||||
}
|
||||
},
|
||||
message: message
|
||||
user: user,
|
||||
app: app
|
||||
}
|
||||
|
||||
const Api = {
|
||||
install(vue: typeof Vue): void {
|
||||
vue.prototype.$api = api
|
||||
}
|
||||
install(vue: App): void {
|
||||
vue.config.globalProperties.$api = api
|
||||
}
|
||||
}
|
||||
export {Api}
|
||||
export default api
|
||||
|
||||
@ -1 +0,0 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 87.5 100"><defs><style>.cls-1{fill:#1697f6;}.cls-2{fill:#7bc6ff;}.cls-3{fill:#1867c0;}.cls-4{fill:#aeddff;}</style></defs><title>Artboard 46</title><polyline class="cls-1" points="43.75 0 23.31 0 43.75 48.32"/><polygon class="cls-2" points="43.75 62.5 43.75 100 0 14.58 22.92 14.58 43.75 62.5"/><polyline class="cls-3" points="43.75 0 64.19 0 43.75 48.32"/><polygon class="cls-4" points="64.58 14.58 87.5 14.58 43.75 100 43.75 62.5 64.58 14.58"/></svg>
|
||||
|
Before Width: | Height: | Size: 539 B |
52
oaf/src/components/HelloWorld.vue
Normal file
52
oaf/src/components/HelloWorld.vue
Normal file
@ -0,0 +1,52 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
|
||||
defineProps<{ msg: string }>()
|
||||
|
||||
const count = ref(0)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>{{ msg }}</h1>
|
||||
|
||||
<p>
|
||||
Recommended IDE setup:
|
||||
<a href="https://code.visualstudio.com/" target="_blank">VSCode</a>
|
||||
+
|
||||
<a href="https://github.com/johnsoncodehk/volar" target="_blank">Volar</a>
|
||||
</p>
|
||||
|
||||
<p>See <code>README.md</code> for more information.</p>
|
||||
|
||||
<p>
|
||||
<a href="https://vitejs.dev/guide/features.html" target="_blank">
|
||||
Vite Docs
|
||||
</a>
|
||||
|
|
||||
<a href="https://v3.vuejs.org/" target="_blank">Vue 3 Docs</a>
|
||||
</p>
|
||||
|
||||
<button type="button" @click="count++">count is: {{ count }}</button>
|
||||
<p>
|
||||
Edit
|
||||
<code>components/HelloWorld.vue</code> to test hot module replacement.
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
a {
|
||||
color: #42b983;
|
||||
}
|
||||
|
||||
label {
|
||||
margin: 0 0.5em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: #eee;
|
||||
padding: 2px 4px;
|
||||
border-radius: 4px;
|
||||
color: #304455;
|
||||
}
|
||||
</style>
|
||||
@ -1,43 +1,32 @@
|
||||
<template>
|
||||
<div id="wx_reg"></div>
|
||||
</template>
|
||||
<script lang='ts'>
|
||||
import {Component, Vue, Prop} from 'vue-property-decorator'
|
||||
import '@/libs/wwLogin.js'
|
||||
<script setup lang='ts'>
|
||||
import {onMounted} from 'vue'
|
||||
|
||||
@Component({
|
||||
components: {}
|
||||
})
|
||||
export default class WxLogin extends Vue {
|
||||
goto(id: string, app: string, url: string, state?: number, href?: string) {
|
||||
// eslint-disable-next-line
|
||||
// @ts-ignore
|
||||
window.WwLogin({
|
||||
id: 'wx_reg',
|
||||
appid: id,
|
||||
agentid: app,
|
||||
redirect_uri: encodeURIComponent(url),
|
||||
state: state,
|
||||
href: href
|
||||
})
|
||||
}
|
||||
|
||||
@Prop({default: ''})
|
||||
aid = ''
|
||||
|
||||
@Prop({default: ''})
|
||||
app = ''
|
||||
|
||||
@Prop({default: ''})
|
||||
url = ''
|
||||
|
||||
mounted() {
|
||||
this.goto(this.aid, this.app, this.url, new Date().getTime())
|
||||
}
|
||||
|
||||
created() {
|
||||
}
|
||||
function goto(id: string, app: string, url: string, state?: number, href?: string) {
|
||||
// eslint-disable-next-line
|
||||
// @ts-ignore
|
||||
window.WwLogin({
|
||||
id: 'wx_reg',
|
||||
appid: id,
|
||||
agentid: app,
|
||||
redirect_uri: encodeURIComponent(url),
|
||||
state: state,
|
||||
href: href
|
||||
})
|
||||
}
|
||||
|
||||
let aid = ''
|
||||
|
||||
let app = ''
|
||||
|
||||
let url = ''
|
||||
|
||||
onMounted(() => {
|
||||
goto(aid, app, url, new Date().getTime())
|
||||
})
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
|
||||
@ -1,20 +0,0 @@
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
<script lang='ts'>
|
||||
import {Component, Vue} from 'vue-property-decorator'
|
||||
|
||||
@Component({
|
||||
components: {}
|
||||
})
|
||||
export default class Demo extends Vue {
|
||||
mounted() {
|
||||
}
|
||||
|
||||
created() {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -1,28 +0,0 @@
|
||||
<template>
|
||||
<svg class="icon" aria-hidden="true">
|
||||
<use :xlink:href="'#icon-'+icon"></use>
|
||||
</svg>
|
||||
</template>
|
||||
<script lang='ts'>
|
||||
import {Component, Vue} from 'vue-property-decorator'
|
||||
|
||||
@Component({
|
||||
components: {}
|
||||
})
|
||||
export default class OneIcon extends Vue {
|
||||
get icon() {
|
||||
if (this.$slots.default) return this.$slots.default[0].text?.trim()
|
||||
console.warn('blank icon name')
|
||||
return ''
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
@ -1,26 +0,0 @@
|
||||
import Vue from 'vue'
|
||||
import OneIcon from './icon.vue'
|
||||
|
||||
function loadJS(url: string) {
|
||||
const script = document.createElement('script')
|
||||
script.type = 'text/javascript'
|
||||
script.src = url
|
||||
document.getElementsByTagName('head')[0].appendChild(script)
|
||||
}
|
||||
|
||||
export default {
|
||||
installed: false,
|
||||
install(vue: typeof Vue, options?: { href: '' }): void {
|
||||
if (this.installed) {
|
||||
return
|
||||
}
|
||||
this.installed = true
|
||||
if (options && options.href) {
|
||||
console.log(options.href)
|
||||
loadJS(options.href)
|
||||
} else {
|
||||
console.error('not set iconfont href')
|
||||
}
|
||||
vue.component('one-icon', OneIcon)
|
||||
}
|
||||
}
|
||||
8
oaf/src/env.d.ts
vendored
Normal file
8
oaf/src/env.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
declare module '*.vue' {
|
||||
import { DefineComponent } from 'vue'
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
|
||||
const component: DefineComponent<{}, {}, any>
|
||||
export default component
|
||||
}
|
||||
6
oaf/src/index.css
Normal file
6
oaf/src/index.css
Normal file
@ -0,0 +1,6 @@
|
||||
/* ./src/index.css */
|
||||
|
||||
/*! @import */
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@ -1,24 +1,17 @@
|
||||
import Vue from 'vue'
|
||||
import {createApp} from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import store from './store'
|
||||
import vuetify from './plugins/vuetify'
|
||||
import {Api} from '@/api'
|
||||
import {store, key} from './store'
|
||||
import OneIcon from '@veypi/one-icon'
|
||||
import Message from 'vue-m-message'
|
||||
import 'vue-m-message/dist/index.css'
|
||||
import naive from 'naive-ui'
|
||||
import './index.css'
|
||||
import {Api} from './api'
|
||||
|
||||
Vue.use(Message) // will mount `Vue.prototype.$message`
|
||||
const app = createApp(App)
|
||||
|
||||
// Vue.use(OneIcon, {href: 'https://at.alicdn.com/t/font_2872366_7aws02sx9bl.js'})
|
||||
Vue.use(OneIcon, {href: './icon.js'})
|
||||
Vue.use(Api)
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
new Vue({
|
||||
router,
|
||||
store,
|
||||
vuetify,
|
||||
render: h => h(App)
|
||||
}).$mount('#app')
|
||||
app.use(Api)
|
||||
app.use(naive)
|
||||
app.use(OneIcon, {href: './icon.js'})
|
||||
app.use(router)
|
||||
app.use(store, key)
|
||||
app.mount('#app')
|
||||
|
||||
@ -1,24 +0,0 @@
|
||||
import Vue from 'vue'
|
||||
import Vuetify from 'vuetify/lib/framework'
|
||||
|
||||
Vue.use(Vuetify)
|
||||
|
||||
const light = {
|
||||
primary: '#2196f3',
|
||||
secondary: '#00bcd4',
|
||||
accent: '#3f51b5',
|
||||
error: '#f44336',
|
||||
warning: '#ff5722',
|
||||
info: '#ff9800',
|
||||
success: '#4caf50',
|
||||
reset: '#684bff'
|
||||
}
|
||||
|
||||
export default new Vuetify({
|
||||
theme: {
|
||||
dark: false,
|
||||
themes: {
|
||||
light: light
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -1,57 +1,70 @@
|
||||
import Vue from 'vue'
|
||||
import VueRouter, {RouteConfig} from 'vue-router'
|
||||
import Home from '../views/Home.vue'
|
||||
import Demo from '@/views/demo.vue'
|
||||
import Login from '@/views/login.vue'
|
||||
import Register from '@/views/register.vue'
|
||||
import NotFound from '@/views/404.vue'
|
||||
import {createRouter, createWebHistory} from 'vue-router'
|
||||
import util from '../libs/util'
|
||||
|
||||
Vue.use(VueRouter)
|
||||
// 避免push到相同路径报错
|
||||
// 获取原型对象上的push函数
|
||||
const originalPush = VueRouter.prototype.push
|
||||
// 修改原型对象中的push方法
|
||||
VueRouter.prototype.push = function push(location: any) {
|
||||
// eslint-disable-next-line
|
||||
// @ts-ignore
|
||||
return originalPush.call(this, location).catch(err => err)
|
||||
declare module 'vue-router' {
|
||||
interface RouteMeta {
|
||||
// 是可选的
|
||||
isAdmin?: boolean
|
||||
// 每个路由都必须声明
|
||||
requiresAuth: boolean
|
||||
}
|
||||
}
|
||||
|
||||
const routes: Array<RouteConfig> = [
|
||||
{
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: Home
|
||||
},
|
||||
{
|
||||
path: '/app',
|
||||
name: 'app',
|
||||
component: Demo
|
||||
},
|
||||
{
|
||||
path: '/login/:uuid?',
|
||||
name: 'login',
|
||||
component: Login
|
||||
},
|
||||
{
|
||||
path: '/register/:uuid?',
|
||||
name: 'register',
|
||||
component: Register
|
||||
},
|
||||
{
|
||||
path: '/wx',
|
||||
name: 'wx',
|
||||
component: () => import('../views/wx.vue')
|
||||
},
|
||||
{
|
||||
path: '*',
|
||||
name: '404',
|
||||
component: NotFound
|
||||
}
|
||||
]
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
name: 'home',
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
},
|
||||
component: () => import('../view/home.vue')
|
||||
},
|
||||
{
|
||||
path: '/app',
|
||||
name: 'app',
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
},
|
||||
component: () => import('../view/demo.vue')
|
||||
},
|
||||
{
|
||||
path: '/wx',
|
||||
name: 'wx',
|
||||
component: () => import('../view/wx.vue')
|
||||
},
|
||||
{
|
||||
path: '/login/:uuid?',
|
||||
name: 'login',
|
||||
component: () => import('../view/login.vue')
|
||||
},
|
||||
{
|
||||
path: '/register/:uuid?',
|
||||
name: 'register',
|
||||
component: () => import('../view/register.vue')
|
||||
},
|
||||
{
|
||||
path: '/:path(.*)',
|
||||
name: '404',
|
||||
component: () => import('../view/404.vue')
|
||||
}
|
||||
//...
|
||||
],
|
||||
})
|
||||
|
||||
const router = new VueRouter({
|
||||
routes
|
||||
router.beforeEach((to, from) => {
|
||||
// 而不是去检查每条路由记录
|
||||
// to.matched.some(record => record.meta.requiresAuth)
|
||||
if (to.meta.requiresAuth && !util.checkLogin()) {
|
||||
// 此路由需要授权,请检查是否已登录
|
||||
// 如果没有,则重定向到登录页面
|
||||
return {
|
||||
name: 'login',
|
||||
// 保存我们所在的位置,以便以后再来
|
||||
query: {redirect: to.fullPath},
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default router
|
||||
|
||||
13
oaf/src/shims-tsx.d.ts
vendored
13
oaf/src/shims-tsx.d.ts
vendored
@ -1,13 +0,0 @@
|
||||
import Vue, { VNode } from 'vue'
|
||||
|
||||
declare global {
|
||||
namespace JSX {
|
||||
// tslint:disable no-empty-interface
|
||||
interface Element extends VNode {}
|
||||
// tslint:disable no-empty-interface
|
||||
interface ElementClass extends Vue {}
|
||||
interface IntrinsicElements {
|
||||
[elem: string]: any;
|
||||
}
|
||||
}
|
||||
}
|
||||
5
oaf/src/shims-vue.d.ts
vendored
5
oaf/src/shims-vue.d.ts
vendored
@ -1,5 +0,0 @@
|
||||
declare module '*.js'
|
||||
declare module '*.vue' {
|
||||
import Vue from 'vue'
|
||||
export default Vue
|
||||
}
|
||||
4
oaf/src/shims-vuetify.d.ts
vendored
4
oaf/src/shims-vuetify.d.ts
vendored
@ -1,4 +0,0 @@
|
||||
declare module 'vuetify/lib/framework' {
|
||||
import Vuetify from 'vuetify'
|
||||
export default Vuetify
|
||||
}
|
||||
@ -1,30 +1,62 @@
|
||||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
import api from '@/api'
|
||||
import router from '@/router'
|
||||
import {InjectionKey} from 'vue'
|
||||
import {createStore, useStore as baseUseStore, Store} from 'vuex'
|
||||
import api from "../api";
|
||||
import router from "../router";
|
||||
import {darkTheme} from 'naive-ui'
|
||||
|
||||
Vue.use(Vuex)
|
||||
export interface State {
|
||||
oauuid: string
|
||||
user: object
|
||||
theme: string
|
||||
|
||||
export default new Vuex.Store({
|
||||
state: {
|
||||
oauuid: '',
|
||||
user: null
|
||||
},
|
||||
mutations: {
|
||||
setOA(state: any, data: any) {
|
||||
state.oauuid = data.uuid
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
fetchSelf({commit}) {
|
||||
api.app.self().Start(d => {
|
||||
commit('setOA', d)
|
||||
})
|
||||
}
|
||||
|
||||
export const key: InjectionKey<Store<State>> = Symbol()
|
||||
|
||||
export const store = createStore<State>({
|
||||
state: {
|
||||
theme: 'light',
|
||||
oauuid: '',
|
||||
user: {}
|
||||
},
|
||||
handleLogout() {
|
||||
localStorage.removeItem('auth_token')
|
||||
router.push({name: 'login'})
|
||||
getters: {
|
||||
IsDark(state: any) {
|
||||
return state.theme === 'dark'
|
||||
},
|
||||
GetTheme(state: any, getters) {
|
||||
return getters.IsDark ? darkTheme : null
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
setOA(state: any, data: any) {
|
||||
state.oauuid = data.uuid
|
||||
},
|
||||
setTheme(state: any, t: string) {
|
||||
state.theme = t
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
changeTheme(context) {
|
||||
if (context.getters.IsDark) {
|
||||
context.commit('setTheme', 'light')
|
||||
} else {
|
||||
context.commit('setTheme', 'dark')
|
||||
}
|
||||
},
|
||||
fetchSelf({commit}) {
|
||||
api.app.self().Start(d => {
|
||||
commit('setOA', d)
|
||||
})
|
||||
},
|
||||
handleLogout() {
|
||||
localStorage.removeItem('auth_token')
|
||||
router.push({name: 'login'})
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
modules: {}
|
||||
})
|
||||
|
||||
// 定义自己的 `useStore` 组合式函数
|
||||
export function useStore() {
|
||||
return baseUseStore(key)
|
||||
}
|
||||
|
||||
14
oaf/src/types/vue-prototype.d.ts
vendored
14
oaf/src/types/vue-prototype.d.ts
vendored
@ -1,14 +0,0 @@
|
||||
// 1. 确保在声明补充的类型之前导入 'vue'
|
||||
import Vue from 'vue'
|
||||
import api from '@/api'
|
||||
|
||||
export type PluginFunction<T> = (Vue: typeof Vue, options?: T) => void;
|
||||
|
||||
// 2. 定制一个文件,设置你想要补充的类型
|
||||
// 在 types/vue.d.ts 里 Vue 有构造函数类型
|
||||
declare module 'vue/types/vue' {
|
||||
// 3. 声明为 Vue 补充的东西
|
||||
interface Vue {
|
||||
$api: typeof api;
|
||||
}
|
||||
}
|
||||
32
oaf/src/view/404.vue
Normal file
32
oaf/src/view/404.vue
Normal file
@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<div class="flex justify-center items-center">
|
||||
<div class="text-center text-xl">
|
||||
<one-icon style="font-size: 200px">404</one-icon>
|
||||
<span>
|
||||
路径失效啦! {{count}}秒
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {useRouter, useRoute} from 'vue-router'
|
||||
import {onMounted, ref} from "vue";
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
let count = ref(5)
|
||||
onMounted(() => {
|
||||
console.log([route.path, route.params])
|
||||
let timer = setInterval(()=> {
|
||||
count.value--
|
||||
if (count.value === 0) {
|
||||
router.push('/')
|
||||
clearInterval(timer)
|
||||
}
|
||||
}, 1000)
|
||||
})
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
10
oaf/src/view/demo.vue
Normal file
10
oaf/src/view/demo.vue
Normal file
@ -0,0 +1,10 @@
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
10
oaf/src/view/file.vue
Normal file
10
oaf/src/view/file.vue
Normal file
@ -0,0 +1,10 @@
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
24
oaf/src/view/home.vue
Normal file
24
oaf/src/view/home.vue
Normal file
@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref} from "vue";
|
||||
import api from "../api";
|
||||
|
||||
let apps = ref([])
|
||||
|
||||
function getApps() {
|
||||
api.app.list().Start(e => {
|
||||
apps.value = e
|
||||
})
|
||||
}
|
||||
|
||||
getApps()
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
61
oaf/src/view/login.vue
Normal file
61
oaf/src/view/login.vue
Normal file
@ -0,0 +1,61 @@
|
||||
<template>
|
||||
<div class="flex items-center justify-center">
|
||||
<div class="p-3" style="">
|
||||
<n-form ref="formRef" label-placement="left">
|
||||
<n-form-item required label="username" :validation-status="rules.username[0]" :feedback="rules.username[1]">
|
||||
<n-input v-model:value="data.username"></n-input>
|
||||
</n-form-item>
|
||||
<n-form-item required label="username" :validation-status="rules.username[0]" :feedback="rules.username[1]">
|
||||
<n-input v-model:value="data.username"></n-input>
|
||||
</n-form-item>
|
||||
<n-button @click="login">登录</n-button>
|
||||
</n-form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {computed, ref} from "vue";
|
||||
|
||||
let formRef = ref(null)
|
||||
let data = ref({
|
||||
username: null,
|
||||
password: null
|
||||
})
|
||||
let ruleInline = {
|
||||
username: [
|
||||
(v: string) => !!v || 'required',
|
||||
(v: string) => (v && v.length >= 3 && v.length <= 16) || '长度要求3~16'
|
||||
],
|
||||
password: [
|
||||
(v: string) => !!v || 'required',
|
||||
(v: string) => (v && v.length >= 6 && v.length <= 16) || '长度要求6~16'
|
||||
]
|
||||
}
|
||||
|
||||
function check(rs: [], v: any) {
|
||||
for (let r of rs) {
|
||||
let res = r(v)
|
||||
if (res !== true) {
|
||||
return ['error', res]
|
||||
}
|
||||
}
|
||||
return ['', '']
|
||||
}
|
||||
|
||||
let rules = ref({
|
||||
username: computed(() => {
|
||||
return check(ruleInline.username, data.value.username)
|
||||
})
|
||||
})
|
||||
|
||||
function login() {
|
||||
formRef.value.validate(e => {
|
||||
console.log(e)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
10
oaf/src/view/register.vue
Normal file
10
oaf/src/view/register.vue
Normal file
@ -0,0 +1,10 @@
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
51
oaf/src/view/wx.vue
Normal file
51
oaf/src/view/wx.vue
Normal file
@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<div class='home d-flex justify-center align-center'>
|
||||
<wx-login v-if="enable" :aid="aid" :app="agentID" :url="url"></wx-login>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang='ts'>
|
||||
import WxLogin from '../components/WxLogin.vue'
|
||||
import {computed, onMounted} from "vue";
|
||||
import {useRoute} from 'vue-router'
|
||||
import api from '../api'
|
||||
|
||||
let route = useRoute()
|
||||
|
||||
let aid = ''
|
||||
let agentID = ''
|
||||
let url = ''
|
||||
let uuid = computed(() => {
|
||||
return route.query.uuid
|
||||
})
|
||||
let enable = computed(() => {
|
||||
return uuid && aid && agentID && url
|
||||
})
|
||||
let code = computed(() => {
|
||||
return route.query.code
|
||||
})
|
||||
|
||||
let state = computed(() => {
|
||||
return route.query.state
|
||||
})
|
||||
|
||||
let msg = computed(() => {
|
||||
return route.query.msg
|
||||
})
|
||||
onMounted(() => {
|
||||
if (msg) {
|
||||
console.log(msg)
|
||||
alert(msg)
|
||||
}
|
||||
})
|
||||
|
||||
if (uuid) {
|
||||
api.app.get(uuid.value as string).Start(e => {
|
||||
url = e.wx.url + '/api/wx/login/' + uuid
|
||||
aid = e.wx.corp_id
|
||||
agentID = e.wx.agent_id
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -1,24 +0,0 @@
|
||||
<style>
|
||||
</style>
|
||||
<template>
|
||||
<div class='home d-flex justify-center align-center'>
|
||||
<one-icon style="font-size: 100px">404</one-icon>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang='ts'>
|
||||
import {Component, Vue} from 'vue-property-decorator'
|
||||
import util from '@/libs/util'
|
||||
|
||||
@Component({
|
||||
components: {}
|
||||
})
|
||||
export default class NotFound extends Vue {
|
||||
mounted() {
|
||||
}
|
||||
|
||||
created() {
|
||||
util.title('404')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -1,43 +0,0 @@
|
||||
<style>
|
||||
.home {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div class='home d-flex justify-center align-center'>
|
||||
<one-icon style="color: aqua;font-size: 50px">glassdoor</one-icon>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang='ts'>
|
||||
import {Component, Vue} from 'vue-property-decorator'
|
||||
import util from '@/libs/util'
|
||||
|
||||
@Component({
|
||||
components: {}
|
||||
})
|
||||
export default class Home extends Vue {
|
||||
apps = []
|
||||
|
||||
getApps() {
|
||||
this.$api.app.list().Start(d => {
|
||||
console.log(d)
|
||||
this.apps = d
|
||||
})
|
||||
}
|
||||
|
||||
mounted() {
|
||||
this.getApps()
|
||||
}
|
||||
|
||||
created() {
|
||||
}
|
||||
|
||||
beforeCreate() {
|
||||
if (!util.checkLogin()) {
|
||||
this.$router.push({name: 'login', query: this.$route.query, params: this.$route.params})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -1,21 +0,0 @@
|
||||
<style>
|
||||
</style>
|
||||
<template>
|
||||
<div class='home d-flex justify-center align-center'>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang='ts'>
|
||||
import {Component, Vue} from 'vue-property-decorator'
|
||||
|
||||
@Component({
|
||||
components: {}
|
||||
})
|
||||
export default class Demo extends Vue {
|
||||
mounted() {
|
||||
}
|
||||
|
||||
created() {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -1,123 +0,0 @@
|
||||
<style>
|
||||
</style>
|
||||
<template>
|
||||
<v-row align="center" class="fill-height" justify="center" style="background: #ebebeb">
|
||||
<v-col cols="12" sm="8" md="6" lg="4" xl="3">
|
||||
<v-card class="elevation-12 mx-5" style="opacity: 0.8">
|
||||
<v-row justify="center">
|
||||
<v-col cols="10">
|
||||
<v-card class="elevation-1 mt-n12 primary theme--dark">
|
||||
<v-card-text class="text-center">
|
||||
<h1 class="display-2 font-weight-bold mb-2">Login</h1>
|
||||
<v-tooltip left>
|
||||
<template v-slot:activator="{ on }">
|
||||
<v-btn icon large v-on="on">
|
||||
<v-icon>mdi-cellphone</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<span style="font-family:'Noto Sans Armenian'">手机登录</span>
|
||||
</v-tooltip>
|
||||
<v-tooltip right>
|
||||
<template v-slot:activator="{ on }">
|
||||
<v-btn icon large v-on="on">
|
||||
<v-icon>mdi-barcode</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<span>授权码登录</span>
|
||||
</v-tooltip>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-card-text>
|
||||
<v-form ref="form">
|
||||
<v-text-field
|
||||
v-model="formInline.user"
|
||||
:counter="16"
|
||||
:rules="ruleInline.user"
|
||||
label="账号"
|
||||
required
|
||||
prepend-inner-icon="mdi-account-circle"
|
||||
></v-text-field>
|
||||
<v-text-field
|
||||
v-model="formInline.password"
|
||||
type="password"
|
||||
:counter="16"
|
||||
:rules="ruleInline.password"
|
||||
label="密码"
|
||||
prepend-inner-icon="mdi-lock"
|
||||
@keyup.enter="handleSubmit"
|
||||
required
|
||||
></v-text-field>
|
||||
</v-form>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer/>
|
||||
<v-btn type="primary" @click="handleSubmit">登录</v-btn>
|
||||
<router-link :to="{name: 'register', query:$route.query, params: $route.params}"
|
||||
style="text-decoration: none;">
|
||||
<v-btn type="primary" style="margin-left:8px">注册</v-btn>
|
||||
</router-link>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</template>
|
||||
|
||||
<script lang='ts'>
|
||||
import {Component, Vue} from 'vue-property-decorator'
|
||||
import util from '@/libs/util'
|
||||
|
||||
@Component({
|
||||
components: {}
|
||||
})
|
||||
export default class Login extends Vue {
|
||||
formInline = {
|
||||
user: '',
|
||||
password: ''
|
||||
}
|
||||
|
||||
ruleInline = {
|
||||
user: [
|
||||
(v: string) => !!v || 'required',
|
||||
(v: string) => (v && v.length >= 3 && v.length <= 16) || '长度要求3~16'
|
||||
],
|
||||
password: [
|
||||
(v: string) => !!v || 'required',
|
||||
(v: string) => (v && v.length >= 6 && v.length <= 16) || '长度要求6~16'
|
||||
]
|
||||
}
|
||||
|
||||
get app_uuid() {
|
||||
return this.$route.params.uuid || this.$store.state.oauuid
|
||||
}
|
||||
|
||||
handleSubmit() {
|
||||
// eslint-disable-next-line
|
||||
// @ts-ignore
|
||||
if (!this.$refs.form.validate()) {
|
||||
return
|
||||
}
|
||||
this.$api.user.login(this.formInline.user, this.formInline.password, this.app_uuid).Start(
|
||||
data => {
|
||||
console.log(data)
|
||||
if (util.checkLogin()) {
|
||||
// this.$message.success('登录成功')
|
||||
// EventBus.$emit('login', true)
|
||||
this.$nextTick(() => {
|
||||
if (this.$route.query.redirect) {
|
||||
window.location.href = this.$route.query.redirect as string
|
||||
}
|
||||
this.$router.push({name: 'home'})
|
||||
})
|
||||
} else {
|
||||
// this.$message.error('用户名或密码错误')
|
||||
}
|
||||
},
|
||||
() => {
|
||||
// this.$message.error('网络错误!')
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -1,124 +0,0 @@
|
||||
<style>
|
||||
</style>
|
||||
<template>
|
||||
<v-row class="fill-height" align="center" justify="center" style="background: #ebebeb">
|
||||
<v-col cols="12" sm="8" md="6" lg="4" xl="3">
|
||||
<v-card class="elevation-12 mx-5" style="opacity: 0.8">
|
||||
<v-row justify="center">
|
||||
<v-card class="elevation-1 mt-n7 primary" style="width: 80%">
|
||||
<v-card-actions>
|
||||
<v-row>
|
||||
<v-icon
|
||||
style="position: absolute;left: 10px;top:19px;z-index: 1"
|
||||
@click="$router.back()"
|
||||
size="36"
|
||||
>mdi-arrow-left-circle
|
||||
</v-icon>
|
||||
<v-col cols="12" class="text-center">
|
||||
<h1 class="display-2 ">注册</h1>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-row>
|
||||
<v-card-text class="text-center">
|
||||
<v-form ref="form">
|
||||
<v-text-field
|
||||
type="text"
|
||||
prepend-inner-icon="mdi-account-circle"
|
||||
v-model="form.username"
|
||||
label="账号"
|
||||
:rules="ruleInline.user"
|
||||
:counter="16"
|
||||
>
|
||||
</v-text-field>
|
||||
<v-text-field
|
||||
type="password"
|
||||
v-model="form.passwd"
|
||||
label="密码"
|
||||
prepend-inner-icon="mdi-lock"
|
||||
:rules="ruleInline.password"
|
||||
:counter="16"
|
||||
></v-text-field>
|
||||
<v-text-field
|
||||
type="password"
|
||||
v-model="form.passwdCheck"
|
||||
label="密码"
|
||||
prepend-inner-icon="mdi-lock"
|
||||
:rules="ruleInline.passwordCheck"
|
||||
:counter="16"
|
||||
@keyup.enter="handleSubmit"
|
||||
></v-text-field>
|
||||
</v-form>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn type="primary" @click="handleSubmit">提交</v-btn>
|
||||
<v-btn @click="handleReset()">重置</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</template>
|
||||
|
||||
<script lang='ts'>
|
||||
import {Component, Vue} from 'vue-property-decorator'
|
||||
|
||||
@Component({
|
||||
components: {}
|
||||
})
|
||||
export default class Register extends Vue {
|
||||
form = {
|
||||
passwd: '',
|
||||
passwdCheck: '',
|
||||
email: '',
|
||||
username: ''
|
||||
}
|
||||
|
||||
ruleInline = {
|
||||
user: [
|
||||
(v: string) => !!v || 'required',
|
||||
(v: string) => (v && v.length >= 3 && v.length <= 16) || '长度要求3~16'
|
||||
],
|
||||
password: [
|
||||
(v: string) => !!v || 'required',
|
||||
(v: string) => (v && v.length >= 6 && v.length <= 16) || '长度要求6~16'
|
||||
],
|
||||
passwordCheck: [
|
||||
(v: string) => !!v || 'required',
|
||||
(v: string) => (v && v === this.form.passwd) || '密码不一致'
|
||||
]
|
||||
}
|
||||
|
||||
get app_uuid() {
|
||||
return this.$route.params.uuid || this.$store.state.oauuid
|
||||
}
|
||||
|
||||
handleSubmit() {
|
||||
// eslint-disable-next-line
|
||||
// @ts-ignore
|
||||
if (!this.$refs.form.validate()) {
|
||||
return
|
||||
}
|
||||
this.$api.user.register(this.form.username, this.form.passwd, this.app_uuid).Start(
|
||||
(data) => {
|
||||
this.$message.success('注册成功!')
|
||||
this.$router.push({name: 'login', params: this.$route.params, query: this.$route.query})
|
||||
},
|
||||
(data) => {
|
||||
if (data && data.code === '31011') {
|
||||
this.$message.error('用户名重复')
|
||||
} else {
|
||||
this.$message.error('注册失败')
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
handleReset() {
|
||||
this.form.username = ''
|
||||
this.form.passwd = ''
|
||||
this.form.passwdCheck = ''
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -1,66 +0,0 @@
|
||||
<template>
|
||||
<div class='home d-flex justify-center align-center'>
|
||||
<wx-login v-if="enable" :aid="aid" :app="agentID" :url="url"></wx-login>
|
||||
<v-overlay :value="!enable">
|
||||
<v-progress-circular
|
||||
indeterminate
|
||||
size="64"
|
||||
></v-progress-circular>
|
||||
</v-overlay>
|
||||
</div>
|
||||
</template>
|
||||
<script lang='ts'>
|
||||
import {Component, Vue} from 'vue-property-decorator'
|
||||
import WxLogin from '@/components/WxLogin.vue'
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
WxLogin
|
||||
}
|
||||
})
|
||||
export default class Wx extends Vue {
|
||||
aid = ''
|
||||
agentID = ''
|
||||
url = ''
|
||||
|
||||
get enable() {
|
||||
return this.uuid && this.aid && this.agentID && this.url
|
||||
}
|
||||
|
||||
get uuid() {
|
||||
return this.$route.query.uuid
|
||||
}
|
||||
|
||||
get code() {
|
||||
return this.$route.query.code
|
||||
}
|
||||
|
||||
get state() {
|
||||
return this.$route.query.state
|
||||
}
|
||||
|
||||
get msg() {
|
||||
return this.$route.query.msg
|
||||
}
|
||||
|
||||
mounted() {
|
||||
if (this.msg) {
|
||||
console.log(this.msg)
|
||||
alert(this.msg)
|
||||
}
|
||||
}
|
||||
|
||||
created() {
|
||||
if (this.uuid) {
|
||||
this.$api.app.get(this.uuid as string).Start(e => {
|
||||
this.url = e.wx.url + '/api/wx/login/' + this.uuid
|
||||
this.aid = e.wx.corp_id
|
||||
this.agentID = e.wx.agent_id
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -1,40 +1,15 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"useDefineForClassFields": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"strict": true,
|
||||
"jsx": "preserve",
|
||||
"importHelpers": true,
|
||||
"moduleResolution": "node",
|
||||
"experimentalDecorators": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"sourceMap": true,
|
||||
"baseUrl": ".",
|
||||
"types": [
|
||||
"webpack-env"
|
||||
],
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
]
|
||||
},
|
||||
"lib": [
|
||||
"esnext",
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"scripthost"
|
||||
]
|
||||
"resolveJsonModule": true,
|
||||
"esModuleInterop": true,
|
||||
"lib": ["esnext", "dom"]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.tsx",
|
||||
"src/**/*.vue",
|
||||
"tests/**/*.ts",
|
||||
"tests/**/*.tsx"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
|
||||
}
|
||||
|
||||
19
oaf/vite.config.ts
Normal file
19
oaf/vite.config.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
server: {
|
||||
// host: '0.0.0.0',
|
||||
host: '127.0.0.1',
|
||||
port: 8080,
|
||||
proxy: {
|
||||
'/api': 'http://127.0.0.1:4001/'
|
||||
}
|
||||
},
|
||||
build: {
|
||||
outDir: '../build/static/',
|
||||
assetsDir: 'assets'
|
||||
}
|
||||
})
|
||||
@ -1,28 +0,0 @@
|
||||
module.exports = {
|
||||
transpileDependencies: [
|
||||
'vuetify'
|
||||
],
|
||||
configureWebpack: {
|
||||
output: {
|
||||
filename: '[name].[hash].js'
|
||||
}
|
||||
},
|
||||
outputDir: '../sub/static',
|
||||
devServer: {
|
||||
host: '0.0.0.0',
|
||||
port: 19520,
|
||||
disableHostCheck: true,
|
||||
proxy: {
|
||||
'^/api': {
|
||||
target: 'http://127.0.0.1:4001',
|
||||
ws: true,
|
||||
changeOrigin: true
|
||||
},
|
||||
'^/media': {
|
||||
target: 'http://127.0.0.1:4001',
|
||||
ws: true,
|
||||
changeOrigin: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
10146
oaf/yarn.lock
10146
oaf/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user