index.vue 8.2 KB

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