editTemplate.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. <template>
  2. <div class="sys-config-container">
  3. <el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="900px">
  4. <template #header>
  5. <div style="color: #fff">
  6. <el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
  7. <span> {{ props.title }} </span>
  8. </div>
  9. </template>
  10. <el-form :model="state.ruleForm" ref="ruleFormRef">
  11. <el-tabs v-model="state.selectedTabName">
  12. <el-tab-pane label="基础信息" name="1" >
  13. <el-row :gutter="35">
  14. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
  15. <el-form-item label="名称" prop="name" :rules="[{ required: true, message: '名称不能为空', trigger: 'blur' }]">
  16. <el-input v-model="state.ruleForm.name" placeholder="名称" clearable />
  17. </el-form-item>
  18. </el-col>
  19. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
  20. <el-form-item label="编码" prop="code" :rules="[{ required: true, message: '编码不能为空', trigger: 'blur' }]">
  21. <el-input v-model="state.ruleForm.code" placeholder="编码" clearable />
  22. </el-form-item>
  23. </el-col>
  24. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
  25. <el-form-item label="分组" prop="groupName" :rules="[{ required: true, message: '分组不能为空', trigger: 'blur' }]">
  26. <el-input v-model="state.ruleForm.groupName" placeholder="分组" clearable />
  27. </el-form-item>
  28. </el-col>
  29. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
  30. <el-form-item label="类型" prop="type" :rules="[{ required: true, message: '类型不能为空', trigger: 'blur' }]">
  31. <g-sys-dict v-model="state.ruleForm.type" code="TemplateTypeEnum" render-as="select"/>
  32. </el-form-item>
  33. </el-col>
  34. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
  35. <el-form-item label="排序">
  36. <el-input-number v-model="state.ruleForm.orderNo" placeholder="排序" class="w100" />
  37. </el-form-item>
  38. </el-col>
  39. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
  40. <el-form-item label="备注">
  41. <el-input v-model="state.ruleForm.remark" placeholder="请输入备注内容" clearable type="textarea" />
  42. </el-form-item>
  43. </el-col>
  44. </el-row>
  45. </el-tab-pane>
  46. <el-tab-pane label="模板内容" name="2">
  47. <el-row :gutter="5">
  48. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
  49. <el-form-item label="内容类型">
  50. <el-radio-group v-model="state.contentType">
  51. <el-radio :value="1">富文本</el-radio>
  52. <el-radio :value="2">纯文本</el-radio>
  53. </el-radio-group>
  54. <el-button class="ml35" @click="() => editorRef?.ref?.insertNode({ text: '@(name)' })">插入参数</el-button>
  55. </el-form-item>
  56. </el-col>
  57. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
  58. <el-form-item label="内容" prop="content" :rules="[{ required: true, message: '内容不能为空', trigger: 'blur' }]" label-position="top">
  59. <Editor v-model:get-html="state.ruleForm.content" ref="editorRef" height="200px" v-if="state.contentType == 1" />
  60. <el-input v-model="state.ruleForm.content" v-else type="textarea" :rows="15" show-word-limit clearable />
  61. </el-form-item>
  62. </el-col>
  63. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20" style="user-select: none;">
  64. <el-row :gutter="5">
  65. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20" title="双击删除参数项">
  66. <el-form-item label="预览参数" label-position="top">
  67. <el-button icon="ele-Plus" text @click="() => state.renderData.push([])"></el-button>
  68. </el-form-item>
  69. </el-col>
  70. <el-col v-for="(item, index) in state.renderData" :key="index" :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb5" @dblclick="() => state.renderData.splice(index, 1)">
  71. <el-row :gutter="5">
  72. <el-col :span="8">
  73. <el-input v-model="item[0]" :placeholder="'参数名' + (index + 1)"/>
  74. </el-col>
  75. <el-col :span="16">
  76. <el-input v-model="item[1]" :placeholder="'参数值' + (index + 1)"/>
  77. </el-col>
  78. </el-row>
  79. </el-col>
  80. </el-row>
  81. </el-col>
  82. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
  83. <el-form-item label="预览结果:" label-width="85" />
  84. </el-col>
  85. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
  86. <span v-html="state.result"></span>
  87. </el-col>
  88. </el-row>
  89. </el-tab-pane>
  90. </el-tabs>
  91. </el-form>
  92. <template #footer>
  93. <span class="dialog-footer">
  94. <el-button @click="cancel">取 消</el-button>
  95. <el-button @click="showPreView" v-reclick="3000">预览</el-button>
  96. <el-button type="primary" @click="submit" v-reclick="2000">确 定</el-button>
  97. </span>
  98. </template>
  99. </el-dialog>
  100. </div>
  101. </template>
  102. <script lang="ts" setup name="sysEditConfig">
  103. import {reactive, ref, watch} from 'vue';
  104. import { getAPI } from '/@/utils/axios-utils';
  105. import { SysTemplateApi } from '/@/api-services/api';
  106. import { UpdateTemplateInput } from '/@/api-services/models';
  107. import Editor from "/@/components/editor/index.vue";
  108. import GSysDict from "/@/components/sysDict/sysDict.vue";
  109. const props = defineProps({
  110. title: String,
  111. });
  112. const editorRef = ref();
  113. const ruleFormRef = ref();
  114. const emits = defineEmits(['updateData']);
  115. const state = reactive({
  116. isShowDialog: false,
  117. selectedTabName: "1",
  118. renderData: [] as any,
  119. result: '' as any,
  120. contentType: 1,
  121. ruleForm: {} as UpdateTemplateInput,
  122. });
  123. const getRenderData = () => {
  124. const data = {} as any;
  125. state.renderData.forEach((e: [string, string]) => data[e[0]] = e[1]);
  126. return data;
  127. }
  128. const getRenderContent = async () => {
  129. const res = await getAPI(SysTemplateApi).apiSysTemplateRenderPost({ content: state.ruleForm.content, data: getRenderData() })
  130. state.result = res.data.result;
  131. }
  132. const showPreView = () => {
  133. getRenderContent();
  134. state.selectedTabName = '2';
  135. }
  136. // 打开弹窗
  137. const openDialog = (row: any) => {
  138. state.ruleForm = JSON.parse(JSON.stringify(row));
  139. state.selectedTabName = "1";
  140. state.isShowDialog = true;
  141. ruleFormRef.value?.resetFields();
  142. };
  143. // 关闭弹窗
  144. const closeDialog = () => {
  145. emits('updateData');
  146. state.isShowDialog = false;
  147. };
  148. // 取消
  149. const cancel = () => {
  150. state.isShowDialog = false;
  151. };
  152. // 提交
  153. const submit = () => {
  154. ruleFormRef.value.validate(async (valid: boolean) => {
  155. if (!valid) return;
  156. if (state.ruleForm.id != undefined && state.ruleForm.id > 0) {
  157. await getAPI(SysTemplateApi).apiSysTemplateUpdatePost(state.ruleForm);
  158. } else {
  159. await getAPI(SysTemplateApi).apiSysTemplateAddPost(state.ruleForm);
  160. }
  161. closeDialog();
  162. });
  163. };
  164. watch(
  165. () => state.ruleForm.content,
  166. () => {
  167. state.ruleForm.content?.match(/@\((.*?)\)/g)?.forEach((pa: string, index) => {
  168. const key = pa.substring(2, pa.length - 1);
  169. if (!state.renderData.find((e: [string, string]) => e[0] === key)) {
  170. state.renderData.push([key, '参数' + (index + 1)]);
  171. }
  172. });
  173. }
  174. )
  175. // 导出对象
  176. defineExpose({ openDialog });
  177. </script>