@fudanda/admin-antd 2.20261107.1-beta.1 → 2.20261109.1-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/ApiTokensPage-w3JGRNQC.js +2 -0
- package/dist/chunks/ApiTokensPage-w3JGRNQC.js.map +1 -0
- package/dist/chunks/{App-BF96TQ_D.js → App-nh6_qOo8.js} +5 -5
- package/dist/chunks/{App-BF96TQ_D.js.map → App-nh6_qOo8.js.map} +1 -1
- package/dist/chunks/{AppModal-CLkMJ-96.js → AppModal-CEouaU03.js} +2 -2
- package/dist/chunks/{AppModal-CLkMJ-96.js.map → AppModal-CEouaU03.js.map} +1 -1
- package/dist/chunks/{ArcBaseAdmin--xQxd4tg.js → ArcBaseAdmin-CX7fQz4x.js} +2 -2
- package/dist/chunks/{ArcBaseAdmin--xQxd4tg.js.map → ArcBaseAdmin-CX7fQz4x.js.map} +1 -1
- package/dist/chunks/{DepartmentsPage-D6YVegPU.js → DepartmentsPage-BdD9VfDI.js} +2 -2
- package/dist/chunks/{DepartmentsPage-D6YVegPU.js.map → DepartmentsPage-BdD9VfDI.js.map} +1 -1
- package/dist/chunks/{DictsPage-uV3Uukwc.js → DictsPage-fxBdV1-3.js} +2 -2
- package/dist/chunks/{DictsPage-uV3Uukwc.js.map → DictsPage-fxBdV1-3.js.map} +1 -1
- package/dist/chunks/{EntityContextRuntime-DbjyzCtY.js → EntityContextRuntime-CMhoj6qe.js} +2 -2
- package/dist/chunks/{EntityContextRuntime-DbjyzCtY.js.map → EntityContextRuntime-CMhoj6qe.js.map} +1 -1
- package/dist/chunks/EntityContextRuntime-Dc89ZSnM.js +1 -0
- package/dist/chunks/{ExportButton-e2ybxuHb.js → ExportButton-DGxB2tcu.js} +2 -2
- package/dist/chunks/{ExportButton-e2ybxuHb.js.map → ExportButton-DGxB2tcu.js.map} +1 -1
- package/dist/chunks/{FileViewerPreviewPanel-BhI3pTi8.js → FileViewerPreviewPanel-BMZ7FdKV.js} +3 -3
- package/dist/chunks/{FileViewerPreviewPanel-BhI3pTi8.js.map → FileViewerPreviewPanel-BMZ7FdKV.js.map} +1 -1
- package/dist/chunks/{FilesPage-BI35mStl.js → FilesPage-DrgWELKy.js} +3 -3
- package/dist/chunks/{FilesPage-BI35mStl.js.map → FilesPage-DrgWELKy.js.map} +1 -1
- package/dist/chunks/IdentitySecurityPage-BjTKvr-O.js +9 -0
- package/dist/chunks/IdentitySecurityPage-BjTKvr-O.js.map +1 -0
- package/dist/chunks/{LogStatsScaffold-m0vVUXPh.js → LogStatsScaffold-DaB0JeAN.js} +2 -2
- package/dist/chunks/{LogStatsScaffold-m0vVUXPh.js.map → LogStatsScaffold-DaB0JeAN.js.map} +1 -1
- package/dist/chunks/{LoginLogsPage-BzBUR4Oo.js → LoginLogsPage-VmYC7i6q.js} +2 -2
- package/dist/chunks/{LoginLogsPage-BzBUR4Oo.js.map → LoginLogsPage-VmYC7i6q.js.map} +1 -1
- package/dist/chunks/{LoginLogsTable-BweUEjQX.js → LoginLogsTable-CULcc_e8.js} +2 -2
- package/dist/chunks/{LoginLogsTable-BweUEjQX.js.map → LoginLogsTable-CULcc_e8.js.map} +1 -1
- package/dist/chunks/{MarkdownPreviewPanel-C1OKSLmh.js → MarkdownPreviewPanel-CBcPc7Wv.js} +2 -2
- package/dist/chunks/{MarkdownPreviewPanel-C1OKSLmh.js.map → MarkdownPreviewPanel-CBcPc7Wv.js.map} +1 -1
- package/dist/chunks/{MasterDetailLayout-KVizcSNO.js → MasterDetailLayout-ByIBpmkZ.js} +2 -2
- package/dist/chunks/{MasterDetailLayout-KVizcSNO.js.map → MasterDetailLayout-ByIBpmkZ.js.map} +1 -1
- package/dist/chunks/{McpSettingsPage-Dhf0CbDN.js → McpSettingsPage-C5V_rj2V.js} +2 -2
- package/dist/chunks/{McpSettingsPage-Dhf0CbDN.js.map → McpSettingsPage-C5V_rj2V.js.map} +1 -1
- package/dist/chunks/{MemberAssignmentSheet-TYpnyA0z.js → MemberAssignmentSheet-DL0fg1Yf.js} +2 -2
- package/dist/chunks/{MemberAssignmentSheet-TYpnyA0z.js.map → MemberAssignmentSheet-DL0fg1Yf.js.map} +1 -1
- package/dist/chunks/{MenuCommandPalette-BcvpUfK7.js → MenuCommandPalette-C2PvK3Gh.js} +2 -2
- package/dist/chunks/{MenuCommandPalette-BcvpUfK7.js.map → MenuCommandPalette-C2PvK3Gh.js.map} +1 -1
- package/dist/chunks/{MenusPage-Dd7OLQYT.js → MenusPage-Bytd1HlW.js} +2 -2
- package/dist/chunks/{MenusPage-Dd7OLQYT.js.map → MenusPage-Bytd1HlW.js.map} +1 -1
- package/dist/chunks/{MonacoPreviewPanel-BW1j3ZTF.js → MonacoPreviewPanel-BZrNIcFZ.js} +2 -2
- package/dist/chunks/{MonacoPreviewPanel-BW1j3ZTF.js.map → MonacoPreviewPanel-BZrNIcFZ.js.map} +1 -1
- package/dist/chunks/{NavListPanel-Iz1RCkVw.js → NavListPanel-zwUDIYSP.js} +2 -2
- package/dist/chunks/{NavListPanel-Iz1RCkVw.js.map → NavListPanel-zwUDIYSP.js.map} +1 -1
- package/dist/chunks/{OperationLogsPage-Dt22tU4I.js → OperationLogsPage-D2BQdGNp.js} +2 -2
- package/dist/chunks/{OperationLogsPage-Dt22tU4I.js.map → OperationLogsPage-D2BQdGNp.js.map} +1 -1
- package/dist/chunks/{OperationLogsTable-B23Ry-2v.js → OperationLogsTable-DaaON4QR.js} +3 -3
- package/dist/chunks/{OperationLogsTable-B23Ry-2v.js.map → OperationLogsTable-DaaON4QR.js.map} +1 -1
- package/dist/chunks/{PDFPreviewPanel-kBPz5dQr.js → PDFPreviewPanel-CMmnWBKW.js} +3 -3
- package/dist/chunks/{PDFPreviewPanel-kBPz5dQr.js.map → PDFPreviewPanel-CMmnWBKW.js.map} +1 -1
- package/dist/chunks/{PositionsPage-BIKYQDB5.js → PositionsPage-CBZITssT.js} +2 -2
- package/dist/chunks/{PositionsPage-BIKYQDB5.js.map → PositionsPage-CBZITssT.js.map} +1 -1
- package/dist/chunks/{PreferencesSheetBody-D276rrp4.js → PreferencesSheetBody-B0poTPEA.js} +2 -2
- package/dist/chunks/{PreferencesSheetBody-D276rrp4.js.map → PreferencesSheetBody-B0poTPEA.js.map} +1 -1
- package/dist/chunks/{ProfilePage-DLftC6KZ.js → ProfilePage-DLhacdWt.js} +2 -2
- package/dist/chunks/{ProfilePage-DLftC6KZ.js.map → ProfilePage-DLhacdWt.js.map} +1 -1
- package/dist/chunks/{ProjectInfoPage-DkuBLC8t.js → ProjectInfoPage-CJpGxpu5.js} +2 -2
- package/dist/chunks/{ProjectInfoPage-DkuBLC8t.js.map → ProjectInfoPage-CJpGxpu5.js.map} +1 -1
- package/dist/chunks/{RelationPanel-B4BeO0Bz.js → RelationPanel-BsbfEDo2.js} +2 -2
- package/dist/chunks/{RelationPanel-B4BeO0Bz.js.map → RelationPanel-BsbfEDo2.js.map} +1 -1
- package/dist/chunks/{RolesPage-BhltU2Qm.js → RolesPage-46dzdiah.js} +2 -2
- package/dist/chunks/{RolesPage-BhltU2Qm.js.map → RolesPage-46dzdiah.js.map} +1 -1
- package/dist/chunks/{SessionConflictModal-3R8jdYkI.js → SessionConflictModal-Bm38eExL.js} +2 -2
- package/dist/chunks/{SessionConflictModal-3R8jdYkI.js.map → SessionConflictModal-Bm38eExL.js.map} +1 -1
- package/dist/chunks/SettingModuleDetail-BjxUJeH5.js +17 -0
- package/dist/chunks/SettingModuleDetail-BjxUJeH5.js.map +1 -0
- package/dist/chunks/{SettingsPage-DMzeDrnc.js → SettingsPage-C32Vuizm.js} +2 -2
- package/dist/chunks/{SettingsPage-DMzeDrnc.js.map → SettingsPage-C32Vuizm.js.map} +1 -1
- package/dist/chunks/{StatCard-C0xSZyiS.js → StatCard-CRPfkSBY.js} +2 -2
- package/dist/chunks/{StatCard-C0xSZyiS.js.map → StatCard-CRPfkSBY.js.map} +1 -1
- package/dist/chunks/{UserGroupsPage-DTJdszHl.js → UserGroupsPage-08G5MdGm.js} +2 -2
- package/dist/chunks/{UserGroupsPage-DTJdszHl.js.map → UserGroupsPage-08G5MdGm.js.map} +1 -1
- package/dist/chunks/{UserLogsPanels-z4UhQtgu.js → UserLogsPanels-nbIrMym9.js} +2 -2
- package/dist/chunks/{UserLogsPanels-z4UhQtgu.js.map → UserLogsPanels-nbIrMym9.js.map} +1 -1
- package/dist/chunks/{UserTransferSelect-BJNUXMhl.js → UserTransferSelect-C8betaWG.js} +2 -2
- package/dist/chunks/{UserTransferSelect-BJNUXMhl.js.map → UserTransferSelect-C8betaWG.js.map} +1 -1
- package/dist/chunks/{UsersPage--p68X2Yr.js → UsersPage-BjTiNEqF.js} +2 -2
- package/dist/chunks/{UsersPage--p68X2Yr.js.map → UsersPage-BjTiNEqF.js.map} +1 -1
- package/dist/chunks/{browser-BKLM0ThC-3Xar5rZw.js → browser-BKLM0ThC-Cp7Gi4-F.js} +1 -1
- package/dist/chunks/{code-P0HJS_q1.js → code-LswxAr98.js} +1 -1
- package/dist/chunks/{direct-engine-BYEscsGg.js → direct-engine-Dv_6v4sx.js} +1 -1
- package/dist/chunks/{html-B__1Vr_C.js → html-BokjxlLb.js} +1 -1
- package/dist/chunks/{line-DzLRZVEq.js → line-Bqh6atHH.js} +1 -1
- package/dist/chunks/{lrc-kf-TilFB.js → lrc-T5e1svZG.js} +1 -1
- package/dist/chunks/{markdown-xIo-vnKK.js → markdown-BpWokN1s.js} +1 -1
- package/dist/chunks/{patch-BEaX-xYV.js → patch-BYVX5C9G.js} +1 -1
- package/dist/chunks/{worker-engine-FCdIQLzN.js → worker-engine-CtUAeI4G.js} +1 -1
- package/dist/core/hooks/queries/settings.d.ts +6 -0
- package/dist/core/hooks/queries/settings.d.ts.map +1 -1
- package/dist/core/hooks/queries/settings.js +34 -25
- package/dist/core/hooks/queries/settings.js.map +1 -1
- package/dist/core/hooks/useAuth.d.ts +2 -0
- package/dist/core/hooks/useAuth.d.ts.map +1 -1
- package/dist/core/hooks/useAuth.js.map +1 -1
- package/dist/core/index.js +7 -7
- package/dist/core/lib/go-auth-api.d.ts +1 -1
- package/dist/core/lib/go-auth-api.d.ts.map +1 -1
- package/dist/core/lib/go-auth-api.js +12 -8
- package/dist/core/lib/go-auth-api.js.map +1 -1
- package/dist/core/lib/native-operations.d.ts +85 -4
- package/dist/core/lib/native-operations.d.ts.map +1 -1
- package/dist/core/lib/native-operations.js +1 -0
- package/dist/core/lib/native-operations.js.map +1 -1
- package/dist/core/providers/GoAuthProvider.d.ts.map +1 -1
- package/dist/core/providers/GoAuthProvider.js +191 -142
- package/dist/core/providers/GoAuthProvider.js.map +1 -1
- package/dist/core/session-renewal.d.ts +15 -0
- package/dist/core/session-renewal.d.ts.map +1 -0
- package/dist/core/session-renewal.js +95 -0
- package/dist/core/session-renewal.js.map +1 -0
- package/dist/core/session-transition.d.ts +2 -0
- package/dist/core/session-transition.d.ts.map +1 -1
- package/dist/core/session-transition.js +20 -7
- package/dist/core/session-transition.js.map +1 -1
- package/dist/core/session.d.ts +4 -0
- package/dist/core/session.d.ts.map +1 -1
- package/dist/core/session.js +88 -61
- package/dist/core/session.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/{src-C8_bzBi4.js → src-D6UlLiVN.js} +2 -2
- package/dist/{src-C8_bzBi4.js.map → src-D6UlLiVN.js.map} +1 -1
- package/package.json +9 -9
- package/dist/chunks/ApiTokensPage-DiRMgViD.js +0 -2
- package/dist/chunks/ApiTokensPage-DiRMgViD.js.map +0 -1
- package/dist/chunks/EntityContextRuntime-BOJySc1D.js +0 -1
- package/dist/chunks/IdentitySecurityPage-DW5ybVL4.js +0 -9
- package/dist/chunks/IdentitySecurityPage-DW5ybVL4.js.map +0 -1
- package/dist/chunks/SettingModuleDetail-Dppk9An1.js +0 -17
- package/dist/chunks/SettingModuleDetail-Dppk9An1.js.map +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{n as e}from"./rolldown-runtime-Bruge11p.js";import{E as t,I as n,It as r,M as i,O as a,R as o,T as s,_ as ee,f as c,l,m as u,o as d,v as te}from"./clipboard-dpqHdCyy.js";import{i as f}from"./feedback-B1UL2ETz.js";import{n as p,t as m}from"./MasterDetailLayout-KVizcSNO.js";import{a as h,i as g,n as ne,o as re,r as _,s as v,t as ie}from"./UserLogsPanels-z4UhQtgu.js";import{a as y,i as b,r as x,t as S}from"./SessionClientTag-ht0d4JHq.js";import{n as C,t as w}from"./list-wgUaW69x.js";import{n as T,t as E}from"./monitor-DjHEaSak.js";import{n as D,t as O}from"./shield-Cf8xmgtJ.js";import{i as k,t as ae}from"./deleteAction-CNNyRUSw.js";import{n as A,t as j}from"./DateTimeText-DldSUPjX.js";import{F as M,P as oe,v as N,y as P}from"./App-BF96TQ_D.js";import{n as F,t as se}from"./UserAvatar-PoQSTuhw.js";import{n as I,t as L}from"./PasswordInput-D1X5p0WR.js";import{n as ce,r as R}from"./NavListPanel-Iz1RCkVw.js";import{i as z,n as le,r as ue,t as B}from"./useSectionSelection-DBggfIoz.js";import{n as de,t as fe}from"./DictTag-ChBs3uuY.js";import{useState as V}from"react";import{Fragment as pe,jsx as H,jsxs as U}from"react/jsx-runtime";import{useDictItems as me}from"@fudanda/admin-antd/core/hooks/useDictItems";import{formatDateForApi as he,formatDateTime as ge}from"@fudanda/admin-antd/core/utils/date";import{useMySettings as _e}from"@fudanda/admin-antd/core/hooks/queries/settings";import{uploadAvatarBlobToFileCenter as ve}from"@fudanda/admin-antd/core/utils/avatar-upload";import{formatSessionPolicyHint as ye}from"@fudanda/client/settings";import{useChangeProfilePassword as be,useKickOtherProfileSessions as xe,useKickProfileSession as Se,useProfileSessions as Ce,useUpdateProfile as W}from"@fudanda/admin-antd/core/hooks/queries/profile";var G;function K(){return(K=e((()=>{C(),T(),D(),P(),G=[{key:`profile`,title:`基本信息`,description:`头像、联系方式与个人资料`,icon:N},{key:`security`,title:`账号安全`,description:`登录密码与账号安全`,icon:O},{key:`devices`,title:`我的设备`,description:`当前会话与在线设备`,icon:E},{key:`login`,title:`登录记录`,description:`查看自己的登录记录`,icon:w},{key:`operation`,title:`操作记录`,description:`查看自己的操作记录`,icon:w}]})))()}function we({policy:e}){return!e||e.maxSessions<=0?null:/* @__PURE__ */ H(c,{type:`info`,closeIcon:null,fullMode:!1,style:{marginBottom:12},description:`当前策略:${ye(e)}`})}function q({sessions:e,loading:t,onKick:r}){return/* @__PURE__ */ H(n,{className:`session-list`,dataSource:e,emptyContent:/* @__PURE__ */ H(`div`,{className:`session-list-empty`,children:`暂无在线设备信息`}),loading:t,renderItem:e=>/* @__PURE__ */ H(n.Item,{align:`center`,className:`session-list-item`,main:/* @__PURE__ */ U(`div`,{className:`session-list-main`,children:[/* @__PURE__ */ H(S,{client:e.client,size:16,className:`session-list-client`}),/* @__PURE__ */ H(Y,{strong:!0,children:e.browser}),/* @__PURE__ */ H(Y,{type:`tertiary`,size:`small`,children:y(e.client)}),e.isCurrent&&/* @__PURE__ */ H(a,{color:`blue`,size:`small`,children:`当前设备`}),/* @__PURE__ */ U(Y,{type:`tertiary`,size:`small`,className:`session-list-meta`,children:[e.os,` · `,`IP: ${e.ip}`,` · `,`登录 `,/* @__PURE__ */ H(j,{value:e.loginAt}),` · `,`活跃 `,/* @__PURE__ */ H(j,{value:e.lastActiveAt})]})]}),extra:!e.isCurrent&&/* @__PURE__ */ H(u,{theme:`borderless`,type:`danger`,size:`small`,onClick:()=>{d({title:`确定要退出该设备吗?`,onOk:()=>r(e.tokenId)})},children:`退出`})},e.tokenId)})}function Te({user:e}){let n=G,r=le(n.map(e=>e.key),`profile`),i=r.active,{options:l}=me(`user_gender`),[p,h]=V(!1),[_,v]=V(``);V(``);let y=_e(),b=Ce(i===`devices`),x=y.data?.identitySecurity.password??null,S=b.data??[],C=W(),w=W(),T=be(),E=xe(),D=Se(),O=C.isPending,k=T.isPending,A=b.isFetching,j=E.isPending,M=w.isPending;async function N(e){await C.mutateAsync({body:{nickname:e.nickname,email:e.email||void 0,phone:e.phone||void 0,gender:e.gender||void 0,birthDate:e.birthDate?he(e.birthDate):void 0,clearFields:[...e.email?[]:[`email`],...e.phone?[]:[`phone`],...e.gender?[]:[`gender`],...e.birthDate?[]:[`birthDate`]]}}),f.success(`资料已更新`)}async function P(e){if(e.newPassword!==e.confirmPassword)return f.error(`两次密码输入不一致`),!1;await T.mutateAsync({body:{oldPassword:e.oldPassword,newPassword:e.newPassword}}),f.success(`密码修改成功,请重新登录`),v(``)}async function F(){await E.mutateAsync({}),f.success(`操作成功`)}async function I(e){await D.mutateAsync({params:{tokenId:e}}),f.success(`已退出该设备`)}async function R(){ae({title:`确定要移除头像吗?`,content:`移除后将使用昵称缩写作为默认头像。`,run:()=>w.mutateAsync({body:{clearFields:[`avatar`]}}),successMessage:`头像已移除`})}function z(){h(!0)}async function B(e){h(!1),await w.mutateAsync({body:{avatar:e}}),f.success(`头像已更新`)}return/* @__PURE__ */ U(`div`,{className:`page-container page-container--stretch`,children:[/* @__PURE__ */ H(m,{defaultSize:260,minSize:200,maxSize:400,persistKey:`profile`,style:{flex:1,minHeight:0,overflow:`hidden`},showDetail:i!==null,onBack:r.back,onResponsiveChange:r.responsiveChange,master:/* @__PURE__ */ H(ce,{title:`个人中心`,rawBody:!0,children:/* @__PURE__ */ H(ue,{sections:n,active:i,onSelect:r.select})}),detail:/* @__PURE__ */ U(m.Body,{className:`profile-content-card`,scroll:`auto`,children:[i===`profile`&&/* @__PURE__ */ U(`div`,{className:`profile-section`,children:[/* @__PURE__ */ H(`div`,{className:`section-title`,children:`基本信息`}),e.accountSource===`casdoor`&&/* @__PURE__ */ H(c,{type:`info`,description:`统一账户资料由 Casdoor 管理;请联系管理员修改。`,closeIcon:null}),/* @__PURE__ */ U(`div`,{className:`profile-basic-overview`,children:[/* @__PURE__ */ U(`div`,{className:`avatar-column`,children:[/* @__PURE__ */ H(`button`,{type:`button`,className:`avatar-upload-trigger`,disabled:e.accountSource===`casdoor`,onClick:z,"aria-label":`更换头像`,children:M?/* @__PURE__ */ H(`div`,{className:`avatar-loading-wrapper`,style:{width:80,height:80},children:/* @__PURE__ */ H(t,{})}):/* @__PURE__ */ U(pe,{children:[/* @__PURE__ */ H(se,{name:e.nickname||`用户`,avatar:e.avatar,size:80,style:{fontSize:28}}),/* @__PURE__ */ H(`div`,{className:`avatar-upload-mask`,children:`更换头像`})]})}),/* @__PURE__ */ H(u,{size:`small`,theme:`light`,loading:M,disabled:e.accountSource===`casdoor`,onClick:z,style:{width:`100%`},children:`更换头像`})]}),/* @__PURE__ */ U(`div`,{className:`profile-basic-summary`,children:[/* @__PURE__ */ U(`div`,{className:`profile-basic-heading`,children:[/* @__PURE__ */ H(J,{heading:5,style:{margin:0},children:e.nickname}),/* @__PURE__ */ U(Y,{type:`tertiary`,size:`small`,children:[`@`,e.username]})]}),/* @__PURE__ */ H(ee,{align:`plain`,layout:`horizontal`,column:2,style:{width:`100%`},data:[{key:`手机号`,value:e.phone,hidden:!e.phone},{key:`邮箱`,value:e.email},{key:`性别`,value:/* @__PURE__ */ H(fe,{dictCode:`user_gender`,value:e.gender}),hidden:!e.gender},{key:`出生日期`,value:e.birthDate,hidden:!e.birthDate},{key:`部门`,value:e.departmentName,hidden:!e.departmentName},{key:`岗位`,value:e.positions?.length?/* @__PURE__ */ H(s,{spacing:4,style:{display:`inline-flex`,flexWrap:`wrap`},children:e.positions.map(e=>/* @__PURE__ */ H(a,{size:`small`,style:X,children:e.name},e.id))}):void 0,hidden:!e.positions?.length},{key:`角色`,value:e.roles?.length?/* @__PURE__ */ H(s,{spacing:4,style:{display:`inline-flex`,flexWrap:`wrap`},children:e.roles.map(e=>/* @__PURE__ */ H(a,{size:`small`,style:X,children:e.name},e.id))}):`无角色`},{key:`注册时间`,value:ge(e.createdAt)}]})]})]}),/* @__PURE__ */ H(te,{margin:28}),/* @__PURE__ */ H(`div`,{className:`section-title`,children:`资料编辑`}),/* @__PURE__ */ U(o,{initValues:{nickname:e.nickname,email:e.email??``,phone:e.phone??``,gender:e.gender??void 0,birthDate:e.birthDate??void 0},disabled:e.accountSource===`casdoor`,onSubmit:N,allowEmpty:!0,labelPosition:`left`,labelWidth:80,children:[/* @__PURE__ */ H(o.Input,{field:`nickname`,label:`昵称`,placeholder:`请输入昵称`,rules:[{required:!0,message:`昵称不能为空`}],style:Q}),/* @__PURE__ */ H(o.Input,{field:`phone`,label:`手机号`,placeholder:`请输入手机号(选填)`,rules:[{pattern:/^1[3-9]\d{9}$/,message:`请输入正确的手机号码`}],style:Q}),/* @__PURE__ */ H(o.Input,{field:`email`,label:`邮箱`,placeholder:`请输入邮箱(选填)`,rules:[{type:`email`,message:`邮箱格式不正确`}],style:Q}),/* @__PURE__ */ H(o.Select,{field:`gender`,label:`性别`,style:Q,showClear:!0,optionList:l,placeholder:`请选择性别(选填)`}),/* @__PURE__ */ H(o.DatePicker,{field:`birthDate`,label:`出生日期`,type:`date`,style:Q,placeholder:`请选择出生日期(选填)`,showClear:!0}),/* @__PURE__ */ H(o.Slot,{children:/* @__PURE__ */ H(u,{htmlType:`submit`,type:`primary`,loading:O,children:`保存修改`})})]})]}),!1,i===`security`&&/* @__PURE__ */ U(`div`,{className:`profile-section`,children:[/* @__PURE__ */ H(`div`,{className:`section-title`,children:`修改密码`}),e.accountSource===`casdoor`&&/* @__PURE__ */ H(c,{type:`info`,description:`密码及 MFA 请在 Casdoor 中管理。`,closeIcon:null}),/* @__PURE__ */ U(o,{disabled:e.accountSource===`casdoor`,onSubmit:P,labelPosition:`left`,labelWidth:100,children:[/* @__PURE__ */ H(L,{field:`oldPassword`,label:`原密码`,placeholder:`请输入原密码`,rules:[{required:!0,message:`请输入原密码`}],style:Q}),/* @__PURE__ */ H(L,{field:`newPassword`,label:`新密码`,placeholder:`请输入新密码`,rules:[{required:!0,message:`请输入新密码`},...x?.minLength?[{min:x.minLength,message:`密码至少${x.minLength}个字符`}]:[]],style:Q,onChange:e=>v(String(e??``)),helpText:/* @__PURE__ */ H(g,{password:_,policy:x})}),/* @__PURE__ */ H(L,{field:`confirmPassword`,label:`确认密码`,placeholder:`请再次输入新密码`,rules:[{required:!0,message:`请确认新密码`}],style:Q}),/* @__PURE__ */ H(o.Slot,{children:/* @__PURE__ */ H(u,{htmlType:`submit`,type:`primary`,loading:k,children:`修改密码`})})]}),!1]}),!1,i===`devices`&&/* @__PURE__ */ U(`div`,{className:`profile-section`,children:[/* @__PURE__ */ U(`div`,{style:{display:`flex`,justifyContent:`space-between`,alignItems:`center`,marginBottom:20},children:[/* @__PURE__ */ H(`div`,{className:`section-title`,style:{margin:0},children:`在线设备`}),/* @__PURE__ */ H(u,{type:`danger`,theme:`light`,size:`small`,loading:j,icon:/* @__PURE__ */ H(oe,{size:14}),onClick:()=>{d({title:`确定要退出其他所有设备吗?`,content:`退出后其他设备将需要重新登录。`,onOk:F})},children:`退出其他设备`})]}),/* @__PURE__ */ H(we,{policy:y.data?.identitySecurity.session}),/* @__PURE__ */ H(q,{sessions:S,loading:A,onKick:I})]}),i===`login`&&/* @__PURE__ */ H(`div`,{className:`profile-section`,children:/* @__PURE__ */ H(ie,{scope:Z,enabled:i===`login`,columnSettingsKey:`profile-login-logs`})}),i===`operation`&&/* @__PURE__ */ H(`div`,{className:`profile-section`,children:/* @__PURE__ */ H(ne,{scope:Z,enabled:i===`operation`,columnSettingsKey:`profile-operation-logs`})}),!1]})}),/* @__PURE__ */ H(re,{visible:p,currentAvatar:e.avatar,confirmLoading:w.isPending,uploadBlob:ve,onCancel:()=>h(!1),onSelect:e=>void B(e),onRemove:e.avatar?R:void 0}),!1]})}var J,Y,X,Z,Q;function $(){return($=e((()=>{I(),i(),M(),p(),R(),z(),K(),B(),v(),F(),b(),x(),A(),h(),de(),k(),l(),_(),{Title:J,Text:Y}=r,X={color:`var(--arc-antd-color-primary)`,backgroundColor:`var(--arc-antd-color-primary-light-default)`,borderColor:`transparent`},Z={kind:`self`},Q={width:`100%`,maxWidth:320}})))()}$();export{Te as default};
|
|
2
|
-
//# sourceMappingURL=ProfilePage-
|
|
1
|
+
import{n as e}from"./rolldown-runtime-Bruge11p.js";import{E as t,I as n,It as r,M as i,O as a,R as o,T as s,_ as ee,f as c,l,m as u,o as d,v as te}from"./clipboard-dpqHdCyy.js";import{i as f}from"./feedback-B1UL2ETz.js";import{n as p,t as m}from"./MasterDetailLayout-ByIBpmkZ.js";import{a as h,i as g,n as ne,o as re,r as _,s as v,t as ie}from"./UserLogsPanels-nbIrMym9.js";import{a as y,i as b,r as x,t as S}from"./SessionClientTag-ht0d4JHq.js";import{n as C,t as w}from"./list-wgUaW69x.js";import{n as T,t as E}from"./monitor-DjHEaSak.js";import{n as D,t as O}from"./shield-Cf8xmgtJ.js";import{i as k,t as ae}from"./deleteAction-CNNyRUSw.js";import{n as A,t as j}from"./DateTimeText-DldSUPjX.js";import{F as M,P as oe,v as N,y as P}from"./App-nh6_qOo8.js";import{n as F,t as se}from"./UserAvatar-PoQSTuhw.js";import{n as I,t as L}from"./PasswordInput-D1X5p0WR.js";import{n as ce,r as R}from"./NavListPanel-zwUDIYSP.js";import{i as z,n as le,r as ue,t as B}from"./useSectionSelection-DBggfIoz.js";import{n as de,t as fe}from"./DictTag-ChBs3uuY.js";import{useState as V}from"react";import{Fragment as pe,jsx as H,jsxs as U}from"react/jsx-runtime";import{useDictItems as me}from"@fudanda/admin-antd/core/hooks/useDictItems";import{formatDateForApi as he,formatDateTime as ge}from"@fudanda/admin-antd/core/utils/date";import{useMySettings as _e}from"@fudanda/admin-antd/core/hooks/queries/settings";import{uploadAvatarBlobToFileCenter as ve}from"@fudanda/admin-antd/core/utils/avatar-upload";import{formatSessionPolicyHint as ye}from"@fudanda/client/settings";import{useChangeProfilePassword as be,useKickOtherProfileSessions as xe,useKickProfileSession as Se,useProfileSessions as Ce,useUpdateProfile as W}from"@fudanda/admin-antd/core/hooks/queries/profile";var G;function K(){return(K=e((()=>{C(),T(),D(),P(),G=[{key:`profile`,title:`基本信息`,description:`头像、联系方式与个人资料`,icon:N},{key:`security`,title:`账号安全`,description:`登录密码与账号安全`,icon:O},{key:`devices`,title:`我的设备`,description:`当前会话与在线设备`,icon:E},{key:`login`,title:`登录记录`,description:`查看自己的登录记录`,icon:w},{key:`operation`,title:`操作记录`,description:`查看自己的操作记录`,icon:w}]})))()}function we({policy:e}){return!e||e.maxSessions<=0?null:/* @__PURE__ */ H(c,{type:`info`,closeIcon:null,fullMode:!1,style:{marginBottom:12},description:`当前策略:${ye(e)}`})}function q({sessions:e,loading:t,onKick:r}){return/* @__PURE__ */ H(n,{className:`session-list`,dataSource:e,emptyContent:/* @__PURE__ */ H(`div`,{className:`session-list-empty`,children:`暂无在线设备信息`}),loading:t,renderItem:e=>/* @__PURE__ */ H(n.Item,{align:`center`,className:`session-list-item`,main:/* @__PURE__ */ U(`div`,{className:`session-list-main`,children:[/* @__PURE__ */ H(S,{client:e.client,size:16,className:`session-list-client`}),/* @__PURE__ */ H(Y,{strong:!0,children:e.browser}),/* @__PURE__ */ H(Y,{type:`tertiary`,size:`small`,children:y(e.client)}),e.isCurrent&&/* @__PURE__ */ H(a,{color:`blue`,size:`small`,children:`当前设备`}),/* @__PURE__ */ U(Y,{type:`tertiary`,size:`small`,className:`session-list-meta`,children:[e.os,` · `,`IP: ${e.ip}`,` · `,`登录 `,/* @__PURE__ */ H(j,{value:e.loginAt}),` · `,`活跃 `,/* @__PURE__ */ H(j,{value:e.lastActiveAt})]})]}),extra:!e.isCurrent&&/* @__PURE__ */ H(u,{theme:`borderless`,type:`danger`,size:`small`,onClick:()=>{d({title:`确定要退出该设备吗?`,onOk:()=>r(e.tokenId)})},children:`退出`})},e.tokenId)})}function Te({user:e}){let n=G,r=le(n.map(e=>e.key),`profile`),i=r.active,{options:l}=me(`user_gender`),[p,h]=V(!1),[_,v]=V(``);V(``);let y=_e(),b=Ce(i===`devices`),x=y.data?.identitySecurity.password??null,S=b.data??[],C=W(),w=W(),T=be(),E=xe(),D=Se(),O=C.isPending,k=T.isPending,A=b.isFetching,j=E.isPending,M=w.isPending;async function N(e){await C.mutateAsync({body:{nickname:e.nickname,email:e.email||void 0,phone:e.phone||void 0,gender:e.gender||void 0,birthDate:e.birthDate?he(e.birthDate):void 0,clearFields:[...e.email?[]:[`email`],...e.phone?[]:[`phone`],...e.gender?[]:[`gender`],...e.birthDate?[]:[`birthDate`]]}}),f.success(`资料已更新`)}async function P(e){if(e.newPassword!==e.confirmPassword)return f.error(`两次密码输入不一致`),!1;await T.mutateAsync({body:{oldPassword:e.oldPassword,newPassword:e.newPassword}}),f.success(`密码修改成功,请重新登录`),v(``)}async function F(){await E.mutateAsync({}),f.success(`操作成功`)}async function I(e){await D.mutateAsync({params:{tokenId:e}}),f.success(`已退出该设备`)}async function R(){ae({title:`确定要移除头像吗?`,content:`移除后将使用昵称缩写作为默认头像。`,run:()=>w.mutateAsync({body:{clearFields:[`avatar`]}}),successMessage:`头像已移除`})}function z(){h(!0)}async function B(e){h(!1),await w.mutateAsync({body:{avatar:e}}),f.success(`头像已更新`)}return/* @__PURE__ */ U(`div`,{className:`page-container page-container--stretch`,children:[/* @__PURE__ */ H(m,{defaultSize:260,minSize:200,maxSize:400,persistKey:`profile`,style:{flex:1,minHeight:0,overflow:`hidden`},showDetail:i!==null,onBack:r.back,onResponsiveChange:r.responsiveChange,master:/* @__PURE__ */ H(ce,{title:`个人中心`,rawBody:!0,children:/* @__PURE__ */ H(ue,{sections:n,active:i,onSelect:r.select})}),detail:/* @__PURE__ */ U(m.Body,{className:`profile-content-card`,scroll:`auto`,children:[i===`profile`&&/* @__PURE__ */ U(`div`,{className:`profile-section`,children:[/* @__PURE__ */ H(`div`,{className:`section-title`,children:`基本信息`}),e.accountSource===`casdoor`&&/* @__PURE__ */ H(c,{type:`info`,description:`统一账户资料由 Casdoor 管理;请联系管理员修改。`,closeIcon:null}),/* @__PURE__ */ U(`div`,{className:`profile-basic-overview`,children:[/* @__PURE__ */ U(`div`,{className:`avatar-column`,children:[/* @__PURE__ */ H(`button`,{type:`button`,className:`avatar-upload-trigger`,disabled:e.accountSource===`casdoor`,onClick:z,"aria-label":`更换头像`,children:M?/* @__PURE__ */ H(`div`,{className:`avatar-loading-wrapper`,style:{width:80,height:80},children:/* @__PURE__ */ H(t,{})}):/* @__PURE__ */ U(pe,{children:[/* @__PURE__ */ H(se,{name:e.nickname||`用户`,avatar:e.avatar,size:80,style:{fontSize:28}}),/* @__PURE__ */ H(`div`,{className:`avatar-upload-mask`,children:`更换头像`})]})}),/* @__PURE__ */ H(u,{size:`small`,theme:`light`,loading:M,disabled:e.accountSource===`casdoor`,onClick:z,style:{width:`100%`},children:`更换头像`})]}),/* @__PURE__ */ U(`div`,{className:`profile-basic-summary`,children:[/* @__PURE__ */ U(`div`,{className:`profile-basic-heading`,children:[/* @__PURE__ */ H(J,{heading:5,style:{margin:0},children:e.nickname}),/* @__PURE__ */ U(Y,{type:`tertiary`,size:`small`,children:[`@`,e.username]})]}),/* @__PURE__ */ H(ee,{align:`plain`,layout:`horizontal`,column:2,style:{width:`100%`},data:[{key:`手机号`,value:e.phone,hidden:!e.phone},{key:`邮箱`,value:e.email},{key:`性别`,value:/* @__PURE__ */ H(fe,{dictCode:`user_gender`,value:e.gender}),hidden:!e.gender},{key:`出生日期`,value:e.birthDate,hidden:!e.birthDate},{key:`部门`,value:e.departmentName,hidden:!e.departmentName},{key:`岗位`,value:e.positions?.length?/* @__PURE__ */ H(s,{spacing:4,style:{display:`inline-flex`,flexWrap:`wrap`},children:e.positions.map(e=>/* @__PURE__ */ H(a,{size:`small`,style:X,children:e.name},e.id))}):void 0,hidden:!e.positions?.length},{key:`角色`,value:e.roles?.length?/* @__PURE__ */ H(s,{spacing:4,style:{display:`inline-flex`,flexWrap:`wrap`},children:e.roles.map(e=>/* @__PURE__ */ H(a,{size:`small`,style:X,children:e.name},e.id))}):`无角色`},{key:`注册时间`,value:ge(e.createdAt)}]})]})]}),/* @__PURE__ */ H(te,{margin:28}),/* @__PURE__ */ H(`div`,{className:`section-title`,children:`资料编辑`}),/* @__PURE__ */ U(o,{initValues:{nickname:e.nickname,email:e.email??``,phone:e.phone??``,gender:e.gender??void 0,birthDate:e.birthDate??void 0},disabled:e.accountSource===`casdoor`,onSubmit:N,allowEmpty:!0,labelPosition:`left`,labelWidth:80,children:[/* @__PURE__ */ H(o.Input,{field:`nickname`,label:`昵称`,placeholder:`请输入昵称`,rules:[{required:!0,message:`昵称不能为空`}],style:Q}),/* @__PURE__ */ H(o.Input,{field:`phone`,label:`手机号`,placeholder:`请输入手机号(选填)`,rules:[{pattern:/^1[3-9]\d{9}$/,message:`请输入正确的手机号码`}],style:Q}),/* @__PURE__ */ H(o.Input,{field:`email`,label:`邮箱`,placeholder:`请输入邮箱(选填)`,rules:[{type:`email`,message:`邮箱格式不正确`}],style:Q}),/* @__PURE__ */ H(o.Select,{field:`gender`,label:`性别`,style:Q,showClear:!0,optionList:l,placeholder:`请选择性别(选填)`}),/* @__PURE__ */ H(o.DatePicker,{field:`birthDate`,label:`出生日期`,type:`date`,style:Q,placeholder:`请选择出生日期(选填)`,showClear:!0}),/* @__PURE__ */ H(o.Slot,{children:/* @__PURE__ */ H(u,{htmlType:`submit`,type:`primary`,loading:O,children:`保存修改`})})]})]}),!1,i===`security`&&/* @__PURE__ */ U(`div`,{className:`profile-section`,children:[/* @__PURE__ */ H(`div`,{className:`section-title`,children:`修改密码`}),e.accountSource===`casdoor`&&/* @__PURE__ */ H(c,{type:`info`,description:`密码及 MFA 请在 Casdoor 中管理。`,closeIcon:null}),/* @__PURE__ */ U(o,{disabled:e.accountSource===`casdoor`,onSubmit:P,labelPosition:`left`,labelWidth:100,children:[/* @__PURE__ */ H(L,{field:`oldPassword`,label:`原密码`,placeholder:`请输入原密码`,rules:[{required:!0,message:`请输入原密码`}],style:Q}),/* @__PURE__ */ H(L,{field:`newPassword`,label:`新密码`,placeholder:`请输入新密码`,rules:[{required:!0,message:`请输入新密码`},...x?.minLength?[{min:x.minLength,message:`密码至少${x.minLength}个字符`}]:[]],style:Q,onChange:e=>v(String(e??``)),helpText:/* @__PURE__ */ H(g,{password:_,policy:x})}),/* @__PURE__ */ H(L,{field:`confirmPassword`,label:`确认密码`,placeholder:`请再次输入新密码`,rules:[{required:!0,message:`请确认新密码`}],style:Q}),/* @__PURE__ */ H(o.Slot,{children:/* @__PURE__ */ H(u,{htmlType:`submit`,type:`primary`,loading:k,children:`修改密码`})})]}),!1]}),!1,i===`devices`&&/* @__PURE__ */ U(`div`,{className:`profile-section`,children:[/* @__PURE__ */ U(`div`,{style:{display:`flex`,justifyContent:`space-between`,alignItems:`center`,marginBottom:20},children:[/* @__PURE__ */ H(`div`,{className:`section-title`,style:{margin:0},children:`在线设备`}),/* @__PURE__ */ H(u,{type:`danger`,theme:`light`,size:`small`,loading:j,icon:/* @__PURE__ */ H(oe,{size:14}),onClick:()=>{d({title:`确定要退出其他所有设备吗?`,content:`退出后其他设备将需要重新登录。`,onOk:F})},children:`退出其他设备`})]}),/* @__PURE__ */ H(we,{policy:y.data?.identitySecurity.session}),/* @__PURE__ */ H(q,{sessions:S,loading:A,onKick:I})]}),i===`login`&&/* @__PURE__ */ H(`div`,{className:`profile-section`,children:/* @__PURE__ */ H(ie,{scope:Z,enabled:i===`login`,columnSettingsKey:`profile-login-logs`})}),i===`operation`&&/* @__PURE__ */ H(`div`,{className:`profile-section`,children:/* @__PURE__ */ H(ne,{scope:Z,enabled:i===`operation`,columnSettingsKey:`profile-operation-logs`})}),!1]})}),/* @__PURE__ */ H(re,{visible:p,currentAvatar:e.avatar,confirmLoading:w.isPending,uploadBlob:ve,onCancel:()=>h(!1),onSelect:e=>void B(e),onRemove:e.avatar?R:void 0}),!1]})}var J,Y,X,Z,Q;function $(){return($=e((()=>{I(),i(),M(),p(),R(),z(),K(),B(),v(),F(),b(),x(),A(),h(),de(),k(),l(),_(),{Title:J,Text:Y}=r,X={color:`var(--arc-antd-color-primary)`,backgroundColor:`var(--arc-antd-color-primary-light-default)`,borderColor:`transparent`},Z={kind:`self`},Q={width:`100%`,maxWidth:320}})))()}$();export{Te as default};
|
|
2
|
+
//# sourceMappingURL=ProfilePage-DLhacdWt.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProfilePage-DLftC6KZ.js","mappings":"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","names":["UserRound","Shield","Monitor","List","SessionPolicyHint","policy","Banner","formatSessionPolicyHint","SessionList","SemiList","sessions","SessionClientIcon","session","Text","sessionClientLabel","Tag","DateTimeText","Button","confirmDanger","onKick","ProfilePage","sections","profileSections","navigation","useSectionSelection","section","activeSection","genderOptions","useDictItems","avatarSelectVisible","setAvatarSelectVisible","useState","changePwdVal","setChangePwdVal","mySettingsQuery","useMySettings","sessionsQuery","useProfileSessions","passwordPolicy","updateProfileMutation","useUpdateProfile","updateAvatarMutation","changePasswordMutation","useChangeProfilePassword","kickOthersMutation","useKickOtherProfileSessions","kickSessionMutation","useKickProfileSession","profileLoading","pwdLoading","sessionsLoading","kickOthersLoading","avatarLoading","handleUpdateProfile","values","formatDateForApi","Toast","handleChangePassword","handleKickOthers","handleKickSession","handleRemoveAvatar","confirmAndDelete","openAvatarPicker","handleApplyAvatar","url","MasterDetailLayout","NavListPanel","SectionNavigation","user","Spin","_Fragment","UserAvatar","Title","Descriptions","DictTag","Space","THEME_TAG_STYLE","p","r","formatDateTime","Divider","Form","PROFILE_CONTROL_STYLE","FormPasswordInput","v","PasswordStrengthMeter","LogOut","UserLoginLogsPanel","SELF_LOGS_SCOPE","UserOperationLogsPanel","AvatarSelectModal","uploadAvatarBlobToFileCenter","Typography"],"ignoreList":[],"sources":["../../src/pages/profile/profile-sections.ts","../../src/pages/profile/ProfilePage.tsx"],"sourcesContent":["import { List, Monitor, Shield, UserRound } from 'lucide-react';\n\nexport const profileSections = [\n { key: 'profile', title: '基本信息', description: '头像、联系方式与个人资料', icon: UserRound },\n { key: 'security', title: '账号安全', description: '登录密码与账号安全', icon: Shield },\n { key: 'devices', title: '我的设备', description: '当前会话与在线设备', icon: Monitor },\n { key: 'login', title: '登录记录', description: '查看自己的登录记录', icon: List },\n { key: 'operation', title: '操作记录', description: '查看自己的操作记录', icon: List },\n] as const;\n","import { FormPasswordInput } from \"@/components/PasswordInput\";\nimport { useState } from 'react';\nimport { Form, Button, Typography, Toast, Tag, Space, Spin, List as SemiList, Descriptions, Divider, Banner } from \"@/ui\";\nimport { LogOut } from 'lucide-react';\nimport { MasterDetailLayout } from '@/components/MasterDetailLayout';\nimport { NavListPanel } from '@/components/NavListPanel';\nimport { SectionNavigation } from '@/components/SectionNavigation';\nimport { profileSections } from './profile-sections';\nimport { useSectionSelection } from '@/hooks/useSectionSelection';\nimport type { User as UserType, UserSession } from '@fudanda/shared/identity';\nimport { AvatarSelectModal } from \"@/components/AvatarSelectModal\";\nimport { uploadAvatarBlobToFileCenter } from \"@fudanda/react-core/utils/avatar-upload\";\nimport { UserAvatar } from \"@/components/UserAvatar\";\nimport { sessionClientLabel } from '@/components/session-client-label';\nimport { SessionClientIcon } from \"@/components/SessionClientTag\";\nimport { formatDateForApi, formatDateTime } from \"@fudanda/react-core/utils/date\";\nimport DateTimeText from \"@/components/DateTimeText\";\nimport type { PasswordRules as PasswordPolicy, SessionConcurrencyPolicy } from '@fudanda/shared/settings';\nimport { formatSessionPolicyHint } from '@fudanda/shared/settings';\nimport { useMySettings } from \"@fudanda/react-core/hooks/queries/settings\";\nimport { PasswordStrengthMeter } from \"@/components/PasswordStrengthMeter\";\nimport { useDictItems } from \"@fudanda/react-core/hooks/useDictItems\";\n\nimport DictTag from \"@/components/DictTag\";\nimport { confirmAndDelete } from \"@/components/list-page/index\";\nimport { confirmDanger } from \"@/utils/confirm\";\nimport { useChangeProfilePassword, useKickOtherProfileSessions, useKickProfileSession, useProfileSessions, useUpdateProfile, } from \"@fudanda/react-core/hooks/queries/profile\";\nimport \"@/pages/profile/ProfilePage.css\";\nimport { UserLoginLogsPanel, UserOperationLogsPanel } from \"@/components/logs/UserLogsPanels\";\nconst { Title, Text } = Typography;\n/** 跟随主题色的浅底标签:Semi Tag 的 color 只支持固定色板,主题色走 CSS 变量覆盖(亮 / 暗主题与主题色切换自动跟随) */\nconst THEME_TAG_STYLE = {\n color: 'var(--arc-antd-color-primary)',\n backgroundColor: 'var(--arc-antd-color-primary-light-default)',\n borderColor: 'transparent',\n} as const;\n/** 个人视角的记录面板 scope:模块级常量,避免每次渲染换引用 */\nconst SELF_LOGS_SCOPE = { kind: 'self' } as const;\nconst PROFILE_CONTROL_STYLE = { width: '100%', maxWidth: 320 } as const;\ninterface ProfilePageProps {\n readonly user: Omit<UserType, 'password'>;\n}\n/** 会话并发策略生效时向用户说明:为什么会被挤下线 / 为什么新设备登不上 */\nfunction SessionPolicyHint({ policy }: {\n readonly policy: SessionConcurrencyPolicy | undefined;\n}) {\n if (!policy || policy.maxSessions <= 0)\n return null;\n return (<Banner type=\"info\" closeIcon={null} fullMode={false} style={{ marginBottom: 12 }} description={`当前策略:${formatSessionPolicyHint(policy)}`}/>);\n}\nfunction SessionList({ sessions, loading, onKick, }: {\n readonly sessions: UserSession[];\n readonly loading?: boolean;\n readonly onKick: (tokenId: string) => void;\n}) {\n return (<SemiList className=\"session-list\" dataSource={sessions} emptyContent={<div className=\"session-list-empty\">暂无在线设备信息</div>} loading={loading} renderItem={(session: UserSession) => (<SemiList.Item key={session.tokenId} align=\"center\" className=\"session-list-item\" main={(<div className=\"session-list-main\">\n <SessionClientIcon client={session.client} size={16} className=\"session-list-client\"/>\n <Text strong>{session.browser}</Text>\n <Text type=\"tertiary\" size=\"small\">{sessionClientLabel(session.client)}</Text>\n {session.isCurrent && <Tag color=\"blue\" size=\"small\">当前设备</Tag>}\n <Text type=\"tertiary\" size=\"small\" className=\"session-list-meta\">\n {session.os} · {`IP: ${session.ip}`}\n {' · '}登录 <DateTimeText value={session.loginAt}/>\n {' · '}活跃 <DateTimeText value={session.lastActiveAt}/>\n </Text>\n </div>)} extra={!session.isCurrent && (<Button theme=\"borderless\" type=\"danger\" size=\"small\" onClick={() => {\n confirmDanger({\n title: '确定要退出该设备吗?',\n onOk: () => onKick(session.tokenId),\n });\n }}>\n 退出\n </Button>)}/>)}/>);\n}\nexport default function ProfilePage({ user }: ProfilePageProps) {\n const sections = profileSections;\n const navigation = useSectionSelection(sections.map(section => section.key), 'profile');\n const activeSection = navigation.active;\n // ─── 基本信息 ────────────────────────────────────────────────────────────────\n const { options: genderOptions } = useDictItems('user_gender');\n // ─── 头像裁剪 ────────────────────────────────────────────────────────────────\n const [avatarSelectVisible, setAvatarSelectVisible] = useState(false);\n // ─── 账号安全 ────────────────────────────────────────────────────────────────\n const [changePwdVal, setChangePwdVal] = useState('');\n useState('');\n // ─── 我的设备 ────────────────────────────────────────────────────────────────\n // 密码规则来自运行时设置的登录用户投影(与布局共用一次请求)\n const mySettingsQuery = useMySettings();\n const sessionsQuery = useProfileSessions(activeSection === 'devices');\n // ─── 已授权应用 ──────────────────────────────────────────────────────────────\n const passwordPolicy: PasswordPolicy | null = mySettingsQuery.data?.identitySecurity.password ?? null;\n const sessions = sessionsQuery.data ?? [];\n const updateProfileMutation = useUpdateProfile();\n const updateAvatarMutation = useUpdateProfile();\n const changePasswordMutation = useChangeProfilePassword();\n const kickOthersMutation = useKickOtherProfileSessions();\n const kickSessionMutation = useKickProfileSession();\n const profileLoading = updateProfileMutation.isPending;\n const pwdLoading = changePasswordMutation.isPending;\n const sessionsLoading = sessionsQuery.isFetching;\n const kickOthersLoading = kickOthersMutation.isPending;\n const avatarLoading = updateAvatarMutation.isPending;\n // ─── 事件处理 ────────────────────────────────────────────────────────────────\n async function handleUpdateProfile(values: {\n nickname: string;\n email: string;\n phone?: string;\n gender?: string | null;\n birthDate?: Date | string | null;\n }) {\n await updateProfileMutation.mutateAsync({ body: { nickname: values.nickname, email: values.email || undefined, phone: values.phone || undefined, gender: values.gender || undefined, birthDate: values.birthDate ? formatDateForApi(values.birthDate) : undefined, clearFields: [...(!values.email ? ['email' as const] : []), ...(!values.phone ? ['phone' as const] : []), ...(!values.gender ? ['gender' as const] : []), ...(!values.birthDate ? ['birthDate' as const] : [])] } });\n Toast.success('资料已更新');\n }\n async function handleChangePassword(values: {\n oldPassword: string;\n newPassword: string;\n confirmPassword: string;\n }) {\n if (values.newPassword !== values.confirmPassword) {\n Toast.error('两次密码输入不一致');\n return false;\n }\n await changePasswordMutation.mutateAsync({ body: { oldPassword: values.oldPassword, newPassword: values.newPassword } });\n Toast.success('密码修改成功,请重新登录');\n setChangePwdVal('');\n }\n async function handleKickOthers() {\n await kickOthersMutation.mutateAsync({});\n Toast.success('操作成功');\n }\n async function handleKickSession(tokenId: string) {\n await kickSessionMutation.mutateAsync({ params: { tokenId } });\n Toast.success('已退出该设备');\n }\n async function handleRemoveAvatar() {\n confirmAndDelete({\n title: '确定要移除头像吗?',\n content: '移除后将使用昵称缩写作为默认头像。',\n run: () => updateAvatarMutation.mutateAsync({ body: { clearFields: ['avatar'] } }),\n successMessage: '头像已移除',\n });\n }\n function openAvatarPicker() {\n setAvatarSelectVisible(true);\n }\n async function handleApplyAvatar(url: string) {\n setAvatarSelectVisible(false);\n await updateAvatarMutation.mutateAsync({ body: { avatar: url } });\n Toast.success('头像已更新');\n }\n // ─── 静态配置 ────────────────────────────────────────────────────────────────\n return (<div className=\"page-container page-container--stretch\">\n <MasterDetailLayout defaultSize={260} minSize={200} maxSize={400} persistKey=\"profile\"\n style={{ flex: 1, minHeight: 0, overflow: 'hidden' }} showDetail={activeSection !== null}\n onBack={navigation.back} onResponsiveChange={navigation.responsiveChange}\n master={<NavListPanel title=\"个人中心\" rawBody>\n <SectionNavigation sections={sections} active={activeSection} onSelect={navigation.select} />\n </NavListPanel>}\n detail={<MasterDetailLayout.Body\n className=\"profile-content-card\" scroll=\"auto\">\n {/* ── 基本信息 ──────────────────────────────────────── */}\n {activeSection === 'profile' && (\n <div className=\"profile-section\">\n <div className=\"section-title\">基本信息</div>\n {user.accountSource === \"casdoor\" && <Banner type=\"info\" description=\"统一账户资料由 Casdoor 管理;请联系管理员修改。\" closeIcon={null}/>}\n <div className=\"profile-basic-overview\">\n <div className=\"avatar-column\">\n <button type=\"button\" className=\"avatar-upload-trigger\" disabled={user.accountSource === \"casdoor\"} onClick={openAvatarPicker} aria-label=\"更换头像\">\n {avatarLoading ? (<div className=\"avatar-loading-wrapper\" style={{ width: 80, height: 80 }}><Spin /></div>) : (<>\n <UserAvatar name={user.nickname || '用户'} avatar={user.avatar} size={80} style={{ fontSize: 28 }}/>\n <div className=\"avatar-upload-mask\">更换头像</div>\n </>)}\n </button>\n <Button size=\"small\" theme=\"light\" loading={avatarLoading} disabled={user.accountSource === \"casdoor\"} onClick={openAvatarPicker} style={{ width: '100%' }}>更换头像</Button>\n </div>\n <div className=\"profile-basic-summary\">\n <div className=\"profile-basic-heading\">\n <Title heading={5} style={{ margin: 0 }}>{user.nickname}</Title>\n <Text type=\"tertiary\" size=\"small\">@{user.username}</Text>\n </div>\n <Descriptions align=\"plain\" layout=\"horizontal\" column={2} style={{ width: '100%' }} data={[\n { key: '手机号', value: user.phone, hidden: !user.phone },\n { key: '邮箱', value: user.email },\n {\n key: '性别',\n value: <DictTag dictCode=\"user_gender\" value={user.gender}/>,\n hidden: !user.gender,\n },\n { key: '出生日期', value: user.birthDate, hidden: !user.birthDate },\n { key: '部门', value: user.departmentName, hidden: !user.departmentName },\n {\n key: '岗位',\n value: user.positions?.length ? (<Space spacing={4} style={{ display: 'inline-flex', flexWrap: 'wrap' }}>\n {user.positions.map((p) => <Tag key={p.id} size=\"small\" style={THEME_TAG_STYLE}>{p.name}</Tag>)}\n </Space>) : undefined,\n hidden: !user.positions?.length,\n },\n {\n key: '角色',\n value: user.roles?.length ? (<Space spacing={4} style={{ display: 'inline-flex', flexWrap: 'wrap' }}>\n {user.roles.map((r) => <Tag key={r.id} size=\"small\" style={THEME_TAG_STYLE}>{r.name}</Tag>)}\n </Space>) : '无角色',\n },\n { key: '注册时间', value: formatDateTime(user.createdAt) },\n ]}/>\n </div>\n </div>\n\n <Divider margin={28}/>\n\n <div className=\"section-title\">资料编辑</div>\n <Form initValues={{ nickname: user.nickname, email: user.email ?? '', phone: user.phone ?? '', gender: user.gender ?? undefined, birthDate: user.birthDate ?? undefined }} disabled={user.accountSource === \"casdoor\"} onSubmit={handleUpdateProfile} allowEmpty labelPosition=\"left\" labelWidth={80}>\n <Form.Input field=\"nickname\" label=\"昵称\" placeholder=\"请输入昵称\" rules={[{ required: true, message: '昵称不能为空' }]} style={PROFILE_CONTROL_STYLE}/>\n <Form.Input field=\"phone\" label=\"手机号\" placeholder=\"请输入手机号(选填)\" rules={[\n { pattern: /^1[3-9]\\d{9}$/, message: '请输入正确的手机号码' },\n ]} style={PROFILE_CONTROL_STYLE}/>\n <Form.Input field=\"email\" label=\"邮箱\" placeholder=\"请输入邮箱(选填)\" rules={[{ type: 'email', message: '邮箱格式不正确' }]} style={PROFILE_CONTROL_STYLE}/>\n <Form.Select field=\"gender\" label=\"性别\" style={PROFILE_CONTROL_STYLE} showClear optionList={genderOptions} placeholder=\"请选择性别(选填)\"/>\n <Form.DatePicker field=\"birthDate\" label=\"出生日期\" type=\"date\" style={PROFILE_CONTROL_STYLE} placeholder=\"请选择出生日期(选填)\" showClear/>\n <Form.Slot>\n <Button htmlType=\"submit\" type=\"primary\" loading={profileLoading}>保存修改</Button>\n </Form.Slot>\n </Form>\n </div>\n )}\n\n {false}\n\n {/* ── 账号安全 ──────────────────────────────────────── */}\n {activeSection === 'security' && (\n <div className=\"profile-section\">\n <div className=\"section-title\">修改密码</div>\n {user.accountSource === \"casdoor\" && <Banner type=\"info\" description=\"密码及 MFA 请在 Casdoor 中管理。\" closeIcon={null}/>}\n <Form disabled={user.accountSource === \"casdoor\"} onSubmit={handleChangePassword} labelPosition=\"left\" labelWidth={100}>\n <FormPasswordInput field=\"oldPassword\" label=\"原密码\" placeholder=\"请输入原密码\" rules={[{ required: true, message: '请输入原密码' }]} style={PROFILE_CONTROL_STYLE}/>\n <FormPasswordInput field=\"newPassword\" label=\"新密码\" placeholder=\"请输入新密码\" rules={[\n { required: true, message: '请输入新密码' },\n ...(passwordPolicy?.minLength ? [{ min: passwordPolicy.minLength, message: `密码至少${passwordPolicy.minLength}个字符` }] : []),\n ]} style={PROFILE_CONTROL_STYLE} onChange={(v) => setChangePwdVal(String(v ?? ''))} helpText={<PasswordStrengthMeter password={changePwdVal} policy={passwordPolicy}/>}/>\n <FormPasswordInput field=\"confirmPassword\" label=\"确认密码\" placeholder=\"请再次输入新密码\" rules={[{ required: true, message: '请确认新密码' }]} style={PROFILE_CONTROL_STYLE}/>\n <Form.Slot>\n <Button htmlType=\"submit\" type=\"primary\" loading={pwdLoading}>修改密码</Button>\n </Form.Slot>\n </Form>\n\n {false}\n </div>\n )}\n\n {/* ── 通知设置 ──────────────────────────────────────── */}\n {false}\n\n {/* ── 我的设备 ──────────────────────────────────────── */}\n {activeSection === 'devices' && (\n <div className=\"profile-section\">\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20 }}>\n <div className=\"section-title\" style={{ margin: 0 }}>在线设备</div>\n <Button type=\"danger\" theme=\"light\" size=\"small\" loading={kickOthersLoading} icon={<LogOut size={14}/>} onClick={() => {\n confirmDanger({\n title: '确定要退出其他所有设备吗?',\n content: '退出后其他设备将需要重新登录。',\n onOk: handleKickOthers,\n });\n }}>\n 退出其他设备\n </Button>\n </div>\n <SessionPolicyHint policy={mySettingsQuery.data?.identitySecurity.session}/>\n <SessionList sessions={sessions} loading={sessionsLoading} onKick={handleKickSession}/>\n </div>\n )}\n\n {/* ── 登录记录 ──────────────────────────────────────── */}\n {activeSection === 'login' && (\n <div className=\"profile-section\">\n <UserLoginLogsPanel scope={SELF_LOGS_SCOPE} enabled={activeSection === 'login'} columnSettingsKey=\"profile-login-logs\"/>\n </div>\n )}\n\n {/* ── 操作记录 ──────────────────────────────────────── */}\n {activeSection === 'operation' && (\n <div className=\"profile-section\">\n <UserOperationLogsPanel scope={SELF_LOGS_SCOPE} enabled={activeSection === 'operation'} columnSettingsKey=\"profile-operation-logs\"/>\n </div>\n )}\n\n {/* ── 已授权应用 ────────────────────────────────────── */}\n {false}\n\n </MasterDetailLayout.Body>} />\n\n {/* ── 头像选择 Modal(本地上传裁剪 + 移除) ─────────────────────────────── */}\n <AvatarSelectModal visible={avatarSelectVisible} currentAvatar={user.avatar} confirmLoading={updateAvatarMutation.isPending} uploadBlob={uploadAvatarBlobToFileCenter} onCancel={() => setAvatarSelectVisible(false)} onSelect={(url) => void handleApplyAvatar(url)} onRemove={user.avatar ? handleRemoveAvatar : undefined}/>\n\n {false}\n </div>);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ProfilePage-DLhacdWt.js","mappings":"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","names":["UserRound","Shield","Monitor","List","SessionPolicyHint","policy","Banner","formatSessionPolicyHint","SessionList","SemiList","sessions","SessionClientIcon","session","Text","sessionClientLabel","Tag","DateTimeText","Button","confirmDanger","onKick","ProfilePage","sections","profileSections","navigation","useSectionSelection","section","activeSection","genderOptions","useDictItems","avatarSelectVisible","setAvatarSelectVisible","useState","changePwdVal","setChangePwdVal","mySettingsQuery","useMySettings","sessionsQuery","useProfileSessions","passwordPolicy","updateProfileMutation","useUpdateProfile","updateAvatarMutation","changePasswordMutation","useChangeProfilePassword","kickOthersMutation","useKickOtherProfileSessions","kickSessionMutation","useKickProfileSession","profileLoading","pwdLoading","sessionsLoading","kickOthersLoading","avatarLoading","handleUpdateProfile","values","formatDateForApi","Toast","handleChangePassword","handleKickOthers","handleKickSession","handleRemoveAvatar","confirmAndDelete","openAvatarPicker","handleApplyAvatar","url","MasterDetailLayout","NavListPanel","SectionNavigation","user","Spin","_Fragment","UserAvatar","Title","Descriptions","DictTag","Space","THEME_TAG_STYLE","p","r","formatDateTime","Divider","Form","PROFILE_CONTROL_STYLE","FormPasswordInput","v","PasswordStrengthMeter","LogOut","UserLoginLogsPanel","SELF_LOGS_SCOPE","UserOperationLogsPanel","AvatarSelectModal","uploadAvatarBlobToFileCenter","Typography"],"ignoreList":[],"sources":["../../src/pages/profile/profile-sections.ts","../../src/pages/profile/ProfilePage.tsx"],"sourcesContent":["import { List, Monitor, Shield, UserRound } from 'lucide-react';\n\nexport const profileSections = [\n { key: 'profile', title: '基本信息', description: '头像、联系方式与个人资料', icon: UserRound },\n { key: 'security', title: '账号安全', description: '登录密码与账号安全', icon: Shield },\n { key: 'devices', title: '我的设备', description: '当前会话与在线设备', icon: Monitor },\n { key: 'login', title: '登录记录', description: '查看自己的登录记录', icon: List },\n { key: 'operation', title: '操作记录', description: '查看自己的操作记录', icon: List },\n] as const;\n","import { FormPasswordInput } from \"@/components/PasswordInput\";\nimport { useState } from 'react';\nimport { Form, Button, Typography, Toast, Tag, Space, Spin, List as SemiList, Descriptions, Divider, Banner } from \"@/ui\";\nimport { LogOut } from 'lucide-react';\nimport { MasterDetailLayout } from '@/components/MasterDetailLayout';\nimport { NavListPanel } from '@/components/NavListPanel';\nimport { SectionNavigation } from '@/components/SectionNavigation';\nimport { profileSections } from './profile-sections';\nimport { useSectionSelection } from '@/hooks/useSectionSelection';\nimport type { User as UserType, UserSession } from '@fudanda/shared/identity';\nimport { AvatarSelectModal } from \"@/components/AvatarSelectModal\";\nimport { uploadAvatarBlobToFileCenter } from \"@fudanda/react-core/utils/avatar-upload\";\nimport { UserAvatar } from \"@/components/UserAvatar\";\nimport { sessionClientLabel } from '@/components/session-client-label';\nimport { SessionClientIcon } from \"@/components/SessionClientTag\";\nimport { formatDateForApi, formatDateTime } from \"@fudanda/react-core/utils/date\";\nimport DateTimeText from \"@/components/DateTimeText\";\nimport type { PasswordRules as PasswordPolicy, SessionConcurrencyPolicy } from '@fudanda/shared/settings';\nimport { formatSessionPolicyHint } from '@fudanda/shared/settings';\nimport { useMySettings } from \"@fudanda/react-core/hooks/queries/settings\";\nimport { PasswordStrengthMeter } from \"@/components/PasswordStrengthMeter\";\nimport { useDictItems } from \"@fudanda/react-core/hooks/useDictItems\";\n\nimport DictTag from \"@/components/DictTag\";\nimport { confirmAndDelete } from \"@/components/list-page/index\";\nimport { confirmDanger } from \"@/utils/confirm\";\nimport { useChangeProfilePassword, useKickOtherProfileSessions, useKickProfileSession, useProfileSessions, useUpdateProfile, } from \"@fudanda/react-core/hooks/queries/profile\";\nimport \"@/pages/profile/ProfilePage.css\";\nimport { UserLoginLogsPanel, UserOperationLogsPanel } from \"@/components/logs/UserLogsPanels\";\nconst { Title, Text } = Typography;\n/** 跟随主题色的浅底标签:Semi Tag 的 color 只支持固定色板,主题色走 CSS 变量覆盖(亮 / 暗主题与主题色切换自动跟随) */\nconst THEME_TAG_STYLE = {\n color: 'var(--arc-antd-color-primary)',\n backgroundColor: 'var(--arc-antd-color-primary-light-default)',\n borderColor: 'transparent',\n} as const;\n/** 个人视角的记录面板 scope:模块级常量,避免每次渲染换引用 */\nconst SELF_LOGS_SCOPE = { kind: 'self' } as const;\nconst PROFILE_CONTROL_STYLE = { width: '100%', maxWidth: 320 } as const;\ninterface ProfilePageProps {\n readonly user: Omit<UserType, 'password'>;\n}\n/** 会话并发策略生效时向用户说明:为什么会被挤下线 / 为什么新设备登不上 */\nfunction SessionPolicyHint({ policy }: {\n readonly policy: SessionConcurrencyPolicy | undefined;\n}) {\n if (!policy || policy.maxSessions <= 0)\n return null;\n return (<Banner type=\"info\" closeIcon={null} fullMode={false} style={{ marginBottom: 12 }} description={`当前策略:${formatSessionPolicyHint(policy)}`}/>);\n}\nfunction SessionList({ sessions, loading, onKick, }: {\n readonly sessions: UserSession[];\n readonly loading?: boolean;\n readonly onKick: (tokenId: string) => void;\n}) {\n return (<SemiList className=\"session-list\" dataSource={sessions} emptyContent={<div className=\"session-list-empty\">暂无在线设备信息</div>} loading={loading} renderItem={(session: UserSession) => (<SemiList.Item key={session.tokenId} align=\"center\" className=\"session-list-item\" main={(<div className=\"session-list-main\">\n <SessionClientIcon client={session.client} size={16} className=\"session-list-client\"/>\n <Text strong>{session.browser}</Text>\n <Text type=\"tertiary\" size=\"small\">{sessionClientLabel(session.client)}</Text>\n {session.isCurrent && <Tag color=\"blue\" size=\"small\">当前设备</Tag>}\n <Text type=\"tertiary\" size=\"small\" className=\"session-list-meta\">\n {session.os} · {`IP: ${session.ip}`}\n {' · '}登录 <DateTimeText value={session.loginAt}/>\n {' · '}活跃 <DateTimeText value={session.lastActiveAt}/>\n </Text>\n </div>)} extra={!session.isCurrent && (<Button theme=\"borderless\" type=\"danger\" size=\"small\" onClick={() => {\n confirmDanger({\n title: '确定要退出该设备吗?',\n onOk: () => onKick(session.tokenId),\n });\n }}>\n 退出\n </Button>)}/>)}/>);\n}\nexport default function ProfilePage({ user }: ProfilePageProps) {\n const sections = profileSections;\n const navigation = useSectionSelection(sections.map(section => section.key), 'profile');\n const activeSection = navigation.active;\n // ─── 基本信息 ────────────────────────────────────────────────────────────────\n const { options: genderOptions } = useDictItems('user_gender');\n // ─── 头像裁剪 ────────────────────────────────────────────────────────────────\n const [avatarSelectVisible, setAvatarSelectVisible] = useState(false);\n // ─── 账号安全 ────────────────────────────────────────────────────────────────\n const [changePwdVal, setChangePwdVal] = useState('');\n useState('');\n // ─── 我的设备 ────────────────────────────────────────────────────────────────\n // 密码规则来自运行时设置的登录用户投影(与布局共用一次请求)\n const mySettingsQuery = useMySettings();\n const sessionsQuery = useProfileSessions(activeSection === 'devices');\n // ─── 已授权应用 ──────────────────────────────────────────────────────────────\n const passwordPolicy: PasswordPolicy | null = mySettingsQuery.data?.identitySecurity.password ?? null;\n const sessions = sessionsQuery.data ?? [];\n const updateProfileMutation = useUpdateProfile();\n const updateAvatarMutation = useUpdateProfile();\n const changePasswordMutation = useChangeProfilePassword();\n const kickOthersMutation = useKickOtherProfileSessions();\n const kickSessionMutation = useKickProfileSession();\n const profileLoading = updateProfileMutation.isPending;\n const pwdLoading = changePasswordMutation.isPending;\n const sessionsLoading = sessionsQuery.isFetching;\n const kickOthersLoading = kickOthersMutation.isPending;\n const avatarLoading = updateAvatarMutation.isPending;\n // ─── 事件处理 ────────────────────────────────────────────────────────────────\n async function handleUpdateProfile(values: {\n nickname: string;\n email: string;\n phone?: string;\n gender?: string | null;\n birthDate?: Date | string | null;\n }) {\n await updateProfileMutation.mutateAsync({ body: { nickname: values.nickname, email: values.email || undefined, phone: values.phone || undefined, gender: values.gender || undefined, birthDate: values.birthDate ? formatDateForApi(values.birthDate) : undefined, clearFields: [...(!values.email ? ['email' as const] : []), ...(!values.phone ? ['phone' as const] : []), ...(!values.gender ? ['gender' as const] : []), ...(!values.birthDate ? ['birthDate' as const] : [])] } });\n Toast.success('资料已更新');\n }\n async function handleChangePassword(values: {\n oldPassword: string;\n newPassword: string;\n confirmPassword: string;\n }) {\n if (values.newPassword !== values.confirmPassword) {\n Toast.error('两次密码输入不一致');\n return false;\n }\n await changePasswordMutation.mutateAsync({ body: { oldPassword: values.oldPassword, newPassword: values.newPassword } });\n Toast.success('密码修改成功,请重新登录');\n setChangePwdVal('');\n }\n async function handleKickOthers() {\n await kickOthersMutation.mutateAsync({});\n Toast.success('操作成功');\n }\n async function handleKickSession(tokenId: string) {\n await kickSessionMutation.mutateAsync({ params: { tokenId } });\n Toast.success('已退出该设备');\n }\n async function handleRemoveAvatar() {\n confirmAndDelete({\n title: '确定要移除头像吗?',\n content: '移除后将使用昵称缩写作为默认头像。',\n run: () => updateAvatarMutation.mutateAsync({ body: { clearFields: ['avatar'] } }),\n successMessage: '头像已移除',\n });\n }\n function openAvatarPicker() {\n setAvatarSelectVisible(true);\n }\n async function handleApplyAvatar(url: string) {\n setAvatarSelectVisible(false);\n await updateAvatarMutation.mutateAsync({ body: { avatar: url } });\n Toast.success('头像已更新');\n }\n // ─── 静态配置 ────────────────────────────────────────────────────────────────\n return (<div className=\"page-container page-container--stretch\">\n <MasterDetailLayout defaultSize={260} minSize={200} maxSize={400} persistKey=\"profile\"\n style={{ flex: 1, minHeight: 0, overflow: 'hidden' }} showDetail={activeSection !== null}\n onBack={navigation.back} onResponsiveChange={navigation.responsiveChange}\n master={<NavListPanel title=\"个人中心\" rawBody>\n <SectionNavigation sections={sections} active={activeSection} onSelect={navigation.select} />\n </NavListPanel>}\n detail={<MasterDetailLayout.Body\n className=\"profile-content-card\" scroll=\"auto\">\n {/* ── 基本信息 ──────────────────────────────────────── */}\n {activeSection === 'profile' && (\n <div className=\"profile-section\">\n <div className=\"section-title\">基本信息</div>\n {user.accountSource === \"casdoor\" && <Banner type=\"info\" description=\"统一账户资料由 Casdoor 管理;请联系管理员修改。\" closeIcon={null}/>}\n <div className=\"profile-basic-overview\">\n <div className=\"avatar-column\">\n <button type=\"button\" className=\"avatar-upload-trigger\" disabled={user.accountSource === \"casdoor\"} onClick={openAvatarPicker} aria-label=\"更换头像\">\n {avatarLoading ? (<div className=\"avatar-loading-wrapper\" style={{ width: 80, height: 80 }}><Spin /></div>) : (<>\n <UserAvatar name={user.nickname || '用户'} avatar={user.avatar} size={80} style={{ fontSize: 28 }}/>\n <div className=\"avatar-upload-mask\">更换头像</div>\n </>)}\n </button>\n <Button size=\"small\" theme=\"light\" loading={avatarLoading} disabled={user.accountSource === \"casdoor\"} onClick={openAvatarPicker} style={{ width: '100%' }}>更换头像</Button>\n </div>\n <div className=\"profile-basic-summary\">\n <div className=\"profile-basic-heading\">\n <Title heading={5} style={{ margin: 0 }}>{user.nickname}</Title>\n <Text type=\"tertiary\" size=\"small\">@{user.username}</Text>\n </div>\n <Descriptions align=\"plain\" layout=\"horizontal\" column={2} style={{ width: '100%' }} data={[\n { key: '手机号', value: user.phone, hidden: !user.phone },\n { key: '邮箱', value: user.email },\n {\n key: '性别',\n value: <DictTag dictCode=\"user_gender\" value={user.gender}/>,\n hidden: !user.gender,\n },\n { key: '出生日期', value: user.birthDate, hidden: !user.birthDate },\n { key: '部门', value: user.departmentName, hidden: !user.departmentName },\n {\n key: '岗位',\n value: user.positions?.length ? (<Space spacing={4} style={{ display: 'inline-flex', flexWrap: 'wrap' }}>\n {user.positions.map((p) => <Tag key={p.id} size=\"small\" style={THEME_TAG_STYLE}>{p.name}</Tag>)}\n </Space>) : undefined,\n hidden: !user.positions?.length,\n },\n {\n key: '角色',\n value: user.roles?.length ? (<Space spacing={4} style={{ display: 'inline-flex', flexWrap: 'wrap' }}>\n {user.roles.map((r) => <Tag key={r.id} size=\"small\" style={THEME_TAG_STYLE}>{r.name}</Tag>)}\n </Space>) : '无角色',\n },\n { key: '注册时间', value: formatDateTime(user.createdAt) },\n ]}/>\n </div>\n </div>\n\n <Divider margin={28}/>\n\n <div className=\"section-title\">资料编辑</div>\n <Form initValues={{ nickname: user.nickname, email: user.email ?? '', phone: user.phone ?? '', gender: user.gender ?? undefined, birthDate: user.birthDate ?? undefined }} disabled={user.accountSource === \"casdoor\"} onSubmit={handleUpdateProfile} allowEmpty labelPosition=\"left\" labelWidth={80}>\n <Form.Input field=\"nickname\" label=\"昵称\" placeholder=\"请输入昵称\" rules={[{ required: true, message: '昵称不能为空' }]} style={PROFILE_CONTROL_STYLE}/>\n <Form.Input field=\"phone\" label=\"手机号\" placeholder=\"请输入手机号(选填)\" rules={[\n { pattern: /^1[3-9]\\d{9}$/, message: '请输入正确的手机号码' },\n ]} style={PROFILE_CONTROL_STYLE}/>\n <Form.Input field=\"email\" label=\"邮箱\" placeholder=\"请输入邮箱(选填)\" rules={[{ type: 'email', message: '邮箱格式不正确' }]} style={PROFILE_CONTROL_STYLE}/>\n <Form.Select field=\"gender\" label=\"性别\" style={PROFILE_CONTROL_STYLE} showClear optionList={genderOptions} placeholder=\"请选择性别(选填)\"/>\n <Form.DatePicker field=\"birthDate\" label=\"出生日期\" type=\"date\" style={PROFILE_CONTROL_STYLE} placeholder=\"请选择出生日期(选填)\" showClear/>\n <Form.Slot>\n <Button htmlType=\"submit\" type=\"primary\" loading={profileLoading}>保存修改</Button>\n </Form.Slot>\n </Form>\n </div>\n )}\n\n {false}\n\n {/* ── 账号安全 ──────────────────────────────────────── */}\n {activeSection === 'security' && (\n <div className=\"profile-section\">\n <div className=\"section-title\">修改密码</div>\n {user.accountSource === \"casdoor\" && <Banner type=\"info\" description=\"密码及 MFA 请在 Casdoor 中管理。\" closeIcon={null}/>}\n <Form disabled={user.accountSource === \"casdoor\"} onSubmit={handleChangePassword} labelPosition=\"left\" labelWidth={100}>\n <FormPasswordInput field=\"oldPassword\" label=\"原密码\" placeholder=\"请输入原密码\" rules={[{ required: true, message: '请输入原密码' }]} style={PROFILE_CONTROL_STYLE}/>\n <FormPasswordInput field=\"newPassword\" label=\"新密码\" placeholder=\"请输入新密码\" rules={[\n { required: true, message: '请输入新密码' },\n ...(passwordPolicy?.minLength ? [{ min: passwordPolicy.minLength, message: `密码至少${passwordPolicy.minLength}个字符` }] : []),\n ]} style={PROFILE_CONTROL_STYLE} onChange={(v) => setChangePwdVal(String(v ?? ''))} helpText={<PasswordStrengthMeter password={changePwdVal} policy={passwordPolicy}/>}/>\n <FormPasswordInput field=\"confirmPassword\" label=\"确认密码\" placeholder=\"请再次输入新密码\" rules={[{ required: true, message: '请确认新密码' }]} style={PROFILE_CONTROL_STYLE}/>\n <Form.Slot>\n <Button htmlType=\"submit\" type=\"primary\" loading={pwdLoading}>修改密码</Button>\n </Form.Slot>\n </Form>\n\n {false}\n </div>\n )}\n\n {/* ── 通知设置 ──────────────────────────────────────── */}\n {false}\n\n {/* ── 我的设备 ──────────────────────────────────────── */}\n {activeSection === 'devices' && (\n <div className=\"profile-section\">\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20 }}>\n <div className=\"section-title\" style={{ margin: 0 }}>在线设备</div>\n <Button type=\"danger\" theme=\"light\" size=\"small\" loading={kickOthersLoading} icon={<LogOut size={14}/>} onClick={() => {\n confirmDanger({\n title: '确定要退出其他所有设备吗?',\n content: '退出后其他设备将需要重新登录。',\n onOk: handleKickOthers,\n });\n }}>\n 退出其他设备\n </Button>\n </div>\n <SessionPolicyHint policy={mySettingsQuery.data?.identitySecurity.session}/>\n <SessionList sessions={sessions} loading={sessionsLoading} onKick={handleKickSession}/>\n </div>\n )}\n\n {/* ── 登录记录 ──────────────────────────────────────── */}\n {activeSection === 'login' && (\n <div className=\"profile-section\">\n <UserLoginLogsPanel scope={SELF_LOGS_SCOPE} enabled={activeSection === 'login'} columnSettingsKey=\"profile-login-logs\"/>\n </div>\n )}\n\n {/* ── 操作记录 ──────────────────────────────────────── */}\n {activeSection === 'operation' && (\n <div className=\"profile-section\">\n <UserOperationLogsPanel scope={SELF_LOGS_SCOPE} enabled={activeSection === 'operation'} columnSettingsKey=\"profile-operation-logs\"/>\n </div>\n )}\n\n {/* ── 已授权应用 ────────────────────────────────────── */}\n {false}\n\n </MasterDetailLayout.Body>} />\n\n {/* ── 头像选择 Modal(本地上传裁剪 + 移除) ─────────────────────────────── */}\n <AvatarSelectModal visible={avatarSelectVisible} currentAvatar={user.avatar} confirmLoading={updateAvatarMutation.isPending} uploadBlob={uploadAvatarBlobToFileCenter} onCancel={() => setAvatarSelectVisible(false)} onSelect={(url) => void handleApplyAvatar(url)} onRemove={user.avatar ? handleRemoveAvatar : undefined}/>\n\n {false}\n </div>);\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{n as e}from"./rolldown-runtime-Bruge11p.js";import{E as t,M as n,O as r,Rt as i,T as a,Ut as o,_ as s,b as c,bt as l,f as u,m as d,xt as f,zt as p}from"./clipboard-dpqHdCyy.js";import{n as m,t as h}from"./MasterDetailLayout-
|
|
1
|
+
import{n as e}from"./rolldown-runtime-Bruge11p.js";import{E as t,M as n,O as r,Rt as i,T as a,Ut as o,_ as s,b as c,bt as l,f as u,m as d,xt as f,zt as p}from"./clipboard-dpqHdCyy.js";import{n as m,t as h}from"./MasterDetailLayout-ByIBpmkZ.js";import{i as g,s as _}from"./toolbar-controls-CrM8hKZg.js";import{n as v,t as y}from"./info-CMEL1G7n.js";import{n as b,t as x}from"./ConfigurableTable-8sYmeul2.js";import{i as S,t as C}from"./webmcp-control-BR0YABIY.js";import{h as w}from"./App-nh6_qOo8.js";import{n as T,r as E}from"./NavListPanel-zwUDIYSP.js";import{i as D,n as O,r as k,t as A}from"./useSectionSelection-DBggfIoz.js";import{useMemo as j,useState as M}from"react";import{useAdminOptions as N}from"@fudanda/admin-antd/core/admin/runtime";import{Fragment as P,jsx as F,jsxs as I}from"react/jsx-runtime";import{usePermission as L}from"@fudanda/admin-antd/core/hooks/usePermission";import{usePagination as R}from"@fudanda/admin-antd/core/hooks/usePagination";import{useFrontendProjectInfo as z,useProjectInfo as B}from"@fudanda/admin-antd/core/hooks/queries/project-info";var V,H;function U(){return(U=e((()=>{
|
|
2
2
|
/**
|
|
3
3
|
* @license lucide-react v1.67.0 - ISC
|
|
4
4
|
*
|
|
@@ -6,4 +6,4 @@ import{n as e}from"./rolldown-runtime-Bruge11p.js";import{E as t,M as n,O as r,R
|
|
|
6
6
|
* See the LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
8
|
f(),V={name:`boxes`,size:24,node:[[`path`,{d:`M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z`,key:`lc1i9w`}],[`path`,{d:`m7 16.5-4.74-2.85`,key:`1o9zyk`}],[`path`,{d:`m7 16.5 5-3`,key:`va8pkn`}],[`path`,{d:`M7 16.5v5.17`,key:`jnp8gn`}],[`path`,{d:`M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z`,key:`8zsnat`}],[`path`,{d:`m17 16.5-5-3`,key:`8arw3v`}],[`path`,{d:`m17 16.5 4.74-2.85`,key:`8rfmw`}],[`path`,{d:`M17 16.5v5.17`,key:`k6z78m`}],[`path`,{d:`M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z`,key:`1xygjf`}],[`path`,{d:`M12 8 7.26 5.15`,key:`1vbdud`}],[`path`,{d:`m12 8 4.74-2.85`,key:`3rx089`}],[`path`,{d:`M12 13.5V8`,key:`1io7kd`}]]},V.node,H=l(V)})))()}function W(e,t,n){let r=e=>e&&![`development`,`unknown`,`(devel)`].includes(e);return[[`应用版本`,e.appVersion,t?.version],[`源码提交`,e.commit,t?.commit],[`发布批次`,e.releaseId,t?.releaseId],[`ArcBase Go SDK 版本`,e.sdkVersion,n]].filter(([,e,t])=>r(e)&&r(t)&&e!==t).map(([e])=>e)}function G(e,t){return K[e]??(e.startsWith(`@types/`)?`TypeScript 类型定义`:t===`go`?`Go 模块依赖`:`前端或构建依赖`)}var K;function q(){return(q=e((()=>{K={"@fudanda/admin-antd":`ArcBase Ant 管理台`,"@fudanda/client":`ArcBase API 客户端`,"@fudanda/workflow":`可选工作流设计器`,"@fudanda/admin-antd/hooks":`管理台会话、权限与数据查询`,"@fudanda/client/contracts":`业务契约与校验`,"@fudanda/admin-antd/elements":`Ant 业务组件`,"@fudanda/admin-antd/table":`统一表格`,"@fudanda/admin-antd/json-render":`JSON UI 渲染`,"@fudanda/create-arcbase":`项目与模块生成器`,"@fudanda/go-sdk":`Go SDK 源码交付`,react:`界面组件运行时`,"react-dom":`浏览器界面渲染`,"react-router-dom":`页面路由`,antd:`Ant Design 基础组件`,"@ant-design/pro-components":`ProComponents 业务组件`,"@ant-design/icons":`Ant 图标`,"@tanstack/react-query":`服务端数据查询与缓存`,"@tanstack/react-pacer":`交互节流与防抖`,zod:`运行时数据校验`,dayjs:`日期和时间处理`,"lucide-react":`界面图标`,overlayscrollbars:`统一滚动条`,"overlayscrollbars-react":`滚动条 React 适配`,"@openobserve/browser-rum":`前端性能与错误监控`,"@openobserve/browser-logs":`前端日志采集`,vite:`前端开发与构建`,typescript:`TypeScript 编译与类型检查`,eslint:`代码规范检查`,vitest:`自动化测试`,"@vitejs/plugin-react":`React 开发与构建适配`,tailwindcss:`工具类样式编译`,mermaid:`文档图表渲染`,"monaco-editor":`按需代码编辑器`,zustand:`组件状态管理`,"goa.design/goa/v3":`API 契约与传输生成`,"goa.design/clue":`日志与链路追踪`,"entgo.io/ent":`类型安全数据访问`,"github.com/jackc/pgx/v5":`PostgreSQL 驱动`,"modernc.org/sqlite":`SQLite 驱动`,"github.com/fudanda/arcbase/backend/v2":`ArcBase Go SDK`,"github.com/cloudwego/eino":`可选 AI 模型执行`}})))()}function J(){let{hasPermission:e}=L();return e(`system:project-info:view`)?/* @__PURE__ */ F(Y,{}):/* @__PURE__ */ F(`div`,{className:`page-container`,children:/* @__PURE__ */ F(c,{description:`无访问权限`})})}function Y(){let e=N(),n=B(),l=z(e.projectInfo),f=O(Z,`version`);S({id:`project-info`,title:`项目信息`,tools:[],context:()=>({section:f.active??`navigation`})});let[m,_]=M(``),[v,y]=M(`all`),[b,C]=M(!1),E=w(e.versionInfo),D=l.data?.identity??E??{},A=W(D,n.data?.application,n.data?.sdk.version),L=j(()=>[...(l.data?.dependencies??[]).map((e,t)=>({key:`npm:${e.name}:${t}`,name:e.name,version:e.version,ecosystem:`npm`,kind:e.direct?`direct`:`indirect`,development:e.development,replaced:!1,purpose:G(e.name,`npm`)})),...(n.data?.dependencies??[]).map((e,t)=>({key:`go:${e.name}:${t}`,name:e.name,version:e.version,ecosystem:`go`,kind:e.kind,development:!1,replaced:e.replaced,purpose:G(e.name,`go`)}))],[l.data,n.data]),V=L.filter(e=>(v===`all`||e.ecosystem===v)&&(b||e.kind!==`indirect`)&&`${e.name} ${e.version} ${e.purpose}`.toLowerCase().includes(m.trim().toLowerCase())),H=R({resetKey:[m,v,b,L.length]}),U=Math.min(H.page,Math.max(1,Math.ceil(V.length/H.pageSize))),K=()=>{n.refetch(),l.available&&l.refetch()};return/* @__PURE__ */ F(`div`,{className:`page-container page-container--stretch project-info-page`,children:/* @__PURE__ */ F(h,{defaultSize:260,minSize:200,maxSize:400,persistKey:`project-info`,style:{flex:1,minHeight:0,overflow:`hidden`},showDetail:f.active!==null,onBack:f.back,onResponsiveChange:f.responsiveChange,master:/* @__PURE__ */ F(T,{title:`项目信息`,rawBody:!0,children:/* @__PURE__ */ F(k,{sections:X,active:f.active,onSelect:f.select})}),detail:/* @__PURE__ */ I(P,{children:[/* @__PURE__ */ F(h.Header,{extra:/* @__PURE__ */ F(g,{onClick:K,loading:n.isFetching||l.isFetching,children:`刷新`}),children:/* @__PURE__ */ F(`strong`,{children:X.find(e=>e.key===f.active)?.title??`项目信息`})}),/* @__PURE__ */ F(h.Body,{padding:24,children:/* @__PURE__ */ I(`div`,{className:`project-info-content`,children:[n.error&&/* @__PURE__ */ F(u,{type:`danger`,closeIcon:null,description:/* @__PURE__ */ I(`span`,{children:[`后端项目信息加载失败;当前服务可能尚未升级或没有访问权限。`,/* @__PURE__ */ F(d,{onClick:()=>void n.refetch(),children:`重试`})]})}),l.error&&/* @__PURE__ */ F(u,{type:`danger`,closeIcon:null,description:/* @__PURE__ */ I(`span`,{children:[`前端项目信息清单加载失败,请检查本次构建产物。`,/* @__PURE__ */ F(d,{onClick:()=>void l.refetch(),children:`重试`})]})}),l.data?.source===`workspace-source`&&/* @__PURE__ */ F(u,{type:`info`,closeIcon:null,description:`当前为源码热更新模式:前端信息来自工作区,后端信息来自正在运行的二进制。`}),!l.available&&/* @__PURE__ */ F(u,{type:`info`,closeIcon:null,description:`当前宿主未附带前端依赖清单;已有版本信息仍可查看,升级构建入口后可补齐。`}),f.active===`version`?/* @__PURE__ */ I(P,{children:[A.length>0&&/* @__PURE__ */ F(u,{type:`warning`,closeIcon:null,description:`前后端的${A.join(`、`)}不一致,请核对部署或联调状态。`}),(n.isLoading||l.isLoading)&&/* @__PURE__ */ F(`div`,{"aria-busy":`true`,"aria-label":`正在加载项目信息`,children:/* @__PURE__ */ F(t,{})}),/* @__PURE__ */ I(`section`,{className:`project-info-panel`,"aria-label":`前端构建信息`,children:[/* @__PURE__ */ F(`h3`,{children:`前端构建信息`}),/* @__PURE__ */ F(s,{bordered:!0,column:{xs:1,md:2},data:[{key:`应用名称`,value:Q(D.application)},{key:`应用版本`,value:Q(D.appVersion)},{key:`ArcBase Go SDK`,value:Q(D.sdkVersion)},{key:`发布批次`,value:Q(D.releaseId)},{key:`源码提交`,value:Q(D.commit)},{key:`构建时间`,value:Q(D.buildTime)}]})]}),/* @__PURE__ */ I(`section`,{className:`project-info-panel`,"aria-label":`后端运行信息`,children:[/* @__PURE__ */ F(`h3`,{children:`后端运行信息`}),n.data?/* @__PURE__ */ F(s,{bordered:!0,column:{xs:1,md:2},data:[{key:`应用名称`,value:Q(n.data.application?.name)},{key:`应用版本`,value:Q(n.data.application?.version)},{key:`ArcBase Go SDK`,value:Q(n.data.sdk.version)},{key:`发布批次`,value:Q(n.data.application?.releaseId)},{key:`源码提交`,value:Q(n.data.application?.commit)},{key:`构建时间`,value:Q(n.data.application?.buildTime)},{key:`Go 版本`,value:Q(n.data.runtime.version)},{key:`运行平台`,value:`${n.data.runtime.goos} / ${n.data.runtime.goarch}`},{key:`SDK 源码提交`,value:Q(n.data.sdk.commit)}]}):!n.isLoading&&/* @__PURE__ */ F(c,{description:`后端运行信息暂不可用`})]})]}):/* @__PURE__ */ I(P,{children:[/* @__PURE__ */ I(`div`,{className:`project-info-filters`,children:[/* @__PURE__ */ F(p,{"aria-label":`搜索项目依赖`,placeholder:`包名、版本或用途`,value:m,onChange:_,showClear:!0}),/* @__PURE__ */ F(o,{"aria-label":`依赖类型`,value:v,onChange:y,optionList:[{value:`all`,label:`全部依赖`},{value:`npm`,label:`前端 npm`},{value:`go`,label:`Go 模块`}]}),/* @__PURE__ */ F(i,{checked:b,onChange:e=>C(e.target.checked),children:`显示间接依赖`})]}),n.data?.dependencySource===`unavailable`&&/* @__PURE__ */ F(u,{type:`info`,closeIcon:null,description:`当前二进制未提供 Go 构建依赖信息。`}),/* @__PURE__ */ F(`p`,{className:`project-info-hint`,children:`前端清单来自构建时已安装的项目依赖图,包含运行依赖和开发工具,不代表全部进入浏览器产物。Go 依赖未提供直接性时标记为“未分类”。版本展示不查询包仓库。`}),/* @__PURE__ */ F(x,{headerTitle:`项目依赖`,rowKey:`key`,dataSource:V.slice((U-1)*H.pageSize,U*H.pageSize),loading:n.isLoading||l.isLoading,onRefresh:K,refreshLoading:n.isFetching||l.isFetching,pagination:{...H.buildPagination(V.length),currentPage:U},columnSettingsKey:`project-info-dependencies`,columns:[{title:`依赖包`,dataIndex:`name`,minWidth:250,render:e=>/* @__PURE__ */ F(`code`,{children:e})},{title:`实际版本`,dataIndex:`version`,minWidth:180},{title:`类型`,dataIndex:`ecosystem`,width:110,render:e=>/* @__PURE__ */ F(r,{children:e===`go`?`Go`:`npm`})},{title:`关系`,dataIndex:`kind`,width:160,render:(e,t)=>/* @__PURE__ */ I(a,{spacing:4,children:[/* @__PURE__ */ F(r,{children:t.kind===`direct`?`直接`:t.kind===`indirect`?`间接`:`未分类`}),t.development&&/* @__PURE__ */ F(r,{children:`开发`}),t.replaced&&/* @__PURE__ */ F(r,{children:`已替换`})]})},{title:`用途`,dataIndex:`purpose`,minWidth:220}]})]})]})})]})})})}var X,Z,Q;function $(){return($=e((()=>{U(),v(),n(),m(),E(),D(),_(),b(),A(),C(),q(),X=[{key:`version`,title:`版本信息`,description:`当前前端构建与后端运行身份`,icon:y},{key:`dependencies`,title:`项目依赖`,description:`前端和 Go 的实际依赖版本`,icon:H}],Z=X.map(e=>e.key),Q=e=>e||`未提供`})))()}$();export{J as default};
|
|
9
|
-
//# sourceMappingURL=ProjectInfoPage-
|
|
9
|
+
//# sourceMappingURL=ProjectInfoPage-CJpGxpu5.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectInfoPage-DkuBLC8t.js","mappings":"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","names":["__iconData","createLucideIcon","versionDifferences","known","value","frontend","backend","sdkVersion","left","right","label","dependencyPurpose","purposes","name","ecosystem","ProjectInfoPage","usePermission","hasPermission","ProjectInfoContent","Empty","options","useAdminOptions","useProjectInfo","useFrontendProjectInfo","navigation","useSectionSelection","sectionKeys","useWebMcpPageAdapter","search","setSearch","useState","setEcosystem","includeTransitive","setIncludeTransitive","legacy","readAccountVersionInfo","identity","differences","rows","useMemo","dependency","index","filtered","row","pagination","usePagination","page","reload","MasterDetailLayout","NavListPanel","SectionNavigation","_Fragment","RefreshButton","sections","section","Banner","Button","Spin","Descriptions","empty","Input","Select","Checkbox","event","ConfigurableTable","Tag","Space","Info","Boxes"],"ignoreList":[0],"sources":["../../../../node_modules/lucide-react/dist/esm/icons/boxes.mjs","../../src/pages/system/project-info/project-info.ts","../../src/pages/system/project-info/ProjectInfoPage.tsx"],"sourcesContent":[null,"import type { ArcBaseFrontendProjectInfo } from '@fudanda/react-core/admin/types';\n\ntype BuildIdentity = { version?: string; commit?: string; releaseId?: string };\nexport function versionDifferences(frontend: ArcBaseFrontendProjectInfo['identity'], backend: BuildIdentity | undefined, sdkVersion?: string): string[] {\n const known = (value: string | undefined) => value && !['development', 'unknown', '(devel)'].includes(value);\n return [\n ['应用版本', frontend.appVersion, backend?.version],\n ['源码提交', frontend.commit, backend?.commit],\n ['发布批次', frontend.releaseId, backend?.releaseId],\n ['ArcBase Go SDK 版本', frontend.sdkVersion, sdkVersion],\n ].filter(([, left, right]) => known(left) && known(right) && left !== right).map(([label]) => label!);\n}\n\nconst purposes: Record<string, string> = {\n '@fudanda/admin-antd': 'ArcBase Ant 管理台', '@fudanda/client': 'ArcBase API 客户端', '@fudanda/workflow': '可选工作流设计器',\n '@fudanda/react-core': '管理台会话、权限与数据查询', '@fudanda/shared': '业务契约与校验',\n '@fudanda/elements-antd': 'Ant 业务组件', '@fudanda/table-antd': '统一表格', '@fudanda/json-render-antd': 'JSON UI 渲染',\n '@fudanda/create-arcbase': '项目与模块生成器', '@fudanda/go-sdk': 'Go SDK 源码交付',\n react: '界面组件运行时', 'react-dom': '浏览器界面渲染', 'react-router-dom': '页面路由',\n antd: 'Ant Design 基础组件', '@ant-design/pro-components': 'ProComponents 业务组件', '@ant-design/icons': 'Ant 图标',\n '@tanstack/react-query': '服务端数据查询与缓存', '@tanstack/react-pacer': '交互节流与防抖',\n zod: '运行时数据校验', dayjs: '日期和时间处理', 'lucide-react': '界面图标',\n overlayscrollbars: '统一滚动条', 'overlayscrollbars-react': '滚动条 React 适配',\n '@openobserve/browser-rum': '前端性能与错误监控', '@openobserve/browser-logs': '前端日志采集',\n vite: '前端开发与构建', typescript: 'TypeScript 编译与类型检查', eslint: '代码规范检查', vitest: '自动化测试',\n '@vitejs/plugin-react': 'React 开发与构建适配', tailwindcss: '工具类样式编译', mermaid: '文档图表渲染',\n 'monaco-editor': '按需代码编辑器', zustand: '组件状态管理',\n 'goa.design/goa/v3': 'API 契约与传输生成', 'goa.design/clue': '日志与链路追踪', 'entgo.io/ent': '类型安全数据访问',\n 'github.com/jackc/pgx/v5': 'PostgreSQL 驱动', 'modernc.org/sqlite': 'SQLite 驱动',\n 'github.com/fudanda/arcbase/backend/v2': 'ArcBase Go SDK',\n 'github.com/cloudwego/eino': '可选 AI 模型执行',\n};\nexport function dependencyPurpose(name: string, ecosystem: 'npm' | 'go'): string {\n return purposes[name] ?? (name.startsWith('@types/') ? 'TypeScript 类型定义' : ecosystem === 'go' ? 'Go 模块依赖' : '前端或构建依赖');\n}\n\nexport type ProjectDependencyRow = {\n key: string; name: string; version: string; ecosystem: 'npm' | 'go';\n kind: 'direct' | 'indirect' | 'unknown'; development: boolean; replaced: boolean; purpose: string;\n};\n","import { useMemo, useState } from 'react';\nimport { Boxes, Info } from 'lucide-react';\nimport { useAdminOptions } from '@fudanda/react-core/admin/runtime';\nimport type { ArcBaseFrontendProjectInfo } from '@fudanda/react-core/admin/types';\nimport { usePermission } from '@fudanda/react-core/hooks/usePermission';\nimport { usePagination } from '@fudanda/react-core/hooks/usePagination';\nimport { useFrontendProjectInfo, useProjectInfo } from '@fudanda/react-core/hooks/queries/project-info';\nimport { Banner, Button, Checkbox, Descriptions, Empty, Input, Select, Space, Spin, Tag } from '@/ui';\nimport { MasterDetailLayout } from '@/components/MasterDetailLayout';\nimport { NavListPanel } from '@/components/NavListPanel';\nimport { SectionNavigation } from '@/components/SectionNavigation';\nimport { RefreshButton } from '@/components/toolbar-controls';\nimport ConfigurableTable from '@/components/ConfigurableTable';\nimport { readAccountVersionInfo } from '@/components/account-version-info';\nimport { useSectionSelection } from '@/hooks/useSectionSelection';\nimport { useWebMcpPageAdapter } from '@/webmcp-control';\nimport { dependencyPurpose, versionDifferences, type ProjectDependencyRow } from './project-info';\nimport './ProjectInfoPage.css';\n\nconst sections = [\n { key: 'version', title: '版本信息', description: '当前前端构建与后端运行身份', icon: Info },\n { key: 'dependencies', title: '项目依赖', description: '前端和 Go 的实际依赖版本', icon: Boxes },\n] as const;\nconst sectionKeys = sections.map(section => section.key);\nconst empty = (value: string | undefined) => value || '未提供';\n\nexport default function ProjectInfoPage() {\n const { hasPermission } = usePermission();\n if (!hasPermission('system:project-info:view')) return <div className=\"page-container\"><Empty description=\"无访问权限\" /></div>;\n return <ProjectInfoContent />;\n}\n\nfunction ProjectInfoContent() {\n const options = useAdminOptions();\n const backend = useProjectInfo(), frontend = useFrontendProjectInfo(options.projectInfo);\n const navigation = useSectionSelection(sectionKeys, 'version');\n useWebMcpPageAdapter({ id: 'project-info', title: '项目信息', tools: [],\n context: () => ({ section: navigation.active ?? 'navigation' }) });\n const [search, setSearch] = useState('');\n const [ecosystem, setEcosystem] = useState<'all' | 'npm' | 'go'>('all');\n const [includeTransitive, setIncludeTransitive] = useState(false);\n const legacy = readAccountVersionInfo(options.versionInfo);\n const identity: ArcBaseFrontendProjectInfo['identity'] = frontend.data?.identity ?? legacy ?? {};\n const differences = versionDifferences(identity, backend.data?.application, backend.data?.sdk.version);\n const rows = useMemo<ProjectDependencyRow[]>(() => [\n ...(frontend.data?.dependencies ?? []).map((dependency, index): ProjectDependencyRow => ({\n key: `npm:${dependency.name}:${index}`, name: dependency.name, version: dependency.version, ecosystem: 'npm',\n kind: dependency.direct ? 'direct' : 'indirect', development: dependency.development, replaced: false,\n purpose: dependencyPurpose(dependency.name, 'npm'),\n })),\n ...(backend.data?.dependencies ?? []).map((dependency, index): ProjectDependencyRow => ({\n key: `go:${dependency.name}:${index}`, name: dependency.name, version: dependency.version, ecosystem: 'go',\n kind: dependency.kind, development: false, replaced: dependency.replaced,\n purpose: dependencyPurpose(dependency.name, 'go'),\n })),\n ], [frontend.data, backend.data]);\n const filtered = rows.filter(row => (ecosystem === 'all' || row.ecosystem === ecosystem)\n && (includeTransitive || row.kind !== 'indirect')\n && `${row.name} ${row.version} ${row.purpose}`.toLowerCase().includes(search.trim().toLowerCase()));\n const pagination = usePagination({ resetKey: [search, ecosystem, includeTransitive, rows.length] });\n const page = Math.min(pagination.page, Math.max(1, Math.ceil(filtered.length / pagination.pageSize)));\n const reload = () => { void backend.refetch(); if (frontend.available) void frontend.refetch(); };\n return <div className=\"page-container page-container--stretch project-info-page\">\n <MasterDetailLayout defaultSize={260} minSize={200} maxSize={400} persistKey=\"project-info\"\n style={{ flex: 1, minHeight: 0, overflow: 'hidden' }} showDetail={navigation.active !== null}\n onBack={navigation.back} onResponsiveChange={navigation.responsiveChange}\n master={<NavListPanel title=\"项目信息\" rawBody><SectionNavigation sections={sections} active={navigation.active} onSelect={navigation.select} /></NavListPanel>}\n detail={<>\n <MasterDetailLayout.Header extra={<RefreshButton onClick={reload} loading={backend.isFetching || frontend.isFetching}>刷新</RefreshButton>}>\n <strong>{sections.find(section => section.key === navigation.active)?.title ?? '项目信息'}</strong>\n </MasterDetailLayout.Header>\n <MasterDetailLayout.Body padding={24}>\n <div className=\"project-info-content\">\n {backend.error && <Banner type=\"danger\" closeIcon={null} description={<span>后端项目信息加载失败;当前服务可能尚未升级或没有访问权限。<Button onClick={() => void backend.refetch()}>重试</Button></span>} />}\n {frontend.error && <Banner type=\"danger\" closeIcon={null} description={<span>前端项目信息清单加载失败,请检查本次构建产物。<Button onClick={() => void frontend.refetch()}>重试</Button></span>} />}\n {frontend.data?.source === 'workspace-source' && <Banner type=\"info\" closeIcon={null} description=\"当前为源码热更新模式:前端信息来自工作区,后端信息来自正在运行的二进制。\" />}\n {!frontend.available && <Banner type=\"info\" closeIcon={null} description=\"当前宿主未附带前端依赖清单;已有版本信息仍可查看,升级构建入口后可补齐。\" />}\n {navigation.active === 'version' ? <>\n {differences.length > 0 && <Banner type=\"warning\" closeIcon={null} description={`前后端的${differences.join('、')}不一致,请核对部署或联调状态。`} />}\n {(backend.isLoading || frontend.isLoading) && <div aria-busy=\"true\" aria-label=\"正在加载项目信息\"><Spin /></div>}\n <section className=\"project-info-panel\" aria-label=\"前端构建信息\">\n <h3>前端构建信息</h3>\n <Descriptions bordered column={{ xs: 1, md: 2 }} data={[\n { key: '应用名称', value: empty(identity.application) },\n { key: '应用版本', value: empty(identity.appVersion) }, { key: 'ArcBase Go SDK', value: empty(identity.sdkVersion) },\n { key: '发布批次', value: empty(identity.releaseId) }, { key: '源码提交', value: empty(identity.commit) },\n { key: '构建时间', value: empty(identity.buildTime) },\n ]} />\n </section>\n <section className=\"project-info-panel\" aria-label=\"后端运行信息\">\n <h3>后端运行信息</h3>\n {backend.data ? <Descriptions bordered column={{ xs: 1, md: 2 }} data={[\n { key: '应用名称', value: empty(backend.data.application?.name) },\n { key: '应用版本', value: empty(backend.data.application?.version) },\n { key: 'ArcBase Go SDK', value: empty(backend.data.sdk.version) },\n { key: '发布批次', value: empty(backend.data.application?.releaseId) },\n { key: '源码提交', value: empty(backend.data.application?.commit) },\n { key: '构建时间', value: empty(backend.data.application?.buildTime) },\n { key: 'Go 版本', value: empty(backend.data.runtime.version) },\n { key: '运行平台', value: `${backend.data.runtime.goos} / ${backend.data.runtime.goarch}` },\n { key: 'SDK 源码提交', value: empty(backend.data.sdk.commit) },\n ]} /> : !backend.isLoading && <Empty description=\"后端运行信息暂不可用\" />}\n </section>\n </> : <>\n <div className=\"project-info-filters\">\n <Input aria-label=\"搜索项目依赖\" placeholder=\"包名、版本或用途\" value={search} onChange={setSearch} showClear />\n <Select aria-label=\"依赖类型\" value={ecosystem} onChange={setEcosystem} optionList={[{ value: 'all', label: '全部依赖' }, { value: 'npm', label: '前端 npm' }, { value: 'go', label: 'Go 模块' }]} />\n <Checkbox checked={includeTransitive} onChange={event => setIncludeTransitive(event.target.checked)}>显示间接依赖</Checkbox>\n </div>\n {backend.data?.dependencySource === 'unavailable' && <Banner type=\"info\" closeIcon={null} description=\"当前二进制未提供 Go 构建依赖信息。\" />}\n <p className=\"project-info-hint\">前端清单来自构建时已安装的项目依赖图,包含运行依赖和开发工具,不代表全部进入浏览器产物。Go 依赖未提供直接性时标记为“未分类”。版本展示不查询包仓库。</p>\n <ConfigurableTable<ProjectDependencyRow> headerTitle=\"项目依赖\" rowKey=\"key\" dataSource={filtered.slice((page - 1) * pagination.pageSize, page * pagination.pageSize)}\n loading={backend.isLoading || frontend.isLoading} onRefresh={reload} refreshLoading={backend.isFetching || frontend.isFetching}\n pagination={{ ...pagination.buildPagination(filtered.length), currentPage: page }} columnSettingsKey=\"project-info-dependencies\"\n columns={[\n { title: '依赖包', dataIndex: 'name', minWidth: 250, render: (value: string) => <code>{value}</code> },\n { title: '实际版本', dataIndex: 'version', minWidth: 180 },\n { title: '类型', dataIndex: 'ecosystem', width: 110, render: (value: string) => <Tag>{value === 'go' ? 'Go' : 'npm'}</Tag> },\n { title: '关系', dataIndex: 'kind', width: 160, render: (_value: string, row) => <Space spacing={4}><Tag>{row.kind === 'direct' ? '直接' : row.kind === 'indirect' ? '间接' : '未分类'}</Tag>{row.development && <Tag>开发</Tag>}{row.replaced && <Tag>已替换</Tag>}</Space> },\n { title: '用途', dataIndex: 'purpose', minWidth: 220 },\n ]} />\n </>}\n </div>\n </MasterDetailLayout.Body>\n </>} />\n </div>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ProjectInfoPage-CJpGxpu5.js","mappings":"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","names":["__iconData","createLucideIcon","versionDifferences","known","value","frontend","backend","sdkVersion","left","right","label","dependencyPurpose","purposes","name","ecosystem","ProjectInfoPage","usePermission","hasPermission","ProjectInfoContent","Empty","options","useAdminOptions","useProjectInfo","useFrontendProjectInfo","navigation","useSectionSelection","sectionKeys","useWebMcpPageAdapter","search","setSearch","useState","setEcosystem","includeTransitive","setIncludeTransitive","legacy","readAccountVersionInfo","identity","differences","rows","useMemo","dependency","index","filtered","row","pagination","usePagination","page","reload","MasterDetailLayout","NavListPanel","SectionNavigation","_Fragment","RefreshButton","sections","section","Banner","Button","Spin","Descriptions","empty","Input","Select","Checkbox","event","ConfigurableTable","Tag","Space","Info","Boxes"],"ignoreList":[0],"sources":["../../../../node_modules/lucide-react/dist/esm/icons/boxes.mjs","../../src/pages/system/project-info/project-info.ts","../../src/pages/system/project-info/ProjectInfoPage.tsx"],"sourcesContent":[null,"import type { ArcBaseFrontendProjectInfo } from '@fudanda/react-core/admin/types';\n\ntype BuildIdentity = { version?: string; commit?: string; releaseId?: string };\nexport function versionDifferences(frontend: ArcBaseFrontendProjectInfo['identity'], backend: BuildIdentity | undefined, sdkVersion?: string): string[] {\n const known = (value: string | undefined) => value && !['development', 'unknown', '(devel)'].includes(value);\n return [\n ['应用版本', frontend.appVersion, backend?.version],\n ['源码提交', frontend.commit, backend?.commit],\n ['发布批次', frontend.releaseId, backend?.releaseId],\n ['ArcBase Go SDK 版本', frontend.sdkVersion, sdkVersion],\n ].filter(([, left, right]) => known(left) && known(right) && left !== right).map(([label]) => label!);\n}\n\nconst purposes: Record<string, string> = {\n '@fudanda/admin-antd': 'ArcBase Ant 管理台', '@fudanda/client': 'ArcBase API 客户端', '@fudanda/workflow': '可选工作流设计器',\n '@fudanda/react-core': '管理台会话、权限与数据查询', '@fudanda/shared': '业务契约与校验',\n '@fudanda/elements-antd': 'Ant 业务组件', '@fudanda/table-antd': '统一表格', '@fudanda/json-render-antd': 'JSON UI 渲染',\n '@fudanda/create-arcbase': '项目与模块生成器', '@fudanda/go-sdk': 'Go SDK 源码交付',\n react: '界面组件运行时', 'react-dom': '浏览器界面渲染', 'react-router-dom': '页面路由',\n antd: 'Ant Design 基础组件', '@ant-design/pro-components': 'ProComponents 业务组件', '@ant-design/icons': 'Ant 图标',\n '@tanstack/react-query': '服务端数据查询与缓存', '@tanstack/react-pacer': '交互节流与防抖',\n zod: '运行时数据校验', dayjs: '日期和时间处理', 'lucide-react': '界面图标',\n overlayscrollbars: '统一滚动条', 'overlayscrollbars-react': '滚动条 React 适配',\n '@openobserve/browser-rum': '前端性能与错误监控', '@openobserve/browser-logs': '前端日志采集',\n vite: '前端开发与构建', typescript: 'TypeScript 编译与类型检查', eslint: '代码规范检查', vitest: '自动化测试',\n '@vitejs/plugin-react': 'React 开发与构建适配', tailwindcss: '工具类样式编译', mermaid: '文档图表渲染',\n 'monaco-editor': '按需代码编辑器', zustand: '组件状态管理',\n 'goa.design/goa/v3': 'API 契约与传输生成', 'goa.design/clue': '日志与链路追踪', 'entgo.io/ent': '类型安全数据访问',\n 'github.com/jackc/pgx/v5': 'PostgreSQL 驱动', 'modernc.org/sqlite': 'SQLite 驱动',\n 'github.com/fudanda/arcbase/backend/v2': 'ArcBase Go SDK',\n 'github.com/cloudwego/eino': '可选 AI 模型执行',\n};\nexport function dependencyPurpose(name: string, ecosystem: 'npm' | 'go'): string {\n return purposes[name] ?? (name.startsWith('@types/') ? 'TypeScript 类型定义' : ecosystem === 'go' ? 'Go 模块依赖' : '前端或构建依赖');\n}\n\nexport type ProjectDependencyRow = {\n key: string; name: string; version: string; ecosystem: 'npm' | 'go';\n kind: 'direct' | 'indirect' | 'unknown'; development: boolean; replaced: boolean; purpose: string;\n};\n","import { useMemo, useState } from 'react';\nimport { Boxes, Info } from 'lucide-react';\nimport { useAdminOptions } from '@fudanda/react-core/admin/runtime';\nimport type { ArcBaseFrontendProjectInfo } from '@fudanda/react-core/admin/types';\nimport { usePermission } from '@fudanda/react-core/hooks/usePermission';\nimport { usePagination } from '@fudanda/react-core/hooks/usePagination';\nimport { useFrontendProjectInfo, useProjectInfo } from '@fudanda/react-core/hooks/queries/project-info';\nimport { Banner, Button, Checkbox, Descriptions, Empty, Input, Select, Space, Spin, Tag } from '@/ui';\nimport { MasterDetailLayout } from '@/components/MasterDetailLayout';\nimport { NavListPanel } from '@/components/NavListPanel';\nimport { SectionNavigation } from '@/components/SectionNavigation';\nimport { RefreshButton } from '@/components/toolbar-controls';\nimport ConfigurableTable from '@/components/ConfigurableTable';\nimport { readAccountVersionInfo } from '@/components/account-version-info';\nimport { useSectionSelection } from '@/hooks/useSectionSelection';\nimport { useWebMcpPageAdapter } from '@/webmcp-control';\nimport { dependencyPurpose, versionDifferences, type ProjectDependencyRow } from './project-info';\nimport './ProjectInfoPage.css';\n\nconst sections = [\n { key: 'version', title: '版本信息', description: '当前前端构建与后端运行身份', icon: Info },\n { key: 'dependencies', title: '项目依赖', description: '前端和 Go 的实际依赖版本', icon: Boxes },\n] as const;\nconst sectionKeys = sections.map(section => section.key);\nconst empty = (value: string | undefined) => value || '未提供';\n\nexport default function ProjectInfoPage() {\n const { hasPermission } = usePermission();\n if (!hasPermission('system:project-info:view')) return <div className=\"page-container\"><Empty description=\"无访问权限\" /></div>;\n return <ProjectInfoContent />;\n}\n\nfunction ProjectInfoContent() {\n const options = useAdminOptions();\n const backend = useProjectInfo(), frontend = useFrontendProjectInfo(options.projectInfo);\n const navigation = useSectionSelection(sectionKeys, 'version');\n useWebMcpPageAdapter({ id: 'project-info', title: '项目信息', tools: [],\n context: () => ({ section: navigation.active ?? 'navigation' }) });\n const [search, setSearch] = useState('');\n const [ecosystem, setEcosystem] = useState<'all' | 'npm' | 'go'>('all');\n const [includeTransitive, setIncludeTransitive] = useState(false);\n const legacy = readAccountVersionInfo(options.versionInfo);\n const identity: ArcBaseFrontendProjectInfo['identity'] = frontend.data?.identity ?? legacy ?? {};\n const differences = versionDifferences(identity, backend.data?.application, backend.data?.sdk.version);\n const rows = useMemo<ProjectDependencyRow[]>(() => [\n ...(frontend.data?.dependencies ?? []).map((dependency, index): ProjectDependencyRow => ({\n key: `npm:${dependency.name}:${index}`, name: dependency.name, version: dependency.version, ecosystem: 'npm',\n kind: dependency.direct ? 'direct' : 'indirect', development: dependency.development, replaced: false,\n purpose: dependencyPurpose(dependency.name, 'npm'),\n })),\n ...(backend.data?.dependencies ?? []).map((dependency, index): ProjectDependencyRow => ({\n key: `go:${dependency.name}:${index}`, name: dependency.name, version: dependency.version, ecosystem: 'go',\n kind: dependency.kind, development: false, replaced: dependency.replaced,\n purpose: dependencyPurpose(dependency.name, 'go'),\n })),\n ], [frontend.data, backend.data]);\n const filtered = rows.filter(row => (ecosystem === 'all' || row.ecosystem === ecosystem)\n && (includeTransitive || row.kind !== 'indirect')\n && `${row.name} ${row.version} ${row.purpose}`.toLowerCase().includes(search.trim().toLowerCase()));\n const pagination = usePagination({ resetKey: [search, ecosystem, includeTransitive, rows.length] });\n const page = Math.min(pagination.page, Math.max(1, Math.ceil(filtered.length / pagination.pageSize)));\n const reload = () => { void backend.refetch(); if (frontend.available) void frontend.refetch(); };\n return <div className=\"page-container page-container--stretch project-info-page\">\n <MasterDetailLayout defaultSize={260} minSize={200} maxSize={400} persistKey=\"project-info\"\n style={{ flex: 1, minHeight: 0, overflow: 'hidden' }} showDetail={navigation.active !== null}\n onBack={navigation.back} onResponsiveChange={navigation.responsiveChange}\n master={<NavListPanel title=\"项目信息\" rawBody><SectionNavigation sections={sections} active={navigation.active} onSelect={navigation.select} /></NavListPanel>}\n detail={<>\n <MasterDetailLayout.Header extra={<RefreshButton onClick={reload} loading={backend.isFetching || frontend.isFetching}>刷新</RefreshButton>}>\n <strong>{sections.find(section => section.key === navigation.active)?.title ?? '项目信息'}</strong>\n </MasterDetailLayout.Header>\n <MasterDetailLayout.Body padding={24}>\n <div className=\"project-info-content\">\n {backend.error && <Banner type=\"danger\" closeIcon={null} description={<span>后端项目信息加载失败;当前服务可能尚未升级或没有访问权限。<Button onClick={() => void backend.refetch()}>重试</Button></span>} />}\n {frontend.error && <Banner type=\"danger\" closeIcon={null} description={<span>前端项目信息清单加载失败,请检查本次构建产物。<Button onClick={() => void frontend.refetch()}>重试</Button></span>} />}\n {frontend.data?.source === 'workspace-source' && <Banner type=\"info\" closeIcon={null} description=\"当前为源码热更新模式:前端信息来自工作区,后端信息来自正在运行的二进制。\" />}\n {!frontend.available && <Banner type=\"info\" closeIcon={null} description=\"当前宿主未附带前端依赖清单;已有版本信息仍可查看,升级构建入口后可补齐。\" />}\n {navigation.active === 'version' ? <>\n {differences.length > 0 && <Banner type=\"warning\" closeIcon={null} description={`前后端的${differences.join('、')}不一致,请核对部署或联调状态。`} />}\n {(backend.isLoading || frontend.isLoading) && <div aria-busy=\"true\" aria-label=\"正在加载项目信息\"><Spin /></div>}\n <section className=\"project-info-panel\" aria-label=\"前端构建信息\">\n <h3>前端构建信息</h3>\n <Descriptions bordered column={{ xs: 1, md: 2 }} data={[\n { key: '应用名称', value: empty(identity.application) },\n { key: '应用版本', value: empty(identity.appVersion) }, { key: 'ArcBase Go SDK', value: empty(identity.sdkVersion) },\n { key: '发布批次', value: empty(identity.releaseId) }, { key: '源码提交', value: empty(identity.commit) },\n { key: '构建时间', value: empty(identity.buildTime) },\n ]} />\n </section>\n <section className=\"project-info-panel\" aria-label=\"后端运行信息\">\n <h3>后端运行信息</h3>\n {backend.data ? <Descriptions bordered column={{ xs: 1, md: 2 }} data={[\n { key: '应用名称', value: empty(backend.data.application?.name) },\n { key: '应用版本', value: empty(backend.data.application?.version) },\n { key: 'ArcBase Go SDK', value: empty(backend.data.sdk.version) },\n { key: '发布批次', value: empty(backend.data.application?.releaseId) },\n { key: '源码提交', value: empty(backend.data.application?.commit) },\n { key: '构建时间', value: empty(backend.data.application?.buildTime) },\n { key: 'Go 版本', value: empty(backend.data.runtime.version) },\n { key: '运行平台', value: `${backend.data.runtime.goos} / ${backend.data.runtime.goarch}` },\n { key: 'SDK 源码提交', value: empty(backend.data.sdk.commit) },\n ]} /> : !backend.isLoading && <Empty description=\"后端运行信息暂不可用\" />}\n </section>\n </> : <>\n <div className=\"project-info-filters\">\n <Input aria-label=\"搜索项目依赖\" placeholder=\"包名、版本或用途\" value={search} onChange={setSearch} showClear />\n <Select aria-label=\"依赖类型\" value={ecosystem} onChange={setEcosystem} optionList={[{ value: 'all', label: '全部依赖' }, { value: 'npm', label: '前端 npm' }, { value: 'go', label: 'Go 模块' }]} />\n <Checkbox checked={includeTransitive} onChange={event => setIncludeTransitive(event.target.checked)}>显示间接依赖</Checkbox>\n </div>\n {backend.data?.dependencySource === 'unavailable' && <Banner type=\"info\" closeIcon={null} description=\"当前二进制未提供 Go 构建依赖信息。\" />}\n <p className=\"project-info-hint\">前端清单来自构建时已安装的项目依赖图,包含运行依赖和开发工具,不代表全部进入浏览器产物。Go 依赖未提供直接性时标记为“未分类”。版本展示不查询包仓库。</p>\n <ConfigurableTable<ProjectDependencyRow> headerTitle=\"项目依赖\" rowKey=\"key\" dataSource={filtered.slice((page - 1) * pagination.pageSize, page * pagination.pageSize)}\n loading={backend.isLoading || frontend.isLoading} onRefresh={reload} refreshLoading={backend.isFetching || frontend.isFetching}\n pagination={{ ...pagination.buildPagination(filtered.length), currentPage: page }} columnSettingsKey=\"project-info-dependencies\"\n columns={[\n { title: '依赖包', dataIndex: 'name', minWidth: 250, render: (value: string) => <code>{value}</code> },\n { title: '实际版本', dataIndex: 'version', minWidth: 180 },\n { title: '类型', dataIndex: 'ecosystem', width: 110, render: (value: string) => <Tag>{value === 'go' ? 'Go' : 'npm'}</Tag> },\n { title: '关系', dataIndex: 'kind', width: 160, render: (_value: string, row) => <Space spacing={4}><Tag>{row.kind === 'direct' ? '直接' : row.kind === 'indirect' ? '间接' : '未分类'}</Tag>{row.development && <Tag>开发</Tag>}{row.replaced && <Tag>已替换</Tag>}</Space> },\n { title: '用途', dataIndex: 'purpose', minWidth: 220 },\n ]} />\n </>}\n </div>\n </MasterDetailLayout.Body>\n </>} />\n </div>;\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{n as e}from"./rolldown-runtime-Bruge11p.js";import{E as t,F as n,I as r,It as i,M as a,O as o,Rt as s,T as c,b as l,bt as u,it as d,j as f,m as p,nt as m,st as h,xt as g}from"./clipboard-dpqHdCyy.js";import{n as _,t as v}from"./activity-CGO6Qf85.js";import{n as y,t as b}from"./circle-check-7VdHEHqi.js";import{n as x,t as S}from"./eye-off-BZuZBFEk.js";import{n as C,t as w}from"./funnel-DXNBAw6_.js";import{a as ee,c as te,l as ne,s as re}from"./OperationLogsTable-
|
|
1
|
+
import{n as e}from"./rolldown-runtime-Bruge11p.js";import{E as t,F as n,I as r,It as i,M as a,O as o,Rt as s,T as c,b as l,bt as u,it as d,j as f,m as p,nt as m,st as h,xt as g}from"./clipboard-dpqHdCyy.js";import{n as _,t as v}from"./activity-CGO6Qf85.js";import{n as y,t as b}from"./circle-check-7VdHEHqi.js";import{n as x,t as S}from"./eye-off-BZuZBFEk.js";import{n as C,t as w}from"./funnel-DXNBAw6_.js";import{a as ee,c as te,l as ne,s as re}from"./OperationLogsTable-DaaON4QR.js";import{n as ie,t as ae}from"./DateTimeText-DldSUPjX.js";import{D as oe,E as se}from"./App-nh6_qOo8.js";import{Suspense as ce,useCallback as le,useContext as T,useEffect as E,useMemo as ue,useState as D}from"react";import{Fragment as de,jsx as O,jsxs as k}from"react/jsx-runtime";import{useQueryClient as fe}from"@tanstack/react-query";import{useLocation as pe,useNavigate as me}from"react-router-dom";import{entityRelationsContract as A}from"@fudanda/admin-antd/core/lib/native-operations";import{contractKey as j}from"@fudanda/admin-antd/core/lib/contract-query";import{useFilterQuery as he}from"@fudanda/admin-antd/core/hooks/useFilterQuery";import{useListSearch as M}from"@fudanda/admin-antd/core/hooks/useListSearch";import{formatDateTime as N,formatDateTimeRangeForApi as ge}from"@fudanda/admin-antd/core/utils/date";import{useEntityAccessKey as P,useEntityRelationSection as _e,useEntityRelations as ve}from"@fudanda/admin-antd/core/hooks/queries/entity-relations";import{entityDetailRoute as ye,entityRelationKindLabel as F,entityRelationLabel as I,entityStatusLabel as L,entityTypeLabel as be}from"@fudanda/admin-antd/core/utils/entity-relations";import{EntityNavigationContext as xe,EntityRelationViewStateContext as Se,beginEntityRelationNavigation as Ce,entityRelationSourceUrl as we}from"@fudanda/admin-antd/core/components/entity-relations/entity-navigation";var R,z;function B(){return(B=e((()=>{
|
|
2
2
|
/**
|
|
3
3
|
* @license lucide-react v1.67.0 - ISC
|
|
4
4
|
*
|
|
@@ -34,4 +34,4 @@ g(),q={name:`git-branch`,size:24,node:[[`path`,{d:`M15 6a9 9 0 0 0-9 9V3`,key:`1
|
|
|
34
34
|
* See the LICENSE file in the root directory of this source tree.
|
|
35
35
|
*/
|
|
36
36
|
g(),X={name:`zap`,size:24,node:[[`path`,{d:`M15.914 4a1.5 1.5 0 00-2.474-1.561l-9 9A1.5 1.5 0 005.5 14h4.002a.5.5 0 01.471.666L8.086 20a1.5 1.5 0 002.475 1.56l9-9A1.5 1.5 0 0018.5 10h-3.997a.5.5 0 01-.472-.667z`,key:`1v7up4`}]]},X.node,Te=u(X)})))()}function Ee({entityRef:e,capabilities:t,children:n}){let r=me(),a=pe(),o=T(xe),s=JSON.stringify(P()),[c,l]=D(!1),u=n??`${be(e.type)} #${e.key}`;return t.view?t.open?/* @__PURE__ */ k(de,{children:[/* @__PURE__ */ O(p,{theme:`borderless`,size:`small`,style:{maxWidth:`100%`,paddingLeft:0,justifyContent:`flex-start`},onClick:t=>{if(t.stopPropagation(),o){o(e);return}let n=ye(e);n?(Ce({url:we(a),locationKey:a.key,state:a.state,kind:`page`,pageScrollTop:document.querySelector(`.admin-content`)?.scrollTop??0},n,s,a.pathname),r(n)):l(!0)},children:/* @__PURE__ */ O(i.Text,{ellipsis:{showTooltip:!0},style:{color:`inherit`},children:u})}),c&&/* @__PURE__ */ O(ce,{fallback:null,children:/* @__PURE__ */ O(ee,{entityRef:e,onClose:()=>l(!1)})})]}):/* @__PURE__ */ O(i.Text,{children:u}):null}function De(){return(De=e((()=>{a(),re()})))()}function Oe({section:e,search:t}){let n=e.filters;return/* @__PURE__ */ k(c,{wrap:!0,spacing:8,style:{padding:`4px 0 12px`,width:`100%`},children:[n?.keyword&&/* @__PURE__ */ O(d,{"aria-label":`关联记录关键词`,placeholder:`搜索关联记录`,...t.bindKeyword(`keyword`),width:180}),n?.dateRange&&/* @__PURE__ */ O(m,{...t.bind(`range`)}),n?.attentionOnly&&/* @__PURE__ */ O(s,{checked:t.draftParams.attentionOnly,onChange:e=>t.setField(`attentionOnly`)(!!e.target.checked),children:`仅看需处理`}),/* @__PURE__ */ O(p,{size:`small`,onClick:t.handleSearch,children:`查询`}),/* @__PURE__ */ O(p,{size:`small`,theme:`borderless`,onClick:t.handleReset,children:`重置`})]})}function ke(){return(ke=e((()=>{a(),h()})))()}function Ae({section:e,summaryState:t}){let n=I(e.labelKey,e.targetTypes),r=Le[t],i=`${n}:${r.label}`,a=r.Icon,o=Q[e.kind],s=o.Icon,l=`关联来源:${F(e.kind)}`;return/* @__PURE__ */ k(c,{spacing:6,children:[/* @__PURE__ */ O(f,{content:i,children:/* @__PURE__ */ O(`span`,{role:`img`,"aria-label":i,style:{color:r.color,display:`inline-flex`},children:/* @__PURE__ */ O(a,{size:15,"aria-hidden":`true`})})}),/* @__PURE__ */ O(f,{content:l,children:/* @__PURE__ */ O(`span`,{role:`img`,"aria-label":l,style:{color:o.color,display:`inline-flex`},children:/* @__PURE__ */ O(s,{size:14,"aria-hidden":`true`})})}),/* @__PURE__ */ O(`span`,{children:n})]})}function je({section:e,item:t}){let n=t.origin?.kind??e.kind,r=Q[n],i=r.Icon,a=[`关联来源:${F(n)}`];t.origin?.explanation&&a.push(t.origin.explanation),t.origin?.eventType&&a.push(`来源事件:${t.origin.eventType}`),t.origin?.relatedAt&&a.push(`关联建立时间:${N(t.origin.relatedAt)}`),t.occurredAt&&a.push(`记录时间:${N(t.occurredAt)}`);let o=a.join(` · `);return/* @__PURE__ */ O(f,{content:o,children:/* @__PURE__ */ O(`span`,{role:`img`,"aria-label":o,style:{color:r.color,display:`inline-flex`},children:/* @__PURE__ */ O(i,{size:14,"aria-hidden":`true`})})})}function Me({entityType:e,entityKey:t,section:n,active:a,canManageLinks:s,onSummaryStateChange:u,query:d,filtered:m,filters:h,filterToggle:g}){let _=fe(),v=()=>{d.refetch(),_.invalidateQueries({queryKey:j(A.describe,{params:{type:e,key:t}})})},y=d.data?.pages??[],b=y.flatMap(e=>e.items).filter(e=>e.capabilities.view),x=y.some(e=>e.degraded),S=d.isError,C=d.data!==void 0;E(()=>{!a||d.isFetching||m||(S||x?u(n.key,`unavailable`):C&&u(n.key,b.length>0?n.summaryState===`attention`?`attention`:`has-data`:d.hasNextPage?`unavailable`:`empty`))},[a,x,m,C,b.length,u,d.hasNextPage,d.isFetching,n.key,n.summaryState,S]);let w=I(n.labelKey,n.targetTypes);return/* @__PURE__ */ k(`div`,{style:{position:`relative`},children:[g&&/* @__PURE__ */ O(`span`,{style:{position:`absolute`,top:0,right:32,zIndex:1,lineHeight:0},children:g}),/* @__PURE__ */ O(`span`,{style:{position:`absolute`,top:0,right:0,zIndex:1,lineHeight:0},children:/* @__PURE__ */ O(f,{content:`刷新${w}`,children:/* @__PURE__ */ O(p,{size:`small`,theme:`borderless`,icon:/* @__PURE__ */ O(se,{size:14}),loading:d.isFetching,"aria-label":`刷新${w}`,onClick:e=>{e.stopPropagation(),v()}})})}),/* @__PURE__ */ k(`div`,{style:{paddingTop:4,paddingRight:g?64:32},children:[h,(d.isError||x)&&/* @__PURE__ */ k(c,{wrap:!0,spacing:8,children:[/* @__PURE__ */ O(i.Text,{type:`danger`,children:x?`部分关联记录暂时不可用`:`关联记录加载失败`}),/* @__PURE__ */ O(p,{size:`small`,onClick:()=>void(d.isFetchNextPageError?d.fetchNextPage():d.refetch()),children:`重试`})]}),C&&!S&&!x&&b.length===0&&/* @__PURE__ */ O(l,{description:d.hasNextPage?`继续加载以查找可见的匹配记录`:m?`没有符合筛选条件的关联记录`:`暂无关联记录`}),b.length>0&&/* @__PURE__ */ O(r,{size:`small`,split:!0,dataSource:b,renderItem:e=>/* @__PURE__ */ O(r.Item,{main:/* @__PURE__ */ k(`div`,{style:{minWidth:0},children:[/* @__PURE__ */ k(c,{wrap:!0,spacing:8,children:[/* @__PURE__ */ O(Ee,{entityRef:e.ref,capabilities:{view:e.capabilities.view&&n.capabilities.view,open:e.capabilities.open&&n.capabilities.open},children:e.title}),/* @__PURE__ */ O(je,{section:n,item:e}),L(e.status)&&/* @__PURE__ */ O(o,{size:`small`,children:L(e.status)})]}),e.subtitle&&/* @__PURE__ */ O(`div`,{children:/* @__PURE__ */ O(i.Text,{type:`tertiary`,children:e.subtitle})}),e.description&&/* @__PURE__ */ O(`div`,{children:/* @__PURE__ */ O(i.Text,{type:`tertiary`,children:e.description})}),e.occurredAt&&/* @__PURE__ */ O(`div`,{children:/* @__PURE__ */ O(i.Text,{type:`tertiary`,children:/* @__PURE__ */ O(ae,{value:e.occurredAt})})})]})},`${e.ref.type}:${e.ref.key}:${e.relationKey}`)}),d.hasNextPage&&/* @__PURE__ */ O(p,{size:`small`,loading:d.isFetchingNextPage,onClick:()=>void d.fetchNextPage(),children:`加载更多`})]})]})}function Ne({entityType:e,entityKey:t,section:r,active:i,summaryState:a,canManageLinks:o,onSummaryStateChange:s}){let c=M({defaults:Ie,listKey:j(A.section,{params:{type:e,key:t,sectionKey:r.key},query:{}})}),l=he({keyword:c.submittedParams.keyword,status:c.submittedParams.status,...ge(c.submittedParams.range),attentionOnly:c.submittedParams.attentionOnly?!0:void 0}),u=Object.keys(l).length>0,[d,m]=D(u),h=!!(r.filters?.keyword||r.filters?.dateRange||r.filters?.attentionOnly),g=_e(e,t,r.key,i,5,l);return/* @__PURE__ */ O(n.Panel,{itemKey:r.key,header:/* @__PURE__ */ O(Ae,{section:r,summaryState:a}),children:/* @__PURE__ */ O(Me,{entityType:e,entityKey:t,section:r,active:i,canManageLinks:o,onSummaryStateChange:s,query:g,filtered:u,filters:h&&d?/* @__PURE__ */ O(Oe,{section:r,search:c}):void 0,filterToggle:h?/* @__PURE__ */ O(f,{content:`筛选关联记录`,children:/* @__PURE__ */ O(p,{size:`small`,theme:u?`light`:`borderless`,"aria-label":`筛选关联记录`,"aria-expanded":d,icon:/* @__PURE__ */ O(w,{size:14}),onClick:()=>m(e=>!e)})}):void 0})},r.key)}function Pe({entityType:e,entityKey:t,sections:r,canManageLinks:i,hideEmpty:a}){let o=T(Se),[s,c]=D([]),l=o?.expandedGroups??s,u=o?.setExpandedGroups??c,d=ue(()=>Object.fromEntries(r.map(e=>[e.key,e.summaryState])),[r]),[f,p]=D(()=>Object.fromEntries(r.map(e=>[e.key,e.summaryState])));E(()=>{p(d)},[d]);let m=le((e,t)=>{p(n=>n[e]===t?n:{...n,[e]:t})},[]);return/* @__PURE__ */ O(n,{activeKey:l,onChange:e=>u(Array.isArray(e)?e.map(String):[String(e)]),children:r.filter(e=>e.capabilities.view&&(!a||(f[e.key]??e.summaryState)!==`empty`)).map(n=>/* @__PURE__ */ O(Ne,{entityType:e,entityKey:t,section:n,active:l.includes(n.key),summaryState:f[n.key]??`unavailable`,canManageLinks:i,onSummaryStateChange:m},n.key))})}function Fe({entityType:e,entityKey:n,enabled:r=!0,showAnchor:a=!1}){let o=ve(e,n,r),s=P(),u=M({defaults:{hideEmpty:!1},listKey:[`entity-relation-display`,e,n,s],refetchOnSearch:!1});if(!r||!n)return null;if(o.isLoading)return/* @__PURE__ */ O(t,{size:`small`});if(o.isError)return/* @__PURE__ */ k(c,{wrap:!0,children:[/* @__PURE__ */ O(i.Text,{type:`danger`,children:`对象不可用或关联信息加载失败`}),/* @__PURE__ */ O(p,{size:`small`,onClick:()=>void o.refetch(),children:`重试`})]});let d=o.data?.sections??[];return/* @__PURE__ */ k(`div`,{style:{paddingTop:12},children:[a&&o.data&&/* @__PURE__ */ O(i.Title,{heading:6,children:o.data.anchor.title}),/* @__PURE__ */ k(c,{spacing:8,style:{marginBottom:8},children:[!1,/* @__PURE__ */ O(f,{content:u.submittedParams.hideEmpty?`显示空分组`:`隐藏空分组`,children:/* @__PURE__ */ O(p,{size:`small`,theme:u.submittedParams.hideEmpty?`light`:`borderless`,"aria-label":`隐藏空分组`,"aria-pressed":u.submittedParams.hideEmpty,icon:/* @__PURE__ */ O(S,{size:14}),onClick:()=>u.applySearch({hideEmpty:!u.submittedParams.hideEmpty})})})]}),d.length===0?/* @__PURE__ */ O(l,{description:`暂无可见关联信息`}):/* @__PURE__ */ O(Pe,{entityType:e,entityKey:n,sections:d,canManageLinks:o.data?.canManageLinks??!1,hideEmpty:u.submittedParams.hideEmpty},`groups:${e}:${n}:${JSON.stringify(s)}`)]})}var Ie,Le,Q;function $(){return($=e((()=>{a(),_(),B(),y(),U(),K(),x(),C(),Y(),ne(),oe(),Z(),ie(),De(),ke(),Ie=()=>({keyword:``,status:void 0,range:null,attentionOnly:!1}),Le={"has-data":{label:`有记录`,Icon:b,color:`var(--arc-antd-color-success)`},empty:{label:`暂无记录`,Icon:G,color:`var(--arc-antd-color-tertiary)`},attention:{label:`需处理`,Icon:z,color:`var(--arc-antd-color-warning)`},unavailable:{label:`暂不可用`,Icon:H,color:`var(--arc-antd-color-danger)`}},Q={direct:{Icon:te,color:`var(--arc-antd-color-primary)`},derived:{Icon:J,color:`var(--arc-antd-color-info)`},causal:{Icon:Te,color:`var(--arc-antd-color-warning)`},activity:{Icon:v,color:`var(--arc-antd-color-tertiary)`}}})))()}export{$ as n,Fe as t};
|
|
37
|
-
//# sourceMappingURL=RelationPanel-
|
|
37
|
+
//# sourceMappingURL=RelationPanel-BsbfEDo2.js.map
|