Skip to content

Commit 1390ddb

Browse files
paragraph
1 parent 7d898d8 commit 1390ddb

File tree

29 files changed

+1009
-239
lines changed

29 files changed

+1009
-239
lines changed

ui/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"axios": "^1.8.4",
2121
"dingtalk-jsapi": "^3.1.0",
2222
"element-plus": "^2.9.10",
23+
"md-editor-v3": "^5.6.1",
2324
"nprogress": "^0.2.0",
2425
"pinia": "^3.0.1",
2526
"use-element-plus-theme": "^0.0.5",

ui/src/components/dynamics-form/items/slider/Slider.vue

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,4 @@
33
</template>
44
<script setup lang="ts"></script>
55
<style lang="scss" scoped>
6-
.custom-slider {
7-
.el-input-number.is-without-controls .el-input__wrapper {
8-
padding: 0 !important;
9-
}
10-
}
116
</style>

ui/src/components/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ import InfiniteScroll from './infinite-scroll/index.vue'
1616
import ModelSelect from './model-select/index.vue'
1717
import ReadWrite from './read-write/index.vue'
1818
import AutoTooltip from './auto-tooltip/index.vue'
19+
import MdEditor from './markdown/MdEditor.vue'
20+
import MdPreview from './markdown/MdPreview.vue'
21+
import MdEditorMagnify from './markdown/MdEditorMagnify.vue'
1922
export default {
2023
install(app: App) {
2124
app.component('LogoFull', LogoFull)
@@ -35,5 +38,8 @@ export default {
3538
app.component('ModelSelect', ModelSelect)
3639
app.component('ReadWrite', ReadWrite)
3740
app.component('AutoTooltip', AutoTooltip)
41+
app.component('MdPreview', MdPreview)
42+
app.component('MdEditor', MdEditor)
43+
app.component('MdEditorMagnify', MdEditorMagnify)
3844
},
3945
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
<template>
2+
<div class="charts-container">
3+
<div ref="chartsRef" :style="style" v-resize="changeChartSize"></div>
4+
</div>
5+
</template>
6+
<script lang="ts" setup>
7+
import { onMounted, nextTick, watch, onBeforeUnmount, ref } from 'vue'
8+
import * as echarts from 'echarts'
9+
const tmp = ref()
10+
const props = defineProps<{ option: string }>()
11+
const chartsRef = ref()
12+
13+
const style = ref({
14+
height: '220px',
15+
width: '100%'
16+
})
17+
18+
function initChart() {
19+
if (chartsRef.value) {
20+
let myChart = echarts?.getInstanceByDom(chartsRef.value)
21+
if (myChart === null || myChart === undefined) {
22+
myChart = echarts.init(chartsRef.value)
23+
}
24+
const option = JSON.parse(props.option)
25+
if (option.actionType === 'EVAL') {
26+
myChart.setOption(evalParseOption(option), true)
27+
} else {
28+
myChart.setOption(jsonParseOption(option), true)
29+
}
30+
}
31+
}
32+
function jsonParseOption(option: any) {
33+
if (option.style) {
34+
style.value = option.style
35+
}
36+
37+
if (option.option) {
38+
// 渲染数据
39+
return option.option
40+
}
41+
return option
42+
}
43+
function evalParseOption(option_json: any) {
44+
if (option_json.style) {
45+
style.value = option_json.style
46+
}
47+
let option = {}
48+
echarts
49+
tmp.value = echarts
50+
eval(option_json.option)
51+
return option
52+
}
53+
54+
function changeChartSize() {
55+
echarts?.getInstanceByDom(chartsRef.value)?.resize()
56+
}
57+
58+
watch(
59+
() => props.option,
60+
(val) => {
61+
if (val) {
62+
nextTick(() => {
63+
initChart()
64+
})
65+
}
66+
}
67+
)
68+
69+
onMounted(() => {
70+
nextTick(() => {
71+
initChart()
72+
})
73+
})
74+
75+
onBeforeUnmount(() => {
76+
echarts.getInstanceByDom(chartsRef.value)?.dispose()
77+
})
78+
</script>
79+
<style lang="scss" scoped>
80+
.charts-container {
81+
overflow-x: auto;
82+
}
83+
.charts-container::-webkit-scrollbar-track-piece {
84+
background-color: rgba(0, 0, 0, 0);
85+
border-left: 1px solid rgba(0, 0, 0, 0);
86+
}
87+
88+
.charts-container::-webkit-scrollbar {
89+
width: 5px;
90+
height: 5px;
91+
-webkit-border-radius: 5px;
92+
-moz-border-radius: 5px;
93+
border-radius: 5px;
94+
}
95+
96+
.charts-container::-webkit-scrollbar-thumb {
97+
background-color: rgba(0, 0, 0, 0.5);
98+
99+
background-clip: padding-box;
100+
101+
-webkit-border-radius: 5px;
102+
103+
-moz-border-radius: 5px;
104+
105+
border-radius: 5px;
106+
107+
min-height: 28px;
108+
}
109+
110+
.charts-container::-webkit-scrollbar-thumb:hover {
111+
background-color: rgba(0, 0, 0, 0.5);
112+
113+
-webkit-border-radius: 5px;
114+
115+
-moz-border-radius: 5px;
116+
117+
border-radius: 5px;
118+
}
119+
</style>
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<template>
2+
<div>
3+
<DynamicsForm
4+
:disabled="is_submit || disabled"
5+
label-position="top"
6+
require-asterisk-position="right"
7+
ref="dynamicsFormRef"
8+
:render_data="form_field_list"
9+
label-suffix=":"
10+
v-model="form_data"
11+
:model="form_data"
12+
></DynamicsForm>
13+
<el-button
14+
:type="is_submit ? 'info' : 'primary'"
15+
:disabled="is_submit || disabled"
16+
@click="submit"
17+
>{{$t('common.submit')}}</el-button
18+
>
19+
</div>
20+
</template>
21+
<script setup lang="ts">
22+
import { computed, ref } from 'vue'
23+
import DynamicsForm from '@/components/dynamics-form/index.vue'
24+
const props = withDefaults(
25+
defineProps<{
26+
form_setting: string
27+
disabled?: boolean
28+
sendMessage?: (question: string, type: 'old' | 'new', other_params_data?: any) => void
29+
child_node?: any
30+
chat_record_id?: string
31+
runtime_node_id?: string
32+
}>(),
33+
{
34+
disabled: false
35+
}
36+
)
37+
const form_setting_data = computed(() => {
38+
if (props.form_setting) {
39+
return JSON.parse(props.form_setting)
40+
} else {
41+
return {}
42+
}
43+
})
44+
const _submit = ref<boolean>(false)
45+
/**
46+
* 表单字段列表
47+
*/
48+
const form_field_list = computed(() => {
49+
if (form_setting_data.value.form_field_list) {
50+
return form_setting_data.value.form_field_list
51+
}
52+
return []
53+
})
54+
const is_submit = computed(() => {
55+
if (_submit.value) {
56+
return true
57+
}
58+
if (form_setting_data.value.is_submit) {
59+
return form_setting_data.value.is_submit
60+
} else {
61+
return false
62+
}
63+
})
64+
const _form_data = ref<any>({})
65+
const form_data = computed({
66+
get: () => {
67+
if (form_setting_data.value.is_submit) {
68+
return form_setting_data.value.form_data
69+
} else {
70+
return _form_data.value
71+
}
72+
},
73+
set: (v) => {
74+
_form_data.value = v
75+
}
76+
})
77+
const dynamicsFormRef = ref<InstanceType<typeof DynamicsForm>>()
78+
const submit = () => {
79+
dynamicsFormRef.value?.validate().then(() => {
80+
_submit.value = true
81+
if (props.sendMessage) {
82+
props.sendMessage('', 'old', {
83+
child_node: props.child_node,
84+
runtime_node_id: props.runtime_node_id,
85+
chat_record_id: props.chat_record_id,
86+
node_data: form_data.value
87+
})
88+
}
89+
})
90+
}
91+
</script>
92+
<style lang="scss" scoped></style>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<template>
2+
<div ref="htmlRef" :innerHTML="source"></div>
3+
</template>
4+
<script setup lang="ts">
5+
import { onMounted, ref } from 'vue'
6+
const htmlRef = ref<HTMLElement>()
7+
const props = withDefaults(
8+
defineProps<{
9+
source?: string
10+
script_exec?: boolean
11+
}>(),
12+
{
13+
source: '',
14+
script_exec: true
15+
}
16+
)
17+
onMounted(() => {
18+
if (htmlRef.value && props.script_exec) {
19+
const range = document.createRange()
20+
range.selectNode(htmlRef.value)
21+
const scripts = htmlRef.value.getElementsByTagName('script')
22+
if (scripts) {
23+
var documentFragment = range.createContextualFragment(
24+
[...scripts]
25+
.map((item: HTMLElement) => {
26+
htmlRef.value?.removeChild(item)
27+
return item.outerHTML
28+
})
29+
.join('\n')
30+
)
31+
htmlRef.value.appendChild(documentFragment)
32+
}
33+
}
34+
})
35+
</script>
36+
<style lang="scss" scoped></style>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<template>
2+
<MdEditor :language="language" noIconfont noPrettier v-bind="$attrs">
3+
<template #defFooters>
4+
<slot name="defFooters"> </slot>
5+
</template>
6+
</MdEditor>
7+
</template>
8+
9+
<script setup lang="ts">
10+
import { computed } from 'vue'
11+
import { MdEditor, config } from 'md-editor-v3'
12+
import { getBrowserLang } from '@/locales/index'
13+
import './assets/markdown-iconfont.js'
14+
// 引入公共库中的语言配置
15+
import ZH_TW from '@vavt/cm-extension/dist/locale/zh-TW'
16+
17+
defineOptions({ name: 'MdEditor' })
18+
const language = computed(() => localStorage.getItem('MaxKB-locale') || getBrowserLang() || '')
19+
config({
20+
editorConfig: {
21+
languageUserDefined: {
22+
'zh-Hant': ZH_TW
23+
}
24+
}
25+
})
26+
</script>
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<template>
2+
<MdEditor
3+
v-bind="$attrs"
4+
v-model="data"
5+
:preview="false"
6+
:toolbars="[]"
7+
class="magnify-md-editor"
8+
:footers="footers"
9+
>
10+
<template #defFooters>
11+
<el-button text type="info" @click="openDialog">
12+
<AppIcon class="color-secondary" iconName="app-magnify" style="font-size: 16px"></AppIcon>
13+
</el-button>
14+
</template>
15+
</MdEditor>
16+
<!-- 回复内容弹出层 -->
17+
<el-dialog v-model="dialogVisible" :title="title" append-to-body align-center>
18+
<MdEditor v-model="cloneContent" :preview="false" :toolbars="[]" :footers="[]"></MdEditor>
19+
<template #footer>
20+
<div class="dialog-footer mt-24">
21+
<el-button type="primary" @click="submitDialog"> {{ $t('common.confirm') }}</el-button>
22+
</div>
23+
</template>
24+
</el-dialog>
25+
</template>
26+
27+
<script setup lang="ts">
28+
import { ref, computed, watch } from 'vue'
29+
defineOptions({ name: 'MdEditorMagnify' })
30+
const props = defineProps<{
31+
title: String
32+
modelValue: any
33+
}>()
34+
const emit = defineEmits(['update:modelValue', 'submitDialog'])
35+
const data = computed({
36+
set: (value) => {
37+
emit('update:modelValue', value)
38+
},
39+
get: () => {
40+
return props.modelValue
41+
}
42+
})
43+
const dialogVisible = ref(false)
44+
watch(dialogVisible, (bool) => {
45+
if (!bool) {
46+
emit('submitDialog', cloneContent.value)
47+
}
48+
})
49+
50+
const cloneContent = ref('')
51+
const footers: any = [null, '=', 0]
52+
function openDialog() {
53+
cloneContent.value = props.modelValue
54+
dialogVisible.value = true
55+
}
56+
function submitDialog() {
57+
emit('submitDialog', cloneContent.value)
58+
dialogVisible.value = false
59+
}
60+
</script>
61+
62+
<style lang="scss" scoped>
63+
.magnify-md-editor {
64+
:deep(.md-editor-footer) {
65+
border: none !important;
66+
}
67+
}
68+
</style>

0 commit comments

Comments
 (0)