chore: initialize GSREA website project

This commit is contained in:
zlwu committed 2026-10-30 11:05:55 +08:00
commit d3c5461de5
1842 files changed
+246140

No files matched your search

+31
View File
@@ -0,0 +1,31 @@
import request from '@/utils/http'
export function fetchAboutPage(pageKey: string) {
return request.get<Record<string, any>>({ url: `/api/admin/about/pages/${pageKey}` })
}
export function saveAboutPage(pageKey: string, data: Record<string, unknown>) {
return request.put({ url: `/api/admin/about/pages/${pageKey}`, data })
}
export function fetchAboutArticles(category: string) {
return request.get<{ category: string; items: any[] }>({
url: `/api/admin/about/articles/${category}`
})
}
export function fetchAboutExperts() {
return request.get<{ items: any[] }>({ url: '/api/admin/about/experts' })
}
export function createAboutExpert(data: Record<string, unknown>) {
return request.post<{ id: number }>({ url: '/api/admin/about/experts', data })
}
export function updateAboutExpert(id: number, data: Record<string, unknown>) {
return request.put({ url: `/api/admin/about/experts/${id}`, data })
}
export function deleteAboutExpert(id: number) {
return request.del({ url: `/api/admin/about/experts/${id}` })
}
+29
View File
@@ -0,0 +1,29 @@
import request from '@/utils/http'
import type { AdminCaptcha, AdminLoginResult } from '@/types/admin'
export interface LoginBody {
username: string
password: string
captchaId: string
captchaCode: string
}
export function fetchCaptcha() {
return request.get<AdminCaptcha>({
url: '/api/admin/auth/captcha'
})
}
export function fetchLogin(data: LoginBody) {
return request.post<AdminLoginResult>({
url: '/api/admin/auth/login',
data
})
}
export function fetchChangePassword(data: { oldPassword: string; newPassword: string }) {
return request.post<{ ok?: boolean }>({
url: '/api/admin/auth/password',
data
})
}
+24
View File
@@ -0,0 +1,24 @@
import request from '@/utils/http'
export function fetchDisciplineNotice() {
return request.get<Record<string, any>>({ url: '/api/admin/discipline/notice' })
}
export function saveDisciplineNotice(data: Record<string, unknown>) {
return request.put<Record<string, any>>({ url: '/api/admin/discipline/notice', data })
}
export function fetchDisciplineComplaints(status?: string) {
return request.get<{ items: any[]; pendingCount: number; workdays: number }>({
url: '/api/admin/discipline/complaints',
params: status ? { status } : undefined
})
}
export function fetchDisciplineComplaint(id: number) {
return request.get<Record<string, any>>({ url: `/api/admin/discipline/complaints/${id}` })
}
export function processDisciplineComplaint(id: number) {
return request.post({ url: `/api/admin/discipline/complaints/${id}/process` })
}
+20
View File
@@ -0,0 +1,20 @@
import request from '@/utils/http'
export function fetchExpertPendingCount() {
return request.get<{ count: number }>({ url: '/api/admin/expert-questions/pending-count' })
}
export function fetchExpertQuestions(status?: string) {
return request.get<{ items: any[]; pendingCount: number; replyWorkdays: number }>({
url: '/api/admin/expert-questions',
params: status ? { status } : undefined
})
}
export function fetchExpertQuestion(id: number) {
return request.get<Record<string, any>>({ url: `/api/admin/expert-questions/${id}` })
}
export function replyExpertQuestion(id: number, data: Record<string, unknown>) {
return request.post({ url: `/api/admin/expert-questions/${id}/reply`, data })
}
+77
View File
@@ -0,0 +1,77 @@
import request from '@/utils/http'
export function fetchAdminHome() {
return request.get<Record<string, any>>({ url: '/api/admin/home' })
}
export function saveAdminHome(data: Record<string, unknown>) {
return request.put({ url: '/api/admin/home', data })
}
export function saveArticleDisplay(data: Record<string, number>) {
return request.put({ url: '/api/admin/home/articles/display', data })
}
export function createHomeArticle(data: Record<string, unknown>) {
return request.post<{ id: number }>({ url: '/api/admin/home/articles', data })
}
export function updateHomeArticle(id: number, data: Record<string, unknown>) {
return request.put({ url: `/api/admin/home/articles/${id}`, data })
}
export function deleteHomeArticle(id: number) {
return request.del({ url: `/api/admin/home/articles/${id}` })
}
export function createHomeSlide(data: Record<string, unknown>) {
return request.post<{ id: number }>({ url: '/api/admin/home/slides', data })
}
export function updateHomeSlide(id: number, data: Record<string, unknown>) {
return request.put({ url: `/api/admin/home/slides/${id}`, data })
}
export function deleteHomeSlide(id: number) {
return request.del({ url: `/api/admin/home/slides/${id}` })
}
export function saveAudiences(data: Record<string, unknown>) {
return request.put({ url: '/api/admin/home/audiences', data })
}
export function saveHotLinks(data: Record<string, unknown>) {
return request.put({ url: '/api/admin/home/hot-links', data })
}
export function saveHomeMenu(data: Record<string, unknown>) {
return request.put({ url: '/api/admin/home/menu', data })
}
export function fetchEduPlatforms() {
return request.get<{ items: Record<string, any>[] }>({ url: '/api/admin/edu/platforms' })
}
export function saveEduPlatforms(data: Record<string, unknown>) {
return request.put({ url: '/api/admin/edu/platforms', data })
}
export function saveHonors(data: Record<string, unknown>) {
return request.put({ url: '/api/admin/home/honors', data })
}
export function saveMembers(data: Record<string, unknown>) {
return request.put({ url: '/api/admin/home/members', data })
}
export function saveContact(data: Record<string, unknown>) {
return request.put({ url: '/api/admin/home/contact', data })
}
export function saveRelatedLinks(data: Record<string, unknown>) {
return request.put({ url: '/api/admin/home/related-links', data })
}
export function saveCompliance(data: Record<string, unknown>) {
return request.put({ url: '/api/admin/home/compliance', data })
}
+9
View File
@@ -0,0 +1,9 @@
import request from '@/utils/http'
export function fetchLegalPage(pageKey: string) {
return request.get<Record<string, any>>({ url: `/api/admin/legal/${pageKey}` })
}
export function saveLegalPage(pageKey: string, data: Record<string, unknown>) {
return request.put({ url: `/api/admin/legal/${pageKey}`, data })
}
+25
View File
@@ -0,0 +1,25 @@
import request from '@/utils/http'
export interface ReportFiling {
id: number
institutionName: string
reportNumber: string
issuedOn: string
published: boolean
}
export function fetchReportFilings() {
return request.get<{ items: ReportFiling[] }>({ url: '/api/admin/reports' })
}
export function createReportFiling(data: Omit<ReportFiling, 'id'>) {
return request.post<{ id: number }>({ url: '/api/admin/reports', data })
}
export function updateReportFiling(id: number, data: Omit<ReportFiling, 'id'>) {
return request.put({ url: `/api/admin/reports/${id}`, data })
}
export function deleteReportFiling(id: number) {
return request.del({ url: `/api/admin/reports/${id}` })
}
+241
View File
@@ -0,0 +1,241 @@
import type { AxiosProgressEvent } from 'axios'
import request from '@/utils/http'
import type {
AdminFile,
AdminFileQuery,
AdminResource,
AdminResourcePayload,
AdminRole,
AdminRolePayload,
AdminRoleQuery,
AdminUser,
AdminUserPayload,
AdminUserQuery,
AuditLogItem,
AuditLogQuery,
FilterPreview,
IpBlacklistItem,
LoginSecurity,
PageResult,
SensitiveWord,
SiteSettings
} from '@/types/admin'
function cleanQuery(params?: object): Record<string, unknown> {
const query: Record<string, unknown> = {}
if (!params) return query
Object.entries(params as Record<string, unknown>).forEach(([key, value]) => {
if (value === undefined || value === null || value === '') return
query[key] = value
})
return query
}
function asPage<T>(payload: unknown): PageResult<T> {
if (Array.isArray(payload)) {
return { records: payload as T[], current: 1, size: payload.length, total: payload.length }
}
if (payload && typeof payload === 'object') {
const data = payload as Partial<PageResult<T>>
const records = Array.isArray(data.records) ? data.records : []
return {
records,
current: Number(data.current ?? 1),
size: Number(data.size ?? records.length),
total: Number(data.total ?? records.length)
}
}
return { records: [], current: 1, size: 0, total: 0 }
}
function asList<T>(payload: unknown): T[] {
if (Array.isArray(payload)) return payload as T[]
if (
payload &&
typeof payload === 'object' &&
Array.isArray((payload as { records?: T[] }).records)
) {
return (payload as { records: T[] }).records
}
return []
}
export function fetchGetUserList(params: AdminUserQuery) {
return request
.get<unknown>({ url: '/api/admin/users', params: cleanQuery(params) })
.then((data) => asPage<AdminUser>(data))
}
export function fetchCreateUser(data: AdminUserPayload) {
return request.post<AdminUser>({ url: '/api/admin/users', data })
}
export function fetchUpdateUser(id: number, data: Partial<AdminUserPayload>) {
return request.put<AdminUser>({ url: `/api/admin/users/${id}`, data })
}
export function fetchResetUserPassword(id: number, newPassword: string) {
return request.post({ url: `/api/admin/users/${id}/password`, data: { newPassword } })
}
export function fetchGetRoleList(params: AdminRoleQuery) {
return request
.get<unknown>({ url: '/api/admin/roles', params: cleanQuery(params) })
.then((data) => asPage<AdminRole>(data))
}
export async function fetchAllRoles() {
const first = await fetchGetRoleList({ current: 1, size: 100 })
const records = [...first.records]
const size = first.size || 200
const pages = Math.ceil((first.total || records.length) / size)
for (let current = 2; current <= pages && current <= 20; current += 1) {
const next = await fetchGetRoleList({ current, size })
records.push(...next.records)
}
return records
}
export function fetchCreateRole(data: AdminRolePayload) {
return request.post<AdminRole>({ url: '/api/admin/roles', data })
}
export function fetchUpdateRole(id: number, data: AdminRolePayload) {
return request.put<AdminRole>({ url: `/api/admin/roles/${id}`, data })
}
export function fetchUpdateRoleResources(id: number, resourceIds: number[]) {
return request.put({ url: `/api/admin/roles/${id}/resources`, data: { resourceIds } })
}
export function fetchGetResources() {
return request
.get<unknown>({ url: '/api/admin/resources' })
.then((data) => asList<AdminResource>(data))
}
export function fetchCreateResource(data: AdminResourcePayload) {
return request.post<AdminResource>({ url: '/api/admin/resources', data })
}
export function fetchUpdateResource(id: number, data: AdminResourcePayload) {
return request.put<AdminResource>({ url: `/api/admin/resources/${id}`, data })
}
export function fetchDeleteResource(id: number) {
return request.del({ url: `/api/admin/resources/${id}` })
}
export function fetchGetAuditLogs(params: AuditLogQuery) {
return request
.get<unknown>({ url: '/api/admin/audit-logs', params: cleanQuery(params) })
.then((data) => asPage<AuditLogItem>(data))
}
export function fetchGetLoginSecurity() {
return request.get<LoginSecurity>({ url: '/api/admin/login-security' })
}
export function fetchUpdateLoginSecurity(data: LoginSecurity) {
return request.put<LoginSecurity>({ url: '/api/admin/login-security', data })
}
export function fetchGetIpBlacklist() {
return request
.get<unknown>({ url: '/api/admin/ip-blacklist' })
.then((data) => asList<IpBlacklistItem>(data))
}
export function fetchCreateIpBlacklist(data: { ip: string; remark: string }) {
return request.post<IpBlacklistItem>({ url: '/api/admin/ip-blacklist', data })
}
export function fetchDeleteIpBlacklist(id: number) {
return request.del({ url: `/api/admin/ip-blacklist/${id}` })
}
export function uploadAdminFile(
file: File,
bucket: 'public' | 'private',
onProgress?: (percent: number) => void,
showErrorMessage = true
) {
const data = new FormData()
data.append('file', file)
data.append('bucket', bucket)
return request.post<AdminFile>({
url: '/api/admin/files',
data,
timeout: 120000,
showErrorMessage,
onUploadProgress: (event: AxiosProgressEvent) => {
if (!onProgress || !event.total) return
onProgress(Math.min(100, Math.round((event.loaded / event.total) * 100)))
}
})
}
export function fetchGetFileList(params: AdminFileQuery) {
return request
.get<unknown>({ url: '/api/admin/files', params: cleanQuery(params) })
.then((data) => asPage<AdminFile>(data))
}
export function fetchGetFile(id: number) {
return request.get<AdminFile>({ url: `/api/admin/files/${id}` })
}
export function fetchDeleteFile(id: number) {
return request.del({ url: `/api/admin/files/${id}` })
}
export function fetchGetSiteSettings() {
return request.get<SiteSettings>({ url: '/api/admin/site-settings' })
}
export function fetchUpdateSiteSettings(data: Partial<SiteSettings>) {
return request.put<SiteSettings>({ url: '/api/admin/site-settings', data })
}
export function fetchGetSensitiveWords(params?: {
current?: number
size?: number
word?: string
}) {
const word = params?.word?.trim().toLowerCase() || ''
const query = { ...(params || {}) }
delete query.word
return request
.get<unknown>({ url: '/api/admin/sensitive-words', params: cleanQuery(query) })
.then((data) => {
const page = asPage<SensitiveWord>(data)
const records = word
? page.records.filter((item) => item.word.toLowerCase().includes(word))
: page.records
if (!Array.isArray(data) || !params?.current || !params.size) {
return { ...page, records, total: records.length }
}
const start = (params.current - 1) * params.size
return {
records: records.slice(start, start + params.size),
current: params.current,
size: params.size,
total: records.length
}
})
}
export function fetchCreateSensitiveWord(word: string) {
return request.post<SensitiveWord>({ url: '/api/admin/sensitive-words', data: { word } })
}
export function fetchDeleteSensitiveWord(id: number) {
return request.del({ url: `/api/admin/sensitive-words/${id}` })
}
export function fetchPreviewFilter(html: string) {
return request.post<FilterPreview>({
url: '/api/admin/content/preview-filter',
data: { html }
})
}
+13
View File
@@ -0,0 +1,13 @@
import request from '@/utils/http'
export function fetchUploadedCases(kind: string, current = 1, size = 10, q = '') {
const keyword = q.trim()
return request.get<{ items: any[]; total: number; current: number; size: number }>({
url: '/api/admin/uploaded-cases',
params: { kind, current, size, ...(keyword ? { q: keyword } : {}) }
})
}
export function fetchUploadedCase(id: number) {
return request.get<Record<string, any>>({ url: `/api/admin/uploaded-cases/${id}` })
}