index.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. <template>
  2. <div class="app-container channel-plugin-page">
  3. <div class="page-header">
  4. <h3>渠道插件管理</h3>
  5. <span class="page-desc">龙虾引擎即插即用:启用渠道 + 填写API凭证即可接入新的IM平台</span>
  6. </div>
  7. <el-table :data="plugins" v-loading="loading" border stripe size="small">
  8. <el-table-column prop="channelType" label="渠道编码" width="100" />
  9. <el-table-column label="渠道名称" width="140">
  10. <template #default="{row}">
  11. <i :class="row.icon" style="margin-right:4px" /> {{ row.displayName }}
  12. </template>
  13. </el-table-column>
  14. <el-table-column label="SDK状态" width="100">
  15. <template #default="{row}">
  16. <el-tag :type="row.hasMessageChannel ? 'success' : 'warning'" size="small">
  17. {{ row.hasMessageChannel ? '已接入' : '待接入' }}
  18. </el-tag>
  19. </template>
  20. </el-table-column>
  21. <el-table-column label="启用" width="80">
  22. <template #default="{row}">
  23. <el-switch :value="row.enabled === 1 || row.enabled === true"
  24. @change="v => toggle(row, v)" :disabled="!row.hasMessageChannel" size="small" />
  25. </template>
  26. </el-table-column>
  27. <el-table-column label="凭证配置" min-width="200">
  28. <template #default="{row}">
  29. <template v-if="row.channelType === 'QW' || row.channelType === 'WX' || row.channelType === 'IM'">
  30. <el-tag type="info" size="small">内置免配置</el-tag>
  31. </template>
  32. <template v-else>
  33. <div style="display:flex;gap:6px;align-items:center;flex-wrap:wrap">
  34. <template v-if="row.channelType === 'WHATSAPP'">
  35. <el-input v-model="waConfig.phoneNumberId" placeholder="Phone Number ID" size="mini" style="width:150px" />
  36. <el-input v-model="waConfig.token" placeholder="Token" size="mini" style="width:150px" type="password" show-password />
  37. </template>
  38. <template v-else>
  39. <el-input v-model="otherConfig[row.channelType]" placeholder="API Key / Webhook URL" size="mini" style="width:200px" />
  40. </template>
  41. <el-button size="mini" type="primary" @click="saveConfig(row)">保存</el-button>
  42. </div>
  43. </template>
  44. </template>
  45. </el-table-column>
  46. <el-table-column label="测试" width="100">
  47. <template #default="{row}">
  48. <el-button size="mini" :type="row.hasMessageChannel && (row.enabled===1||row.enabled===true) ? 'success' : 'info'"
  49. @click="test(row)" :disabled="!(row.enabled===1||row.enabled===true)">测试连接</el-button>
  50. </template>
  51. </el-table-column>
  52. </el-table>
  53. </div>
  54. </template>
  55. <script>
  56. import request from '@/utils/request'
  57. export default {
  58. name: 'ChannelPlugin',
  59. data() {
  60. return {
  61. plugins: [],
  62. loading: false,
  63. waConfig: { phoneNumberId: '', token: '' },
  64. otherConfig: {}
  65. }
  66. },
  67. mounted() { this.loadPlugins() },
  68. methods: {
  69. loadPlugins() {
  70. this.loading = true
  71. request({ url: '/workflow/lobster/channel-plugin/list', method: 'get' }).then(res => {
  72. this.plugins = res.data || []
  73. }).finally(() => { this.loading = false })
  74. },
  75. toggle(row, v) {
  76. request({ url: `/workflow/lobster/channel-plugin/enable/${row.channelType}`, method: 'post', params: { enabled: v } }).then(() => {
  77. this.$message.success(v ? `${row.displayName} 已启用` : `${row.displayName} 已禁用`)
  78. row.enabled = v ? 1 : 0
  79. })
  80. },
  81. saveConfig(row) {
  82. let config = {}
  83. if (row.channelType === 'WHATSAPP') config = { ...this.waConfig }
  84. else config = { apiKey: this.otherConfig[row.channelType] }
  85. request({ url: `/workflow/lobster/channel-plugin/config/${row.channelType}`, method: 'post', data: config }).then(() => {
  86. this.$message.success('配置已保存')
  87. })
  88. },
  89. test(row) {
  90. request({ url: `/workflow/lobster/channel-plugin/test/${row.channelType}`, method: 'post' }).then(res => {
  91. const r = res.data
  92. this.$message({ type: r.ok ? 'success' : 'error', message: r.reason || (r.ok ? '连接正常' : '连接失败') })
  93. })
  94. }
  95. }
  96. }
  97. </script>
  98. <style scoped>
  99. .channel-plugin-page { padding: 0; }
  100. .page-header { margin-bottom: 16px; }
  101. .page-header h3 { margin: 0 0 4px; }
  102. .page-desc { font-size: 12px; color: #999; }
  103. </style>