增加支付功能

This commit is contained in:
2026-09-15 12:46:29 +08:00
parent 943c3708b0
commit a82b300b1a
46 changed files with 11675 additions and 21 deletions
@@ -0,0 +1,161 @@
<template>
<el-card class="channel-card" shadow="hover" :body-style="{ padding: '18px 20px' }">
<div class="card-head">
<div class="head-left">
<div class="icon-wrap" :class="statusClass">
<el-icon :size="22">
<component :is="iconComp" />
</el-icon>
</div>
<div class="title-wrap">
<div class="channel-name">{{ name }}</div>
<div class="merchant-no">商户号:{{ merchantNo || '未配置' }}</div>
</div>
</div>
<StatusTag :status="status" dict="channel" />
</div>
<div v-if="desc" class="card-desc">{{ desc }}</div>
<div class="card-foot">
<el-button size="small" type="primary" plain @click="emit('config')">配置</el-button>
<el-button v-if="status === 'enabled'" size="small" type="danger" plain @click="emit('disable')">
停用
</el-button>
<el-button v-else size="small" type="success" plain @click="emit('enable')">启用</el-button>
</div>
</el-card>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import {
ChatDotRound,
Wallet,
CreditCard,
Lightning,
Money,
PriceTag
} from '@element-plus/icons-vue'
import StatusTag from './StatusTag.vue'
/** 常用渠道图标映射:微信 / 支付宝 / 银联 / 云闪付 / PayPal / 兜底 */
const ICONS: Record<string, any> = {
ChatDotRound,
Wallet,
CreditCard,
Lightning,
Money,
PriceTag
}
const props = withDefaults(
defineProps<{
/** 渠道名称,如「微信支付」 */
name: string
/** 渠道状态:enabled 已启用 / disabled 已停用 / unconfigured 未配置 */
status?: string
/** 商户号,未配置时显示「未配置」 */
merchantNo?: string
/** 图标名:ChatDotRound / Wallet / CreditCard / Lightning / Money */
icon?: string
/** 卡片补充说明 */
desc?: string
}>(),
{
status: 'unconfigured',
merchantNo: '',
icon: 'PriceTag',
desc: ''
}
)
const emit = defineEmits<{
(e: 'config'): void
(e: 'enable'): void
(e: 'disable'): void
}>()
const iconComp = computed(() => ICONS[props.icon] || PriceTag)
const statusClass = computed(() => {
if (props.status === 'enabled') return 'is-enabled'
if (props.status === 'unconfigured') return 'is-unconfigured'
return 'is-disabled'
})
</script>
<style scoped lang="less">
.channel-card {
margin-bottom: 0;
.card-head {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
}
.head-left {
display: flex;
align-items: center;
gap: 12px;
min-width: 0;
}
.icon-wrap {
width: 42px;
height: 42px;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
flex-shrink: 0;
&.is-enabled {
background: linear-gradient(135deg, #52c41a, #95de64);
}
&.is-disabled {
background: linear-gradient(135deg, #909399, #b1b3b8);
}
&.is-unconfigured {
background: linear-gradient(135deg, #e6a23c, #f3d19e);
}
}
.title-wrap {
min-width: 0;
}
.channel-name {
font-size: 15px;
font-weight: 600;
color: #303133;
}
.merchant-no {
margin-top: 4px;
font-size: 12px;
color: #909399;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.card-desc {
margin-top: 12px;
font-size: 12px;
line-height: 1.6;
color: #909399;
}
.card-foot {
margin-top: 16px;
display: flex;
gap: 8px;
}
}
</style>