mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-06-09 08:52:21 +00:00
Compare commits
23 Commits
main
...
v1.1.5-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db5f035de2 | ||
|
|
ded3f66b61 | ||
|
|
8678684eef | ||
|
|
2513f3e66f | ||
|
|
cce9bbf04b | ||
|
|
5fd1527663 | ||
|
|
d88be3d91e | ||
|
|
d75e72a54a | ||
|
|
2ae6254c7e | ||
|
|
39bfff3e9d | ||
|
|
b275697742 | ||
|
|
d00d8bf449 | ||
|
|
9f216d45e2 | ||
|
|
42fee1c3ee | ||
|
|
6b91417d36 | ||
|
|
73a35b5e7d | ||
|
|
568302820c | ||
|
|
4111f6eecb | ||
|
|
a05a36b06c | ||
|
|
dfa1fcda12 | ||
|
|
cf993af632 | ||
|
|
0c92794ac5 | ||
|
|
237b1bed31 |
23
.github/workflows/pr comment by chatgpt.yml
vendored
Normal file
23
.github/workflows/pr comment by chatgpt.yml
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
name: Pull Request Review By ChatGPT
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize, reopened]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
code-review:
|
||||||
|
name: Code Review
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
# 判断用户是否有写仓库权限
|
||||||
|
- name: 'Check User Permission'
|
||||||
|
uses: 'lannonbr/repo-permission-check-action@2.0.0'
|
||||||
|
with:
|
||||||
|
permission: 'write'
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- uses: opensumi/actions/.github/actions/code-review@main
|
||||||
|
env:
|
||||||
|
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||||
@ -29,12 +29,17 @@ sidebar_position: 0
|
|||||||
- node-children 节点孩子
|
- node-children 节点孩子
|
||||||
- props 属性集
|
- props 属性集
|
||||||
- prop 属性
|
- prop 属性
|
||||||
- setting-prop-entry 设置属性
|
- setting-field 设置属性
|
||||||
- setting-top-entry 设置属性集
|
- setting-top-entry 设置属性集
|
||||||
- component-meta 物料元数据
|
- component-meta 物料元数据
|
||||||
- selection 画布选中
|
- selection 画布选中
|
||||||
- detecting 画布 hover
|
- detecting 画布 hover
|
||||||
- history 操作历史
|
- history 操作历史
|
||||||
|
- window 低代码设计器窗口模型
|
||||||
|
- detecting 画布节点悬停模型
|
||||||
|
- modal-nodes-manager 模态节点管理器模型
|
||||||
|
- plugin-instance 插件实例
|
||||||
|
- drop-location 拖拽放置位置模型
|
||||||
|
|
||||||
|
|
||||||
## API 设计约定
|
## API 设计约定
|
||||||
|
|||||||
@ -9,7 +9,7 @@ sidebar_position: 10
|
|||||||
## 模块简介
|
## 模块简介
|
||||||
提供 init 等方法
|
提供 init 等方法
|
||||||
## 方法
|
## 方法
|
||||||
#### 1. init
|
#### init
|
||||||
初始化引擎
|
初始化引擎
|
||||||
|
|
||||||
**方法定义**
|
**方法定义**
|
||||||
|
|||||||
@ -1,113 +0,0 @@
|
|||||||
---
|
|
||||||
title: Config
|
|
||||||
sidebar_position: 16
|
|
||||||
---
|
|
||||||
> **@types** [IPublicModelEngineConfig](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/engine-config.ts)<br/>
|
|
||||||
> **@since** v1.1.3
|
|
||||||
|
|
||||||
## 方法
|
|
||||||
### has
|
|
||||||
|
|
||||||
判断指定 key 是否有值
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
/**
|
|
||||||
* 判断指定 key 是否有值
|
|
||||||
* check if config has certain key configed
|
|
||||||
* @param key
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
has(key: string): boolean;
|
|
||||||
```
|
|
||||||
|
|
||||||
### get
|
|
||||||
|
|
||||||
获取指定 key 的值
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
/**
|
|
||||||
* 获取指定 key 的值
|
|
||||||
* get value by key
|
|
||||||
* @param key
|
|
||||||
* @param defaultValue
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
get(key: string, defaultValue?: any): any;
|
|
||||||
```
|
|
||||||
|
|
||||||
### set
|
|
||||||
|
|
||||||
设置指定 key 的值
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
/**
|
|
||||||
* 设置指定 key 的值
|
|
||||||
* set value for certain key
|
|
||||||
* @param key
|
|
||||||
* @param value
|
|
||||||
*/
|
|
||||||
set(key: string, value: any): void;
|
|
||||||
```
|
|
||||||
|
|
||||||
### setConfig
|
|
||||||
批量设值,set 的对象版本
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
/**
|
|
||||||
* 批量设值,set 的对象版本
|
|
||||||
* set multiple config key-values
|
|
||||||
* @param config
|
|
||||||
*/
|
|
||||||
setConfig(config: { [key: string]: any }): void;
|
|
||||||
```
|
|
||||||
|
|
||||||
### getPreference
|
|
||||||
获取全局 Preference, 用于管理全局浏览器侧用户 Preference,如 Panel 是否钉住
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
/**
|
|
||||||
* 获取全局 Preference, 用于管理全局浏览器侧用户 Preference,如 Panel 是否钉住
|
|
||||||
* get global user preference manager, which can be use to store
|
|
||||||
* user`s preference in user localstorage, such as a panel is pinned or not.
|
|
||||||
* @returns {IPublicModelPreference}
|
|
||||||
* @since v1.1.0
|
|
||||||
*/
|
|
||||||
getPreference(): IPublicModelPreference;
|
|
||||||
```
|
|
||||||
|
|
||||||
相关类型:[IPublicModelPreference](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/preference.ts)
|
|
||||||
|
|
||||||
## 事件
|
|
||||||
|
|
||||||
### onGot
|
|
||||||
获取指定 key 的值,函数回调模式,若多次被赋值,回调会被多次调用
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
/**
|
|
||||||
* 获取指定 key 的值,函数回调模式,若多次被赋值,回调会被多次调用
|
|
||||||
* set callback for event of value set for some key
|
|
||||||
* this will be called each time the value is set
|
|
||||||
* @param key
|
|
||||||
* @param fn
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
onGot(key: string, fn: (data: any) => void): IPublicTypeDisposable;
|
|
||||||
```
|
|
||||||
|
|
||||||
相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
|
|
||||||
|
|
||||||
### onceGot
|
|
||||||
获取指定 key 的值,若此时还未赋值,则等待,若已有值,则直接返回值
|
|
||||||
> 注:此函数返回 Promise 实例,只会执行(fullfill)一次
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
/**
|
|
||||||
* 获取指定 key 的值,若此时还未赋值,则等待,若已有值,则直接返回值
|
|
||||||
* 注:此函数返回 Promise 实例,只会执行(fullfill)一次
|
|
||||||
* wait until value of certain key is set, will only be
|
|
||||||
* triggered once.
|
|
||||||
* @param key
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
onceGot(key: string): Promise<any>;
|
|
||||||
```
|
|
||||||
@ -254,6 +254,8 @@ sidebar_position: 1
|
|||||||
|
|
||||||
`@type {IPublicModelSettingTopEntry}`
|
`@type {IPublicModelSettingTopEntry}`
|
||||||
|
|
||||||
|
相关章节:[设置器顶层操作对象](./setting-top-entry)
|
||||||
|
|
||||||
相关类型:[IPublicModelSettingTopEntry](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/setting-top-entry.ts)
|
相关类型:[IPublicModelSettingTopEntry](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/setting-top-entry.ts)
|
||||||
|
|
||||||
### visible
|
### visible
|
||||||
|
|||||||
342
docs/docs/api/model/setting-field.md
Normal file
342
docs/docs/api/model/setting-field.md
Normal file
@ -0,0 +1,342 @@
|
|||||||
|
---
|
||||||
|
title: SettingField
|
||||||
|
sidebar_position: 6
|
||||||
|
---
|
||||||
|
> **@types** [IPublicModelSettingField](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/setting-field.ts)<br/>
|
||||||
|
|
||||||
|
## 基本介绍
|
||||||
|
|
||||||
|
setter 设置器操作对象
|
||||||
|
|
||||||
|
## 属性
|
||||||
|
|
||||||
|
#### isGroup
|
||||||
|
|
||||||
|
获取设置属性的 isGroup
|
||||||
|
|
||||||
|
`@type {boolean}`
|
||||||
|
|
||||||
|
|
||||||
|
#### id
|
||||||
|
|
||||||
|
获取设置属性的 id
|
||||||
|
|
||||||
|
`@type {string}`
|
||||||
|
|
||||||
|
#### name
|
||||||
|
|
||||||
|
获取设置属性的 name
|
||||||
|
|
||||||
|
`@type {string | number | undefined}`
|
||||||
|
|
||||||
|
#### key
|
||||||
|
|
||||||
|
获取设置属性的 key
|
||||||
|
|
||||||
|
`@type {string | number | undefined}`
|
||||||
|
|
||||||
|
#### path
|
||||||
|
|
||||||
|
获取设置属性的 path
|
||||||
|
|
||||||
|
`@type {(string | number)[]}`
|
||||||
|
|
||||||
|
#### title
|
||||||
|
|
||||||
|
获取设置属性的 title
|
||||||
|
|
||||||
|
`@type {string}`
|
||||||
|
|
||||||
|
#### setter
|
||||||
|
|
||||||
|
获取设置属性的 setter
|
||||||
|
|
||||||
|
`@type {IPublicTypeSetterType | null}`
|
||||||
|
|
||||||
|
#### expanded
|
||||||
|
|
||||||
|
获取设置属性的 expanded
|
||||||
|
|
||||||
|
`@type {boolean}`
|
||||||
|
|
||||||
|
#### extraProps
|
||||||
|
|
||||||
|
获取设置属性的 extraProps
|
||||||
|
|
||||||
|
`@type {IPublicTypeFieldExtraProps}`
|
||||||
|
|
||||||
|
#### props
|
||||||
|
|
||||||
|
`@type {IPublicModelSettingTopEntry}`
|
||||||
|
|
||||||
|
相关章节:[设置器顶层操作对象](./setting-top-entry)
|
||||||
|
|
||||||
|
相关类型:[IPublicModelSettingTopEntry](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/setting-top-entry.ts)
|
||||||
|
|
||||||
|
#### node
|
||||||
|
|
||||||
|
获取设置属性对应的节点实例
|
||||||
|
|
||||||
|
`@type {IPublicModelNode | null}`
|
||||||
|
|
||||||
|
|
||||||
|
#### parent
|
||||||
|
|
||||||
|
获取设置属性的父设置属性
|
||||||
|
|
||||||
|
`@type {IPublicModelSettingTopEntry | IPublicModelSettingField}`
|
||||||
|
|
||||||
|
相关章节:[设置器顶层操作对象](./setting-top-entry)
|
||||||
|
|
||||||
|
相关类型:[IPublicModelSettingTopEntry](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/setting-top-entry.ts)
|
||||||
|
|
||||||
|
#### top
|
||||||
|
|
||||||
|
获取顶级设置属性
|
||||||
|
|
||||||
|
`@type {IPublicModelSettingTopEntry}`
|
||||||
|
|
||||||
|
相关章节:[设置器顶层操作对象](./setting-top-entry)
|
||||||
|
|
||||||
|
相关类型:[IPublicModelSettingTopEntry](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/setting-top-entry.ts)
|
||||||
|
|
||||||
|
#### isSettingField
|
||||||
|
|
||||||
|
是否是 SettingField 实例
|
||||||
|
|
||||||
|
`@type {boolean}`
|
||||||
|
|
||||||
|
#### componentMeta
|
||||||
|
|
||||||
|
`@type {IPublicModelComponentMeta}`
|
||||||
|
|
||||||
|
相关类型:[IPublicModelComponentMeta](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/component-meta.ts)
|
||||||
|
|
||||||
|
#### items
|
||||||
|
|
||||||
|
获取设置属性的 items
|
||||||
|
|
||||||
|
`@type {Array<IPublicModelSettingField | IPublicTypeCustomView>}`
|
||||||
|
|
||||||
|
相关类型:[IPublicTypeCustomView](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/custom-view.ts)
|
||||||
|
|
||||||
|
## 方法
|
||||||
|
|
||||||
|
#### setKey
|
||||||
|
|
||||||
|
设置 key 值
|
||||||
|
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* 设置 key 值
|
||||||
|
* @param key
|
||||||
|
*/
|
||||||
|
setKey(key: string | number): void;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### setValue
|
||||||
|
|
||||||
|
设置值
|
||||||
|
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* 设置值
|
||||||
|
* @param val 值
|
||||||
|
*/
|
||||||
|
setValue(val: IPublicTypeCompositeValue, extraOptions?: IPublicTypeSetValueOptions): void;
|
||||||
|
```
|
||||||
|
|
||||||
|
相关类型:
|
||||||
|
- [IPublicTypeCompositeValue](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/composite-value.ts)
|
||||||
|
- [IPublicTypeSetValueOptions](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/set-value-options.ts)
|
||||||
|
|
||||||
|
#### setPropValue
|
||||||
|
|
||||||
|
设置子级属性值
|
||||||
|
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* 设置子级属性值
|
||||||
|
* @param propName 子属性名
|
||||||
|
* @param value 值
|
||||||
|
*/
|
||||||
|
setPropValue(propName: string | number, value: any): void;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### clearPropValue
|
||||||
|
|
||||||
|
清空指定属性值
|
||||||
|
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* 清空指定属性值
|
||||||
|
* @param propName
|
||||||
|
*/
|
||||||
|
clearPropValue(propName: string | number): void;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### getDefaultValue
|
||||||
|
|
||||||
|
获取配置的默认值
|
||||||
|
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* 获取配置的默认值
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
getDefaultValue(): any;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### getValue
|
||||||
|
|
||||||
|
获取值
|
||||||
|
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* 获取值
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
getValue(): any;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### getPropValue
|
||||||
|
|
||||||
|
获取子级属性值
|
||||||
|
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* 获取子级属性值
|
||||||
|
* @param propName 子属性名
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
getPropValue(propName: string | number): any;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### getExtraPropValue
|
||||||
|
|
||||||
|
获取顶层附属属性值
|
||||||
|
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* 获取顶层附属属性值
|
||||||
|
*/
|
||||||
|
getExtraPropValue(propName: string): any;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### setExtraPropValue
|
||||||
|
|
||||||
|
设置顶层附属属性值
|
||||||
|
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* 设置顶层附属属性值
|
||||||
|
*/
|
||||||
|
setExtraPropValue(propName: string, value: any): void;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### getProps
|
||||||
|
|
||||||
|
获取设置属性集
|
||||||
|
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* 获取设置属性集
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
getProps(): IPublicModelSettingTopEntry;
|
||||||
|
```
|
||||||
|
|
||||||
|
相关章节:[设置器顶层操作对象](./setting-top-entry)
|
||||||
|
|
||||||
|
相关类型:[IPublicModelSettingTopEntry](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/setting-top-entry.ts)
|
||||||
|
|
||||||
|
#### isUseVariable
|
||||||
|
|
||||||
|
是否绑定了变量
|
||||||
|
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* 是否绑定了变量
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
isUseVariable(): boolean;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### setUseVariable
|
||||||
|
|
||||||
|
设置绑定变量
|
||||||
|
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* 设置绑定变量
|
||||||
|
* @param flag
|
||||||
|
*/
|
||||||
|
setUseVariable(flag: boolean): void;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### createField
|
||||||
|
|
||||||
|
创建一个设置 field 实例
|
||||||
|
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* 创建一个设置 field 实例
|
||||||
|
* @param config
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
createField(config: IPublicTypeFieldConfig): IPublicModelSettingField;
|
||||||
|
```
|
||||||
|
|
||||||
|
相关类型:[IPublicTypeFieldConfig](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/field-config.ts)
|
||||||
|
|
||||||
|
#### getMockOrValue
|
||||||
|
|
||||||
|
获取值,当为变量时,返回 mock
|
||||||
|
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* 获取值,当为变量时,返回 mock
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
getMockOrValue(): any;
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
#### purge
|
||||||
|
|
||||||
|
销毁当前 field 实例
|
||||||
|
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* 销毁当前 field 实例
|
||||||
|
*/
|
||||||
|
purge(): void;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### remove
|
||||||
|
|
||||||
|
移除当前 field 实例
|
||||||
|
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* 移除当前 field 实例
|
||||||
|
*/
|
||||||
|
remove(): void;
|
||||||
|
```
|
||||||
|
|
||||||
|
## 事件
|
||||||
|
|
||||||
|
#### onEffect
|
||||||
|
|
||||||
|
设置 autorun
|
||||||
|
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* 设置 autorun
|
||||||
|
* @param action
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
onEffect(action: () => void): IPublicTypeDisposable;
|
||||||
|
```
|
||||||
|
|
||||||
|
相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
|
||||||
74
docs/docs/api/model/setting-top-entry.md
Normal file
74
docs/docs/api/model/setting-top-entry.md
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
---
|
||||||
|
title: SettingTopEntry
|
||||||
|
sidebar_position: 6
|
||||||
|
---
|
||||||
|
> **@types** [IPublicModelSettingTopEntry](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/setting-top-entry.ts)<br/>
|
||||||
|
|
||||||
|
## 基本介绍
|
||||||
|
|
||||||
|
setter 设置器顶层操作对象
|
||||||
|
|
||||||
|
## 属性
|
||||||
|
|
||||||
|
#### node
|
||||||
|
|
||||||
|
返回所属的节点实例
|
||||||
|
|
||||||
|
`@type {IPublicModelNode | null}`
|
||||||
|
|
||||||
|
## 方法
|
||||||
|
|
||||||
|
#### get
|
||||||
|
|
||||||
|
获取子级属性对象
|
||||||
|
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* 获取子级属性对象
|
||||||
|
* @param propName
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
get(propName: string | number): IPublicModelSettingField | null;
|
||||||
|
```
|
||||||
|
相关章节:[设置器操作对象](./setting-field)
|
||||||
|
|
||||||
|
相关类型:[IPublicModelSettingField](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/setting-field.ts)
|
||||||
|
|
||||||
|
|
||||||
|
#### getPropValue
|
||||||
|
|
||||||
|
获取指定 propName 的值
|
||||||
|
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* 获取指定 propName 的值
|
||||||
|
* @param propName
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
getPropValue(propName: string | number): any;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### setPropValue
|
||||||
|
|
||||||
|
设置指定 propName 的值
|
||||||
|
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* 设置指定 propName 的值
|
||||||
|
* @param propName
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
setPropValue(propName: string | number, value: any): void;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### clearPropValue
|
||||||
|
|
||||||
|
清除指定 propName 的值
|
||||||
|
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* 清除指定 propName 的值
|
||||||
|
* @param propName
|
||||||
|
*/
|
||||||
|
clearPropValue(propName: string | number): void;
|
||||||
|
```
|
||||||
@ -252,6 +252,35 @@ setI18n(value: object): void;
|
|||||||
|
|
||||||
**@since v1.0.17**
|
**@since v1.0.17**
|
||||||
|
|
||||||
|
### setConfig
|
||||||
|
设置当前项目配置
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
/**
|
||||||
|
* 设置当前项目配置
|
||||||
|
* set config for this project
|
||||||
|
* @param value object
|
||||||
|
* @since v1.1.4
|
||||||
|
*/
|
||||||
|
setConfig(value: IPublicTypeAppConfig): void;
|
||||||
|
setConfig<T extends keyof IPublicTypeAppConfig>(key: T, value: IPublicTypeAppConfig[T]): void;
|
||||||
|
```
|
||||||
|
|
||||||
|
**@since v1.1.4**
|
||||||
|
|
||||||
|
#### 如何扩展项目配置
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// shims.d.ts
|
||||||
|
declare module '@alilc/lowcode-types' {
|
||||||
|
export interface IPublicTypeAppConfig {
|
||||||
|
customProp: CustomPropType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {};
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## 事件
|
## 事件
|
||||||
|
|
||||||
|
|||||||
@ -3,17 +3,17 @@ title: 低代码引擎相关文章资料
|
|||||||
---
|
---
|
||||||
|
|
||||||
## 官方文章
|
## 官方文章
|
||||||
|
- [2023/03/23 低代码引擎 LowCodeEngine 茁壮成长的一年](https://mp.weixin.qq.com/s/DDt4LQLFUBQ2-F5ehZGBKg)
|
||||||
- [基于 LowCodeEngine 的低代码组件体系的建设和实践](https://mp.weixin.qq.com/s/rnvbGHImGt6oJuX2wCtaqw)
|
- [2023/02/21 基于 LowCodeEngine 的低代码组件体系的建设和实践](https://mp.weixin.qq.com/s/rnvbGHImGt6oJuX2wCtaqw)
|
||||||
- [低代码多分支协同开发的建设与实践](https://mp.weixin.qq.com/s/DmwxL67htHfTUP1U966N-Q)
|
- [2022/12/21 低代码多分支协同开发的建设与实践](https://mp.weixin.qq.com/s/DmwxL67htHfTUP1U966N-Q)
|
||||||
- [低代码引擎半岁啦,来跟大家唠唠嗑...](https://segmentfault.com/a/1190000042884409)
|
- [2022/11/24 低代码引擎半岁啦,来跟大家唠唠嗑...](https://segmentfault.com/a/1190000042884409)
|
||||||
- [低代码技术在研发团队的应用模式探讨](https://mp.weixin.qq.com/s/Ynk_wjJbmNw7fEG6UtGZbQ)
|
- [2022/10/27 低代码技术在研发团队的应用模式探讨](https://mp.weixin.qq.com/s/Ynk_wjJbmNw7fEG6UtGZbQ)
|
||||||
- [关于 LowCode&ProCode 混合研发的思考](https://mp.weixin.qq.com/s/TY3VXjkSmsQoT47xma3wig)
|
- [2022/06/23 低代码渲染那些事](https://mp.weixin.qq.com/s/yqYey76qLGYPfDtpGkVFfA)
|
||||||
- [低代码渲染那些事](https://mp.weixin.qq.com/s/yqYey76qLGYPfDtpGkVFfA)
|
- [2022/06/16 关于 LowCode&ProCode 混合研发的思考](https://mp.weixin.qq.com/s/TY3VXjkSmsQoT47xma3wig)
|
||||||
- [阿里低代码引擎和生态建设实战及思考](https://mp.weixin.qq.com/s/MI6MrUKKydtnSdO4xq6jwA)
|
- [2022/04/07 磁贴布局在钉钉宜搭报表设计引擎中的实现](https://mp.weixin.qq.com/s/PSTut5ahAB8nlJ9kBpBaxw)
|
||||||
- [磁贴布局在钉钉宜搭报表设计引擎中的实现](https://mp.weixin.qq.com/s/PSTut5ahAB8nlJ9kBpBaxw)
|
- [2022/03/23 阿里低代码引擎 LowCodeEngine 正式开源!](https://mp.weixin.qq.com/s/T66LghtWLz2Oh048XqaniA)
|
||||||
- [2B 领域下的低代码探索之路](https://mp.weixin.qq.com/s/HAxrMHLT43dPH488RiEIdw)
|
- [2022/01/10 阿里低代码引擎和生态建设实战及思考](https://mp.weixin.qq.com/s/MI6MrUKKydtnSdO4xq6jwA)
|
||||||
- [阿里低代码引擎 LowCodeEngine 正式开源!](https://mp.weixin.qq.com/s/T66LghtWLz2Oh048XqaniA)
|
- [2021/04/14 2B 领域下的低代码探索之路](https://mp.weixin.qq.com/s/HAxrMHLT43dPH488RiEIdw)
|
||||||
|
|
||||||
## Portal 设计项目实战
|
## Portal 设计项目实战
|
||||||
#### 直播回放
|
#### 直播回放
|
||||||
|
|||||||
@ -44,6 +44,6 @@ sidebar_position: 3
|
|||||||
| @alifd/fusion-ui | [https://github.com/alibaba/lowcode-materials](https://github.com/alibaba/lowcode-materials) | packages/fusion-ui |
|
| @alifd/fusion-ui | [https://github.com/alibaba/lowcode-materials](https://github.com/alibaba/lowcode-materials) | packages/fusion-ui |
|
||||||
| @alilc/lowcode-materials | [https://github.com/alibaba/lowcode-materials](https://github.com/alibaba/lowcode-materials) | packages/fusion-lowcode-materials |
|
| @alilc/lowcode-materials | [https://github.com/alibaba/lowcode-materials](https://github.com/alibaba/lowcode-materials) | packages/fusion-lowcode-materials |
|
||||||
| @alilc/antd-lowcode-materials | [https://github.com/alibaba/lowcode-materials](https://github.com/alibaba/lowcode-materials) | packages/antd-lowcode-materials |
|
| @alilc/antd-lowcode-materials | [https://github.com/alibaba/lowcode-materials](https://github.com/alibaba/lowcode-materials) | packages/antd-lowcode-materials |
|
||||||
| | | |
|
| @alifd/layout(原 @alifd/pro-layout 升级后的版本) | [https://github.com/alibaba-fusion/layout](https://github.com/alibaba-fusion/layout) | |
|
||||||
| | | |
|
| | | |
|
||||||
| | | |
|
| | | |
|
||||||
|
|||||||
74
docs/docs/guide/appendix/setterDetails/function.md
Normal file
74
docs/docs/guide/appendix/setterDetails/function.md
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
---
|
||||||
|
title: FunctionSetter
|
||||||
|
---
|
||||||
|
## 简介
|
||||||
|
可以将function绑定在物料上
|
||||||
|
|
||||||
|
## 设置器返回
|
||||||
|
|
||||||
|
设置器返回一个Function对象,调用function()运行Function对象得到运行结果。
|
||||||
|
|
||||||
|
如下是一个典型的使用案例:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
export type TestProps = React.ComponentProps<typeof Test> & {
|
||||||
|
testFunction?: Function | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTestData = () => {
|
||||||
|
if(this.props.testFunction === undefined){
|
||||||
|
return undefined;
|
||||||
|
}else{
|
||||||
|
return this.props.testFunction() // 返回testFunction()方法的运行结果;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## 参数设置
|
||||||
|
|
||||||
|
如果需要额外传参,需要将扩展参数设置打开,在代码面板中,编辑参数内容。
|
||||||
|
|
||||||
|
注意:
|
||||||
|
|
||||||
|
- 额外参数必须被包装成一个对象,如参数模板中所示
|
||||||
|
- 可以使用动态变量例如 (this.items,this.state.xxx)
|
||||||
|
```javascript
|
||||||
|
{
|
||||||
|
testKey: this.state.text,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- 该参数是额外参数,会加在原有参数后面,例如在 onClick 中加入扩展传参,最终函数消费的时候应该如下所示
|
||||||
|
```javascript
|
||||||
|
// e 为 onClick 原有函数传参,extParams 为自定义传参
|
||||||
|
onClick(e, extParams) {
|
||||||
|
this.setState({
|
||||||
|
isShowDialog: extParams.isShowDialog,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 事件新建函数模板
|
||||||
|
有时候我们创建的函数会有用到一些通用的函数模板,我们可以在物料协议的 meta.ts 中创建一个模板,如下
|
||||||
|
|
||||||
|
```TypeScript
|
||||||
|
{
|
||||||
|
name: 'onChange',
|
||||||
|
title: {
|
||||||
|
label: 'onChange',
|
||||||
|
tip: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
|
||||||
|
},
|
||||||
|
propType: 'func',
|
||||||
|
setter: [
|
||||||
|
{
|
||||||
|
componentName: 'FunctionSetter',
|
||||||
|
props: {
|
||||||
|
template: 'onTableChange(value,${extParams}){\n\n}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
其中 ${extParams} 为扩展参数占位符,如果用户没有声明扩展参数,会移除对应的参数声明。
|
||||||
@ -14,7 +14,7 @@ sidebar_position: 4
|
|||||||
| DateYearSetter || 日期型 - 年数据设置器 | |
|
| DateYearSetter || 日期型 - 年数据设置器 | |
|
||||||
| [EventSetter](./setterDetails/event) | function | 事件绑定设置器 |  |
|
| [EventSetter](./setterDetails/event) | function | 事件绑定设置器 |  |
|
||||||
| [IconSetter](./setterDetails/icon) | string | 图标设置器 |  |
|
| [IconSetter](./setterDetails/icon) | string | 图标设置器 |  |
|
||||||
| FunctionSetter | any | 函数型数据设置器 |  |
|
| [FunctionSetter](./setterDetails/function) | function | 函数型数据设置器 |  |
|
||||||
| JsonSetter | object | json 型数据设置器 |  |
|
| JsonSetter | object | json 型数据设置器 |  |
|
||||||
| [MixedSetter](./setterDetails/mixed) | any | 混合型数据设置器 |  |
|
| [MixedSetter](./setterDetails/mixed) | any | 混合型数据设置器 |  |
|
||||||
| [NumberSetter](./setterDetails/number) | number | 数值型数据设置器 |  |
|
| [NumberSetter](./setterDetails/number) | number | 数值型数据设置器 |  |
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@alilc/lowcode-engine-docs",
|
"name": "@alilc/lowcode-engine-docs",
|
||||||
"version": "1.0.21",
|
"version": "1.0.24",
|
||||||
"description": "低代码引擎版本化文档",
|
"description": "低代码引擎版本化文档",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"files": [
|
"files": [
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"lerna": "4.0.0",
|
"lerna": "4.0.0",
|
||||||
"version": "1.1.4",
|
"version": "1.1.5-beta.6",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"useWorkspaces": true,
|
"useWorkspaces": true,
|
||||||
"packages": [
|
"packages": [
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@alilc/lowcode-code-generator",
|
"name": "@alilc/lowcode-code-generator",
|
||||||
"version": "1.0.8",
|
"version": "1.1.0",
|
||||||
"description": "出码引擎 for LowCode Engine",
|
"description": "出码引擎 for LowCode Engine",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import { createModuleBuilder } from './generator/ModuleBuilder';
|
|||||||
import { createDiskPublisher } from './publisher/disk';
|
import { createDiskPublisher } from './publisher/disk';
|
||||||
import { createZipPublisher } from './publisher/zip';
|
import { createZipPublisher } from './publisher/zip';
|
||||||
import createIceJsProjectBuilder, { plugins as reactPlugins } from './solutions/icejs';
|
import createIceJsProjectBuilder, { plugins as reactPlugins } from './solutions/icejs';
|
||||||
|
import createIce3JsProjectBuilder, { plugins as icejs3Plugins } from './solutions/icejs3';
|
||||||
import createRaxAppProjectBuilder, { plugins as raxPlugins } from './solutions/rax-app';
|
import createRaxAppProjectBuilder, { plugins as raxPlugins } from './solutions/rax-app';
|
||||||
|
|
||||||
// 引入说明
|
// 引入说明
|
||||||
@ -32,6 +33,7 @@ import * as CONSTANTS from './const';
|
|||||||
|
|
||||||
// 引入内置解决方案模块
|
// 引入内置解决方案模块
|
||||||
import icejs from './plugins/project/framework/icejs';
|
import icejs from './plugins/project/framework/icejs';
|
||||||
|
import icejs3 from './plugins/project/framework/icejs3';
|
||||||
import rax from './plugins/project/framework/rax';
|
import rax from './plugins/project/framework/rax';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -39,10 +41,12 @@ export default {
|
|||||||
createModuleBuilder,
|
createModuleBuilder,
|
||||||
solutions: {
|
solutions: {
|
||||||
icejs: createIceJsProjectBuilder,
|
icejs: createIceJsProjectBuilder,
|
||||||
|
icejs3: createIce3JsProjectBuilder,
|
||||||
rax: createRaxAppProjectBuilder,
|
rax: createRaxAppProjectBuilder,
|
||||||
},
|
},
|
||||||
solutionParts: {
|
solutionParts: {
|
||||||
icejs,
|
icejs,
|
||||||
|
icejs3,
|
||||||
rax,
|
rax,
|
||||||
},
|
},
|
||||||
publishers: {
|
publishers: {
|
||||||
@ -74,6 +78,9 @@ export default {
|
|||||||
i18n,
|
i18n,
|
||||||
utils,
|
utils,
|
||||||
},
|
},
|
||||||
|
icejs3: {
|
||||||
|
...icejs3Plugins,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
postprocessor: {
|
postprocessor: {
|
||||||
prettier,
|
prettier,
|
||||||
|
|||||||
@ -16,7 +16,7 @@ import {
|
|||||||
IWithDependency,
|
IWithDependency,
|
||||||
} from '../../types';
|
} from '../../types';
|
||||||
|
|
||||||
import { isValidIdentifier, isValidComponentName } from '../../utils/validate';
|
import { isValidIdentifier } from '../../utils/validate';
|
||||||
|
|
||||||
// TODO: main 这个信息到底怎么用,是不是外部包不需要使用?
|
// TODO: main 这个信息到底怎么用,是不是外部包不需要使用?
|
||||||
const DEP_MAIN_BLOCKLIST = ['lib', 'lib/index', 'es', 'es/index', 'main'];
|
const DEP_MAIN_BLOCKLIST = ['lib', 'lib/index', 'es', 'es/index', 'main'];
|
||||||
@ -261,7 +261,7 @@ function buildPackageImport(
|
|||||||
if (!isValidIdentifier(name)) {
|
if (!isValidIdentifier(name)) {
|
||||||
throw new CodeGeneratorError(`Invalid Identifier [${name}]`);
|
throw new CodeGeneratorError(`Invalid Identifier [${name}]`);
|
||||||
}
|
}
|
||||||
if (info.nodeIdentifier && !isValidComponentName(info.nodeIdentifier)) {
|
if (info.nodeIdentifier && !isValidIdentifier(info.nodeIdentifier)) {
|
||||||
throw new CodeGeneratorError(`Invalid Identifier [${info.nodeIdentifier}]`);
|
throw new CodeGeneratorError(`Invalid Identifier [${info.nodeIdentifier}]`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -0,0 +1,17 @@
|
|||||||
|
import template from './template';
|
||||||
|
import globalStyle from './plugins/globalStyle';
|
||||||
|
import packageJSON from './plugins/packageJSON';
|
||||||
|
import layout from './plugins/layout';
|
||||||
|
import appConfig from './plugins/appConfig';
|
||||||
|
import buildConfig from './plugins/buildConfig';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
template,
|
||||||
|
plugins: {
|
||||||
|
appConfig,
|
||||||
|
buildConfig,
|
||||||
|
globalStyle,
|
||||||
|
packageJSON,
|
||||||
|
layout,
|
||||||
|
},
|
||||||
|
};
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
import {
|
||||||
|
BuilderComponentPlugin,
|
||||||
|
BuilderComponentPluginFactory,
|
||||||
|
ChunkType,
|
||||||
|
FileType,
|
||||||
|
ICodeStruct,
|
||||||
|
} from '../../../../../types';
|
||||||
|
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
|
||||||
|
|
||||||
|
export interface AppConfigPluginConfig {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function getContent() {
|
||||||
|
return `import { defineAppConfig } from 'ice';
|
||||||
|
|
||||||
|
// App config, see https://v3.ice.work/docs/guide/basic/app
|
||||||
|
export default defineAppConfig(() => ({
|
||||||
|
// Set your configs here.
|
||||||
|
app: {
|
||||||
|
rootId: 'App',
|
||||||
|
},
|
||||||
|
router: {
|
||||||
|
type: 'browser',
|
||||||
|
basename: '/',
|
||||||
|
},
|
||||||
|
}));`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pluginFactory: BuilderComponentPluginFactory<AppConfigPluginConfig> = () => {
|
||||||
|
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
||||||
|
const next: ICodeStruct = {
|
||||||
|
...pre,
|
||||||
|
};
|
||||||
|
|
||||||
|
next.chunks.push({
|
||||||
|
type: ChunkType.STRING,
|
||||||
|
fileType: FileType.TS,
|
||||||
|
name: COMMON_CHUNK_NAME.FileMainContent,
|
||||||
|
content: getContent(),
|
||||||
|
linkAfter: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
return next;
|
||||||
|
};
|
||||||
|
|
||||||
|
return plugin;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default pluginFactory;
|
||||||
@ -0,0 +1,165 @@
|
|||||||
|
import {
|
||||||
|
BuilderComponentPlugin,
|
||||||
|
BuilderComponentPluginFactory,
|
||||||
|
ChunkType,
|
||||||
|
FileType,
|
||||||
|
ICodeStruct,
|
||||||
|
} from '../../../../../types';
|
||||||
|
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
|
||||||
|
import { format } from '../../../../../utils/format';
|
||||||
|
import { getThemeInfo } from '../../../../../utils/theme';
|
||||||
|
|
||||||
|
export interface BuildConfigPluginConfig {
|
||||||
|
|
||||||
|
/** 包名 */
|
||||||
|
themePackage?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getContent(cfg?: BuildConfigPluginConfig, routesContent?: string) {
|
||||||
|
return `
|
||||||
|
import { join } from 'path';
|
||||||
|
import { defineConfig } from '@ice/app';
|
||||||
|
import _ from 'lodash';
|
||||||
|
import fusion from '@ice/plugin-fusion';
|
||||||
|
import locales from '@ice/plugin-moment-locales';
|
||||||
|
import type { Plugin } from '@ice/app/esm/types';
|
||||||
|
|
||||||
|
interface PluginOptions {
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const plugin: Plugin<PluginOptions> = (options) => ({
|
||||||
|
// name 可选,插件名称
|
||||||
|
name: 'plugin-name',
|
||||||
|
// setup 必选,用于定制工程构建配置
|
||||||
|
setup: ({ onGetConfig, modifyUserConfig }) => {
|
||||||
|
modifyUserConfig('codeSplitting', 'page');
|
||||||
|
|
||||||
|
onGetConfig((config) => {
|
||||||
|
config.entry = {
|
||||||
|
web: join(process.cwd(), '.ice/entry.client.tsx'),
|
||||||
|
};
|
||||||
|
|
||||||
|
config.cssFilename = '[name].css';
|
||||||
|
|
||||||
|
config.configureWebpack = config.configureWebpack || [];
|
||||||
|
config.configureWebpack?.push((webpackConfig) => {
|
||||||
|
if (webpackConfig.output) {
|
||||||
|
webpackConfig.output.filename = '[name].js';
|
||||||
|
webpackConfig.output.chunkFilename = '[name].js';
|
||||||
|
}
|
||||||
|
return webpackConfig;
|
||||||
|
});
|
||||||
|
|
||||||
|
config.swcOptions = _.merge(config.swcOptions, {
|
||||||
|
compilationConfig: {
|
||||||
|
jsc: {
|
||||||
|
transform: {
|
||||||
|
react: {
|
||||||
|
runtime: 'classic',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 解决 webpack publicPath 问题
|
||||||
|
config.transforms = config.transforms || [];
|
||||||
|
config.transforms.push((source: string, id: string) => {
|
||||||
|
if (id.includes('.ice/entry.client.tsx')) {
|
||||||
|
let code = \`
|
||||||
|
if (!__webpack_public_path__?.startsWith('http') && document.currentScript) {
|
||||||
|
// @ts-ignore
|
||||||
|
__webpack_public_path__ = document.currentScript.src.replace(/^(.*\\\\/)[^/]+$/, '$1');
|
||||||
|
window.__ICE_ASSETS_MANIFEST__ = window.__ICE_ASSETS_MANIFEST__ || {};
|
||||||
|
window.__ICE_ASSETS_MANIFEST__.publicPath = __webpack_public_path__;
|
||||||
|
}
|
||||||
|
\`;
|
||||||
|
code += source;
|
||||||
|
return { code };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// The project config, see https://v3.ice.work/docs/guide/basic/config
|
||||||
|
const minify = process.env.NODE_ENV === 'production' ? 'swc' : false;
|
||||||
|
export default defineConfig(() => ({
|
||||||
|
ssr: false,
|
||||||
|
ssg: false,
|
||||||
|
minify,
|
||||||
|
${routesContent}
|
||||||
|
externals: {
|
||||||
|
react: 'React',
|
||||||
|
'react-dom': 'ReactDOM',
|
||||||
|
'react-dom/client': 'ReactDOM',
|
||||||
|
'@alifd/next': 'Next',
|
||||||
|
lodash: 'var window._',
|
||||||
|
'@alilc/lowcode-engine': 'var window.AliLowCodeEngine',
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
fusion(${cfg?.themePackage ? `{
|
||||||
|
importStyle: 'sass',
|
||||||
|
themePackage: '${getThemeInfo(cfg.themePackage).name}',
|
||||||
|
}` : `{
|
||||||
|
importStyle: true,
|
||||||
|
}`}),
|
||||||
|
locales(),
|
||||||
|
plugin(),
|
||||||
|
]
|
||||||
|
}));
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRoutesContent(navData: any, needShell = true) {
|
||||||
|
const routes = [
|
||||||
|
'routes: {',
|
||||||
|
' defineRoutes: route => {',
|
||||||
|
];
|
||||||
|
function _getRoutes(nav: any, _routes: string[] = []) {
|
||||||
|
const { slug, children } = nav;
|
||||||
|
if (children && children.length > 0) {
|
||||||
|
children.forEach((_nav: any) => _getRoutes(_nav, _routes));
|
||||||
|
} else if (slug) {
|
||||||
|
_routes.push(`route('/${slug}', '${slug}/index.jsx');`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (needShell) {
|
||||||
|
routes.push(" route('/', 'layout.jsx', () => {");
|
||||||
|
}
|
||||||
|
navData?.forEach((nav: any) => {
|
||||||
|
_getRoutes(nav, routes);
|
||||||
|
});
|
||||||
|
if (needShell) {
|
||||||
|
routes.push(' });');
|
||||||
|
}
|
||||||
|
routes.push(' }'); // end of defineRoutes
|
||||||
|
routes.push(' },'); // end of routes
|
||||||
|
return routes.join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
const pluginFactory: BuilderComponentPluginFactory<BuildConfigPluginConfig> = (cfg?) => {
|
||||||
|
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
||||||
|
const next: ICodeStruct = {
|
||||||
|
...pre,
|
||||||
|
};
|
||||||
|
|
||||||
|
const { navConfig } = next.contextData;
|
||||||
|
const routesContent = navConfig?.data ? getRoutesContent(navConfig.data, true) : '';
|
||||||
|
|
||||||
|
next.chunks.push({
|
||||||
|
type: ChunkType.STRING,
|
||||||
|
fileType: FileType.MTS,
|
||||||
|
name: COMMON_CHUNK_NAME.FileMainContent,
|
||||||
|
content: format(getContent(cfg, routesContent)),
|
||||||
|
linkAfter: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
return next;
|
||||||
|
};
|
||||||
|
|
||||||
|
return plugin;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default pluginFactory;
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
|
||||||
|
|
||||||
|
import {
|
||||||
|
BuilderComponentPlugin,
|
||||||
|
BuilderComponentPluginFactory,
|
||||||
|
ChunkType,
|
||||||
|
FileType,
|
||||||
|
ICodeStruct,
|
||||||
|
IProjectInfo,
|
||||||
|
} from '../../../../../types';
|
||||||
|
|
||||||
|
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
||||||
|
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
||||||
|
const next: ICodeStruct = {
|
||||||
|
...pre,
|
||||||
|
};
|
||||||
|
|
||||||
|
const ir = next.ir as IProjectInfo;
|
||||||
|
|
||||||
|
next.chunks.push({
|
||||||
|
type: ChunkType.STRING,
|
||||||
|
fileType: FileType.SCSS,
|
||||||
|
name: COMMON_CHUNK_NAME.StyleDepsImport,
|
||||||
|
content: `
|
||||||
|
// 引入默认全局样式
|
||||||
|
@import '@alifd/next/reset.scss';
|
||||||
|
`,
|
||||||
|
linkAfter: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
next.chunks.push({
|
||||||
|
type: ChunkType.STRING,
|
||||||
|
fileType: FileType.SCSS,
|
||||||
|
name: COMMON_CHUNK_NAME.StyleCssContent,
|
||||||
|
content: `
|
||||||
|
body {
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
linkAfter: [COMMON_CHUNK_NAME.StyleDepsImport],
|
||||||
|
});
|
||||||
|
|
||||||
|
next.chunks.push({
|
||||||
|
type: ChunkType.STRING,
|
||||||
|
fileType: FileType.SCSS,
|
||||||
|
name: COMMON_CHUNK_NAME.StyleCssContent,
|
||||||
|
content: ir.css || '',
|
||||||
|
linkAfter: [COMMON_CHUNK_NAME.StyleDepsImport],
|
||||||
|
});
|
||||||
|
|
||||||
|
return next;
|
||||||
|
};
|
||||||
|
return plugin;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default pluginFactory;
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
import {
|
||||||
|
BuilderComponentPlugin,
|
||||||
|
BuilderComponentPluginFactory,
|
||||||
|
ChunkType,
|
||||||
|
FileType,
|
||||||
|
ICodeStruct,
|
||||||
|
} from '../../../../../types';
|
||||||
|
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
|
||||||
|
|
||||||
|
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
||||||
|
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
||||||
|
const next: ICodeStruct = {
|
||||||
|
...pre,
|
||||||
|
};
|
||||||
|
|
||||||
|
next.chunks.push({
|
||||||
|
type: ChunkType.STRING,
|
||||||
|
fileType: FileType.JSX,
|
||||||
|
name: COMMON_CHUNK_NAME.FileMainContent,
|
||||||
|
content: `
|
||||||
|
import { Outlet } from 'ice';
|
||||||
|
import BasicLayout from '@/layouts/BasicLayout';
|
||||||
|
|
||||||
|
export default function Layout() {
|
||||||
|
return (
|
||||||
|
<BasicLayout>
|
||||||
|
<Outlet />
|
||||||
|
</BasicLayout>
|
||||||
|
);;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
linkAfter: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
return next;
|
||||||
|
};
|
||||||
|
|
||||||
|
return plugin;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default pluginFactory;
|
||||||
@ -0,0 +1,119 @@
|
|||||||
|
import { PackageJSON } from '@alilc/lowcode-types';
|
||||||
|
|
||||||
|
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
|
||||||
|
|
||||||
|
import {
|
||||||
|
BuilderComponentPlugin,
|
||||||
|
BuilderComponentPluginFactory,
|
||||||
|
ChunkType,
|
||||||
|
FileType,
|
||||||
|
ICodeStruct,
|
||||||
|
IProjectInfo,
|
||||||
|
} from '../../../../../types';
|
||||||
|
import { buildDataSourceDependencies } from '../../../../../utils/dataSource';
|
||||||
|
|
||||||
|
interface IIceJs3PackageJSON extends PackageJSON {
|
||||||
|
originTemplate: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IceJs3PackageJsonPluginConfig = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据源配置
|
||||||
|
*/
|
||||||
|
datasourceConfig?: {
|
||||||
|
|
||||||
|
/** 数据源引擎的版本 */
|
||||||
|
engineVersion?: string;
|
||||||
|
|
||||||
|
/** 数据源引擎的包名 */
|
||||||
|
enginePackage?: string;
|
||||||
|
|
||||||
|
/** 数据源 handlers 的版本 */
|
||||||
|
handlersVersion?: {
|
||||||
|
[key: string]: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 数据源 handlers 的包名 */
|
||||||
|
handlersPackages?: {
|
||||||
|
[key: string]: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 包名 */
|
||||||
|
packageName?: string;
|
||||||
|
|
||||||
|
/** 版本 */
|
||||||
|
packageVersion?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const pluginFactory: BuilderComponentPluginFactory<IceJs3PackageJsonPluginConfig> = (cfg) => {
|
||||||
|
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
||||||
|
const next: ICodeStruct = {
|
||||||
|
...pre,
|
||||||
|
};
|
||||||
|
|
||||||
|
const ir = next.ir as IProjectInfo;
|
||||||
|
|
||||||
|
const packageJson: IIceJs3PackageJSON = {
|
||||||
|
name: cfg?.packageName || 'icejs3-demo-app',
|
||||||
|
version: cfg?.packageVersion || '0.1.5',
|
||||||
|
description: 'icejs 3 轻量级模板,使用 JavaScript,仅包含基础的 Layout。',
|
||||||
|
dependencies: {
|
||||||
|
moment: '^2.24.0',
|
||||||
|
react: '^18.2.0',
|
||||||
|
'react-dom': '^18.2.0',
|
||||||
|
'react-router': '^6.9.0',
|
||||||
|
'react-router-dom': '^6.9.0',
|
||||||
|
'intl-messageformat': '^9.3.6',
|
||||||
|
'@alifd/next': '1.26.15',
|
||||||
|
'@ice/runtime': '^1.0.0',
|
||||||
|
// 数据源相关的依赖:
|
||||||
|
...buildDataSourceDependencies(ir, cfg?.datasourceConfig),
|
||||||
|
},
|
||||||
|
devDependencies: {
|
||||||
|
'@ice/app': '^3.0.0',
|
||||||
|
'@types/react': '^18.0.0',
|
||||||
|
'@types/react-dom': '^18.0.0',
|
||||||
|
'@types/node': '^18.11.17',
|
||||||
|
'@ice/plugin-fusion': '^1.0.1',
|
||||||
|
'@ice/plugin-moment-locales': '^1.0.0',
|
||||||
|
eslint: '^6.0.1',
|
||||||
|
stylelint: '^13.2.0',
|
||||||
|
},
|
||||||
|
scripts: {
|
||||||
|
start: 'ice start',
|
||||||
|
build: 'ice build',
|
||||||
|
lint: 'npm run eslint && npm run stylelint',
|
||||||
|
eslint: 'eslint --cache --ext .js,.jsx ./',
|
||||||
|
stylelint: 'stylelint ./**/*.scss',
|
||||||
|
},
|
||||||
|
engines: {
|
||||||
|
node: '>=14.0.0',
|
||||||
|
},
|
||||||
|
repository: {
|
||||||
|
type: 'git',
|
||||||
|
url: 'http://gitlab.xxx.com/msd/leak-scan/tree/master',
|
||||||
|
},
|
||||||
|
private: true,
|
||||||
|
originTemplate: '@alifd/scaffold-lite-js',
|
||||||
|
};
|
||||||
|
|
||||||
|
ir.packages.forEach((packageInfo) => {
|
||||||
|
packageJson.dependencies[packageInfo.package] = packageInfo.version;
|
||||||
|
});
|
||||||
|
|
||||||
|
next.chunks.push({
|
||||||
|
type: ChunkType.JSON,
|
||||||
|
fileType: FileType.JSON,
|
||||||
|
name: COMMON_CHUNK_NAME.FileMainContent,
|
||||||
|
content: packageJson,
|
||||||
|
linkAfter: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
return next;
|
||||||
|
};
|
||||||
|
return plugin;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default pluginFactory;
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
import { ResultFile } from '@alilc/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
|
export default function getFile(): [string[], ResultFile] {
|
||||||
|
const file = createResultFile(
|
||||||
|
'README',
|
||||||
|
'md',
|
||||||
|
'This project is generated by lowcode-code-generator & lowcode-solution-icejs3.',
|
||||||
|
);
|
||||||
|
|
||||||
|
return [[], file];
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
import { ResultFile } from '@alilc/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
|
export default function getFile(): [string[], ResultFile] {
|
||||||
|
const file = createResultFile(
|
||||||
|
'.browserslistrc',
|
||||||
|
'',
|
||||||
|
`defaults
|
||||||
|
ios_saf 9
|
||||||
|
`,
|
||||||
|
);
|
||||||
|
|
||||||
|
return [[], file];
|
||||||
|
}
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
import { ResultFile } from '@alilc/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
|
/* eslint-disable max-len */
|
||||||
|
export default function getFile(): [string[], ResultFile] {
|
||||||
|
const file = createResultFile(
|
||||||
|
'document',
|
||||||
|
'tsx',
|
||||||
|
`import React from 'react';
|
||||||
|
import { Meta, Title, Links, Main, Scripts } from 'ice';
|
||||||
|
|
||||||
|
export default function Document() {
|
||||||
|
return (
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charSet="utf-8" />
|
||||||
|
<meta name="description" content="ice.js 3 lite scaffold" />
|
||||||
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
<link rel="stylesheet" href="//alifd.alicdn.com/npm/@alifd/next/1.21.16/next.min.css" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
|
||||||
|
<Meta />
|
||||||
|
<Title />
|
||||||
|
<Links />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<Main />
|
||||||
|
<script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react/18.2.0/umd/react.development.js" />
|
||||||
|
<script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react-dom/18.2.0/umd/react-dom.development.js" />
|
||||||
|
<script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/??react-router/6.9.0/react-router.production.min.js,react-router-dom/6.9.0/react-router-dom.production.min.js" />
|
||||||
|
<script crossOrigin="anonymous" src="//alifd.alicdn.com/npm/@alifd/next/1.26.15/next.min.js" />
|
||||||
|
<script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/prop-types/15.7.2/prop-types.js" />
|
||||||
|
<script crossOrigin="anonymous" src="//g.alicdn.com/platform/c/??lodash/4.6.1/lodash.min.js,immutable/3.7.6/dist/immutable.min.js" />
|
||||||
|
<Scripts />
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
return [['src'], file];
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
import { ResultFile } from '@alilc/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
|
export default function getFile(): [string[], ResultFile] {
|
||||||
|
const file = createResultFile(
|
||||||
|
'.gitignore',
|
||||||
|
'',
|
||||||
|
`
|
||||||
|
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# production
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
tmp/
|
||||||
|
lib/
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.idea/
|
||||||
|
.happypack
|
||||||
|
.DS_Store
|
||||||
|
*.swp
|
||||||
|
*.dia~
|
||||||
|
.ice
|
||||||
|
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
index.module.scss.d.ts
|
||||||
|
`,
|
||||||
|
);
|
||||||
|
|
||||||
|
return [[], file];
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
import { ResultFile } from '@alilc/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
|
export default function getFile(): [string[], ResultFile] {
|
||||||
|
const file = createResultFile(
|
||||||
|
'index',
|
||||||
|
'jsx',
|
||||||
|
`
|
||||||
|
import React from 'react';
|
||||||
|
import styles from './index.module.scss';
|
||||||
|
|
||||||
|
export default function Footer() {
|
||||||
|
return (
|
||||||
|
<p className={styles.footer}>
|
||||||
|
<span className={styles.logo}>Alibaba Fusion</span>
|
||||||
|
<br />
|
||||||
|
<span className={styles.copyright}>© 2019-现在 Alibaba Fusion & ICE</span>
|
||||||
|
</p>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
);
|
||||||
|
|
||||||
|
return [['src', 'layouts', 'BasicLayout', 'components', 'Footer'], file];
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
import { ResultFile } from '@alilc/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
|
export default function getFile(): [string[], ResultFile] {
|
||||||
|
const file = createResultFile(
|
||||||
|
'index',
|
||||||
|
'module.scss',
|
||||||
|
`
|
||||||
|
.footer {
|
||||||
|
line-height: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyright {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
);
|
||||||
|
|
||||||
|
return [['src', 'layouts', 'BasicLayout', 'components', 'Footer'], file];
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
import { ResultFile } from '@alilc/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
|
export default function getFile(): [string[], ResultFile] {
|
||||||
|
const file = createResultFile(
|
||||||
|
'index',
|
||||||
|
'jsx',
|
||||||
|
`
|
||||||
|
import React from 'react';
|
||||||
|
import { Link } from 'ice';
|
||||||
|
import styles from './index.module.scss';
|
||||||
|
|
||||||
|
export default function Logo({ image, text, url }) {
|
||||||
|
return (
|
||||||
|
<div className="logo">
|
||||||
|
<Link to={url || '/'} className={styles.logo}>
|
||||||
|
{image && <img src={image} alt="logo" />}
|
||||||
|
<span>{text}</span>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
);
|
||||||
|
|
||||||
|
return [['src', 'layouts', 'BasicLayout', 'components', 'Logo'], file];
|
||||||
|
}
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
import { ResultFile } from '@alilc/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
|
export default function getFile(): [string[], ResultFile] {
|
||||||
|
const file = createResultFile(
|
||||||
|
'index',
|
||||||
|
'module.scss',
|
||||||
|
`
|
||||||
|
.logo{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: $color-text1-1;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 22px;
|
||||||
|
|
||||||
|
&:visited, &:link {
|
||||||
|
color: $color-text1-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 24px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
);
|
||||||
|
|
||||||
|
return [['src', 'layouts', 'BasicLayout', 'components', 'Logo'], file];
|
||||||
|
}
|
||||||
@ -0,0 +1,79 @@
|
|||||||
|
import { ResultFile } from '@alilc/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
|
export default function getFile(): [string[], ResultFile] {
|
||||||
|
const file = createResultFile(
|
||||||
|
'index',
|
||||||
|
'jsx',
|
||||||
|
`import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { Link, useLocation } from 'ice';
|
||||||
|
import { Nav } from '@alifd/next';
|
||||||
|
import { asideMenuConfig } from '../../menuConfig';
|
||||||
|
|
||||||
|
const { SubNav } = Nav;
|
||||||
|
const NavItem = Nav.Item;
|
||||||
|
|
||||||
|
function getNavMenuItems(menusData) {
|
||||||
|
if (!menusData) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return menusData
|
||||||
|
.filter(item => item.name && !item.hideInMenu)
|
||||||
|
.map((item, index) => getSubMenuOrItem(item, index));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSubMenuOrItem(item, index) {
|
||||||
|
if (item.children && item.children.some(child => child.name)) {
|
||||||
|
const childrenItems = getNavMenuItems(item.children);
|
||||||
|
|
||||||
|
if (childrenItems && childrenItems.length > 0) {
|
||||||
|
const subNav = (
|
||||||
|
<SubNav key={index} icon={item.icon} label={item.name}>
|
||||||
|
{childrenItems}
|
||||||
|
</SubNav>
|
||||||
|
);
|
||||||
|
return subNav;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const navItem = (
|
||||||
|
<NavItem key={item.path} icon={item.icon}>
|
||||||
|
<Link to={item.path}>{item.name}</Link>
|
||||||
|
</NavItem>
|
||||||
|
);
|
||||||
|
return navItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Navigation = (props, context) => {
|
||||||
|
const location = useLocation();
|
||||||
|
const { pathname } = location;
|
||||||
|
const { isCollapse } = context;
|
||||||
|
return (
|
||||||
|
<Nav
|
||||||
|
type="primary"
|
||||||
|
selectedKeys={[pathname]}
|
||||||
|
defaultSelectedKeys={[pathname]}
|
||||||
|
embeddable
|
||||||
|
openMode="single"
|
||||||
|
iconOnly={isCollapse}
|
||||||
|
hasArrow={false}
|
||||||
|
mode={isCollapse ? 'popup' : 'inline'}
|
||||||
|
>
|
||||||
|
{getNavMenuItems(asideMenuConfig)}
|
||||||
|
</Nav>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Navigation.contextTypes = {
|
||||||
|
isCollapse: PropTypes.bool,
|
||||||
|
};
|
||||||
|
export default Navigation;
|
||||||
|
`,
|
||||||
|
);
|
||||||
|
|
||||||
|
return [['src', 'layouts', 'BasicLayout', 'components', 'PageNav'], file];
|
||||||
|
}
|
||||||
@ -0,0 +1,92 @@
|
|||||||
|
import { ResultFile } from '@alilc/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
|
export default function getFile(): [string[], ResultFile] {
|
||||||
|
const file = createResultFile(
|
||||||
|
'index',
|
||||||
|
'jsx',
|
||||||
|
`
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Shell, ConfigProvider } from '@alifd/next';
|
||||||
|
import PageNav from './components/PageNav';
|
||||||
|
import Logo from './components/Logo';
|
||||||
|
import Footer from './components/Footer';
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
const throttle = function(type, name, obj = window) {
|
||||||
|
let running = false;
|
||||||
|
|
||||||
|
const func = () => {
|
||||||
|
if (running) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
running = true;
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
obj.dispatchEvent(new CustomEvent(name));
|
||||||
|
running = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
obj.addEventListener(type, func);
|
||||||
|
};
|
||||||
|
|
||||||
|
throttle('resize', 'optimizedResize');
|
||||||
|
})();
|
||||||
|
|
||||||
|
export default function BasicLayout({ children }) {
|
||||||
|
const getDevice = width => {
|
||||||
|
const isPhone =
|
||||||
|
typeof navigator !== 'undefined' && navigator && navigator.userAgent.match(/phone/gi);
|
||||||
|
|
||||||
|
if (width < 680 || isPhone) {
|
||||||
|
return 'phone';
|
||||||
|
}
|
||||||
|
if (width < 1280 && width > 680) {
|
||||||
|
return 'tablet';
|
||||||
|
}
|
||||||
|
return 'desktop';
|
||||||
|
};
|
||||||
|
|
||||||
|
const [device, setDevice] = useState(getDevice(NaN));
|
||||||
|
window.addEventListener('optimizedResize', e => {
|
||||||
|
setDevice(getDevice(e && e.target && e.target.innerWidth));
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<ConfigProvider device={device}>
|
||||||
|
<Shell
|
||||||
|
type="dark"
|
||||||
|
style={{
|
||||||
|
minHeight: '100vh',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Shell.Branding>
|
||||||
|
<Logo
|
||||||
|
image="https://img.alicdn.com/tfs/TB1.ZBecq67gK0jSZFHXXa9jVXa-904-826.png"
|
||||||
|
text="Logo"
|
||||||
|
/>
|
||||||
|
</Shell.Branding>
|
||||||
|
<Shell.Navigation
|
||||||
|
direction="hoz"
|
||||||
|
style={{
|
||||||
|
marginRight: 10,
|
||||||
|
}}
|
||||||
|
></Shell.Navigation>
|
||||||
|
<Shell.Action></Shell.Action>
|
||||||
|
<Shell.Navigation>
|
||||||
|
<PageNav />
|
||||||
|
</Shell.Navigation>
|
||||||
|
|
||||||
|
<Shell.Content>{children}</Shell.Content>
|
||||||
|
<Shell.Footer>
|
||||||
|
<Footer />
|
||||||
|
</Shell.Footer>
|
||||||
|
</Shell>
|
||||||
|
</ConfigProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
);
|
||||||
|
|
||||||
|
return [['src', 'layouts', 'BasicLayout'], file];
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
import { ResultFile } from '@alilc/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
|
export default function getFile(): [string[], ResultFile] {
|
||||||
|
const file = createResultFile(
|
||||||
|
'menuConfig',
|
||||||
|
'js',
|
||||||
|
`
|
||||||
|
const headerMenuConfig = [];
|
||||||
|
const asideMenuConfig = [
|
||||||
|
{
|
||||||
|
name: 'Dashboard',
|
||||||
|
path: '/',
|
||||||
|
icon: 'smile',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
export { headerMenuConfig, asideMenuConfig };
|
||||||
|
`,
|
||||||
|
);
|
||||||
|
|
||||||
|
return [['src', 'layouts', 'BasicLayout'], file];
|
||||||
|
}
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
import { ResultFile } from '@alilc/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
|
export default function getFile(): [string[], ResultFile] {
|
||||||
|
const file = createResultFile(
|
||||||
|
'tsconfig',
|
||||||
|
'json',
|
||||||
|
`
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": "./",
|
||||||
|
"module": "ESNext",
|
||||||
|
"target": "ESNext",
|
||||||
|
"lib": ["DOM", "ESNext", "DOM.Iterable"],
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noImplicitThis": true,
|
||||||
|
"noImplicitAny": false,
|
||||||
|
"importHelpers": true,
|
||||||
|
"strictNullChecks": true,
|
||||||
|
"suppressImplicitAnyIndexErrors": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"],
|
||||||
|
"ice": [".ice"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": ["src", ".ice"],
|
||||||
|
"exclude": ["build"]
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
);
|
||||||
|
|
||||||
|
return [[], file];
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
import { ResultFile } from '@alilc/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
|
export default function getFile(): [string[], ResultFile] {
|
||||||
|
const file = createResultFile(
|
||||||
|
'typings.d',
|
||||||
|
'ts',
|
||||||
|
`/// <reference types="@ice/app/types" />
|
||||||
|
|
||||||
|
export {};
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
g_config: Record<string, any>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
);
|
||||||
|
|
||||||
|
return [['src'], file];
|
||||||
|
}
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
import { IProjectTemplate } from '../../../../../types';
|
||||||
|
import { generateStaticFiles } from './static-files';
|
||||||
|
|
||||||
|
const icejs3Template: IProjectTemplate = {
|
||||||
|
slots: {
|
||||||
|
components: {
|
||||||
|
path: ['src', 'components'],
|
||||||
|
fileName: 'index',
|
||||||
|
},
|
||||||
|
pages: {
|
||||||
|
path: ['src', 'pages'],
|
||||||
|
fileName: 'index',
|
||||||
|
},
|
||||||
|
entry: {
|
||||||
|
path: ['src'],
|
||||||
|
fileName: 'app',
|
||||||
|
},
|
||||||
|
constants: {
|
||||||
|
path: ['src'],
|
||||||
|
fileName: 'constants',
|
||||||
|
},
|
||||||
|
utils: {
|
||||||
|
path: ['src'],
|
||||||
|
fileName: 'utils',
|
||||||
|
},
|
||||||
|
i18n: {
|
||||||
|
path: ['src'],
|
||||||
|
fileName: 'i18n',
|
||||||
|
},
|
||||||
|
globalStyle: {
|
||||||
|
path: ['src'],
|
||||||
|
fileName: 'global',
|
||||||
|
},
|
||||||
|
packageJSON: {
|
||||||
|
path: [],
|
||||||
|
fileName: 'package',
|
||||||
|
},
|
||||||
|
appConfig: {
|
||||||
|
path: ['src'],
|
||||||
|
fileName: 'app',
|
||||||
|
},
|
||||||
|
buildConfig: {
|
||||||
|
path: [],
|
||||||
|
fileName: 'ice.config',
|
||||||
|
},
|
||||||
|
layout: {
|
||||||
|
path: ['src', 'pages'],
|
||||||
|
fileName: 'layout',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
generateTemplate() {
|
||||||
|
return generateStaticFiles();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default icejs3Template;
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
import { ResultDir } from '@alilc/lowcode-types';
|
||||||
|
import { createResultDir } from '../../../../../utils/resultHelper';
|
||||||
|
import { runFileGenerator } from '../../../../../utils/templateHelper';
|
||||||
|
|
||||||
|
import file1 from './files/gitignore';
|
||||||
|
import file2 from './files/README.md';
|
||||||
|
import file3 from './files/browserslistrc';
|
||||||
|
import file4 from './files/typings';
|
||||||
|
import file5 from './files/document';
|
||||||
|
import file6 from './files/src/layouts/BasicLayout/components/Footer/index.jsx';
|
||||||
|
import file7 from './files/src/layouts/BasicLayout/components/Footer/index.style';
|
||||||
|
import file8 from './files/src/layouts/BasicLayout/components/Logo/index.jsx';
|
||||||
|
import file9 from './files/src/layouts/BasicLayout/components/Logo/index.style';
|
||||||
|
import file10 from './files/src/layouts/BasicLayout/components/PageNav/index.jsx';
|
||||||
|
import file11 from './files/src/layouts/BasicLayout/index.jsx';
|
||||||
|
import file12 from './files/src/layouts/BasicLayout/menuConfig.js';
|
||||||
|
|
||||||
|
export function generateStaticFiles(root = createResultDir('.')): ResultDir {
|
||||||
|
runFileGenerator(root, file1);
|
||||||
|
runFileGenerator(root, file2);
|
||||||
|
runFileGenerator(root, file3);
|
||||||
|
runFileGenerator(root, file4);
|
||||||
|
runFileGenerator(root, file5);
|
||||||
|
runFileGenerator(root, file6);
|
||||||
|
runFileGenerator(root, file7);
|
||||||
|
runFileGenerator(root, file8);
|
||||||
|
runFileGenerator(root, file9);
|
||||||
|
runFileGenerator(root, file10);
|
||||||
|
runFileGenerator(root, file11);
|
||||||
|
runFileGenerator(root, file12);
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
109
modules/code-generator/src/solutions/icejs3.ts
Normal file
109
modules/code-generator/src/solutions/icejs3.ts
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
import { IProjectBuilder, IProjectBuilderOptions } from '../types';
|
||||||
|
|
||||||
|
import { createProjectBuilder } from '../generator/ProjectBuilder';
|
||||||
|
|
||||||
|
import esmodule from '../plugins/common/esmodule';
|
||||||
|
import containerClass from '../plugins/component/react/containerClass';
|
||||||
|
import containerInitState from '../plugins/component/react/containerInitState';
|
||||||
|
import containerInjectContext from '../plugins/component/react/containerInjectContext';
|
||||||
|
import containerInjectUtils from '../plugins/component/react/containerInjectUtils';
|
||||||
|
import containerInjectDataSourceEngine from '../plugins/component/react/containerInjectDataSourceEngine';
|
||||||
|
import containerInjectConstants from '../plugins/component/react/containerInjectConstants';
|
||||||
|
import containerInjectI18n from '../plugins/component/react/containerInjectI18n';
|
||||||
|
import containerLifeCycle from '../plugins/component/react/containerLifeCycle';
|
||||||
|
import containerMethod from '../plugins/component/react/containerMethod';
|
||||||
|
import jsx from '../plugins/component/react/jsx';
|
||||||
|
import reactCommonDeps from '../plugins/component/react/reactCommonDeps';
|
||||||
|
import css from '../plugins/component/style/css';
|
||||||
|
import constants from '../plugins/project/constants';
|
||||||
|
import i18n from '../plugins/project/i18n';
|
||||||
|
import utils from '../plugins/project/utils';
|
||||||
|
|
||||||
|
import icejs3 from '../plugins/project/framework/icejs3';
|
||||||
|
|
||||||
|
import { prettier } from '../postprocessor';
|
||||||
|
|
||||||
|
export type IceJs3ProjectBuilderOptions = IProjectBuilderOptions;
|
||||||
|
|
||||||
|
export default function createIceJsProjectBuilder(
|
||||||
|
options?: IceJs3ProjectBuilderOptions,
|
||||||
|
): IProjectBuilder {
|
||||||
|
return createProjectBuilder({
|
||||||
|
inStrictMode: options?.inStrictMode,
|
||||||
|
extraContextData: { ...options },
|
||||||
|
template: icejs3.template,
|
||||||
|
plugins: {
|
||||||
|
components: [
|
||||||
|
reactCommonDeps(),
|
||||||
|
esmodule({
|
||||||
|
fileType: 'jsx',
|
||||||
|
}),
|
||||||
|
containerClass(),
|
||||||
|
containerInjectContext(),
|
||||||
|
containerInjectUtils(),
|
||||||
|
containerInjectDataSourceEngine(),
|
||||||
|
containerInjectI18n(),
|
||||||
|
containerInitState(),
|
||||||
|
containerLifeCycle(),
|
||||||
|
containerMethod(),
|
||||||
|
jsx({
|
||||||
|
nodeTypeMapping: {
|
||||||
|
Div: 'div',
|
||||||
|
Component: 'div',
|
||||||
|
Page: 'div',
|
||||||
|
Block: 'div',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
css(),
|
||||||
|
],
|
||||||
|
pages: [
|
||||||
|
reactCommonDeps(),
|
||||||
|
esmodule({
|
||||||
|
fileType: 'jsx',
|
||||||
|
}),
|
||||||
|
containerClass(),
|
||||||
|
containerInjectContext(),
|
||||||
|
containerInjectUtils(),
|
||||||
|
containerInjectDataSourceEngine(),
|
||||||
|
containerInjectI18n(),
|
||||||
|
containerInjectConstants(),
|
||||||
|
containerInitState(),
|
||||||
|
containerLifeCycle(),
|
||||||
|
containerMethod(),
|
||||||
|
jsx({
|
||||||
|
nodeTypeMapping: {
|
||||||
|
Div: 'div',
|
||||||
|
Component: 'div',
|
||||||
|
Page: 'div',
|
||||||
|
Block: 'div',
|
||||||
|
Box: 'div',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
css(),
|
||||||
|
],
|
||||||
|
constants: [constants()],
|
||||||
|
utils: [esmodule(), utils('react')],
|
||||||
|
i18n: [i18n()],
|
||||||
|
globalStyle: [icejs3.plugins.globalStyle()],
|
||||||
|
packageJSON: [icejs3.plugins.packageJSON()],
|
||||||
|
buildConfig: [icejs3.plugins.buildConfig()],
|
||||||
|
appConfig: [icejs3.plugins.appConfig()],
|
||||||
|
layout: [icejs3.plugins.layout()],
|
||||||
|
},
|
||||||
|
postProcessors: [prettier()],
|
||||||
|
customizeBuilderOptions: options?.customizeBuilderOptions,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export const plugins = {
|
||||||
|
containerClass,
|
||||||
|
containerInitState,
|
||||||
|
containerInjectContext,
|
||||||
|
containerInjectUtils,
|
||||||
|
containerInjectI18n,
|
||||||
|
containerInjectDataSourceEngine,
|
||||||
|
containerLifeCycle,
|
||||||
|
containerMethod,
|
||||||
|
jsx,
|
||||||
|
commonDeps: reactCommonDeps,
|
||||||
|
};
|
||||||
12
modules/code-generator/src/utils/format.ts
Normal file
12
modules/code-generator/src/utils/format.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import prettier from 'prettier';
|
||||||
|
import parserBabel from 'prettier/parser-babel';
|
||||||
|
|
||||||
|
export function format(content: string, options = {}) {
|
||||||
|
return prettier.format(content, {
|
||||||
|
parser: 'babel',
|
||||||
|
plugins: [parserBabel],
|
||||||
|
singleQuote: true,
|
||||||
|
jsxSingleQuote: false,
|
||||||
|
...options,
|
||||||
|
});
|
||||||
|
}
|
||||||
20
modules/code-generator/src/utils/theme.ts
Normal file
20
modules/code-generator/src/utils/theme.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* 获取主题信息
|
||||||
|
* @param theme theme 形如 @alife/theme-97 或者 @alife/theme-97@^1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface ThemeInfo {
|
||||||
|
name: string;
|
||||||
|
version?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getThemeInfo(theme: string): ThemeInfo {
|
||||||
|
const sepIdx = theme.indexOf('@', 1);
|
||||||
|
if (sepIdx === -1) {
|
||||||
|
return { name: theme };
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
name: theme.slice(0, sepIdx),
|
||||||
|
version: theme.slice(sepIdx + 1),
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
defaults
|
||||||
|
ios_saf 9
|
||||||
|
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# production
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
tmp/
|
||||||
|
lib/
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.idea/
|
||||||
|
.happypack
|
||||||
|
.DS_Store
|
||||||
|
*.swp
|
||||||
|
*.dia~
|
||||||
|
.ice
|
||||||
|
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
index.module.scss.d.ts
|
||||||
|
|
||||||
@ -0,0 +1 @@
|
|||||||
|
This project is generated by lowcode-code-generator & lowcode-solution-icejs3.
|
||||||
@ -0,0 +1,90 @@
|
|||||||
|
import { join } from 'path';
|
||||||
|
import { defineConfig } from '@ice/app';
|
||||||
|
import _ from 'lodash';
|
||||||
|
import fusion from '@ice/plugin-fusion';
|
||||||
|
import locales from '@ice/plugin-moment-locales';
|
||||||
|
import type { Plugin } from '@ice/app/esm/types';
|
||||||
|
|
||||||
|
interface PluginOptions {
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const plugin: Plugin<PluginOptions> = (options) => ({
|
||||||
|
// name 可选,插件名称
|
||||||
|
name: 'plugin-name',
|
||||||
|
// setup 必选,用于定制工程构建配置
|
||||||
|
setup: ({ onGetConfig, modifyUserConfig }) => {
|
||||||
|
modifyUserConfig('codeSplitting', 'page');
|
||||||
|
|
||||||
|
onGetConfig((config) => {
|
||||||
|
config.entry = {
|
||||||
|
web: join(process.cwd(), '.ice/entry.client.tsx'),
|
||||||
|
};
|
||||||
|
|
||||||
|
config.cssFilename = '[name].css';
|
||||||
|
|
||||||
|
config.configureWebpack = config.configureWebpack || [];
|
||||||
|
config.configureWebpack?.push((webpackConfig) => {
|
||||||
|
if (webpackConfig.output) {
|
||||||
|
webpackConfig.output.filename = '[name].js';
|
||||||
|
webpackConfig.output.chunkFilename = '[name].js';
|
||||||
|
}
|
||||||
|
return webpackConfig;
|
||||||
|
});
|
||||||
|
|
||||||
|
config.swcOptions = _.merge(config.swcOptions, {
|
||||||
|
compilationConfig: {
|
||||||
|
jsc: {
|
||||||
|
transform: {
|
||||||
|
react: {
|
||||||
|
runtime: 'classic',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 解决 webpack publicPath 问题
|
||||||
|
config.transforms = config.transforms || [];
|
||||||
|
config.transforms.push((source: string, id: string) => {
|
||||||
|
if (id.includes('.ice/entry.client.tsx')) {
|
||||||
|
let code = `
|
||||||
|
if (!__webpack_public_path__?.startsWith('http') && document.currentScript) {
|
||||||
|
// @ts-ignore
|
||||||
|
__webpack_public_path__ = document.currentScript.src.replace(/^(.*\\/)[^/]+$/, '$1');
|
||||||
|
window.__ICE_ASSETS_MANIFEST__ = window.__ICE_ASSETS_MANIFEST__ || {};
|
||||||
|
window.__ICE_ASSETS_MANIFEST__.publicPath = __webpack_public_path__;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
code += source;
|
||||||
|
return { code };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// The project config, see https://v3.ice.work/docs/guide/basic/config
|
||||||
|
const minify = process.env.NODE_ENV === 'production' ? 'swc' : false;
|
||||||
|
export default defineConfig(() => ({
|
||||||
|
ssr: false,
|
||||||
|
ssg: false,
|
||||||
|
minify,
|
||||||
|
|
||||||
|
externals: {
|
||||||
|
react: 'React',
|
||||||
|
'react-dom': 'ReactDOM',
|
||||||
|
'react-dom/client': 'ReactDOM',
|
||||||
|
'@alifd/next': 'Next',
|
||||||
|
lodash: 'var window._',
|
||||||
|
'@alilc/lowcode-engine': 'var window.AliLowCodeEngine',
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
fusion({
|
||||||
|
importStyle: true,
|
||||||
|
}),
|
||||||
|
locales(),
|
||||||
|
plugin(),
|
||||||
|
],
|
||||||
|
}));
|
||||||
|
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"name": "icejs3-demo-app",
|
||||||
|
"version": "0.1.5",
|
||||||
|
"description": "icejs 3 轻量级模板,使用 JavaScript,仅包含基础的 Layout。",
|
||||||
|
"dependencies": {
|
||||||
|
"moment": "^2.24.0",
|
||||||
|
"react": "^18.2.0",
|
||||||
|
"react-dom": "^18.2.0",
|
||||||
|
"react-router": "^6.9.0",
|
||||||
|
"react-router-dom": "^6.9.0",
|
||||||
|
"intl-messageformat": "^9.3.6",
|
||||||
|
"@alifd/next": "1.19.18",
|
||||||
|
"@ice/runtime": "^1.0.0",
|
||||||
|
"@alilc/lowcode-datasource-engine": "^1.0.0",
|
||||||
|
"@alilc/lowcode-datasource-url-params-handler": "^1.0.0",
|
||||||
|
"@alilc/lowcode-datasource-fetch-handler": "^1.0.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@ice/app": "^3.0.0",
|
||||||
|
"@types/react": "^18.0.0",
|
||||||
|
"@types/react-dom": "^18.0.0",
|
||||||
|
"@types/node": "^18.11.17",
|
||||||
|
"@ice/plugin-fusion": "^1.0.1",
|
||||||
|
"@ice/plugin-moment-locales": "^1.0.0",
|
||||||
|
"eslint": "^6.0.1",
|
||||||
|
"stylelint": "^13.2.0"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"start": "ice start",
|
||||||
|
"build": "ice build",
|
||||||
|
"lint": "npm run eslint && npm run stylelint",
|
||||||
|
"eslint": "eslint --cache --ext .js,.jsx ./",
|
||||||
|
"stylelint": "stylelint ./**/*.scss"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "http://gitlab.xxx.com/msd/leak-scan/tree/master"
|
||||||
|
},
|
||||||
|
"private": true,
|
||||||
|
"originTemplate": "@alifd/scaffold-lite-js"
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
import { defineAppConfig } from 'ice';
|
||||||
|
|
||||||
|
// App config, see https://v3.ice.work/docs/guide/basic/app
|
||||||
|
export default defineAppConfig(() => ({
|
||||||
|
// Set your configs here.
|
||||||
|
app: {
|
||||||
|
rootId: 'App',
|
||||||
|
},
|
||||||
|
router: {
|
||||||
|
type: 'browser',
|
||||||
|
basename: '/',
|
||||||
|
},
|
||||||
|
}));
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
const __$$constants = { ENV: 'prod', DOMAIN: 'xxx.xxx.com' };
|
||||||
|
|
||||||
|
export default __$$constants;
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Meta, Title, Links, Main, Scripts } from 'ice';
|
||||||
|
|
||||||
|
export default function Document() {
|
||||||
|
return (
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charSet="utf-8" />
|
||||||
|
<meta name="description" content="ice.js 3 lite scaffold" />
|
||||||
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
<link rel="stylesheet" href="//alifd.alicdn.com/npm/@alifd/next/1.21.16/next.min.css" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
|
||||||
|
<Meta />
|
||||||
|
<Title />
|
||||||
|
<Links />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<Main />
|
||||||
|
<script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react/18.2.0/umd/react.development.js" />
|
||||||
|
<script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react-dom/18.2.0/umd/react-dom.development.js" />
|
||||||
|
<script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/??react-router/6.9.0/react-router.production.min.js,react-router-dom/6.9.0/react-router-dom.production.min.js" />
|
||||||
|
<script crossOrigin="anonymous" src="//alifd.alicdn.com/npm/@alifd/next/1.26.15/next.min.js" />
|
||||||
|
<script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/prop-types/15.7.2/prop-types.js" />
|
||||||
|
<script crossOrigin="anonymous" src="//g.alicdn.com/platform/c/??lodash/4.6.1/lodash.min.js,immutable/3.7.6/dist/immutable.min.js" />
|
||||||
|
<Scripts />
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
// 引入默认全局样式
|
||||||
|
@import '@alifd/next/reset.scss';
|
||||||
|
|
||||||
|
body {
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.table {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
const i18nConfig = {};
|
||||||
|
|
||||||
|
let locale =
|
||||||
|
typeof navigator === 'object' && typeof navigator.language === 'string'
|
||||||
|
? navigator.language
|
||||||
|
: 'zh-CN';
|
||||||
|
|
||||||
|
const getLocale = () => locale;
|
||||||
|
|
||||||
|
const setLocale = (target) => {
|
||||||
|
locale = target;
|
||||||
|
};
|
||||||
|
|
||||||
|
const isEmptyVariables = (variables) =>
|
||||||
|
(Array.isArray(variables) && variables.length === 0) ||
|
||||||
|
(typeof variables === 'object' &&
|
||||||
|
(!variables || Object.keys(variables).length === 0));
|
||||||
|
|
||||||
|
// 按低代码规范里面的要求进行变量替换
|
||||||
|
const format = (msg, variables) =>
|
||||||
|
typeof msg === 'string'
|
||||||
|
? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? '')
|
||||||
|
: msg;
|
||||||
|
|
||||||
|
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
|
||||||
|
const msg =
|
||||||
|
i18nConfig[locale]?.[id] ??
|
||||||
|
i18nConfig[locale.replace('-', '_')]?.[id] ??
|
||||||
|
defaultMessage;
|
||||||
|
if (msg == null) {
|
||||||
|
console.warn('[i18n]: unknown message id: %o (locale=%o)', id, locale);
|
||||||
|
return fallback === undefined ? `${id}` : fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
return format(msg, variables);
|
||||||
|
};
|
||||||
|
|
||||||
|
const i18n = (id, params) => {
|
||||||
|
return i18nFormat({ id }, params);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 将国际化的一些方法注入到目标对象&上下文中
|
||||||
|
const _inject2 = (target) => {
|
||||||
|
target.i18n = i18n;
|
||||||
|
target.getLocale = getLocale;
|
||||||
|
target.setLocale = (locale) => {
|
||||||
|
setLocale(locale);
|
||||||
|
target.forceUpdate();
|
||||||
|
};
|
||||||
|
target._i18nText = (t) => {
|
||||||
|
// 优先取直接传过来的语料
|
||||||
|
const localMsg = t[locale] ?? t[String(locale).replace('-', '_')];
|
||||||
|
if (localMsg != null) {
|
||||||
|
return format(localMsg, t.params);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其次用项目级别的
|
||||||
|
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
|
||||||
|
if (projectMsg != null) {
|
||||||
|
return projectMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 兜底用 use 指定的或默认语言的
|
||||||
|
return format(t[t.use || 'zh-CN'] ?? t.en_US, t.params);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 注入到上下文中去
|
||||||
|
if (target._context && target._context !== target) {
|
||||||
|
Object.assign(target._context, {
|
||||||
|
i18n,
|
||||||
|
getLocale,
|
||||||
|
setLocale: target.setLocale,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import styles from './index.module.scss';
|
||||||
|
|
||||||
|
export default function Footer() {
|
||||||
|
return (
|
||||||
|
<p className={styles.footer}>
|
||||||
|
<span className={styles.logo}>Alibaba Fusion</span>
|
||||||
|
<br />
|
||||||
|
<span className={styles.copyright}>© 2019-现在 Alibaba Fusion & ICE</span>
|
||||||
|
</p>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
.footer {
|
||||||
|
line-height: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyright {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { Link } from 'ice';
|
||||||
|
import styles from './index.module.scss';
|
||||||
|
|
||||||
|
export default function Logo({ image, text, url }) {
|
||||||
|
return (
|
||||||
|
<div className="logo">
|
||||||
|
<Link to={url || '/'} className={styles.logo}>
|
||||||
|
{image && <img src={image} alt="logo" />}
|
||||||
|
<span>{text}</span>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
.logo{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: $color-text1-1;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 22px;
|
||||||
|
|
||||||
|
&:visited, &:link {
|
||||||
|
color: $color-text1-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 24px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { Link, useLocation } from 'ice';
|
||||||
|
import { Nav } from '@alifd/next';
|
||||||
|
import { asideMenuConfig } from '../../menuConfig';
|
||||||
|
|
||||||
|
const { SubNav } = Nav;
|
||||||
|
const NavItem = Nav.Item;
|
||||||
|
|
||||||
|
function getNavMenuItems(menusData) {
|
||||||
|
if (!menusData) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return menusData
|
||||||
|
.filter(item => item.name && !item.hideInMenu)
|
||||||
|
.map((item, index) => getSubMenuOrItem(item, index));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSubMenuOrItem(item, index) {
|
||||||
|
if (item.children && item.children.some(child => child.name)) {
|
||||||
|
const childrenItems = getNavMenuItems(item.children);
|
||||||
|
|
||||||
|
if (childrenItems && childrenItems.length > 0) {
|
||||||
|
const subNav = (
|
||||||
|
<SubNav key={index} icon={item.icon} label={item.name}>
|
||||||
|
{childrenItems}
|
||||||
|
</SubNav>
|
||||||
|
);
|
||||||
|
return subNav;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const navItem = (
|
||||||
|
<NavItem key={item.path} icon={item.icon}>
|
||||||
|
<Link to={item.path}>{item.name}</Link>
|
||||||
|
</NavItem>
|
||||||
|
);
|
||||||
|
return navItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Navigation = (props, context) => {
|
||||||
|
const location = useLocation();
|
||||||
|
const { pathname } = location;
|
||||||
|
const { isCollapse } = context;
|
||||||
|
return (
|
||||||
|
<Nav
|
||||||
|
type="primary"
|
||||||
|
selectedKeys={[pathname]}
|
||||||
|
defaultSelectedKeys={[pathname]}
|
||||||
|
embeddable
|
||||||
|
openMode="single"
|
||||||
|
iconOnly={isCollapse}
|
||||||
|
hasArrow={false}
|
||||||
|
mode={isCollapse ? 'popup' : 'inline'}
|
||||||
|
>
|
||||||
|
{getNavMenuItems(asideMenuConfig)}
|
||||||
|
</Nav>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Navigation.contextTypes = {
|
||||||
|
isCollapse: PropTypes.bool,
|
||||||
|
};
|
||||||
|
export default Navigation;
|
||||||
|
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Shell, ConfigProvider } from '@alifd/next';
|
||||||
|
import PageNav from './components/PageNav';
|
||||||
|
import Logo from './components/Logo';
|
||||||
|
import Footer from './components/Footer';
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
const throttle = function(type, name, obj = window) {
|
||||||
|
let running = false;
|
||||||
|
|
||||||
|
const func = () => {
|
||||||
|
if (running) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
running = true;
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
obj.dispatchEvent(new CustomEvent(name));
|
||||||
|
running = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
obj.addEventListener(type, func);
|
||||||
|
};
|
||||||
|
|
||||||
|
throttle('resize', 'optimizedResize');
|
||||||
|
})();
|
||||||
|
|
||||||
|
export default function BasicLayout({ children }) {
|
||||||
|
const getDevice = width => {
|
||||||
|
const isPhone =
|
||||||
|
typeof navigator !== 'undefined' && navigator && navigator.userAgent.match(/phone/gi);
|
||||||
|
|
||||||
|
if (width < 680 || isPhone) {
|
||||||
|
return 'phone';
|
||||||
|
}
|
||||||
|
if (width < 1280 && width > 680) {
|
||||||
|
return 'tablet';
|
||||||
|
}
|
||||||
|
return 'desktop';
|
||||||
|
};
|
||||||
|
|
||||||
|
const [device, setDevice] = useState(getDevice(NaN));
|
||||||
|
window.addEventListener('optimizedResize', e => {
|
||||||
|
setDevice(getDevice(e && e.target && e.target.innerWidth));
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<ConfigProvider device={device}>
|
||||||
|
<Shell
|
||||||
|
type="dark"
|
||||||
|
style={{
|
||||||
|
minHeight: '100vh',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Shell.Branding>
|
||||||
|
<Logo
|
||||||
|
image="https://img.alicdn.com/tfs/TB1.ZBecq67gK0jSZFHXXa9jVXa-904-826.png"
|
||||||
|
text="Logo"
|
||||||
|
/>
|
||||||
|
</Shell.Branding>
|
||||||
|
<Shell.Navigation
|
||||||
|
direction="hoz"
|
||||||
|
style={{
|
||||||
|
marginRight: 10,
|
||||||
|
}}
|
||||||
|
></Shell.Navigation>
|
||||||
|
<Shell.Action></Shell.Action>
|
||||||
|
<Shell.Navigation>
|
||||||
|
<PageNav />
|
||||||
|
</Shell.Navigation>
|
||||||
|
|
||||||
|
<Shell.Content>{children}</Shell.Content>
|
||||||
|
<Shell.Footer>
|
||||||
|
<Footer />
|
||||||
|
</Shell.Footer>
|
||||||
|
</Shell>
|
||||||
|
</ConfigProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
const headerMenuConfig = [];
|
||||||
|
const asideMenuConfig = [
|
||||||
|
{
|
||||||
|
name: 'Dashboard',
|
||||||
|
path: '/',
|
||||||
|
icon: 'smile',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
export { headerMenuConfig, asideMenuConfig };
|
||||||
|
|
||||||
@ -0,0 +1,195 @@
|
|||||||
|
// 注意: 出码引擎注入的临时变量默认都以 "__$$" 开头,禁止在搭建的代码中直接访问。
|
||||||
|
// 例外:react 框架的导出名和各种组件名除外。
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { Form, Input, NumberPicker, Select, Button } from '@alifd/next';
|
||||||
|
|
||||||
|
import { createUrlParamsHandler as __$$createUrlParamsRequestHandler } from '@alilc/lowcode-datasource-url-params-handler';
|
||||||
|
|
||||||
|
import { createFetchHandler as __$$createFetchRequestHandler } from '@alilc/lowcode-datasource-fetch-handler';
|
||||||
|
|
||||||
|
import { create as __$$createDataSourceEngine } from '@alilc/lowcode-datasource-engine/runtime';
|
||||||
|
|
||||||
|
import utils, { RefsManager } from '../../utils';
|
||||||
|
|
||||||
|
import * as __$$i18n from '../../i18n';
|
||||||
|
|
||||||
|
import __$$constants from '../../constants';
|
||||||
|
|
||||||
|
import './index.css';
|
||||||
|
|
||||||
|
class Test$$Page extends React.Component {
|
||||||
|
_context = this;
|
||||||
|
|
||||||
|
_dataSourceConfig = this._defineDataSourceConfig();
|
||||||
|
_dataSourceEngine = __$$createDataSourceEngine(this._dataSourceConfig, this, {
|
||||||
|
runtimeConfig: true,
|
||||||
|
requestHandlersMap: {
|
||||||
|
urlParams: __$$createUrlParamsRequestHandler(window.location.search),
|
||||||
|
fetch: __$$createFetchRequestHandler(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
get dataSourceMap() {
|
||||||
|
return this._dataSourceEngine.dataSourceMap || {};
|
||||||
|
}
|
||||||
|
|
||||||
|
reloadDataSource = async () => {
|
||||||
|
await this._dataSourceEngine.reloadDataSource();
|
||||||
|
};
|
||||||
|
|
||||||
|
get constants() {
|
||||||
|
return __$$constants || {};
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(props, context) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.utils = utils;
|
||||||
|
|
||||||
|
this._refsManager = new RefsManager();
|
||||||
|
|
||||||
|
__$$i18n._inject2(this);
|
||||||
|
|
||||||
|
this.state = { text: 'outter' };
|
||||||
|
}
|
||||||
|
|
||||||
|
$ = (refName) => {
|
||||||
|
return this._refsManager.get(refName);
|
||||||
|
};
|
||||||
|
|
||||||
|
$$ = (refName) => {
|
||||||
|
return this._refsManager.getAll(refName);
|
||||||
|
};
|
||||||
|
|
||||||
|
_defineDataSourceConfig() {
|
||||||
|
const _this = this;
|
||||||
|
return {
|
||||||
|
list: [
|
||||||
|
{
|
||||||
|
id: 'urlParams',
|
||||||
|
type: 'urlParams',
|
||||||
|
isInit: function () {
|
||||||
|
return undefined;
|
||||||
|
}.bind(_this),
|
||||||
|
options: function () {
|
||||||
|
return undefined;
|
||||||
|
}.bind(_this),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'user',
|
||||||
|
type: 'fetch',
|
||||||
|
options: function () {
|
||||||
|
return {
|
||||||
|
method: 'GET',
|
||||||
|
uri: 'https://shs.xxx.com/mock/1458/demo/user',
|
||||||
|
isSync: true,
|
||||||
|
};
|
||||||
|
}.bind(_this),
|
||||||
|
dataHandler: function (response) {
|
||||||
|
if (!response.data.success) {
|
||||||
|
throw new Error(response.data.message);
|
||||||
|
}
|
||||||
|
return response.data.data;
|
||||||
|
},
|
||||||
|
isInit: function () {
|
||||||
|
return undefined;
|
||||||
|
}.bind(_this),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'orders',
|
||||||
|
type: 'fetch',
|
||||||
|
options: function () {
|
||||||
|
return {
|
||||||
|
method: 'GET',
|
||||||
|
uri: 'https://shs.xxx.com/mock/1458/demo/orders',
|
||||||
|
isSync: true,
|
||||||
|
};
|
||||||
|
}.bind(_this),
|
||||||
|
dataHandler: function (response) {
|
||||||
|
if (!response.data.success) {
|
||||||
|
throw new Error(response.data.message);
|
||||||
|
}
|
||||||
|
return response.data.data.result;
|
||||||
|
},
|
||||||
|
isInit: function () {
|
||||||
|
return undefined;
|
||||||
|
}.bind(_this),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
dataHandler: function (dataMap) {
|
||||||
|
console.info('All datasources loaded:', dataMap);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this._dataSourceEngine.reloadDataSource();
|
||||||
|
|
||||||
|
console.log('componentDidMount');
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const __$$context = this._context || this;
|
||||||
|
const { state } = __$$context;
|
||||||
|
return (
|
||||||
|
<div ref={this._refsManager.linkRef('outterView')} autoLoading={true}>
|
||||||
|
<Form
|
||||||
|
labelCol={__$$eval(() => this.state.colNum)}
|
||||||
|
style={{}}
|
||||||
|
ref={this._refsManager.linkRef('testForm')}
|
||||||
|
>
|
||||||
|
<Form.Item label="姓名:" name="name" initValue="李雷">
|
||||||
|
<Input placeholder="请输入" size="medium" style={{ width: 320 }} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="年龄:" name="age" initValue="22">
|
||||||
|
<NumberPicker size="medium" type="normal" />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="职业:" name="profession">
|
||||||
|
<Select
|
||||||
|
dataSource={[
|
||||||
|
{ label: '教师', value: 't' },
|
||||||
|
{ label: '医生', value: 'd' },
|
||||||
|
{ label: '歌手', value: 's' },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<div style={{ textAlign: 'center' }}>
|
||||||
|
<Button.Group>
|
||||||
|
{__$$evalArray(() => ['a', 'b', 'c']).map((item, index) =>
|
||||||
|
((__$$context) =>
|
||||||
|
!!__$$eval(() => index >= 1) && (
|
||||||
|
<Button type="primary" style={{ margin: '0 5px 0 5px' }}>
|
||||||
|
{__$$eval(() => item)}
|
||||||
|
</Button>
|
||||||
|
))(__$$createChildContext(__$$context, { item, index }))
|
||||||
|
)}
|
||||||
|
</Button.Group>
|
||||||
|
</div>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Test$$Page;
|
||||||
|
|
||||||
|
function __$$eval(expr) {
|
||||||
|
try {
|
||||||
|
return expr();
|
||||||
|
} catch (error) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function __$$evalArray(expr) {
|
||||||
|
const res = __$$eval(expr);
|
||||||
|
return Array.isArray(res) ? res : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function __$$createChildContext(oldContext, ext) {
|
||||||
|
const childContext = {
|
||||||
|
...oldContext,
|
||||||
|
...ext,
|
||||||
|
};
|
||||||
|
childContext.__proto__ = oldContext;
|
||||||
|
return childContext;
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
import { Outlet } from 'ice';
|
||||||
|
import BasicLayout from '@/layouts/BasicLayout';
|
||||||
|
|
||||||
|
export default function Layout() {
|
||||||
|
return (
|
||||||
|
<BasicLayout>
|
||||||
|
<Outlet />
|
||||||
|
</BasicLayout>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
/// <reference types="@ice/app/types" />
|
||||||
|
|
||||||
|
export {};
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
g_config: Record<string, any>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
import { createRef } from 'react';
|
||||||
|
|
||||||
|
export class RefsManager {
|
||||||
|
constructor() {
|
||||||
|
this.refInsStore = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
clearNullRefs() {
|
||||||
|
Object.keys(this.refInsStore).forEach((refName) => {
|
||||||
|
const filteredInsList = this.refInsStore[refName].filter(
|
||||||
|
(insRef) => !!insRef.current
|
||||||
|
);
|
||||||
|
if (filteredInsList.length > 0) {
|
||||||
|
this.refInsStore[refName] = filteredInsList;
|
||||||
|
} else {
|
||||||
|
delete this.refInsStore[refName];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get(refName) {
|
||||||
|
this.clearNullRefs();
|
||||||
|
if (this.refInsStore[refName] && this.refInsStore[refName].length > 0) {
|
||||||
|
return this.refInsStore[refName][0].current;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
getAll(refName) {
|
||||||
|
this.clearNullRefs();
|
||||||
|
if (this.refInsStore[refName] && this.refInsStore[refName].length > 0) {
|
||||||
|
return this.refInsStore[refName].map((i) => i.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
linkRef(refName) {
|
||||||
|
const refIns = createRef();
|
||||||
|
this.refInsStore[refName] = this.refInsStore[refName] || [];
|
||||||
|
this.refInsStore[refName].push(refIns);
|
||||||
|
return refIns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {};
|
||||||
276
modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo1/schema.json5
vendored
Normal file
276
modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo1/schema.json5
vendored
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
{
|
||||||
|
"version": "1.0.0",
|
||||||
|
"componentsMap": [
|
||||||
|
{
|
||||||
|
"componentName": "Button",
|
||||||
|
"package": "@alifd/next",
|
||||||
|
"version": "1.19.18",
|
||||||
|
"destructuring": true,
|
||||||
|
"exportName": "Button"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentName": "Button.Group",
|
||||||
|
"package": "@alifd/next",
|
||||||
|
"version": "1.19.18",
|
||||||
|
"destructuring": true,
|
||||||
|
"exportName": "Button",
|
||||||
|
"subName": "Group"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentName": "Input",
|
||||||
|
"package": "@alifd/next",
|
||||||
|
"version": "1.19.18",
|
||||||
|
"destructuring": true,
|
||||||
|
"exportName": "Input"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentName": "Form",
|
||||||
|
"package": "@alifd/next",
|
||||||
|
"version": "1.19.18",
|
||||||
|
"destructuring": true,
|
||||||
|
"exportName": "Form"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentName": "Form.Item",
|
||||||
|
"package": "@alifd/next",
|
||||||
|
"version": "1.19.18",
|
||||||
|
"destructuring": true,
|
||||||
|
"exportName": "Form",
|
||||||
|
"subName": "Item"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentName": "NumberPicker",
|
||||||
|
"package": "@alifd/next",
|
||||||
|
"version": "1.19.18",
|
||||||
|
"destructuring": true,
|
||||||
|
"exportName": "NumberPicker"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentName": "Select",
|
||||||
|
"package": "@alifd/next",
|
||||||
|
"version": "1.19.18",
|
||||||
|
"destructuring": true,
|
||||||
|
"exportName": "Select"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"componentsTree": [
|
||||||
|
{
|
||||||
|
"componentName": "Page",
|
||||||
|
"id": "node$1",
|
||||||
|
"meta": {
|
||||||
|
"title": "测试",
|
||||||
|
"router": "/"
|
||||||
|
},
|
||||||
|
"props": {
|
||||||
|
"ref": "outterView",
|
||||||
|
"autoLoading": true
|
||||||
|
},
|
||||||
|
"fileName": "test",
|
||||||
|
"state": {
|
||||||
|
"text": "outter"
|
||||||
|
},
|
||||||
|
"lifeCycles": {
|
||||||
|
"componentDidMount": {
|
||||||
|
"type": "JSFunction",
|
||||||
|
"value": "function() { console.log('componentDidMount'); }"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dataSource: {
|
||||||
|
list: [
|
||||||
|
{
|
||||||
|
id: 'urlParams',
|
||||||
|
type: 'urlParams',
|
||||||
|
},
|
||||||
|
// 示例数据源:https://shs.xxx.com/mock/1458/demo/user
|
||||||
|
{
|
||||||
|
id: 'user',
|
||||||
|
type: 'fetch',
|
||||||
|
options: {
|
||||||
|
method: 'GET',
|
||||||
|
uri: 'https://shs.xxx.com/mock/1458/demo/user',
|
||||||
|
isSync: true,
|
||||||
|
},
|
||||||
|
dataHandler: {
|
||||||
|
type: 'JSExpression',
|
||||||
|
value: 'function (response) {\nif (!response.data.success){\n throw new Error(response.data.message);\n }\n return response.data.data;\n}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 示例数据源:https://shs.xxx.com/mock/1458/demo/orders
|
||||||
|
{
|
||||||
|
id: 'orders',
|
||||||
|
type: 'fetch',
|
||||||
|
options: {
|
||||||
|
method: 'GET',
|
||||||
|
uri: "https://shs.xxx.com/mock/1458/demo/orders",
|
||||||
|
isSync: true,
|
||||||
|
},
|
||||||
|
dataHandler: {
|
||||||
|
type: 'JSExpression',
|
||||||
|
value: 'function (response) {\nif (!response.data.success){\n throw new Error(response.data.message);\n }\n return response.data.data.result;\n}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
dataHandler: {
|
||||||
|
type: 'JSExpression',
|
||||||
|
value: 'function (dataMap) {\n console.info("All datasources loaded:", dataMap);\n}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"componentName": "Form",
|
||||||
|
"id": "node$2",
|
||||||
|
"props": {
|
||||||
|
"labelCol": {
|
||||||
|
"type": "JSExpression",
|
||||||
|
"value": "this.state.colNum"
|
||||||
|
},
|
||||||
|
"style": {},
|
||||||
|
"ref": "testForm"
|
||||||
|
},
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"componentName": "Form.Item",
|
||||||
|
"id": "node$3",
|
||||||
|
"props": {
|
||||||
|
"label": "姓名:",
|
||||||
|
"name": "name",
|
||||||
|
"initValue": "李雷"
|
||||||
|
},
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"componentName": "Input",
|
||||||
|
"id": "node$4",
|
||||||
|
"props": {
|
||||||
|
"placeholder": "请输入",
|
||||||
|
"size": "medium",
|
||||||
|
"style": {
|
||||||
|
"width": 320
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentName": "Form.Item",
|
||||||
|
"id": "node$5",
|
||||||
|
"props": {
|
||||||
|
"label": "年龄:",
|
||||||
|
"name": "age",
|
||||||
|
"initValue": "22"
|
||||||
|
},
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"componentName": "NumberPicker",
|
||||||
|
"id": "node$6",
|
||||||
|
"props": {
|
||||||
|
"size": "medium",
|
||||||
|
"type": "normal"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentName": "Form.Item",
|
||||||
|
"id": "node$7",
|
||||||
|
"props": {
|
||||||
|
"label": "职业:",
|
||||||
|
"name": "profession"
|
||||||
|
},
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"componentName": "Select",
|
||||||
|
"id": "node$8",
|
||||||
|
"props": {
|
||||||
|
"dataSource": [
|
||||||
|
{
|
||||||
|
"label": "教师",
|
||||||
|
"value": "t"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "医生",
|
||||||
|
"value": "d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "歌手",
|
||||||
|
"value": "s"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentName": "Div",
|
||||||
|
"id": "node$9",
|
||||||
|
"props": {
|
||||||
|
"style": {
|
||||||
|
"textAlign": "center"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"componentName": "Button.Group",
|
||||||
|
"id": "node$a",
|
||||||
|
"props": {},
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"componentName": "Button",
|
||||||
|
"id": "node$b",
|
||||||
|
"condition": {
|
||||||
|
"type": "JSExpression",
|
||||||
|
"value": "this.index >= 1"
|
||||||
|
},
|
||||||
|
"loop": ["a", "b", "c"],
|
||||||
|
"props": {
|
||||||
|
"type": "primary",
|
||||||
|
"style": {
|
||||||
|
"margin": "0 5px 0 5px"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "JSExpression",
|
||||||
|
"value": "this.item"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"constants": {
|
||||||
|
"ENV": "prod",
|
||||||
|
"DOMAIN": "xxx.xxx.com"
|
||||||
|
},
|
||||||
|
"css": "body {font-size: 12px;} .table { width: 100px;}",
|
||||||
|
"config": {
|
||||||
|
"sdkVersion": "1.0.3",
|
||||||
|
"historyMode": "hash",
|
||||||
|
"targetRootID": "J_Container",
|
||||||
|
"layout": {
|
||||||
|
"componentName": "BasicLayout",
|
||||||
|
"props": {
|
||||||
|
"logo": "...",
|
||||||
|
"name": "测试网站"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"theme": {
|
||||||
|
"package": "@alife/theme-fusion",
|
||||||
|
"version": "^0.1.0",
|
||||||
|
"primary": "#ff9966"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
"name": "demo应用",
|
||||||
|
"git_group": "appGroup",
|
||||||
|
"project_name": "app_demo",
|
||||||
|
"description": "这是一个测试应用",
|
||||||
|
"spma": "spa23d",
|
||||||
|
"creator": "月飞"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
defaults
|
||||||
|
ios_saf 9
|
||||||
|
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# production
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
tmp/
|
||||||
|
lib/
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.idea/
|
||||||
|
.happypack
|
||||||
|
.DS_Store
|
||||||
|
*.swp
|
||||||
|
*.dia~
|
||||||
|
.ice
|
||||||
|
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
index.module.scss.d.ts
|
||||||
|
|
||||||
@ -0,0 +1 @@
|
|||||||
|
This project is generated by lowcode-code-generator & lowcode-solution-icejs3.
|
||||||
@ -0,0 +1,90 @@
|
|||||||
|
import { join } from 'path';
|
||||||
|
import { defineConfig } from '@ice/app';
|
||||||
|
import _ from 'lodash';
|
||||||
|
import fusion from '@ice/plugin-fusion';
|
||||||
|
import locales from '@ice/plugin-moment-locales';
|
||||||
|
import type { Plugin } from '@ice/app/esm/types';
|
||||||
|
|
||||||
|
interface PluginOptions {
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const plugin: Plugin<PluginOptions> = (options) => ({
|
||||||
|
// name 可选,插件名称
|
||||||
|
name: 'plugin-name',
|
||||||
|
// setup 必选,用于定制工程构建配置
|
||||||
|
setup: ({ onGetConfig, modifyUserConfig }) => {
|
||||||
|
modifyUserConfig('codeSplitting', 'page');
|
||||||
|
|
||||||
|
onGetConfig((config) => {
|
||||||
|
config.entry = {
|
||||||
|
web: join(process.cwd(), '.ice/entry.client.tsx'),
|
||||||
|
};
|
||||||
|
|
||||||
|
config.cssFilename = '[name].css';
|
||||||
|
|
||||||
|
config.configureWebpack = config.configureWebpack || [];
|
||||||
|
config.configureWebpack?.push((webpackConfig) => {
|
||||||
|
if (webpackConfig.output) {
|
||||||
|
webpackConfig.output.filename = '[name].js';
|
||||||
|
webpackConfig.output.chunkFilename = '[name].js';
|
||||||
|
}
|
||||||
|
return webpackConfig;
|
||||||
|
});
|
||||||
|
|
||||||
|
config.swcOptions = _.merge(config.swcOptions, {
|
||||||
|
compilationConfig: {
|
||||||
|
jsc: {
|
||||||
|
transform: {
|
||||||
|
react: {
|
||||||
|
runtime: 'classic',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 解决 webpack publicPath 问题
|
||||||
|
config.transforms = config.transforms || [];
|
||||||
|
config.transforms.push((source: string, id: string) => {
|
||||||
|
if (id.includes('.ice/entry.client.tsx')) {
|
||||||
|
let code = `
|
||||||
|
if (!__webpack_public_path__?.startsWith('http') && document.currentScript) {
|
||||||
|
// @ts-ignore
|
||||||
|
__webpack_public_path__ = document.currentScript.src.replace(/^(.*\\/)[^/]+$/, '$1');
|
||||||
|
window.__ICE_ASSETS_MANIFEST__ = window.__ICE_ASSETS_MANIFEST__ || {};
|
||||||
|
window.__ICE_ASSETS_MANIFEST__.publicPath = __webpack_public_path__;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
code += source;
|
||||||
|
return { code };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// The project config, see https://v3.ice.work/docs/guide/basic/config
|
||||||
|
const minify = process.env.NODE_ENV === 'production' ? 'swc' : false;
|
||||||
|
export default defineConfig(() => ({
|
||||||
|
ssr: false,
|
||||||
|
ssg: false,
|
||||||
|
minify,
|
||||||
|
|
||||||
|
externals: {
|
||||||
|
react: 'React',
|
||||||
|
'react-dom': 'ReactDOM',
|
||||||
|
'react-dom/client': 'ReactDOM',
|
||||||
|
'@alifd/next': 'Next',
|
||||||
|
lodash: 'var window._',
|
||||||
|
'@alilc/lowcode-engine': 'var window.AliLowCodeEngine',
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
fusion({
|
||||||
|
importStyle: true,
|
||||||
|
}),
|
||||||
|
locales(),
|
||||||
|
plugin(),
|
||||||
|
],
|
||||||
|
}));
|
||||||
|
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
{
|
||||||
|
"name": "icejs3-demo-app",
|
||||||
|
"version": "0.1.5",
|
||||||
|
"description": "icejs 3 轻量级模板,使用 JavaScript,仅包含基础的 Layout。",
|
||||||
|
"dependencies": {
|
||||||
|
"moment": "^2.24.0",
|
||||||
|
"react": "^18.2.0",
|
||||||
|
"react-dom": "^18.2.0",
|
||||||
|
"react-router": "^6.9.0",
|
||||||
|
"react-router-dom": "^6.9.0",
|
||||||
|
"intl-messageformat": "^9.3.6",
|
||||||
|
"@alifd/next": "1.26.15",
|
||||||
|
"@ice/runtime": "^1.0.0",
|
||||||
|
"@alilc/lowcode-datasource-engine": "^1.0.0",
|
||||||
|
"@alilc/lowcode-datasource-url-params-handler": "^1.0.0",
|
||||||
|
"@alilc/b6-page": "^0.1.0",
|
||||||
|
"@alilc/b6-text": "^0.1.0",
|
||||||
|
"@alilc/b6-compact-legao-builtin": "1.x",
|
||||||
|
"antd": "3.x",
|
||||||
|
"@alilc/b6-util-mocks": "1.x"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@ice/app": "^3.0.0",
|
||||||
|
"@types/react": "^18.0.0",
|
||||||
|
"@types/react-dom": "^18.0.0",
|
||||||
|
"@types/node": "^18.11.17",
|
||||||
|
"@ice/plugin-fusion": "^1.0.1",
|
||||||
|
"@ice/plugin-moment-locales": "^1.0.0",
|
||||||
|
"eslint": "^6.0.1",
|
||||||
|
"stylelint": "^13.2.0"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"start": "ice start",
|
||||||
|
"build": "ice build",
|
||||||
|
"lint": "npm run eslint && npm run stylelint",
|
||||||
|
"eslint": "eslint --cache --ext .js,.jsx ./",
|
||||||
|
"stylelint": "stylelint ./**/*.scss"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "http://gitlab.xxx.com/msd/leak-scan/tree/master"
|
||||||
|
},
|
||||||
|
"private": true,
|
||||||
|
"originTemplate": "@alifd/scaffold-lite-js"
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
import { defineAppConfig } from 'ice';
|
||||||
|
|
||||||
|
// App config, see https://v3.ice.work/docs/guide/basic/app
|
||||||
|
export default defineAppConfig(() => ({
|
||||||
|
// Set your configs here.
|
||||||
|
app: {
|
||||||
|
rootId: 'App',
|
||||||
|
},
|
||||||
|
router: {
|
||||||
|
type: 'browser',
|
||||||
|
basename: '/',
|
||||||
|
},
|
||||||
|
}));
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
const __$$constants = {};
|
||||||
|
|
||||||
|
export default __$$constants;
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Meta, Title, Links, Main, Scripts } from 'ice';
|
||||||
|
|
||||||
|
export default function Document() {
|
||||||
|
return (
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charSet="utf-8" />
|
||||||
|
<meta name="description" content="ice.js 3 lite scaffold" />
|
||||||
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
<link rel="stylesheet" href="//alifd.alicdn.com/npm/@alifd/next/1.21.16/next.min.css" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
|
||||||
|
<Meta />
|
||||||
|
<Title />
|
||||||
|
<Links />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<Main />
|
||||||
|
<script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react/18.2.0/umd/react.development.js" />
|
||||||
|
<script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react-dom/18.2.0/umd/react-dom.development.js" />
|
||||||
|
<script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/??react-router/6.9.0/react-router.production.min.js,react-router-dom/6.9.0/react-router-dom.production.min.js" />
|
||||||
|
<script crossOrigin="anonymous" src="//alifd.alicdn.com/npm/@alifd/next/1.26.15/next.min.js" />
|
||||||
|
<script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/prop-types/15.7.2/prop-types.js" />
|
||||||
|
<script crossOrigin="anonymous" src="//g.alicdn.com/platform/c/??lodash/4.6.1/lodash.min.js,immutable/3.7.6/dist/immutable.min.js" />
|
||||||
|
<Scripts />
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
// 引入默认全局样式
|
||||||
|
@import '@alifd/next/reset.scss';
|
||||||
|
|
||||||
|
body {
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
}
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
const i18nConfig = {};
|
||||||
|
|
||||||
|
let locale =
|
||||||
|
typeof navigator === 'object' && typeof navigator.language === 'string'
|
||||||
|
? navigator.language
|
||||||
|
: 'zh-CN';
|
||||||
|
|
||||||
|
const getLocale = () => locale;
|
||||||
|
|
||||||
|
const setLocale = (target) => {
|
||||||
|
locale = target;
|
||||||
|
};
|
||||||
|
|
||||||
|
const isEmptyVariables = (variables) =>
|
||||||
|
(Array.isArray(variables) && variables.length === 0) ||
|
||||||
|
(typeof variables === 'object' &&
|
||||||
|
(!variables || Object.keys(variables).length === 0));
|
||||||
|
|
||||||
|
// 按低代码规范里面的要求进行变量替换
|
||||||
|
const format = (msg, variables) =>
|
||||||
|
typeof msg === 'string'
|
||||||
|
? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? '')
|
||||||
|
: msg;
|
||||||
|
|
||||||
|
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
|
||||||
|
const msg =
|
||||||
|
i18nConfig[locale]?.[id] ??
|
||||||
|
i18nConfig[locale.replace('-', '_')]?.[id] ??
|
||||||
|
defaultMessage;
|
||||||
|
if (msg == null) {
|
||||||
|
console.warn('[i18n]: unknown message id: %o (locale=%o)', id, locale);
|
||||||
|
return fallback === undefined ? `${id}` : fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
return format(msg, variables);
|
||||||
|
};
|
||||||
|
|
||||||
|
const i18n = (id, params) => {
|
||||||
|
return i18nFormat({ id }, params);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 将国际化的一些方法注入到目标对象&上下文中
|
||||||
|
const _inject2 = (target) => {
|
||||||
|
target.i18n = i18n;
|
||||||
|
target.getLocale = getLocale;
|
||||||
|
target.setLocale = (locale) => {
|
||||||
|
setLocale(locale);
|
||||||
|
target.forceUpdate();
|
||||||
|
};
|
||||||
|
target._i18nText = (t) => {
|
||||||
|
// 优先取直接传过来的语料
|
||||||
|
const localMsg = t[locale] ?? t[String(locale).replace('-', '_')];
|
||||||
|
if (localMsg != null) {
|
||||||
|
return format(localMsg, t.params);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其次用项目级别的
|
||||||
|
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
|
||||||
|
if (projectMsg != null) {
|
||||||
|
return projectMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 兜底用 use 指定的或默认语言的
|
||||||
|
return format(t[t.use || 'zh-CN'] ?? t.en_US, t.params);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 注入到上下文中去
|
||||||
|
if (target._context && target._context !== target) {
|
||||||
|
Object.assign(target._context, {
|
||||||
|
i18n,
|
||||||
|
getLocale,
|
||||||
|
setLocale: target.setLocale,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import styles from './index.module.scss';
|
||||||
|
|
||||||
|
export default function Footer() {
|
||||||
|
return (
|
||||||
|
<p className={styles.footer}>
|
||||||
|
<span className={styles.logo}>Alibaba Fusion</span>
|
||||||
|
<br />
|
||||||
|
<span className={styles.copyright}>© 2019-现在 Alibaba Fusion & ICE</span>
|
||||||
|
</p>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
.footer {
|
||||||
|
line-height: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyright {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { Link } from 'ice';
|
||||||
|
import styles from './index.module.scss';
|
||||||
|
|
||||||
|
export default function Logo({ image, text, url }) {
|
||||||
|
return (
|
||||||
|
<div className="logo">
|
||||||
|
<Link to={url || '/'} className={styles.logo}>
|
||||||
|
{image && <img src={image} alt="logo" />}
|
||||||
|
<span>{text}</span>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
.logo{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: $color-text1-1;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 22px;
|
||||||
|
|
||||||
|
&:visited, &:link {
|
||||||
|
color: $color-text1-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 24px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { Link, useLocation } from 'ice';
|
||||||
|
import { Nav } from '@alifd/next';
|
||||||
|
import { asideMenuConfig } from '../../menuConfig';
|
||||||
|
|
||||||
|
const { SubNav } = Nav;
|
||||||
|
const NavItem = Nav.Item;
|
||||||
|
|
||||||
|
function getNavMenuItems(menusData) {
|
||||||
|
if (!menusData) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return menusData
|
||||||
|
.filter(item => item.name && !item.hideInMenu)
|
||||||
|
.map((item, index) => getSubMenuOrItem(item, index));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSubMenuOrItem(item, index) {
|
||||||
|
if (item.children && item.children.some(child => child.name)) {
|
||||||
|
const childrenItems = getNavMenuItems(item.children);
|
||||||
|
|
||||||
|
if (childrenItems && childrenItems.length > 0) {
|
||||||
|
const subNav = (
|
||||||
|
<SubNav key={index} icon={item.icon} label={item.name}>
|
||||||
|
{childrenItems}
|
||||||
|
</SubNav>
|
||||||
|
);
|
||||||
|
return subNav;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const navItem = (
|
||||||
|
<NavItem key={item.path} icon={item.icon}>
|
||||||
|
<Link to={item.path}>{item.name}</Link>
|
||||||
|
</NavItem>
|
||||||
|
);
|
||||||
|
return navItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Navigation = (props, context) => {
|
||||||
|
const location = useLocation();
|
||||||
|
const { pathname } = location;
|
||||||
|
const { isCollapse } = context;
|
||||||
|
return (
|
||||||
|
<Nav
|
||||||
|
type="primary"
|
||||||
|
selectedKeys={[pathname]}
|
||||||
|
defaultSelectedKeys={[pathname]}
|
||||||
|
embeddable
|
||||||
|
openMode="single"
|
||||||
|
iconOnly={isCollapse}
|
||||||
|
hasArrow={false}
|
||||||
|
mode={isCollapse ? 'popup' : 'inline'}
|
||||||
|
>
|
||||||
|
{getNavMenuItems(asideMenuConfig)}
|
||||||
|
</Nav>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Navigation.contextTypes = {
|
||||||
|
isCollapse: PropTypes.bool,
|
||||||
|
};
|
||||||
|
export default Navigation;
|
||||||
|
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Shell, ConfigProvider } from '@alifd/next';
|
||||||
|
import PageNav from './components/PageNav';
|
||||||
|
import Logo from './components/Logo';
|
||||||
|
import Footer from './components/Footer';
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
const throttle = function(type, name, obj = window) {
|
||||||
|
let running = false;
|
||||||
|
|
||||||
|
const func = () => {
|
||||||
|
if (running) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
running = true;
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
obj.dispatchEvent(new CustomEvent(name));
|
||||||
|
running = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
obj.addEventListener(type, func);
|
||||||
|
};
|
||||||
|
|
||||||
|
throttle('resize', 'optimizedResize');
|
||||||
|
})();
|
||||||
|
|
||||||
|
export default function BasicLayout({ children }) {
|
||||||
|
const getDevice = width => {
|
||||||
|
const isPhone =
|
||||||
|
typeof navigator !== 'undefined' && navigator && navigator.userAgent.match(/phone/gi);
|
||||||
|
|
||||||
|
if (width < 680 || isPhone) {
|
||||||
|
return 'phone';
|
||||||
|
}
|
||||||
|
if (width < 1280 && width > 680) {
|
||||||
|
return 'tablet';
|
||||||
|
}
|
||||||
|
return 'desktop';
|
||||||
|
};
|
||||||
|
|
||||||
|
const [device, setDevice] = useState(getDevice(NaN));
|
||||||
|
window.addEventListener('optimizedResize', e => {
|
||||||
|
setDevice(getDevice(e && e.target && e.target.innerWidth));
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<ConfigProvider device={device}>
|
||||||
|
<Shell
|
||||||
|
type="dark"
|
||||||
|
style={{
|
||||||
|
minHeight: '100vh',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Shell.Branding>
|
||||||
|
<Logo
|
||||||
|
image="https://img.alicdn.com/tfs/TB1.ZBecq67gK0jSZFHXXa9jVXa-904-826.png"
|
||||||
|
text="Logo"
|
||||||
|
/>
|
||||||
|
</Shell.Branding>
|
||||||
|
<Shell.Navigation
|
||||||
|
direction="hoz"
|
||||||
|
style={{
|
||||||
|
marginRight: 10,
|
||||||
|
}}
|
||||||
|
></Shell.Navigation>
|
||||||
|
<Shell.Action></Shell.Action>
|
||||||
|
<Shell.Navigation>
|
||||||
|
<PageNav />
|
||||||
|
</Shell.Navigation>
|
||||||
|
|
||||||
|
<Shell.Content>{children}</Shell.Content>
|
||||||
|
<Shell.Footer>
|
||||||
|
<Footer />
|
||||||
|
</Shell.Footer>
|
||||||
|
</Shell>
|
||||||
|
</ConfigProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
const headerMenuConfig = [];
|
||||||
|
const asideMenuConfig = [
|
||||||
|
{
|
||||||
|
name: 'Dashboard',
|
||||||
|
path: '/',
|
||||||
|
icon: 'smile',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
export { headerMenuConfig, asideMenuConfig };
|
||||||
|
|
||||||
@ -0,0 +1,118 @@
|
|||||||
|
// 注意: 出码引擎注入的临时变量默认都以 "__$$" 开头,禁止在搭建的代码中直接访问。
|
||||||
|
// 例外:react 框架的导出名和各种组件名除外。
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { Page } from '@alilc/b6-page';
|
||||||
|
|
||||||
|
import { Text } from '@alilc/b6-text';
|
||||||
|
|
||||||
|
import { createUrlParamsHandler as __$$createUrlParamsRequestHandler } from '@alilc/lowcode-datasource-url-params-handler';
|
||||||
|
|
||||||
|
import { create as __$$createDataSourceEngine } from '@alilc/lowcode-datasource-engine/runtime';
|
||||||
|
|
||||||
|
import utils from '../../utils';
|
||||||
|
|
||||||
|
import * as __$$i18n from '../../i18n';
|
||||||
|
|
||||||
|
import __$$constants from '../../constants';
|
||||||
|
|
||||||
|
import './index.css';
|
||||||
|
|
||||||
|
class Aaaa$$Page extends React.Component {
|
||||||
|
_context = this;
|
||||||
|
|
||||||
|
_dataSourceConfig = this._defineDataSourceConfig();
|
||||||
|
_dataSourceEngine = __$$createDataSourceEngine(this._dataSourceConfig, this, {
|
||||||
|
runtimeConfig: true,
|
||||||
|
requestHandlersMap: {
|
||||||
|
urlParams: __$$createUrlParamsRequestHandler(window.location.search),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
get dataSourceMap() {
|
||||||
|
return this._dataSourceEngine.dataSourceMap || {};
|
||||||
|
}
|
||||||
|
|
||||||
|
reloadDataSource = async () => {
|
||||||
|
await this._dataSourceEngine.reloadDataSource();
|
||||||
|
};
|
||||||
|
|
||||||
|
get constants() {
|
||||||
|
return __$$constants || {};
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(props, context) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.utils = utils;
|
||||||
|
|
||||||
|
__$$i18n._inject2(this);
|
||||||
|
|
||||||
|
this.state = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
$ = () => null;
|
||||||
|
|
||||||
|
$$ = () => [];
|
||||||
|
|
||||||
|
_defineDataSourceConfig() {
|
||||||
|
const _this = this;
|
||||||
|
return {
|
||||||
|
list: [
|
||||||
|
{
|
||||||
|
id: 'urlParams',
|
||||||
|
type: 'urlParams',
|
||||||
|
description: 'URL参数',
|
||||||
|
options: function () {
|
||||||
|
return {
|
||||||
|
uri: '',
|
||||||
|
};
|
||||||
|
}.bind(_this),
|
||||||
|
isInit: function () {
|
||||||
|
return undefined;
|
||||||
|
}.bind(_this),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this._dataSourceEngine.reloadDataSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const __$$context = this._context || this;
|
||||||
|
const { state } = __$$context;
|
||||||
|
return (
|
||||||
|
<div title="" backgroundColor="#fff" textColor="#333" style={{}}>
|
||||||
|
<Text
|
||||||
|
content="欢迎使用 BuildSuccess!sadsad"
|
||||||
|
style={{}}
|
||||||
|
fieldId="text_kp6ci11t"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Aaaa$$Page;
|
||||||
|
|
||||||
|
function __$$eval(expr) {
|
||||||
|
try {
|
||||||
|
return expr();
|
||||||
|
} catch (error) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function __$$evalArray(expr) {
|
||||||
|
const res = __$$eval(expr);
|
||||||
|
return Array.isArray(res) ? res : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function __$$createChildContext(oldContext, ext) {
|
||||||
|
const childContext = {
|
||||||
|
...oldContext,
|
||||||
|
...ext,
|
||||||
|
};
|
||||||
|
childContext.__proto__ = oldContext;
|
||||||
|
return childContext;
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
import { Outlet } from 'ice';
|
||||||
|
import BasicLayout from '@/layouts/BasicLayout';
|
||||||
|
|
||||||
|
export default function Layout() {
|
||||||
|
return (
|
||||||
|
<BasicLayout>
|
||||||
|
<Outlet />
|
||||||
|
</BasicLayout>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
/// <reference types="@ice/app/types" />
|
||||||
|
|
||||||
|
export {};
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
g_config: Record<string, any>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
import legaoBuiltin from '@alilc/b6-compact-legao-builtin';
|
||||||
|
|
||||||
|
import { message, Modal as modal } from 'antd';
|
||||||
|
|
||||||
|
import { mocks } from '@alilc/b6-util-mocks';
|
||||||
|
|
||||||
|
import { createRef } from 'react';
|
||||||
|
|
||||||
|
export class RefsManager {
|
||||||
|
constructor() {
|
||||||
|
this.refInsStore = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
clearNullRefs() {
|
||||||
|
Object.keys(this.refInsStore).forEach((refName) => {
|
||||||
|
const filteredInsList = this.refInsStore[refName].filter(
|
||||||
|
(insRef) => !!insRef.current
|
||||||
|
);
|
||||||
|
if (filteredInsList.length > 0) {
|
||||||
|
this.refInsStore[refName] = filteredInsList;
|
||||||
|
} else {
|
||||||
|
delete this.refInsStore[refName];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get(refName) {
|
||||||
|
this.clearNullRefs();
|
||||||
|
if (this.refInsStore[refName] && this.refInsStore[refName].length > 0) {
|
||||||
|
return this.refInsStore[refName][0].current;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
getAll(refName) {
|
||||||
|
this.clearNullRefs();
|
||||||
|
if (this.refInsStore[refName] && this.refInsStore[refName].length > 0) {
|
||||||
|
return this.refInsStore[refName].map((i) => i.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
linkRef(refName) {
|
||||||
|
const refIns = createRef();
|
||||||
|
this.refInsStore[refName] = this.refInsStore[refName] || [];
|
||||||
|
this.refInsStore[refName].push(refIns);
|
||||||
|
return refIns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
legaoBuiltin,
|
||||||
|
|
||||||
|
message,
|
||||||
|
|
||||||
|
mocks,
|
||||||
|
|
||||||
|
modal,
|
||||||
|
};
|
||||||
123
modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo2-utils-name-alias/schema.json5
vendored
Normal file
123
modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo2-utils-name-alias/schema.json5
vendored
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
{
|
||||||
|
version: '1.0.0',
|
||||||
|
componentsMap: [
|
||||||
|
{
|
||||||
|
package: '@alilc/b6-page',
|
||||||
|
version: '^0.1.0',
|
||||||
|
componentName: 'Page',
|
||||||
|
destructuring: true,
|
||||||
|
exportName: 'Page',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
package: '@alilc/b6-text',
|
||||||
|
version: '^0.1.0',
|
||||||
|
componentName: 'Text',
|
||||||
|
destructuring: true,
|
||||||
|
exportName: 'Text',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
componentsTree: [
|
||||||
|
{
|
||||||
|
componentName: 'Page',
|
||||||
|
id: 'node_ockp6ci0hm1',
|
||||||
|
props: {
|
||||||
|
title: '',
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
textColor: '#333',
|
||||||
|
style: {},
|
||||||
|
},
|
||||||
|
fileName: 'aaaa',
|
||||||
|
dataSource: {
|
||||||
|
list: [
|
||||||
|
{
|
||||||
|
id: 'urlParams',
|
||||||
|
type: 'urlParams',
|
||||||
|
description: 'URL参数',
|
||||||
|
options: {
|
||||||
|
uri: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
componentName: 'Text',
|
||||||
|
id: 'node_ockp6ci0hm2',
|
||||||
|
props: {
|
||||||
|
content: '欢迎使用 BuildSuccess!sadsad',
|
||||||
|
style: {},
|
||||||
|
fieldId: 'text_kp6ci11t',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
meta: {
|
||||||
|
router: '/aaaa',
|
||||||
|
},
|
||||||
|
methodsModule: {
|
||||||
|
type: 'JSModule',
|
||||||
|
compiled: '"use strict";\n\nObject.defineProperty(exports, "__esModule", {\n value: true\n});\nexports.helloPage = helloPage;\n\n/**\n * Private, and can be re-used functions\n * Actions panel help documentation:\n * @see https://yuque.antfin.com/docs/share/89ca7965-6387-4e3a-9964-81929ed48f1e\n */\nfunction printLog(obj) {\n console.info(obj);\n}\n/**\n * page function\n */\n\n\nfunction helloPage() {\n console.log(\'hello page\');\n}',
|
||||||
|
source: "/**\n * Private, and can be re-used functions\n * Actions panel help documentation:\n * @see https://yuque.antfin.com/docs/share/89ca7965-6387-4e3a-9964-81929ed48f1e\n */\nfunction printLog(obj) {\n console.info(obj);\n}\n\n/**\n * page function\n */\nexport function helloPage() {\n console.log('hello page');\n}",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
i18n: {},
|
||||||
|
utils: [
|
||||||
|
{
|
||||||
|
name: 'legaoBuiltin',
|
||||||
|
type: 'npm',
|
||||||
|
content: {
|
||||||
|
exportName: 'legaoBuiltin',
|
||||||
|
package: '@alilc/b6-compact-legao-builtin',
|
||||||
|
version: '1.x',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'message',
|
||||||
|
type: 'npm',
|
||||||
|
content: {
|
||||||
|
package: 'antd',
|
||||||
|
version: '3.x',
|
||||||
|
destructuring: true,
|
||||||
|
exportName: 'message',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'mocks',
|
||||||
|
type: 'npm',
|
||||||
|
content: {
|
||||||
|
package: '@alilc/b6-util-mocks',
|
||||||
|
version: '1.x',
|
||||||
|
exportName: 'mocks',
|
||||||
|
destructuring: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'modal',
|
||||||
|
type: 'npm',
|
||||||
|
content: {
|
||||||
|
package: 'antd',
|
||||||
|
version: '3.x',
|
||||||
|
destructuring: true,
|
||||||
|
exportName: 'Modal',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
constants: {},
|
||||||
|
dataSource: {
|
||||||
|
list: [],
|
||||||
|
},
|
||||||
|
config: {
|
||||||
|
sdkVersion: '1.0.3',
|
||||||
|
historyMode: 'hash',
|
||||||
|
targetRootID: 'root',
|
||||||
|
miniAppBuildType: 'runtime',
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
name: 'jinyuan-test2',
|
||||||
|
git_group: 'b6',
|
||||||
|
project_name: 'jinyuan-test2',
|
||||||
|
description: '瑾源测试',
|
||||||
|
spma: 'spmademo',
|
||||||
|
creator: '张三',
|
||||||
|
},
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
defaults
|
||||||
|
ios_saf 9
|
||||||
|
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# production
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
tmp/
|
||||||
|
lib/
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.idea/
|
||||||
|
.happypack
|
||||||
|
.DS_Store
|
||||||
|
*.swp
|
||||||
|
*.dia~
|
||||||
|
.ice
|
||||||
|
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
index.module.scss.d.ts
|
||||||
|
|
||||||
@ -0,0 +1 @@
|
|||||||
|
This project is generated by lowcode-code-generator & lowcode-solution-icejs3.
|
||||||
@ -0,0 +1,90 @@
|
|||||||
|
import { join } from 'path';
|
||||||
|
import { defineConfig } from '@ice/app';
|
||||||
|
import _ from 'lodash';
|
||||||
|
import fusion from '@ice/plugin-fusion';
|
||||||
|
import locales from '@ice/plugin-moment-locales';
|
||||||
|
import type { Plugin } from '@ice/app/esm/types';
|
||||||
|
|
||||||
|
interface PluginOptions {
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const plugin: Plugin<PluginOptions> = (options) => ({
|
||||||
|
// name 可选,插件名称
|
||||||
|
name: 'plugin-name',
|
||||||
|
// setup 必选,用于定制工程构建配置
|
||||||
|
setup: ({ onGetConfig, modifyUserConfig }) => {
|
||||||
|
modifyUserConfig('codeSplitting', 'page');
|
||||||
|
|
||||||
|
onGetConfig((config) => {
|
||||||
|
config.entry = {
|
||||||
|
web: join(process.cwd(), '.ice/entry.client.tsx'),
|
||||||
|
};
|
||||||
|
|
||||||
|
config.cssFilename = '[name].css';
|
||||||
|
|
||||||
|
config.configureWebpack = config.configureWebpack || [];
|
||||||
|
config.configureWebpack?.push((webpackConfig) => {
|
||||||
|
if (webpackConfig.output) {
|
||||||
|
webpackConfig.output.filename = '[name].js';
|
||||||
|
webpackConfig.output.chunkFilename = '[name].js';
|
||||||
|
}
|
||||||
|
return webpackConfig;
|
||||||
|
});
|
||||||
|
|
||||||
|
config.swcOptions = _.merge(config.swcOptions, {
|
||||||
|
compilationConfig: {
|
||||||
|
jsc: {
|
||||||
|
transform: {
|
||||||
|
react: {
|
||||||
|
runtime: 'classic',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 解决 webpack publicPath 问题
|
||||||
|
config.transforms = config.transforms || [];
|
||||||
|
config.transforms.push((source: string, id: string) => {
|
||||||
|
if (id.includes('.ice/entry.client.tsx')) {
|
||||||
|
let code = `
|
||||||
|
if (!__webpack_public_path__?.startsWith('http') && document.currentScript) {
|
||||||
|
// @ts-ignore
|
||||||
|
__webpack_public_path__ = document.currentScript.src.replace(/^(.*\\/)[^/]+$/, '$1');
|
||||||
|
window.__ICE_ASSETS_MANIFEST__ = window.__ICE_ASSETS_MANIFEST__ || {};
|
||||||
|
window.__ICE_ASSETS_MANIFEST__.publicPath = __webpack_public_path__;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
code += source;
|
||||||
|
return { code };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// The project config, see https://v3.ice.work/docs/guide/basic/config
|
||||||
|
const minify = process.env.NODE_ENV === 'production' ? 'swc' : false;
|
||||||
|
export default defineConfig(() => ({
|
||||||
|
ssr: false,
|
||||||
|
ssg: false,
|
||||||
|
minify,
|
||||||
|
|
||||||
|
externals: {
|
||||||
|
react: 'React',
|
||||||
|
'react-dom': 'ReactDOM',
|
||||||
|
'react-dom/client': 'ReactDOM',
|
||||||
|
'@alifd/next': 'Next',
|
||||||
|
lodash: 'var window._',
|
||||||
|
'@alilc/lowcode-engine': 'var window.AliLowCodeEngine',
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
fusion({
|
||||||
|
importStyle: true,
|
||||||
|
}),
|
||||||
|
locales(),
|
||||||
|
plugin(),
|
||||||
|
],
|
||||||
|
}));
|
||||||
|
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "icejs3-demo-app",
|
||||||
|
"version": "0.1.5",
|
||||||
|
"description": "icejs 3 轻量级模板,使用 JavaScript,仅包含基础的 Layout。",
|
||||||
|
"dependencies": {
|
||||||
|
"moment": "^2.24.0",
|
||||||
|
"react": "^18.2.0",
|
||||||
|
"react-dom": "^18.2.0",
|
||||||
|
"react-router": "^6.9.0",
|
||||||
|
"react-router-dom": "^6.9.0",
|
||||||
|
"intl-messageformat": "^9.3.6",
|
||||||
|
"@alifd/next": "1.19.18",
|
||||||
|
"@ice/runtime": "^1.0.0",
|
||||||
|
"@alilc/lowcode-datasource-engine": "^1.0.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@ice/app": "^3.0.0",
|
||||||
|
"@types/react": "^18.0.0",
|
||||||
|
"@types/react-dom": "^18.0.0",
|
||||||
|
"@types/node": "^18.11.17",
|
||||||
|
"@ice/plugin-fusion": "^1.0.1",
|
||||||
|
"@ice/plugin-moment-locales": "^1.0.0",
|
||||||
|
"eslint": "^6.0.1",
|
||||||
|
"stylelint": "^13.2.0"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"start": "ice start",
|
||||||
|
"build": "ice build",
|
||||||
|
"lint": "npm run eslint && npm run stylelint",
|
||||||
|
"eslint": "eslint --cache --ext .js,.jsx ./",
|
||||||
|
"stylelint": "stylelint ./**/*.scss"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "http://gitlab.xxx.com/msd/leak-scan/tree/master"
|
||||||
|
},
|
||||||
|
"private": true,
|
||||||
|
"originTemplate": "@alifd/scaffold-lite-js"
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
import { defineAppConfig } from 'ice';
|
||||||
|
|
||||||
|
// App config, see https://v3.ice.work/docs/guide/basic/app
|
||||||
|
export default defineAppConfig(() => ({
|
||||||
|
// Set your configs here.
|
||||||
|
app: {
|
||||||
|
rootId: 'App',
|
||||||
|
},
|
||||||
|
router: {
|
||||||
|
type: 'browser',
|
||||||
|
basename: '/',
|
||||||
|
},
|
||||||
|
}));
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
const __$$constants = { ENV: 'prod', DOMAIN: 'xxx.xxx.com' };
|
||||||
|
|
||||||
|
export default __$$constants;
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Meta, Title, Links, Main, Scripts } from 'ice';
|
||||||
|
|
||||||
|
export default function Document() {
|
||||||
|
return (
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charSet="utf-8" />
|
||||||
|
<meta name="description" content="ice.js 3 lite scaffold" />
|
||||||
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
<link rel="stylesheet" href="//alifd.alicdn.com/npm/@alifd/next/1.21.16/next.min.css" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
|
||||||
|
<Meta />
|
||||||
|
<Title />
|
||||||
|
<Links />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<Main />
|
||||||
|
<script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react/18.2.0/umd/react.development.js" />
|
||||||
|
<script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react-dom/18.2.0/umd/react-dom.development.js" />
|
||||||
|
<script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/??react-router/6.9.0/react-router.production.min.js,react-router-dom/6.9.0/react-router-dom.production.min.js" />
|
||||||
|
<script crossOrigin="anonymous" src="//alifd.alicdn.com/npm/@alifd/next/1.26.15/next.min.js" />
|
||||||
|
<script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/prop-types/15.7.2/prop-types.js" />
|
||||||
|
<script crossOrigin="anonymous" src="//g.alicdn.com/platform/c/??lodash/4.6.1/lodash.min.js,immutable/3.7.6/dist/immutable.min.js" />
|
||||||
|
<Scripts />
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
// 引入默认全局样式
|
||||||
|
@import '@alifd/next/reset.scss';
|
||||||
|
|
||||||
|
body {
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.table {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
@ -0,0 +1,86 @@
|
|||||||
|
const i18nConfig = {
|
||||||
|
'zh-CN': {
|
||||||
|
'i18n-jwg27yo4': '你好',
|
||||||
|
'i18n-jwg27yo3': '中国',
|
||||||
|
},
|
||||||
|
'en-US': {
|
||||||
|
'i18n-jwg27yo4': 'Hello',
|
||||||
|
'i18n-jwg27yo3': 'China',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let locale =
|
||||||
|
typeof navigator === 'object' && typeof navigator.language === 'string'
|
||||||
|
? navigator.language
|
||||||
|
: 'zh-CN';
|
||||||
|
|
||||||
|
const getLocale = () => locale;
|
||||||
|
|
||||||
|
const setLocale = (target) => {
|
||||||
|
locale = target;
|
||||||
|
};
|
||||||
|
|
||||||
|
const isEmptyVariables = (variables) =>
|
||||||
|
(Array.isArray(variables) && variables.length === 0) ||
|
||||||
|
(typeof variables === 'object' &&
|
||||||
|
(!variables || Object.keys(variables).length === 0));
|
||||||
|
|
||||||
|
// 按低代码规范里面的要求进行变量替换
|
||||||
|
const format = (msg, variables) =>
|
||||||
|
typeof msg === 'string'
|
||||||
|
? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? '')
|
||||||
|
: msg;
|
||||||
|
|
||||||
|
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
|
||||||
|
const msg =
|
||||||
|
i18nConfig[locale]?.[id] ??
|
||||||
|
i18nConfig[locale.replace('-', '_')]?.[id] ??
|
||||||
|
defaultMessage;
|
||||||
|
if (msg == null) {
|
||||||
|
console.warn('[i18n]: unknown message id: %o (locale=%o)', id, locale);
|
||||||
|
return fallback === undefined ? `${id}` : fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
return format(msg, variables);
|
||||||
|
};
|
||||||
|
|
||||||
|
const i18n = (id, params) => {
|
||||||
|
return i18nFormat({ id }, params);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 将国际化的一些方法注入到目标对象&上下文中
|
||||||
|
const _inject2 = (target) => {
|
||||||
|
target.i18n = i18n;
|
||||||
|
target.getLocale = getLocale;
|
||||||
|
target.setLocale = (locale) => {
|
||||||
|
setLocale(locale);
|
||||||
|
target.forceUpdate();
|
||||||
|
};
|
||||||
|
target._i18nText = (t) => {
|
||||||
|
// 优先取直接传过来的语料
|
||||||
|
const localMsg = t[locale] ?? t[String(locale).replace('-', '_')];
|
||||||
|
if (localMsg != null) {
|
||||||
|
return format(localMsg, t.params);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其次用项目级别的
|
||||||
|
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
|
||||||
|
if (projectMsg != null) {
|
||||||
|
return projectMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 兜底用 use 指定的或默认语言的
|
||||||
|
return format(t[t.use || 'zh-CN'] ?? t.en_US, t.params);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 注入到上下文中去
|
||||||
|
if (target._context && target._context !== target) {
|
||||||
|
Object.assign(target._context, {
|
||||||
|
i18n,
|
||||||
|
getLocale,
|
||||||
|
setLocale: target.setLocale,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import styles from './index.module.scss';
|
||||||
|
|
||||||
|
export default function Footer() {
|
||||||
|
return (
|
||||||
|
<p className={styles.footer}>
|
||||||
|
<span className={styles.logo}>Alibaba Fusion</span>
|
||||||
|
<br />
|
||||||
|
<span className={styles.copyright}>© 2019-现在 Alibaba Fusion & ICE</span>
|
||||||
|
</p>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
.footer {
|
||||||
|
line-height: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyright {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { Link } from 'ice';
|
||||||
|
import styles from './index.module.scss';
|
||||||
|
|
||||||
|
export default function Logo({ image, text, url }) {
|
||||||
|
return (
|
||||||
|
<div className="logo">
|
||||||
|
<Link to={url || '/'} className={styles.logo}>
|
||||||
|
{image && <img src={image} alt="logo" />}
|
||||||
|
<span>{text}</span>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user