index.vue 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. <template>
  2. <ContentWrap>
  3. <!-- 列表 -->
  4. <XTable @register="registerTable">
  5. <template #accountId_search>
  6. <el-select v-model="queryParams.accountId">
  7. <el-option :key="undefined" label="全部" value="" />
  8. <el-option
  9. v-for="item in accountOptions"
  10. :key="item.id"
  11. :label="item.mail"
  12. :value="item.id"
  13. />
  14. </el-select>
  15. </template>
  16. <template #toolbar_buttons>
  17. <!-- 操作:新增 -->
  18. <XButton
  19. type="primary"
  20. preIcon="ep:zoom-in"
  21. :title="t('action.add')"
  22. v-hasPermi="['system:mail-template:create']"
  23. @click="handleCreate()"
  24. />
  25. </template>
  26. <template #accountId_default="{ row }">
  27. <span>{{ accountOptions.find((account) => account.id === row.accountId)?.mail }}</span>
  28. </template>
  29. <template #actionbtns_default="{ row }">
  30. <!-- 操作:测试短信 -->
  31. <XTextButton
  32. preIcon="ep:cpu"
  33. :title="t('action.test')"
  34. v-hasPermi="['system:mail-template:send-mail']"
  35. @click="handleSendMail(row)"
  36. />
  37. <!-- 操作:修改 -->
  38. <XTextButton
  39. preIcon="ep:edit"
  40. :title="t('action.edit')"
  41. v-hasPermi="['system:mail-template:update']"
  42. @click="handleUpdate(row.id)"
  43. />
  44. <!-- 操作:详情 -->
  45. <XTextButton
  46. preIcon="ep:view"
  47. :title="t('action.detail')"
  48. v-hasPermi="['system:mail-template:query']"
  49. @click="handleDetail(row.id)"
  50. />
  51. <!-- 操作:删除 -->
  52. <XTextButton
  53. preIcon="ep:delete"
  54. :title="t('action.del')"
  55. v-hasPermi="['system:mail-template:delete']"
  56. @click="deleteData(row.id)"
  57. />
  58. </template>
  59. </XTable>
  60. </ContentWrap>
  61. <!-- 添加/修改/详情的弹窗 -->
  62. <XModal
  63. id="mailTemplateModel"
  64. :loading="modelLoading"
  65. v-model="modelVisible"
  66. :title="modelTitle"
  67. :height="['create', 'update'].includes(actionType) ? '99%' : ''"
  68. >
  69. <!-- 表单:添加/修改 -->
  70. <Form
  71. ref="formRef"
  72. v-if="['create', 'update'].includes(actionType)"
  73. :schema="allSchemas.formSchema"
  74. :rules="rules"
  75. >
  76. <template #accountId="form">
  77. <el-select v-model="form.accountId">
  78. <el-option
  79. v-for="item in accountOptions"
  80. :key="item.id"
  81. :label="item.mail"
  82. :value="item.id"
  83. />
  84. </el-select>
  85. </template>
  86. </Form>
  87. <!-- 表单:详情 -->
  88. <Descriptions
  89. v-if="actionType === 'detail'"
  90. :schema="allSchemas.detailSchema"
  91. :data="detailData"
  92. />
  93. <template #footer>
  94. <!-- 按钮:保存 -->
  95. <XButton
  96. v-if="['create', 'update'].includes(actionType)"
  97. type="primary"
  98. :title="t('action.save')"
  99. :loading="actionLoading"
  100. @click="submitForm()"
  101. />
  102. <!-- 按钮:关闭 -->
  103. <XButton :loading="actionLoading" :title="t('dialog.close')" @click="modelVisible = false" />
  104. </template>
  105. </XModal>
  106. <!-- 测试邮件的弹窗 -->
  107. <XModal id="sendTest" v-model="sendVisible" title="测试">
  108. <el-form :model="sendForm" :rules="sendRules" label-width="200px" label-position="top">
  109. <el-form-item label="模板内容" prop="content">
  110. <Editor :model-value="sendForm.content" readonly height="150px" />
  111. </el-form-item>
  112. <el-form-item label="收件邮箱" prop="mail">
  113. <el-input v-model="sendForm.mail" placeholder="请输入收件邮箱" />
  114. </el-form-item>
  115. <el-form-item
  116. v-for="param in sendForm.params"
  117. :key="param"
  118. :label="'参数 {' + param + '}'"
  119. :prop="'templateParams.' + param"
  120. >
  121. <el-input
  122. v-model="sendForm.templateParams[param]"
  123. :placeholder="'请输入 ' + param + ' 参数'"
  124. />
  125. </el-form-item>
  126. </el-form>
  127. <!-- 操作按钮 -->
  128. <template #footer>
  129. <XButton
  130. type="primary"
  131. :title="t('action.test')"
  132. :loading="actionLoading"
  133. @click="sendTest()"
  134. />
  135. <XButton :title="t('dialog.close')" @click="sendVisible = false" />
  136. </template>
  137. </XModal>
  138. </template>
  139. <script setup lang="ts" name="SystemMailTemplate">
  140. import { FormExpose } from '@/components/Form'
  141. // 业务相关的 import
  142. import { rules, allSchemas } from './template.data'
  143. import * as MailTemplateApi from '@/api/system/mail/template'
  144. import * as MailAccountApi from '@/api/system/mail/account'
  145. const { t } = useI18n() // 国际化
  146. const message = useMessage() // 消息弹窗
  147. // 列表相关的变量
  148. const queryParams = reactive({
  149. accountId: null
  150. })
  151. const [registerTable, { reload, deleteData }] = useXTable({
  152. allSchemas: allSchemas,
  153. params: queryParams,
  154. getListApi: MailTemplateApi.getMailTemplatePageApi,
  155. deleteApi: MailTemplateApi.deleteMailTemplateApi
  156. })
  157. const accountOptions = ref<any[]>([]) // 账号下拉选项
  158. // 弹窗相关的变量
  159. const modelVisible = ref(false) // 是否显示弹出层
  160. const modelTitle = ref('edit') // 弹出层标题
  161. const modelLoading = ref(false) // 弹出层loading
  162. const actionType = ref('') // 操作按钮的类型
  163. const actionLoading = ref(false) // 按钮 Loading
  164. const formRef = ref<FormExpose>() // 表单 Ref
  165. const detailData = ref() // 详情 Ref
  166. // 设置标题
  167. const setDialogTile = (type: string) => {
  168. modelLoading.value = true
  169. modelTitle.value = t('action.' + type)
  170. actionType.value = type
  171. modelVisible.value = true
  172. }
  173. // 新增操作
  174. const handleCreate = () => {
  175. setDialogTile('create')
  176. modelLoading.value = false
  177. }
  178. // 修改操作
  179. const handleUpdate = async (rowId: number) => {
  180. setDialogTile('update')
  181. // 设置数据
  182. const res = await MailTemplateApi.getMailTemplateApi(rowId)
  183. unref(formRef)?.setValues(res)
  184. modelLoading.value = false
  185. }
  186. // 详情操作
  187. const handleDetail = async (rowId: number) => {
  188. setDialogTile('detail')
  189. const res = await MailTemplateApi.getMailTemplateApi(rowId)
  190. detailData.value = res
  191. modelLoading.value = false
  192. }
  193. // 提交按钮
  194. const submitForm = async () => {
  195. const elForm = unref(formRef)?.getElFormRef()
  196. if (!elForm) return
  197. elForm.validate(async (valid) => {
  198. if (valid) {
  199. actionLoading.value = true
  200. // 提交请求
  201. try {
  202. const data = unref(formRef)?.formModel as MailTemplateApi.MailTemplateVO
  203. if (actionType.value === 'create') {
  204. await MailTemplateApi.createMailTemplateApi(data)
  205. message.success(t('common.createSuccess'))
  206. } else {
  207. await MailTemplateApi.updateMailTemplateApi(data)
  208. message.success(t('common.updateSuccess'))
  209. }
  210. modelVisible.value = false
  211. } finally {
  212. actionLoading.value = false
  213. // 刷新列表
  214. await reload()
  215. }
  216. }
  217. })
  218. }
  219. // ========== 测试相关 ==========
  220. const sendForm = ref({
  221. content: '',
  222. params: {},
  223. mail: '',
  224. templateCode: '',
  225. templateParams: {}
  226. })
  227. const sendRules = ref({
  228. mail: [{ required: true, message: '邮箱不能为空', trigger: 'blur' }],
  229. templateCode: [{ required: true, message: '模版编号不能为空', trigger: 'blur' }],
  230. templateParams: {}
  231. })
  232. const sendVisible = ref(false)
  233. const handleSendMail = (row: any) => {
  234. sendForm.value.content = row.content
  235. sendForm.value.params = row.params
  236. sendForm.value.templateCode = row.code
  237. sendForm.value.templateParams = row.params.reduce(function (obj, item) {
  238. obj[item] = undefined
  239. return obj
  240. }, {})
  241. sendRules.value.templateParams = row.params.reduce(function (obj, item) {
  242. obj[item] = { required: true, message: '参数 ' + item + ' 不能为空', trigger: 'change' }
  243. return obj
  244. }, {})
  245. sendVisible.value = true
  246. }
  247. const sendTest = async () => {
  248. const data: MailTemplateApi.MailSendReqVO = {
  249. mail: sendForm.value.mail,
  250. templateCode: sendForm.value.templateCode,
  251. templateParams: sendForm.value.templateParams as unknown as Map<string, Object>
  252. }
  253. const res = await MailTemplateApi.sendMailApi(data)
  254. if (res) {
  255. message.success('提交发送成功!发送结果,见发送日志编号:' + res)
  256. }
  257. sendVisible.value = false
  258. }
  259. // ========== 初始化 ==========
  260. onMounted(() => {
  261. MailAccountApi.getSimpleMailAccounts().then((data) => {
  262. accountOptions.value = data
  263. })
  264. })
  265. </script>