From cd7029c298779af818a35e334f272465b3428d58 Mon Sep 17 00:00:00 2001 From: veypi Date: Wed, 13 Oct 2021 14:43:03 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=9D=83=E9=99=90=E5=92=8C?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +- api/api.go | 2 +- api/app/app.go | 2 +- api/user/user.go | 22 +++-- api/user/user_role.go | 4 +- cfg/cfg.go | 40 +++++---- libs/auth/{auth.go => user_handler.go} | 10 +-- libs/auth/user_key.go | 27 ++++++ libs/base/api_handler.go | 4 +- models/app.go | 28 ++++-- models/role.go | 86 +++++++----------- models/user.go | 101 +++++++++++---------- oaf/public/index.html | 2 +- oaf/src/App.vue | 3 +- oaf/src/api/index.ts | 33 ++++++- oaf/src/libs/util.ts | 64 ++++++++++++++ oaf/src/router/index.ts | 22 +++-- oaf/src/shims-vue.d.ts | 1 + oaf/src/store/index.ts | 1 + oaf/src/types/vue-prototype.d.ts | 14 +++ oaf/src/views/About.vue | 5 -- oaf/src/views/demo.vue | 21 +++++ oaf/src/views/login.vue | 116 ++++++++++++++++++++++++ oaf/src/views/register.vue | 118 +++++++++++++++++++++++++ oaf/src/views/wx.vue | 2 +- oaf/vue.config.js | 2 +- sub/web.go | 1 - 27 files changed, 575 insertions(+), 162 deletions(-) rename libs/auth/{auth.go => user_handler.go} (70%) create mode 100644 libs/auth/user_key.go create mode 100644 oaf/src/libs/util.ts create mode 100644 oaf/src/types/vue-prototype.d.ts delete mode 100644 oaf/src/views/About.vue create mode 100644 oaf/src/views/demo.vue create mode 100644 oaf/src/views/login.vue create mode 100644 oaf/src/views/register.vue diff --git a/README.md b/README.md index 7d1654e..5a8fb54 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ # OneAuth -统一验证服务 \ No newline at end of file +统一验证服务 + +## 用户验证思路 + +![](https://public.veypi.com/img/screenshot/20211012194238.png) diff --git a/api/api.go b/api/api.go index 5888df8..9a25ec4 100644 --- a/api/api.go +++ b/api/api.go @@ -15,7 +15,7 @@ func Router(r OneBD.Router) { r.SetInternalErrorFunc(func(m core.Meta) { m.Write([]byte("{\"status\": 0}")) }) - user.Router(r.SubRouter("/auth/user")) + user.Router(r.SubRouter("/user")) wx.Router(r.SubRouter("wx")) app.Router(r.SubRouter("app")) //message.Router(r.SubRouter("/message")) diff --git a/api/app/app.go b/api/app/app.go index 0c009b6..4e950be 100644 --- a/api/app/app.go +++ b/api/app/app.go @@ -31,7 +31,7 @@ func (h *appHandler) Get() (interface{}, error) { } h.query = &models.App{} h.query.UUID = id - err := cfg.DB().Where(h.query).Preload("Wx").First(h.query).Error + err := cfg.DB().Where(h.query).First(h.query).Error if err != nil { return nil, err } diff --git a/api/user/user.go b/api/user/user.go index 51ebe37..4115131 100644 --- a/api/user/user.go +++ b/api/user/user.go @@ -20,7 +20,7 @@ import ( func Router(r OneBD.Router) { pool := OneBD.NewHandlerPool(func() OneBD.Handler { h := &handler{} - h.Ignore(rfc.MethodHead) + h.Ignore(rfc.MethodHead, rfc.MethodPost) return h }) r.Set("/", pool, rfc.MethodGet, rfc.MethodPost) // list @@ -68,8 +68,8 @@ func (h *handler) Get() (interface{}, error) { // Post register user func (h *handler) Post() (interface{}, error) { - if !h.CheckAuth("user").CanCreate() { - return nil, oerr.NoAuth + if !cfg.CFG.EnableRegister { + return nil, oerr.NoAuth.AttachStr("register disabled.") } var userdata = struct { Username string `json:"username"` @@ -138,7 +138,7 @@ func (h *handler) Patch() (interface{}, error) { if err := cfg.DB().Where(&target).First(&target).Error; err != nil { return nil, err } - if target.ID != h.Payload.ID && !h.CheckAuth("admin").CanDoAny() { + if target.ID != h.Payload.ID { return nil, oerr.NoAuth } if len(opts.Password) >= 6 { @@ -187,6 +187,10 @@ func (h *handler) Head() (interface{}, error) { if len(uid) == 0 || len(password) == 0 { return nil, oerr.ApiArgsError } + appID, err := strconv.Atoi(h.Meta().Query("app_id")) + if err != nil || appID <= 0 { + return nil, oerr.ApiArgsMissing + } h.User = new(models.User) uidType := h.Meta().Query("uid_type") switch uidType { @@ -199,6 +203,12 @@ func (h *handler) Head() (interface{}, error) { default: h.User.Username = uid } + app := &models.App{} + app.ID = uint(appID) + err = cfg.DB().Where(app).Find(app).Error + if err != nil { + return nil, oerr.DBErr.Attach(err) + } if err := cfg.DB().Preload("Roles").Where(h.User).First(h.User).Error; err != nil { if err.Error() == gorm.ErrRecordNotFound.Error() { // admin 登录自动注册 @@ -221,7 +231,7 @@ func (h *handler) Head() (interface{}, error) { } } else { log.HandlerErrs(err) - return nil, err + return nil, oerr.DBErr.Attach(err) } } isAuth, err := h.User.CheckLogin(password) @@ -231,7 +241,7 @@ func (h *handler) Head() (interface{}, error) { if h.User.Status == "disabled" { return nil, oerr.DisableLogin } - token, err := h.User.GetToken(cfg.CFG.Key) + token, err := h.User.GetToken(app.Key, app.ID) if err != nil { log.HandlerErrs(err) return nil, oerr.Unknown.Attach(err) diff --git a/api/user/user_role.go b/api/user/user_role.go index 05f86d7..be0673c 100644 --- a/api/user/user_role.go +++ b/api/user/user_role.go @@ -19,7 +19,7 @@ type userRoleHandler struct { } func (h *userRoleHandler) Post() (interface{}, error) { - if !h.CheckAuth("role").CanCreate() { + if !h.GetAuth("role").CanCreate() { return nil, oerr.NoAuth } uid := h.Meta().ParamsInt("user_id") @@ -67,7 +67,7 @@ func (h *userRoleHandler) Post() (interface{}, error) { } func (h *userRoleHandler) Delete() (interface{}, error) { - if !h.CheckAuth("role").CanDelete() { + if !h.GetAuth("role").CanDelete() { return nil, oerr.NoAuth } uid := h.Meta().ParamsInt("user_id") diff --git a/cfg/cfg.go b/cfg/cfg.go index d7a2d6c..ba2d52a 100644 --- a/cfg/cfg.go +++ b/cfg/cfg.go @@ -11,15 +11,16 @@ import ( var Path = cmd.GetCfgPath("OneAuth", "oa") var CFG = &struct { - AdminUser string - Host string - LoggerPath string - LoggerLevel string - Key string - TimeFormat string - Debug bool - EXEDir string - DB struct { + AdminUser string + Host string + LoggerPath string + LoggerLevel string + Key string + TimeFormat string + Debug bool + EXEDir string + EnableRegister bool + DB struct { Type string Addr string User string @@ -27,13 +28,14 @@ var CFG = &struct { DB string } }{ - AdminUser: "admin", - Host: "0.0.0.0:19528", - LoggerPath: "", - LoggerLevel: "debug", - TimeFormat: "2006/01/02 15:04:05", - Debug: true, - EXEDir: "./", + AdminUser: "admin", + Host: "0.0.0.0:4001", + LoggerPath: "", + LoggerLevel: "debug", + TimeFormat: "2006/01/02 15:04:05", + Debug: true, + EXEDir: "./", + EnableRegister: true, DB: struct { Type string Addr string @@ -41,9 +43,9 @@ var CFG = &struct { Pass string DB string }{ - Type: "sqlite", - //Addr: "127.0.0.1:3306", - Addr: "oa.db", + //Type: "sqlite", + Addr: "127.0.0.1:3306", + //Addr: "oa.db", User: "root", Pass: "123456", DB: "one_auth", diff --git a/libs/auth/auth.go b/libs/auth/user_handler.go similarity index 70% rename from libs/auth/auth.go rename to libs/auth/user_handler.go index bed7ada..6be1042 100644 --- a/libs/auth/auth.go +++ b/libs/auth/user_handler.go @@ -8,12 +8,12 @@ import ( "github.com/veypi/OneBD/rfc" ) -type Auth struct { +type UserHandler struct { Payload *models.PayLoad ignoreMethod map[rfc.Method]bool } -func (a *Auth) Init(m OneBD.Meta) error { +func (a *UserHandler) Init(m OneBD.Meta) error { if a.ignoreMethod != nil && a.ignoreMethod[m.Method()] { return nil } @@ -29,7 +29,7 @@ func (a *Auth) Init(m OneBD.Meta) error { return oerr.NotLogin.Attach(err) } -func (a *Auth) Ignore(methods ...rfc.Method) { +func (a *UserHandler) Ignore(methods ...rfc.Method) { if a.ignoreMethod == nil { a.ignoreMethod = make(map[rfc.Method]bool) } @@ -38,6 +38,6 @@ func (a *Auth) Ignore(methods ...rfc.Method) { } } -func (a *Auth) CheckAuth(name string, tags ...string) models.AuthLevel { - return a.Payload.CheckAuth(name, tags...) +func (a *UserHandler) GetAuth(ResourceID string, ResourceUUID ...string) models.AuthLevel { + return a.Payload.GetAuth(ResourceID, ResourceUUID...) } diff --git a/libs/auth/user_key.go b/libs/auth/user_key.go new file mode 100644 index 0000000..4f6fbf3 --- /dev/null +++ b/libs/auth/user_key.go @@ -0,0 +1,27 @@ +package auth + +import ( + "OneAuth/models" + "github.com/veypi/utils" + "sync" +) + +var keyCache = sync.Map{} + +func GetUserKey(uid uint, app *models.App) string { + if app.ID == 1 { + key, _ := keyCache.LoadOrStore(uid, utils.RandSeq(16)) + return key.(string) + } + // TODO: 获取其他应用user_key + return "" +} + +func RefreshUserKey(uid uint, app *models.App) string { + if app.ID == 1 { + key := utils.RandSeq(16) + keyCache.Store(uid, key) + return key + } + return "" +} diff --git a/libs/base/api_handler.go b/libs/base/api_handler.go index 7cf34f6..464b787 100644 --- a/libs/base/api_handler.go +++ b/libs/base/api_handler.go @@ -17,11 +17,11 @@ var json = jsoniter.ConfigFastest type ApiHandler struct { OneBD.BaseHandler - auth.Auth + auth.UserHandler } func (h *ApiHandler) Init(m OneBD.Meta) error { - return tools.MultiIniter(m, &h.BaseHandler, &h.Auth) + return tools.MultiIniter(m, &h.BaseHandler, &h.UserHandler) } func (h *ApiHandler) OnResponse(data interface{}) { diff --git a/models/app.go b/models/app.go index 76392e3..c34951d 100644 --- a/models/app.go +++ b/models/app.go @@ -1,16 +1,34 @@ package models +var AppKeys = map[string]string{} + type App struct { BaseModel - Name string `json:"name"` - UUID string `json:"uuid"` - Host string `json:"host"` - WxID string `json:"wx_id" gorm:""` - Wx *Wechat `json:"wx" gorm:"association_foreignkey:ID"` + Name string `json:"name"` + Icon string `json:"icon"` + UUID string `json:"uuid"` + // 认证成功跳转链接 + Host string `json:"host"` + // 加解密用户token (key+key2) + // 两个key都是请求获取时刷新 + // key oa发放给app 双方保存 针对app生成 每个应用有一个 + // key2 app发放给oa app保存 oa使用一次销毁 针对当个用户生成 每个用户有一个 + // 获取app用户加密秘钥key2 + UserRefreshUrl string `json:"user_refresh_url"` + // app 校验用户token时使用 + Key string `json:"key"` + // 是否允许用户注册 + EnableRegister string `json:"enable_register"` + 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 Wechat struct { BaseModel + AppID uint `json:"app_id"` // 网页授权登录用 WxID string `json:"wx_id"` AgentID string `json:"agent_id"` diff --git a/models/role.go b/models/role.go index ed68db9..751fe82 100644 --- a/models/role.go +++ b/models/role.go @@ -1,74 +1,44 @@ package models -import ( - "OneAuth/cfg" - "github.com/veypi/utils/log" -) - -var GlobalRoles = make(map[uint]*Role) - -func SyncGlobalRoles() { - roles := make([]*Role, 0, 10) - err := cfg.DB().Preload("Auths").Find(&roles).Error - if err != nil { - log.Warn().Msgf("sync global roles error: %s", err.Error()) - return - } - for _, r := range roles { - GlobalRoles[r.ID] = r - } -} - type UserRole struct { BaseModel UserID uint `json:"user_id"` RoleID uint `json:"role_id"` } -type RoleAuth struct { - BaseModel - RoleID uint `json:"role_id"` - AuthID uint `json:"auth_id"` -} - type Role struct { BaseModel Name string `json:"name"` // 角色类型 - // 0: 系统角色 1: 用户角色 - Category uint `json:"category" gorm:"default:0"` + // 1: 系统定义角色 2: 用户自定义角色 + Category uint `json:"category" gorm:"default:1"` // 角色标签 Tag string `json:"tag" gorm:"default:''"` Users []*User `json:"users" gorm:"many2many:user_role;"` // 具体权限 - Auths []*Auth `json:"auths" gorm:"many2many:role_auth;"` + Auths []*Auth `json:"auths" gorm:"foreignkey:RoleID;references:ID"` IsUnique bool `json:"is_unique" gorm:"default:false"` } -func (r Role) CheckAuth(name string, tags ...string) AuthLevel { - res := AuthNone - tag := "" - if len(tags) > 0 { - tag = tags[0] - } - for _, a := range r.Auths { - if a.Name == "admin" && a.Tag == "" || (a.Name == "admin" && a.Tag == tag) || (a.Name == name && a.Tag == tag) { - if a.Level > res { - res = a.Level - } - } - } - return res -} - +// AuthLevel 权限等级 +// 0 相当于没有 +// 1 有限读权限 +// 2 读权限 +// 3 创建权限 +// 4 修改权限 +// 5 删除权限 +// 6 赋予其余人权限 type AuthLevel uint const ( - AuthNone AuthLevel = 0 - AuthRead AuthLevel = 1 - AuthCreate AuthLevel = 2 - AuthUpdate AuthLevel = 3 - AuthDelete AuthLevel = 4 + AuthNone AuthLevel = 0 + // AuthPart TODO: 临时权限 + AuthPart AuthLevel = 1 + AuthRead AuthLevel = 2 + AuthCreate AuthLevel = 3 + AuthUpdate AuthLevel = 4 + AuthDelete AuthLevel = 5 + AuthAll AuthLevel = 6 ) func (a AuthLevel) CanRead() bool { @@ -88,17 +58,25 @@ func (a AuthLevel) CanDelete() bool { } func (a AuthLevel) CanDoAny() bool { - return a >= AuthDelete + return a >= AuthAll } // 资源权限 type Auth struct { BaseModel - Name string `json:"name"` - AppID uint `json:"app_id"` + Name string `json:"name"` + // 该权限作用的应用 + AppID uint `json:"app_id"` + // 权限绑定只能绑定一个 + RoleID uint `json:"role_id"` + UserID uint `json:"user_id"` + // 资源id + RID string `json:"rid" gorm:""` + // 具体某个资源的id + RUID string `json:"ruid"` // 权限标签 - Tag string `json:"tag"` - // 权限等级 0 相当于没有 1 读权限 2 创建权限 3 修改权限 4 删除权限 + Tag string `json:"tag"` Level AuthLevel `json:"level"` + Des string `json:"des"` } diff --git a/models/user.go b/models/user.go index c1a1419..e1faf70 100644 --- a/models/user.go +++ b/models/user.go @@ -7,7 +7,6 @@ import ( "encoding/json" "errors" "github.com/veypi/utils" - "github.com/veypi/utils/log" "strings" "time" ) @@ -27,33 +26,47 @@ type User struct { Icon string `json:"icon"` Roles []*Role `json:"roles" gorm:"many2many:user_role;"` + Auths []*Auth `json:"auths" gorm:"foreignkey:UserID;references:ID"` +} + +type simpleAuth struct { + RID string `json:"rid"` + // 具体某个资源的id + RUID string `json:"ruid"` + Level AuthLevel `json:"level"` } // TODO:: roles 是否会造成token过大 ? type PayLoad struct { - ID uint `json:"id"` - Username string `json:"username"` - Nickname string `json:"nickname"` - Icon string `json:"icon"` - Iat int64 `json:"iat"` //token time - Exp int64 `json:"exp"` - Roles []uint `json:"roles"` + ID uint `json:"id"` + Iat int64 `json:"iat"` //token time + Exp int64 `json:"exp"` + Auth map[uint]*simpleAuth `json:"auth"` } -func (p *PayLoad) CheckAuth(name string, tags ...string) AuthLevel { +// GetAuth resource_uuid 缺省或仅第一个有效 权限会被更高权限覆盖 +func (p *PayLoad) GetAuth(ResourceID string, ResourceUUID ...string) AuthLevel { res := AuthNone - if p == nil || p.Roles == nil { + if p == nil || p.Auth == nil { return res } - for _, id := range p.Roles { - r := GlobalRoles[id] - if r == nil { - log.Warn().Msgf("not found role id: %d", id) - continue - } - t := r.CheckAuth(name, tags...) - if t > res { - res = t + ruid := "" + if len(ResourceUUID) > 0 { + ruid = ResourceUUID[0] + } + for _, a := range p.Auth { + if a.RID == ResourceID { + if a.RUID != "" { + if a.RUID == ruid { + if a.Level > res { + res = a.Level + } + } else { + continue + } + } else if a.Level > res { + res = a.Level + } } } return res @@ -63,26 +76,7 @@ func (u *User) String() string { return u.Username + ":" + u.Nickname } -func (u *User) CheckAuth(name string, tags ...string) AuthLevel { - res := AuthNone - if u == nil || u.Roles == nil { - return res - } - for _, t := range u.Roles { - r := GlobalRoles[t.ID] - if r == nil { - log.Warn().Msgf("not found role id: %d", t.ID) - continue - } - t := r.CheckAuth(name, tags...) - if t > res { - res = t - } - } - return res -} - -func (u *User) GetToken(key string) (string, error) { +func (u *User) GetToken(key string, appID uint) (string, error) { header := map[string]string{ "typ": "JWT", "alg": "HS256", @@ -90,15 +84,30 @@ func (u *User) GetToken(key string) (string, error) { //header := "{\"typ\": \"JWT\", \"alg\": \"HS256\"}" now := time.Now().Unix() payload := PayLoad{ - ID: u.ID, - Username: u.Username, - Nickname: u.Nickname, - Icon: u.Icon, - Iat: now, - Exp: now + 60*60*24, + ID: u.ID, + Iat: now, + Exp: now + 60*60*24, + Auth: map[uint]*simpleAuth{}, } for _, r := range u.Roles { - payload.Roles = append(payload.Roles, r.ID) + for _, a := range r.Auths { + if appID == a.AppID { + payload.Auth[a.ID] = &simpleAuth{ + RID: a.RID, + RUID: a.RUID, + Level: a.Level, + } + } + } + } + for _, a := range u.Auths { + if appID == a.AppID { + payload.Auth[a.ID] = &simpleAuth{ + RID: a.RID, + RUID: a.RUID, + Level: a.Level, + } + } } a, err := json.Marshal(header) if err != nil { diff --git a/oaf/public/index.html b/oaf/public/index.html index bc51465..642a583 100644 --- a/oaf/public/index.html +++ b/oaf/public/index.html @@ -4,7 +4,7 @@ - + <%= htmlWebpackPlugin.options.title %> diff --git a/oaf/src/App.vue b/oaf/src/App.vue index 6f867e8..af75969 100644 --- a/oaf/src/App.vue +++ b/oaf/src/App.vue @@ -21,6 +21,7 @@ diff --git a/oaf/src/api/index.ts b/oaf/src/api/index.ts index 94cb810..d52f1d6 100644 --- a/oaf/src/api/index.ts +++ b/oaf/src/api/index.ts @@ -4,10 +4,14 @@ * Distributed under terms of the MIT license. */ +import Vue from 'vue' import {Base64} from 'js-base64' import ajax from './ajax' import store from '@/store' +export type SuccessFunction = (e: any) => void; +export type FailedFunction = (e: any) => void; + const Code = { 42011: '无操作权限', 22031: '资源不存在 或 您无权操作该资源' @@ -24,15 +28,16 @@ class Interface { this.data = data } - Start(success: Function, fail?: Function) { + Start(success: SuccessFunction, fail?: FailedFunction) { 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]) { - // Message.warning({message: Code[data.code] || data.err, offset: 100}) } if (fail) { fail(data) @@ -103,12 +108,32 @@ const app = { local: '/api/app/', 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, prop?: any) { + const data = Object.assign({ + username: username, + password: Base64.encode(password) + }, prop) + return new Interface(ajax.post, this.local, data) + }, + login(username: string, password: string) { + return new Interface(ajax.head, this.local + username, { + password: Base64.encode(password) + }) } } const api = { role: role, app: app, + user: user, admin: { auths() { return new Interface(ajax.get, '/api/auth/') @@ -192,8 +217,8 @@ const api = { } const Api = { - install(Vue: any) { - Vue.prototype.api = api + install(vue: typeof Vue): void { + vue.prototype.$api = api } } export {Api} diff --git a/oaf/src/libs/util.ts b/oaf/src/libs/util.ts new file mode 100644 index 0000000..7fbd742 --- /dev/null +++ b/oaf/src/libs/util.ts @@ -0,0 +1,64 @@ +function padLeftZero(str: string): string { + return ('00' + str).substr(str.length) +} + +const util = { + title: function (title: string) { + window.document.title = title ? title + ' - Home' : 'veypi project' + }, + getCookie(name: string) { + const reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)') + const arr = document.cookie.match(reg) + if (arr) { + return unescape(arr[2]) + } else return null + }, + delCookie(name: string) { + const exp = new Date() + exp.setTime(exp.getTime() - 1) + const cval = this.getCookie(name) + if (cval !== null) { + document.cookie = name + '=' + cval + ';expires=' + exp.toLocaleString() + } + }, + setCookie(name: string, value: string, time: number) { + const exp = new Date() + exp.setTime(exp.getTime() + time) + document.cookie = + name + '=' + escape(value) + ';expires=' + exp.toLocaleString() + }, + checkLogin() { + // return parseInt(this.getCookie('stat')) === 1 + return Boolean(localStorage.auth_token) + }, + + formatDate(date: Date, fmt: string) { + if (/(y+)/.test(fmt)) { + fmt = fmt.replace( + RegExp.$1, + (date.getFullYear() + '').substr(4 - RegExp.$1.length) + ) + } + const o = { + 'M+': date.getMonth() + 1, + 'd+': date.getDate(), + 'h+': date.getHours(), + 'm+': date.getMinutes(), + 's+': date.getSeconds() + } + for (const k in o) { + if (new RegExp(`(${k})`).test(fmt)) { + // eslint-disable-next-line @typescript-eslint/ban-ts-ignore + // @ts-ignore + const str = o[k] + '' + fmt = fmt.replace( + RegExp.$1, + RegExp.$1.length === 1 ? str : padLeftZero(str) + ) + } + } + return fmt + } +} + +export default util diff --git a/oaf/src/router/index.ts b/oaf/src/router/index.ts index 83f5ef8..6d6179d 100644 --- a/oaf/src/router/index.ts +++ b/oaf/src/router/index.ts @@ -1,6 +1,9 @@ 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' Vue.use(VueRouter) @@ -11,12 +14,19 @@ const routes: Array = [ component: Home }, { - path: '/about', - name: 'About', - // route level code-splitting - // this generates a separate chunk (about.[hash].js) for this route - // which is lazy-loaded when the route is visited. - component: () => import(/* webpackChunkName: "about" */ '../views/About.vue') + path: '/app', + name: 'app', + component: Demo + }, + { + path: '/login', + name: 'login', + component: Login + }, + { + path: '/register', + name: 'register', + component: Register }, { path: '/wx', diff --git a/oaf/src/shims-vue.d.ts b/oaf/src/shims-vue.d.ts index d9f24fa..a095766 100644 --- a/oaf/src/shims-vue.d.ts +++ b/oaf/src/shims-vue.d.ts @@ -1,3 +1,4 @@ +declare module '*.js' declare module '*.vue' { import Vue from 'vue' export default Vue diff --git a/oaf/src/store/index.ts b/oaf/src/store/index.ts index 332b916..3d5636e 100644 --- a/oaf/src/store/index.ts +++ b/oaf/src/store/index.ts @@ -5,6 +5,7 @@ Vue.use(Vuex) export default new Vuex.Store({ state: { + user: null }, mutations: { }, diff --git a/oaf/src/types/vue-prototype.d.ts b/oaf/src/types/vue-prototype.d.ts new file mode 100644 index 0000000..e8af855 --- /dev/null +++ b/oaf/src/types/vue-prototype.d.ts @@ -0,0 +1,14 @@ +// 1. 确保在声明补充的类型之前导入 'vue' +import Vue from 'vue' +import api from '@/api' + +export type PluginFunction = (Vue: typeof Vue, options?: T) => void; + +// 2. 定制一个文件,设置你想要补充的类型 +// 在 types/vue.d.ts 里 Vue 有构造函数类型 +declare module 'vue/types/vue' { +// 3. 声明为 Vue 补充的东西 + interface Vue { + $api: typeof api; + } +} diff --git a/oaf/src/views/About.vue b/oaf/src/views/About.vue deleted file mode 100644 index 3fa2807..0000000 --- a/oaf/src/views/About.vue +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/oaf/src/views/demo.vue b/oaf/src/views/demo.vue new file mode 100644 index 0000000..57fe68e --- /dev/null +++ b/oaf/src/views/demo.vue @@ -0,0 +1,21 @@ + + + + diff --git a/oaf/src/views/login.vue b/oaf/src/views/login.vue new file mode 100644 index 0000000..e952959 --- /dev/null +++ b/oaf/src/views/login.vue @@ -0,0 +1,116 @@ + + + + diff --git a/oaf/src/views/register.vue b/oaf/src/views/register.vue new file mode 100644 index 0000000..e008b2e --- /dev/null +++ b/oaf/src/views/register.vue @@ -0,0 +1,118 @@ + + + + diff --git a/oaf/src/views/wx.vue b/oaf/src/views/wx.vue index b42e6c0..7e860a8 100644 --- a/oaf/src/views/wx.vue +++ b/oaf/src/views/wx.vue @@ -52,7 +52,7 @@ export default class Wx extends Vue { created() { if (this.uuid) { - this.api.app.get(this.uuid).Start(e => { + 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 diff --git a/oaf/vue.config.js b/oaf/vue.config.js index a25a4f3..a763404 100644 --- a/oaf/vue.config.js +++ b/oaf/vue.config.js @@ -10,7 +10,7 @@ module.exports = { outputDir: '../sub/static', devServer: { host: '0.0.0.0', - port: 19528, + port: 19520, disableHostCheck: true, proxy: { '^/api': { diff --git a/sub/web.go b/sub/web.go index a19cda1..0abda23 100644 --- a/sub/web.go +++ b/sub/web.go @@ -76,7 +76,6 @@ func runSyncDB(*cli.Context) error { log.HandlerErrs( db.SetupJoinTable(&models.User{}, "Roles", &models.UserRole{}), db.SetupJoinTable(&models.Role{}, "Users", &models.UserRole{}), - db.SetupJoinTable(&models.Role{}, "Auths", &models.RoleAuth{}), db.AutoMigrate(&models.User{}, &models.Role{}, &models.Auth{}), ) log.HandlerErrs(