Compare commits
24 Commits
Author | SHA1 | Date |
---|---|---|
![]() |
603be3bdb9 | |
![]() |
50f968f27d | |
![]() |
9ccfc9fa8a | |
![]() |
c35c34e036 | |
![]() |
76c23b767b | |
![]() |
c218724543 | |
![]() |
871463f185 | |
![]() |
59eaf035bb | |
![]() |
1ed91983b0 | |
|
a442108e2b | |
![]() |
3a204624af | |
![]() |
0d36f2d344 | |
![]() |
a383421c38 | |
![]() |
fd164a1cd2 | |
![]() |
fec563dda3 | |
![]() |
732bed9795 | |
![]() |
2c27f9141a | |
![]() |
66268d3ec3 | |
![]() |
e651dffa2b | |
![]() |
91d3ae108c | |
![]() |
277be2f11e | |
![]() |
2c478ce391 | |
![]() |
c341f4c2c5 | |
![]() |
858e178af6 |
|
@ -88,9 +88,9 @@ gantt
|
||||||
dateFormat YYYY-MM-DD
|
dateFormat YYYY-MM-DD
|
||||||
axisFormat %Y-%m-%d
|
axisFormat %Y-%m-%d
|
||||||
|
|
||||||
1.0.0-beta.x version :active,2023-09-25, 2024-03-31
|
1.0.0-beta.x version : 2023-09-25, 2024-05-20
|
||||||
1.0.0-rc version : 2024-04-01, 2024-06-30
|
1.0.0-rc version(refactor version) : 2024-10-01
|
||||||
1.0.0 version : 2024-07-01, 2024-07-31
|
1.0.0 version : 2024-11-01
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -88,9 +88,9 @@ gantt
|
||||||
dateFormat YYYY-MM-DD
|
dateFormat YYYY-MM-DD
|
||||||
axisFormat %Y-%m-%d
|
axisFormat %Y-%m-%d
|
||||||
|
|
||||||
1.0.0-beta.x version :active,2023-09-25, 2024-03-31
|
1.0.0-beta.x version : 2023-09-25, 2024-05-20
|
||||||
1.0.0-rc version : 2024-04-01, 2024-06-30
|
1.0.0-rc version(refactor version) : 2024-10-01
|
||||||
1.0.0 version : 2024-07-01, 2024-07-31
|
1.0.0 version : 2024-11-01
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -1918,6 +1918,13 @@
|
||||||
"destructuring": true,
|
"destructuring": true,
|
||||||
"version": "0.1.17"
|
"version": "0.1.17"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"componentName": "TinyCheckbox",
|
||||||
|
"package": "@opentiny/vue",
|
||||||
|
"exportName": "Checkbox",
|
||||||
|
"destructuring": true,
|
||||||
|
"version": "3.14.0"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"componentName": "TinySelect",
|
"componentName": "TinySelect",
|
||||||
"package": "@opentiny/vue",
|
"package": "@opentiny/vue",
|
||||||
|
@ -1974,6 +1981,76 @@
|
||||||
"destructuring": true,
|
"destructuring": true,
|
||||||
"version": "0.1.16"
|
"version": "0.1.16"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"componentName": "TinyCollapse",
|
||||||
|
"package": "@opentiny/vue",
|
||||||
|
"exportName": "Collapse",
|
||||||
|
"destructuring": true,
|
||||||
|
"version": "3.14.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentName": "TinyCollapseItem",
|
||||||
|
"package": "@opentiny/vue",
|
||||||
|
"exportName": "CollapseItem",
|
||||||
|
"destructuring": true,
|
||||||
|
"version": "3.14.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentName": "TinyBreadcrumb",
|
||||||
|
"package": "@opentiny/vue",
|
||||||
|
"exportName": "Breadcrumb",
|
||||||
|
"destructuring": true,
|
||||||
|
"version": "3.14.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentName": "TinyBreadcrumbItem",
|
||||||
|
"package": "@opentiny/vue",
|
||||||
|
"exportName": "BreadcrumbItem",
|
||||||
|
"destructuring": true,
|
||||||
|
"version": "3.14.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentName": "ElInput",
|
||||||
|
"package": "element-plus",
|
||||||
|
"exportName": "ElInput",
|
||||||
|
"destructuring": true,
|
||||||
|
"version": "2.4.2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentName": "ElButton",
|
||||||
|
"package": "element-plus",
|
||||||
|
"exportName": "ElButton",
|
||||||
|
"destructuring": true,
|
||||||
|
"version": "2.4.2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentName": "ElForm",
|
||||||
|
"package": "element-plus",
|
||||||
|
"exportName": "ElForm",
|
||||||
|
"destructuring": true,
|
||||||
|
"version": "2.4.2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentName": "ElFormItem",
|
||||||
|
"package": "element-plus",
|
||||||
|
"exportName": "ElFormItem",
|
||||||
|
"destructuring": true,
|
||||||
|
"version": "2.4.2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentName": "ElTable",
|
||||||
|
"package": "element-plus",
|
||||||
|
"exportName": "ElTable",
|
||||||
|
"destructuring": true,
|
||||||
|
"version": "2.4.2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentName": "ElTableColumn",
|
||||||
|
"package": "element-plus",
|
||||||
|
"exportName": "ElTableColumn",
|
||||||
|
"destructuring": true,
|
||||||
|
"version": "2.4.2"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"componentName": "PortalHome",
|
"componentName": "PortalHome",
|
||||||
"main": "common/components/home",
|
"main": "common/components/home",
|
||||||
|
|
|
@ -25,8 +25,6 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/eslint-parser": "^7.21.3",
|
"@babel/eslint-parser": "^7.21.3",
|
||||||
"@esbuild-plugins/node-globals-polyfill": "^0.2.3",
|
|
||||||
"@esbuild-plugins/node-modules-polyfill": "^0.2.2",
|
|
||||||
"@types/node": "^18.0.0",
|
"@types/node": "^18.0.0",
|
||||||
"@vitejs/plugin-vue": "^4.2.3",
|
"@vitejs/plugin-vue": "^4.2.3",
|
||||||
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
||||||
|
|
|
@ -43,7 +43,7 @@ export default defineConfig(({ command, mode }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const vuePluginConfig = {}
|
const vuePluginConfig = {}
|
||||||
const styleLinks = ['https://npm.onmicrosoft.cn/@opentiny/vue-theme@3.14/index.css']
|
const styleLinks = ['https://unpkg.com/@opentiny/vue-theme@3.14/index.css']
|
||||||
|
|
||||||
config.publicDir = false
|
config.publicDir = false
|
||||||
|
|
||||||
|
|
|
@ -229,7 +229,10 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
const showAction = computed(() => {
|
const showAction = computed(() => {
|
||||||
const { parent } = getCurrent()
|
const { schema, parent } = getCurrent()
|
||||||
|
if (schema?.props?.['data-id'] === 'root-container') {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return !props.resize && parent && parent?.type !== 'JSSlot'
|
return !props.resize && parent && parent?.type !== 'JSSlot'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -185,6 +185,8 @@ export const dragEnd = () => {
|
||||||
if (element && canvasState.type === 'absolute') {
|
if (element && canvasState.type === 'absolute') {
|
||||||
data.props = data.props || {}
|
data.props = data.props || {}
|
||||||
data.props.style = element.style.cssText
|
data.props.style = element.style.cssText
|
||||||
|
|
||||||
|
getController().addHistory()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重置拖拽状态
|
// 重置拖拽状态
|
||||||
|
@ -541,6 +543,8 @@ const setHoverRect = (element, data) => {
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let moveUpdateTimer = null
|
||||||
|
|
||||||
// 绝对布局
|
// 绝对布局
|
||||||
const absoluteMove = (event, element) => {
|
const absoluteMove = (event, element) => {
|
||||||
const { clientX, clientY } = event
|
const { clientX, clientY } = event
|
||||||
|
@ -572,6 +576,19 @@ const absoluteMove = (event, element) => {
|
||||||
element.style.height = `${clientY - y}px`
|
element.style.height = `${clientY - y}px`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearTimeout(moveUpdateTimer)
|
||||||
|
|
||||||
|
const { data } = dragState
|
||||||
|
data.props = data.props || {}
|
||||||
|
|
||||||
|
// 防抖更新位置信息到 schema
|
||||||
|
moveUpdateTimer = setTimeout(() => {
|
||||||
|
data.props.style = element.style.cssText
|
||||||
|
|
||||||
|
getController().addHistory()
|
||||||
|
}, 100)
|
||||||
|
|
||||||
updateRect()
|
updateRect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -716,11 +733,7 @@ export const onMouseUp = () => {
|
||||||
if (absolute) {
|
if (absolute) {
|
||||||
targetNode.node = getSchema()
|
targetNode.node = getSchema()
|
||||||
data.props = data.props || {}
|
data.props = data.props || {}
|
||||||
data.props.style = {
|
data.props.style = `position: absolute; top: ${dragState.mouse.y}px; left: ${dragState.mouse.x}px`
|
||||||
position: 'absolute',
|
|
||||||
top: dragState.mouse.y + 'px',
|
|
||||||
left: dragState.mouse.x + 'px'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
insertNode(targetNode, position)
|
insertNode(targetNode, position)
|
||||||
|
|
|
@ -379,7 +379,8 @@ export default {
|
||||||
// 渲染画布增加根节点,与出码和预览保持一致
|
// 渲染画布增加根节点,与出码和预览保持一致
|
||||||
const rootChildrenSchema = {
|
const rootChildrenSchema = {
|
||||||
componentName: 'div',
|
componentName: 'div',
|
||||||
props: schema.props,
|
// 手动添加一个唯一的属性,后续在画布选中此节点时方便处理额外的逻辑。由于没有修改schema,不会影响出码
|
||||||
|
props: { ...schema.props, 'data-id': 'root-container' },
|
||||||
children: schema.children
|
children: schema.children
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -558,7 +558,7 @@ const getBindProps = (schema, scope) => {
|
||||||
...parseData(schema.props, scope),
|
...parseData(schema.props, scope),
|
||||||
[DESIGN_UIDKEY]: id,
|
[DESIGN_UIDKEY]: id,
|
||||||
[DESIGN_TAGKEY]: componentName,
|
[DESIGN_TAGKEY]: componentName,
|
||||||
onMoseover: stopEvent,
|
onMouseover: stopEvent,
|
||||||
onFocus: stopEvent
|
onFocus: stopEvent
|
||||||
}
|
}
|
||||||
if (scope) {
|
if (scope) {
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="head-content">
|
<div class="head-content">
|
||||||
<meta-input v-model="state.text" type="textarea" @change="change"></meta-input>
|
<meta-input v-model="state.text" type="textarea" @update:modelValue="change"></meta-input>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# alpha mode, used by the "build:alpha" script
|
# alpha mode, used by the "build:alpha" script
|
||||||
|
|
||||||
NODE_ENV=production
|
NODE_ENV=production
|
||||||
VITE_CDN_DOMAIN=https://npm.onmicrosoft.cn
|
VITE_CDN_DOMAIN=https://unpkg.com
|
||||||
VITE_LOCAL_IMPORT_MAPS=false
|
VITE_LOCAL_IMPORT_MAPS=false
|
||||||
VITE_LOCAL_BUNDLE_DEPS=false
|
VITE_LOCAL_BUNDLE_DEPS=false
|
||||||
# VITE_ORIGIN=
|
# VITE_ORIGIN=
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# development mode, used by the "vite" command
|
# development mode, used by the "vite" command
|
||||||
|
|
||||||
NODE_ENV=development
|
NODE_ENV=development
|
||||||
VITE_CDN_DOMAIN=https://npm.onmicrosoft.cn
|
VITE_CDN_DOMAIN=https://unpkg.com
|
||||||
VITE_LOCAL_IMPORT_MAPS=false
|
VITE_LOCAL_IMPORT_MAPS=false
|
||||||
VITE_LOCAL_BUNDLE_DEPS=false
|
VITE_LOCAL_BUNDLE_DEPS=false
|
||||||
# request data via alpha service
|
# request data via alpha service
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# prod mode, used by the "build:prod" script
|
# prod mode, used by the "build:prod" script
|
||||||
|
|
||||||
NODE_ENV=production
|
NODE_ENV=production
|
||||||
VITE_CDN_DOMAIN=https://npm.onmicrosoft.cn
|
VITE_CDN_DOMAIN=https://unpkg.com
|
||||||
VITE_LOCAL_IMPORT_MAPS=false
|
VITE_LOCAL_IMPORT_MAPS=false
|
||||||
VITE_LOCAL_BUNDLE_DEPS=false
|
VITE_LOCAL_BUNDLE_DEPS=false
|
||||||
#VITE_ORIGIN=
|
#VITE_ORIGIN=
|
||||||
|
|
|
@ -89,7 +89,6 @@
|
||||||
"eslint-linter-browserify": "8.57.0",
|
"eslint-linter-browserify": "8.57.0",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"html2canvas": "^1.4.1",
|
"html2canvas": "^1.4.1",
|
||||||
"jszip": "^3.10.1",
|
|
||||||
"monaco-editor": "0.33.0",
|
"monaco-editor": "0.33.0",
|
||||||
"prettier": "2.7.1",
|
"prettier": "2.7.1",
|
||||||
"sortablejs": "^1.14.0",
|
"sortablejs": "^1.14.0",
|
||||||
|
@ -107,6 +106,7 @@
|
||||||
"assert": "^2.0.0",
|
"assert": "^2.0.0",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
|
"esbuild": "^0.21.5",
|
||||||
"esbuild-plugin-copy": "^2.1.1",
|
"esbuild-plugin-copy": "^2.1.1",
|
||||||
"eslint": "^8.38.0",
|
"eslint": "^8.38.0",
|
||||||
"eslint-plugin-vue": "^8.0.0",
|
"eslint-plugin-vue": "^8.0.0",
|
||||||
|
|
|
@ -20,10 +20,11 @@
|
||||||
"npm": {
|
"npm": {
|
||||||
"package": "element-plus",
|
"package": "element-plus",
|
||||||
"version": "2.4.2",
|
"version": "2.4.2",
|
||||||
"script": "https://npm.onmicrosoft.cn/element-plus@2.4.2/dist/index.full.mjs",
|
"script": "https://unpkg.com/element-plus@2.4.2/dist/index.full.mjs",
|
||||||
"css": "https://npm.onmicrosoft.cn/element-plus@2.4.2/dist/index.css",
|
"css": "https://unpkg.com/element-plus@2.4.2/dist/index.css",
|
||||||
"dependencies": null,
|
"dependencies": null,
|
||||||
"exportName": "ElInput"
|
"exportName": "ElInput",
|
||||||
|
"destructuring": true
|
||||||
},
|
},
|
||||||
"group": "表单组件",
|
"group": "表单组件",
|
||||||
"category": "element-plus",
|
"category": "element-plus",
|
||||||
|
@ -300,10 +301,11 @@
|
||||||
"npm": {
|
"npm": {
|
||||||
"package": "element-plus",
|
"package": "element-plus",
|
||||||
"version": "2.4.2",
|
"version": "2.4.2",
|
||||||
"script": "https://npm.onmicrosoft.cn/element-plus@2.4.2/dist/index.full.mjs",
|
"script": "https://unpkg.com/element-plus@2.4.2/dist/index.full.mjs",
|
||||||
"css": "https://npm.onmicrosoft.cn/element-plus@2.4.2/dist/index.css",
|
"css": "https://unpkg.com/element-plus@2.4.2/dist/index.css",
|
||||||
"dependencies": null,
|
"dependencies": null,
|
||||||
"exportName": "ElButton"
|
"exportName": "ElButton",
|
||||||
|
"destructuring": true
|
||||||
},
|
},
|
||||||
"group": "基础组件",
|
"group": "基础组件",
|
||||||
"category": "element-plus",
|
"category": "element-plus",
|
||||||
|
@ -621,9 +623,10 @@
|
||||||
"npm": {
|
"npm": {
|
||||||
"package": "element-plus",
|
"package": "element-plus",
|
||||||
"version": "2.4.2",
|
"version": "2.4.2",
|
||||||
"script": "https://npm.onmicrosoft.cn/element-plus@2.4.2/dist/index.full.mjs",
|
"script": "https://unpkg.com/element-plus@2.4.2/dist/index.full.mjs",
|
||||||
"css": "https://npm.onmicrosoft.cn/element-plus@2.4.2/dist/index.css",
|
"css": "https://unpkg.com/element-plus@2.4.2/dist/index.css",
|
||||||
"dependencies": null,
|
"dependencies": null,
|
||||||
|
"destructuring": true,
|
||||||
"exportName": "ElForm"
|
"exportName": "ElForm"
|
||||||
},
|
},
|
||||||
"group": "表单组件",
|
"group": "表单组件",
|
||||||
|
@ -1078,9 +1081,10 @@
|
||||||
"npm": {
|
"npm": {
|
||||||
"package": "element-plus",
|
"package": "element-plus",
|
||||||
"version": "2.4.2",
|
"version": "2.4.2",
|
||||||
"script": "https://npm.onmicrosoft.cn/element-plus@2.4.2/dist/index.full.mjs",
|
"script": "https://unpkg.com/element-plus@2.4.2/dist/index.full.mjs",
|
||||||
"css": "https://npm.onmicrosoft.cn/element-plus@2.4.2/dist/index.css",
|
"css": "https://unpkg.com/element-plus@2.4.2/dist/index.css",
|
||||||
"dependencies": null,
|
"dependencies": null,
|
||||||
|
"destructuring": true,
|
||||||
"exportName": "ElFormItem"
|
"exportName": "ElFormItem"
|
||||||
},
|
},
|
||||||
"group": "表单组件",
|
"group": "表单组件",
|
||||||
|
@ -1428,9 +1432,10 @@
|
||||||
"npm": {
|
"npm": {
|
||||||
"package": "element-plus",
|
"package": "element-plus",
|
||||||
"version": "2.4.2",
|
"version": "2.4.2",
|
||||||
"script": "https://npm.onmicrosoft.cn/element-plus@2.4.2/dist/index.full.mjs",
|
"script": "https://unpkg.com/element-plus@2.4.2/dist/index.full.mjs",
|
||||||
"css": "https://npm.onmicrosoft.cn/element-plus@2.4.2/dist/index.css",
|
"css": "https://unpkg.com/element-plus@2.4.2/dist/index.css",
|
||||||
"dependencies": null,
|
"dependencies": null,
|
||||||
|
"destructuring": true,
|
||||||
"exportName": "ElTable"
|
"exportName": "ElTable"
|
||||||
},
|
},
|
||||||
"group": "数据展示",
|
"group": "数据展示",
|
||||||
|
@ -2666,9 +2671,10 @@
|
||||||
"npm": {
|
"npm": {
|
||||||
"package": "element-plus",
|
"package": "element-plus",
|
||||||
"version": "2.4.2",
|
"version": "2.4.2",
|
||||||
"script": "https://npm.onmicrosoft.cn/element-plus@2.4.2/dist/index.full.mjs",
|
"script": "https://unpkg.com/element-plus@2.4.2/dist/index.full.mjs",
|
||||||
"css": "https://npm.onmicrosoft.cn/element-plus@2.4.2/dist/index.css",
|
"css": "https://unpkg.com/element-plus@2.4.2/dist/index.css",
|
||||||
"dependencies": null,
|
"dependencies": null,
|
||||||
|
"destructuring": true,
|
||||||
"exportName": "ElTableColumn"
|
"exportName": "ElTableColumn"
|
||||||
},
|
},
|
||||||
"group": "表单组件",
|
"group": "表单组件",
|
||||||
|
@ -8901,7 +8907,7 @@
|
||||||
"devMode": "proCode",
|
"devMode": "proCode",
|
||||||
"npm": {
|
"npm": {
|
||||||
"package": "@opentiny/vue",
|
"package": "@opentiny/vue",
|
||||||
"exportName": "Select",
|
"exportName": "Breadcrumb",
|
||||||
"version": "",
|
"version": "",
|
||||||
"destructuring": true
|
"destructuring": true
|
||||||
},
|
},
|
||||||
|
@ -14007,20 +14013,10 @@
|
||||||
"schema": {
|
"schema": {
|
||||||
"componentName": "TinyBreadcrumb",
|
"componentName": "TinyBreadcrumb",
|
||||||
"props": {
|
"props": {
|
||||||
"options": [
|
"options": {
|
||||||
{
|
"type": "JSExpression",
|
||||||
"to": "{ path: '/' }",
|
"value": "[{to: { path: '/' },label: '首页'},{to: { path: '/breadcrumb' },label: '产品'},{'replace': true,'label': '软件'}]"
|
||||||
"label": "首页"
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"to": "{ path: '/breadcrumb' }",
|
|
||||||
"label": "产品"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"replace": "true",
|
|
||||||
"label": "软件"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -14275,7 +14271,7 @@
|
||||||
"schema": {
|
"schema": {
|
||||||
"componentName": "TinyTimeLine",
|
"componentName": "TinyTimeLine",
|
||||||
"props": {
|
"props": {
|
||||||
"active": "2",
|
"active": 2,
|
||||||
"data": [
|
"data": [
|
||||||
{
|
{
|
||||||
"name": "已下单"
|
"name": "已下单"
|
||||||
|
|
|
@ -86,11 +86,17 @@ export default {
|
||||||
.map((name) => fetchBlockSchema(name))
|
.map((name) => fetchBlockSchema(name))
|
||||||
|
|
||||||
const schemaList = await Promise.allSettled(promiseList)
|
const schemaList = await Promise.allSettled(promiseList)
|
||||||
|
const extraList = []
|
||||||
|
|
||||||
schemaList.forEach((item) => {
|
schemaList.forEach((item) => {
|
||||||
if (item.status === 'fulfilled' && item.value?.[0]?.content) {
|
if (item.status === 'fulfilled' && item.value?.[0]?.content) {
|
||||||
res.push(item.value[0].content)
|
res.push(item.value[0].content)
|
||||||
res.push(...getBlocksSchema(item.value[0].content, blockSet))
|
extraList.push(getBlocksSchema(item.value[0].content, blockSet))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
;(await Promise.allSettled(extraList)).forEach((item) => {
|
||||||
|
if (item.status === 'fulfilled' && item.value) {
|
||||||
|
res.push(...item.value)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -136,11 +142,10 @@ export default {
|
||||||
},
|
},
|
||||||
...(blocks || []).map((blockSchema) => {
|
...(blocks || []).map((blockSchema) => {
|
||||||
return {
|
return {
|
||||||
panelName: blockSchema.fileName,
|
panelName: `${blockSchema.fileName}.vue`,
|
||||||
panelValue:
|
panelValue:
|
||||||
genSFCWithDefaultPlugin(blockSchema, appData?.componentsMap || [], { blockRelativePath: './' }) || '',
|
genSFCWithDefaultPlugin(blockSchema, appData?.componentsMap || [], { blockRelativePath: './' }) || '',
|
||||||
panelType: 'vue',
|
panelType: 'vue'
|
||||||
index: true
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<tiny-dialog-box
|
<tiny-dialog-box
|
||||||
v-show="dialogVisible"
|
:visible="dialogVisible"
|
||||||
title="事件绑定"
|
title="事件绑定"
|
||||||
width="50%"
|
width="50%"
|
||||||
:append-to-body="true"
|
:append-to-body="true"
|
||||||
|
|
|
@ -69,7 +69,6 @@ import { ref, watch } from 'vue'
|
||||||
import { Collapse, CollapseItem, Input } from '@opentiny/vue'
|
import { Collapse, CollapseItem, Input } from '@opentiny/vue'
|
||||||
import { useHistory, useCanvas, useProperties } from '@opentiny/tiny-engine-controller'
|
import { useHistory, useCanvas, useProperties } from '@opentiny/tiny-engine-controller'
|
||||||
import { MetaCodeEditor, MetaBindVariable } from '@opentiny/tiny-engine-common'
|
import { MetaCodeEditor, MetaBindVariable } from '@opentiny/tiny-engine-common'
|
||||||
import { formatString } from '@opentiny/tiny-engine-controller/js/ast'
|
|
||||||
import {
|
import {
|
||||||
SizeGroup,
|
SizeGroup,
|
||||||
LayoutGroup,
|
LayoutGroup,
|
||||||
|
@ -128,7 +127,7 @@ export default {
|
||||||
const { getSchema: getCanvasPageSchema, updateRect } = useCanvas().canvasApi.value
|
const { getSchema: getCanvasPageSchema, updateRect } = useCanvas().canvasApi.value
|
||||||
const pageSchema = getCanvasPageSchema()
|
const pageSchema = getCanvasPageSchema()
|
||||||
const schema = getSchema() || pageSchema
|
const schema = getSchema() || pageSchema
|
||||||
const styleString = formatString(styleStrRemoveRoot(content), 'css')
|
const styleString = styleStrRemoveRoot(content)
|
||||||
const currentSchema = getCurrentSchema() || pageSchema
|
const currentSchema = getCurrentSchema() || pageSchema
|
||||||
|
|
||||||
state.styleContent = content
|
state.styleContent = content
|
||||||
|
|
|
@ -429,7 +429,7 @@ export default {
|
||||||
|
|
||||||
properties[name] = {
|
properties[name] = {
|
||||||
value,
|
value,
|
||||||
text: value === 'auto' ? 'auto' : String(Number.parseInt(value || 0)), // 界面 box 中显示的数值
|
text: value === 'auto' ? 'auto' : String(Number.parseInt(value) || 0), // 界面 box 中显示的数值
|
||||||
setting: Boolean(value) // 属性是否已设置值
|
setting: Boolean(value) // 属性是否已设置值
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -61,6 +61,10 @@ export default {
|
||||||
props.property.value?.indexOf('px') > -1 ? Number.parseInt(props.property.value) : props.property.value
|
props.property.value?.indexOf('px') > -1 ? Number.parseInt(props.property.value) : props.property.value
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const updateStyle = (value) => {
|
||||||
|
emit('update', { [props.property.name]: value })
|
||||||
|
}
|
||||||
|
|
||||||
const sliderChange = () => {
|
const sliderChange = () => {
|
||||||
if (sliderFlag) {
|
if (sliderFlag) {
|
||||||
updateStyle(`${sliderValue.value}px`)
|
updateStyle(`${sliderValue.value}px`)
|
||||||
|
@ -83,11 +87,7 @@ export default {
|
||||||
|
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
sliderFlag = false
|
sliderFlag = false
|
||||||
updateStyle('')
|
updateStyle(null)
|
||||||
}
|
|
||||||
|
|
||||||
const updateStyle = (value) => {
|
|
||||||
emit('update', { [props.property.name]: value })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const inputChange = (property) => {
|
const inputChange = (property) => {
|
||||||
|
|
|
@ -231,7 +231,7 @@ export const stringify = (originParseList, styleObject, config = {}) => {
|
||||||
if (key.includes('comment')) {
|
if (key.includes('comment')) {
|
||||||
str += `${value.value}\n`
|
str += `${value.value}\n`
|
||||||
} else {
|
} else {
|
||||||
str += `${key}: ${value.value};\n`
|
str += `${key}: ${value.value === '' ? "''" : value.value};\n`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -249,7 +249,7 @@ export const stringify = (originParseList, styleObject, config = {}) => {
|
||||||
// 在 styleObject 的,可能有改动,所以需要用 styleObject 拼接
|
// 在 styleObject 的,可能有改动,所以需要用 styleObject 拼接
|
||||||
for (const [key, value] of Object.entries(styleObject[item.selectors].rules)) {
|
for (const [key, value] of Object.entries(styleObject[item.selectors].rules)) {
|
||||||
if (![null, undefined].includes(value)) {
|
if (![null, undefined].includes(value)) {
|
||||||
str += `${key}: ${value};\n`
|
str += `${key}: ${value === '' ? "''" : value};\n`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -266,7 +266,7 @@ export const stringify = (originParseList, styleObject, config = {}) => {
|
||||||
str += `${selector} {\n`
|
str += `${selector} {\n`
|
||||||
|
|
||||||
for (const [declKey, declValue] of Object.entries(value.rules)) {
|
for (const [declKey, declValue] of Object.entries(value.rules)) {
|
||||||
str += `${declKey}: ${declValue};\n`
|
str += `${declKey}: ${declValue === '' ? "''" : declValue};\n`
|
||||||
}
|
}
|
||||||
|
|
||||||
str += '}\n'
|
str += '}\n'
|
||||||
|
|
|
@ -28,6 +28,9 @@ export default defineConfig({
|
||||||
formats: ['es']
|
formats: ['es']
|
||||||
},
|
},
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
banner: 'import "./style.css"'
|
||||||
|
},
|
||||||
external: ['vue', /@opentiny\/tiny-engine.*/, /@opentiny\/vue.*/, /^prettier.*/]
|
external: ['vue', /@opentiny\/tiny-engine.*/, /@opentiny\/vue.*/, /^prettier.*/]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,9 @@
|
||||||
"vite": "^4.3.7",
|
"vite": "^4.3.7",
|
||||||
"vitest": "^1.4.0"
|
"vitest": "^1.4.0"
|
||||||
},
|
},
|
||||||
"dependencies": {},
|
"dependencies": {
|
||||||
|
"jszip": "^3.10.1"
|
||||||
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@opentiny/vue-renderless": "^3.14.0",
|
"@opentiny/vue-renderless": "^3.14.0",
|
||||||
"vue": "^3.4.15"
|
"vue": "^3.4.15"
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2023 - present TinyEngine Authors.
|
||||||
|
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by an MIT-style license.
|
||||||
|
*
|
||||||
|
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||||
|
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// browser File System Access API encapsulation
|
||||||
|
import JSZIP from 'jszip'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载文件到本地
|
||||||
|
* @param {Blob} blobData 文件二进制数据
|
||||||
|
* @param {string} fileName 文件名
|
||||||
|
*/
|
||||||
|
export function saveAs(blobData, fileName) {
|
||||||
|
const downloadLink = document.createElement('a')
|
||||||
|
downloadLink.download = fileName
|
||||||
|
downloadLink.style.display = 'none'
|
||||||
|
downloadLink.href = URL.createObjectURL(blobData)
|
||||||
|
document.body.appendChild(downloadLink)
|
||||||
|
downloadLink.click()
|
||||||
|
document.body.removeChild(downloadLink)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建一个zip
|
||||||
|
*/
|
||||||
|
export const createZip = () => {
|
||||||
|
return new JSZIP()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 往zip里面写入文件夹和文件
|
||||||
|
* @param {Array<FileInfo>} filesInfo 文件信息
|
||||||
|
* FileInfo.filePath 文件相对路径,以'/'相连
|
||||||
|
* FileInfo.fileContent 文件内容
|
||||||
|
* @param {ZipExtraInfo} ZipExtraInfo zip额外信息
|
||||||
|
* {string} zipName 打出来的zip名称
|
||||||
|
* {JSZIP} zipHandle 创建好的zip句柄,可以不传,不传就用新的
|
||||||
|
*/
|
||||||
|
export const writeZip = (filesInfo, { zipHandle, zipName } = {}) => {
|
||||||
|
let zip = zipHandle
|
||||||
|
if (!zipHandle) {
|
||||||
|
zip = createZip()
|
||||||
|
}
|
||||||
|
filesInfo.forEach(({ filePath, fileContent }) => {
|
||||||
|
const file = filePath.split('/')
|
||||||
|
const fileName = file.pop()
|
||||||
|
const path = file.join('/')
|
||||||
|
if (path) {
|
||||||
|
zip.folder(path).file(fileName, fileContent)
|
||||||
|
} else {
|
||||||
|
zip.file(fileName, fileContent)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 把打包的内容异步转成blob二进制格式
|
||||||
|
return zip.generateAsync({ type: 'blob' }).then((content) => {
|
||||||
|
// content就是blob数据
|
||||||
|
saveAs(content, `${zipName}.zip`)
|
||||||
|
})
|
||||||
|
}
|
|
@ -1,17 +1,23 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2023 - present TinyEngine Authors.
|
* Copyright (c) 2023 - present TinyEngine Authors.
|
||||||
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
|
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||||
*
|
*
|
||||||
* Use of this source code is governed by an MIT-style license.
|
* Use of this source code is governed by an MIT-style license.
|
||||||
*
|
*
|
||||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// browser File System Access API encapsulation
|
// browser File System Access API encapsulation
|
||||||
|
|
||||||
|
import { createZip, writeZip } from './fszip'
|
||||||
|
|
||||||
|
// 支持file system api的条件:存在这个方法 && 不处于iframe中
|
||||||
|
export const isSupportFileSystemAccess =
|
||||||
|
Object.prototype.hasOwnProperty.call(window, 'showDirectoryPicker') && window.self === window.top
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户选择并授权的文件夹根路径
|
* 获取用户选择并授权的文件夹根路径
|
||||||
* @param {*} options
|
* @param {*} options
|
||||||
|
@ -19,8 +25,8 @@
|
||||||
* @returns dirHandle 目录句柄
|
* @returns dirHandle 目录句柄
|
||||||
*/
|
*/
|
||||||
export const getUserBaseDirHandle = async (options = {}) => {
|
export const getUserBaseDirHandle = async (options = {}) => {
|
||||||
if (!window.showOpenFilePicker) {
|
if (!isSupportFileSystemAccess) {
|
||||||
throw new Error('不支持的浏览器!')
|
return createZip()
|
||||||
}
|
}
|
||||||
const dirHandle = await window.showDirectoryPicker({ mode: 'readwrite', ...options })
|
const dirHandle = await window.showDirectoryPicker({ mode: 'readwrite', ...options })
|
||||||
return dirHandle
|
return dirHandle
|
||||||
|
@ -75,8 +81,8 @@ export async function getFileHandle(baseDirHandle, filePath, { create = false }
|
||||||
* @returns fileHandle 文件句柄
|
* @returns fileHandle 文件句柄
|
||||||
*/
|
*/
|
||||||
export const getUserFileHandle = async (options = {}) => {
|
export const getUserFileHandle = async (options = {}) => {
|
||||||
if (!window.showOpenFilePicker) {
|
if (!isSupportFileSystemAccess) {
|
||||||
throw new Error('不支持的浏览器!')
|
throw new Error('不支持的浏览器或处于iframe中')
|
||||||
}
|
}
|
||||||
const [fileHandle] = await window.showOpenFilePicker({ mode: 'readwrite', ...options })
|
const [fileHandle] = await window.showOpenFilePicker({ mode: 'readwrite', ...options })
|
||||||
return fileHandle
|
return fileHandle
|
||||||
|
@ -166,16 +172,29 @@ export const writeFile = async (handle, { filePath, fileContent }) => {
|
||||||
* @param {Array<FileInfo>} filesInfo 文件信息
|
* @param {Array<FileInfo>} filesInfo 文件信息
|
||||||
* FileInfo.filePath 文件相对路径
|
* FileInfo.filePath 文件相对路径
|
||||||
* FileInfo.fileContent 文件内容
|
* FileInfo.fileContent 文件内容
|
||||||
|
* @param {Boolean} supportZipCache 是否支持zip缓存,zip缓存可能会导致文件不能及时更新,默认不缓存
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
export const writeFiles = async (baseDirHandle, filesInfo) => {
|
export const writeFiles = async (
|
||||||
|
baseDirHandle,
|
||||||
|
filesInfo,
|
||||||
|
zipName = 'tiny-engine-generate-code',
|
||||||
|
supportZipCache = false
|
||||||
|
) => {
|
||||||
if (!filesInfo?.length) {
|
if (!filesInfo?.length) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isSupportFileSystemAccess) {
|
||||||
|
const zipInfo = { zipName, zipHandle: supportZipCache && baseDirHandle }
|
||||||
|
await writeZip(filesInfo, zipInfo)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let directoryHandle = baseDirHandle
|
let directoryHandle = baseDirHandle
|
||||||
if (!directoryHandle) {
|
if (!directoryHandle) {
|
||||||
directoryHandle = await window.showDirectoryPicker({ mode: 'readwrite' })
|
directoryHandle = await window.showDirectoryPicker({ mode: 'readwrite' })
|
||||||
}
|
}
|
||||||
|
|
||||||
await Promise.all(filesInfo.map((fileInfo) => writeFile(baseDirHandle, fileInfo)))
|
await Promise.all(filesInfo.map((fileInfo) => writeFile(directoryHandle, fileInfo)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
const { rules } = require('../../.eslintrc')
|
||||||
|
|
||||||
/* eslint-env node */
|
/* eslint-env node */
|
||||||
require('@rushstack/eslint-patch/modern-module-resolution')
|
require('@rushstack/eslint-patch/modern-module-resolution')
|
||||||
|
|
||||||
|
@ -17,5 +19,6 @@ module.exports = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 忽略 expected 中的内容
|
// 忽略 expected 中的内容
|
||||||
ignorePatterns: ['**/**/expected/*', '**/**.ts']
|
ignorePatterns: ['**/**/expected/*', '**/**.ts'],
|
||||||
|
rules
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
"fs-extra": "^10.0.1",
|
"fs-extra": "^10.0.1",
|
||||||
"prettier": "^2.6.1",
|
"prettier": "^2.6.1",
|
||||||
"vite": "^4.3.7",
|
"vite": "^4.3.7",
|
||||||
"vite-plugin-static-copy": "^1.0.4",
|
"vite-plugin-static-copy": "^0.16.0",
|
||||||
"vitest": "^1.4.0",
|
"vitest": "^1.4.0",
|
||||||
"winston": "^3.10.0"
|
"winston": "^3.10.0"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { BUILTIN_COMPONENTS_MAP } from '@/constant'
|
||||||
import { getImportMap } from './parseImport'
|
import { getImportMap } from './parseImport'
|
||||||
import {
|
import {
|
||||||
genTemplateByHook,
|
genTemplateByHook,
|
||||||
|
@ -18,7 +19,8 @@ import {
|
||||||
handleI18nAttrHook,
|
handleI18nAttrHook,
|
||||||
handleObjBindAttrHook,
|
handleObjBindAttrHook,
|
||||||
handleEventAttrHook,
|
handleEventAttrHook,
|
||||||
handleTinyIconPropsHook
|
handleTinyIconPropsHook,
|
||||||
|
handleJsxModelValueUpdate
|
||||||
} from './generateAttribute'
|
} from './generateAttribute'
|
||||||
import {
|
import {
|
||||||
GEN_SCRIPT_HOOKS,
|
GEN_SCRIPT_HOOKS,
|
||||||
|
@ -212,6 +214,7 @@ export const genSFCWithDefaultPlugin = (schema, componentsMap, config = {}) => {
|
||||||
|
|
||||||
const defaultAttributeHook = [
|
const defaultAttributeHook = [
|
||||||
handleTinyGrid,
|
handleTinyGrid,
|
||||||
|
handleJsxModelValueUpdate,
|
||||||
handleConditionAttrHook,
|
handleConditionAttrHook,
|
||||||
handleLoopAttrHook,
|
handleLoopAttrHook,
|
||||||
handleSlotBindAttrHook,
|
handleSlotBindAttrHook,
|
||||||
|
@ -259,7 +262,10 @@ export const genSFCWithDefaultPlugin = (schema, componentsMap, config = {}) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return generateSFCFile(schema, componentsMap, newConfig)
|
// 兼容单独调用的场景,单独调用时,这里会默认加上 builtInComponents
|
||||||
|
const compsMapWithBuiltIn = [...componentsMap, ...BUILTIN_COMPONENTS_MAP]
|
||||||
|
|
||||||
|
return generateSFCFile(schema, compsMapWithBuiltIn, newConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default generateSFCFile
|
export default generateSFCFile
|
||||||
|
|
|
@ -229,7 +229,7 @@ export const handleSlotBindAttrHook = (schemaData) => {
|
||||||
let paramsValue = ''
|
let paramsValue = ''
|
||||||
|
|
||||||
if (Array.isArray(params)) {
|
if (Array.isArray(params)) {
|
||||||
paramsValue = `={ ${params.join(',')} }`
|
paramsValue = `="{ ${params.join(',')} }"`
|
||||||
} else if (typeof params === 'string') {
|
} else if (typeof params === 'string') {
|
||||||
paramsValue = `="${params}"`
|
paramsValue = `="${params}"`
|
||||||
}
|
}
|
||||||
|
@ -515,3 +515,28 @@ export const handleBindUtilsHooks = (schemaData, globalHooks, config) => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为 modelvalue 绑定自动生成 onUpdate:modelValue 事件绑定
|
||||||
|
* @param {*} schemaData
|
||||||
|
* @param {*} globalHooks
|
||||||
|
* @param {*} config
|
||||||
|
*/
|
||||||
|
export const handleJsxModelValueUpdate = (schemaData, globalHooks, config) => {
|
||||||
|
const { schema: { props = {} } = {} } = schemaData || {}
|
||||||
|
const isJSX = config.isJSX
|
||||||
|
|
||||||
|
if (!isJSX) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const propsEntries = Object.entries(props)
|
||||||
|
const modelValue = propsEntries.find(([_key, value]) => value?.type === JS_EXPRESSION && value?.model === true)
|
||||||
|
const hasUpdateModelValue = propsEntries.find(([key]) => isOn(key) && key.startsWith(`onUpdate:${modelValue?.[0]}`))
|
||||||
|
|
||||||
|
// jsx 形式的 modelvalue, 如果 schema 没有声明,出码需要同时声明 onUpdate:modelValue,否则更新失效
|
||||||
|
if (modelValue && !hasUpdateModelValue) {
|
||||||
|
// 添加 onUpdate:modelKey 事件,让后续钩子生成 对应的事件声明
|
||||||
|
props[`onUpdate:${modelValue?.[0]}`] = { type: JS_EXPRESSION, value: `(value) => ${modelValue[1].value}=value` }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -44,8 +44,8 @@ function genDependenciesPlugin(options = {}) {
|
||||||
.map((item) => {
|
.map((item) => {
|
||||||
let [key, value] = item
|
let [key, value] = item
|
||||||
|
|
||||||
if (value === '') {
|
if (typeof value === 'string') {
|
||||||
value = "''"
|
value = `'${value}'`
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value && typeof value === 'object') {
|
if (value && typeof value === 'object') {
|
||||||
|
@ -57,19 +57,19 @@ function genDependenciesPlugin(options = {}) {
|
||||||
.join(',')} })`
|
.join(',')} })`
|
||||||
|
|
||||||
const getterExpression = Object.entries(getters)
|
const getterExpression = Object.entries(getters)
|
||||||
.filter((item) => item.value?.type === 'JSFunction')
|
.filter((item) => item[1]?.type === 'JSFunction')
|
||||||
.map(([key, value]) => `${key}: ${value.value}`)
|
.map(([key, value]) => `${key}: ${value.value}`)
|
||||||
.join(',')
|
.join(',')
|
||||||
|
|
||||||
const actionExpressions = Object.entries(actions)
|
const actionExpressions = Object.entries(actions)
|
||||||
.filter((item) => item.value?.type === 'JSFunction')
|
.filter((item) => item[1]?.type === 'JSFunction')
|
||||||
.map(([key, value]) => `${key}: ${value.value}`)
|
.map(([key, value]) => `${key}: ${value.value}`)
|
||||||
.join(',')
|
.join(',')
|
||||||
|
|
||||||
const storeFiles = `
|
const storeFiles = `
|
||||||
${importStatement}
|
${importStatement}
|
||||||
export const ${id} = defineStore({
|
export const ${id} = defineStore({
|
||||||
id: ${id},
|
id: '${id}',
|
||||||
state: ${stateExpression},
|
state: ${stateExpression},
|
||||||
getters: { ${getterExpression} },
|
getters: { ${getterExpression} },
|
||||||
actions: { ${actionExpressions} }
|
actions: { ${actionExpressions} }
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
export { testState } from './testState'
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
export const testState = defineStore({
|
||||||
|
id: 'testState',
|
||||||
|
state: () => ({
|
||||||
|
name: 'testName',
|
||||||
|
license: '',
|
||||||
|
age: 18,
|
||||||
|
food: ['apple', 'orange', 'banana', 19],
|
||||||
|
desc: { description: 'hello world', money: 100, other: '', rest: ['a', 'b', 'c', 20] }
|
||||||
|
}),
|
||||||
|
getters: {
|
||||||
|
getAge: function getAge() {
|
||||||
|
return this.age
|
||||||
|
},
|
||||||
|
getName: function getName() {
|
||||||
|
return this.name
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
setAge: function setAge(age) {
|
||||||
|
this.age = age
|
||||||
|
},
|
||||||
|
setName: function setName(name) {
|
||||||
|
this.name = name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
|
@ -676,7 +676,43 @@ export const appSchemaDemo01 = {
|
||||||
value: 'function dataHanlder(res){\n return res;\n}'
|
value: 'function dataHanlder(res){\n return res;\n}'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
globalState: [],
|
globalState: [
|
||||||
|
{
|
||||||
|
id: 'testState',
|
||||||
|
state: {
|
||||||
|
name: 'testName',
|
||||||
|
license: '',
|
||||||
|
age: 18,
|
||||||
|
food: ['apple', 'orange', 'banana', 19],
|
||||||
|
desc: {
|
||||||
|
description: 'hello world',
|
||||||
|
money: 100,
|
||||||
|
other: '',
|
||||||
|
rest: ['a', 'b', 'c', 20]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getters: {
|
||||||
|
getAge: {
|
||||||
|
type: 'JSFunction',
|
||||||
|
value: 'function getAge() {\n return this.age \n}'
|
||||||
|
},
|
||||||
|
getName: {
|
||||||
|
type: 'JSFunction',
|
||||||
|
value: 'function getName() {\n return this.name \n}'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
setAge: {
|
||||||
|
type: 'JSFunction',
|
||||||
|
value: 'function setAge(age) {\n this.age = age; \n}'
|
||||||
|
},
|
||||||
|
setName: {
|
||||||
|
type: 'JSFunction',
|
||||||
|
value: 'function setName(name) {\n this.name = name; \n}'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
utils: [
|
utils: [
|
||||||
{
|
{
|
||||||
name: 'axios',
|
name: 'axios',
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { expect, test } from 'vitest'
|
||||||
|
import { genSFCWithDefaultPlugin } from '@/generator/vue/sfc'
|
||||||
|
import schema from './page.schema.json'
|
||||||
|
import componentsMap from './components-map.json'
|
||||||
|
import { formatCode } from '@/utils/formatCode'
|
||||||
|
|
||||||
|
test('should generate slot declaration correctly', async () => {
|
||||||
|
const res = genSFCWithDefaultPlugin(schema, componentsMap)
|
||||||
|
const formattedCode = formatCode(res, 'vue')
|
||||||
|
|
||||||
|
await expect(formattedCode).toMatchFileSnapshot('./expected/slotTest.vue')
|
||||||
|
})
|
|
@ -0,0 +1,9 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"componentName": "TinyTree",
|
||||||
|
"exportName": "Tree",
|
||||||
|
"package": "@opentiny/vue",
|
||||||
|
"version": "^3.10.0",
|
||||||
|
"destructuring": true
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,54 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<tiny-tree
|
||||||
|
:data="[
|
||||||
|
{ label: '一级 1', children: [{ label: '二级 1-1', children: [{ label: '三级 1-1-1' }] }] },
|
||||||
|
{
|
||||||
|
label: '一级 2',
|
||||||
|
children: [
|
||||||
|
{ label: '二级 2-1', children: [{ label: '三级 2-1-1' }] },
|
||||||
|
{ label: '二级 2-2', children: [{ label: '三级 2-2-1' }] }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<template #default="{ data }">
|
||||||
|
<span>{{ data.label }}</span></template
|
||||||
|
></tiny-tree
|
||||||
|
>
|
||||||
|
<tiny-tree
|
||||||
|
:data="[
|
||||||
|
{ label: '一级 1', children: [{ label: '二级 1-1', children: [{ label: '三级 1-1-1' }] }] },
|
||||||
|
{
|
||||||
|
label: '一级 2',
|
||||||
|
children: [
|
||||||
|
{ label: '二级 2-1', children: [{ label: '三级 2-1-1' }] },
|
||||||
|
{ label: '二级 2-2', children: [{ label: '三级 2-2-1' }] }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<template #default="data">
|
||||||
|
<span>{{ data.label }}</span></template
|
||||||
|
></tiny-tree
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { Tree as TinyTree } from '@opentiny/vue'
|
||||||
|
import * as vue from 'vue'
|
||||||
|
import { defineProps, defineEmits } from 'vue'
|
||||||
|
import { I18nInjectionKey } from 'vue-i18n'
|
||||||
|
|
||||||
|
const props = defineProps({})
|
||||||
|
|
||||||
|
const emit = defineEmits([])
|
||||||
|
const { t, lowcodeWrap, stores } = vue.inject(I18nInjectionKey).lowcode()
|
||||||
|
const wrap = lowcodeWrap(props, { emit })
|
||||||
|
wrap({ stores })
|
||||||
|
|
||||||
|
const state = vue.reactive({})
|
||||||
|
wrap({ state })
|
||||||
|
</script>
|
||||||
|
<style scoped></style>
|
|
@ -0,0 +1,143 @@
|
||||||
|
{
|
||||||
|
"state": {},
|
||||||
|
"methods": {},
|
||||||
|
"componentName": "Page",
|
||||||
|
"fileName": "createVm",
|
||||||
|
"css": "",
|
||||||
|
"props": {},
|
||||||
|
"lifeCycles": {},
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"componentName": "TinyTree",
|
||||||
|
"props": {
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"label": "一级 1",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"label": "二级 1-1",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"label": "三级 1-1-1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "一级 2",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"label": "二级 2-1",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"label": "三级 2-1-1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "二级 2-2",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"label": "三级 2-2-1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"id": "33f52342",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"componentName": "Template",
|
||||||
|
"props": {
|
||||||
|
"slot": {
|
||||||
|
"name": "default",
|
||||||
|
"params": ["data"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"componentName": "Text",
|
||||||
|
"props": {
|
||||||
|
"text": {
|
||||||
|
"type": "JSExpression",
|
||||||
|
"value": "data.label"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": "c225d165"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"id": "415d5f65"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentName": "TinyTree",
|
||||||
|
"props": {
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"label": "一级 1",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"label": "二级 1-1",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"label": "三级 1-1-1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "一级 2",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"label": "二级 2-1",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"label": "三级 2-1-1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "二级 2-2",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"label": "三级 2-2-1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"id": "33f52342",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"componentName": "Template",
|
||||||
|
"props": {
|
||||||
|
"slot": {
|
||||||
|
"name": "default",
|
||||||
|
"params": "data"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"componentName": "Text",
|
||||||
|
"props": {
|
||||||
|
"text": {
|
||||||
|
"type": "JSExpression",
|
||||||
|
"value": "data.label"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": "c225d165"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"id": "415d5f65"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"componentName": "TinyGrid",
|
||||||
|
"exportName": "Grid",
|
||||||
|
"package": "@opentiny/vue",
|
||||||
|
"version": "^3.10.0",
|
||||||
|
"destructuring": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentName": "TinyNumeric",
|
||||||
|
"exportName": "Numeric",
|
||||||
|
"package": "@opentiny/vue",
|
||||||
|
"version": "^3.10.0",
|
||||||
|
"destructuring": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"componentName": "TinyInput",
|
||||||
|
"exportName": "Input",
|
||||||
|
"package": "@opentiny/vue",
|
||||||
|
"version": "^3.10.0",
|
||||||
|
"destructuring": true
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,96 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<tiny-grid
|
||||||
|
:editConfig="{ trigger: 'click', mode: 'cell', showStatus: true }"
|
||||||
|
:columns="state.columns"
|
||||||
|
:data="[
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
name: 'GFD科技有限公司',
|
||||||
|
city: '福州',
|
||||||
|
employees: 800,
|
||||||
|
created_date: '2014-04-30 00:56:00',
|
||||||
|
boole: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
name: 'WWW科技有限公司',
|
||||||
|
city: '深圳',
|
||||||
|
employees: 300,
|
||||||
|
created_date: '2016-07-08 12:36:22',
|
||||||
|
boole: true
|
||||||
|
}
|
||||||
|
]"
|
||||||
|
></tiny-grid>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="jsx">
|
||||||
|
import { Grid as TinyGrid, Numeric as TinyNumeric, Input as TinyInput } from '@opentiny/vue'
|
||||||
|
import * as vue from 'vue'
|
||||||
|
import { defineProps, defineEmits } from 'vue'
|
||||||
|
import { I18nInjectionKey } from 'vue-i18n'
|
||||||
|
|
||||||
|
const props = defineProps({})
|
||||||
|
|
||||||
|
const emit = defineEmits([])
|
||||||
|
const { t, lowcodeWrap, stores } = vue.inject(I18nInjectionKey).lowcode()
|
||||||
|
const wrap = lowcodeWrap(props, { emit })
|
||||||
|
wrap({ stores })
|
||||||
|
|
||||||
|
const state = vue.reactive({
|
||||||
|
columns: [
|
||||||
|
{ type: 'index', width: 60 },
|
||||||
|
{ type: 'selection', width: 60 },
|
||||||
|
{
|
||||||
|
field: 'employees',
|
||||||
|
title: '员工数',
|
||||||
|
slots: {
|
||||||
|
default: ({ row, column, rowIndex }, h) => (
|
||||||
|
<div>
|
||||||
|
<TinyNumeric
|
||||||
|
allow-empty={true}
|
||||||
|
placeholder="请输入"
|
||||||
|
controlsPosition="right"
|
||||||
|
step={1}
|
||||||
|
modelValue={row.employees}
|
||||||
|
onChange={(...eventArgs) => onChangeNumber(eventArgs, row, column, rowIndex)}
|
||||||
|
onUpdate:modelValue={(value) => (row.employees = value)}
|
||||||
|
></TinyNumeric>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ field: 'created_date', title: '创建日期' },
|
||||||
|
{
|
||||||
|
field: 'city',
|
||||||
|
title: '城市',
|
||||||
|
slots: {
|
||||||
|
default: ({ row, column, rowIndex }, h) => (
|
||||||
|
<div>
|
||||||
|
<TinyInput
|
||||||
|
placeholder="请输入"
|
||||||
|
modelValue={row.city}
|
||||||
|
onChange={(...eventArgs) => onChangeInput(eventArgs, row, column, rowIndex)}
|
||||||
|
onUpdate:modelValue={(value) => (row.city = value)}
|
||||||
|
></TinyInput>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
wrap({ state })
|
||||||
|
|
||||||
|
const onChangeInput = wrap(function onChangeInput(eventArgs, args0, args1, args2) {
|
||||||
|
console.log('onChangeInput', eventArgs)
|
||||||
|
})
|
||||||
|
const onChangeNumber = wrap(function onChangeNumber(eventArgs, args0, args1, args2) {
|
||||||
|
console.log('onChangeNumber', eventArgs)
|
||||||
|
})
|
||||||
|
|
||||||
|
wrap({ onChangeInput, onChangeNumber })
|
||||||
|
</script>
|
||||||
|
<style scoped></style>
|
|
@ -0,0 +1,150 @@
|
||||||
|
{
|
||||||
|
"state": {},
|
||||||
|
"methods": {
|
||||||
|
"onChangeInput": {
|
||||||
|
"type": "JSFunction",
|
||||||
|
"value": "function onChangeInput(eventArgs,args0,args1,args2) {\n console.log('onChangeInput', eventArgs);\n}"
|
||||||
|
},
|
||||||
|
"onChangeNumber": {
|
||||||
|
"type": "JSFunction",
|
||||||
|
"value": "function onChangeNumber(eventArgs, args0, args1, args2) {\n console.log('onChangeNumber', eventArgs)\n}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"componentName": "Page",
|
||||||
|
"css": "",
|
||||||
|
"props": {},
|
||||||
|
"lifeCycles": {},
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"componentName": "div",
|
||||||
|
"props": {},
|
||||||
|
"id": "85375559",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"componentName": "TinyGrid",
|
||||||
|
"props": {
|
||||||
|
"editConfig": {
|
||||||
|
"trigger": "click",
|
||||||
|
"mode": "cell",
|
||||||
|
"showStatus": true
|
||||||
|
},
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"type": "index",
|
||||||
|
"width": 60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "selection",
|
||||||
|
"width": 60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "employees",
|
||||||
|
"title": "员工数",
|
||||||
|
"slots": {
|
||||||
|
"default": {
|
||||||
|
"type": "JSSlot",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"componentName": "div",
|
||||||
|
"id": "44523622",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"componentName": "TinyNumeric",
|
||||||
|
"props": {
|
||||||
|
"allow-empty": true,
|
||||||
|
"placeholder": "请输入",
|
||||||
|
"controlsPosition": "right",
|
||||||
|
"step": 1,
|
||||||
|
"modelValue": {
|
||||||
|
"type": "JSExpression",
|
||||||
|
"value": "row.employees",
|
||||||
|
"model": true
|
||||||
|
},
|
||||||
|
"onChange": {
|
||||||
|
"type": "JSExpression",
|
||||||
|
"value": "this.onChangeNumber",
|
||||||
|
"params": ["row", "column", "rowIndex"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": "62166343"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": ["row", "column", "rowIndex"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "created_date",
|
||||||
|
"title": "创建日期"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "city",
|
||||||
|
"title": "城市",
|
||||||
|
"slots": {
|
||||||
|
"default": {
|
||||||
|
"type": "JSSlot",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"componentName": "div",
|
||||||
|
"id": "66326314",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"componentName": "TinyInput",
|
||||||
|
"props": {
|
||||||
|
"placeholder": "请输入",
|
||||||
|
"modelValue": {
|
||||||
|
"type": "JSExpression",
|
||||||
|
"value": "row.city",
|
||||||
|
"model": true
|
||||||
|
},
|
||||||
|
"onChange": {
|
||||||
|
"type": "JSExpression",
|
||||||
|
"value": "this.onChangeInput",
|
||||||
|
"params": ["row", "column", "rowIndex"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": "22396a2a"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": ["row", "column", "rowIndex"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"id": "1",
|
||||||
|
"name": "GFD科技有限公司",
|
||||||
|
"city": "福州",
|
||||||
|
"employees": 800,
|
||||||
|
"created_date": "2014-04-30 00:56:00",
|
||||||
|
"boole": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2",
|
||||||
|
"name": "WWW科技有限公司",
|
||||||
|
"city": "深圳",
|
||||||
|
"employees": 300,
|
||||||
|
"created_date": "2016-07-08 12:36:22",
|
||||||
|
"boole": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"id": "63623253"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dataSource": {
|
||||||
|
"list": []
|
||||||
|
},
|
||||||
|
"utils": [],
|
||||||
|
"bridge": [],
|
||||||
|
"inputs": [],
|
||||||
|
"outputs": [],
|
||||||
|
"fileName": "slotModelValueTest"
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { expect, test } from 'vitest'
|
||||||
|
import { genSFCWithDefaultPlugin } from '@/generator/vue/sfc'
|
||||||
|
import schema from './page.schema.json'
|
||||||
|
import componentsMap from './components-map.json'
|
||||||
|
import { formatCode } from '@/utils/formatCode'
|
||||||
|
|
||||||
|
test('should generate onUpdate:modelValue event', async () => {
|
||||||
|
const res = genSFCWithDefaultPlugin(schema, componentsMap)
|
||||||
|
const formattedCode = formatCode(res, 'vue')
|
||||||
|
|
||||||
|
await expect(formattedCode).toMatchFileSnapshot('./expected/slotModelValueTest.vue')
|
||||||
|
})
|
|
@ -17,7 +17,7 @@ import { viteStaticCopy } from 'vite-plugin-static-copy'
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
test: {
|
test: {
|
||||||
exclude: ['**/result/**'],
|
exclude: ['**/result/**', 'node_modules'],
|
||||||
watchExclude: ['**/result/**']
|
watchExclude: ['**/result/**']
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
|
|
|
@ -12,7 +12,10 @@ const materialsDir = 'materials'
|
||||||
const bundlePath = path.join(process.cwd(), '/packages/design-core/public/mock/bundle.json')
|
const bundlePath = path.join(process.cwd(), '/packages/design-core/public/mock/bundle.json')
|
||||||
// mockServer应用数据
|
// mockServer应用数据
|
||||||
const appInfoPath = path.join(process.cwd(), '/mockServer/src/services/appinfo.json')
|
const appInfoPath = path.join(process.cwd(), '/mockServer/src/services/appinfo.json')
|
||||||
|
const appSchemaPath = path.join(process.cwd(), 'mockServer/src/mock/get/app-center/v1/apps/schema/918.json')
|
||||||
|
|
||||||
const appInfo = fsExtra.readJSONSync(appInfoPath)
|
const appInfo = fsExtra.readJSONSync(appInfoPath)
|
||||||
|
const appSchema = fsExtra.readJSONSync(appSchemaPath)
|
||||||
|
|
||||||
const connection = new MysqlConnection()
|
const connection = new MysqlConnection()
|
||||||
|
|
||||||
|
@ -22,6 +25,7 @@ const connection = new MysqlConnection()
|
||||||
const write = (bundle) => {
|
const write = (bundle) => {
|
||||||
fsExtra.outputJSONSync(bundlePath, bundle, { spaces: 2 })
|
fsExtra.outputJSONSync(bundlePath, bundle, { spaces: 2 })
|
||||||
fsExtra.outputJSONSync(appInfoPath, appInfo, { spaces: 2 })
|
fsExtra.outputJSONSync(appInfoPath, appInfo, { spaces: 2 })
|
||||||
|
fsExtra.outputJSONSync(appSchemaPath, appSchema, { spaces: 2 })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,13 +40,13 @@ const validateComponent = (file, component) => {
|
||||||
const requiredList = requiredFields.filter((field) => !fields.includes(field))
|
const requiredList = requiredFields.filter((field) => !fields.includes(field))
|
||||||
|
|
||||||
if (requiredList.length) {
|
if (requiredList.length) {
|
||||||
logger.error(`组件文件 ${file} 缺少必要字段:${requiredList.join('、')}。`)
|
logger.error(`missing required fields: ${requiredList.join(',')} at ${file}.`)
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!component.npm) {
|
if (!component.npm) {
|
||||||
logger.warn(`组件文件 ${file} 缺少 npm 字段,出码时将不能通过import语句导入组件。`)
|
logger.warn(`missing the \`npm\` field, and it cannot be imported when coding at ${file}.`)
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -62,7 +66,7 @@ const validateBlock = (file, block) => {
|
||||||
const requiredList = requiredFields.filter((field) => !fields.includes(field))
|
const requiredList = requiredFields.filter((field) => !fields.includes(field))
|
||||||
|
|
||||||
if (requiredList.length) {
|
if (requiredList.length) {
|
||||||
logger.error(`区块文件 ${file} 缺少必要字段:${requiredList.join('、')}。`)
|
logger.error(`missing required fields: ${requiredList.join(',')} at ${file}.`)
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -80,7 +84,7 @@ const generateComponents = () => {
|
||||||
try {
|
try {
|
||||||
fg([`${materialsDir}/**/*.json`]).then((files) => {
|
fg([`${materialsDir}/**/*.json`]).then((files) => {
|
||||||
if (!files.length) {
|
if (!files.length) {
|
||||||
logger.warn('物料文件夹为空,请先执行`pnpm splitMaterials`命令拆分物料资产包')
|
logger.warn('please execute `pnpm splitMaterials` first to split the materials.')
|
||||||
}
|
}
|
||||||
|
|
||||||
const bundle = {
|
const bundle = {
|
||||||
|
@ -95,6 +99,7 @@ const generateComponents = () => {
|
||||||
}
|
}
|
||||||
const { components = [], snippets = [], blocks = [] } = bundle.data.materials
|
const { components = [], snippets = [], blocks = [] } = bundle.data.materials
|
||||||
const componentsMap = []
|
const componentsMap = []
|
||||||
|
const packagesMap = []
|
||||||
const appInfoBlocksLabels = appInfo.blockHistories.map((item) => item.label)
|
const appInfoBlocksLabels = appInfo.blockHistories.map((item) => item.label)
|
||||||
|
|
||||||
files.forEach((file) => {
|
files.forEach((file) => {
|
||||||
|
@ -103,7 +108,7 @@ const generateComponents = () => {
|
||||||
if (!material) {
|
if (!material) {
|
||||||
const fileFullPath = path.join(process.cwd(), file)
|
const fileFullPath = path.join(process.cwd(), file)
|
||||||
|
|
||||||
logger.error(`文件格式有误 (${fileFullPath})`)
|
logger.error(`incorrect file format at ${fileFullPath}.`)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -151,13 +156,31 @@ const generateComponents = () => {
|
||||||
|
|
||||||
appInfo.materialHistory.components = componentsMap
|
appInfo.materialHistory.components = componentsMap
|
||||||
|
|
||||||
write(bundle)
|
const { package: packageName = '', version = '', exportName = '' } = npm || {}
|
||||||
|
|
||||||
|
const mapItem = {
|
||||||
|
componentName: component,
|
||||||
|
package: packageName,
|
||||||
|
version,
|
||||||
|
exportName
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof npm.destructuring === 'boolean') {
|
||||||
|
mapItem.destructuring = npm.destructuring
|
||||||
|
}
|
||||||
|
|
||||||
|
if (npm.package) {
|
||||||
|
packagesMap.push(mapItem)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
appSchema.data.componentsMap = packagesMap
|
||||||
|
write(bundle)
|
||||||
})
|
})
|
||||||
|
|
||||||
logger.success('物料资产包构建成功')
|
logger.success('materials built.')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`物料资产包构建失败:${error}`)
|
logger.error(`failed to build materials: ${error}.`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,13 +189,13 @@ const watcher = chokidar.watch(`${materialsDir}/**/*.json`, { ignoreInitial: tru
|
||||||
|
|
||||||
watcher.on('all', (event, file) => {
|
watcher.on('all', (event, file) => {
|
||||||
const eventMap = {
|
const eventMap = {
|
||||||
add: '新增',
|
add: 'added',
|
||||||
change: '更新',
|
change: 'changed',
|
||||||
unlink: '删除'
|
unlink: 'deleted'
|
||||||
}
|
}
|
||||||
const fileFullPath = path.join(process.cwd(), file)
|
const fileFullPath = path.join(process.cwd(), file)
|
||||||
|
|
||||||
logger.info(`${eventMap[event]}组件文件 (${fileFullPath})`)
|
logger.info(`${fileFullPath} ${eventMap[event]}, rebuilding materials...`)
|
||||||
|
|
||||||
// 监听物料文件变化,更新物料资产包
|
// 监听物料文件变化,更新物料资产包
|
||||||
generateComponents()
|
generateComponents()
|
||||||
|
|
|
@ -38,10 +38,10 @@ class MysqlConnection {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.connection.connect((error) => {
|
this.connection.connect((error) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
logger.warn('未能连接到数据库,请查看数据库配置是否正确')
|
logger.warn('unable to connect to the database, please check the database configuration is correct.')
|
||||||
reject()
|
reject()
|
||||||
} else {
|
} else {
|
||||||
logger.success('数据库连接成功')
|
logger.success('database connected.')
|
||||||
this.connected = true
|
this.connected = true
|
||||||
resolve()
|
resolve()
|
||||||
}
|
}
|
||||||
|
@ -100,11 +100,11 @@ class MysqlConnection {
|
||||||
* @returns boolean 校验组件字段是否失败,false-有字段出错
|
* @returns boolean 校验组件字段是否失败,false-有字段出错
|
||||||
*/
|
*/
|
||||||
isValid(component, file) {
|
isValid(component, file) {
|
||||||
const longtextFields = ['name', 'npm', 'snippets', 'schema_fragment', 'configure', 'component_metadata']
|
const longTextFields = ['name', 'npm', 'snippets', 'schema_fragment', 'configure', 'component_metadata']
|
||||||
|
|
||||||
return Object.entries(component).every(([key, value]) => {
|
return Object.entries(component).every(([key, value]) => {
|
||||||
if (longtextFields.includes(key) && value !== null && typeof value !== 'object') {
|
if (longTextFields.includes(key) && value !== null && typeof value !== 'object') {
|
||||||
logger.error(`"${key}" 的值不是有效的JSON (${file})`)
|
logger.error(`the value of "${key}" is not valid JSON at ${file}.`)
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -193,10 +193,10 @@ class MysqlConnection {
|
||||||
|
|
||||||
this.query(sqlContent, component.component)
|
this.query(sqlContent, component.component)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
logger.success(`组件 ${component.component} 数据更新成功`)
|
logger.success(`${component.component} updated.`)
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
logger.error(`组件 ${component.component} 数据更新失败 ${error}`)
|
logger.error(`failed to update ${component.component}: ${error}.`)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,11 +322,11 @@ class MysqlConnection {
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
const id = result.insertId
|
const id = result.insertId
|
||||||
|
|
||||||
logger.success(`组件 ${component.component} 数据新增成功`)
|
logger.success(`${component.component} added.`)
|
||||||
this.relationMaterialHistory(id)
|
this.relationMaterialHistory(id)
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
logger.success(`组件 ${component.component} 数据新增失败:${error}`)
|
logger.error(`add ${component.component} failed:${error}.`)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,7 +344,7 @@ class MysqlConnection {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
logger.success(`查询组件 ${component.component} 失败:${error}`)
|
logger.error(`query ${component.component} failed:${error}.`)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,11 +395,11 @@ class MysqlConnection {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.query(sqlContent)
|
this.query(sqlContent)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
logger.success(`表 ${componentsTableName} 创建成功`)
|
logger.success(`table ${componentsTableName} created.`)
|
||||||
resolve(result)
|
resolve(result)
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
logger.success(`表 ${componentsTableName} 创建失败:${error}`)
|
logger.error(`create table ${componentsTableName} failed:${error}.`)
|
||||||
reject(error)
|
reject(error)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -51,9 +51,9 @@ const splitMaterials = () => {
|
||||||
fs.outputJsonSync(blockPath, block, { spaces: 2 })
|
fs.outputJsonSync(blockPath, block, { spaces: 2 })
|
||||||
})
|
})
|
||||||
|
|
||||||
logger.success('拆分物料资产包完成')
|
logger.success('materials splitted.')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`拆分物料资产包失败: ${error}`)
|
logger.error(`failed to split materials: ${error}.`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue