邮件管理编辑内容方式修改

main
wangxiaoshuang 2025-06-05 16:59:44 +08:00
parent 10f2953a94
commit 3bcf097c52
3 changed files with 117 additions and 197 deletions

23
package-lock.json generated
View File

@ -48,6 +48,7 @@
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"path-to-regexp": "^0.1.10", "path-to-regexp": "^0.1.10",
"pdfobject": "^2.3.0", "pdfobject": "^2.3.0",
"prismjs": "^1.30.0",
"qrcodejs2": "^0.0.2", "qrcodejs2": "^0.0.2",
"screenfull": "^6.0.2", "screenfull": "^6.0.2",
"sortablejs": "^1.15.5", "sortablejs": "^1.15.5",
@ -62,6 +63,7 @@
"vue-count-to": "^1.0.13", "vue-count-to": "^1.0.13",
"vue-demi": "^0.14.10", "vue-demi": "^0.14.10",
"vue-i18n": "^8.28.2", "vue-i18n": "^8.28.2",
"vue-prism-editor": "^1.3.0",
"vue-puzzle-vcode": "^1.1.10", "vue-puzzle-vcode": "^1.1.10",
"vue-router": "^3.0.6", "vue-router": "^3.0.6",
"vue-seamless-scroll": "^1.1.23", "vue-seamless-scroll": "^1.1.23",
@ -18044,6 +18046,15 @@
"renderkid": "^3.0.0" "renderkid": "^3.0.0"
} }
}, },
"node_modules/prismjs": {
"version": "1.30.0",
"resolved": "https://registry.npmmirror.com/prismjs/-/prismjs-1.30.0.tgz",
"integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/process": { "node_modules/process": {
"version": "0.11.10", "version": "0.11.10",
"resolved": "https://registry.npmmirror.com/process/-/process-0.11.10.tgz", "resolved": "https://registry.npmmirror.com/process/-/process-0.11.10.tgz",
@ -22997,6 +23008,18 @@
"url": "https://github.com/chalk/chalk?sponsor=1" "url": "https://github.com/chalk/chalk?sponsor=1"
} }
}, },
"node_modules/vue-prism-editor": {
"version": "1.3.0",
"resolved": "https://registry.npmmirror.com/vue-prism-editor/-/vue-prism-editor-1.3.0.tgz",
"integrity": "sha512-54RfgtMGRMNr9484zKMOZs1wyLDR6EfFylzE2QrMCD9alCvXyYYcS0vX8oUHh+6pMUu6ts59uSN9cHglpU2NRQ==",
"license": "MIT",
"engines": {
"node": ">=10"
},
"peerDependencies": {
"vue": "^2.6.11"
}
},
"node_modules/vue-puzzle-vcode": { "node_modules/vue-puzzle-vcode": {
"version": "1.1.10", "version": "1.1.10",
"resolved": "https://registry.npmmirror.com/vue-puzzle-vcode/-/vue-puzzle-vcode-1.1.10.tgz", "resolved": "https://registry.npmmirror.com/vue-puzzle-vcode/-/vue-puzzle-vcode-1.1.10.tgz",

View File

@ -54,6 +54,7 @@
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"path-to-regexp": "^0.1.10", "path-to-regexp": "^0.1.10",
"pdfobject": "^2.3.0", "pdfobject": "^2.3.0",
"prismjs": "^1.30.0",
"qrcodejs2": "^0.0.2", "qrcodejs2": "^0.0.2",
"screenfull": "^6.0.2", "screenfull": "^6.0.2",
"sortablejs": "^1.15.5", "sortablejs": "^1.15.5",
@ -68,6 +69,7 @@
"vue-count-to": "^1.0.13", "vue-count-to": "^1.0.13",
"vue-demi": "^0.14.10", "vue-demi": "^0.14.10",
"vue-i18n": "^8.28.2", "vue-i18n": "^8.28.2",
"vue-prism-editor": "^1.3.0",
"vue-puzzle-vcode": "^1.1.10", "vue-puzzle-vcode": "^1.1.10",
"vue-router": "^3.0.6", "vue-router": "^3.0.6",
"vue-seamless-scroll": "^1.1.23", "vue-seamless-scroll": "^1.1.23",

View File

@ -1,12 +1,5 @@
<template> <template>
<el-form <el-form ref="emailForm" v-loading="loading" :model="form" label-width="180px" size="small" :rules="rules">
ref="emailForm"
v-loading="loading"
:model="form"
label-width="180px"
size="small"
:rules="rules"
>
<el-row> <el-row>
<el-col :span="24"> <el-col :span="24">
<!-- Code --> <!-- Code -->
@ -29,12 +22,7 @@
<el-col :span="12"> <el-col :span="12">
<!-- 邮件延时发送s数 --> <!-- 邮件延时发送s数 -->
<el-form-item :label="$t('dictionary:email:label:emailDelaySeconds')" prop="EmailDelaySeconds"> <el-form-item :label="$t('dictionary:email:label:emailDelaySeconds')" prop="EmailDelaySeconds">
<el-input <el-input v-model.number="form.EmailDelaySeconds" style="width: 300px" type="number" clearable>
v-model.number="form.EmailDelaySeconds"
style="width: 300px"
type="number"
clearable
>
</el-input> </el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -42,12 +30,8 @@
<!-- 业务层级 --> <!-- 业务层级 -->
<el-form-item :label="$t('dictionary:email:label:businessLevel')" prop="BusinessLevelEnum"> <el-form-item :label="$t('dictionary:email:label:businessLevel')" prop="BusinessLevelEnum">
<el-select v-model="form.BusinessLevelEnum" clearable class="mr"> <el-select v-model="form.BusinessLevelEnum" clearable class="mr">
<el-option <el-option v-for="item of $d.BusinessLevel" :key="`BusinessLevel${item.label}`" :label="item.label"
v-for="item of $d.BusinessLevel" :value="item.value" />
:key="`BusinessLevel${item.label}`"
:label="item.label"
:value="item.value"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -55,12 +39,8 @@
<!-- 业务模块 --> <!-- 业务模块 -->
<el-form-item :label="$t('dictionary:email:label:businessModule')" prop="BusinessModuleEnum"> <el-form-item :label="$t('dictionary:email:label:businessModule')" prop="BusinessModuleEnum">
<el-select v-model="form.BusinessModuleEnum" clearable class="mr"> <el-select v-model="form.BusinessModuleEnum" clearable class="mr">
<el-option <el-option v-for="item of $d.BusinessModule" :key="`BusinessModule${item.label}`" :label="item.label"
v-for="item of $d.BusinessModule" :value="item.value" />
:key="`BusinessModule${item.label}`"
:label="item.label"
:value="item.value"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -68,80 +48,46 @@
<!-- 业务场景 --> <!-- 业务场景 -->
<el-form-item :label="$t('trials:emailManageCfg:table:BusinessScenarioEnum')" prop="BusinessScenarioEnum"> <el-form-item :label="$t('trials:emailManageCfg:table:BusinessScenarioEnum')" prop="BusinessScenarioEnum">
<el-select v-model="form.BusinessScenarioEnum" clearable class="mr"> <el-select v-model="form.BusinessScenarioEnum" clearable class="mr">
<el-option <el-option v-for="item of $d.Email_BusinessScenario" :key="`BusinessScenarioEnum${item.label}`"
v-for="item of $d.Email_BusinessScenario" :label="item.label" :value="item.value" />
:key="`BusinessScenarioEnum${item.label}`"
:label="item.label"
:value="item.value"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<!-- 收件人 --> <!-- 收件人 -->
<el-form-item :label="$t('trials:emailManageCfg:title:toUserTypeList')" prop="ToUserTypeList"> <el-form-item :label="$t('trials:emailManageCfg:title:toUserTypeList')" prop="ToUserTypeList">
<el-select <el-select v-model="form.ToUserTypeList" clearable multiple class="mr">
v-model="form.ToUserTypeList" <el-option v-for="item of $d.UserType" :key="`ToUserTypeList${item.label}`" :label="item.label"
clearable :value="item.value" />
multiple
class="mr"
>
<el-option
v-for="item of $d.UserType"
:key="`ToUserTypeList${item.label}`"
:label="item.label"
:value="item.value"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<!-- 抄送人 --> <!-- 抄送人 -->
<el-form-item :label="$t('trials:emailManageCfg:title:copyUserTypeList')" prop="CopyUserTypeList"> <el-form-item :label="$t('trials:emailManageCfg:title:copyUserTypeList')" prop="CopyUserTypeList">
<el-select <el-select v-model="form.CopyUserTypeList" clearable multiple class="mr">
v-model="form.CopyUserTypeList" <el-option v-for="item of $d.UserType" :key="`CopyUserTypeList${item.label}`" :label="item.label"
clearable :value="item.value" />
multiple
class="mr"
>
<el-option
v-for="item of $d.UserType"
:key="`CopyUserTypeList${item.label}`"
:label="item.label"
:value="item.value"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<!-- 加急状态 --> <!-- 加急状态 -->
<el-form-item :label="$t('dictionary:email:label:IsUrgent')" prop="EmailUrgentEnum"> <el-form-item :label="$t('dictionary:email:label:IsUrgent')" prop="EmailUrgentEnum">
<el-select <el-select v-model="form.EmailUrgentEnum" @change="
v-model="form.EmailUrgentEnum"
@change="
(v) => { (v) => {
v === 1 ? (form.EmailCron = null) : null v === 1 ? (form.EmailCron = null) : null
} }
" " clearable class="mr">
clearable <el-option v-for="item of $d.EmailUrgent" :key="`EmailUrgent${item.label}`" :label="item.label"
class="mr" :value="item.value" />
>
<el-option
v-for="item of $d.EmailUrgent"
:key="`EmailUrgent${item.label}`"
:label="item.label"
:value="item.value"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<!-- 发送周期和时间 --> <!-- 发送周期和时间 -->
<el-form-item <el-form-item :label="$t('trials:emailManageCfg:table:EmailCron')" v-if="form.EmailUrgentEnum !== 1"
:label="$t('trials:emailManageCfg:table:EmailCron')" prop="EmailCron">
v-if="form.EmailUrgentEnum !== 1"
prop="EmailCron"
>
<el-input style="width: 300px" readonly v-model="form.EmailCron" /> <el-input style="width: 300px" readonly v-model="form.EmailCron" />
<!-- 生成 cron --> <!-- 生成 cron -->
<el-button type="primary" @click="showDialog"> {{ $t('dictionary:email:button:cron') }} </el-button> <el-button type="primary" @click="showDialog"> {{ $t('dictionary:email:button:cron') }} </el-button>
@ -151,12 +97,8 @@
<!-- 是否需要回执 --> <!-- 是否需要回执 -->
<el-form-item :label="$t('trials:emailManageCfg:title:isReturnRequired')" prop="IsReturnRequired"> <el-form-item :label="$t('trials:emailManageCfg:title:isReturnRequired')" prop="IsReturnRequired">
<el-radio-group v-model="form.IsReturnRequired"> <el-radio-group v-model="form.IsReturnRequired">
<el-radio <el-radio v-for="item of $d.YesOrNo" :label="item.value" :key="`IsReturnRequired${item.value}`">{{
v-for="item of $d.YesOrNo" item.label }}</el-radio>
:label="item.value"
:key="`IsReturnRequired${item.value}`"
>{{ item.label }}</el-radio
>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -164,48 +106,30 @@
<!-- 是否自动发送 --> <!-- 是否自动发送 -->
<el-form-item :label="$t('trials:emailManageCfg:table:IsAutoSend')" prop="IsAutoSend"> <el-form-item :label="$t('trials:emailManageCfg:table:IsAutoSend')" prop="IsAutoSend">
<el-radio-group v-model="form.IsAutoSend"> <el-radio-group v-model="form.IsAutoSend">
<el-radio <el-radio v-for="item of $d.YesOrNo" :label="item.value" :key="`IsAutoSend${item.value}`">{{ item.label
v-for="item of $d.YesOrNo" }}</el-radio>
:label="item.value"
:key="`IsAutoSend${item.value}`"
>{{ item.label }}</el-radio
>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" v-if="systemLevel"> <el-col :span="12" v-if="systemLevel">
<!-- 是否区分标准 --> <!-- 是否区分标准 -->
<el-form-item :label="$t('dictionary:email:button:isDistinguishCriteria')" prop="IsDistinguishCriteria"> <el-form-item :label="$t('dictionary:email:button:isDistinguishCriteria')" prop="IsDistinguishCriteria">
<el-radio-group <el-radio-group v-model="form.IsDistinguishCriteria" @change="
v-model="form.IsDistinguishCriteria"
@change="
() => { () => {
form.CriterionTypeEnum = null form.CriterionTypeEnum = null
} }
" ">
> <el-radio v-for="item of $d.YesOrNo" :label="item.value" :key="`IsDistinguishCriteria${item.value}`">{{
<el-radio item.label }}</el-radio>
v-for="item of $d.YesOrNo"
:label="item.value"
:key="`IsDistinguishCriteria${item.value}`"
>{{ item.label }}</el-radio
>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item :label="$t('trials:auditRecord:table:criterion')" v-if="form.IsDistinguishCriteria"
:label="$t('trials:auditRecord:table:criterion')" prop="CriterionTypeEnum">
v-if="form.IsDistinguishCriteria"
prop="CriterionTypeEnum"
>
<el-select v-model="form.CriterionTypeEnum" clearable class="mr"> <el-select v-model="form.CriterionTypeEnum" clearable class="mr">
<el-option <el-option v-for="item of $d.CriterionType" :key="`CriterionType${item.label}`" :label="item.label"
v-for="item of $d.CriterionType" :value="item.value" />
:key="`CriterionType${item.label}`"
:label="item.label"
:value="item.value"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -213,106 +137,65 @@
<!-- 是否启用 --> <!-- 是否启用 -->
<el-form-item :label="$t('trials:emailManageCfg:table:IsEnable')" prop="IsEnable"> <el-form-item :label="$t('trials:emailManageCfg:table:IsEnable')" prop="IsEnable">
<el-radio-group v-model="form.IsEnable"> <el-radio-group v-model="form.IsEnable">
<el-radio <el-radio v-for="item of $d.YesOrNo" :label="item.value" :key="`IsEnable${item.value}`">{{ item.label
v-for="item of $d.YesOrNo" }}</el-radio>
:label="item.value"
:key="`IsEnable${item.value}`"
>{{ item.label }}</el-radio
>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<!-- 附件CN --> <!-- 附件CN -->
<el-form-item :label="$t('trials:emailManageCfg:table:fileListCN')" prop="IsEnable"> <el-form-item :label="$t('trials:emailManageCfg:table:fileListCN')" prop="IsEnable">
<el-upload <el-upload class="upload-demo" action :before-upload="beforeUploadCN" :http-request="handleUploadFileCN"
class="upload-demo" :on-preview="handlePreviewCN" :on-remove="handleRemoveFileCN" :show-file-list="true" :limit="1"
action :file-list="fileListCN">
:before-upload="beforeUploadCN" <el-button size="small" type="primary" :disabled="fileListCN.length > 0">{{ $t('common:button:upload')
:http-request="handleUploadFileCN" }}</el-button>
:on-preview="handlePreviewCN"
:on-remove="handleRemoveFileCN"
:show-file-list="true"
:limit="1"
:file-list="fileListCN"
>
<el-button
size="small"
type="primary"
:disabled="fileListCN.length > 0"
>{{ $t('common:button:upload') }}</el-button
>
</el-upload> </el-upload>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<!-- 附件EN --> <!-- 附件EN -->
<el-form-item :label="$t('trials:emailManageCfg:table:fileListEN')" prop="IsEnable"> <el-form-item :label="$t('trials:emailManageCfg:table:fileListEN')" prop="IsEnable">
<el-upload <el-upload class="upload-demo" action :before-upload="beforeUploadEN" :http-request="handleUploadFileEN"
class="upload-demo" :on-preview="handlePreviewEN" :on-remove="handleRemoveFileEN" :show-file-list="true" :limit="1"
action :file-list="fileListEN">
:before-upload="beforeUploadEN" <el-button size="small" type="primary" :disabled="fileListEN.length > 0">{{ $t('common:button:upload')
:http-request="handleUploadFileEN" }}</el-button>
:on-preview="handlePreviewEN"
:on-remove="handleRemoveFileEN"
:show-file-list="true"
:limit="1"
:file-list="fileListEN"
>
<el-button
size="small"
type="primary"
:disabled="fileListEN.length > 0"
>{{ $t('common:button:upload') }}</el-button
>
</el-upload> </el-upload>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<!-- 邮件内容模版CN --> <!-- 邮件内容模版CN -->
<el-form-item <el-form-item :label="$t('dictionary:email:label:emailHtmlContentCN')" prop="EmailHtmlContentCN"
:label="$t('dictionary:email:label:emailHtmlContentCN')" style="position: relative">
prop="EmailHtmlContentCN" <div class="html_temp">
style="position: relative" <prism-editor class="my-editor" v-model="form.EmailHtmlContentCN" :highlight="highlighter" :line-numbers="true"
> style="width: 50%;max-height: 500px;"></prism-editor>
<el-input <div v-html="form.EmailHtmlContentCN" style="width: 50%;"></div>
v-model="form.EmailHtmlContentCN" </div>
type="textarea" <!-- <el-input v-model="form.EmailHtmlContentCN" type="textarea" :autosize="{ minRows: 8, maxRows: 8 }" />
:autosize="{ minRows: 8, maxRows: 8 }" <el-button :disabled="!form.EmailHtmlContentCN && form.EmailHtmlContent" type="text"
/>
<el-button
:disabled="!form.EmailHtmlContentCN && form.EmailHtmlContent"
type="text"
@click="PreviewHTML(form.EmailHtmlContentCN, form.EmailHtmlContent)" @click="PreviewHTML(form.EmailHtmlContentCN, form.EmailHtmlContent)"
style="position: absolute; left: -50px; top: 30px" style="position: absolute; left: -50px; top: 30px">
>
{{ $t('common:button:preview') }} {{ $t('common:button:preview') }}
</el-button> </el-button> -->
</el-form-item> </el-form-item>
<!-- 邮件内容模版EN --> <!-- 邮件内容模版EN -->
<el-form-item <el-form-item :label="$t('dictionary:email:label:emailHtmlContent')" prop="EmailHtmlContent"
:label="$t('dictionary:email:label:emailHtmlContent')" style="position: relative">
prop="EmailHtmlContent" <div class="html_temp">
style="position: relative" <prism-editor class="my-editor" v-model="form.EmailHtmlContent" :highlight="highlighter" :line-numbers="true"
> style="width: 50%;max-height: 500px;"></prism-editor>
<el-input <div v-html="form.EmailHtmlContent" style="width: 50%;"></div>
v-model="form.EmailHtmlContent" </div>
type="textarea" <!-- <el-input v-model="form.EmailHtmlContent" type="textarea" :autosize="{ minRows: 8, maxRows: 8 }" />
:autosize="{ minRows: 8, maxRows: 8 }" <el-button :disabled="!form.EmailHtmlContentCN && form.EmailHtmlContent" type="text"
/>
<el-button
:disabled="!form.EmailHtmlContentCN && form.EmailHtmlContent"
type="text"
@click="PreviewHTML(form.EmailHtmlContentCN, form.EmailHtmlContent)" @click="PreviewHTML(form.EmailHtmlContentCN, form.EmailHtmlContent)"
style="position: absolute; left: -50px; top: 30px" style="position: absolute; left: -50px; top: 30px">
>
{{ $t('common:button:preview') }} {{ $t('common:button:preview') }}
</el-button> </el-button> -->
</el-form-item> </el-form-item>
<div <div class="base-dialog-footer" style="text-align: right; margin-top: 10px; padding-bottom: 10px">
class="base-dialog-footer"
style="text-align: right; margin-top: 10px; padding-bottom: 10px"
>
<el-form-item style="text-align: right"> <el-form-item style="text-align: right">
<el-button size="small" type="primary" @click="handleSave"> <el-button size="small" type="primary" @click="handleSave">
{{ $t('common:button:save') }} {{ $t('common:button:save') }}
@ -321,12 +204,7 @@
</div> </div>
<!-- 生成 cron --> <!-- 生成 cron -->
<el-dialog append-to-body :title="$t('dictionary:email:button:cron')" :visible.sync="showCron"> <el-dialog append-to-body :title="$t('dictionary:email:button:cron')" :visible.sync="showCron">
<vcrontab <vcrontab :hideComponent="['year']" @hide="showCron = false" @fill="crontabFill" :expression="expression">
:hideComponent="['year']"
@hide="showCron = false"
@fill="crontabFill"
:expression="expression"
>
</vcrontab> </vcrontab>
</el-dialog> </el-dialog>
</el-form> </el-form>
@ -334,6 +212,14 @@
<script> <script>
import { Upload, addOrUpdateEmailNoticeConfigList } from '@/api/dictionary' import { Upload, addOrUpdateEmailNoticeConfigList } from '@/api/dictionary'
import vcrontab from 'vcrontab' import vcrontab from 'vcrontab'
import { PrismEditor } from 'vue-prism-editor';
import 'vue-prism-editor/dist/prismeditor.min.css';
import { highlight, languages } from 'prismjs/components/prism-core';
import 'prismjs/components/prism-clike';
import 'prismjs/components/prism-javascript';
import 'prismjs/themes/prism.css';
export default { export default {
props: { props: {
data: { data: {
@ -355,7 +241,7 @@ export default {
}, },
}, },
}, },
components: { vcrontab }, components: { vcrontab, PrismEditor },
data() { data() {
return { return {
expression: '', expression: '',
@ -440,6 +326,9 @@ export default {
} }
}, },
methods: { methods: {
highlighter(code) {
return highlight(code, languages.js);
},
showDialog() { showDialog() {
this.expression = this.form.EmailCron // cron UI this.expression = this.form.EmailCron // cron UI
this.showCron = true this.showCron = true
@ -563,3 +452,9 @@ export default {
}, },
} }
</script> </script>
<style lang="scss" scoped>
.html_temp {
display: flex;
}
</style>