Skip to content

Commit 71cb848

Browse files
committed
feat(resource) handle conflict
2 parents 636a57f + f45f686 commit 71cb848

69 files changed

Lines changed: 9325 additions & 507 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/api/frontend-api/main-package-api.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export { default as Bridge } from '@opentiny/tiny-engine-plugin-bridge'
3434
export { default as Block, BlockService } from '@opentiny/tiny-engine-plugin-block'
3535
export { default as Datasource, DataSourceService } from '@opentiny/tiny-engine-plugin-datasource'
3636
export { default as Robot } from '@opentiny/tiny-engine-plugin-robot'
37+
export { default as ModelManager } from '@opentiny/tiny-engine-plugin-model-manager'
3738
export { default as Props, PropertiesService, PropertyService } from '@opentiny/tiny-engine-setting-props'
3839
export { default as Events } from '@opentiny/tiny-engine-setting-events'
3940
export { default as Styles } from '@opentiny/tiny-engine-setting-styles'

packages/build/vite-config/src/vite-plugins/devAliasPlugin.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const getDevAlias = (useSourceAlias) => {
3030
'@opentiny/tiny-engine-plugin-tutorial': path.resolve(basePath, 'packages/plugins/tutorial/index.ts'),
3131
'@opentiny/tiny-engine-plugin-robot': path.resolve(basePath, 'packages/plugins/robot/index.ts'),
3232
'@opentiny/tiny-engine-plugin-resource': path.resolve(basePath, 'packages/plugins/resource/index.ts'),
33+
'@opentiny/tiny-engine-plugin-model-manager': path.resolve(basePath, 'packages/plugins/model-manager/index.ts'),
3334
'@opentiny/tiny-engine-settings-panel': path.resolve(basePath, 'packages/settings/panel/index.ts'),
3435
'@opentiny/tiny-engine-setting-events': path.resolve(basePath, 'packages/settings/events/index.ts'),
3536
'@opentiny/tiny-engine-setting-props': path.resolve(basePath, 'packages/settings/props/index.ts'),
@@ -55,7 +56,6 @@ const getDevAlias = (useSourceAlias) => {
5556
'@opentiny/tiny-engine-canvas/render': path.resolve(basePath, 'packages/canvas/render/index.ts'),
5657
'@opentiny/tiny-engine-canvas': path.resolve(basePath, 'packages/canvas/index.ts'),
5758
'@opentiny/tiny-engine-utils': path.resolve(basePath, 'packages/utils/src/index.ts'),
58-
'@opentiny/tiny-engine-webcomponent-core': path.resolve(basePath, 'packages/webcomponent/src/lib.js'),
5959
'@opentiny/tiny-engine-i18n-host': path.resolve(basePath, 'packages/i18n/src/lib.ts'),
6060
'@opentiny/tiny-engine-builtin-component': path.resolve(basePath, 'packages/builtinComponent/index.ts'),
6161
'@opentiny/tiny-engine-meta-register': path.resolve(basePath, 'packages/register/src/index.ts'),

packages/builtinComponent/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,7 @@ export { default as CanvasRow } from './src/components/CanvasRow.vue'
33
export { default as CanvasRowColContainer } from './src/components/CanvasRowColContainer.vue'
44
export { default as CanvasFlexBox } from './src/components/CanvasFlexBox.vue'
55
export { default as CanvasSection } from './src/components/CanvasSection.vue'
6+
export { default as FormModel } from './src/components/BaseForm.vue'
7+
export { default as TableModel } from './src/components/BaseTable.vue'
8+
export { default as PageModel } from './src/components/BasePage.vue'
69
export { default as meta } from './src/meta'

packages/builtinComponent/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"preview": "vite preview"
2222
},
2323
"dependencies": {
24+
"axios": "^0.28.0",
2425
"vite-plugin-css-injected-by-js": "^3.3.1"
2526
},
2627
"devDependencies": {
@@ -29,6 +30,9 @@
2930
"vite": "^5.4.2"
3031
},
3132
"peerDependencies": {
33+
"@opentiny/vue": "^3.20.0",
34+
"@opentiny/vue-icon": "^3.20.0",
35+
"@opentiny/vue-renderless": "^3.20.0",
3236
"vue": "^3.4.15"
3337
}
3438
}
Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
<template>
2+
<div>
3+
<div class="placeholder-layer" v-if="!formModel || !formModel?.id">请选择表单模型</div>
4+
<tiny-form v-else ref="formRef" label-width="120" label-position="left" :model="modelData" v-bind="$attrs">
5+
<tiny-row>
6+
<tiny-col :span="colNumber" v-for="(item, index) in formModel.parameters" :key="index">
7+
<tiny-form-item :prop="item.prop">
8+
<template #label>
9+
<div class="custom-label" v-auto-tip>
10+
{{ item.label }}
11+
</div>
12+
</template>
13+
<div v-if="item.isModel && item.defaultValue !== null">
14+
<tiny-form label-width="100" label-position="left" :model="modelData[item.prop]">
15+
<tiny-row>
16+
<tiny-col
17+
:span="insideColNumber"
18+
v-for="(insideItem, insideIndex) in item.defaultValue"
19+
:key="insideIndex"
20+
>
21+
<tiny-form-item :prop="insideItem.prop">
22+
<template #label>
23+
<div class="custom-label" v-auto-tip>
24+
{{ insideItem.label }}
25+
</div>
26+
</template>
27+
<component
28+
:is="componentsMap[insideItem.component]"
29+
v-model="modelData[item.prop][insideItem.prop]"
30+
:disabled="viewOnly"
31+
v-bind="insideItem"
32+
></component>
33+
</tiny-form-item>
34+
</tiny-col>
35+
</tiny-row>
36+
</tiny-form>
37+
</div>
38+
<component
39+
v-else
40+
:is="componentsMap[item.component]"
41+
v-model="modelData[item.prop]"
42+
:disabled="viewOnly"
43+
v-bind="item"
44+
></component>
45+
</tiny-form-item>
46+
</tiny-col>
47+
</tiny-row>
48+
</tiny-form>
49+
</div>
50+
</template>
51+
<script setup>
52+
import { ref, defineProps, defineExpose, computed, watch, reactive } from 'vue'
53+
import {
54+
Form as TinyForm,
55+
FormItem as TinyFormItem,
56+
Input as TinyInput,
57+
Select as TinySelect,
58+
Checkbox as TinyCheckbox,
59+
Radio as TinyRadio,
60+
DatePicker as TinyDatePicker,
61+
Numeric as TinyNumeric,
62+
Row as TinyRow,
63+
Col as TinyCol
64+
} from '@opentiny/vue'
65+
import axios from 'axios'
66+
67+
const props = defineProps({
68+
style: {
69+
type: String
70+
},
71+
className: {
72+
type: String
73+
},
74+
layout: {
75+
type: Number,
76+
default: 2
77+
},
78+
viewOnly: {
79+
type: Boolean,
80+
default: false
81+
},
82+
modelValue: {
83+
type: Object
84+
},
85+
serviceModel: {
86+
type: Object
87+
},
88+
modelApis: {
89+
type: Array,
90+
default: () => []
91+
}
92+
})
93+
94+
const modelData = ref()
95+
96+
const formRef = ref(null)
97+
98+
const colNumber = computed(() => 12 / props.layout)
99+
100+
const insideColNumber = computed(() => (props.layout === 1 ? 6 : 12))
101+
102+
const formModel = computed(() => props.serviceModel)
103+
104+
const componentsMap = reactive({
105+
TinyInput,
106+
TinySelect,
107+
TinyCheckbox,
108+
TinyRadio,
109+
TinyDatePicker,
110+
TinyNumeric
111+
})
112+
113+
const insertApi = (data = modelData.value) => {
114+
const apiInfo = props.modelApis.find((api) => api.nameEn === 'insertApi')
115+
if (!apiInfo) {
116+
return undefined
117+
}
118+
return axios[apiInfo.method](apiInfo.url, data)
119+
.then((res) => {
120+
if (res.status === 200) {
121+
return res.data
122+
} else {
123+
throw new Error('request fail')
124+
}
125+
})
126+
.catch((err) => {
127+
throw new Error(err)
128+
})
129+
}
130+
131+
const updateApi = (data = modelData.value) => {
132+
const apiInfo = props.modelApis.find((api) => api.nameEn === 'updateApi')
133+
if (!apiInfo) {
134+
return undefined
135+
}
136+
return axios[apiInfo.method](apiInfo.url, data)
137+
.then((res) => {
138+
if (res.status === 200) {
139+
return res.data
140+
} else {
141+
throw new Error('request fail')
142+
}
143+
})
144+
.catch((err) => {
145+
throw new Error(err)
146+
})
147+
}
148+
149+
const queryApi = ({ currentPage, pageSize, data } = {}) => {
150+
const apiInfo = props.modelApis.find((api) => api.nameEn === 'queryApi')
151+
if (!apiInfo) {
152+
return undefined
153+
}
154+
return axios[apiInfo.method](`${apiInfo.url}?currentPage=${currentPage || 1}&pageSize=${pageSize || 10}`, {
155+
params: data || modelData.value
156+
})
157+
.then((res) => {
158+
if (res.status === 200) {
159+
return res.data
160+
}
161+
throw new Error('request fail')
162+
})
163+
.catch((err) => {
164+
throw new Error(err)
165+
})
166+
}
167+
168+
const deleteApi = (evidence = { id: modelData.value?.id }) => {
169+
const apiInfo = props.modelApis.find((api) => api.nameEn === 'deleteApi')
170+
if (!apiInfo) {
171+
return undefined
172+
}
173+
return axios[apiInfo.method](apiInfo.url, { params: evidence })
174+
.then((res) => {
175+
if (res.status === 200) {
176+
return res.data
177+
} else {
178+
throw new Error('request fail')
179+
}
180+
})
181+
.catch((err) => {
182+
throw new Error(err)
183+
})
184+
}
185+
186+
const initFormData = () => {
187+
modelData.value = Object.fromEntries(
188+
(formModel.value.parameters || []).map((item) => {
189+
return [
190+
item.prop,
191+
item?.isModel
192+
? Object.fromEntries(
193+
item.defaultValue.map((insideItem) => [insideItem.prop, insideItem.defaultValue || null])
194+
)
195+
: item.defaultValue || null
196+
]
197+
})
198+
)
199+
}
200+
201+
watch(
202+
() => props.modelValue,
203+
(value) => {
204+
if (value) {
205+
modelData.value = props.modelValue
206+
}
207+
},
208+
{ deep: true, immediate: true }
209+
)
210+
211+
watch(
212+
() => props.serviceModel,
213+
() => {
214+
if (!modelData.value) {
215+
initFormData()
216+
}
217+
},
218+
{ immediate: true }
219+
)
220+
221+
const exposedData = {
222+
formData: () => modelData.value,
223+
formRef,
224+
insertApi,
225+
updateApi,
226+
queryApi,
227+
deleteApi
228+
}
229+
230+
defineExpose({
231+
...exposedData
232+
})
233+
</script>
234+
<style lang="less" scoped>
235+
.placeholder-layer {
236+
height: 40px;
237+
background-color: #f5f5f5;
238+
width: 100%;
239+
text-align: center;
240+
line-height: 40px;
241+
}
242+
</style>

0 commit comments

Comments
 (0)