mirror of
https://github.com/fumiama/paper-manager.git
synced 2026-06-10 19:10:25 +08:00
add /api/getUsersCount
This commit is contained in:
@@ -7,15 +7,22 @@ import (
|
||||
"github.com/fumiama/paper-manager/backend/utils"
|
||||
)
|
||||
|
||||
// Handler serves all backend /api call
|
||||
func Handler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path[0] != '/' {
|
||||
r.URL.Path = "/" + r.URL.Path
|
||||
type apihandler struct {
|
||||
md string
|
||||
do func(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
func (h *apihandler) handle(w http.ResponseWriter, r *http.Request) {
|
||||
if !utils.IsMethod(h.md, w, r) {
|
||||
return
|
||||
}
|
||||
if r.URL.Path == "/api/getLoginSalt" {
|
||||
if !utils.IsMethod("GET", w, r) {
|
||||
return
|
||||
}
|
||||
h.do(w, r)
|
||||
}
|
||||
|
||||
var apimap = make(map[string]*apihandler, 512)
|
||||
|
||||
func init() {
|
||||
apimap["/api/getLoginSalt"] = &apihandler{"GET", func(w http.ResponseWriter, r *http.Request) {
|
||||
username := r.URL.Query().Get("username")
|
||||
if username == "" {
|
||||
writeresult(w, codeError, nil, "empty username", typeError)
|
||||
@@ -27,59 +34,68 @@ func Handler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
writeresult(w, codeSuccess, salt, messageOk, typeSuccess)
|
||||
return
|
||||
}
|
||||
if r.URL.Path == "/api/login" {
|
||||
if !utils.IsMethod("POST", w, r) {
|
||||
return
|
||||
}}
|
||||
|
||||
apimap["/api/login"] = &apihandler{"POST", func(w http.ResponseWriter, r *http.Request) {
|
||||
type loginbody struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
defer r.Body.Close()
|
||||
var body loginbody
|
||||
defer r.Body.Close()
|
||||
err := json.NewDecoder(r.Body).Decode(&body)
|
||||
if err != nil {
|
||||
writeresult(w, codeError, nil, err.Error(), typeError)
|
||||
return
|
||||
}
|
||||
r, err := login(body.Username, body.Password)
|
||||
ret, err := login(body.Username, body.Password)
|
||||
if err != nil {
|
||||
writeresult(w, codeError, nil, err.Error(), typeError)
|
||||
return
|
||||
}
|
||||
writeresult(w, codeSuccess, r, messageOk, typeSuccess)
|
||||
return
|
||||
}
|
||||
if r.URL.Path == "/api/getUserInfo" {
|
||||
if !utils.IsMethod("GET", w, r) {
|
||||
return
|
||||
}
|
||||
writeresult(w, codeSuccess, ret, messageOk, typeSuccess)
|
||||
}}
|
||||
|
||||
apimap["/api/getUserInfo"] = &apihandler{"GET", func(w http.ResponseWriter, r *http.Request) {
|
||||
token := r.Header.Get("Authorization")
|
||||
r, err := getUserInfo(token)
|
||||
ret, err := getUserInfo(token)
|
||||
if err != nil {
|
||||
writeresult(w, codeError, nil, err.Error(), typeError)
|
||||
return
|
||||
}
|
||||
writeresult(w, codeSuccess, r, messageOk, typeSuccess)
|
||||
return
|
||||
}
|
||||
if r.URL.Path == "/api/logout" {
|
||||
if !utils.IsMethod("GET", w, r) {
|
||||
return
|
||||
}
|
||||
writeresult(w, codeSuccess, ret, messageOk, typeSuccess)
|
||||
}}
|
||||
|
||||
apimap["/api/logout"] = &apihandler{"GET", func(w http.ResponseWriter, r *http.Request) {
|
||||
err := logout(r.Header.Get("Authorization"))
|
||||
if err != nil {
|
||||
writeresult(w, codeError, nil, err.Error(), typeError)
|
||||
return
|
||||
}
|
||||
writeresult(w, codeSuccess, nil, messageOk, typeSuccess)
|
||||
return
|
||||
}
|
||||
if !utils.IsMethod("GET", w, r) {
|
||||
return
|
||||
}
|
||||
http.Error(w, "404 Not Found", http.StatusNotFound)
|
||||
}}
|
||||
|
||||
apimap["/api/getUsersCount"] = &apihandler{"GET", func(w http.ResponseWriter, r *http.Request) {
|
||||
token := r.Header.Get("Authorization")
|
||||
n, err := getUsersCount(token)
|
||||
if err != nil {
|
||||
writeresult(w, codeError, nil, err.Error(), typeError)
|
||||
return
|
||||
}
|
||||
writeresult(w, codeSuccess, n, messageOk, typeSuccess)
|
||||
}}
|
||||
}
|
||||
|
||||
type loginbody struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
// Handler serves all backend /api call
|
||||
func Handler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path[0] != '/' {
|
||||
r.URL.Path = "/" + r.URL.Path
|
||||
}
|
||||
|
||||
if h, ok := apimap[r.URL.Path]; ok {
|
||||
h.handle(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
http.Error(w, "404 Not Found", http.StatusNotFound)
|
||||
}
|
||||
|
||||
@@ -72,3 +72,11 @@ func logout(token string) error {
|
||||
usertokens.Delete(token)
|
||||
return nil
|
||||
}
|
||||
|
||||
func getUsersCount(token string) (int, error) {
|
||||
user := usertokens.Get(token)
|
||||
if user == nil {
|
||||
return 0, errInvalidToken
|
||||
}
|
||||
return global.UserDB.GetUsersCount()
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ func init() {
|
||||
Nick: "源文雨",
|
||||
Avtr: "https://q1.qlogo.cn/g?b=qq&nk=1332524221&s=640",
|
||||
Cont: "028-61830156",
|
||||
Desc: "日は山の端にかかりぬ",
|
||||
Desc: "天何所沓,十二焉分。日月安属,列星安陈。",
|
||||
}, "系统")
|
||||
logrus.Warn("[user] 初次启动, 创建初始账户 fumiama 密码 123456")
|
||||
}
|
||||
@@ -270,6 +270,13 @@ func (u *UserDatabase) GetUsers() (users []User, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// GetUsersCount ...
|
||||
func (u *UserDatabase) GetUsersCount() (int, error) {
|
||||
u.mu.RLock()
|
||||
defer u.mu.RUnlock()
|
||||
return u.db.Count(UserTableUser)
|
||||
}
|
||||
|
||||
func (u *UserDatabase) GetSuperIDs() (ids []int, err error) {
|
||||
var user User
|
||||
ids = make([]int, 0, 16)
|
||||
|
||||
@@ -19,6 +19,7 @@ enum Api {
|
||||
ResetPassword = '/resetPassword',
|
||||
Register = '/register',
|
||||
GetUserInfo = '/getUserInfo',
|
||||
GetUsersCount = '/getUsersCount',
|
||||
GetPermCode = '/getPermCode',
|
||||
TestRetry = '/testRetry',
|
||||
}
|
||||
@@ -82,15 +83,22 @@ export function getUserInfo() {
|
||||
return defHttp.get<GetUserInfoModel>({ url: Api.GetUserInfo }, { errorMessageMode: 'none' })
|
||||
}
|
||||
|
||||
export function getPermCode() {
|
||||
return defHttp.get<string[]>({ url: Api.GetPermCode })
|
||||
/**
|
||||
* @description: getUsersCount
|
||||
*/
|
||||
export function getUsersCount() {
|
||||
return defHttp.get<number>({ url: Api.GetUsersCount }, { errorMessageMode: 'none' })
|
||||
}
|
||||
|
||||
/*export function getPermCode() {
|
||||
return defHttp.get<string[]>({ url: Api.GetPermCode })
|
||||
}*/
|
||||
|
||||
export function doLogout() {
|
||||
return defHttp.get({ url: Api.Logout })
|
||||
}
|
||||
|
||||
export function testRetry() {
|
||||
/*export function testRetry() {
|
||||
return defHttp.get(
|
||||
{ url: Api.TestRetry },
|
||||
{
|
||||
@@ -101,4 +109,4 @@ export function testRetry() {
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
}*/
|
||||
|
||||
@@ -7,6 +7,8 @@ export enum PageEnum {
|
||||
PAGE_FILELIST = '/filelist',
|
||||
// personal settings path
|
||||
PAGE_SETTINGS = '/settings',
|
||||
// password settings path
|
||||
PAGE_PASSWORD_SETTINGS = '/settings/password',
|
||||
// error page path
|
||||
ERROR_PAGE = '/exception',
|
||||
// error log page path
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export default {
|
||||
name: '个人设置',
|
||||
password: '修改密码',
|
||||
}
|
||||
|
||||
@@ -25,6 +25,16 @@ const settings: AppRouteModule = {
|
||||
hideMenu: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'password',
|
||||
name: 'PasswordSettingsPage',
|
||||
component: () => import('/@/views/page/settings/password/index.vue'),
|
||||
meta: {
|
||||
title: t('routes.settings.password'),
|
||||
icon: 'ion:settings-outline',
|
||||
hideMenu: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import { PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic'
|
||||
import { filter } from '/@/utils/helper/treeHelper'
|
||||
|
||||
import { getMenuList } from '/@/api/sys/menu'
|
||||
import { getPermCode } from '/@/api/sys/user'
|
||||
// import { getPermCode } from '/@/api/sys/user'
|
||||
|
||||
import { useMessage } from '/@/hooks/web/useMessage'
|
||||
import { PageEnum } from '/@/enums/pageEnum'
|
||||
@@ -104,8 +104,8 @@ export const usePermissionStore = defineStore({
|
||||
this.lastBuildMenuTime = 0
|
||||
},
|
||||
async changePermissionCode() {
|
||||
const codeList = await getPermCode()
|
||||
this.setPermCodeList(codeList)
|
||||
// const codeList = await getPermCode()
|
||||
// this.setPermCodeList(codeList)
|
||||
},
|
||||
|
||||
// 构建路由
|
||||
|
||||
@@ -12,22 +12,27 @@
|
||||
})()
|
||||
}}安, {{ userinfo.realName }}, 要注意劳逸结合哦!</h1
|
||||
>
|
||||
<span class="text-secondary"> 今日共有1人上线 </span>
|
||||
<span class="text-secondary"> {{ userinfo.desc }} </span>
|
||||
</div>
|
||||
<div class="flex flex-1 justify-end md:mt-0 mt-4">
|
||||
<div class="flex flex-col justify-center text-right md:mr-10 mr-4">
|
||||
<span class="text-secondary"> 课程组人数 </span>
|
||||
<span class="text-2xl">300</span>
|
||||
<span class="text-2xl"> {{ userscount }} </span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
import { ref, computed } from 'vue'
|
||||
import { Avatar } from 'ant-design-vue'
|
||||
import { useUserStore } from '/@/store/modules/user'
|
||||
import headerImg from '/@/assets/images/header.jpg'
|
||||
import { getUsersCount } from '/@/api/sys/user'
|
||||
|
||||
const userStore = useUserStore()
|
||||
const userinfo = computed(() => userStore.getUserInfo)
|
||||
const userscount = ref(0)
|
||||
getUsersCount().then((value: number) => {
|
||||
userscount.value = value
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<ListItemMeta>
|
||||
<template #title>
|
||||
{{ item.title }}
|
||||
<div class="extra" v-if="item.extra">
|
||||
<div class="extra" v-if="item.extra" @click="item.click">
|
||||
{{ item.extra }}
|
||||
</div>
|
||||
</template>
|
||||
@@ -24,12 +24,16 @@
|
||||
import { defineComponent } from 'vue'
|
||||
import { CollapseContainer } from '/@/components/Container/index'
|
||||
import { useUserStore } from '/@/store/modules/user'
|
||||
import { PageEnum } from '/@/enums/pageEnum'
|
||||
import { useGo } from '/@/hooks/web/usePage'
|
||||
|
||||
export default defineComponent({
|
||||
components: { CollapseContainer, List, ListItem: List.Item, ListItemMeta: List.Item.Meta },
|
||||
setup() {
|
||||
const userStore = useUserStore()
|
||||
const { last, contact } = userStore.getUserInfo
|
||||
const go = useGo()
|
||||
|
||||
return {
|
||||
list: [
|
||||
{
|
||||
@@ -37,11 +41,14 @@
|
||||
title: '账户密码',
|
||||
description: '上次修改密码: ' + last,
|
||||
extra: '修改',
|
||||
click: () => {
|
||||
go(PageEnum.PAGE_PASSWORD_SETTINGS)
|
||||
},
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
title: '我的手机',
|
||||
description: '已绑定手机: ' + contact,
|
||||
title: '联系方式',
|
||||
description: '已记录的联系方式: ' + contact,
|
||||
extra: '修改',
|
||||
},
|
||||
],
|
||||
|
||||
45
frontend/vben/src/views/page/settings/contact/index.vue
Normal file
45
frontend/vben/src/views/page/settings/contact/index.vue
Normal file
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<PageWrapper title="修改当前联系方式" content="修改成功后会自动退出当前登录!">
|
||||
<div class="py-8 bg-white flex flex-col justify-center items-center">
|
||||
<BasicForm @register="register" />
|
||||
<div class="flex justify-center">
|
||||
<a-button @click="resetFields"> 重置 </a-button>
|
||||
<a-button class="!ml-4" type="primary" @click="handleSubmit"> 确认 </a-button>
|
||||
</div>
|
||||
</div>
|
||||
</PageWrapper>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import { PageWrapper } from '/@/components/Page'
|
||||
import { BasicForm, useForm } from '/@/components/Form'
|
||||
|
||||
import { formSchema } from './pwd.data'
|
||||
export default defineComponent({
|
||||
name: 'ChangeContact',
|
||||
components: { BasicForm, PageWrapper },
|
||||
setup() {
|
||||
const [register, { validate, resetFields }] = useForm({
|
||||
size: 'large',
|
||||
baseColProps: { span: 24 },
|
||||
labelWidth: 100,
|
||||
showActionButtonGroup: false,
|
||||
schemas: formSchema,
|
||||
})
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const values = await validate()
|
||||
const { passwordOld, passwordNew } = values
|
||||
|
||||
// TODO custom api
|
||||
console.log(passwordOld, passwordNew)
|
||||
// const { router } = useRouter()
|
||||
// router.push(pageEnum.BASE_LOGIN)
|
||||
} catch (error) {}
|
||||
}
|
||||
|
||||
return { register, resetFields, handleSubmit }
|
||||
},
|
||||
})
|
||||
</script>
|
||||
46
frontend/vben/src/views/page/settings/contact/pwd.data.ts
Normal file
46
frontend/vben/src/views/page/settings/contact/pwd.data.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { FormSchema } from '/@/components/Form'
|
||||
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'passwordOld',
|
||||
label: '当前密码',
|
||||
component: 'InputPassword',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
field: 'passwordNew',
|
||||
label: '新密码',
|
||||
component: 'StrengthMeter',
|
||||
componentProps: {
|
||||
placeholder: '新密码',
|
||||
},
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入新密码',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
field: 'confirmPassword',
|
||||
label: '确认密码',
|
||||
component: 'InputPassword',
|
||||
|
||||
dynamicRules: ({ values }) => {
|
||||
return [
|
||||
{
|
||||
required: true,
|
||||
validator: (_, value) => {
|
||||
if (!value) {
|
||||
return Promise.reject('密码不能为空')
|
||||
}
|
||||
if (value !== values.passwordNew) {
|
||||
return Promise.reject('两次输入的密码不一致!')
|
||||
}
|
||||
return Promise.resolve()
|
||||
},
|
||||
},
|
||||
]
|
||||
},
|
||||
},
|
||||
]
|
||||
45
frontend/vben/src/views/page/settings/password/index.vue
Normal file
45
frontend/vben/src/views/page/settings/password/index.vue
Normal file
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<PageWrapper title="修改当前用户密码" content="修改成功后会自动退出当前登录!">
|
||||
<div class="py-8 bg-white flex flex-col justify-center items-center">
|
||||
<BasicForm @register="register" />
|
||||
<div class="flex justify-center">
|
||||
<a-button @click="resetFields"> 重置 </a-button>
|
||||
<a-button class="!ml-4" type="primary" @click="handleSubmit"> 确认 </a-button>
|
||||
</div>
|
||||
</div>
|
||||
</PageWrapper>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import { PageWrapper } from '/@/components/Page'
|
||||
import { BasicForm, useForm } from '/@/components/Form'
|
||||
|
||||
import { formSchema } from './pwd.data'
|
||||
export default defineComponent({
|
||||
name: 'ChangePassword',
|
||||
components: { BasicForm, PageWrapper },
|
||||
setup() {
|
||||
const [register, { validate, resetFields }] = useForm({
|
||||
size: 'large',
|
||||
baseColProps: { span: 24 },
|
||||
labelWidth: 100,
|
||||
showActionButtonGroup: false,
|
||||
schemas: formSchema,
|
||||
})
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const values = await validate()
|
||||
const { passwordOld, passwordNew } = values
|
||||
|
||||
// TODO custom api
|
||||
console.log(passwordOld, passwordNew)
|
||||
// const { router } = useRouter()
|
||||
// router.push(pageEnum.BASE_LOGIN)
|
||||
} catch (error) {}
|
||||
}
|
||||
|
||||
return { register, resetFields, handleSubmit }
|
||||
},
|
||||
})
|
||||
</script>
|
||||
46
frontend/vben/src/views/page/settings/password/pwd.data.ts
Normal file
46
frontend/vben/src/views/page/settings/password/pwd.data.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { FormSchema } from '/@/components/Form'
|
||||
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'passwordOld',
|
||||
label: '当前密码',
|
||||
component: 'InputPassword',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
field: 'passwordNew',
|
||||
label: '新密码',
|
||||
component: 'StrengthMeter',
|
||||
componentProps: {
|
||||
placeholder: '新密码',
|
||||
},
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入新密码',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
field: 'confirmPassword',
|
||||
label: '确认密码',
|
||||
component: 'InputPassword',
|
||||
|
||||
dynamicRules: ({ values }) => {
|
||||
return [
|
||||
{
|
||||
required: true,
|
||||
validator: (_, value) => {
|
||||
if (!value) {
|
||||
return Promise.reject('密码不能为空')
|
||||
}
|
||||
if (value !== values.passwordNew) {
|
||||
return Promise.reject('两次输入的密码不一致!')
|
||||
}
|
||||
return Promise.resolve()
|
||||
},
|
||||
},
|
||||
]
|
||||
},
|
||||
},
|
||||
]
|
||||
Reference in New Issue
Block a user