@_tc/template-core 0.2.0-bate.9 → 0.2.1
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/AGENT_README.md +2 -2
- package/README.md +67 -30
- package/cjs/app/controller/project.js +1 -1
- package/cjs/app/controller/view.js +1 -1
- package/cjs/app/extends/db.js +4 -4
- package/cjs/app/middlewares/error-handle.js +1 -1
- package/cjs/app/middlewares/project-handler.js +1 -1
- package/cjs/app/utils/i18n.js +1 -0
- package/cjs/app/view/entry.tpl +1 -0
- package/cjs/packages/common/i18n/default.js +1 -1
- package/cjs/packages/common/i18n/en-US.js +1 -1
- package/cjs/packages/common/index.js +1 -1
- package/esm/app/controller/project.js +12 -11
- package/esm/app/controller/view.js +1 -0
- package/esm/app/extends/db.js +64 -60
- package/esm/app/middlewares/error-handle.js +16 -15
- package/esm/app/middlewares/project-handler.js +8 -7
- package/esm/app/utils/i18n.js +36 -0
- package/esm/app/view/entry.tpl +1 -0
- package/esm/packages/common/i18n/default.js +13 -0
- package/esm/packages/common/i18n/en-US.js +13 -0
- package/esm/packages/common/index.js +9 -9
- package/fe/frontend/apps/dash/Dashboard.js +6 -4
- package/fe/frontend/apps/dash/dash.entry.js +2 -0
- package/fe/frontend/src/common/generateMenuData.d.ts +4 -1
- package/fe/frontend/src/common/generateMenuData.js +3 -3
- package/fe/frontend/src/common/language.d.ts +1 -2
- package/fe/frontend/src/common/language.js +10 -10
- package/fe/frontend/src/common/request.js +3 -1
- package/fe/frontend/src/components/AsyncSelect/AsyncSelect.js +10 -2
- package/fe/frontend/src/components/BasePage/HeaderView.js +2 -2
- package/fe/frontend/src/components/LanguageSwitch/LanguageSwitch.js +13 -9
- package/fe/frontend/src/components/ThemeSwitch/ThemeSwitch.js +4 -3
- package/fe/frontend/src/defaultPages/NotFoundPage/index.js +4 -3
- package/fe/frontend/src/defaultPages/SchemaPage/components/CallCom/DetailPanel.js +14 -9
- package/fe/frontend/src/defaultPages/SchemaPage/components/CallCom/PopFrom.js +8 -7
- package/fe/frontend/src/defaultPages/SchemaPage/components/SchemaSearch/index.js +6 -12
- package/fe/frontend/src/defaultPages/SchemaPage/components/SchemaTable/index.js +25 -18
- package/fe/frontend/src/defaultPages/SchemaPage/index.js +5 -3
- package/fe/frontend/src/defaultPages/SidebarSlotPageTmp.js +4 -2
- package/fe/frontend/src/hooks/useText.d.ts +3 -0
- package/fe/frontend/src/hooks/useText.js +14 -0
- package/fe/frontend/src/index.d.ts +1 -0
- package/fe/frontend/src/index.js +3 -2
- package/fe/frontend/src/language/index.d.ts +0 -2
- package/fe/frontend/src/language/index.js +1 -7
- package/fe/frontend/src/language/resources.d.ts +2 -0
- package/fe/frontend/src/language/resources.js +9 -0
- package/fe/packages/common/i18n/default.d.ts +15 -0
- package/fe/packages/common/i18n/default.js +16 -0
- package/fe/packages/common/i18n/en-US.d.ts +15 -0
- package/fe/packages/common/i18n/en-US.js +18 -2
- package/fe/packages/common/i18n/index.js +13 -0
- package/fe/packages/common/i18n/locales.js +7 -0
- package/fe/packages/react/ui/components/Date/Calendar.js +9 -5
- package/fe/packages/react/ui/components/Date/LocaleContext.d.ts +22 -1
- package/fe/packages/react/ui/components/Date/LocaleContext.js +28 -3
- package/fe/packages/react/ui/components/Date/LocaleProvider.d.ts +1 -1
- package/fe/packages/react/ui/components/Date/LocaleProvider.js +7 -16
- package/fe/packages/react/ui/components/Date/index.js +2 -2
- package/fe/packages/react/ui/components/Date/locales.d.ts +2 -0
- package/fe/packages/react/ui/components/Date/locales.js +29 -13
- package/fe/packages/react/ui/components/TableSearch/TableSearch.js +21 -1
- package/fe/packages/react/ui/components/TableSearch/lang.d.ts +2 -0
- package/fe/packages/react/ui/components/TableSearch/lang.js +18 -7
- package/fe/packages/react/ui/components/Textarea/Textarea.d.ts +1 -1
- package/fe/packages/react/ui/components/Textarea/Textarea.js +1 -1
- package/model/frontend/src/common/language.d.ts +1 -2
- package/model/frontend/src/hooks/useText.d.ts +3 -0
- package/model/frontend/src/language/index.d.ts +0 -2
- package/model/frontend/src/language/resources.d.ts +2 -0
- package/model/packages/common/i18n/default.d.ts +15 -0
- package/model/packages/common/i18n/en-US.d.ts +15 -0
- package/model/packages/react/ui/components/Date/LocaleContext.d.ts +22 -1
- package/model/packages/react/ui/components/Date/LocaleProvider.d.ts +1 -1
- package/model/packages/react/ui/components/Date/locales.d.ts +2 -0
- package/model/packages/react/ui/components/TableSearch/lang.d.ts +2 -0
- package/model/packages/react/ui/components/Textarea/Textarea.d.ts +1 -1
- package/package.json +1 -1
- package/types/app/utils/i18n.d.ts +12 -0
- package/types/packages/common/i18n/default.d.ts +19 -0
- package/types/packages/common/i18n/en-US.d.ts +21 -2
- package/types/packages/common/i18n/index.d.ts +21 -0
- package/types/packages/common/i18n/locales.d.ts +10 -0
- package/types/packages/common/i18n/types.d.ts +40 -0
package/AGENT_README.md
CHANGED
|
@@ -369,7 +369,6 @@ import '@_tc/template-core/fe/tailwind_ui.css'
|
|
|
369
369
|
|
|
370
370
|
```ts
|
|
371
371
|
import {
|
|
372
|
-
addLanguage,
|
|
373
372
|
addLanguageResources,
|
|
374
373
|
clearRafTimer,
|
|
375
374
|
api,
|
|
@@ -387,6 +386,7 @@ import {
|
|
|
387
386
|
setAuthToken,
|
|
388
387
|
setLanguage,
|
|
389
388
|
useSchemaStore,
|
|
389
|
+
useText,
|
|
390
390
|
LanguageSwitch,
|
|
391
391
|
ThemeSwitch,
|
|
392
392
|
} from '@_tc/template-core/fe'
|
|
@@ -423,7 +423,7 @@ import { Button, DataTable, Form, Input, Modal, Select } from '@_tc/template-cor
|
|
|
423
423
|
- 组件加载辅助:`renderImportComponent(import('./Page'))` 会用 `React.lazy` + `Suspense` 渲染动态组件。
|
|
424
424
|
- Schema 通信:`schemaEventBus`、`eventsInfo`、`merge`。
|
|
425
425
|
- 共享状态:`modeStore`、`schemaStore`、`apiFreezerStore` 及对应 hooks。
|
|
426
|
-
- 多语言:`addLanguageResources()`
|
|
426
|
+
- 多语言:`addLanguageResources()` 追加或新增某语种文案,`setLanguage()` 切换语言。React render 中用 `useText()`,非 React 工具代码用 `getText()`;`$i18n::` 前缀会被去掉后查询资源,无前缀字符串会按原 key 查询,未命中时原样返回。配置文案推荐写 `$i18n::...`,也可写普通字符串。
|
|
427
427
|
- 主题:`ThemeSwitch` 会同步根节点 `dark` class 和 `localStorage`。
|
|
428
428
|
- `Input type="password"` 会自动显示密码显隐按钮;`allowClear` 不作用于密码输入。
|
|
429
429
|
- RAF 风格计时器由 `@tc/common/rafTimer` 提供,浏览器优先使用 RAF,Node/SSR 自动降级到 `setTimeout`。
|
package/README.md
CHANGED
|
@@ -116,7 +116,9 @@ export default {
|
|
|
116
116
|
}
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
-
`auth.ATKey` / `auth.RTKey`
|
|
119
|
+
`auth.ATKey` / `auth.RTKey` 用于约定项目鉴权中间件读取短 token 和刷新 token 的 header 名;默认分别为 `Authorization` 和 `RT`。
|
|
120
|
+
|
|
121
|
+
服务端返回给前端的错误消息会按请求头里的语种翻译。当前优先读取 `x-tc-language`,也兼容 `tc_language`、`tc-language`、`language`、`lang`、`locale` 和 `accept-language`;如果没取到,默认按英文 `en-US` 处理。
|
|
120
122
|
|
|
121
123
|
静态资源挂载顺序为:项目 `app/public`、框架 `app/public`、`additionalPublicPaths`。Nunjucks 模板查找顺序为:项目 `app/public/dist`、框架 `app/public/dist`、`additionalPublicPaths/dist`。这些目录由 `app.publicsPath` 统一维护。当 `buildFE` 输出到自定义目录时,可以用 `additionalPublicPaths` 把该目录交给 Koa 提供静态资源访问和模板渲染;如果需要模板查找也命中追加目录,请传绝对路径数组。
|
|
122
124
|
|
|
@@ -127,7 +129,7 @@ buildFE(mode: 'dev' | 'prod', options?: BuildFEOptions)
|
|
|
127
129
|
```
|
|
128
130
|
|
|
129
131
|
**mode**:构建模式
|
|
130
|
-
- `'dev'
|
|
132
|
+
- `'dev'`:开发模式,构建一次并监听项目 `frontend/` 变化后重建
|
|
131
133
|
- `'prod'`:生产模式,构建优化后的静态资源
|
|
132
134
|
|
|
133
135
|
**options.output**:构建输出位置
|
|
@@ -192,7 +194,7 @@ http://localhost:9000/dash?projk=demo
|
|
|
192
194
|
|
|
193
195
|
### 后端类型
|
|
194
196
|
|
|
195
|
-
`@_tc/template-core` 会导出常用 Node
|
|
197
|
+
`@_tc/template-core` 会导出常用 Node 侧类型,项目编写 `app/*` 文件时建议优先复用这些类型。
|
|
196
198
|
|
|
197
199
|
| 类型 | 使用场景 |
|
|
198
200
|
| --- | --- |
|
|
@@ -313,9 +315,7 @@ VS Code 建议安装官方 Tailwind CSS IntelliSense 插件,并在工作区 `.
|
|
|
313
315
|
import {
|
|
314
316
|
api,
|
|
315
317
|
apiFreezerStore,
|
|
316
|
-
addLanguage,
|
|
317
318
|
addLanguageResources,
|
|
318
|
-
addResources,
|
|
319
319
|
AsyncSelect,
|
|
320
320
|
clearAuthToken,
|
|
321
321
|
eventsInfo,
|
|
@@ -331,6 +331,7 @@ import {
|
|
|
331
331
|
modeStore,
|
|
332
332
|
post,
|
|
333
333
|
renderImportComponent,
|
|
334
|
+
registerFrontendI18nResources,
|
|
334
335
|
request,
|
|
335
336
|
schemaEventBus,
|
|
336
337
|
schemaStore,
|
|
@@ -343,6 +344,7 @@ import {
|
|
|
343
344
|
useApiFreezer,
|
|
344
345
|
useModeStore,
|
|
345
346
|
useSchemaStore,
|
|
347
|
+
useText,
|
|
346
348
|
} from '@_tc/template-core/fe'
|
|
347
349
|
|
|
348
350
|
import type {
|
|
@@ -380,7 +382,7 @@ import type {
|
|
|
380
382
|
| 请求类型 | `BaseResponse`、`PageParams`、`PageResponse`、`RequestConfig`、`ResponseConfig`、`AxiosError` |
|
|
381
383
|
| RAF 风格计时器 | `rafSetTimeout`、`rafSetInterval`、`rafClearTimeout`、`rafClearInterval`、`clearRafTimer`、`RafTimerId`、`RafTimerCallback` |
|
|
382
384
|
| Token 工具 | `getAuthToken`、`setAuthToken`、`clearAuthToken`、`localKeyMap` |
|
|
383
|
-
| 多语言工具 | `getText`、`t`、`
|
|
385
|
+
| 多语言工具 | `useText`、`getText`、`t`、`registerFrontendI18nResources`、`addLanguageResources`、`setLanguage`、`setFallbackLanguage`、`setResources`、`getCurrentLanguage`、`getFallbackLanguage`、`getSupportedLanguages` |
|
|
384
386
|
| 请求冻结 | `apiFreezerStore`、`useApiFreezer`、`FreezeState`、`ApiFreezerRequestMatcher` |
|
|
385
387
|
| 事件工具 | `eventsInfo`、`merge` |
|
|
386
388
|
| 共享状态 | `modeStore`、`useModeStore`、`schemaStore`、`useSchemaStore`、`schemaEventBus` |
|
|
@@ -393,7 +395,21 @@ import type {
|
|
|
393
395
|
|
|
394
396
|
### 前端多语言
|
|
395
397
|
|
|
396
|
-
TemplateCore 前端通过 `@_tc/template-core/fe` 暴露 i18n
|
|
398
|
+
TemplateCore 前端通过 `@_tc/template-core/fe` 暴露 i18n 能力。框架内置中文、英文资源,但不会在普通自定义页面 import 前端入口时自动注册,避免非 Dashboard 页面把框架文案整包带入运行时资源。
|
|
399
|
+
|
|
400
|
+
默认 Dashboard 入口会自动调用 `registerFrontendI18nResources()`,所以 Dashboard、Schema CRUD、内置页头、语言切换等框架页面可以直接使用框架内置文案。自定义入口如果也要复用这些框架文案,需要在渲染前手动注册:
|
|
401
|
+
|
|
402
|
+
```ts
|
|
403
|
+
import { initApp, registerFrontendI18nResources } from '@_tc/template-core/fe'
|
|
404
|
+
|
|
405
|
+
initApp(App, {
|
|
406
|
+
beforeRender: async () => {
|
|
407
|
+
await registerFrontendI18nResources()
|
|
408
|
+
},
|
|
409
|
+
})
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
项目可以继续追加自己的资源或新增语种。
|
|
397
413
|
|
|
398
414
|
**追加自定义语言资源**:
|
|
399
415
|
|
|
@@ -401,7 +417,7 @@ TemplateCore 前端通过 `@_tc/template-core/fe` 暴露 i18n 能力。框架内
|
|
|
401
417
|
import { addLanguageResources } from '@_tc/template-core/fe'
|
|
402
418
|
|
|
403
419
|
addLanguageResources('zh-CN', {
|
|
404
|
-
|
|
420
|
+
app: {
|
|
405
421
|
product: {
|
|
406
422
|
menu: '商品管理',
|
|
407
423
|
name: '商品名称',
|
|
@@ -411,8 +427,8 @@ addLanguageResources('zh-CN', {
|
|
|
411
427
|
},
|
|
412
428
|
})
|
|
413
429
|
|
|
414
|
-
|
|
415
|
-
|
|
430
|
+
addLanguageResources('en-US', {
|
|
431
|
+
app: {
|
|
416
432
|
product: {
|
|
417
433
|
menu: 'Products',
|
|
418
434
|
name: 'Product name',
|
|
@@ -426,10 +442,10 @@ i18nStore.getState().addResources('en-US', {
|
|
|
426
442
|
**新增语种并切换**:
|
|
427
443
|
|
|
428
444
|
```ts
|
|
429
|
-
import {
|
|
445
|
+
import { addLanguageResources, setLanguage } from '@_tc/template-core/fe'
|
|
430
446
|
|
|
431
|
-
|
|
432
|
-
|
|
447
|
+
addLanguageResources('ja-JP', {
|
|
448
|
+
app: {
|
|
433
449
|
product: {
|
|
434
450
|
menu: '商品管理',
|
|
435
451
|
},
|
|
@@ -439,19 +455,40 @@ addLanguage('ja-JP', {
|
|
|
439
455
|
setLanguage('ja-JP')
|
|
440
456
|
```
|
|
441
457
|
|
|
442
|
-
`addLanguageResources()`
|
|
458
|
+
`addLanguageResources()` 用于追加或新增某个语种的文案,默认会深合并同语种资源;传 `{ merge: false }` 可以替换该语种资源。`setResources(resources, { merge: true })` 可批量合并多语种资源。`LanguageSwitch` 默认会把已注册语种加入选项;需要自定义展示文案时仍可传入 `options`。
|
|
459
|
+
|
|
460
|
+
React 组件 render 中使用 `useText()` 读取文案。它会订阅语言和资源变化,调用 `setLanguage()` 后组件会自动重渲染。
|
|
461
|
+
|
|
462
|
+
`useText()` / `getText()` 遇到 `$i18n::` 前缀会先去掉前缀再查语言资源;没有前缀时会直接把传入字符串作为 key 查询,查不到才原样返回:
|
|
463
|
+
|
|
464
|
+
```tsx
|
|
465
|
+
import { useText } from '@_tc/template-core/fe'
|
|
466
|
+
|
|
467
|
+
function ProductTitle() {
|
|
468
|
+
const text = useText()
|
|
469
|
+
|
|
470
|
+
return (
|
|
471
|
+
<>
|
|
472
|
+
<h1>{text('$i18n::app.product.menu')}</h1>
|
|
473
|
+
<span>{text('Plain title')}</span>
|
|
474
|
+
</>
|
|
475
|
+
)
|
|
476
|
+
}
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
`getText()` 是普通函数,适合请求错误、日志、校验工具或事件回调等非 React 场景;它不会主动触发 React 组件重渲染。
|
|
443
480
|
|
|
444
481
|
资源注册时不写 `$i18n::` 前缀,配置中使用时才写:
|
|
445
482
|
|
|
446
483
|
```ts
|
|
447
|
-
const title = '$i18n::
|
|
484
|
+
const title = '$i18n::app.product.createTitle'
|
|
448
485
|
```
|
|
449
486
|
|
|
450
487
|
**在 model / Schema 配置中使用**:
|
|
451
488
|
|
|
452
489
|
```ts
|
|
453
490
|
{
|
|
454
|
-
name: '$i18n::
|
|
491
|
+
name: '$i18n::app.product.menu',
|
|
455
492
|
moduleType: 'schema',
|
|
456
493
|
schemaConfig: {
|
|
457
494
|
schema: {
|
|
@@ -459,7 +496,7 @@ const title = '$i18n::business.product.createTitle'
|
|
|
459
496
|
properties: {
|
|
460
497
|
name: {
|
|
461
498
|
type: 'string',
|
|
462
|
-
label: '$i18n::
|
|
499
|
+
label: '$i18n::app.product.name',
|
|
463
500
|
minLength: 2,
|
|
464
501
|
createFormOption: {
|
|
465
502
|
comType: 'input',
|
|
@@ -473,7 +510,7 @@ const title = '$i18n::business.product.createTitle'
|
|
|
473
510
|
tableConfig: {
|
|
474
511
|
headerButtons: [
|
|
475
512
|
{
|
|
476
|
-
label: '$i18n::
|
|
513
|
+
label: '$i18n::app.product.create',
|
|
477
514
|
eventKey: 'callComponent',
|
|
478
515
|
eventOption: { comName: 'createForm' },
|
|
479
516
|
},
|
|
@@ -481,7 +518,7 @@ const title = '$i18n::business.product.createTitle'
|
|
|
481
518
|
},
|
|
482
519
|
componentConfig: {
|
|
483
520
|
createForm: {
|
|
484
|
-
title: '$i18n::
|
|
521
|
+
title: '$i18n::app.product.createTitle',
|
|
485
522
|
saveBtnText: '$i18n::common.submit',
|
|
486
523
|
},
|
|
487
524
|
},
|
|
@@ -939,7 +976,7 @@ const unsafeUsers = app.extends.db.queryDB(
|
|
|
939
976
|
)
|
|
940
977
|
```
|
|
941
978
|
|
|
942
|
-
|
|
979
|
+
项目可以用自己的 `app/extends/db.ts` 覆盖默认实现。建议保留同一组方法名,这样 controller/service 调用方不用调整。
|
|
943
980
|
|
|
944
981
|
```ts
|
|
945
982
|
// app/extends/db.ts
|
|
@@ -1055,7 +1092,7 @@ export default (app: KoaApp, router: Router) => {
|
|
|
1055
1092
|
- 每个 `app/router/*.ts` 文件都会获得独立的 `koa-router` 实例。
|
|
1056
1093
|
- 可以通过 `router.level = number` 控制挂载顺序,数值越小越早挂载。
|
|
1057
1094
|
- 默认 `level` 是 `0`,框架兜底 router 是 `99`。
|
|
1058
|
-
- 通配、兜底、重定向类路由建议设置较大的 `level
|
|
1095
|
+
- 通配、兜底、重定向类路由建议设置较大的 `level`,避免抢先匹配项目 API。
|
|
1059
1096
|
|
|
1060
1097
|
```ts
|
|
1061
1098
|
import type { KoaApp, Router } from '@_tc/template-core'
|
|
@@ -1344,7 +1381,7 @@ DELETE {api} -> 删除
|
|
|
1344
1381
|
|
|
1345
1382
|
### 服务端兜底路由守卫
|
|
1346
1383
|
|
|
1347
|
-
|
|
1384
|
+
项目可以创建 `app/router-guard.ts` 或 `app/router-guard.js`。它只在所有正常 `app/router/*` 路由都没有命中时执行。
|
|
1348
1385
|
|
|
1349
1386
|
```ts
|
|
1350
1387
|
import type { Ctx, KoaApp } from '@_tc/template-core'
|
|
@@ -1369,7 +1406,7 @@ export default (_app: KoaApp) => {
|
|
|
1369
1406
|
|
|
1370
1407
|
### 扩展 Dashboard 顶部用户区域
|
|
1371
1408
|
|
|
1372
|
-
|
|
1409
|
+
项目可以创建 `frontend/extended/dash/components.tsx`,通过组件映射填充内置 Dashboard 页头右侧区域。
|
|
1373
1410
|
|
|
1374
1411
|
```tsx
|
|
1375
1412
|
// frontend/extended/dash/components.tsx
|
|
@@ -1390,7 +1427,7 @@ export default components
|
|
|
1390
1427
|
|
|
1391
1428
|
### 扩展 Dashboard 登录守卫
|
|
1392
1429
|
|
|
1393
|
-
|
|
1430
|
+
项目可以创建 `frontend/extended/dash/routeGuard.ts`,用于在 Dashboard 内置 `homePage` / 首菜单重定向前做登录判断。
|
|
1394
1431
|
|
|
1395
1432
|
```ts
|
|
1396
1433
|
// frontend/extended/dash/routeGuard.ts
|
|
@@ -1406,9 +1443,9 @@ export default dashRouteGuard
|
|
|
1406
1443
|
返回值规则:
|
|
1407
1444
|
|
|
1408
1445
|
- 返回 `string`:框架使用 `window.location.href` 跳转,登录页不需要在 Dash 路由下。
|
|
1409
|
-
- 返回非 `string`:中断 Dashboard
|
|
1446
|
+
- 返回非 `string`:中断 Dashboard 内置重定向,使用方可自行跳转或处理提示。
|
|
1410
1447
|
- `DashRouteGuardResult` 是 `string | undefined`;`undefined`(包括已登录分支的隐式返回)也会打断 Dashboard 内置重定向。
|
|
1411
|
-
-
|
|
1448
|
+
- 没有自定义 `routeGuard` 文件时,框架使用兜底空对象,不影响默认 Dashboard 重定向。
|
|
1412
1449
|
|
|
1413
1450
|
### 扩展 SchemaForm 字段组件
|
|
1414
1451
|
|
|
@@ -1580,7 +1617,7 @@ remark: {
|
|
|
1580
1617
|
|
|
1581
1618
|
### 扩展 SchemaTable 单元格渲染组件
|
|
1582
1619
|
|
|
1583
|
-
SchemaPage 表格列支持通过 `tableOption.renderComponent`
|
|
1620
|
+
SchemaPage 表格列支持通过 `tableOption.renderComponent` 使用内置或自定义注册的渲染组件。内置组件:
|
|
1584
1621
|
|
|
1585
1622
|
- `PreviewImage`:把当前单元格值渲染成图片预览;值是数组时直接作为图片列表,值是单个字符串时自动转成单图数组。
|
|
1586
1623
|
|
|
@@ -1635,7 +1672,7 @@ const componentsMap = {
|
|
|
1635
1672
|
export default componentsMap
|
|
1636
1673
|
```
|
|
1637
1674
|
|
|
1638
|
-
组件会收到 `value`、`record`、`rowIndex`、`fieldKey`,以及 `renderComponentProps`
|
|
1675
|
+
组件会收到 `value`、`record`、`rowIndex`、`fieldKey`,以及 `renderComponentProps` 中的自定义参数:
|
|
1639
1676
|
|
|
1640
1677
|
```tsx
|
|
1641
1678
|
// frontend/components/PriceCell.tsx
|
|
@@ -1775,7 +1812,7 @@ declare module '@_tc/template-core/model' {
|
|
|
1775
1812
|
|
|
1776
1813
|
- `RenderComponentPropsMap` 的 key 对应 `tableOption.renderComponent`。
|
|
1777
1814
|
- 运行时组件注册在 `frontend/extended/SchemaPage/SchemaTable/data.ts`。
|
|
1778
|
-
- 组件运行时会自动收到 `value`、`record`、`rowIndex`、`fieldKey`;`renderComponentProps`
|
|
1815
|
+
- 组件运行时会自动收到 `value`、`record`、`rowIndex`、`fieldKey`;`renderComponentProps` 只配置自定义参数。
|
|
1779
1816
|
|
|
1780
1817
|
### KoaApp 类型扩展
|
|
1781
1818
|
|
|
@@ -2130,6 +2167,6 @@ await buildBE({
|
|
|
2130
2167
|
- `model` 数组合并依赖稳定 `key`。
|
|
2131
2168
|
- Dashboard 默认需要 URL 带 `?projk=项目key`。
|
|
2132
2169
|
- Dashboard 登录守卫放在 `frontend/extended/dash/routeGuard.ts`;登录页通常不在 Dash 路由下,返回登录页 URL 即可。
|
|
2133
|
-
-
|
|
2170
|
+
- 服务端兜底守卫放在项目根目录的 `app/router-guard.ts|js`。
|
|
2134
2171
|
- 前端入口必须命名为 `.entry.tsx`、`.entry.ts`、`.entry.jsx` 或 `.entry.js`。
|
|
2135
2172
|
- 入口同目录的 `.html` 只能作为插槽文件使用,不能写完整 HTML 文档;页面外壳始终由 `app/view/entry.tpl` 生成。
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=require(`./base.js`);var
|
|
1
|
+
const e=require(`./base.js`),t=require(`../utils/i18n.js`);var n=(n=>{let r=e(n);return class extends r{getModelList=async e=>{let t=(await this.service.project.getModelList()).reduce((e,t)=>{let{model:n,project:r}=t,{key:i,name:a,desc:o}=n,s={key:i,name:a,desc:o},c=Object.keys(r).reduce((e,t)=>{let{key:n,name:i,desc:a,homePage:o}=r[t];return e[t]={key:n,name:i,desc:a,homePage:o},e},{});return e.push({model:s,project:c}),e},[]);this.success(e,t)};getProjectList=async e=>{let t=e.reqData?.data.projk,n=(await this.service.project.getList(t))?.map(e=>{let{modelKey:t,key:n,name:r,desc:i,homePage:a}=e;return{modelKey:t,key:n,name:r,desc:i,homePage:a}});this.success(e,n)};getProject=async e=>{let{key:n}=e.params;if(!n){this.fail(e,10001,t.requestT(e,`server.errors.getProjectFailed`));return}let r=this.service.project.getProject(n);if(!r){this.fail(e,10001,t.requestT(e,`server.errors.getProjectFailed`));return}this.success(e,r)}}});module.exports=n;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=require(`../../packages/common/string/index.js`);var t=e=>JSON.stringify(e).replace(/</g,`\\u003c`).replace(/>/g,`\\u003e`).replace(/&/g,`\\u0026`).replace(/\u2028/g,`\\u2028`).replace(/\u2029/g,`\\u2029`),n=(n=>class{async renderPage(r,i){let a=r.path;if(n.extends.localCacheHtmlEtag.keepFreshFEBuildKey(),a.includes(`${n.options.apiPrefix}/`))await i();else{n.extends.logger.log(` - render page: `+r.params.page);try{let i=r.query.projk;Array.isArray(i)&&(i=e.joinStr(...i));let a={projKey:i??``,name:n.options?.name??``,env:n.envs.get(),basePath:t(`${n.options.pageBasePage}${r.params.page}`),projKeyJson:t(String(r.query.projk??``)),signKey:t(n.config.signKey),options:t(n.options)},o=n.extends.renderView(`${r.params.page}.entry.tpl`,r,a),s=e.joinStr(a.basePath,a.name,a.env,a.projKey);if(!n.extends.localCacheHtmlEtag.hasEtag(s)){let e=n.extends.crypto.hmacSign(o);n.extends.localCacheHtmlEtag.setEtag(s,e)}let c=n.extends.localCacheHtmlEtag.getEtag(s);if(c||console.log(`---- etag 缓存异常 请检查服务 ----`),r.etag=c??Date.now()+``,r.fresh){r.status=304;return}}catch(e){console.log(`-------------- render view error --------------`),console.log(e),n.extends.generateErrorMessage(`template not found`,{status:404,showError:!0,code:0})}}}});module.exports=n;
|
|
1
|
+
const e=require(`../../packages/common/string/index.js`);var t=e=>JSON.stringify(e).replace(/</g,`\\u003c`).replace(/>/g,`\\u003e`).replace(/&/g,`\\u0026`).replace(/\u2028/g,`\\u2028`).replace(/\u2029/g,`\\u2029`),n=(n=>class{async renderPage(r,i){let a=r.path;if(n.extends.localCacheHtmlEtag.keepFreshFEBuildKey(),a.includes(`${n.options.apiPrefix}/`))await i();else{n.extends.logger.log(` - render page: `+r.params.page);try{let i=r.query.projk;Array.isArray(i)&&(i=e.joinStr(...i));let a={projKey:i??``,name:n.options?.name??``,env:n.envs.get(),FEBasePage:t(`${n.options.pageBasePage}`),basePath:t(`${n.options.pageBasePage}${r.params.page}`),projKeyJson:t(String(r.query.projk??``)),signKey:t(n.config.signKey),options:t(n.options)},o=n.extends.renderView(`${r.params.page}.entry.tpl`,r,a),s=e.joinStr(a.basePath,a.name,a.env,a.projKey);if(!n.extends.localCacheHtmlEtag.hasEtag(s)){let e=n.extends.crypto.hmacSign(o);n.extends.localCacheHtmlEtag.setEtag(s,e)}let c=n.extends.localCacheHtmlEtag.getEtag(s);if(c||console.log(`---- etag 缓存异常 请检查服务 ----`),r.etag=c??Date.now()+``,r.fresh){r.status=304;return}}catch(e){console.log(`-------------- render view error --------------`),console.log(e),n.extends.generateErrorMessage(`template not found`,{status:404,showError:!0,code:0})}}}});module.exports=n;
|
package/cjs/app/extends/db.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
require(`../../_virtual/_rolldown/runtime.js`);
|
|
1
|
+
require(`../../_virtual/_rolldown/runtime.js`);const e=require(`../utils/i18n.js`);let t=require(`node:fs`),n=require(`node:path`);var r=`framework`,i=`.template-core/template-core.sqlite`;function a(e){let r=c(e),i,a=!1,l=0,u=()=>(y(a),i||((0,t.mkdirSync)((0,n.dirname)(r),{recursive:!0}),i=o(r),s(i)),i),_={dbPath:r,getDBConnection:u,execDB:e=>{u().exec(e)},runDB:(e,t)=>{let n=u().prepare(e).run(...d(t));return{changes:Number(n.changes??0),lastInsertRowid:n.lastInsertRowid??0}},queryDB:(e,t)=>u().prepare(e).all(...d(t)),getDBFirst:(e,t)=>u().prepare(e).get(...d(t)),transactionDB:e=>{let t=u(),n=`tc_savepoint_${l}`,r=l===0;t.exec(r?`BEGIN IMMEDIATE`:`SAVEPOINT ${n}`),l+=1;try{let i=e(_);return--l,t.exec(r?`COMMIT`:`RELEASE SAVEPOINT ${n}`),i}catch(e){throw--l,t.exec(r?`ROLLBACK`:`ROLLBACK TO SAVEPOINT ${n}`),r||t.exec(`RELEASE SAVEPOINT ${n}`),e}},getDBData:(e,t)=>_.getDBDataRecord(e,t)?.value,getDBDataRecord:(e,t)=>{let n=_.getDBFirst(`SELECT namespace, data_key, data_value, created_at, updated_at FROM tc_framework_data WHERE namespace = ? AND data_key = ? LIMIT 1`,[f(t?.namespace),p(e)]);return n?v(n):void 0},setDBData:(e,t,n)=>{let r=new Date().toISOString();return _.runDB(`INSERT INTO tc_framework_data (namespace, data_key, data_value, created_at, updated_at)
|
|
2
2
|
VALUES (?, ?, ?, ?, ?)
|
|
3
3
|
ON CONFLICT(namespace, data_key) DO UPDATE SET
|
|
4
4
|
data_value = excluded.data_value,
|
|
5
|
-
updated_at = excluded.updated_at`,[
|
|
5
|
+
updated_at = excluded.updated_at`,[f(n?.namespace),p(e),g(t),r,r])},hasDBData:(e,t)=>!!_.getDBFirst(`SELECT 1 AS exists_value FROM tc_framework_data WHERE namespace = ? AND data_key = ? LIMIT 1`,[f(t?.namespace),p(e)]),deleteDBData:(e,t)=>_.runDB(`DELETE FROM tc_framework_data WHERE namespace = ? AND data_key = ?`,[f(t?.namespace),p(e)]).changes>0,listDBData:e=>{let t=m(e?.limit),n=h(e?.offset);return _.queryDB(`SELECT namespace, data_key, data_value, created_at, updated_at
|
|
6
6
|
FROM tc_framework_data
|
|
7
7
|
WHERE namespace = ?
|
|
8
8
|
ORDER BY updated_at DESC, data_key ASC
|
|
9
|
-
LIMIT ? OFFSET ?`,[
|
|
9
|
+
LIMIT ? OFFSET ?`,[f(e?.namespace),t,n]).map(e=>v(e))},countDBData:e=>{let t=_.getDBFirst(`SELECT COUNT(1) AS count_value FROM tc_framework_data WHERE namespace = ?`,[f(e?.namespace)]);return Number(t?.count_value??0)},clearDBData:e=>_.runDB(`DELETE FROM tc_framework_data WHERE namespace = ?`,[f(e?.namespace)]).changes,closeDB:()=>{a||=(i?.close(),!0)}};return _}function o(t){let n=`node:sqlite`,r;try{r=require(n)}catch(t){throw e.createI18nError(`server.errors.dbNodeSqliteUnavailable`,{sqliteSpecifier:n,cause:b(t)})}if(!r.DatabaseSync)throw e.createI18nError(`server.errors.dbDatabaseSyncUnavailable`,{sqliteSpecifier:n});return new r.DatabaseSync(t)}function s(e){e.exec(`
|
|
10
10
|
CREATE TABLE IF NOT EXISTS tc_framework_data (
|
|
11
11
|
namespace TEXT NOT NULL,
|
|
12
12
|
data_key TEXT NOT NULL,
|
|
@@ -17,4 +17,4 @@ require(`../../_virtual/_rolldown/runtime.js`);let e=require(`node:fs`),t=requir
|
|
|
17
17
|
);
|
|
18
18
|
CREATE INDEX IF NOT EXISTS idx_tc_framework_data_namespace_updated_at
|
|
19
19
|
ON tc_framework_data (namespace, updated_at);
|
|
20
|
-
`)}function
|
|
20
|
+
`)}function c(e){let t=l(e),r=typeof t==`string`?t:t?.path??t?.filename??t?.sqlitePath??u(t?.sqlite);return r?(0,n.isAbsolute)(r)?r:(0,n.resolve)(e.baseDir,r):(0,n.resolve)(e.baseDir,i)}function l(e){let t=e.config;return t.db??(t.sqlite?{sqlite:t.sqlite}:void 0)}function u(e){if(e)return typeof e==`string`?e:e.path??e.filename}function d(e){return e?Array.isArray(e)?e:[e]:[]}function f(t=r){let n=t.trim();if(!n)throw e.createI18nError(`server.errors.dbNamespaceRequired`);return n}function p(t){let n=t.trim();if(!n)throw e.createI18nError(`server.errors.dbKeyRequired`);return n}function m(t=100){if(!Number.isSafeInteger(t)||t<=0)throw e.createI18nError(`server.errors.dbLimitInvalid`);return t}function h(t=0){if(!Number.isSafeInteger(t)||t<0)throw e.createI18nError(`server.errors.dbOffsetInvalid`);return t}function g(t){try{let e=JSON.stringify(t);if(e===void 0)throw Error(`value is not JSON serializable`);return e}catch(t){throw e.createI18nError(`server.errors.dbValueNotSerializable`,{cause:b(t)})}}function _(e){return JSON.parse(e)}function v(e){return{key:e.data_key,value:_(e.data_value),namespace:e.namespace,createdAt:e.created_at,updatedAt:e.updated_at}}function y(t){if(t)throw e.createI18nError(`server.errors.dbClosed`)}function b(e){return e instanceof Error&&e.message?` Cause: ${e.message}`:``}module.exports=a;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
const e=require(`../utils/i18n.js`);var t={},n=n=>async(r,i)=>{try{await i()}catch(i){let a=i,{status:o=200,message:s,detail:c,code:l=5e4,returnError:u}=a,d=e.getRequestErrorMessage(r,a,s);if(n.extends.logger?.info(`error info -> ${JSON.stringify(i)}`),n.extends.logger?.error(`-- [excption] --`,i),n.extends.logger?.error(`-- [excption] info --`,o,s,c),s?.includes(`template not found`)){let e=r.path??r.req.url??r.url;if(t[e]===void 0?t[e]=0:t[e]+=1,t[e]<n.config.notFoundRedirectCount){r.status=302,r.redirect(n.options?.homePage??`/`);return}else t[e]=0}u?(r.status=o,r.body={code:l,message:d}):(r.status=200,r.body={code:5e4,message:e.requestT(r,`server.errors.network`)})}};module.exports=n;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
const e=require(`../utils/i18n.js`);var t=t=>async(n,r)=>{let i=n.headers.projk,{path:a}=n;if(a.indexOf(`${t.options.apiPrefix}/proj/`)!==-1&&(!i||[`undefined`,`null`].includes(i))){n.status=200,n.body={code:110,data:null,message:e.requestT(n,`server.errors.invalidRequest`)};return}n.extInfo={key:i},await r()};module.exports=t;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../../packages/common/i18n/index.js`);var t=`x-tc-language`,n=`en-US`,r=[t,`tc_language`,`tc-language`,`language`,`lang`,`locale`],i=e=>Array.isArray(e)?e[0]:e,a=(e,t)=>i(e[t.toLowerCase()]),o=e=>e?e.split(`,`).map(e=>e.trim().split(`;`)[0]?.trim()).filter(e=>!!e):[],s=t=>{if(!t)return n;let r=Object.keys(e.i18nStore.getState().resources),i=t.trim().toLowerCase(),a=r.find(e=>e.toLowerCase()===i);if(a)return a;let o=i.split(`-`)[0];return r.find(e=>e.toLowerCase().split(`-`)[0]===o)??n},c=e=>{for(let t of r){let n=a(e.headers,t);if(n)return s(n)}let t=o(a(e.headers,`accept-language`));for(let e of t){let t=s(e);if(t)return t}return n},l=(t,r,i,a)=>e.i18n(r,i,{...a,language:a?.language??c(t),fallbackLanguage:a?.fallbackLanguage??n}),u=(e,t,n)=>{let r=Error(n??e);return r.i18nKey=e,r.i18nData=t,r},d=(e,t,n)=>t.i18nKey?l(e,t.i18nKey,t.i18nData,{fallback:n??t.message}):n??t.message;exports.LANGUAGE_HEADER_KEY=t,exports.createI18nError=u,exports.getRequestErrorMessage=d,exports.getRequestLanguage=c,exports.normalizeI18nLanguage=s,exports.requestT=l;
|
package/cjs/app/view/entry.tpl
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e={common:{tip:`提示`,confirm:`确认`,cancel:`取消`,close:`关闭`,submit:`提交`,reset:`重置`},components:{breadcrumb:{close:`关闭`},confirmDialog:{title:`提示`,okText:`确认`,cancelText:`取消`},dataTable:{noData:`暂无数据`},date:{placeholder:`请选择日期`,placeholderDateTime:`请选择日期时间`,placeholderRange:`选择日期范围`,placeholderDateTimeRange:`选择日期时间范围`,weekDays:[`日`,`一`,`二`,`三`,`四`,`五`,`六`],selectTime:`选择时间`,startTime:`开始时间`,endTime:`结束时间`,confirm:`确认`,monthFormat:`yyyy年 M月`,quickRanges:`快速选择`,quickRangeToday:`今天`,quickRangeYesterday:`昨天`,quickRangeLast7Days:`近7天`,quickRangeLast30Days:`近30天`,quickRangeThisMonth:`本月`,quickRangeLastYear:`最近一年`,clear:`清除`},form:{submit:`提交`,cancel:`取消`},imagePreview:{closePreview:`关闭预览`,previousImage:`上一张`,nextImage:`下一张`,zoomOut:`缩小`,zoomIn:`放大`,reset:`重置`,rotateLeft:`左旋转`,rotateRight:`右旋转`,flipHorizontal:`左右镜像`,flipVertical:`上下镜像`,previewImage:`预览第{index}张`},modal:{close:`关闭`,confirmTitle:`提示`,okText:`确认`,cancelText:`取消`},message:{close:`关闭`},select:{empty:`暂无选项`},tableSearch:{reset:`重置`,search:`查询`,export:`导出Excel`,expand:`展开`,collapse:`收起`,exportCurrentPage:`当前页`,exportCurrentQuery:`当前查询条件`},upload:{deleteImage:`删除图片`,upload:`上传`}}};exports.defaultLanguageResources=e;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e={common:{tip:`提示`,confirm:`确认`,cancel:`取消`,close:`关闭`,submit:`提交`,reset:`重置`},server:{errors:{network:`网络错误`,invalidRequest:`请求不合法`,getProjectFailed:`获取项目异常`,dbNodeSqliteUnavailable:`[db] 默认数据库依赖 Node.js 内置 {sqliteSpecifier},当前运行环境不可用。请升级 Node.js,或在业务项目覆盖 app/extends/db.ts。{cause}`,dbDatabaseSyncUnavailable:`[db] {sqliteSpecifier} 未提供 DatabaseSync,无法初始化默认 SQLite 数据库。`,dbNamespaceRequired:`[db] namespace 不能为空`,dbKeyRequired:`[db] key 不能为空`,dbLimitInvalid:`[db] limit 必须是大于 0 的整数`,dbOffsetInvalid:`[db] offset 必须是大于等于 0 的整数`,dbValueNotSerializable:`[db] value 必须可以被 JSON.stringify 序列化。{cause}`,dbClosed:`[db] SQLite 数据库连接已关闭`}},components:{breadcrumb:{close:`关闭`},confirmDialog:{title:`提示`,okText:`确认`,cancelText:`取消`},dataTable:{noData:`暂无数据`},date:{placeholder:`请选择日期`,placeholderDateTime:`请选择日期时间`,placeholderRange:`选择日期范围`,placeholderDateTimeRange:`选择日期时间范围`,weekDays:[`日`,`一`,`二`,`三`,`四`,`五`,`六`],selectTime:`选择时间`,startTime:`开始时间`,endTime:`结束时间`,confirm:`确认`,monthFormat:`yyyy年 M月`,quickRanges:`快速选择`,quickRangeToday:`今天`,quickRangeYesterday:`昨天`,quickRangeLast7Days:`近7天`,quickRangeLast30Days:`近30天`,quickRangeThisMonth:`本月`,quickRangeLastYear:`最近一年`,clear:`清除`},form:{submit:`提交`,cancel:`取消`},imagePreview:{closePreview:`关闭预览`,previousImage:`上一张`,nextImage:`下一张`,zoomOut:`缩小`,zoomIn:`放大`,reset:`重置`,rotateLeft:`左旋转`,rotateRight:`右旋转`,flipHorizontal:`左右镜像`,flipVertical:`上下镜像`,previewImage:`预览第{index}张`},modal:{close:`关闭`,confirmTitle:`提示`,okText:`确认`,cancelText:`取消`},message:{close:`关闭`},select:{empty:`暂无选项`},tableSearch:{reset:`重置`,search:`查询`,export:`导出Excel`,expand:`展开`,collapse:`收起`,exportCurrentPage:`当前页`,exportCurrentQuery:`当前查询条件`},upload:{deleteImage:`删除图片`,upload:`上传`}}};exports.defaultLanguageResources=e;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e={common:{tip:`Prompt`,confirm:`Confirm`,cancel:`Cancel`,close:`Close`,submit:`Submit`,reset:`Reset`},components:{breadcrumb:{close:`Close`},confirmDialog:{title:`Prompt`,okText:`Confirm`,cancelText:`Cancel`},dataTable:{noData:`No Data`},date:{placeholder:`Select date`,placeholderDateTime:`Select date and time`,placeholderRange:`Select date range`,placeholderDateTimeRange:`Select date and time range`,weekDays:[`Sun`,`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`],selectTime:`Select time`,startTime:`Start time`,endTime:`End time`,confirm:`Confirm`,monthFormat:`MMM yyyy`,quickRanges:`Quick ranges`,quickRangeToday:`Today`,quickRangeYesterday:`Yesterday`,quickRangeLast7Days:`Last 7 days`,quickRangeLast30Days:`Last 30 days`,quickRangeThisMonth:`This month`,quickRangeLastYear:`Last year`,clear:`Clear`},form:{submit:`Submit`,cancel:`Cancel`},imagePreview:{closePreview:`Close preview`,previousImage:`Previous image`,nextImage:`Next image`,zoomOut:`Zoom out`,zoomIn:`Zoom in`,reset:`Reset`,rotateLeft:`Rotate left`,rotateRight:`Rotate right`,flipHorizontal:`Flip horizontal`,flipVertical:`Flip vertical`,previewImage:`Preview image {index}`},modal:{close:`Close`,confirmTitle:`Prompt`,okText:`Confirm`,cancelText:`Cancel`},message:{close:`Close`},select:{empty:`No options`},tableSearch:{reset:`Reset`,search:`Search`,export:`Export Excel`,expand:`Expand`,collapse:`Collapse`,exportCurrentPage:`Current Page`,exportCurrentQuery:`Current Filters`},upload:{deleteImage:`Delete image`,upload:`Upload`}}};exports.defaultEnglishResources=e;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e={common:{tip:`Prompt`,confirm:`Confirm`,cancel:`Cancel`,close:`Close`,submit:`Submit`,reset:`Reset`},server:{errors:{network:`Network error`,invalidRequest:`Invalid request`,getProjectFailed:`Failed to get project`,dbNodeSqliteUnavailable:`[db] The default database depends on Node.js built-in {sqliteSpecifier}, which is unavailable in the current runtime. Upgrade Node.js or override app/extends/db.ts in the business project.{cause}`,dbDatabaseSyncUnavailable:`[db] {sqliteSpecifier} does not provide DatabaseSync, so the default SQLite database cannot be initialized.`,dbNamespaceRequired:`[db] namespace cannot be empty`,dbKeyRequired:`[db] key cannot be empty`,dbLimitInvalid:`[db] limit must be an integer greater than 0`,dbOffsetInvalid:`[db] offset must be an integer greater than or equal to 0`,dbValueNotSerializable:`[db] value must be serializable by JSON.stringify.{cause}`,dbClosed:`[db] SQLite database connection is closed`}},components:{breadcrumb:{close:`Close`},confirmDialog:{title:`Prompt`,okText:`Confirm`,cancelText:`Cancel`},dataTable:{noData:`No Data`},date:{placeholder:`Select date`,placeholderDateTime:`Select date and time`,placeholderRange:`Select date range`,placeholderDateTimeRange:`Select date and time range`,weekDays:[`Sun`,`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`],selectTime:`Select time`,startTime:`Start time`,endTime:`End time`,confirm:`Confirm`,monthFormat:`MMM yyyy`,quickRanges:`Quick ranges`,quickRangeToday:`Today`,quickRangeYesterday:`Yesterday`,quickRangeLast7Days:`Last 7 days`,quickRangeLast30Days:`Last 30 days`,quickRangeThisMonth:`This month`,quickRangeLastYear:`Last year`,clear:`Clear`},form:{submit:`Submit`,cancel:`Cancel`},imagePreview:{closePreview:`Close preview`,previousImage:`Previous image`,nextImage:`Next image`,zoomOut:`Zoom out`,zoomIn:`Zoom in`,reset:`Reset`,rotateLeft:`Rotate left`,rotateRight:`Rotate right`,flipHorizontal:`Flip horizontal`,flipVertical:`Flip vertical`,previewImage:`Preview image {index}`},modal:{close:`Close`,confirmTitle:`Prompt`,okText:`Confirm`,cancelText:`Cancel`},message:{close:`Close`},select:{empty:`No options`},tableSearch:{reset:`Reset`,search:`Search`,export:`Export Excel`,expand:`Expand`,collapse:`Collapse`,exportCurrentPage:`Current Page`,exportCurrentQuery:`Current Filters`},upload:{deleteImage:`Delete image`,upload:`Upload`}}};exports.defaultEnglishResources=e;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./i18n/default.js`),t=require(`./i18n/en-US.js`),n=require(`./i18n/locales.js`),r=require(`./i18n/index.js`),i=require(`./guards/index.js`),a=require(`./array/index.js`),o=require(`./cache/LRUCache.js`),s=require(`./http/index.js`),c=require(`./log/index.js`),l=require(`./number/index.js`),u=require(`./object/filterEmpty.js`),d=require(`./object/index.js`),f=require(`./rafTimer.js`),p=require(`./string/index.js`);exports.ANSI_RESET=c.ANSI_RESET,exports.FetchAxios=s.FetchAxios,exports.LRUCache=o.LRUCache,exports.ansiColors=c.ansiColors,exports.axios=s.axios,exports.capitalize=p.capitalize,exports.chunk=a.chunk,exports.clamp=l.clamp,exports.clearRafTimer=f.clearRafTimer,exports.colorLog=c.colorLog,exports.colorize=c.colorize,exports.compact=a.compact,exports.createInstance=s.createInstance,exports.defaultEnglishResources=t.defaultEnglishResources,exports.defaultLanguage=n.defaultLanguage,exports.defaultLanguageResources=e.defaultLanguageResources,exports.filterEmpty=u.filterEmpty,exports.filtereEmpty=u.filtereEmpty,exports.getI18nPathValue=r.getI18nPathValue,exports.getLanguage=r.getLanguage,exports.groupBy=a.groupBy,exports.i18n=r.i18n,exports.i18nStore=r.i18nStore,exports.interpolateI18nMessage=r.interpolateI18nMessage,exports.isBlank=p.isBlank,exports.isBoolean=i.isBoolean,exports.isFunction=i.isFunction,exports.isNil=i.isNil,exports.isNonNullable=i.isNonNullable,exports.isNumber=i.isNumber,exports.isPlainI18nDictionary=r.isPlainI18nDictionary,exports.isPlainObject=i.isPlainObject,exports.isString=i.isString,exports.joinColorized=c.joinColorized,exports.joinStr=p.joinStr,exports.kebabCase=p.kebabCase,exports.languageLocalKey=n.languageLocalKey,exports.logColor=c.logColor,exports.logColorized=c.logColorized,exports.logGreen=c.logGreen,exports.logJoinColorized=c.logJoinColorized,exports.logPink=c.logPink,exports.logRed=c.logRed,exports.logWhite=c.logWhite,exports.logYellow=c.logYellow,exports.mapValues=d.mapValues,exports.mergeI18nDictionary=r.mergeI18nDictionary,exports.mergeI18nResources=r.mergeI18nResources,exports.omit=d.omit,exports.pick=d.pick,exports.rafClearInterval=f.rafClearInterval,exports.rafClearTimeout=f.rafClearTimeout,exports.rafSetInterval=f.rafSetInterval,exports.rafSetTimeout=f.rafSetTimeout,exports.t=r.t,exports.toArray=a.toArray,exports.toFiniteNumber=l.toFiniteNumber,exports.translate=r.translate,exports.translations=n.translations,exports.uniqueBy=a.uniqueBy;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import e from "./base.js";
|
|
2
|
+
import { requestT as t } from "../utils/i18n.js";
|
|
2
3
|
//#region app/controller/project.ts
|
|
3
|
-
var
|
|
4
|
-
let
|
|
5
|
-
return class extends
|
|
4
|
+
var n = ((n) => {
|
|
5
|
+
let r = e(n);
|
|
6
|
+
return class extends r {
|
|
6
7
|
getModelList = async (e) => {
|
|
7
8
|
let t = (await this.service.project.getModelList()).reduce((e, t) => {
|
|
8
9
|
let { model: n, project: r } = t, { key: i, name: a, desc: o } = n, s = {
|
|
@@ -39,19 +40,19 @@ var t = ((t) => {
|
|
|
39
40
|
this.success(e, n);
|
|
40
41
|
};
|
|
41
42
|
getProject = async (e) => {
|
|
42
|
-
let { key:
|
|
43
|
-
if (!
|
|
44
|
-
this.fail(e, 10001, "
|
|
43
|
+
let { key: n } = e.params;
|
|
44
|
+
if (!n) {
|
|
45
|
+
this.fail(e, 10001, t(e, "server.errors.getProjectFailed"));
|
|
45
46
|
return;
|
|
46
47
|
}
|
|
47
|
-
let
|
|
48
|
-
if (!
|
|
49
|
-
this.fail(e, 10001, "
|
|
48
|
+
let r = this.service.project.getProject(n);
|
|
49
|
+
if (!r) {
|
|
50
|
+
this.fail(e, 10001, t(e, "server.errors.getProjectFailed"));
|
|
50
51
|
return;
|
|
51
52
|
}
|
|
52
|
-
this.success(e,
|
|
53
|
+
this.success(e, r);
|
|
53
54
|
};
|
|
54
55
|
};
|
|
55
56
|
});
|
|
56
57
|
//#endregion
|
|
57
|
-
export {
|
|
58
|
+
export { n as default };
|
|
@@ -13,6 +13,7 @@ var t = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u003e
|
|
|
13
13
|
projKey: i ?? "",
|
|
14
14
|
name: n.options?.name ?? "",
|
|
15
15
|
env: n.envs.get(),
|
|
16
|
+
FEBasePage: t(`${n.options.pageBasePage}`),
|
|
16
17
|
basePath: t(`${n.options.pageBasePage}${r.params.page}`),
|
|
17
18
|
projKeyJson: t(String(r.query.projk ?? "")),
|
|
18
19
|
signKey: t(n.config.signKey),
|