Browse Source

✨ PAY:增加钱包、微信条码支付的渠道配置界面

YunaiV 1 year ago
parent
commit
948ef08533

+ 4 - 0
src/utils/constants.ts

@@ -133,6 +133,10 @@ export const PayChannelEnum = {
     code: 'alipay_bar',
     name: '支付宝条码支付'
   },
+  WALLET: {
+    code: 'wallet',
+    name: '钱包支付'
+  },
   MOCK: {
     code: 'mock',
     name: '模拟支付'

+ 122 - 0
src/views/pay/app/components/channel/WalletChannelForm.vue

@@ -0,0 +1,122 @@
+<template>
+  <div>
+    <Dialog v-model="dialogVisible" :title="dialogTitle" @closed="close" width="800px">
+      <el-form
+        ref="formRef"
+        :model="formData"
+        :rules="formRules"
+        label-width="100px"
+        v-loading="formLoading"
+      >
+        <el-form-item label-width="180px" label="渠道状态" prop="status">
+          <el-radio-group v-model="formData.status">
+            <el-radio
+              v-for="dict in getDictOptions(DICT_TYPE.COMMON_STATUS)"
+              :key="parseInt(dict.value)"
+              :label="parseInt(dict.value)"
+            >
+              {{ dict.label }}
+            </el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label-width="180px" label="备注" prop="remark">
+          <el-input v-model="formData.remark" :style="{ width: '100%' }" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="dialogVisible = false">取 消</el-button>
+      </template>
+    </Dialog>
+  </div>
+</template>
+<script lang="ts" setup>
+import { CommonStatusEnum } from '@/utils/constants'
+import { DICT_TYPE, getDictOptions } from '@/utils/dict'
+import * as ChannelApi from '@/api/pay/channel'
+
+defineOptions({ name: 'WalletChannelForm' })
+
+const { t } = useI18n() // 国际化
+const message = useMessage() // 消息弹窗
+
+const dialogVisible = ref(false) // 弹窗的是否展示
+const dialogTitle = ref('') // 弹窗的标题
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+const formData = ref<any>({
+  appId: '',
+  code: '',
+  status: undefined,
+  feeRate: 0,
+  remark: '',
+  config: {
+    name: 'mock-conf'
+  }
+})
+const formRules = {
+  status: [{ required: true, message: '渠道状态不能为空', trigger: 'blur' }]
+}
+const formRef = ref() // 表单 Ref
+
+/** 打开弹窗 */
+const open = async (appId, code) => {
+  dialogVisible.value = true
+  formLoading.value = true
+  resetForm(appId, code)
+  // 加载数据
+  try {
+    const data = await ChannelApi.getChannel(appId, code)
+
+    if (data && data.id) {
+      formData.value = data
+      formData.value.config = JSON.parse(data.config)
+    }
+    dialogTitle.value = !formData.value.id ? '创建支付渠道' : '编辑支付渠道'
+  } finally {
+    formLoading.value = false
+  }
+}
+defineExpose({ open }) // 提供 open 方法,用于打开弹窗
+
+/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const submitForm = async () => {
+  // 校验表单
+  if (!formRef) return
+  const valid = await formRef.value.validate()
+  if (!valid) return
+  // 提交请求
+  formLoading.value = true
+  try {
+    const data = { ...formData.value } as unknown as ChannelApi.ChannelVO
+    data.config = JSON.stringify(formData.value.config)
+    if (!data.id) {
+      await ChannelApi.createChannel(data)
+      message.success(t('common.createSuccess'))
+    } else {
+      await ChannelApi.updateChannel(data)
+      message.success(t('common.updateSuccess'))
+    }
+    dialogVisible.value = false
+    // 发送操作成功的事件
+    emit('success')
+  } finally {
+    formLoading.value = false
+  }
+}
+
+/** 重置表单 */
+const resetForm = (appId, code) => {
+  formData.value = {
+    appId: appId,
+    code: code,
+    status: CommonStatusEnum.ENABLE,
+    remark: '',
+    feeRate: 0,
+    config: {
+      name: 'mock-conf'
+    }
+  }
+  formRef.value?.resetFields()
+}
+</script>

+ 49 - 2
src/views/pay/app/index.vue

@@ -232,6 +232,48 @@
             </el-button>
           </template>
         </el-table-column>
+        <el-table-column :label="PayChannelEnum.WX_BAR.name" align="center">
+          <template #default="scope">
+            <el-button
+              type="success"
+              circle
+              v-if="isChannelExists(scope.row.channelCodes, PayChannelEnum.WX_BAR.code)"
+              @click="openChannelForm(scope.row, PayChannelEnum.WX_BAR.code)"
+            >
+              <Icon icon="ep:check" />
+            </el-button>
+            <el-button
+              v-else
+              type="danger"
+              circle
+              @click="openChannelForm(scope.row, PayChannelEnum.WX_BAR.code)"
+            >
+              <Icon icon="ep:close" />
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table-column>
+      <el-table-column label="钱包支付配置" align="center">
+        <el-table-column :label="PayChannelEnum.WALLET.name" align="center">
+          <template #default="scope">
+            <el-button
+              type="success"
+              circle
+              v-if="isChannelExists(scope.row.channelCodes, PayChannelEnum.WALLET.code)"
+              @click="openChannelForm(scope.row, PayChannelEnum.WALLET.code)"
+            >
+              <Icon icon="ep:check" />
+            </el-button>
+            <el-button
+              v-else
+              type="danger"
+              circle
+              @click="openChannelForm(scope.row, PayChannelEnum.WALLET.code)"
+            >
+              <Icon icon="ep:close" />
+            </el-button>
+          </template>
+        </el-table-column>
       </el-table-column>
       <el-table-column label="模拟支付配置" align="center">
         <el-table-column :label="PayChannelEnum.MOCK.name" align="center">
@@ -290,16 +332,17 @@
   <AlipayChannelForm ref="alipayFormRef" @success="getList" />
   <WeixinChannelForm ref="weixinFormRef" @success="getList" />
   <MockChannelForm ref="mockFormRef" @success="getList" />
+  <WalletChannelForm ref="walletFormRef" @success="getList" />
 </template>
 <script lang="ts" setup>
 import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
-import download from '@/utils/download'
 import * as AppApi from '@/api/pay/app'
 import AppForm from './components/AppForm.vue'
-import { PayChannelEnum, PayType } from '@/utils/constants'
+import { PayChannelEnum } from '@/utils/constants'
 import AlipayChannelForm from './components/channel/AlipayChannelForm.vue'
 import WeixinChannelForm from './components/channel/WeixinChannelForm.vue'
 import MockChannelForm from './components/channel/MockChannelForm.vue'
+import WalletChannelForm from './components/channel/WalletChannelForm.vue'
 import { CommonStatusEnum } from '@/utils/constants'
 
 defineOptions({ name: 'PayApp' })
@@ -397,6 +440,7 @@ const isChannelExists = (channels, channelCode) => {
 const alipayFormRef = ref()
 const weixinFormRef = ref()
 const mockFormRef = ref()
+const walletFormRef = ref()
 const channelParam = reactive({
   appId: null, // 应用 ID
   payCode: null // 渠道编码
@@ -415,6 +459,9 @@ const openChannelForm = async (row, payCode) => {
   if (payCode.indexOf('mock') === 0) {
     mockFormRef.value.open(row.id, payCode)
   }
+  if (payCode.indexOf('wallet') === 0) {
+    mockFormRef.value.open(row.id, payCode)
+  }
 }
 
 /** 初始化 **/