From bb422b7c319c2f2b88d13da88a2b89a5af6d914a Mon Sep 17 00:00:00 2001 From: kely Date: Sat, 26 Jul 2025 22:20:57 +0800 Subject: [PATCH] =?UTF-8?q?feat(client):=20=E6=B7=BB=E5=8A=A0=E7=BD=91?= =?UTF-8?q?=E7=AB=99=E9=85=8D=E7=BD=AE=E5=B9=B6=E4=BC=98=E5=8C=96=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 config.json 文件用于网站配置 - 添加 ConfigService 服务加载配置信息 - 更新 App 组件和 Login 组件以使用新配置 - 修改版权组件以动态显示备案号和公司名称 - 优化组织信息组件,添加技术支持联系功能 - 更新页面标题策略以使用配置中的网站名称 --- projects/admin/src/assets/config.json | 17 +++ projects/cdk/src/app-settings/index.ts | 2 +- .../copyright/copyright.component.html | 10 +- .../copyright/copyright.component.ts | 12 +- projects/cdk/src/types/index.ts | 105 ++++++++++------- projects/client/src/app/app.component.ts | 27 ++++- projects/client/src/app/app.module.ts | 15 ++- .../app-layout/app-layout.component.html | 4 +- .../app-layout/app-layout.component.ts | 64 ++++++----- .../src/app/pages/login/login.component.html | 54 +++------ .../src/app/pages/login/login.component.ts | 68 ++++++----- .../system/org-info/org-info.component.html | 4 +- .../system/org-info/org-info.component.ts | 106 ++++++++++-------- .../src/app/services/client-api.service.ts | 94 ++++++++-------- .../client/src/app/services/config.service.ts | 38 +++++++ .../client/src/app/services/title.service.ts | 23 ++-- projects/client/src/assets/config.json | 17 +++ projects/client/src/{ => assets}/favicon.ico | Bin projects/client/src/index.html | 26 ++--- 19 files changed, 404 insertions(+), 282 deletions(-) create mode 100644 projects/admin/src/assets/config.json create mode 100644 projects/client/src/app/services/config.service.ts create mode 100644 projects/client/src/assets/config.json rename projects/client/src/{ => assets}/favicon.ico (100%) diff --git a/projects/admin/src/assets/config.json b/projects/admin/src/assets/config.json new file mode 100644 index 0000000..2a7ec2a --- /dev/null +++ b/projects/admin/src/assets/config.json @@ -0,0 +1,17 @@ +{ + "websiteInfo": { + "name": "营养配餐实训系统" + }, + "assets": { + "logo": "/assets/images/jl-logo.png", + "favicon": "/assets/favicon.ico", + "loginBackground": "/assets/images/jl-logo.png" + }, + "contactInfo": { + "phoneNumber": "19181752603" + }, + "copyrightInfo": { + "icpLicense": "蜀ICP备2023038072号", + "companyName": "" + } +} diff --git a/projects/cdk/src/app-settings/index.ts b/projects/cdk/src/app-settings/index.ts index 799de80..205e2f2 100644 --- a/projects/cdk/src/app-settings/index.ts +++ b/projects/cdk/src/app-settings/index.ts @@ -1 +1 @@ -export const appName = "营养配餐系统"; +export const appName = '营养配餐系统' diff --git a/projects/cdk/src/shared/components/copyright/copyright.component.html b/projects/cdk/src/shared/components/copyright/copyright.component.html index 4aae36c..94a2723 100644 --- a/projects/cdk/src/shared/components/copyright/copyright.component.html +++ b/projects/cdk/src/shared/components/copyright/copyright.component.html @@ -1,10 +1,6 @@
- - 蜀ICP备2023038072号 + + {{ icpLicense }} - ©{{ year }} 成都积络科技有限公司 + ©{{ year }} {{ companyName }}
diff --git a/projects/cdk/src/shared/components/copyright/copyright.component.ts b/projects/cdk/src/shared/components/copyright/copyright.component.ts index 8453cdd..44e651e 100644 --- a/projects/cdk/src/shared/components/copyright/copyright.component.ts +++ b/projects/cdk/src/shared/components/copyright/copyright.component.ts @@ -1,10 +1,12 @@ -import { Component } from "@angular/core"; +import { Component, Input } from '@angular/core' @Component({ - selector: "lib-copyright", - templateUrl: "./copyright.component.html", - styleUrls: ["./copyright.component.less"], + selector: 'lib-copyright', + templateUrl: './copyright.component.html', + styleUrls: ['./copyright.component.less'], }) export class CopyrightComponent { - year = new Date().getFullYear(); + @Input() icpLicense?: string + @Input() companyName?: string + year = new Date().getFullYear() } diff --git a/projects/cdk/src/types/index.ts b/projects/cdk/src/types/index.ts index d7d4b73..18c3840 100644 --- a/projects/cdk/src/types/index.ts +++ b/projects/cdk/src/types/index.ts @@ -1,59 +1,86 @@ -export type AnyObject = { [k: string]: any }; +export type AnyObject = { [k: string]: any } -export type DecSafeAny = any; +export type DecSafeAny = any -export type DecText = number | string; +export type DecText = number | string -export type Augmented = O & AnyObject; +export type Augmented = O & AnyObject -export type Optional = Omit & Partial>; +export type Optional = Omit & Partial> export type NutrientInterface = { - key: string; - measurement: string; - nrv: number; - value: string; -}; + key: string + measurement: string + nrv: number + value: string +} export type OptionItemInterface = Augmented<{ - label: string; - value: string; -}>; + label: string + value: string +}> export interface ResponseType { - body: T; - code: number; - desc: string; - success: boolean; + body: T + code: number + desc: string + success: boolean } -export type MyResponse = ResponseType; +export type MyResponse = ResponseType export interface TableListColumns { - key: string; - title: string; - visible?: boolean; - width?: string; - sort?: boolean; - order?: number; - disabled?: boolean; - coverStorage?: boolean; + key: string + title: string + visible?: boolean + width?: string + sort?: boolean + order?: number + disabled?: boolean + coverStorage?: boolean } export interface TableOperation { - title: string; - href?: string; - link?: string[]; - target?: string; - premissions: string[]; - danger?: boolean; - disabled?: boolean; - onClick?: (v: DecSafeAny) => void; - visible?: (v: DecSafeAny) => boolean; + title: string + href?: string + link?: string[] + target?: string + premissions: string[] + danger?: boolean + disabled?: boolean + onClick?: (v: DecSafeAny) => void + visible?: (v: DecSafeAny) => boolean } export interface PageResult { - total: number; - content: T[]; - totalElements: number; - totalPages: number; + total: number + content: T[] + totalElements: number + totalPages: number +} + +export interface WebSiteConfig { + websiteInfo: WebsiteInfo + assets: Assets + contactInfo: ContactInfo + copyrightInfo: CopyrightInfo +} + +export interface Assets { + logo: string + favicon: string + loginBackground: string +} + +export interface ContactInfo { + phoneNumber: string +} + +export interface CopyrightInfo { + icpLicense: string + companyName: string + yeah: number +} + +export interface WebsiteInfo { + name: string } diff --git a/projects/client/src/app/app.component.ts b/projects/client/src/app/app.component.ts index c2c895d..8035a9c 100644 --- a/projects/client/src/app/app.component.ts +++ b/projects/client/src/app/app.component.ts @@ -1,10 +1,27 @@ -import { Component } from '@angular/core'; +import { Component } from '@angular/core' +import { WebSiteConfig } from '@cdk/types' +import { ConfigService } from './services/config.service' @Component({ - selector: 'app-root', - templateUrl: './app.component.html', - styleUrls: ['./app.component.less'] + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.less'], }) export class AppComponent { - title = 'client'; + title = 'client' + + appConfig: WebSiteConfig | null = null + constructor(private configService: ConfigService) {} + + ngOnInit() { + this.appConfig = this.configService.getConfig() + if (this.appConfig) { + if (this.appConfig?.assets?.favicon) { + ;(document.querySelector('#favicon') as HTMLLinkElement).href = this.appConfig.assets.favicon + } + if (this.appConfig?.websiteInfo?.name) { + document.title = this.appConfig.websiteInfo.name + (document.title ? ' - ' + document.title : '') + } + } + } } diff --git a/projects/client/src/app/app.module.ts b/projects/client/src/app/app.module.ts index 686b69e..9e4c39d 100644 --- a/projects/client/src/app/app.module.ts +++ b/projects/client/src/app/app.module.ts @@ -1,4 +1,4 @@ -import { NgModule } from '@angular/core' +import { APP_INITIALIZER, NgModule } from '@angular/core' import { BrowserModule } from '@angular/platform-browser' import { NZ_DATE_CONFIG, NZ_DATE_LOCALE, NZ_I18N } from 'ng-zorro-antd/i18n' @@ -41,6 +41,11 @@ import { IngredientModule } from '@cdk/ingredient/ingredient.module' import { NgxPermissionsModule } from 'ngx-permissions' import { TemplatePageTitleStrategy } from './services/title.service' import { TitleStrategy } from '@angular/router' +import { ConfigService } from './services/config.service' + +function initializeApp(configService: ConfigService) { + return () => configService.loadConfig().toPromise() // 返回一个 Promise +} registerLocaleData(zh) @@ -95,6 +100,14 @@ registerLocaleData(zh) firstDayOfWeek: 1, }, }, + + ConfigService, + { + provide: APP_INITIALIZER, + useFactory: initializeApp, + deps: [ConfigService], + multi: true, + }, ], bootstrap: [AppComponent], }) diff --git a/projects/client/src/app/components/app-layout/app-layout.component.html b/projects/client/src/app/components/app-layout/app-layout.component.html index cbd54bd..4c3fc97 100644 --- a/projects/client/src/app/components/app-layout/app-layout.component.html +++ b/projects/client/src/app/components/app-layout/app-layout.component.html @@ -7,9 +7,9 @@
diff --git a/projects/client/src/app/components/app-layout/app-layout.component.ts b/projects/client/src/app/components/app-layout/app-layout.component.ts index f946ae7..1f5b35a 100644 --- a/projects/client/src/app/components/app-layout/app-layout.component.ts +++ b/projects/client/src/app/components/app-layout/app-layout.component.ts @@ -1,60 +1,64 @@ -import { Component, OnInit } from "@angular/core"; -import { NavigationEnd, Router, RouterModule } from "@angular/router"; -import { NzMessageService } from "ng-zorro-antd/message"; +import { Component, OnInit } from '@angular/core' +import { NavigationEnd, Router, RouterModule } from '@angular/router' +import { NzMessageService } from 'ng-zorro-antd/message' -import { NzModalService } from "ng-zorro-antd/modal"; -import { Subject, filter, lastValueFrom, takeUntil } from "rxjs"; -import { ApiService } from "@cdk/services"; -import { appName } from "@cdk/app-settings"; +import { NzModalService } from 'ng-zorro-antd/modal' +import { Subject, filter, lastValueFrom, takeUntil } from 'rxjs' +import { ApiService } from '@cdk/services' + +import { WebSiteConfig } from '@cdk/types' +import { ConfigService } from '@client/app/services/config.service' @Component({ - selector: "app-layout", - templateUrl: "./app-layout.component.html", - styleUrls: ["./app-layout.component.less"], + selector: 'app-layout', + templateUrl: './app-layout.component.html', + styleUrls: ['./app-layout.component.less'], }) export class AppLayoutComponent implements OnInit { constructor( private router: Router, private modal: NzModalService, private msg: NzMessageService, - private api: ApiService + private api: ApiService, + private configService: ConfigService, ) { this.router.events .pipe( takeUntil(this.unSubscribe$), - filter((e): e is NavigationEnd => e instanceof NavigationEnd) + filter((e): e is NavigationEnd => e instanceof NavigationEnd), ) .subscribe((e) => { - this.currentUrl = e.url; - this.fullPage = ["/ingredient/preview", "/data-vis"].some((s) => e.url.startsWith(s)); - }); + this.currentUrl = e.url + this.fullPage = ['/ingredient/preview', '/data-vis'].some((s) => e.url.startsWith(s)) + }) } - fullPage = false; - account = this.api.account; - - appName = appName; + fullPage = false + account = this.api.account - unSubscribe$ = new Subject(); + unSubscribe$ = new Subject() - currentUrl: string = ""; + currentUrl: string = '' + appConfig: WebSiteConfig | null = null - ngOnInit(): void {} + ngOnInit(): void { + this.appConfig = this.configService.getConfig() + } openDataVis() { - window.open("/data-vis"); + window.open('/data-vis') } logout() { this.modal.confirm({ - nzTitle: "警告", - nzContent: "是否要退出登录?", + nzTitle: '警告', + nzContent: '是否要退出登录?', nzOnOk: async () => { - const res = await lastValueFrom(this.api.logout()); - this.msg.success(res.desc); - localStorage.removeItem(this.api.accountKey); - this.router.navigate(["/login"]); + const res = await lastValueFrom(this.api.logout()) + this.msg.success(res.desc) + localStorage.removeItem(this.api.accountKey) + this.router.navigate(['/login']) }, - }); + }) } } diff --git a/projects/client/src/app/pages/login/login.component.html b/projects/client/src/app/pages/login/login.component.html index 4a3b902..df27bbf 100644 --- a/projects/client/src/app/pages/login/login.component.html +++ b/projects/client/src/app/pages/login/login.component.html @@ -8,58 +8,32 @@
-->
- +
-

{{ appName }}

+

{{ appConfig?.websiteInfo?.name }}

登录

-
+ - - + + - + - - + + - + @@ -85,14 +59,14 @@
- +
diff --git a/projects/client/src/app/pages/login/login.component.ts b/projects/client/src/app/pages/login/login.component.ts index 0bdbe96..f510513 100644 --- a/projects/client/src/app/pages/login/login.component.ts +++ b/projects/client/src/app/pages/login/login.component.ts @@ -1,48 +1,56 @@ -import { Component } from "@angular/core"; -import { FormControl, FormGroup } from "@angular/forms"; -import { Router } from "@angular/router"; -import { NzMessageService } from "ng-zorro-antd/message"; -import { FormValidators } from "projects/cdk/src/public-api"; -import { Utils } from "projects/cdk/src/utils"; -import { finalize, lastValueFrom } from "rxjs"; -import { MD5 } from "crypto-js"; -import { ApiService } from "@cdk/services"; -import { appName } from "@cdk/app-settings"; +import { Component } from '@angular/core' +import { FormControl, FormGroup } from '@angular/forms' +import { Router } from '@angular/router' +import { NzMessageService } from 'ng-zorro-antd/message' +import { FormValidators, WebSiteConfig } from 'projects/cdk/src/public-api' +import { Utils } from 'projects/cdk/src/utils' +import { finalize, lastValueFrom } from 'rxjs' +import { MD5 } from 'crypto-js' +import { ApiService } from '@cdk/services' + +import { ConfigService } from '@client/app/services/config.service' @Component({ - selector: "app-login", - templateUrl: "./login.component.html", - styleUrls: ["./login.component.less"], + selector: 'app-login', + templateUrl: './login.component.html', + styleUrls: ['./login.component.less'], }) export class LoginComponent { - constructor(private msg: NzMessageService, private api: ApiService, private router: Router) {} + constructor( + private configService: ConfigService, + private msg: NzMessageService, + private api: ApiService, + private router: Router, + ) {} public loginForm = new FormGroup({ - uid: new FormControl("", [FormValidators.required("请输入账户")]), - pwd: new FormControl("", [FormValidators.required("请输入密码")]), - }); + uid: new FormControl('', [FormValidators.required('请输入账户')]), + pwd: new FormControl('', [FormValidators.required('请输入密码')]), + }) - public loading: boolean = false; + public loading: boolean = false - appName = appName; + appConfig: WebSiteConfig | null = null - ngOnInit(): void {} + ngOnInit(): void { + this.appConfig = this.configService.getConfig() + } async onLogin() { if (Utils.validateFormGroup(this.loginForm)) { - const { value } = this.loginForm; - const pwd = value.pwd as string; - value["pwd"] = MD5(pwd).toString().slice(-16).toUpperCase(); - this.loading = true; + const { value } = this.loginForm + const pwd = value.pwd as string + value['pwd'] = MD5(pwd).toString().slice(-16).toUpperCase() + this.loading = true const res = await lastValueFrom( this.api.login(value).pipe( finalize(() => { - this.loading = false; - }) - ) - ); - this.msg.success(res.desc); - this.router.navigate(["/"]); + this.loading = false + }), + ), + ) + this.msg.success(res.desc) + this.router.navigate(['/']) } } } diff --git a/projects/client/src/app/pages/system/org-info/org-info.component.html b/projects/client/src/app/pages/system/org-info/org-info.component.html index dfad971..4a8ec44 100644 --- a/projects/client/src/app/pages/system/org-info/org-info.component.html +++ b/projects/client/src/app/pages/system/org-info/org-info.component.html @@ -72,7 +72,7 @@ 账号到期时间 {{ org?.expire | date : 'yyyy-MM-dd' }} - 续费 + 技术支持
@@ -84,7 +84,7 @@ - 028-85463212 + {{ appConfig?.contactInfo?.phoneNumber ?? '-' }}
diff --git a/projects/client/src/app/pages/system/org-info/org-info.component.ts b/projects/client/src/app/pages/system/org-info/org-info.component.ts index cc03e3a..708deae 100644 --- a/projects/client/src/app/pages/system/org-info/org-info.component.ts +++ b/projects/client/src/app/pages/system/org-info/org-info.component.ts @@ -1,20 +1,22 @@ -import { ChangeDetectorRef, Component, OnInit, TemplateRef } from "@angular/core"; -import { NzModalService } from "ng-zorro-antd/modal"; -import { format } from "date-fns"; -import { ApiService } from "@cdk/services"; -import { FormControl, FormGroup } from "@angular/forms"; -import { FormValidators } from "@cdk/validators"; -import { Utils } from "@cdk/utils"; -import { NzMessageService } from "ng-zorro-antd/message"; -import { OrgFormComponent } from "../../../components"; -import { lastValueFrom } from "rxjs"; -import { MD5 } from "crypto-js"; -import { Router } from "@angular/router"; +import { ChangeDetectorRef, Component, OnInit, TemplateRef } from '@angular/core' +import { NzModalService } from 'ng-zorro-antd/modal' +import { format } from 'date-fns' +import { ApiService } from '@cdk/services' +import { FormControl, FormGroup } from '@angular/forms' +import { FormValidators } from '@cdk/validators' +import { Utils } from '@cdk/utils' +import { NzMessageService } from 'ng-zorro-antd/message' +import { OrgFormComponent } from '../../../components' +import { lastValueFrom } from 'rxjs' +import { MD5 } from 'crypto-js' +import { Router } from '@angular/router' +import { WebSiteConfig } from '@cdk/public-api' +import { ConfigService } from '@client/app/services/config.service' @Component({ - selector: "app-org-info", - templateUrl: "./org-info.component.html", - styleUrls: ["./org-info.component.less"], + selector: 'app-org-info', + templateUrl: './org-info.component.html', + styleUrls: ['./org-info.component.less'], }) export class OrgInfoComponent implements OnInit { constructor( @@ -22,40 +24,46 @@ export class OrgInfoComponent implements OnInit { private modal: NzModalService, private msg: NzMessageService, private router: Router, - private cdr: ChangeDetectorRef + private configService: ConfigService, ) {} - account: any = this.api.account; + account: any = this.api.account pwdForm = new FormGroup({ - oldPwd: new FormControl("", [FormValidators.required("请输入原密码")]), - newPwd: new FormControl("", [FormValidators.required("请输入新密码")]), - rePwd: new FormControl("", [FormValidators.required("请再次输入新密码")]), - }); + oldPwd: new FormControl('', [FormValidators.required('请输入原密码')]), + newPwd: new FormControl('', [FormValidators.required('请输入新密码')]), + rePwd: new FormControl('', [FormValidators.required('请再次输入新密码')]), + }) - ngOnInit(): void {} + appConfig: WebSiteConfig | null = null + + ngOnInit(): void { + this.appConfig = this.configService.getConfig() + } updateAccount(type: string | number, nzContent: TemplateRef<{}>) { const nzTitle = - type === "uid" - ? "如需修改超级管理员账号,请联系:" - : `账号将于 ${format(type as number, "yyyy-MM-dd")} 到期,续费请联系`; + type === 'uid' + ? '如需修改超级管理员账号,请联系:' + : `账号将于 ${format(type as number, 'yyyy-MM-dd')} 到期,续费请联系` this.modal.info({ - nzTitle, + nzTitle: '技术支持请联系', nzContent, - nzOkText: "知道了", - }); + nzOkText: '知道了', + }) } updateOrg() { this.modal.create({ - nzTitle: "修改单位基础信息", + nzTitle: '修改单位基础信息', nzContent: OrgFormComponent, nzData: this.account.vender, nzOnOk: async (e) => { if (Utils.validateFormGroup(e.formGroup)) { - const res = await lastValueFrom(this.api.saveOrg({ ...e.formGroup.value, venderId: this.account.vender.id })); - this.msg.success(res.desc); + const res = await lastValueFrom( + this.api.saveOrg({ ...e.formGroup.value, venderId: this.account.vender.id }), + ) + this.msg.success(res.desc) // localStorage.setItem( // this.api.accountKey, // JSON.stringify({ @@ -68,46 +76,46 @@ export class OrgInfoComponent implements OnInit { // }) // ); // window.location.reload(); - this.api.getOrgInfo().subscribe(() => {}); - return true; + this.api.getOrgInfo().subscribe(() => {}) + return true } - return false; + return false }, - }); + }) } cancelPwdForm() { - this.pwdForm.reset(); + this.pwdForm.reset() } changePassword(nzContent: TemplateRef<{}>) { this.modal.create({ - nzTitle: "修改密码", + nzTitle: '修改密码', nzContent, nzOnOk: async () => { if (Utils.validateFormGroup(this.pwdForm)) { - const { value } = this.pwdForm; + const { value } = this.pwdForm if (value.newPwd !== value.rePwd) { - this.msg.error("两次密码输入不一致"); - return false; + this.msg.error('两次密码输入不一致') + return false } const res = await lastValueFrom( this.api.updatePassword({ oldPassword: MD5(value.oldPwd!).toString().slice(-16), password: MD5(value.newPwd!).toString().slice(-16), // name: - }) - ); - this.msg.success(res.desc); + }), + ) + this.msg.success(res.desc) this.api.logout().subscribe(() => { - this.msg.success("请重新登录"); - this.router.navigate(["/login"]); - }); - return true; + this.msg.success('请重新登录') + this.router.navigate(['/login']) + }) + return true } - return false; + return false }, nzOnCancel: this.cancelPwdForm.bind(this), - }); + }) } } diff --git a/projects/client/src/app/services/client-api.service.ts b/projects/client/src/app/services/client-api.service.ts index cab52fd..061fdb2 100644 --- a/projects/client/src/app/services/client-api.service.ts +++ b/projects/client/src/app/services/client-api.service.ts @@ -1,5 +1,5 @@ -import { HttpClient, HttpParams } from "@angular/common/http"; -import { Injectable } from "@angular/core"; +import { HttpClient, HttpParams } from '@angular/common/http' +import { Injectable } from '@angular/core' import { Utils, AnyObject, @@ -10,120 +10,120 @@ import { GlobalEnum, OrgConfigDTO, ClientAccountDTO, -} from "@cdk/public-api"; -import { Observable, map, of, tap } from "rxjs"; +} from '@cdk/public-api' +import { Observable, map, of, tap } from 'rxjs' @Injectable({ - providedIn: "root", + providedIn: 'root', }) export class ClientApiServicde { constructor(private http: HttpClient) { try { - const strageAccount = localStorage.getItem(this.accountKey); + const strageAccount = localStorage.getItem(this.accountKey) if (strageAccount) { - this.account = JSON.parse(strageAccount); + this.account = JSON.parse(strageAccount) } } catch (error) { - console.error("获取用户信息失败", error); + console.error('获取用户信息失败', error) } } - public account!: ClientAccountDTO; + public account!: ClientAccountDTO - public accountKey = "CATERING_ACCOUNT"; + public accountKey = 'CATERING_ACCOUNT' - globalEnum!: GlobalEnum; + globalEnum!: GlobalEnum page(v: {}, q: {}) { - return this.http.get("https://jsonplaceholder.typicode.com/users", v).pipe( + return this.http.get('https://jsonplaceholder.typicode.com/users', v).pipe( map((r) => { return { total: 10, content: r, - }; - }) - ); + } + }), + ) } getAllEnum(force?: boolean): Observable { if (this.globalEnum && !force) { - return of(this.globalEnum); + return of(this.globalEnum) } - return this.http.get>("/api/basic/enum").pipe( + return this.http.get>('/api/basic/enum').pipe( map((res) => { - return res.body; + return res.body }), tap((r) => { - this.globalEnum = r; - }) - ); + this.globalEnum = r + }), + ) } login(v: {}) { - const params = Utils.objectToHttpParams(v); - return this.http.get("/api/login", { params }); + const params = Utils.objectToHttpParams(v) + return this.http.get('/api/login', { params }) } logout() { - return this.http.get("/api/logout"); + return this.http.get('/api/logout') } getRoleList() { - return this.http.get>("/api/role"); + return this.http.get>('/api/role') } deleteRole(roleId: string) { - const params = new HttpParams().set("roleId", roleId); - return this.http.delete("/api/role", { + const params = new HttpParams().set('roleId', roleId) + return this.http.delete('/api/role', { params, - }); + }) } updateRole(rule: AnyObject) { - const body = Utils.objectToFormData(rule); - const method = rule["roleId"] ? "post" : "put"; - return this.http[method]("/api/role", body); + const body = Utils.objectToFormData(rule) + const method = rule['roleId'] ? 'post' : 'put' + return this.http[method]('/api/role', body) } getRolePerms() { - return this.http.get>("/api/role/item"); + return this.http.get>('/api/role/item') } getUserList() { - return this.http.get>("/api/user"); + return this.http.get>('/api/user') } checkUid(uid: string) { - const params = new HttpParams().set("uid", uid); - return this.http.delete("/api/user/check", { + const params = new HttpParams().set('uid', uid) + return this.http.delete('/api/user/check', { params, - }); + }) } saveUser(user: AnyObject, edit: boolean) { - const body = Utils.objectToFormData(user); - const method = edit ? "post" : "put"; - return this.http[method]("/api/user", body); + const body = Utils.objectToFormData(user) + const method = edit ? 'post' : 'put' + return this.http[method]('/api/user', body) } deleteUser(uid: string) { - const params = new HttpParams().set("uid", uid); - return this.http.delete("/api/user", { + const params = new HttpParams().set('uid', uid) + return this.http.delete('/api/user', { params, - }); + }) } saveOrg(org: AnyObject) { - const body = Utils.objectToFormData(org); - return this.http.post(" /api/vender", body); + const body = Utils.objectToFormData(org) + return this.http.post(' /api/vender', body) } getOrgConfig() { - return this.http.get>("/api/vender/config"); + return this.http.get>('/api/vender/config') } saveOrgConfig(config: AnyObject) { - const body = Utils.objectToFormData(config); - return this.http.post("/api/vender/config", body); + const body = Utils.objectToFormData(config) + return this.http.post('/api/vender/config', body) } } diff --git a/projects/client/src/app/services/config.service.ts b/projects/client/src/app/services/config.service.ts new file mode 100644 index 0000000..357ed13 --- /dev/null +++ b/projects/client/src/app/services/config.service.ts @@ -0,0 +1,38 @@ +import { Injectable } from '@angular/core' +import { HttpClient } from '@angular/common/http' +import { Observable, of, throwError } from 'rxjs' +import { tap, catchError } from 'rxjs/operators' +import { WebSiteConfig } from '@cdk/public-api' + +@Injectable({ + providedIn: 'root', +}) +export class ConfigService { + private configUrl = 'assets/config.json' + private appConfig: WebSiteConfig | null = null + + constructor(private http: HttpClient) {} + + loadConfig(): Observable { + if (this.appConfig) { + return of(this.appConfig) + } + + console.log(123) + + return this.http.get(this.configUrl).pipe( + tap((config) => { + this.appConfig = config + }), + catchError((error) => { + console.error('加载 config.json 失败:', error) + + return throwError(() => new Error('无法加载应用配置')) + }), + ) + } + + getConfig(): WebSiteConfig | null { + return this.appConfig + } +} diff --git a/projects/client/src/app/services/title.service.ts b/projects/client/src/app/services/title.service.ts index 1540d3e..efc0edc 100644 --- a/projects/client/src/app/services/title.service.ts +++ b/projects/client/src/app/services/title.service.ts @@ -1,19 +1,22 @@ -import { Injectable } from "@angular/core"; -import { Title } from "@angular/platform-browser"; -import { RouterStateSnapshot, TitleStrategy } from "@angular/router"; +import { OnInit } from '@angular/core' +import { ConfigService } from '@client/app/services/config.service' +import { Injectable } from '@angular/core' +import { Title } from '@angular/platform-browser' +import { RouterStateSnapshot, TitleStrategy } from '@angular/router' -@Injectable({ providedIn: "root" }) +@Injectable({ providedIn: 'root' }) export class TemplatePageTitleStrategy extends TitleStrategy { - constructor(private readonly title: Title) { - super(); + fullTitle = '' + constructor(private readonly title: Title, private ConfigService: ConfigService) { + super() } override updateTitle(routerState: RouterStateSnapshot) { - const title = this.buildTitle(routerState); - let fullTitle = "营养配餐系统"; + const title = this.buildTitle(routerState) + let fullTitle = this.ConfigService.getConfig()?.websiteInfo?.name || '' if (title !== undefined) { - fullTitle += ` | ${title}`; + fullTitle += ` | ${title}` } - this.title.setTitle(fullTitle); + this.title.setTitle(fullTitle) } } diff --git a/projects/client/src/assets/config.json b/projects/client/src/assets/config.json new file mode 100644 index 0000000..2a7ec2a --- /dev/null +++ b/projects/client/src/assets/config.json @@ -0,0 +1,17 @@ +{ + "websiteInfo": { + "name": "营养配餐实训系统" + }, + "assets": { + "logo": "/assets/images/jl-logo.png", + "favicon": "/assets/favicon.ico", + "loginBackground": "/assets/images/jl-logo.png" + }, + "contactInfo": { + "phoneNumber": "19181752603" + }, + "copyrightInfo": { + "icpLicense": "蜀ICP备2023038072号", + "companyName": "" + } +} diff --git a/projects/client/src/favicon.ico b/projects/client/src/assets/favicon.ico similarity index 100% rename from projects/client/src/favicon.ico rename to projects/client/src/assets/favicon.ico diff --git a/projects/client/src/index.html b/projects/client/src/index.html index 367a73a..58ade6f 100644 --- a/projects/client/src/index.html +++ b/projects/client/src/index.html @@ -1,16 +1,14 @@ - + + + + + + + + - - - 营养配餐系统 - - - - - - - - - - \ No newline at end of file + + + +