lan-low-code-cli 0.0.0-stage → 2.1.0
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/README.md +814 -3
- package/bin/llc.js +13 -0
- package/dist/api/formDefine.js +161 -0
- package/dist/client.js +140 -0
- package/dist/commands/app.js +252 -0
- package/dist/commands/config.js +75 -0
- package/dist/commands/control.js +158 -0
- package/dist/commands/field.js +125 -0
- package/dist/commands/form.js +1294 -0
- package/dist/commands/locale.js +60 -0
- package/dist/config.js +106 -0
- package/dist/constants.js +275 -0
- package/dist/generator/index.js +1317 -0
- package/dist/index.js +136 -0
- package/dist/types.js +50 -0
- package/dist/utils/icon.js +26 -0
- package/dist/utils/locale.js +53 -0
- package/dist/utils/logger.js +78 -0
- package/dist/utils/random.js +79 -0
- package/dist/widgets.js +304 -0
- package/package.json +40 -3
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerLocaleCommand = registerLocaleCommand;
|
|
4
|
+
const config_1 = require("../config");
|
|
5
|
+
const constants_1 = require("../constants");
|
|
6
|
+
const logger_1 = require("../utils/logger");
|
|
7
|
+
const locale_1 = require("../utils/locale");
|
|
8
|
+
const widgets_1 = require("../widgets");
|
|
9
|
+
function createRegistry(opts) {
|
|
10
|
+
const runtime = (0, config_1.resolveRuntime)({ baseUrl: opts.baseUrl, token: opts.token });
|
|
11
|
+
return new widgets_1.WidgetRegistry({ baseUrl: runtime.baseUrl, token: runtime.token });
|
|
12
|
+
}
|
|
13
|
+
/** 默认探测用的控件(任意控件均可,只取其多语言资源的语言码) */
|
|
14
|
+
const DEFAULT_ELEMENT = '@elem/xform-input';
|
|
15
|
+
function registerLocaleCommand(program) {
|
|
16
|
+
const locale = program.command('locale').description('查询环境提供的语言(多语言文案可用范围)');
|
|
17
|
+
locale
|
|
18
|
+
.command('list')
|
|
19
|
+
.description('列出环境为控件提供的语言码(数据源:sys-lang/getFrontResource)')
|
|
20
|
+
.option('--element <pkg>', `探测用的控件包名,默认 ${DEFAULT_ELEMENT}`)
|
|
21
|
+
.option('--json', '以 JSON 输出')
|
|
22
|
+
.action(async (opts) => {
|
|
23
|
+
const pkg = opts.element || DEFAULT_ELEMENT;
|
|
24
|
+
const key = (0, widgets_1.elementLangKey)(pkg, 'placeholder');
|
|
25
|
+
const registry = createRegistry(opts);
|
|
26
|
+
logger_1.logger.step(`探测控件多语言:${key}`);
|
|
27
|
+
const langs = await registry.getElementLangs(key);
|
|
28
|
+
if (!langs) {
|
|
29
|
+
logger_1.logger.warn('未获取到控件多语言资源,请检查 --base-url / --token 是否正确');
|
|
30
|
+
logger_1.logger.info(' 接口:POST {baseUrl}/sys-lang/getFrontResource');
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const entries = Object.entries(langs).map(([raw, text]) => ({
|
|
34
|
+
/** 接口返回的原始语言码,如 zh-cn */
|
|
35
|
+
raw,
|
|
36
|
+
/** 前端 getLocale 归一后的语言码,如 Cn */
|
|
37
|
+
locale: (0, locale_1.toLocaleCode)(raw),
|
|
38
|
+
text,
|
|
39
|
+
}));
|
|
40
|
+
const codes = entries.map((item) => item.locale).filter(Boolean);
|
|
41
|
+
if (opts.json) {
|
|
42
|
+
logger_1.logger.json({ element: pkg, key, locales: entries, suggested: codes });
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
logger_1.logger.title(`环境为「${pkg}」提供的语言(共 ${entries.length} 个)`);
|
|
46
|
+
entries.forEach((item) => {
|
|
47
|
+
logger_1.logger.info(` ${item.raw.padEnd(10)} -> ${(item.locale || '(无法归一)').padEnd(6)} ${item.text}`);
|
|
48
|
+
});
|
|
49
|
+
if (codes.length) {
|
|
50
|
+
logger_1.logger.title('可直接用于 --locale 的取值');
|
|
51
|
+
logger_1.logger.info(` ${codes.join(',')}`);
|
|
52
|
+
logger_1.logger.info(` 默认主语言:${constants_1.DEFAULT_LOCALE}`);
|
|
53
|
+
if (!codes.includes(constants_1.DEFAULT_LOCALE)) {
|
|
54
|
+
logger_1.logger.warn(`环境未提供 ${constants_1.DEFAULT_LOCALE} 译文;仍建议把 ${constants_1.DEFAULT_LOCALE} 放在 --locale 首位作为主语言兜底`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
logger_1.logger.info('\n说明:以上来自控件多语言资源接口,表示「哪些语言有现成译文(如 placeholder)」。');
|
|
58
|
+
logger_1.logger.info(' 环境配置的全部语言(前端 allLocales)未暴露接口,如需其它语言请直接 --locale 指定。');
|
|
59
|
+
});
|
|
60
|
+
}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PROJECT_CONFIG_FILE = exports.GLOBAL_CONFIG_FILE = exports.GLOBAL_CONFIG_DIR = void 0;
|
|
4
|
+
exports.loadConfig = loadConfig;
|
|
5
|
+
exports.saveGlobalConfig = saveGlobalConfig;
|
|
6
|
+
exports.clearGlobalConfig = clearGlobalConfig;
|
|
7
|
+
exports.resolveRuntime = resolveRuntime;
|
|
8
|
+
exports.resolveControlMap = resolveControlMap;
|
|
9
|
+
exports.ensureDir = ensureDir;
|
|
10
|
+
const fs_1 = require("fs");
|
|
11
|
+
const os_1 = require("os");
|
|
12
|
+
const path_1 = require("path");
|
|
13
|
+
const constants_1 = require("./constants");
|
|
14
|
+
const random_1 = require("./utils/random");
|
|
15
|
+
/** 全局配置文件:~/.lcode/config.json */
|
|
16
|
+
exports.GLOBAL_CONFIG_DIR = (0, path_1.join)((0, os_1.homedir)(), '.lcode');
|
|
17
|
+
exports.GLOBAL_CONFIG_FILE = (0, path_1.join)(exports.GLOBAL_CONFIG_DIR, 'config.json');
|
|
18
|
+
/** 项目级配置文件(相对 cwd) */
|
|
19
|
+
exports.PROJECT_CONFIG_FILE = (0, path_1.resolve)(process.cwd(), 'lcode.config.json');
|
|
20
|
+
/** 解析优先级:命令行参数 > 环境变量 > 项目级配置 > 全局配置 */
|
|
21
|
+
function loadConfig() {
|
|
22
|
+
const globalConf = readJsonFile(exports.GLOBAL_CONFIG_FILE) ?? {};
|
|
23
|
+
const projectConf = readJsonFile(exports.PROJECT_CONFIG_FILE) ?? {};
|
|
24
|
+
return {
|
|
25
|
+
...globalConf,
|
|
26
|
+
...projectConf,
|
|
27
|
+
controlMap: { ...(globalConf.controlMap ?? {}), ...(projectConf.controlMap ?? {}) },
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** 写入全局配置(合并) */
|
|
31
|
+
function saveGlobalConfig(patch) {
|
|
32
|
+
const current = readJsonFile(exports.GLOBAL_CONFIG_FILE) ?? {};
|
|
33
|
+
const next = {
|
|
34
|
+
...current,
|
|
35
|
+
...patch,
|
|
36
|
+
controlMap: { ...(current.controlMap ?? {}), ...(patch.controlMap ?? {}) },
|
|
37
|
+
};
|
|
38
|
+
if (!(0, fs_1.existsSync)(exports.GLOBAL_CONFIG_DIR)) {
|
|
39
|
+
(0, fs_1.mkdirSync)(exports.GLOBAL_CONFIG_DIR, { recursive: true });
|
|
40
|
+
}
|
|
41
|
+
(0, fs_1.writeFileSync)(exports.GLOBAL_CONFIG_FILE, JSON.stringify(next, null, 2), 'utf-8');
|
|
42
|
+
return next;
|
|
43
|
+
}
|
|
44
|
+
/** 清除指定键 */
|
|
45
|
+
function clearGlobalConfig(keys) {
|
|
46
|
+
const current = readJsonFile(exports.GLOBAL_CONFIG_FILE) ?? {};
|
|
47
|
+
keys.forEach((key) => delete current[key]);
|
|
48
|
+
if (!(0, fs_1.existsSync)(exports.GLOBAL_CONFIG_DIR)) {
|
|
49
|
+
(0, fs_1.mkdirSync)(exports.GLOBAL_CONFIG_DIR, { recursive: true });
|
|
50
|
+
}
|
|
51
|
+
(0, fs_1.writeFileSync)(exports.GLOBAL_CONFIG_FILE, JSON.stringify(current, null, 2), 'utf-8');
|
|
52
|
+
return current;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 解析运行时配置(baseUrl + token)。
|
|
56
|
+
* baseUrl 与 token 二者均可由用户提供:
|
|
57
|
+
* --base-url / --token 参数,或环境变量 LLC_BASE_URL / LLC_TOKEN,或配置文件。
|
|
58
|
+
*/
|
|
59
|
+
function resolveRuntime(options = {}) {
|
|
60
|
+
const conf = loadConfig();
|
|
61
|
+
const baseUrl = options.baseUrl || process.env.LLC_BASE_URL || conf.baseUrl;
|
|
62
|
+
const token = options.token || process.env.LLC_TOKEN || conf.token;
|
|
63
|
+
const timeout = options.timeout ?? conf.timeout ?? 30000;
|
|
64
|
+
const missing = [];
|
|
65
|
+
if (!baseUrl)
|
|
66
|
+
missing.push('baseUrl(--base-url 或 LLC_BASE_URL 或 llc config set)');
|
|
67
|
+
if (!token)
|
|
68
|
+
missing.push('token(--token 或 LLC_TOKEN 或 llc config set)');
|
|
69
|
+
if (missing.length > 0) {
|
|
70
|
+
throw new Error(`缺少必要配置:\n - ${missing.join('\n - ')}`);
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
baseUrl: normalizeBaseUrl(baseUrl),
|
|
74
|
+
token: token,
|
|
75
|
+
timeout,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/** 获取合并后的控件映射(内置默认 + 用户覆盖) */
|
|
79
|
+
function resolveControlMap() {
|
|
80
|
+
const conf = loadConfig();
|
|
81
|
+
const overrides = conf.controlMap ?? {};
|
|
82
|
+
const result = { ...constants_1.DEFAULT_CONTROL_MAP };
|
|
83
|
+
Object.keys(overrides).forEach((key) => {
|
|
84
|
+
result[key] = { ...(result[key] ?? constants_1.DEFAULT_CONTROL_MAP.varchar), ...overrides[key] };
|
|
85
|
+
});
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
function normalizeBaseUrl(baseUrl) {
|
|
89
|
+
return baseUrl.trim().replace(/\/+$/, '');
|
|
90
|
+
}
|
|
91
|
+
function readJsonFile(file) {
|
|
92
|
+
if (!(0, fs_1.existsSync)(file))
|
|
93
|
+
return null;
|
|
94
|
+
try {
|
|
95
|
+
return (0, random_1.safeJsonParse)((0, fs_1.readFileSync)(file, 'utf-8'), null);
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/** 确保目录存在(供导出等场景使用) */
|
|
102
|
+
function ensureDir(filePath) {
|
|
103
|
+
const dir = (0, path_1.dirname)(filePath);
|
|
104
|
+
if (!(0, fs_1.existsSync)(dir))
|
|
105
|
+
(0, fs_1.mkdirSync)(dir, { recursive: true });
|
|
106
|
+
}
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 常量定义:与 sys-xform 前端 util/constant.ts 中的约定保持一致。
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DEFAULT_DETAIL_CONTROL_STYLE = exports.DEFAULT_CONTROL_STYLE = exports.DEFAULT_MOBILE_THEME = exports.DEFAULT_DESKTOP_THEME = exports.DEFAULT_FORM_ICON_JSON = exports.DEFAULT_FORM_ICON = exports.FIELD_NAME_PREFIX = exports.LOCALE_PATTERN = exports.LOCALE_ALL = exports.LOCALES = exports.DEFAULT_LOCALE = exports.DEFAULT_SPAN = exports.OPTION_DICT_TYPE = exports.OPTION_CONTROL_TYPES = exports.DETAIL_CONTROL_DEFAULTS = exports.DETAIL_ROW_FLAGS = exports.DETAIL_OPERATIONS = exports.DETAIL_SYSTEM_FIELDS = exports.DETAIL_CONTROL = exports.CONTROL_TYPE_MAP = exports.FALLBACK_CONTROL = exports.DEFAULT_CONTROL_MAP = exports.ELEMENT_ARTIFACT_PREFIX = exports.DEFAULT_SCENE_NAME = exports.DEFAULT_SCENE_CODE = exports.MODELING_ENTITY_CODE = exports.MODELING_ENTITY_NAME = exports.ENTITY_CODE = exports.ENTITY_NAME = exports.MODULE = exports.REQUIRED_PROP_DEFAULTS = exports.I18N_PROP_TABS = exports.TAB_PANE_MOBILE = exports.TAB_PANE = exports.TABS_MOBILE = exports.TABS = exports.TAB_APPEARANCE_MOBILE = exports.TAB_APPEARANCE = exports.LAYOUT_GRID_ITEM = exports.LAYOUT_GRID = exports.LAYOUT = exports.ROW = exports.APPEARANCE = exports.MAIN = void 0;
|
|
7
|
+
/** 设计器主容器 key */
|
|
8
|
+
exports.MAIN = 'main';
|
|
9
|
+
/** 外观容器 */
|
|
10
|
+
exports.APPEARANCE = '@elem/xform-appearance';
|
|
11
|
+
/** 虚拟行容器 */
|
|
12
|
+
exports.ROW = '@elem/xform-row';
|
|
13
|
+
/**
|
|
14
|
+
* 布局模式容器(栅格布局)。
|
|
15
|
+
* 前端 `util/constant.ts#LAYOUT`:作为 `main` 的直接子节点,内部包一个 `layout-grid`。
|
|
16
|
+
*/
|
|
17
|
+
exports.LAYOUT = 'layout';
|
|
18
|
+
/** 栅格布局容器 */
|
|
19
|
+
exports.LAYOUT_GRID = '@elem/layout-grid';
|
|
20
|
+
/** 栅格单元格 */
|
|
21
|
+
exports.LAYOUT_GRID_ITEM = '@elem/layout-grid.GridItem';
|
|
22
|
+
/** 多页签外观(仅作为 key 前缀与 parent.name,渲染树中无独立节点) */
|
|
23
|
+
exports.TAB_APPEARANCE = '@elem/xform-tab-appearance';
|
|
24
|
+
exports.TAB_APPEARANCE_MOBILE = '@elem/xform-m-tab-appearance';
|
|
25
|
+
/** 多页签容器 */
|
|
26
|
+
exports.TABS = '@elem/xform-tabs';
|
|
27
|
+
exports.TABS_MOBILE = '@elem/xform-m-tabs';
|
|
28
|
+
/** 多页签面板 */
|
|
29
|
+
exports.TAB_PANE = '@elem/xform-tabpane';
|
|
30
|
+
exports.TAB_PANE_MOBILE = '@elem/xform-m-tabpane';
|
|
31
|
+
/** 页签标题的多语言 prop 取值(前端 EI18nProp.tabs) */
|
|
32
|
+
exports.I18N_PROP_TABS = 'tabs';
|
|
33
|
+
/** 控件必填属性的兜底默认值(键为 desktop 控件包名),取值依据见 README「控件必填属性校验」 */
|
|
34
|
+
exports.REQUIRED_PROP_DEFAULTS = {
|
|
35
|
+
'@elem/xform-textarea': { height: '3' },
|
|
36
|
+
'@elem/xform-rate': { max: 5 },
|
|
37
|
+
'@elem/xform-slider': { min: 0, max: 100 },
|
|
38
|
+
'@elem/xform-rich-text': { height: 300 },
|
|
39
|
+
'@elem/xform-bar-code': { height: 80 },
|
|
40
|
+
'@elem/xform-hyperlinks': { largestSet: 'infinit' },
|
|
41
|
+
'@elem/xform-address': {
|
|
42
|
+
org: { orgTypeArr: ['8'], defaultValueType: 'null' },
|
|
43
|
+
multi: false,
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
/** 后端模块前缀(拼在 baseUrl 之后) */
|
|
47
|
+
exports.MODULE = 'sys-xform';
|
|
48
|
+
/** 默认实体名(审批意见表单机制) */
|
|
49
|
+
exports.ENTITY_NAME = 'com.landray.sys.xform.core.entity.define.SysGeneralFormDefine';
|
|
50
|
+
/** 默认实体编码(审批意见表单机制) */
|
|
51
|
+
exports.ENTITY_CODE = 'sys-xform';
|
|
52
|
+
/** 业务建模(低代码应用)机制实体名 */
|
|
53
|
+
exports.MODELING_ENTITY_NAME = 'com.landray.sys.modeling.core.entity.main.SysModelingMainEntity';
|
|
54
|
+
/** 业务建模机制编码 */
|
|
55
|
+
exports.MODELING_ENTITY_CODE = 'sys-modeling';
|
|
56
|
+
/** 默认场景编码 */
|
|
57
|
+
exports.DEFAULT_SCENE_CODE = 'SCENE_DEFAULT';
|
|
58
|
+
/** 默认场景名称 */
|
|
59
|
+
exports.DEFAULT_SCENE_NAME = '默认';
|
|
60
|
+
/** 控件元数据静态产物路径(相对站点根) */
|
|
61
|
+
exports.ELEMENT_ARTIFACT_PREFIX = 'web/sys/artifact/elements';
|
|
62
|
+
exports.DEFAULT_CONTROL_MAP = {
|
|
63
|
+
varchar: { desktop: '@elem/xform-input', mobile: '@elem/xform-m-input', logicalType: 'text' },
|
|
64
|
+
number: { desktop: '@elem/xform-number', mobile: '@elem/xform-m-number', logicalType: 'numbertext' },
|
|
65
|
+
boolean: { desktop: '@elem/xform-switch', mobile: '@elem/xform-m-switch', logicalType: 'switch' },
|
|
66
|
+
timestamp: {
|
|
67
|
+
desktop: '@elem/xform-datetime',
|
|
68
|
+
mobile: '@elem/xform-m-datetime',
|
|
69
|
+
logicalType: 'timestamp',
|
|
70
|
+
},
|
|
71
|
+
address: { desktop: '@elem/xform-address', mobile: '@elem/xform-m-address', logicalType: 'address' },
|
|
72
|
+
attach: {
|
|
73
|
+
desktop: '@elem/xform-attachment',
|
|
74
|
+
mobile: '@elem/xform-m-attachment',
|
|
75
|
+
logicalType: 'attachment',
|
|
76
|
+
},
|
|
77
|
+
clob: { desktop: '@elem/xform-textarea', mobile: '@elem/xform-m-textarea', logicalType: 'textarea' },
|
|
78
|
+
relation: { desktop: '@elem/xform-relation', mobile: '@elem/xform-m-relation', logicalType: 'relation' },
|
|
79
|
+
};
|
|
80
|
+
/** 兜底控件(未知类型) */
|
|
81
|
+
exports.FALLBACK_CONTROL = exports.DEFAULT_CONTROL_MAP.varchar;
|
|
82
|
+
/**
|
|
83
|
+
* 控件映射:**控件逻辑类型(xform.type)→ 桌面/移动端控件包 + 数据项类型**。
|
|
84
|
+
*
|
|
85
|
+
* 与 `DEFAULT_CONTROL_MAP`(按数据项类型索引)互补:同一数据项类型可对应多个控件
|
|
86
|
+
* (如 `number` 对应 数字/金额/评分/滑块),因此按业务需要选择控件时用本表。
|
|
87
|
+
*
|
|
88
|
+
* 全部条目已对真实环境 `@elem/xform-*` 与 `@elem/xform-m-*` 的 `config.json`
|
|
89
|
+
* 做过 `xform.type` 一致性校验(无移动端包的控件回落为桌面端包,与平台 `platform=all` 行为一致)。
|
|
90
|
+
*/
|
|
91
|
+
exports.CONTROL_TYPE_MAP = {
|
|
92
|
+
text: { desktop: '@elem/xform-input', mobile: '@elem/xform-m-input', logicalType: 'text', dataType: 'varchar' },
|
|
93
|
+
textarea: { desktop: '@elem/xform-textarea', mobile: '@elem/xform-m-textarea', logicalType: 'textarea', dataType: 'clob' },
|
|
94
|
+
'rich-text': { desktop: '@elem/xform-rich-text', mobile: '@elem/xform-m-rtf', logicalType: 'rich-text', dataType: 'clob' },
|
|
95
|
+
numbertext: { desktop: '@elem/xform-number', mobile: '@elem/xform-m-number', logicalType: 'numbertext', dataType: 'number' },
|
|
96
|
+
moneytext: { desktop: '@elem/xform-money', mobile: '@elem/xform-m-money', logicalType: 'moneytext', dataType: 'number' },
|
|
97
|
+
rate: { desktop: '@elem/xform-rate', mobile: '@elem/xform-rate', logicalType: 'rate', dataType: 'number' },
|
|
98
|
+
slider: { desktop: '@elem/xform-slider', mobile: '@elem/xform-slider', logicalType: 'slider', dataType: 'number' },
|
|
99
|
+
switch: { desktop: '@elem/xform-switch', mobile: '@elem/xform-m-switch', logicalType: 'switch', dataType: 'boolean' },
|
|
100
|
+
timestamp: { desktop: '@elem/xform-datetime', mobile: '@elem/xform-m-datetime', logicalType: 'timestamp', dataType: 'timestamp' },
|
|
101
|
+
timepicker: { desktop: '@elem/xform-timepicker', mobile: '@elem/xform-m-timepicker', logicalType: 'timepicker', dataType: 'number' },
|
|
102
|
+
daterange: { desktop: '@elem/xform-daterange', mobile: '@elem/xform-m-daterange', logicalType: 'daterange', dataType: 'number' },
|
|
103
|
+
address: { desktop: '@elem/xform-address', mobile: '@elem/xform-m-address', logicalType: 'address', dataType: 'address' },
|
|
104
|
+
select: { desktop: '@elem/xform-select', mobile: '@elem/xform-m-select', logicalType: 'select', dataType: 'varchar' },
|
|
105
|
+
radio: { desktop: '@elem/xform-radio', mobile: '@elem/xform-m-radio', logicalType: 'radio', dataType: 'varchar' },
|
|
106
|
+
checkbox: { desktop: '@elem/xform-checkbox', mobile: '@elem/xform-m-checkbox', logicalType: 'checkbox', dataType: 'varchar' },
|
|
107
|
+
attachment: { desktop: '@elem/xform-attach', mobile: '@elem/xform-m-attach', logicalType: 'attachment', dataType: 'varchar' },
|
|
108
|
+
image: { desktop: '@elem/xform-image', mobile: '@elem/xform-m-image', logicalType: 'image', dataType: 'varchar' },
|
|
109
|
+
video: { desktop: '@elem/xform-video', mobile: '@elem/xform-m-video', logicalType: 'video', dataType: 'varchar' },
|
|
110
|
+
dividing: { desktop: '@elem/xform-divider', mobile: '@elem/xform-divider', logicalType: 'dividing', dataType: 'varchar' },
|
|
111
|
+
hidden: { desktop: '@elem/xform-hidden', mobile: '@elem/xform-hidden', logicalType: 'hidden', dataType: 'varchar' },
|
|
112
|
+
phoneNumber: { desktop: '@elem/xform-phone-number', mobile: '@elem/xform-m-phone-number', logicalType: 'phoneNumber', dataType: 'varchar' },
|
|
113
|
+
barcode: { desktop: '@elem/xform-bar-code', mobile: '@elem/xform-bar-code', logicalType: 'barcode', dataType: 'varchar' },
|
|
114
|
+
qrcode: { desktop: '@elem/xform-qr-code', mobile: '@elem/xform-qr-code', logicalType: 'qrcode', dataType: 'varchar' },
|
|
115
|
+
upcasing: { desktop: '@elem/xform-upcasing', mobile: '@elem/xform-upcasing', logicalType: 'upcasing', dataType: 'varchar' },
|
|
116
|
+
subject: { desktop: '@elem/xform-subject', mobile: '@elem/xform-m-subject', logicalType: 'subject', dataType: 'varchar' },
|
|
117
|
+
hyperlinks: { desktop: '@elem/xform-hyperlinks', mobile: '@elem/xform-m-hyperlinks', logicalType: 'hyperlinks', dataType: 'clob' },
|
|
118
|
+
timeZone: { desktop: '@elem/xform-time-zone', mobile: '@elem/xform-m-time-zone', logicalType: 'timeZone', dataType: 'varchar' },
|
|
119
|
+
relation: { desktop: '@elem/xform-relation', mobile: '@elem/xform-m-relation', logicalType: 'relation', dataType: 'relation' },
|
|
120
|
+
relationQuery: { desktop: '@elem/xform-relation-query', mobile: '@elem/xform-relation-query', logicalType: 'relationQuery', dataType: 'relation' },
|
|
121
|
+
};
|
|
122
|
+
/** 明细表控件(数据项类型为 varchar,控件逻辑类型 detail) */
|
|
123
|
+
exports.DETAIL_CONTROL = {
|
|
124
|
+
desktop: '@elem/xform-detail-table',
|
|
125
|
+
mobile: '@elem/xform-m-detail-table',
|
|
126
|
+
logicalType: 'detail',
|
|
127
|
+
dataType: 'varchar',
|
|
128
|
+
};
|
|
129
|
+
/** 明细表系统字段(由 getSystemDefaultModel 返回,此处仅作兜底) */
|
|
130
|
+
exports.DETAIL_SYSTEM_FIELDS = ['fd_id', 'fd_main_id', 'fd_order'];
|
|
131
|
+
/**
|
|
132
|
+
* 明细表行操作(auth 中的 operations)。
|
|
133
|
+
* 与真实表单一致,messageKey 为平台静态多语言键。
|
|
134
|
+
*/
|
|
135
|
+
exports.DETAIL_OPERATIONS = {
|
|
136
|
+
add: [
|
|
137
|
+
{ id: 'canAddRow', label: '添加行', messageKey: 'sys-xform:detail.operation.addRow', showType: 'always', type: 'operation' },
|
|
138
|
+
{ id: 'canDeleteRow', label: '删除行', messageKey: 'sys-xform:detail.operation.deleteRow', showType: 'always', type: 'operation' },
|
|
139
|
+
{ id: 'canImport', label: '导入', messageKey: 'sys-xform:detail.operation.import', showType: 'always', type: 'operation' },
|
|
140
|
+
],
|
|
141
|
+
view: [
|
|
142
|
+
{ id: 'canExport', label: '导出', messageKey: 'sys-xform:detail.operation.export', showType: 'always', type: 'view' },
|
|
143
|
+
],
|
|
144
|
+
};
|
|
145
|
+
/** 明细表行操作开关(auth 顶层) */
|
|
146
|
+
exports.DETAIL_ROW_FLAGS = { add: { canAddRow: true, canDeleteRow: true, canImport: true } };
|
|
147
|
+
/**
|
|
148
|
+
* 明细表控件的默认属性。
|
|
149
|
+
*
|
|
150
|
+
* 这些默认值**不在** `@elem/xform-detail-table` 的 `config.json` 里(其中多数无 `default`),
|
|
151
|
+
* 而是由前端 `controlConfigGeneratorByDataField` 写死,取自真实表单的落库数据。
|
|
152
|
+
*/
|
|
153
|
+
exports.DETAIL_CONTROL_DEFAULTS = {
|
|
154
|
+
mode: 'table',
|
|
155
|
+
defaultRowNumber: 1,
|
|
156
|
+
showNumber: true,
|
|
157
|
+
showFieldName: true,
|
|
158
|
+
showRowSelection: true,
|
|
159
|
+
showTopActionBar: true,
|
|
160
|
+
detailAlign: [
|
|
161
|
+
{ key: 'alignItems', value: 'left' },
|
|
162
|
+
{ key: 'alignHeader', value: 'left' },
|
|
163
|
+
],
|
|
164
|
+
mobileRender: ['simple'],
|
|
165
|
+
alignTitle: 'left',
|
|
166
|
+
nest: false,
|
|
167
|
+
canChangeSpan: false,
|
|
168
|
+
pcSetting: ['pagination'],
|
|
169
|
+
pcNestSetting: ['toggle'],
|
|
170
|
+
printLayoutType: 'table',
|
|
171
|
+
defaultPageSize: 10,
|
|
172
|
+
};
|
|
173
|
+
/** 可使用 `--option` 配置选项的控件类型 */
|
|
174
|
+
exports.OPTION_CONTROL_TYPES = new Set(['select', 'radio', 'checkbox']);
|
|
175
|
+
/** 数据项类型 -> 控件映射中「有选项」的类型(optionDict) */
|
|
176
|
+
exports.OPTION_DICT_TYPE = 'optionDict';
|
|
177
|
+
/** 默认网格栅格 */
|
|
178
|
+
exports.DEFAULT_SPAN = 12;
|
|
179
|
+
/**
|
|
180
|
+
* 默认语言(主语言)。
|
|
181
|
+
*
|
|
182
|
+
* 前端 `getLocale('zh-cn')` 取语言码第二段并首字母大写,得到 `Cn` / `Us` / `Tw` / `Hk`。
|
|
183
|
+
* `sys-xform/src/components/runtime/utils.ts` 的解析顺序为
|
|
184
|
+
* `content[当前语言] → content['Cn']`,所以「只写 Cn」在任何语言下都能兜底显示。
|
|
185
|
+
*/
|
|
186
|
+
exports.DEFAULT_LOCALE = 'Cn';
|
|
187
|
+
/** 常见语言(`--locale all` 展开用) */
|
|
188
|
+
exports.LOCALES = ['Cn', 'Us', 'Tw'];
|
|
189
|
+
/** `--locale` 中表示「全部常见语言」的取值 */
|
|
190
|
+
exports.LOCALE_ALL = 'all';
|
|
191
|
+
/** 语言码合法性(与前端 getLocale 的产物一致,如 Cn / Us / Tw / Hk / Ja) */
|
|
192
|
+
exports.LOCALE_PATTERN = /^[A-Za-z][A-Za-z0-9]{1,15}$/;
|
|
193
|
+
/** 新建业务字段的物理名前缀(与前端 generateColId 一致) */
|
|
194
|
+
exports.FIELD_NAME_PREFIX = 'fd_col_';
|
|
195
|
+
/**
|
|
196
|
+
* 默认表单图标。
|
|
197
|
+
*
|
|
198
|
+
* ⚠️ 必须提供:sys-modeling 表单编辑页 `content.tsx` 存在
|
|
199
|
+
* `JSON.parse(\`${fdIcon}\` || '{}')` 的写法,当 fdIcon 为 undefined 时
|
|
200
|
+
* `` `${fdIcon}` `` 会得到真值字符串 "undefined",兜底失效并抛
|
|
201
|
+
* `SyntaxError: "undefined" is not valid JSON`,导致编辑器无法进入。
|
|
202
|
+
*/
|
|
203
|
+
exports.DEFAULT_FORM_ICON = {
|
|
204
|
+
name: 'iconCommon_line_16_file',
|
|
205
|
+
type: 'vector',
|
|
206
|
+
style: { backgroundColor: '', color: '#4285F4', borderRadius: 0 },
|
|
207
|
+
normalize: true,
|
|
208
|
+
};
|
|
209
|
+
exports.DEFAULT_FORM_ICON_JSON = JSON.stringify(exports.DEFAULT_FORM_ICON);
|
|
210
|
+
/**
|
|
211
|
+
* 基础主题(默认)—— 对应 sys-xform `store/viewModel/theme/preset.ts` 的 desktopDefault。
|
|
212
|
+
*/
|
|
213
|
+
exports.DEFAULT_DESKTOP_THEME = {
|
|
214
|
+
title: '基础主题(默认)',
|
|
215
|
+
desktopPaddingMode: 'standard',
|
|
216
|
+
desktopLayout: 'horizontal',
|
|
217
|
+
labelTextAlign: 'left',
|
|
218
|
+
desktopTitleStyle: { color: '#000000', fontSize: 14 },
|
|
219
|
+
desktopTitleBgColor: 'unset',
|
|
220
|
+
desktopValueStyle: { color: '#000000', fontSize: 14 },
|
|
221
|
+
desktopDividerStyleSelect: 'default',
|
|
222
|
+
desktopDividerTitleStyle: { color: '#000000', fontWeight: 'bold', fontSize: 16 },
|
|
223
|
+
desktopDividerColor: '',
|
|
224
|
+
mobileDividerColor: '',
|
|
225
|
+
formTitle: {
|
|
226
|
+
colorStyle: '#DDDDDD',
|
|
227
|
+
lineSelect: 'thin',
|
|
228
|
+
styleSelect: 'line',
|
|
229
|
+
titleStyle: { fontWeight: 'bold', fontSize: 24 },
|
|
230
|
+
titleTextAlign: 'center',
|
|
231
|
+
title: '',
|
|
232
|
+
},
|
|
233
|
+
desktopGridItemStyle: { backgroundColor: '' },
|
|
234
|
+
desktopValidatorInfoUIType: 'normal',
|
|
235
|
+
backgroundSetting: {
|
|
236
|
+
type: 'color',
|
|
237
|
+
data: {
|
|
238
|
+
color: { r: 255, g: 255, b: 255, a: 1 },
|
|
239
|
+
toFade: false,
|
|
240
|
+
height: 400,
|
|
241
|
+
autoHeight: true,
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
};
|
|
245
|
+
exports.DEFAULT_MOBILE_THEME = {
|
|
246
|
+
mobileLayout: 'vertical',
|
|
247
|
+
mobileDividerStyleSelect: 'default',
|
|
248
|
+
mobileDividerColor: '',
|
|
249
|
+
};
|
|
250
|
+
/** 默认控件样式(依据默认主题推导,与前端 getControlAttr 结果一致) */
|
|
251
|
+
exports.DEFAULT_CONTROL_STYLE = {
|
|
252
|
+
labelStyle: { color: '#000000', fontSize: 14 },
|
|
253
|
+
controlValueStyle: { color: '#000000', fontSize: 14 },
|
|
254
|
+
desktopTitleBgColor: 'unset',
|
|
255
|
+
desktopPaddingMode: 'standard',
|
|
256
|
+
layout: 'horizontal',
|
|
257
|
+
titleStyle: { color: '#000000', fontWeight: 'bold', fontSize: 16 },
|
|
258
|
+
color: '',
|
|
259
|
+
};
|
|
260
|
+
/**
|
|
261
|
+
* 明细表自身的 controlStyle。
|
|
262
|
+
* 实测真实表单:明细表有独立条目(desktop + mobile),而**明细字段没有**。
|
|
263
|
+
*/
|
|
264
|
+
exports.DEFAULT_DETAIL_CONTROL_STYLE = {
|
|
265
|
+
desktop: { ...exports.DEFAULT_CONTROL_STYLE },
|
|
266
|
+
mobile: {
|
|
267
|
+
color: '',
|
|
268
|
+
layout: 'horizontal',
|
|
269
|
+
titleStyle: {},
|
|
270
|
+
desktopTitleBgColor: 'unset',
|
|
271
|
+
desktopPaddingMode: 'standard',
|
|
272
|
+
labelStyle: {},
|
|
273
|
+
controlValueStyle: {},
|
|
274
|
+
},
|
|
275
|
+
};
|