index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. <template>
  2. <div>
  3. <page-header :title="$t('system.text_130', [$t('system.notify_channels')])" />
  4. <page-body needMarginBottom>
  5. <a-form
  6. class="mt-3"
  7. :form="form.fc"
  8. v-bind="formItemLayout"
  9. hideRequiredMark>
  10. <scope-radio
  11. :decorators="decorators"
  12. :form="form"
  13. :hidden-scope="['project']"
  14. :label="$t('common_547', [])"
  15. @change="scopeChange" />
  16. <a-form-item :label="$t('common.name')">
  17. <a-input v-decorator="decorators.name" :placeholder="$t('validator.resourceName')" />
  18. <name-repeated
  19. v-slot:extra
  20. res="notifyconfigs"
  21. version="v1"
  22. :name="form.fd.name" />
  23. </a-form-item>
  24. <a-form-item :label="$t('system.text_48')">
  25. <a-radio-group v-decorator="decorators.type">
  26. <a-radio-button
  27. v-for="item in typesOpts"
  28. :value="item.key"
  29. :key="item.key"
  30. :disabled="existTypes.includes(item.key)">{{ item.label }}</a-radio-button>
  31. </a-radio-group>
  32. </a-form-item>
  33. </a-form>
  34. <component
  35. ref="typeRef"
  36. :is="form.fd.type"
  37. :form-item-layout="formItemLayout"
  38. :docUrl="DOCS_MAP.mailConfig(form.fd.type)" />
  39. </page-body>
  40. <page-footer>
  41. <div slot="right">
  42. <a-button @click="doTest()" :loading="testLoading">{{ $t('common_269') }}</a-button>
  43. <a-button class="ml-3 mr-3" type="primary" :loading="loading" @click="doOk()">{{ $t('dialog.ok') }}</a-button>
  44. <a-button @click="cancel">{{ $t('dialog.cancel') }}</a-button>
  45. </div>
  46. </page-footer>
  47. </div>
  48. </template>
  49. <script>
  50. import WindowsMixin from '@/mixins/windows'
  51. import NameRepeated from '@/sections/NameRepeated/index'
  52. import ScopeRadio from '@/sections/ScopeRadio'
  53. import { DOCS_MAP, showDocsLink } from '@/constants/docs'
  54. import Email from './components/Email'
  55. import Mobile from './components/Mobile'
  56. import Dingtalk from './components/Dingtalk'
  57. import Feishu from './components/Feishu'
  58. import Workwx from './components/Workwx'
  59. export default {
  60. name: 'NotifyconfigCreate',
  61. components: {
  62. ScopeRadio,
  63. NameRepeated,
  64. Email,
  65. Mobile,
  66. Dingtalk,
  67. Feishu,
  68. Workwx,
  69. },
  70. mixins: [WindowsMixin],
  71. data () {
  72. const scope = this.$store.getters.scope
  73. return {
  74. DOCS_MAP,
  75. showDocsLink,
  76. testLoading: false,
  77. loading: false,
  78. existTypes: [],
  79. types: [
  80. { label: this.$t('system.text_302'), key: 'email' },
  81. { label: this.$t('system.text_144'), key: 'mobile' },
  82. { label: this.$t('system.text_136'), key: 'dingtalk' },
  83. { label: this.$t('system.text_133'), key: 'feishu' },
  84. { label: this.$t('system.wecom.1'), key: 'workwx' },
  85. ],
  86. form: {
  87. fc: this.$form.createForm(this, {
  88. onValuesChange: (props, values) => {
  89. Object.keys(values).forEach((key) => {
  90. this.form.fd[key] = values[key]
  91. })
  92. },
  93. }),
  94. fd: {
  95. scope,
  96. type: '',
  97. },
  98. },
  99. decorators: {
  100. scope: [
  101. 'scope',
  102. {
  103. initialValue: scope,
  104. rules: [{ required: true, message: `${this.$t('common.select')}` }],
  105. },
  106. ],
  107. domain: [
  108. 'domain',
  109. {
  110. rules: [
  111. { required: true, message: `${this.$t('common.select')}` },
  112. ],
  113. },
  114. ],
  115. name: [
  116. 'name',
  117. {
  118. rules: [
  119. { required: true, message: `${this.$t('common.placeholder')}${this.$t('common.name')}` },
  120. { validator: this.$validate('resourceName') },
  121. ],
  122. },
  123. ],
  124. type: [
  125. 'type',
  126. {
  127. rules: [
  128. { required: true, message: `${this.$t('common.select')}` },
  129. ],
  130. },
  131. ],
  132. },
  133. formItemLayout: {
  134. wrapperCol: {
  135. span: 21,
  136. },
  137. labelCol: {
  138. span: 3,
  139. },
  140. },
  141. }
  142. },
  143. computed: {
  144. typesOpts () {
  145. if (this.form.fd.scope === 'system') return this.types
  146. return this.types.filter(v => !['email', 'mobile'].includes(v.key))
  147. },
  148. },
  149. watch: {
  150. 'form.fd.scope' (val) {
  151. if (!this.typesOpts.some(item => item.key === val)) {
  152. this.form.fc.setFieldsValue({
  153. type: '',
  154. })
  155. }
  156. },
  157. },
  158. created () {
  159. this.manager = new this.$Manager('notifyconfigs', 'v1')
  160. this.notifytemplatesManager = new this.$Manager('notifytemplates/save', 'v1')
  161. this.fetchTypes({ attribution: this.$store.getters.scope, scope: this.$store.getters.scope })
  162. },
  163. destroyed () {
  164. this.manager = null
  165. this.notifytemplatesManager = null
  166. },
  167. methods: {
  168. cancel () {
  169. this.$router.push('/notifyconfig')
  170. },
  171. scopeChange ({ scope, domain_id }) {
  172. if (domain_id) {
  173. this.fetchTypes({ attribution: scope, scope: this.$store.getters.scope, project_domain_id: domain_id })
  174. } else {
  175. this.fetchTypes({ attribution: scope, scope: this.$store.getters.scope })
  176. }
  177. },
  178. fetchTypes (params) {
  179. this.manager.list({ params }).then(res => {
  180. const { data } = res.data
  181. this.existTypes = data.map(v => v.type)
  182. }).catch(err => {
  183. console.error(err)
  184. })
  185. },
  186. doOk () {
  187. const { $refs: { typeRef } } = this
  188. const commonForm = new Promise((resolve, reject) => {
  189. this.form.fc.validateFields((err, values) => {
  190. if (err) {
  191. reject(err)
  192. return
  193. }
  194. resolve(values)
  195. })
  196. })
  197. const typeForm = new Promise((resolve, reject) => {
  198. typeRef.form.fc.validateFields((err, values) => {
  199. if (err) {
  200. reject(err)
  201. return
  202. }
  203. resolve(values)
  204. })
  205. })
  206. Promise.all([commonForm, typeForm]).then(async values => {
  207. const [common, content] = values
  208. const { scope, domain, name, type } = common
  209. const { verifiyCode, alertsCode, errorCode, verifiyCodeChannel, alertsCodeChannel, errorCodeChannel, verifiyCodeEn, alertsCodeEn, errorCodeEn, verifiyCodeEnChannel, alertsCodeEnChannel, errorCodeEnChannel, ...rest } = content
  210. this.loading = true
  211. await this.manager.create({
  212. data: {
  213. content: rest,
  214. generate_name: name,
  215. type,
  216. attribution: scope,
  217. project_domain_id: domain,
  218. },
  219. })
  220. if (type === 'mobile') {
  221. this.doCreateMobileTpl(
  222. verifiyCode, alertsCode, errorCode,
  223. verifiyCodeChannel, alertsCodeChannel, errorCodeChannel,
  224. verifiyCodeEn, alertsCodeEn, errorCodeEn,
  225. verifiyCodeEnChannel, alertsCodeEnChannel, errorCodeEnChannel,
  226. )
  227. }
  228. this.$router.push('/notifyconfig')
  229. this.loading = false
  230. }).catch((err) => {
  231. this.loading = false
  232. console.error(err)
  233. })
  234. },
  235. async doTest () {
  236. try {
  237. const { $refs: { typeRef } } = this
  238. const commonForm = new Promise((resolve, reject) => {
  239. this.form.fc.validateFields((err, values) => {
  240. if (err) {
  241. reject(err)
  242. return
  243. }
  244. resolve(values)
  245. })
  246. })
  247. const typeForm = new Promise((resolve, reject) => {
  248. typeRef.form.fc.validateFields((err, values) => {
  249. if (err) {
  250. reject(err)
  251. return
  252. }
  253. resolve(values)
  254. })
  255. })
  256. Promise.all([commonForm, typeForm]).then(async values => {
  257. const [common, content] = values
  258. const { type } = common
  259. if (type === 'mobile') {
  260. this.createDialog('NotifyTestMobileDialog', {
  261. data: {
  262. content,
  263. type: type,
  264. },
  265. })
  266. } else {
  267. this.testLoading = true
  268. const res = await this.manager.performClassAction({
  269. action: 'validate',
  270. data: {
  271. content,
  272. type: type,
  273. },
  274. })
  275. const { is_valid, message } = res.data
  276. if (is_valid) {
  277. this.$notification.success({
  278. message: this.$t('common_270'),
  279. description: this.$t('common_271'),
  280. })
  281. } else {
  282. this.$notification.error({
  283. message: message,
  284. })
  285. }
  286. this.testLoading = false
  287. }
  288. }).catch((err) => {
  289. this.testLoading = false
  290. console.error(err)
  291. })
  292. } catch (err) {
  293. this.$message.error(this.$t('common_623', [this.$t('common_269')]))
  294. console.error(err)
  295. }
  296. },
  297. async doCreateMobileTpl (verifiyCode, alertsCode, errorCode, verifiyCodeChannel, alertsCodeChannel, errorCodeChannel, verifiyCodeEn, alertsCodeEn, errorCodeEn, verifiyCodeEnChannel, alertsCodeEnChannel, errorCodeEnChannel) {
  298. const tpls = this.generateTemplates(verifiyCode, alertsCode, errorCode, verifiyCodeChannel, alertsCodeChannel, errorCodeChannel, verifiyCodeEn, alertsCodeEn, errorCodeEn, verifiyCodeEnChannel, alertsCodeEnChannel, errorCodeEnChannel)
  299. if (tpls) {
  300. try {
  301. await this.notifytemplatesManager.create({
  302. data: {
  303. contact_type: 'mobile',
  304. force: true,
  305. templates: tpls,
  306. },
  307. })
  308. } catch (err) {
  309. console.error(err)
  310. }
  311. }
  312. },
  313. channelCodeContent (code, channel) {
  314. if (channel) {
  315. return channel + '/' + code
  316. } else {
  317. return code
  318. }
  319. },
  320. generateTemplates (verifiyCode, alertsCode, errorCode, verifiyCodeChannel, alertsCodeChannel, errorCodeChannel, verifiyCodeEn, alertsCodeEn, errorCodeEn, verifiyCodeEnChannel, alertsCodeEnChannel, errorCodeEnChannel) {
  321. const tpls = []
  322. let cont = this.channelCodeContent(verifiyCode, verifiyCodeChannel)
  323. if (cont) {
  324. tpls.push({
  325. lang: 'cn',
  326. topic: 'VERIFY',
  327. content: cont,
  328. })
  329. }
  330. cont = this.channelCodeContent(alertsCode, alertsCodeChannel)
  331. if (cont) {
  332. tpls.push({
  333. lang: 'cn',
  334. topic: 'MONITOR',
  335. content: cont,
  336. })
  337. }
  338. cont = this.channelCodeContent(errorCode, errorCodeChannel)
  339. if (cont) {
  340. tpls.push({
  341. lang: 'cn',
  342. topic: 'USER_LOGIN_EXCEPTION',
  343. content: cont,
  344. })
  345. }
  346. cont = this.channelCodeContent(verifiyCodeEn, verifiyCodeEnChannel)
  347. if (cont) {
  348. tpls.push({
  349. lang: 'en',
  350. topic: 'VERIFY',
  351. content: cont,
  352. })
  353. }
  354. cont = this.channelCodeContent(alertsCodeEn, alertsCodeEnChannel)
  355. if (cont) {
  356. tpls.push({
  357. lang: 'en',
  358. topic: 'MONITOR',
  359. content: cont,
  360. })
  361. }
  362. cont = this.channelCodeContent(errorCodeEn, errorCodeEnChannel)
  363. if (cont) {
  364. tpls.push({
  365. lang: 'en',
  366. topic: 'USER_LOGIN_EXCEPTION',
  367. content: cont,
  368. })
  369. }
  370. return tpls.map(v => {
  371. return {
  372. ...v,
  373. contact_type: 'mobile',
  374. template_type: 'remote',
  375. }
  376. })
  377. },
  378. },
  379. }
  380. </script>