This commit is contained in:
磷叶 2025-01-23 16:17:27 +08:00
parent 2c44be717f
commit fc8ff0a738
13 changed files with 248 additions and 95 deletions

View File

@ -9,6 +9,14 @@ export function listChannel(query) {
})
}
// 查询所有充值渠道列表
export function listAllChannel() {
return request({
url: '/system/channel/listAll',
method: 'get'
})
}
// 查询充值渠道列表
export function listChannelByIds(ids) {
return request({

View File

@ -0,0 +1,74 @@
<template>
<el-select
v-model="selectValue"
:placeholder="placeholder"
clearable
filterable
:disabled="disabled"
:multiple="multiple"
v-on="$listeners"
:style="{ width: width }"
>
<el-option
v-for="item in list"
:key="item.channelId"
:label="item.name"
:value="item.channelId"
/>
</el-select>
</template>
<script>
import { listAllChannel } from "@/api/system/channel";
export default {
name: "ChannelSelect",
props: {
value: {
type: [String, Array],
default: null
},
placeholder: {
type: String,
default: "请选择渠道"
},
disabled: {
type: Boolean,
default: false
},
multiple: {
type: Boolean,
default: false
},
width: {
type: String,
default: null
}
},
data() {
return {
list: [],
};
},
computed: {
selectValue: {
get() {
return this.value;
},
set(val) {
this.$emit("input", val);
}
}
},
created() {
this.getList();
},
methods: {
getList() {
listAllChannel().then(response => {
this.list = response.data;
});
},
}
};
</script>

View File

@ -1,7 +1,12 @@
<template>
<el-col :span="span">
<el-form-item :label="label" :prop="prop" :label-width="labelWidth" :rules="rules" :class="table ? 'table-form-item' : ''">
<slot></slot>
<el-tooltip v-if="tip" :content="tip" placement="top">
<div>
<slot></slot>
</div>
</el-tooltip>
<slot v-else></slot>
</el-form-item>
</el-col>
</template>
@ -33,6 +38,10 @@ export default {
table: {
type: Boolean,
default: false
},
tip: {
type: String,
default: null
}
}
}

View File

@ -19,7 +19,7 @@ export default {
position: relative;
font-size: 16px;
padding-left: 0.5em;
border-left: 3px solid #00BA88;
border-left: 4px solid #8883F0;
margin: 0.5em 0 1em;
}
</style>

View File

@ -188,6 +188,7 @@ export const ConfigKey = {
RISK_WITHDRAW_TIME: "risk.withdraw.time", // 风控订单和提现相隔时长(分钟)
RISK_WITHDRAW_COUNT: "risk.withdraw.count", // 提现风控累计风险次数
LOGIN_WITH_PHONE: "login.with.phone", // 登录获取手机号
VIP_SERVICE_FEE_RATE: "vip.service.fee.rate", // 会员服务费费率
}
// 用户类型

View File

@ -6,9 +6,10 @@
:end-date.sync="queryParams.dateEnd"
@change="getList"
/>
<el-select v-model="queryParams.channelId" @change="getList" placeholder="请选择渠道">
<!-- <el-select v-model="queryParams.channelId" @change="getList" placeholder="请选择渠道">
<el-option v-for="dict of dict.type.channel_type" :key="dict.value" :label="dict.label" :value="dict.value"/>
</el-select>
</el-select> -->
<channel-select v-model="queryParams.channelId" @change="getList"/>
</el-row>
<daily-bill-amount-report :bill-data="billData" width="100%" height="250px"/>
</div>
@ -19,11 +20,12 @@ import { getLastDateStr } from '@/utils'
import { getBillDailyAmount } from '@/api/system/dashboard'
import DateRangePicker from '@/components/DateRangePicker/index.vue'
import DailyBillAmountReport from '@/views/dashboard/DailyBillAmountReport.vue'
import ChannelSelect from '@/components/Business/Channel/ChannelSelect.vue'
export default {
name: 'DailyBillAmountChart',
dicts: ['channel_type'],
components: { DailyBillAmountReport, DateRangePicker },
components: { DailyBillAmountReport, DateRangePicker, ChannelSelect },
data() {
return {
//

View File

@ -20,14 +20,7 @@
</el-select>
</el-form-item>
<el-form-item label="支付渠道" prop="channelId">
<el-select v-model="queryParams.channelId" placeholder="请选择支付状态" clearable @change="handleQuery">
<el-option
v-for="dict in dict.type.channel_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
<channel-select v-model="queryParams.channelId" @change="handleQuery"/>
</el-form-item>
<el-form-item label="支付状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择支付状态" clearable @change="handleQuery">
@ -99,9 +92,6 @@
<template v-else-if="column.key === 'status'">
<dict-tag :options="dict.type.pay_bill_status" :value="d.row[column.key]"/>
</template>
<template v-else-if="column.key === 'channelId'">
<dict-tag :options="dict.type.channel_type" :value="d.row.channelId"/>
</template>
<template v-else-if="['channelCost', 'amount', 'refundingAmount', 'refundAmount'].includes(column.key)">
{{d.row[column.key] | money}}
</template>
@ -155,7 +145,7 @@
import { listPayBill, getPayBill, delPayBill, addPayBill, updatePayBill, refundPayBill } from '@/api/ss/payBill'
import { $showColumns, $view } from '@/utils/mixins'
import { PayBillStatus } from '@/utils/constants'
import ChannelSelect from '@/components/Business/Channel/ChannelSelect.vue'
//
const defaultSort = {
prop: "createTime",
@ -165,7 +155,8 @@ const defaultSort = {
export default {
name: "PayBill",
mixins: [$showColumns, $view],
dicts: ['pay_bill_status', 'pay_bill_bst_type', 'channel_type'],
dicts: ['pay_bill_status', 'pay_bill_bst_type'],
components: { ChannelSelect },
props: {
query: {
type: Object,
@ -198,7 +189,7 @@ export default {
{key: 'bstType', visible: true, label: '业务类型', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'bstId', visible: false, label: '业务ID', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'amount', visible: true, label: '支付金额', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'channelId', visible: true, label: '支付渠道', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'channelName', visible: true, label: '支付渠道', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'status', visible: true, label: '支付状态', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'payTime', visible: true, label: '支付时间', minWidth: "120", sortable: false, overflow: false, align: 'center', width: null},
{key: 'description', visible: true, label: '描述', minWidth: "200", sortable: true, overflow: true, align: 'center', width: null},

View File

@ -10,17 +10,7 @@
<el-form-item label="备注名" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注名" maxlength="200" show-word-limit/>
</el-form-item>
<el-form-item label="角色" prop="role">
<el-select v-model="form.role" placeholder="请选择角色" style="width: 100%">
<el-option
v-for="dict in dict.type.store_staff_role"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="分成比例" prop="point">
<el-form-item label="充值分成" prop="point">
<el-input-number
v-model="form.point"
placeholder="请输入分成比例"
@ -30,6 +20,16 @@
controls-position="right"
/> %
</el-form-item>
<el-form-item label="VIP分成" prop="vipPoint">
<el-input-number
v-model="form.vipPoint"
placeholder="请输入分成比例"
:min="0"
:max="100"
style="width: calc(100% - 2em)"
controls-position="right"
/> %
</el-form-item>
<el-form-item label="是否启用" prop="enabled">
<el-switch v-model="form.enabled" active-text="启用" inactive-text="禁用"/>
</el-form-item>
@ -116,6 +116,9 @@ export default {
enabled: [
{ required: true, message: "是否启用不能为空", trigger: "change" }
],
vipPoint: [
{ required: true, message: "VIP分成不能为空", trigger: "change" }
],
}
}
},
@ -166,6 +169,7 @@ export default {
remark: null,
role: StoreStaffRole.PARTNER,
point: 0,
vipPoint: 0,
enabled: true,
permissions: [],
...this.initForm

View File

@ -63,7 +63,9 @@
</template>
<template v-else-if="column.key === 'limitType'">
<dict-tag :options="dict.type.vip_level_limit_type" :value="d.row[column.key]"/>
{{d.row[column.key] | defaultValue}}
<template v-if="d.row.limitType !== VipLevelLimitType.NONE">
{{d.row.limitCount | defaultValue}}
</template>
</template>
<template v-else-if="['roundCount', 'totalCount', 'surplusCount'].includes(column.key)">
{{d.row[column.key] | defaultValue}}
@ -112,6 +114,7 @@ import { $showColumns } from '@/utils/mixins'
import StoreLink from '@/components/Business/Store/StoreLink.vue'
import BooleanTag from '@/components/BooleanTag/index.vue'
import UserLink from '@/components/Business/SmUser/UserLink.vue'
import { VipLevelLimitType } from '@/utils/constants'
//
const defaultSort = {
prop: "createTime",
@ -130,6 +133,7 @@ export default {
},
data() {
return {
VipLevelLimitType,
//
columns: [
{key: 'id', visible: true, label: 'ID', minWidth: null, sortable: true, overflow: false, align: 'center', width: "80"},

View File

@ -2,11 +2,12 @@
<div class="app-container" v-loading="loading">
<el-tabs tab-position="left">
<el-tab-pane label="充值/提现配置" lazy>
<h3>充值</h3>
<h3>支付</h3>
<config-item :config="getConfig(ConfigKey.SERVICE_FEE_RATE)"/>
<config-item :config="getConfig(ConfigKey.RECHARGE_MIN_SERVICE)"/>
<config-item :config="getConfig(ConfigKey.ORDER_AUTO_CLOSE_CD)"/>
<config-item :config="getConfig(ConfigKey.ARRIVAL_DELAY)"/>
<config-item :config="getConfig(ConfigKey.VIP_SERVICE_FEE_RATE)"/>
<h3>提现</h3>
<config-item :config="getConfig(ConfigKey.DAILY_WITHDRAW_AMOUNT)"/>
<config-item :config="getConfig(ConfigKey.DAILY_WITHDRAW_COUNT)"/>

View File

@ -1,16 +1,16 @@
<template>
<el-dialog :title="title" :visible.sync="visible" width="700px" append-to-body @close="onClose">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-dialog :title="title" :visible.sync="visible" width="1200px" append-to-body @close="onClose">
<el-form ref="form" :model="form" :rules="rules" label-width="80px" class="scrollbar-form" v-loading="loading">
<el-row>
<form-col :span="span" label="用户头像" prop="avatar">
<form-col :span="span" label="头像" prop="avatar">
<image-upload v-model="form.avatar" :limit="1"/>
</form-col>
<form-col :span="span" label="用户角色" prop="type">
<form-col :span="span" label="角色" prop="type">
<el-select v-model="form.type" placeholder="请选择用户角色" style="width: 100%">
<el-option v-for="item of dict.type.sm_user_type" :key="item.value" :label="item.label" :value="item.value"/>
</el-select>
</form-col>
<form-col :span="span" label="用户名称" prop="userName">
<form-col :span="span" label="名称" prop="userName">
<el-input v-model="form.userName" placeholder="请输入用户名称" :maxlength="20" ></el-input>
</form-col>
<form-col :span="span" label="手机号" prop="phonenumber">
@ -20,19 +20,22 @@
<form-col :span="span" label="密码" prop="password">
<el-input v-model="form.password" placeholder="请输入密码,为空则不修改" type="password" :maxlength="32" show-word-limit show-password/>
</form-col>
<form-col :span="span * 2" label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" :maxlength="500" show-word-limit type="textarea"/>
</form-col>
</el-row>
<el-row>
<form-col :span="span" label="商户服务费" prop="serviceRate" label-width="8em" tip="平台收取商户的服务费">
<el-input v-model="form.serviceRate" placeholder="请输入平台收取商户服务费" type="number">
<template #append>%</template>
</el-input>
<group-title title="费用配置"/>
<form-col :span="span" label="商户服务费" prop="serviceRate" label-width="7em" tip="平台收取商户的服务费">
<el-input-number v-model="form.serviceRate" placeholder="请输入平台收取商户服务费" type="number" controls-position="right" :min="0" :max="100" :step="1" style="width: calc(100% - 2em)"/> %
</form-col>
<form-col :span="span" label="代理服务费" prop="agentServiceRate" label-width="9em" v-if="form.type === SmUserType.AGENT" tip="平台收取代理商的服务费">
<el-input v-model="form.agentServiceRate" placeholder="请输入平台收取代理商服务费" type="number">
<template #append>%</template>
</el-input>
<form-col :span="span" label="VIP服务费" prop="vipServiceRate" label-width="7em" tip="平台收取商户的VIP订单服务费">
<el-input-number v-model="form.vipServiceRate" placeholder="请输入平台收取商户VIP订单服务费" type="number" controls-position="right" :min="0" :max="100" :step="1" style="width: calc(100% - 2em)"/> %
</form-col>
<form-col :span="span * 2" label="提现服务费" prop="withdrawServiceRate" label-width="6em">
<form-col :span="span" label="代理服务费" prop="agentServiceRate" label-width="7em" tip="平台收取代理商的服务费">
<el-input-number v-model="form.agentServiceRate" placeholder="请输入平台收取代理商服务费" type="number" :disabled="form.type !== SmUserType.AGENT" controls-position="right" :min="0" :max="100" :step="1" style="width: calc(100% - 2em)"/> %
</form-col>
<form-col :span="12" label="提现服务费" prop="withdrawServiceRate" label-width="6em" tip="平台收取商户的提现服务费">
<el-input v-model="form.withdrawServiceRate" placeholder="请输入提现服务费" type="number">
<template #prepend>
<el-select v-model="form.withdrawServiceType" placeholder="请选择提现服务费收取方式" style="width: 10em">
@ -47,14 +50,43 @@
<template #append>{{withdrawServiceUnit(form.withdrawServiceType)}}</template>
</el-input>
</form-col>
<form-col :span="span * 2" label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" :maxlength="500" show-word-limit type="textarea"/>
<form-col :span="12" label="订单手机号" label-width="7em" tip="开启后,订单将显示用户手机号,并按单收取费用">
<el-input v-model="form.showBillMobilePrice" :min="0" type="number" placeholder="请输入单价">
<template #prepend>
<el-switch v-model="form.showBillMobile" active-text="开启" inactive-text="不开启"/>
</template>
<template #append> / </template>
</el-input>
</form-col>
<form-col :span="24" label="所属应用" prop="appId">
<app-input v-model="form.appId" @change="onChangeApp"/>
<form-col :span="24" label="专属收款渠道" label-width="7em" prop="channelIds">
<channel-input v-model="form.channelIds" :multiple="true"/>
</form-col>
<form-col :span="24" label="专属渠道" prop="channelIds">
<channel-input v-model="form.channelIds" :multiple="true" :query="{appId: form.appId}"/>
</el-row>
<el-row>
<group-title title="风控配置"/>
<form-col :span="span" label="充值延迟到账" prop="arrivalDelay" label-width="7em" tip="开启后,该用户的收益将延迟到账">
<el-input v-model="form.arrivalDelay" placeholder="请输入到账延迟时长">
<template #append>小时</template>
</el-input>
</form-col>
</el-row>
<el-row v-if="form.type === SmUserType.AGENT">
<group-title title="代理商配置"/>
<form-col :span="span" label="默认设备服务费" label-width="8em" tip="代理商所拥有的设备的默认收取商户的服务费" prop="agentDeviceService">
<el-input v-model="form.agentDeviceService" type="number" :min="0" placeholder="请输入默认设备服务费">
<template #append>%</template>
</el-input>
</form-col>
<form-col :span="span" label="商户开关/充值设备" label-width="10em" tip="关闭后,商户将无法通过后台开关/充值设备" prop="agentDeviceService">
<el-switch v-model="form.agentAllowMchSwitch" active-text="允许" inactive-text="不允许"/>
</form-col>
</el-row>
<el-row>
<group-title title="其他设置"/>
<form-col :span="8" label="设备管理员权限" label-width="8em" prop="deviceAdmin" tip="重要权限!!!开启后,用户将拥有设备管理员权限,可以录入设备">
<el-switch v-model="form.deviceAdmin" active-text="开启" inactive-text="关闭" @change="onChangeDeviceAdmin"/>
</form-col>
</el-row>
</el-form>
@ -71,11 +103,13 @@ import { SmUserType } from '@/utils/constants'
import { $withdrawServiceType } from '@/utils/mixins'
import ChannelInput from '@/components/Business/Channel/ChannelInput.vue'
import AppInput from '@/components/Business/App/AppInput.vue'
import GroupTitle from '@/components/GroupTitle/index.vue'
export default {
name: "UserFormDialog",
mixins: [$withdrawServiceType],
dicts: ['sm_user_status', 'sm_user_type', 'sys_user_sex', 'service_type', 'withdraw_service_type'],
components: { ChannelInput, AppInput },
components: { ChannelInput, AppInput, GroupTitle },
props: {
show: {
type: Boolean,
@ -88,19 +122,29 @@ export default {
},
data() {
return {
loading: false,
visible: false,
span: 12,
title: '',
span: 8,
title: '新增用户',
//
form: {},
//
rules: {
userName: [
{ required: true, message: '请输入用户名称', trigger: 'blur' }
{ required: true, message: '请输入用户名称', trigger: 'change' }
],
type: [
{ required: true, message: '请选择用户角色', trigger: 'change' }
]
],
serviceRate: [
{ required: true, message: '请输入商户服务费', trigger: 'change' }
],
vipServiceRate: [
{ required: true, message: '请输入VIP服务费', trigger: 'change' }
],
agentServiceRate: [
{ required: true, message: '请输入代理服务费', trigger: 'change' }
],
}
}
},
@ -136,16 +180,21 @@ export default {
deviceAdmin: false,
serviceType: '1',
withdrawServiceType: "1",
channelIds: []
channelIds: [],
showBillMobile: false,
showBillMobilePrice: 0
}
this.$nextTick(() => {
this.$refs.form && this.$refs.form.clearValidate()
})
},
getDetail() {
this.loading = true
getSmUser(this.userId).then(response => {
this.form = response.data
this.title = "修改用户信息"
}).finally(() => {
this.loading = false
})
},
submitForm() {
@ -172,7 +221,30 @@ export default {
},
onChangeApp(app) {
this.form.channelIds = []
}
},
//
onChangeDeviceAdmin(val) {
if (val) {
this.$confirm('【高危操作】是否确认设置用户为设备管理员?<br/>用户将可以通过微信小程序注册设备!', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
dangerouslyUseHTMLString: true
}).then(() => {
this.form.deviceAdmin = true;
}).catch((e) => {
this.form.deviceAdmin = false;
});
}
},
}
}
</script>
</script>
<style scoped>
.scrollbar-form {
height: 600px;
padding: 0 10px;
overflow-y: auto;
}
</style>

View File

@ -8,14 +8,14 @@
<el-row type="flex" style="justify-content: space-between">
<div>用户详情</div>
<div>
<el-button
<!-- <el-button
type="text"
icon="el-icon-setting"
size="small"
style="padding: 5px 0 0"
@click="showConfigDialog = true"
>配置</el-button
>
> -->
<el-button
type="text"
icon="el-icon-edit"

View File

@ -1,7 +1,7 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="手机号码" prop="phonenumber">
<el-form-item label="手机号码" prop="phonenumber" v-if="isShow('phonenumber')">
<el-input
v-model="queryParams.phonenumber"
placeholder="请输入手机号码"
@ -9,7 +9,7 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="用户名称" prop="realOrUserName">
<el-form-item label="用户名称" prop="realOrUserName" v-if="isShow('realOrUserName')">
<el-input
v-model="queryParams.realOrUserName"
placeholder="请输入用户名称"
@ -17,7 +17,12 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="应用名称" prop="appName">
<el-form-item label="用户角色" prop="type" v-if="isShow('type')">
<el-select v-model="queryParams.type" placeholder="请选择用户角色" clearable @change="handleQuery">
<el-option v-for="item of dict.type.sm_user_type" :key="item.value" :label="item.label" :value="item.value"/>
</el-select>
</el-form-item>
<el-form-item label="应用名称" prop="appName" v-if="isShow('appName')">
<el-input
v-model="queryParams.appName"
placeholder="请输入应用名称"
@ -25,7 +30,7 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-form-item label="备注" prop="remark" v-if="isShow('remark')">
<el-input
v-model="queryParams.remark"
placeholder="请输入备注"
@ -33,12 +38,7 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="用户类型" prop="type">
<el-select v-model="queryParams.type" placeholder="请选择用户类型" clearable @change="handleQuery">
<el-option v-for="item of dict.type.sm_user_type" :key="item.value" :label="item.label" :value="item.value"/>
</el-select>
</el-form-item>
<el-form-item label="帐号状态" prop="status">
<el-form-item label="帐号状态" prop="status" v-if="isShow('status')">
<el-select v-model="queryParams.status" placeholder="请选择帐号状态" clearable @change="handleQuery">
<el-option
v-for="dict in dict.type.sm_user_status"
@ -48,33 +48,20 @@
/>
</el-select>
</el-form-item>
<el-form-item label="设备服务费类型" prop="serviceType" label-width="8em">
<el-select v-model="queryParams.serviceType" placeholder="请选择设备服务费类型" clearable @change="handleQuery">
<el-option
v-for="dict in dict.type.service_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="提现服务费类型" prop="withdrawServiceType" label-width="8em">
<el-select v-model="queryParams.withdrawServiceType" placeholder="请选择提现服务费类型" clearable @change="handleQuery">
<el-option
v-for="dict in dict.type.withdraw_service_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="是否管理" prop="deviceAdmin">
<el-form-item label="是否管理" prop="deviceAdmin" v-if="isShow('deviceAdmin')">
<el-radio-group v-model="queryParams.deviceAdmin" @change="handleQuery">
<el-radio :label="null">全部</el-radio>
<el-radio :label="true"></el-radio>
<el-radio :label="false"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="是否实名" prop="isReal" v-if="isShow('isReal')">
<el-radio-group v-model="queryParams.isReal" @change="handleQuery">
<el-radio :label="null">全部</el-radio>
<el-radio :label="true"></el-radio>
<el-radio :label="false"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
@ -213,13 +200,13 @@
@click="handleResetService(scope.row)"
v-hasPermi="['system:smUser:edit']"
>重置服务费</el-button>
<el-button
<!-- <el-button
size="mini"
type="text"
icon="el-icon-setting"
@click="handleUpdateRisk(scope.row)"
v-hasPermi="['system:smUser:edit']"
>配置</el-button>
>配置</el-button> -->
</template>
</el-table-column>
</el-table>