feat: a lot

v3
veypi 11 months ago
parent 9e157d0f0e
commit 765502bdd9

@ -2,6 +2,7 @@ package app
import (
"oa/cfg"
"oa/errs"
"oa/libs/auth"
M "oa/models"
@ -13,10 +14,24 @@ import (
func useApp(r rest.Router) {
r.Delete("/:app_id", auth.Check("app", "app_id", auth.DoDelete), appDelete)
r.Get("/:app_id", auth.Check("app", "app_id", auth.DoRead), appGet)
r.Get("/:app_id/key", auth.Check("app", "app_id", auth.DoDelete), appKey)
r.Get("/", appList)
r.Patch("/:app_id", auth.Check("app", "app_id", auth.DoUpdate), appPatch)
r.Post("/", auth.Check("app", "", auth.DoCreate), appPost)
}
func appKey(x *rest.X) (any, error) {
id := x.Params.GetStr("app_id")
if id == "" {
return nil, errs.ArgsInvalid.WithStr("missing app_id")
}
data := &M.App{}
data.ID = id
key := utils.RandSeq(32)
// err := cfg.DB().Where("id = ?", x.Params.GetStr("app_id")).First(data).Error
err := cfg.DB().Model(data).Update("key", key).Error
return key, err
}
func appDelete(x *rest.X) (any, error) {
opts := &M.AppDelete{}
err := x.Parse(opts)
@ -72,6 +87,36 @@ func appList(x *rest.X) (any, error) {
return data, err
}
func appPost(x *rest.X) (any, error) {
opts := &M.AppPost{}
err := x.Parse(opts)
if err != nil {
return nil, err
}
data := &M.App{}
data.Name = opts.Name
data.Icon = opts.Icon
data.Typ = opts.Typ
if opts.Des != nil {
data.Des = *opts.Des
}
err = cfg.DB().Transaction(func(tx *gorm.DB) error {
data.Key = utils.RandSeq(32)
err := tx.Create(data).Error
if err != nil {
return err
}
au := &M.AppUser{
AppID: data.ID,
UserID: x.Request.Context().Value("uid").(string),
Status: M.AUSTATUS_OK,
}
return tx.Create(au).Error
})
return data, err
}
func appPatch(x *rest.X) (any, error) {
opts := &M.AppPatch{}
err := x.Parse(opts)
@ -100,37 +145,13 @@ func appPatch(x *rest.X) (any, error) {
if opts.InitRoleID != nil {
optsMap["init_role_id"] = opts.InitRoleID
}
err = cfg.DB().Model(data).Updates(optsMap).Error
return data, err
}
func appPost(x *rest.X) (any, error) {
opts := &M.AppPost{}
err := x.Parse(opts)
if err != nil {
return nil, err
}
data := &M.App{}
data.Name = opts.Name
data.Icon = opts.Icon
data.Typ = opts.Typ
if opts.Des != nil {
data.Des = *opts.Des
}
err = cfg.DB().Transaction(func(tx *gorm.DB) error {
data.Key = utils.RandSeq(32)
err := tx.Create(data).Error
if err != nil {
return err
if opts.Status != nil {
optsMap["status"] = opts.Status
}
au := &M.AppUser{
AppID: data.ID,
UserID: x.Request.Context().Value("uid").(string),
Status: M.AUSTATUS_OK,
if opts.InitUrl != nil {
optsMap["init_url"] = opts.InitUrl
}
return tx.Create(au).Error
})
err = cfg.DB().Model(data).Updates(optsMap).Error
return data, err
}

@ -15,4 +15,5 @@ func Use(r rest.Router) {
useApp(r)
useAppUser(r.SubRouter(":app_id/app_user"))
useResource(r.SubRouter(":app_id/resource"))
useRole(r.SubRouter(":app_id/role"))
}

@ -1,29 +1,27 @@
package role
package app
import (
"github.com/google/uuid"
"github.com/veypi/OneBD/rest"
"oa/cfg"
M "oa/models"
"strings"
)
func useRole(r rest.Router) {
r.Get("/:role_id", roleGet)
r.Delete("/:role_id", roleDelete)
r.Get("/", roleList)
r.Patch("/:role_id", rolePatch)
r.Post("/", rolePost)
r.Delete("/:role_id", roleDelete)
r.Get("/:role_id", roleGet)
r.Patch("/:role_id", rolePatch)
}
func roleGet(x *rest.X) (any, error) {
opts := &M.RoleGet{}
func roleDelete(x *rest.X) (any, error) {
opts := &M.RoleDelete{}
err := x.Parse(opts)
if err != nil {
return nil, err
}
data := &M.Role{}
err = cfg.DB().Where("id = ?", opts.ID).First(data).Error
err = cfg.DB().Where("id = ?", opts.ID).Delete(data).Error
return data, err
}
@ -36,6 +34,9 @@ func roleList(x *rest.X) (any, error) {
data := make([]*M.Role, 0, 10)
query := cfg.DB()
if opts.AppID != nil {
query = query.Where("app_id LIKE ?", opts.AppID)
}
if opts.Name != nil {
query = query.Where("name LIKE ?", opts.Name)
}
@ -43,57 +44,53 @@ func roleList(x *rest.X) (any, error) {
return data, err
}
func rolePatch(x *rest.X) (any, error) {
opts := &M.RolePatch{}
func rolePost(x *rest.X) (any, error) {
opts := &M.RolePost{}
err := x.Parse(opts)
if err != nil {
return nil, err
}
data := &M.Role{}
err = cfg.DB().Where("id = ?", opts.ID).First(data).Error
if err != nil {
return nil, err
}
optsMap := make(map[string]interface{})
if opts.Name != nil {
optsMap["name"] = opts.Name
}
if opts.Des != nil {
optsMap["des"] = opts.Des
}
if opts.AppID != nil {
optsMap["app_id"] = opts.AppID
}
err = cfg.DB().Model(data).Updates(optsMap).Error
data.AppID = opts.AppID
data.Name = opts.Name
data.Des = opts.Des
err = cfg.DB().Create(data).Error
return data, err
}
func rolePost(x *rest.X) (any, error) {
opts := &M.RolePost{}
func roleGet(x *rest.X) (any, error) {
opts := &M.RoleGet{}
err := x.Parse(opts)
if err != nil {
return nil, err
}
data := &M.Role{}
data.ID = strings.ReplaceAll(uuid.New().String(), "-", "")
data.Name = opts.Name
data.Des = opts.Des
data.AppID = opts.AppID
err = cfg.DB().Create(data).Error
err = cfg.DB().Where("id = ?", opts.ID).First(data).Error
return data, err
}
func roleDelete(x *rest.X) (any, error) {
opts := &M.RoleDelete{}
func rolePatch(x *rest.X) (any, error) {
opts := &M.RolePatch{}
err := x.Parse(opts)
if err != nil {
return nil, err
}
data := &M.Role{}
err = cfg.DB().Where("id = ?", opts.ID).Delete(data).Error
err = cfg.DB().Where("id = ?", opts.ID).First(data).Error
if err != nil {
return nil, err
}
optsMap := make(map[string]interface{})
if opts.Name != nil {
optsMap["name"] = opts.Name
}
if opts.Des != nil {
optsMap["des"] = opts.Des
}
err = cfg.DB().Model(data).Updates(optsMap).Error
return data, err
}

@ -9,7 +9,6 @@ package api
import (
"oa/api/access"
"oa/api/app"
"oa/api/role"
"oa/api/token"
"oa/api/user"
"oa/cfg"
@ -23,7 +22,6 @@ func Use(r rest.Router) {
r.Use(libs.CorsAllowAny)
access.Use(r.SubRouter("access"))
app.Use(r.SubRouter("app"))
role.Use(r.SubRouter("role"))
user.Use(r.SubRouter("user"))
token.Use(r.SubRouter("token"))
r.Get("", baseInfo)

@ -1,16 +0,0 @@
//
// Copyright (C) 2024 veypi <i@veypi.com>
// 2024-09-23 16:28:13
// Distributed under terms of the MIT license.
//
// Auto generated by OneBD. DO NOT EDIT
package role
import (
"github.com/veypi/OneBD/rest"
)
func Use(r rest.Router) {
useRole(r)
}

@ -27,6 +27,7 @@ func useToken(r rest.Router) {
func tokenSalt(x *rest.X) (any, error) {
opts := &M.TokenSalt{}
err := x.Parse(opts)
logv.Warn().Msg(opts.Username)
if err != nil {
return nil, err
}

@ -12,6 +12,7 @@ type AppPatch struct {
Typ *string `json:"typ" gorm:"default:auto" parse:"json"`
InitRoleID *string `json:"init_role_id" gorm:"index;type:varchar(32)" parse:"json"`
Status *string `json:"status" gorm:"default:ok" parse:"json"`
InitUrl *string `json:"init_url" parse:"json"`
}
type AppDelete struct {
@ -81,3 +82,28 @@ type ResourcePost struct {
Name string `json:"name" parse:"json"`
Des string `json:"des" parse:"json"`
}
type RoleGet struct {
ID string `json:"id" gorm:"primaryKey;type:varchar(32)" parse:"path@role_id"`
}
type RolePatch struct {
ID string `json:"id" gorm:"primaryKey;type:varchar(32)" parse:"path@role_id"`
Name *string `json:"name" parse:"json"`
Des *string `json:"des" parse:"json"`
}
type RoleDelete struct {
ID string `json:"id" gorm:"primaryKey;type:varchar(32)" parse:"path@role_id"`
}
type RoleList struct {
AppID *string `json:"app_id" parse:"path"`
Name *string `json:"name" parse:"query"`
}
type RolePost struct {
AppID string `json:"app_id" parse:"path"`
Name string `json:"name" parse:"json"`
Des string `json:"des" parse:"json"`
}

@ -19,7 +19,7 @@ type App struct {
Status string `json:"status" gorm:"default:ok" methods:"post,*patch" parse:"json"`
InitRoleID *string `json:"init_role_id" gorm:"index;type:varchar(32);default: null" methods:"*patch" parse:"json"`
InitRole *Role `json:"init_role" gorm:"foreignKey:InitRoleID;references:ID"`
InitUrl string `json:"init_url"`
InitUrl string `json:"init_url" methods:"*patch" parse:"json"`
UserCount uint `json:"user_count"`
Key string `json:"-"`
}
@ -74,3 +74,13 @@ type Resource struct {
Name string `json:"name" methods:"post" parse:"json"`
Des string `json:"des" methods:"post,*patch" parse:"json"`
}
type Role struct {
BaseModel
AppID string `json:"app_id" methods:"*list,post" parse:"path"`
App *App `json:"-" gorm:"foreignKey:AppID;references:ID"`
Name string `json:"name" methods:"post,*patch,*list" parse:"json"`
Des string `json:"des" methods:"post,*patch" parse:"json"`
UserCount uint `json:"user_count"`
Access []*Access `json:"-"`
}

@ -1,26 +0,0 @@
package models
type RoleGet struct {
ID string `json:"id" gorm:"primaryKey;type:varchar(32)" parse:"path@role_id"`
}
type RolePatch struct {
ID string `json:"id" gorm:"primaryKey;type:varchar(32)" parse:"path@role_id"`
Name *string `json:"name" parse:"json"`
Des *string `json:"des" parse:"json"`
AppID *string `json:"app_id" gorm:"index;type:varchar(32)" parse:"json"`
}
type RoleDelete struct {
ID string `json:"id" gorm:"primaryKey;type:varchar(32)" parse:"path@role_id"`
}
type RolePost struct {
Name string `json:"name" parse:"json"`
Des string `json:"des" parse:"json"`
AppID string `json:"app_id" gorm:"index;type:varchar(32)" parse:"json"`
}
type RoleList struct {
Name *string `json:"name" parse:"query"`
}

@ -1,11 +0,0 @@
package models
type Role struct {
BaseModel
Name string `json:"name" methods:"post,*patch,*list" parse:"json"`
Des string `json:"des" methods:"post,*patch" parse:"json"`
AppID string `json:"app_id" gorm:"index;type:varchar(32)" methods:"post,*patch" parse:"json"`
App *App `json:"-" gorm:"foreignKey:AppID;references:ID"`
UserCount uint `json:"user_count"`
Access []*Access `json:"-"`
}

@ -1,4 +1,4 @@
<!--
<!--
* crud.vue
* Copyright (C) 2023 veypi <i@veypi.com>
* 2023-10-10 19:29
@ -26,7 +26,8 @@
<template v-if="k.editable === undefined ? editable :
k.editable">
<Vinput :align="valign" :model-value="item[k.name] === undefined ?
k.default : item[k.name]" :type="k.typ" :options="k.options" @update:model-value="setv(item,
k.default : item[k.name]" :type="k.typ" :validate="k.validate" :options="k.options"
@update:model-value="setv(item,
k.name)($event)"></Vinput>
</template>
<template v-else>
@ -57,6 +58,7 @@ interface keyProp {
editable?: boolean,
options?: any,
style?: { [k: string]: string },
validate?: any
}
let emits = defineEmits<{
(e: 'update', v: any): void
@ -74,7 +76,6 @@ let props = withDefaults(defineProps<{
valign?: 'center' | 'left' | 'right',
editable?: boolean
ifselect?: boolean
}>(),
{
vertical: false,
@ -243,4 +244,3 @@ defineExpose({
}
}
</style>

@ -14,7 +14,7 @@
<OneIcon :name='v.ico' />
</div>
<div class="text-nowrap" v-if="show_name">
{{ v.name.startsWith('!') ? v.name.slice(1) : $t(v.name) }}
{{ v.name ? v.name.startsWith('!') ? v.name.slice(1) : $t(v.name) : '' }}
</div>
</slot>
</div>

@ -41,7 +41,7 @@
<!-- @click="setParameter(v.key,vv.key, c.value)"-->
</template>
<template v-else-if="type === 'radio'">
<div class="flex justify-between gap-4">
<div class="flex px-8 justify-between gap-4">
<template :key="ok" v-for="(ov, ok) of transDic">
<div :class="[value === ok ? 'radio-btn-active' :
'div-btn']" @click="setSelect(ok)" style="color:white;"
@ -227,7 +227,7 @@ const sync = () => {
transDic.value[i.key] = i.name
}
}
console.log(transDic.value)
// console.log(transDic.value)
} else {
for (let i in props.options) {
transDic.value[i] = props.options[i]

@ -6,6 +6,11 @@
import webapi from "./webapi"
import * as models from "./models"
export function Key(app_id: string) {
return webapi.Get<string>(`/app/${app_id}/key`, {})
}
export function Get(app_id: string) {
return webapi.Get<models.App>(`/app/${app_id}`, {})
}
@ -16,6 +21,7 @@ export interface PatchOpts {
des?: string
typ?: string
init_role_id?: string
init_url?: string
status?: string
}
export function Patch(app_id: string, json: PatchOpts) {

@ -12,8 +12,9 @@ export interface TokenSaltOpts {
}
// keep
export function TokenSalt(json: TokenSaltOpts) {
return webapi.Get<{ id: string, salt: string }>(`/token/TokenSalt`, { json })
return webapi.Post<{ id: string, salt: string }>(`/token/salt`, { json })
}
export interface PostOpts {
refresh?: string
typ?: string
@ -47,6 +48,7 @@ export function Delete(token_id: string) {
}
export interface ListQuery {
limit?: number
user_id: string
app_id: string
}

@ -32,7 +32,7 @@ let core = ref({} as models.App)
const set_menu = () => {
let p = '/app/' + core.value.id
menu.set([
{ ico: 'home', name: '!' + core.value.name, path: p },
{ ico: 'home', name: core.value.name ? '!' + core.value.name : '', path: p },
{ ico: 'user', name: 'menu.user', path: p + '/user' },
{ ico: 'team', name: 'menu.auth', path: p + '/auth' },
{ ico: 'setting', name: 'menu.setting', path: p + '/cfg' },

@ -1,15 +1,310 @@
<!--
<!--
* auth.vue
* Copyright (C) 2024 veypi <i@veypi.com>
* 2024-06-12 18:38
* Distributed under terms of the MIT license.
-->
<template>
<div></div>
<div class="">
<div class="flex justify-between">
<div class="text-3xl">角色管理</div>
<div @click="created(0)"></div>
</div>
<div class="w-full">
<crud vertical :keys="role_keys" :data="role" @update="update(0,
$event)">
<template #k_created="{ value }">{{ util.datetostr(value) }}</template>
<template #k__="{ row }">
<div color="primary" size="sm" @click="show_dialog(0,
row.id)">权限</div>
<div color="secondary" size="sm" @click="show_dialog(1,
row.id)">用户</div>
<div color="negative" size="sm" @click="del(0, row.id)">删除</div>
<template v-if="row.id === app.role_id">
<div color="positive" disable size="sm">初始角色</div>
</template>
<template v-else>
<div size="sm" @click="api.app.update(app.id, {
role_id:
row.id
}).then(_ => app.role_id = row.id)">设置为初始角色</div>
</template>
</template>
</crud>
</div>
<div class="flex mt-16 justify-between">
<div class="text-3xl">资源管理</div>
<div @click="created(1)"></div>
</div>
<div class="w-full">
<crud vertical :keys="resource_keys" :data="resource" @update="update(1,
$event)">
<template #k_created="{ value }">{{ util.datetostr(value) }}</template>
<template #k__="{ row }">
<div color="negative" size="sm" @click="del(1, row.name)">删除</div>
</template>
</crud>
</div>
<q-dialog v-model="dialog">
<q-card v-if="dialog_obj" class="mx-4 mt-4" style="width: 1000px;max-width: 90vw;">
<q-card-section class="row items-center q-pb-none">
<div class="text-h6">{{ dialog_obj.name }}
</div>
<q-space />
<div v-if="dialog_mode">
<q-select filled :model-value="''" @update:model-value="roleuser.add" use-input hide-selected fill-input
input-debounce="0" label="添加用户" :options="users_cache" @filter="filterFn" style="width: 20rem">
<template v-slot:no-option>
<q-item>
<q-item-section class="text-grey">
无结果
</q-item-section>
</q-item>
</template>
</q-select>
</div>
<div v-else @click="created(2, { role_id: dialog_obj.id })">添加权限</div>
</q-card-section>
<q-card-section v-if="dialog_mode">
<crud vertical :keys="users_keys" :data="users">
<template #k__="{ row }">
<div color="negative" size="sm" @click="roleuser.drop(row)"></div>
</template>
</crud>
</q-card-section>
<q-card-section v-else>
<crud vertical :keys="access_keys" :data="access" @update="update(2, $event)">
<template #k__="{ row }">
<div color="negative" size="sm" @click="del(2, row.id)">删除</div>
</template>
</crud>
</q-card-section>
</q-card>
</q-dialog>
</div>
</template>
<script lang="ts" setup>
import type { models } from '#imports';
import msg from '@veypi/msg';
let dialog = ref(false)
let dialog_mode = ref(0)
let dialog_obj = ref<models.Role>({} as any)
const role_keys = ref<any>([
{
name: 'id',
label: 'ID',
},
{ name: 'name', label: '标识符' },
{ name: 'des', label: '描述', editable: true },
{ name: 'created', label: '创建时间' },
{ name: 'user_count', label: '绑定用户数' },
{
name: '_', label: '操作', style: { 'justify-content': 'start' },
width: 40
},
])
const resource_keys = ref<any>([
{ name: 'name', label: '标识符' },
{ name: 'des', label: '描述', editable: true },
{ name: 'created', label: '创建时间' },
{
name: '_', label: '操作', style: { 'justify-content': 'start' },
width: 40
},
])
const access_keys = ref<any>([
{ name: 'id', label: 'ID' },
{ name: 'name', label: '标识符' },
{ name: 'rid', label: '特定子资源id', editable: true },
{
name: 'level', label: '权限等级', editable: true, typ:
ArgType.Select, options: LevelOptions,
},
{
name: '_', label: '操作', style: { 'justify-content': 'start' },
width: 40
},
])
const users_keys = ref<any>([
{ name: 'id', label: 'ID' },
{ name: 'username', label: '用户名' },
{ name: 'nickname', label: '昵称' },
{
name: '_', label: '操作', style: { 'justify-content': 'start' },
width: 40
},
])
let access = ref<models.Access[]>([])
let users = ref<models.User[]>([])
let users_cache = ref<any[]>([])
const resource = ref<any[]>([])
const role = ref<any[]>([])
const app = inject('app') as Ref<models.App>
watch(computed(() => app.value.id), (v) => {
sync(v)
})
const sync = (id: any) => {
if (!id) {
return
}
api.role.List(id).then(e => {
role.value = e
})
api.role(id).list().then(e => {
role.value = e
})
api.resource(id).list().then(e => {
resource.value = e
})
}
const show_dialog = (mode: number, idx: string) => {
dialog_obj.value = role.value.find(e => e.id === idx)
dialog.value = true
dialog_mode.value = mode
if (mode) {
api.user.list({ role_id: idx }).then(e => {
users.value = e
})
} else {
api.access(app.value.id).list({ role_id: idx }).then(e => {
access.value = e
})
}
}
// 0: role 1: resource 2: access 3: users
const crud_option = (mode: number) => {
let res = {
api: api.role(app.value.id),
lable: '角色',
obj: role,
}
if (mode === 1) {
res.api = api.resource(app.value.id) as any
res.lable = '资源'
res.obj = resource
} else if (mode === 2) {
res.api = api.access(app.value.id) as any
res.lable = '权限'
res.obj = access
} else if (mode === 3) {
res.api = api.user as any
res.lable = '用户'
res.obj = users
}
return res
}
const created = (k: number, props?: any) => {
let opt = crud_option(k)
let options;
let prompt;
if (k !== 2) {
prompt = { model: '', type: 'text' }
} else {
console.log(k)
options = {
model: '', type: 'radio', items: resource.value.map(e => {
return {
label: e.name,
value: e.name
}
})
}
}
$q.dialog({
title: '创建' + opt.lable,
message: '请输入标识码',
prompt: prompt as any,
options: options as any,
cancel: true,
persistent: true
}).onOk(data => {
opt.api.create(data, props).then(e => {
msg.Info('创建成功')
opt.obj.value.push(e)
}).catch(e => {
msg.Warn('创建失败: ' + e)
})
})
}
const update = (k: number, props: any[]) => {
let opt = crud_option(k)
console.log(props)
for (let i in props) {
let id = opt.obj.value[i][k === 1 ? 'name' : 'id']
console.log(id)
opt.api.update(id, props[i]).then(() => {
Object.assign(opt.obj.value[i], props[i])
}).catch(e => {
msg.Warn('更新失败: ' + e)
})
}
}
const del = (k: number, id: string) => {
let opt = crud_option(k)
$q.dialog({
title: '是否确定删除',
message: '',
cancel: true,
persistent: true
}).onOk(() => {
opt.api.del(id).then(e => {
msg.Info('删除成功')
opt.obj.value.splice(opt.obj.value.findIndex(e => e.name === id
|| e.id === id), 1)
}).catch(e => {
msg.Warn('删除失败: ' + e)
})
})
}
const roleuser = {
add: (u: any) => {
let idx = users.value.findIndex(e => e.id == u.id)
if (idx >= 0) {
return
}
api.role(app.value.id).add(dialog_obj.value?.id || '', u.id).then(e => {
users.value.push(u)
dialog_obj.value.user_count = dialog_obj.value?.user_count + 1
})
},
drop: (u: any) => {
api.role(app.value.id).drop(dialog_obj.value?.id || '', u.id).then(e => {
users.value.splice(users.value.findIndex(e => e.id === u.id), 1)
dialog_obj.value.user_count = dialog_obj.value?.user_count - 1
})
}
}
const filterFn = (val: string, cb: any) => {
if (val && val.length > 1) {
api.user.list({ name: val }).then((e: modelsUser[]) => {
cb(() => {
users_cache.value = e.map(i => {
return Object.assign({
label: i.username,
value: i.id,
}, i)
})
})
})
}
}
onMounted(() => {
sync(app.value.id)
})
</script>
<style scoped></style>

@ -1,4 +1,4 @@
<!--
<!--
* cfg.vue
* Copyright (C) 2024 veypi <i@veypi.com>
* 2024-06-12 18:38
@ -18,8 +18,8 @@
</template>
<template #k_key>
<div class="w-full div-center">
<div class='vbtn' @click="getkey"></div>
<span class="mx-2 select-all" v-if="tmpkey">{{ tmpkey }}</span>
<div v-else class='vbtn' @click="getkey"></div>
</div>
</template>
<template #k_redirect_append>
@ -28,7 +28,7 @@
</template>
</Crud>
</div>
<div v-if="newApp" class="flex justify-center gap-8 mt-6">
<div v-if="Object.keys(newApp).length" class="flex justify-center gap-8 mt-6">
<div class="vbtn" style="background: var(--color-primary);" @click="table.reload">退</div>
<div class="vbtn" style="background: var(--color-warning);" @click="save"></div>
</div>
@ -36,8 +36,11 @@
</template>
<script lang="ts" setup>
import type { models } from '#imports';
import msg from '@veypi/msg';
import { useI18n } from 'vue-i18n';
const { t } = useI18n()
const keys = ref<any>([
{
name: 'name',
@ -47,27 +50,26 @@ const keys = ref<any>([
{ name: 'key', label: '秘钥Key' },
{ name: 'icon', label: 'logo' },
{
name: 'join_method', label: '用户注册', typ: ArgType.Radio,
options: [{ key: 0, name: '允许' }, { key: 1, name: '禁止' },
{ key: 2, name: '申请' }]
name: 'typ', label: '用户注册', typ: ArgType.Radio,
options: { 'public': t('atyp.public'), 'apply': t('atyp.apply'), 'private': t('atyp.private') }
},
{ name: 'host', label: '项目首页' },
{ name: 'init_url', label: '项目首页', validate: /^(https?:\/\/)?(([\da-z\.-]+)|(\d{1,3}(\.\d{1,3}){3}))(:\d+)?([\/\w \.-]*)*\/?$/ },
{ name: 'redirect', label: '跳转地址' },
])
let props = withDefaults(defineProps<{
core: modelsApp,
core: models.App,
}>(),
{}
)
const newApp = ref(null)
const newApp = ref({})
const table = ref()
const save = () => {
api.app.update(props.core.id, newApp.value).then(e => {
api.app.Patch(props.core.id, newApp.value).then(e => {
msg.Info('更新成功')
Object.assign(props.core, newApp.value)
newApp.value = null
newApp.value = {}
}).catch(e => {
msg.Warn('更新失败 ' + e)
})
@ -77,13 +79,15 @@ const tmpkey = ref('')
const getkey = () => {
msg.Prompt('请输入应用名确认', '').then((s) => {
if (s === props.core.name) {
api.app.getKey(props.core.id).then(e => {
api.app.Key(props.core.id).then(e => {
tmpkey.value = e
copyToClipboard(e).then(e => {
navigator.clipboard.writeText(e)
.then(() => {
msg.Info('已复制到剪贴板')
}).catch(e => {
tmpkey.value = e
})
.catch(() => {
tmpkey.value = e
});
}).catch(e => {
msg.Warn('获取失败 ' + e)
})
@ -100,4 +104,3 @@ onMounted(() => {
</script>
<style scoped></style>

Loading…
Cancel
Save