@@ -43,6 +43,193 @@ site = AdminSite(
4343
4444管理站点重写可以实现非常自由丰富的站点配置,例如更换后台界面模板,添加/删除默认管理类或管理应用,更换静态资源链接等等.
4545
46+ 我们仍旧基于第一节[ 快速开始] ( /tutorials/quickstart ) 中创建的` adminsite.py ` 来修改。
47+
48+ 1、首先注释(或删除)掉` site = AdminSite(settings=Settings(database_url_async='sqlite+aiosqlite:///amisadmin.db')) `
49+ 2、在` templates ` 目录中创建` new_app.html ` 模板文件(如果指定了模板文件而模板文件内容为空的话,后台将显示空白),html内容如下:
50+ ``` html
51+ <!DOCTYPE html>
52+ <html lang =" " >
53+ <head >
54+ <meta charset =" UTF-8" />
55+ <title >${site_title} - 这里是自定义的后台首页</title >
56+ <meta content =" text/html; charset=utf-8" http-equiv =" Content-Type" />
57+ <meta content =" width=device-width, initial-scale=1, maximum-scale=1" name =" viewport" />
58+ <meta content =" IE=Edge" http-equiv =" X-UA-Compatible" />
59+ <!-- 可以自由替换静态资源的链接以加快访问速度。 -->
60+ <link href =" ${site_icon}" rel =" shortcut icon" type =" image/x-icon" />
61+ <link href =" ${cdn}/${pkg}/sdk/sdk.css" rel =" stylesheet" title =" default" />
62+ <link href =" ${cdn}/${pkg}/sdk/helper.css" rel =" stylesheet" />
63+ <link href =" ${cdn}/${pkg}/sdk/iconfont.css" rel =" stylesheet" />
64+ ${theme_css}
65+ <script src =" ${cdn}/${pkg}/sdk/sdk.js" ></script >
66+ <script src =" ${cdn}/vue@2.7.14/dist/vue.min.js" ></script >
67+ <script src =" ${cdn}/history@5.3.0/umd/history.production.min.js" ></script >
68+ <!-- 可以自由修改样式文件以实现不同的显示效果。 -->
69+ <style >
70+ html , body ,
71+ .app-wrapper {
72+ position : relative ;
73+ width : 100% ;
74+ height : 100% ;
75+ margin : 0 ;
76+ padding : 0 ;
77+ }
78+
79+ /* DropDownButton组件下拉菜单样式修改*/
80+ .amis-scope .cxd-DropDown-menu {
81+ min-width : 100% ;
82+ text-align : center ;
83+ }
84+ </style >
85+ </head >
86+ <body >
87+ <div class =" app-wrapper" id =" root" ></div >
88+ <script >
89+ (function () {
90+ let amis = amisRequire (' amis/embed' );
91+ const match = amisRequire (' path-to-regexp' ).match ;
92+
93+ // 如果想用 browserHistory 请切换下这处代码, 其他不用变
94+ // const history = HistoryLibrary.createBrowserHistory();
95+ const history = HistoryLibrary .createHashHistory ();
96+ const app = ${AmisSchemaJson};
97+
98+ function normalizeLink (to , location = history .location ) {
99+ to = to || ' ' ;
100+
101+ if (to && to[0 ] === ' #' ) {
102+ to = location .pathname + location .search + to;
103+ } else if (to && to[0 ] === ' ?' ) {
104+ to = location .pathname + to;
105+ }
106+
107+ const idx = to .indexOf (' ?' );
108+ const idx2 = to .indexOf (' #' );
109+ let pathname = ~ idx ? to .substring (0 , idx) : ~ idx2 ? to .substring (0 , idx2) : to;
110+ let search = ~ idx ? to .substring (idx, ~ idx2 ? idx2 : undefined ) : ' ' ;
111+ let hash = ~ idx2 ? to .substring (idx2) : location .hash ;
112+ if (! pathname) {
113+ pathname = location .pathname ;
114+ } else if (pathname[0 ] != ' /' && ! / ^ https? \:\/\/ / .test (pathname)) {
115+ let relativeBase = location .pathname ;
116+ const paths = relativeBase .split (' /' );
117+ paths .pop ();
118+ let m;
119+ while ((m = / ^ \.\. ? \/ / .exec (pathname))) {
120+ if (m[0 ] === ' ../' ) {
121+ paths .pop ();
122+ }
123+ pathname = pathname .substring (m[0 ].length );
124+ }
125+ pathname = paths .concat (pathname).join (' /' );
126+ }
127+ return pathname + search + hash;
128+ }
129+
130+ function isCurrentUrl (to , ctx ) {
131+ if (! to) {
132+ return false ;
133+ }
134+ const pathname = history .location .pathname ;
135+ const link = normalizeLink (to, {
136+ ... location,
137+ pathname,
138+ hash: ' '
139+ });
140+
141+ if (! ~ link .indexOf (' http' ) && ~ link .indexOf (' :' )) {
142+ let strict = ctx && ctx .strict ;
143+ return match (link, {
144+ decode: decodeURIComponent,
145+ strict: typeof strict !== ' undefined' ? strict : true
146+ })(pathname);
147+ }
148+
149+ return decodeURI (pathname) === link;
150+ }
151+
152+ let amisInstance = amis .embed (
153+ ' #root' ,
154+ app,
155+ {location: history .location , locale: " ${locale}" },
156+ {
157+ // watchRouteChange: fn => {
158+ // return history.listen(fn);
159+ // },
160+ updateLocation : (location , replace ) => {
161+ location = normalizeLink (location);
162+ if (location === ' goBack' ) {
163+ return history .goBack ();
164+ } else if (
165+ (! / ^ https? \:\/\/ / .test (location) &&
166+ location ===
167+ history .location .pathname + history .location .search ) ||
168+ location === history .location .href
169+ ) {
170+ // 目标地址和当前地址一样,不处理,免得重复刷新
171+ return ;
172+ } else if (/ ^ https? \:\/\/ / .test (location) || ! history) {
173+ return (window .location .href = location);
174+ }
175+
176+ history[replace ? ' replace' : ' push' ](location);
177+ },
178+ jumpTo : (to , action ) => {
179+ if (to === ' goBack' ) {
180+ return history .goBack ();
181+ }
182+
183+ to = normalizeLink (to);
184+
185+ if (isCurrentUrl (to)) {
186+ return ;
187+ }
188+
189+ if (action && action .actionType === ' url' ) {
190+ action .blank === false
191+ ? (window .location .href = to)
192+ : window .open (to, ' _blank' );
193+ return ;
194+ } else if (action && action .blank ) {
195+ window .open (to, ' _blank' );
196+ return ;
197+ }
198+
199+ if (/ ^ https? :\/\/ / .test (to)) {
200+ window .location .href = to;
201+ } else if (
202+ (! / ^ https? \:\/\/ / .test (to) &&
203+ to === history .pathname + history .location .search ) ||
204+ to === history .location .href
205+ ) {
206+ // do nothing
207+ } else if (location .hash && to .indexOf (" ?" ) > - 1 ) {
208+ // 如果当前页面有hash,且跳转的页面有参数,将hash拼接到参数后面
209+ const [hash , search ] = to .split (" ?" );
210+ window .location .href = location .pathname + " ?" + search + " #" + hash;
211+ } else {
212+ history .push (to);
213+ }
214+ },
215+ isCurrentUrl: isCurrentUrl,
216+ theme: " ${theme}"
217+ }
218+ );
219+
220+ history .listen (state => {
221+ amisInstance .updateProps ({
222+ location: state .location || state,
223+ locale: " ${locale}"
224+ });
225+ });
226+ })();
227+ </script >
228+ </body >
229+ </html >
230+
231+ ```
232+
46233### 示例-2
47234
48235``` python
@@ -59,15 +246,15 @@ class NewAdminSite(AdminSite):
59246 template_name = ' /templates/new_app.html'
60247
61248 def __init__ (self , settings : Settings, fastapi : FastAPI = None , engine : AsyncEngine = None ):
62- super ().__init__ (settings, fastapi, engine)
249+ super ().__init__ (settings, fastapi = fastapi, engine = engine)
63250 # 取消注册默认管理类
64251 self .unregister_admin(DocsAdmin, ReDocsAdmin)
65252
66253 async def get_page (self , request : Request) -> App:
67254 app = await super ().get_page(request)
68255 # 自定义站点名称,logo信息, 参考: https://baidu.gitee.io/amis/zh-CN/components/app
69256 app.brandName = ' MyAdminSite'
70- app.logo = ' https://baidu.gitee.io/amis/static/logo_408c434 .png'
257+ app.logo = " https://baidu.gitee.io/amis/static/favicon_b3b0647 .png"
71258 return app
72259
73260
@@ -80,6 +267,6 @@ site = NewAdminSite(settings=Settings(debug=True, database_url_async='sqlite+aio
80267!!! note annotate "关于自定义管理站点"
81268
82269 管理站点继承重写属于高级功能,建议对fastapi_amis_admin足够了解的情况下才进行重写.
83-
270+
84271 你可以自由修改后台管理界面,但是请尊重fastapi_amis_admin团队的开发成果,必须在展示界面中明确显示关于FastAPI-Amis-Admin的版权信息.
85272
0 commit comments