fix(entry): add entry

This commit is contained in:
zhangheng
2026-02-28 13:31:19 +08:00
parent af29bd39c1
commit bcf46df7ec
11 changed files with 115 additions and 94 deletions

View File

@@ -156,7 +156,6 @@ async function httpfetch<T>(options: OptionsProps): Promise<T> {
} }
} else { } else {
const { status } = response const { status } = response
if (status === 400) { if (status === 400) {
if ( if (
response.headers.get("Content-Type")?.includes("application/json") response.headers.get("Content-Type")?.includes("application/json")
@@ -170,6 +169,42 @@ async function httpfetch<T>(options: OptionsProps): Promise<T> {
Message.error({ content: errInfo || "" }) Message.error({ content: errInfo || "" })
throw new Error(errInfo) throw new Error(errInfo)
} }
} else if (status === 401) {
try {
const refreshResponse = await refreshKey({
token: refresh_token,
})
if (refreshResponse.code === 200) {
let access_token = refreshResponse.message?.access || ""
let refresh_token = refreshResponse.message?.refresh || ""
refreshToken({
refresh_token,
access_token,
})
const retry_request = createNewRequest(options, access_token)
const retry_response = await fetch(retry_request)
return options.isDownload
? retry_response.blob()
: retry_response.json()
} else {
const { code } = refreshResponse
if (code === 406) {
try {
await deleteCookie()
} catch (error) {
rejected(error)
} finally {
// 清空身份信息并跳转至登录页面
removeUserInfo()
window.location.href = "/login"
}
} else {
throw new Error("重新获取token失败")
}
}
} catch (error) {
rejected(error)
}
} else if (status === 403) { } else if (status === 403) {
if ( if (
response.headers.get("Content-Type")?.includes("application/json") response.headers.get("Content-Type")?.includes("application/json")

35
app/entry/page.tsx Normal file
View File

@@ -0,0 +1,35 @@
"use client"
import { useUserStore } from "@/app/store/user"
import { usePermissionStore } from "@/components/label/store/auth"
import { getUserPermission } from "@/components/login/api"
import { useCallback, useEffect } from "react"
export default function EntryCheck() {
const user_info = useUserStore.getState().user_info
const { setUserPermissionInfo } = usePermissionStore()
const asyncGetUserPermission = useCallback(async () => {
const { message: permissionRes } = await getUserPermission()
const { uid, name } = permissionRes
setUserPermissionInfo({
user_id: uid,
user_name: name,
detailInfo: permissionRes,
})
}, [setUserPermissionInfo])
useEffect(() => {
if (!user_info.account) {
window.location.href = "/login"
} else {
try {
asyncGetUserPermission()
window.location.href = `${process.env.NEXT_PUBLIC_BASE_PATH}/management`
} catch {
window.location.href = "/login"
}
}
}, [asyncGetUserPermission, user_info.account])
return <></>
}

View File

@@ -1,20 +1,10 @@
"use client" "use client"
import { getUserList, userEditById } from "@/components/label/api/user" import { getUserList } from "@/components/label/api/user"
import { User } from "@/components/label/api/user/typing" import { User } from "@/components/label/api/user/typing"
import useAuth from "@/components/label/hooks/useAuth" import useAuth from "@/components/label/hooks/useAuth"
import { useAllUserStore } from "@/components/label/store/auth" import { useAllUserStore } from "@/components/label/store/auth"
import { import { Badge, Button, Group, Paper, Stack, TextInput } from "@mantine/core"
ActionIcon,
Badge,
Button,
Group,
Paper,
Stack,
Text,
TextInput,
} from "@mantine/core"
import { modals } from "@mantine/modals"
import { notifications } from "@mantine/notifications" import { notifications } from "@mantine/notifications"
import { IconEdit, IconRefresh, IconSearch } from "@tabler/icons-react" import { IconEdit, IconRefresh, IconSearch } from "@tabler/icons-react"
import { DataTable, DataTableColumn } from "mantine-datatable" import { DataTable, DataTableColumn } from "mantine-datatable"
@@ -107,7 +97,7 @@ export default function TeamEmployeePage() {
textAlign: "center", textAlign: "center",
render: (record) => ( render: (record) => (
<Group justify="center" gap={4} wrap="nowrap"> <Group justify="center" gap={4} wrap="nowrap">
{isShow("edit") ? ( {/* {isShow("edit") ? (
<Button <Button
variant="subtle" variant="subtle"
size="compact-xs" size="compact-xs"
@@ -131,17 +121,18 @@ export default function TeamEmployeePage() {
}}> }}>
重置密码 重置密码
</Button> </Button>
) : null} ) : null} */}
{isShow("edit") ? ( {isShow("edit") ? (
<ActionIcon <Button
variant="subtle" variant="transparent"
leftSection={<IconEdit size={16} />}
color="blue" color="blue"
onClick={() => { onClick={() => {
setSelectedUser(record) setSelectedUser(record)
setEditOpened(true) setEditOpened(true)
}}> }}>
<IconEdit size={16} />
</ActionIcon> </Button>
) : null} ) : null}
</Group> </Group>
), ),
@@ -234,6 +225,7 @@ export default function TeamEmployeePage() {
fetching={loading} fetching={loading}
records={records} records={records}
columns={columns} columns={columns}
idAccessor="uid"
noRecordsText="暂无数据" noRecordsText="暂无数据"
totalRecords={totalItems} totalRecords={totalItems}
recordsPerPage={pageSize} recordsPerPage={pageSize}

View File

@@ -107,7 +107,12 @@ export default function CreateModal({ opened, onCloseAction }: ComponentProps) {
radius="xs" radius="xs"
withAsterisk withAsterisk
searchable searchable
data={finalUserOpts} data={finalUserOpts.map((item) => {
return {
label: item.label.toString(),
value: item.value.toString(),
}
})}
{...form.getInputProps("leader_uid")} {...form.getInputProps("leader_uid")}
/> />
<Select <Select

View File

@@ -6,7 +6,7 @@ import { useEffect } from "react"
export default function Home() { export default function Home() {
const router = useRouter() const router = useRouter()
useEffect(() => { useEffect(() => {
router.push("/management") router.push("/entry")
}, [router]) }, [router])
return <></> return <></>
} }

View File

@@ -1,8 +1,8 @@
"use client" "use client"
import { useUserStore } from "@/app/store/user"
import { usePathname } from "next/navigation" import { usePathname } from "next/navigation"
import { useEffect } from "react" import { useEffect } from "react"
import { useUserStore } from "@/app/store/user"
export function InfoCheck() { export function InfoCheck() {
const pathname = usePathname() const pathname = usePathname()

View File

@@ -3,11 +3,11 @@ import { BASE_LABEL_API } from "../const"
import { Organization, User } from "./typing" import { Organization, User } from "./typing"
// 获取用户列表 // 获取用户列表
export const getUserList = (params: User.ListRequest) => { export const getUserList = (data: User.ListRequest) => {
return httpFetch<User.ListResponse>({ return httpFetch<User.ListResponse>({
url: BASE_LABEL_API + "/api/v1/label_server/user/list", url: BASE_LABEL_API + "/api/v1/label_server/user/list",
method: "GET", method: "POST",
data: params, body: JSON.stringify({ ...data, tenant: "cowarobot" }),
}) })
} }

View File

@@ -1,11 +1,10 @@
import { useCallback, useEffect } from "react" import { APP, PLATFORM, TENANT } from "@/components/login/libs/common"
import { DigitalIcon } from "../resource/icons/digital"
import { useLoginStore } from "@/components/login/store" import { useLoginStore } from "@/components/login/store"
import { useRouter } from "next/navigation" import { useRouter } from "next/navigation"
import { APP, PLATFORM, TENANT } from "@/components/login/libs/common" import { useCallback, useEffect } from "react"
import { fetchFeishuLogin } from "../api"
import { DigitalIcon } from "../resource/icons/digital"
import { APP_ID, APP_SECRECT } from "./util" import { APP_ID, APP_SECRECT } from "./util"
import { fetchFeishuLogin, getUserPermission } from "../api"
import { usePermissionStore } from "@/components/label/store/auth"
const HeaderIcon = DigitalIcon const HeaderIcon = DigitalIcon
@@ -22,8 +21,6 @@ const FeishuAutoLogin = ({ useUserStore }: { useUserStore: any }) => {
const { setUserInfo, refreshToken } = useUserStore() const { setUserInfo, refreshToken } = useUserStore()
const router = useRouter() const router = useRouter()
const { setUserPermissionInfo } = usePermissionStore()
const autoLogin = useCallback( const autoLogin = useCallback(
( (
fingerprint: any, fingerprint: any,
@@ -63,13 +60,6 @@ const FeishuAutoLogin = ({ useUserStore }: { useUserStore: any }) => {
access_token: info.access_token || "", access_token: info.access_token || "",
refresh_token: info.refresh_token || "", refresh_token: info.refresh_token || "",
}) })
const { message: permissionRes } = await getUserPermission()
const { uid, name } = permissionRes
setUserPermissionInfo({
user_id: uid,
user_name: name,
detailInfo: permissionRes,
})
window.location.href = "/" window.location.href = "/"
} catch (err) { } catch (err) {
console.log(err) console.log(err)
@@ -82,7 +72,7 @@ const FeishuAutoLogin = ({ useUserStore }: { useUserStore: any }) => {
}) })
}) })
}, },
[refreshToken, setUserPermissionInfo] [refreshToken]
) )
const isFeishu = useCallback(() => !!(window.h5sdk && window.tt), []) const isFeishu = useCallback(() => !!(window.h5sdk && window.tt), [])

View File

@@ -1,16 +1,15 @@
import { useCallback, useEffect, useState } from "react"
import { useSearchParams } from "next/navigation"
import { Flex } from "@mantine/core"
import { useLoginStore } from "@/components/login/store"
import { APP_ID, APP_SECRECT, qr_load, qr_login } from "./util"
import { import {
APP, APP,
PLATFORM, PLATFORM,
TENANT, TENANT,
getQueryVariable, getQueryVariable,
} from "@/components/login/libs/common" } from "@/components/login/libs/common"
import { fetchFeishuLogin, getUserPermission } from "../api" import { useLoginStore } from "@/components/login/store"
import { usePermissionStore } from "@/components/label/store/auth" import { Flex } from "@mantine/core"
import { useSearchParams } from "next/navigation"
import { useCallback, useEffect, useState } from "react"
import { fetchFeishuLogin } from "../api"
import { APP_ID, APP_SECRECT, qr_load, qr_login } from "./util"
const QrLogin = ({ useUserStore }: { useUserStore: any }) => { const QrLogin = ({ useUserStore }: { useUserStore: any }) => {
const fingerprint = useLoginStore.getState().fingerprint const fingerprint = useLoginStore.getState().fingerprint
@@ -39,8 +38,6 @@ const QrLogin = ({ useUserStore }: { useUserStore: any }) => {
const { setUserInfo, refreshToken } = useUserStore() const { setUserInfo, refreshToken } = useUserStore()
const { setUserPermissionInfo } = usePermissionStore()
const feishuLogin = useCallback(async () => { const feishuLogin = useCallback(async () => {
try { try {
const params = { const params = {
@@ -60,24 +57,11 @@ const QrLogin = ({ useUserStore }: { useUserStore: any }) => {
access_token: info.access_token || "", access_token: info.access_token || "",
refresh_token: info.refresh_token || "", refresh_token: info.refresh_token || "",
}) })
const { message: permissionRes } = await getUserPermission()
const { uid, name } = permissionRes
setUserPermissionInfo({
user_id: uid,
user_name: name,
detailInfo: permissionRes,
})
window.location.href = "/" window.location.href = "/"
} catch (err) { } catch (err) {
console.log(err) console.log(err)
} }
}, [ }, [fingerprint, redirect_url, refreshToken, setUserInfo])
fingerprint,
redirect_url,
refreshToken,
setUserInfo,
setUserPermissionInfo,
])
useEffect(() => { useEffect(() => {
if (times === 1) { if (times === 1) {

View File

@@ -26,12 +26,7 @@ import {
import { useForm } from "@mantine/form" import { useForm } from "@mantine/form"
import { useDisclosure } from "@mantine/hooks" import { useDisclosure } from "@mantine/hooks"
import { useCallback, useEffect, useMemo, useState } from "react" import { useCallback, useEffect, useMemo, useState } from "react"
import { import { getVerifyCode, passwdLogin, verificationLogin } from "./api"
getUserPermission,
getVerifyCode,
passwdLogin,
verificationLogin,
} from "./api"
import QrLogin from "./feishu/qr-login" import QrLogin from "./feishu/qr-login"
import { APP, PLATFORM, TENANT } from "./libs/common" import { APP, PLATFORM, TENANT } from "./libs/common"
import { DigitalIcon } from "./resource/icons/digital" import { DigitalIcon } from "./resource/icons/digital"
@@ -44,7 +39,6 @@ import LightBgImage from "./resource/images/light-login-bg.png"
import loginBg2Dark from "./resource/images/login-bg2-dark.png" import loginBg2Dark from "./resource/images/login-bg2-dark.png"
import loginBg2Light from "./resource/images/login-bg2-light.png" import loginBg2Light from "./resource/images/login-bg2-light.png"
import LogoDigImage from "./resource/images/logo-dig.png" import LogoDigImage from "./resource/images/logo-dig.png"
import { usePermissionStore } from "../label/store/auth"
const HeaderIcon = DigitalIcon const HeaderIcon = DigitalIcon
@@ -56,8 +50,6 @@ export default function LoginPage({ useUserStore }: { useUserStore: any }) {
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const [error, setError] = useState<string | null>(null) const [error, setError] = useState<string | null>(null)
const { setUserPermissionInfo } = usePermissionStore()
const [isClient, setIsClient] = useState(false) const [isClient, setIsClient] = useState(false)
useEffect(() => { useEffect(() => {
setIsClient(true) setIsClient(true)
@@ -212,13 +204,6 @@ export default function LoginPage({ useUserStore }: { useUserStore: any }) {
access_token: info.access_token || "", access_token: info.access_token || "",
refresh_token: info.refresh_token || "", refresh_token: info.refresh_token || "",
}) })
const { message: permissionRes } = await getUserPermission()
const { uid, name } = permissionRes
setUserPermissionInfo({
user_id: uid,
user_name: name,
detailInfo: permissionRes,
})
window.location.href = "/" window.location.href = "/"
} catch (error) { } catch (error) {
if (error) { if (error) {
@@ -310,13 +295,6 @@ export default function LoginPage({ useUserStore }: { useUserStore: any }) {
access_token: info.access_token || "", access_token: info.access_token || "",
refresh_token: info.refresh_token || "", refresh_token: info.refresh_token || "",
}) })
const { message: permissionRes } = await getUserPermission()
const { uid, name } = permissionRes
setUserPermissionInfo({
user_id: uid,
user_name: name,
detailInfo: permissionRes,
})
window.location.href = "/" window.location.href = "/"
} catch (err) { } catch (err) {
const message = err instanceof Error ? err.message : "登录失败,请重试" const message = err instanceof Error ? err.message : "登录失败,请重试"

View File

@@ -1,5 +1,5 @@
import { NextRequest, NextResponse } from "next/server"
import { cookies } from "next/headers" import { cookies } from "next/headers"
import { NextRequest, NextResponse } from "next/server"
const publicRoutes = ["/login", "/"] const publicRoutes = ["/login", "/"]
@@ -35,22 +35,24 @@ export default async function middleware(req: NextRequest) {
console.log("Lark environment detected, redirecting with auto login") console.log("Lark environment detected, redirecting with auto login")
return NextResponse.redirect( return NextResponse.redirect(
new URL( new URL(
`${process.env.NEXT_PUBLIC_BASE_PATH}/login?auto=true`, // `${process.env.NEXT_PUBLIC_BASE_PATH}/login?auto=true`,
`/login?auto=true`,
req.nextUrl req.nextUrl
) )
) )
} else { } else {
return NextResponse.redirect( return NextResponse.redirect(
new URL(`${process.env.NEXT_PUBLIC_BASE_PATH}/login`, req.nextUrl) // new URL(`${process.env.NEXT_PUBLIC_BASE_PATH}/login`, req.nextUrl)
new URL(`/login`, req.nextUrl)
) )
} }
} }
// 5. Redirect to /dashboard if the user is authenticated // 5. Redirect to /dashboard if the user is authenticated
if (isPublicRoute && session && !path.startsWith("/management")) { // if (isPublicRoute && session && !path.startsWith("/management")) {
return NextResponse.redirect( // return NextResponse.redirect(
new URL(`${process.env.NEXT_PUBLIC_BASE_PATH}/management`, req.nextUrl) // new URL(`${process.env.NEXT_PUBLIC_BASE_PATH}/management`, req.nextUrl)
) // )
} // }
return NextResponse.next() return NextResponse.next()
} }