houzhongjian
2024-08-08 820397e43a0b64d35c6d31d2a55475061438593b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<template>
  <ContentWrap>
    <el-row>
      <el-col>
        <div class="float-right mb-2">
          <el-button size="small" type="primary" @click="showJson">生成 JSON</el-button>
          <el-button size="small" type="success" @click="showOption">生成 Options</el-button>
          <el-button size="small" type="danger" @click="showTemplate">生成组件</el-button>
        </div>
      </el-col>
    </el-row>
    <!-- 表单设计器 -->
    <FcDesigner ref="designer" height="780px" />
  </ContentWrap>
 
  <!-- 弹窗:表单预览 -->
  <Dialog v-model="dialogVisible" :title="dialogTitle" max-height="600">
    <div v-if="dialogVisible" ref="editor">
      <el-button style="float: right" @click="copy(formData)">
        {{ t('common.copy') }}
      </el-button>
      <el-scrollbar height="580">
        <div>
          <pre><code v-dompurify-html="highlightedCode(formData)" class="hljs"></code></pre>
        </div>
      </el-scrollbar>
    </div>
  </Dialog>
</template>
<script lang="ts" setup>
import { useFormCreateDesigner } from '@/components/FormCreate'
import { useClipboard } from '@vueuse/core'
import { isString } from '@/utils/is'
 
import hljs from 'highlight.js' // 导入代码高亮文件
import 'highlight.js/styles/github.css' // 导入代码高亮样式
import xml from 'highlight.js/lib/languages/java'
import json from 'highlight.js/lib/languages/json'
import formCreate from '@form-create/element-ui'
 
defineOptions({ name: 'InfraBuild' })
 
const { t } = useI18n() // 国际化
const message = useMessage() // 消息
 
const designer = ref() // 表单设计器
const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formType = ref(-1) // 表单的类型:0 - 生成 JSON;1 - 生成 Options;2 - 生成组件
const formData = ref('') // 表单数据
useFormCreateDesigner(designer) // 表单设计器增强
 
/** 打开弹窗 */
const openModel = (title: string) => {
  dialogVisible.value = true
  dialogTitle.value = title
}
 
/** 生成 JSON */
const showJson = () => {
  openModel('生成 JSON')
  formType.value = 0
  formData.value = designer.value.getRule()
}
 
/** 生成 Options */
const showOption = () => {
  openModel('生成 Options')
  formType.value = 1
  formData.value = designer.value.getOption()
}
 
/** 生成组件 */
const showTemplate = () => {
  openModel('生成组件')
  formType.value = 2
  formData.value = makeTemplate()
}
 
const makeTemplate = () => {
  const rule = designer.value.getRule()
  const opt = designer.value.getOption()
  return `<template>
    <form-create
      v-model:api="fApi"
      :rule="rule"
      :option="option"
      @submit="onSubmit"
    ></form-create>
  </template>
  <script setup lang=ts>
    const faps = ref(null)
    const rule = ref('')
    const option = ref('')
    const init = () => {
      rule.value = formCreate.parseJson('${formCreate.toJson(rule).replaceAll('\\', '\\\\')}')
      option.value = formCreate.parseJson('${JSON.stringify(opt)}')
    }
    const onSubmit = (formData) => {
      //todo 提交表单
    }
    init()
  <\/script>`
}
 
/** 复制 **/
const copy = async (text: string) => {
  const { copy, copied, isSupported } = useClipboard({ source: text })
  if (!isSupported) {
    message.error(t('common.copyError'))
  } else {
    await copy()
    if (unref(copied)) {
      message.success(t('common.copySuccess'))
    }
  }
}
 
/**
 * 代码高亮
 */
const highlightedCode = (code) => {
  // 处理语言和代码
  let language = 'json'
  if (formType.value === 2) {
    language = 'xml'
  }
  if (!isString(code)) {
    code = JSON.stringify(code)
  }
  // 高亮
  const result = hljs.highlight(language, code, true)
  return result.value || '&nbsp;'
}
 
/** 初始化 **/
onMounted(async () => {
  // 注册代码高亮的各种语言
  hljs.registerLanguage('xml', xml)
  hljs.registerLanguage('json', json)
})
</script>