2929 </a-radio-group >
3030 <a-label v-else >{{ llmTypeName }}</a-label >
3131 </a-form-item >
32- <a-form-item :label =" $t('aice.llm_image')" >
32+ <template v-if =" form .fd .llm_type === ' dify' " >
33+ <a-form-item :label =" $t('aice.dify_api_image')" >
34+ <base-select
35+ v-decorator =" decorators.dify_api_image_id"
36+ resource =" llm_images"
37+ :params =" { ...appImageParams, $t: 'dify_api_image' }"
38+ :selectProps =" { placeholder: $t('common.tips.select', [$t('aice.dify_api_image')]) }" />
39+ </a-form-item >
40+ <a-form-item :label =" $t('aice.dify_plugin_image')" >
41+ <base-select
42+ v-decorator =" decorators.dify_plugin_image_id"
43+ resource =" llm_images"
44+ :params =" { ...appImageParams, $t: 'dify_plugin_image' }"
45+ :selectProps =" { placeholder: $t('common.tips.select', [$t('aice.dify_plugin_image')]) }" />
46+ </a-form-item >
47+ <a-form-item :label =" $t('aice.dify_sandbox_image')" >
48+ <base-select
49+ v-decorator =" decorators.dify_sandbox_image_id"
50+ resource =" llm_images"
51+ :params =" { ...appImageParams, $t: 'dify_sandbox_image' }"
52+ :selectProps =" { placeholder: $t('common.tips.select', [$t('aice.dify_sandbox_image')]) }" />
53+ </a-form-item >
54+ <a-form-item :label =" $t('aice.dify_ssrf_image')" >
55+ <base-select
56+ v-decorator =" decorators.dify_ssrf_image_id"
57+ resource =" llm_images"
58+ :params =" { ...appImageParams, $t: 'dify_ssr_image' }"
59+ :selectProps =" { placeholder: $t('common.tips.select', [$t('aice.dify_ssr_image')]) }" />
60+ </a-form-item >
61+ <a-form-item :label =" $t('aice.dify_weaviate_image')" >
62+ <base-select
63+ v-decorator =" decorators.dify_weaviate_image_id"
64+ resource =" llm_images"
65+ :params =" { ...appImageParams, $t: 'dify_weaviate_image' }"
66+ :selectProps =" { placeholder: $t('common.tips.select', [$t('aice.dify_weaviate_image')]) }" />
67+ </a-form-item >
68+ <a-form-item :label =" $t('aice.dify_web_image')" >
69+ <base-select
70+ v-decorator =" decorators.dify_web_image_id"
71+ resource =" llm_images"
72+ :params =" { ...appImageParams, $t: 'dify_web_image' }"
73+ :selectProps =" { placeholder: $t('common.tips.select', [$t('aice.dify_web_image')]) }" />
74+ </a-form-item >
75+ <a-form-item :label =" $t('aice.nginx_image')" >
76+ <base-select
77+ v-decorator =" decorators.nginx_image_id"
78+ resource =" llm_images"
79+ :params =" { ...appImageParams, $t: 'nginx_image' }"
80+ :selectProps =" { placeholder: $t('common.tips.select', [$t('aice.nginx_image')]) }" />
81+ </a-form-item >
82+ <a-form-item :label =" $t('aice.postgres_image')" >
83+ <base-select
84+ v-decorator =" decorators.postgres_image_id"
85+ resource =" llm_images"
86+ :params =" { ...appImageParams, $t: 'postgres_image' }"
87+ :selectProps =" { placeholder: $t('common.tips.select', [$t('aice.postgres_image')]) }" />
88+ </a-form-item >
89+ <a-form-item :label =" $t('aice.redis_image')" >
90+ <base-select
91+ v-decorator =" decorators.redis_image_id"
92+ resource =" llm_images"
93+ :params =" { ...appImageParams, $t: 'redis_image' }"
94+ :selectProps =" { placeholder: $t('common.tips.select', [$t('aice.redis_image')]) }" />
95+ </a-form-item >
96+ </template >
97+ <a-form-item v-else :label =" $t('aice.llm_image')" >
3398 <base-select
3499 v-decorator =" decorators.llm_image_id"
35100 resource =" llm_images"
146211 </a-row >
147212 </a-form-item >
148213 </a-form >
149- <div class =" form-footer" >
150- <a-button type =" primary" @click =" handleConfirm" :loading =" loading" >{{ $t('dialog.ok') }}</a-button >
151- <a-button @click =" handleCancel" >{{ $t('dialog.cancel') }}</a-button >
152- </div >
153214 </div >
154215</template >
155216
@@ -214,6 +275,17 @@ export default {
214275 openclaw: openclawConf = {},
215276 port_mappings = [],
216277 } = data
278+ const {
279+ dify_api_image_id ,
280+ dify_plugin_image_id ,
281+ dify_sandbox_image_id ,
282+ dify_ssrf_image_id ,
283+ dify_weaviate_image_id ,
284+ dify_web_image_id ,
285+ nginx_image_id ,
286+ postgres_image_id ,
287+ redis_image_id ,
288+ } = llmSpec? .dify || {}
217289 // openclaw 优先来自 llm_spec.openclaw,其次兼容旧的顶层 openclaw 字段
218290 let openclawConfObj = llmSpec? .openclaw ?? openclawConf
219291 if (typeof openclawConfObj === ' string' ) {
@@ -245,7 +317,8 @@ export default {
245317 },
246318 }),
247319 fd: {
248- llm_type: rowLlmType || (LLM_TYPE_OPTIONS [0 ] && LLM_TYPE_OPTIONS [0 ].id ) || ' openclaw' ,
320+ // 须与 decorators.llm_type.initialValue 一致,否则 currentTypeFields / v-if 与真实选中类型不同步,初始化不展示类型字段
321+ llm_type: rowLlmType || defaultLlmType,
249322 },
250323 },
251324 decorators: {
@@ -285,6 +358,42 @@ export default {
285358 ],
286359 },
287360 ],
361+ dify_api_image_id: [
362+ ' dify_api_image_id' ,
363+ {
364+ initialValue: dify_api_image_id,
365+ rules: [
366+ { required: true , message: this .$t (' common.tips.select' , [this .$t (' aice.dify_api_image' )]) },
367+ ],
368+ },
369+ ],
370+ dify_plugin_image_id: [
371+ ' dify_plugin_image_id' ,
372+ {
373+ initialValue: dify_plugin_image_id,
374+ rules: [
375+ { required: true , message: this .$t (' common.tips.select' , [this .$t (' aice.dify_plugin_image' )]) },
376+ ],
377+ },
378+ ],
379+ dify_sandbox_image_id: [
380+ ' dify_sandbox_image_id' ,
381+ {
382+ initialValue: dify_sandbox_image_id,
383+ rules: [
384+ { required: true , message: this .$t (' common.tips.select' , [this .$t (' aice.dify_sandbox_image' )]) },
385+ ],
386+ },
387+ ],
388+ dify_ssrf_image_id: [
389+ ' dify_ssrf_image_id' ,
390+ {
391+ initialValue: dify_ssrf_image_id,
392+ rules: [
393+ { required: true , message: this .$t (' common.tips.select' , [this .$t (' aice.dify_ssr_image' )]) },
394+ ],
395+ },
396+ ],
288397 llm_type: [
289398 ' llm_type' ,
290399 {
@@ -294,6 +403,51 @@ export default {
294403 ],
295404 },
296405 ],
406+ dify_weaviate_image_id: [
407+ ' dify_weaviate_image_id' ,
408+ {
409+ initialValue: dify_weaviate_image_id,
410+ rules: [
411+ { required: true , message: this .$t (' common.tips.select' , [this .$t (' aice.dify_weaviate_image' )]) },
412+ ],
413+ },
414+ ],
415+ dify_web_image_id: [
416+ ' dify_web_image_id' ,
417+ {
418+ initialValue: dify_web_image_id,
419+ rules: [
420+ { required: true , message: this .$t (' common.tips.select' , [this .$t (' aice.dify_web_image' )]) },
421+ ],
422+ },
423+ ],
424+ nginx_image_id: [
425+ ' nginx_image_id' ,
426+ {
427+ initialValue: nginx_image_id,
428+ rules: [
429+ { required: true , message: this .$t (' common.tips.select' , [this .$t (' aice.nginx_image' )]) },
430+ ],
431+ },
432+ ],
433+ postgres_image_id: [
434+ ' postgres_image_id' ,
435+ {
436+ initialValue: postgres_image_id,
437+ rules: [
438+ { required: true , message: this .$t (' common.tips.select' , [this .$t (' aice.postgres_image' )]) },
439+ ],
440+ },
441+ ],
442+ redis_image_id: [
443+ ' redis_image_id' ,
444+ {
445+ initialValue: redis_image_id,
446+ rules: [
447+ { required: true , message: this .$t (' common.tips.select' , [this .$t (' aice.redis_image' )]) },
448+ ],
449+ },
450+ ],
297451 openclaw_agents_md: [
298452 ' openclaw_agents_md' ,
299453 {
@@ -375,7 +529,7 @@ export default {
375529 device: [
376530 ' device' ,
377531 {
378- initialValue: devices && devices[ 0 ] ? . model ,
532+ initialValue: devices && devices . length > 0 ? devices . map ( v => v . model ) : [] ,
379533 rules: [
380534 { required: true , message: this .$t (' common.tips.select' , [this .$t (' aice.devices' )]) },
381535 ],
@@ -406,8 +560,8 @@ export default {
406560 },
407561 },
408562 formItemLayout: {
409- wrapperCol: { span: 18 },
410- labelCol: { span: 5 },
563+ wrapperCol: { span: 20 },
564+ labelCol: { span: 4 },
411565 },
412566 envVars,
413567 projectName: (project_domain != null && tenant != null ) ? ` ${ project_domain} /${ tenant} ` : ' ' ,
@@ -519,6 +673,15 @@ export default {
519673 phone_image ,
520674 request_sync_image ,
521675 llm_image_id ,
676+ dify_api_image_id ,
677+ dify_plugin_image_id ,
678+ dify_sandbox_image_id ,
679+ dify_ssrf_image_id ,
680+ dify_weaviate_image_id ,
681+ dify_web_image_id ,
682+ nginx_image_id ,
683+ postgres_image_id ,
684+ redis_image_id ,
522685 cpu ,
523686 memory ,
524687 volume_size ,
@@ -577,7 +740,7 @@ export default {
577740 const v = pickTypeValues[key]
578741 if (v === undefined ) return
579742 if (key === ' device' ) {
580- data .devices = [ { model: v }]
743+ data .devices = v . map ( k => ( { model: k }))
581744 } else {
582745 data[key] = v
583746 }
@@ -594,6 +757,22 @@ export default {
594757 data .llm_spec = { openclaw: { workspace_templates } }
595758 }
596759 }
760+ if (effectiveLlmType === ' dify' ) {
761+ data .llm_spec = {
762+ dify: {
763+ dify_api_image_id: dify_api_image_id,
764+ dify_plugin_image_id: dify_plugin_image_id,
765+ dify_sandbox_image_id: dify_sandbox_image_id,
766+ dify_ssrf_image_id: dify_ssrf_image_id,
767+ dify_weaviate_image_id: dify_weaviate_image_id,
768+ dify_web_image_id: dify_web_image_id,
769+ nginx_image_id: nginx_image_id,
770+ postgres_image_id: postgres_image_id,
771+ redis_image_id: redis_image_id,
772+ },
773+ }
774+ delete data .llm_image_id
775+ }
597776 if (this .mode === ' edit' && this .onManager && this .editData ) {
598777 if (request_sync_image) data .request_sync_image = true
599778 await this .onManager (' update' , {
0 commit comments