This commit is contained in:
磷叶 2024-11-06 08:41:31 +08:00
parent c801bd1274
commit 2ca728a30a
8 changed files with 202 additions and 31 deletions

View File

@ -54,4 +54,13 @@ export function getBonusMonthAmount(params) {
})
}
// 根据天获取分成金额
export function getBonusDailyAmount(params) {
return request({
url: '/system/dashboard/bonusDailyAmount',
method: 'get',
params
})
}

View File

@ -0,0 +1,69 @@
<template>
<el-date-picker
v-model="dateRange"
type="daterange"
value-format="yyyy-MM-dd"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
:picker-options="pickerOptions"
:clearable="false"
v-on="$listeners"
/>
</template>
<script >
import { getLastDate, getLastMonth } from '@/utils'
export default {
name: "DateRangePicker",
props: {
startDate: {
type: String,
default: false,
},
endDate: {
type: String,
default: false,
}
},
data() {
return {
pickerOptions: {
shortcuts: [{
text: '最近一周',
onClick(picker) {
const end = getLastDate(0);
const start = getLastDate(6);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近一个月',
onClick(picker) {
const end = getLastDate(0);
const start = getLastMonth(1);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近三个月',
onClick(picker) {
const end = getLastDate(0);
const start = getLastMonth(3);
picker.$emit('pick', [start, end]);
}
}]
},
}
},
computed: {
dateRange: {
get() {
return [this.startDate, this.endDate];
},
set(val) {
this.$emit('update:startDate', val[0]);
this.$emit('update:endDate', val[1])
}
}
},
}
</script>

View File

@ -34,6 +34,13 @@
<el-radio :label="false">风控中</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="实名解封" prop="unsealSelf">
<el-radio-group v-model="queryParams.unsealSelf" @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>
@ -102,6 +109,9 @@
<template v-else-if="column.key === 'isFinished'">
<boolean-tag :value="d.row.isFinished" true-text="已解封" false-text="风控中"/>
</template>
<template v-else-if="column.key === 'unsealSelf'">
<boolean-tag :value="d.row.unsealSelf" true-text="允许" false-text="不允许"/>
</template>
<template v-else>
{{d.row[column.key]}}
</template>
@ -143,14 +153,6 @@
<user-input v-model="form.userId" :disabled="hasView(views.user)"/>
</el-form-item>
<el-form-item label="类型" prop="type">
<!-- <el-select v-model="form.type" placeholder="请选择类型">-->
<!-- <el-option-->
<!-- v-for="dict in dict.type.risk_type"-->
<!-- :key="dict.value"-->
<!-- :label="dict.label"-->
<!-- :value="dict.value"-->
<!-- ></el-option>-->
<!-- </el-select>-->
<el-checkbox-group v-model="form.type">
<el-checkbox v-for="dict in dict.type.risk_type" :key="dict.value" :label="dict.value">{{dict.label}}</el-checkbox>
</el-checkbox-group>
@ -165,9 +167,12 @@
v-model="form.endTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择解封时间">
placeholder="请选择解封时间,为空则永久封禁">
</el-date-picker>
</el-form-item>
<el-form-item label="实名解封" prop="unsealSelf">
<el-switch v-model="form.unsealSelf" active-text="允许" inactive-text="不允许"/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
@ -211,9 +216,10 @@ export default {
{key: 'userId', visible: true, label: '用户', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'type', visible: true, label: '类型', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'isFinished', visible: true, label: '风控状态', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'reason', visible: true, label: '风控原因', minWidth: null, sortable: true, overflow: true, align: 'center', width: null},
{key: 'endTime', visible: true, label: '解封时间', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'createTime', visible: true, label: '创建时间', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'reason', visible: true, label: '风控原因', minWidth: "150", sortable: true, overflow: true, align: 'center', width: null},
{key: 'endTime', visible: true, label: '解封时间', minWidth: null, sortable: true, overflow: false, align: 'center', width: "100"},
{key: 'unsealSelf', visible: true, label: '实名解封', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
{key: 'createTime', visible: true, label: '创建时间', minWidth: null, sortable: true, overflow: false, align: 'center', width: "100"},
{key: 'realNameId', visible: false, label: '实名认证ID', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
],
//
@ -247,7 +253,9 @@ export default {
userId: null,
type: null,
reason: null,
realNameId: null
realNameId: null,
unsealSelf: null,
isFinished: null,
},
//
form: {},
@ -259,6 +267,9 @@ export default {
type: [
{ required: true, message: "类型不能为空", trigger: "change" }
],
unsealSelf: [
{ required: true, message: "实名解封不能为空", trigger: "change" }
]
}
};
},
@ -305,7 +316,8 @@ export default {
reason: null,
endTime: null,
createTime: null,
realNameId: null
realNameId: null,
unsealSelf: false
};
this.resetForm("form");
},

View File

@ -2,16 +2,22 @@
<div>
<el-button style="width: 100%" type="success" icon="el-icon-link" size="small" plain @click="showDialog = true">绑定代理商</el-button>
<sm-user-dialog :show.sync="showDialog" @select="handleSubmit"/>
<sm-user-dialog :show.sync="showDialog" @select="handleSubmit" :query="{type: SmUserType.AGENT}"/>
</div>
</template>
<script>
import SmUserDialog from '@/components/Business/SmUser/smUserDialog.vue'
import { bindAgent, bindMch } from '@/api/system/device'
import { SmUserType } from '@/utils/constants'
export default {
name: "BindAgentButton",
computed: {
SmUserType() {
return SmUserType
}
},
components: { SmUserDialog },
props: {
deviceId: {

View File

@ -0,0 +1,64 @@
<template>
<div v-loading="loading" >
<date-range-picker :start-date.sync="queryParams.payDateStart" :end-date.sync="queryParams.payDateEnd" @change="getList"/>
<single-line-chart :labels="labels" :chart-data="chartData" name="收入(元)" height="268px"/>
</div>
</template>
<script>
import SingleLineChart from '@/components/SingleLineChart/index.vue'
import { BonusArrivalType } from '@/utils/constants'
import { getLastDateStr } from '@/utils'
import DateRangePicker from '@/components/DateRangePicker/index.vue'
import { getBonusDailyAmount } from '@/api/system/dashboard'
export default {
name: "UserDailyRechargeReport",
components: { DateRangePicker, SingleLineChart },
props: {
query: {
type: Object,
default: () => {
return {}
}
}
},
data() {
return {
loading: false,
list: [],
queryParams: {
payDateStart: getLastDateStr(30),
payDateEnd: getLastDateStr(0),
arrivalId: null,
arrivalTypes: BonusArrivalType.userList()
},
}
},
computed: {
labels() {
return this.list.map(item => item.key);
},
chartData() {
return this.list.map(item => item.sum == null ? 0 : item.sum.toFixed(2));
}
},
created() {
this.queryParams = {
...this.queryParams,
...this.query
}
this.getList();
},
methods: {
getList() {
this.loading = true;
getBonusDailyAmount(this.queryParams).then(res => {
this.list = res.data;
}).finally(() => {
this.loading = false;
})
}
}
}
</script>

View File

@ -1,20 +1,13 @@
<template>
<div>
<el-row type="flex">
<el-tabs style="width: 100%">
<el-tab-pane label="月报表">
<range-picker v-model="queryParams.payTimeYear" @change="onChangeYear" suffix="年"/>
</el-tab-pane>
</el-tabs>
</el-row>
<single-line-chart v-loading="loading" :labels="labels" :chart-data="chartData" name="收入(元)" height="268px"/>
<div v-loading="loading">
<range-picker v-model="queryParams.payTimeYear" @change="onChangeYear" suffix="年"/>
<single-line-chart :labels="labels" :chart-data="chartData" name="收入(元)" height="268px"/>
</div>
</template>
<script>
import SingleLineChart from "@/components/SingleLineChart/index.vue";
import RangePicker from "@/components/RangePicker/index.vue";
import {countBill, listBill} from "@/api/system/recharge";
import {BonusArrivalType} from "@/utils/constants";
import {getBonusMonthAmount} from "@/api/system/dashboard";
@ -45,6 +38,9 @@ export default {
this.getReportData(nv);
}
},
created() {
this.getReportData(this.mchId);
},
methods: {
//
onChangeYear(year) {

View File

@ -17,7 +17,7 @@
<div class="user-header">
<el-avatar :size="64" :src="detail.avatar"></el-avatar>
<el-row type="flex" class="name-box">
<span class="user-name">{{detail.nickName}}</span>
<span class="user-name">{{detail.realOrUserName}}</span>
<dict-tag :value="detail.type" :options="dict.type.sm_user_type"/>
</el-row>
<div class="phone-number">{{detail.phonenumber}}</div>
@ -80,7 +80,16 @@
</el-col>
<el-col :lg="14" :md="12" :xs="24">
<el-card class="box-card">
<user-recharge-report :mch-id="detail.userId"/>
<el-row type="flex">
<el-tabs style="width: 100%">
<el-tab-pane label="日报表" lazy>
<user-daily-recharge-report v-if="detail.userId != null" :query="{arrivalId: detail.userId}"/>
</el-tab-pane>
<el-tab-pane label="月报表" lazy>
<user-recharge-report :mch-id="detail.userId"/>
</el-tab-pane>
</el-tabs>
</el-row>
</el-card>
</el-col>
</el-row>
@ -155,11 +164,12 @@ import UserConfigDialog from '@/views/system/smUser/components/UserConfigDialog.
import { SmUserType } from '@/utils/constants'
import ReceiveBill from '@/views/ss/receiveBill/index.vue'
import Risk from '@/views/ss/risk/index.vue'
import UserDailyRechargeReport from '@/views/system/smUser/components/UserDailyRechargeReport.vue'
export default {
name: 'User/:userId',
mixins: [$view, $serviceType],
components: { Risk, ReceiveBill, UserConfigDialog, RealName, Withdraw, BooleanTag, Recharge, Device, Suit, Account, RecordBalance, Store, Access, UserRechargeReport, UserAccount, UserDevice, LineChart},
components: { UserDailyRechargeReport, Risk, ReceiveBill, UserConfigDialog, RealName, Withdraw, BooleanTag, Recharge, Device, Suit, Account, RecordBalance, Store, Access, UserRechargeReport, UserAccount, UserDevice, LineChart},
dicts: ['sm_user_type', 'service_type', 'withdraw_service_type'],
computed: {
SmUserType() {

View File

@ -156,6 +156,9 @@
<template v-else-if="column.key === 'deviceCount'">
{{d.row.deviceCount | defaultValue}}
</template>
<template v-else-if="column.key === 'isReal'">
<boolean-tag :value="d.row.isReal" true-text="已实名" false-text="未实名"/>
</template>
<template v-else-if="column.key === 'deviceAdmin'">
<el-tag :type="d.row.deviceAdmin ? 'danger' : 'info'">{{d.row.deviceAdmin ? '是' : '否'}}</el-tag>
</template>
@ -293,6 +296,7 @@ import { $serviceType, $showColumns, $withdrawServiceType } from '@/utils/mixins
import UserLink from '@/components/Business/SmUser/UserLink.vue'
import { SmUserType } from '@/utils/constants'
import UserConfigDialog from '@/views/system/smUser/components/UserConfigDialog.vue'
import BooleanTag from '@/components/BooleanTag/index.vue'
const defaultSort = {
prop: "createTime",
@ -302,7 +306,7 @@ const defaultSort = {
export default {
name: "SmUser",
mixins: [$showColumns, $serviceType, $withdrawServiceType],
components: { UserConfigDialog, UserLink },
components: { BooleanTag, UserConfigDialog, UserLink },
dicts: ['sm_user_status', 'sm_user_type', 'sys_user_sex', 'service_type', 'withdraw_service_type'],
computed: {
SmUserType() {
@ -322,12 +326,13 @@ export default {
span: 12,
columns: [
{key: 'userId', visible: false, label: 'ID', align: 'center', minWidth: "80", sortable: true, width: null},
{key: 'phonenumber', visible: true, label: '手机', align: 'center', minWidth: null, sortable: true, width: null},
{key: 'realOrUserName', visible: true, label: '名称', align: 'center', minWidth: null, sortable: false, width: null},
{key: 'isReal', visible: true, label: '实名', align: 'center', minWidth: null, sortable: true, width: null},
{key: 'phonenumber', visible: true, label: '手机', align: 'center', minWidth: null, sortable: true, width: null},
{key: 'type', visible: true, label: '类型', align: 'center', minWidth: null, sortable: true, width: null},
{key: 'remark', visible: true, label: '备注', align: 'center', minWidth: null, sortable: false, overflow: true, width: null},
{key: 'status', visible: true, label: '状态', align: 'center', minWidth: null, sortable: true, width: null},
{key: 'createTime', visible: true, label: '注册时间', align: 'center', minWidth: "120", sortable: true, width: "100"},
{key: 'createTime', visible: false, label: '注册时间', align: 'center', minWidth: "120", sortable: true, width: "100"},
{key: 'totalIncome', visible: true, label: '收入金额', align: 'center', minWidth: null, sortable: false, width: "120"},
{key: 'withDrawlAmount', visible: true, label: '提现金额', align: 'center', minWidth: null, sortable: false, width: "120"},
{key: 'balance', visible: true, label: '余额', align: 'center', minWidth: null, sortable: true, width: null},