1
0
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:
源文雨
2023-03-18 15:38:28 +08:00
parent a072cfe1cf
commit a00b9e4048
14 changed files with 299 additions and 53 deletions

View File

@@ -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)
}

View File

@@ -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()
}

View File

@@ -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)

View File

@@ -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() {
},
},
)
}
}*/

View File

@@ -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

View File

@@ -1,3 +1,4 @@
export default {
name: '个人设置',
password: '修改密码',
}

View File

@@ -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,
},
},
],
}

View File

@@ -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)
},
// 构建路由

View File

@@ -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>

View File

@@ -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: '修改',
},
],

View 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>

View 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()
},
},
]
},
},
]

View 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>

View 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()
},
},
]
},
},
]