j1ack 2 years ago
parent
commit
8b2a3cc54a
  1. 9
      src/api/merchant/merchant.js
  2. 67
      src/layout/components/Navbar.vue
  3. 9
      src/utils/constants.js
  4. 284
      src/utils/ruoyi.js
  5. 17
      src/views/data-view/data-view.vue
  6. 4
      src/views/merchant/merchant/index.vue

9
src/api/merchant/merchant.js

@ -53,3 +53,12 @@ export function exportMerchant(query) {
params: query
})
}
// 商户数据
export function onLineMerchant(query) {
return request({
url: '/system/merchant/onLineMerchant',
method: 'get',
params: query
})
}

67
src/layout/components/Navbar.vue

@ -9,8 +9,17 @@
<div class="right-menu">
<template v-if="device !== 'mobile'">
<!-- <el-button type="primary" icon="" size="small" style="margin-right:24px"-->
<!-- @click="dialogVisible = true">码商押金</el-button>-->
<el-button
v-hasPermi="['system:merchant:onLineMerchant']"
type="primary" icon="" size="small" style="margin-right:24px" @click="onMerchantBalanceClick">
商户余额
</el-button>
<el-button
v-hasPermi="['carddealer:carddealer:onLineCarddealer']"
type="primary" icon="" size="small" style="margin-right:24px" @click="onCarddealerMarginClick">
码商押金
</el-button>
<el-button type="primary" icon="" size="small" style="margin-right:24px" @click="goDataView"
v-hasPermi="['data-view']">数据看板</el-button>
@ -59,14 +68,14 @@
<el-dialog title="码商押金" :visible.sync="dialogVisible" width="20%">
<el-table :data="tableData" style="width: 100%">
<el-table-column :label="'名称'" align="center" prop="storeNo" min-width="150">
<el-table-column :label="'名称'" align="center" prop="username" min-width="150">
<template slot-scope="scope">
<span style="color:#333">{{ scope.row.username }}</span>
</template>
</el-table-column>
<el-table-column :label="'押金'" align="center" prop="storeNo" min-width="150">
<el-table-column :label="'押金'" align="center" prop="margin" min-width="150">
<template slot-scope="scope">
<span :style="{ color: NumberDiv(scope.row.margin, 100) < 5000 ? '#FF3535' : '#30C17B' }">
<span :style="{ color: scope.row.balanceWarning === 1 ? '#FF3535' : '#30C17B' }">
{{ NumberDiv(scope.row.margin, 100) }}
</span>
</template>
@ -74,6 +83,23 @@
</el-table>
</el-dialog>
<el-dialog title="商户余额" :visible.sync="merchantDialogStates.visible" width="20%">
<el-table :data="merchantDialogStates.data" style="width: 100%">
<el-table-column label="名称" align="center" prop="username" min-width="150">
<template slot-scope="scope">
<span style="color:#333">{{ scope.row.username }}</span>
</template>
</el-table-column>
<el-table-column label="余额" align="center" prop="balance" min-width="150">
<template slot-scope="scope">
<span :style="{ color: scope.row.balanceWarning === 1 ? '#FF3535' : '#30C17B' }">
{{ NumberDiv(scope.row.balance, 100) }}
</span>
</template>
</el-table-column>
</el-table>
</el-dialog>
</div>
</template>
@ -89,6 +115,7 @@ import RuoYiGit from '@/components/RuoYi/Git'
import RuoYiDoc from '@/components/RuoYi/Doc'
import { getUserProfile } from "@/api/system/user";
import { common_api } from "@/api/form";
import { onLineMerchant } from '@/api/merchant/merchant'
export default {
components: {
@ -109,6 +136,13 @@ export default {
dialogVisible: false,
tableData: [],
timer: null,
//
merchantDialogStates: {
//
visible: false,
//
data: [],
}
};
},
computed: {
@ -139,8 +173,6 @@ export default {
},
mounted() {
this.getUser();
this.getList();
this.secondMethod()
},
methods: {
goDataView() {
@ -152,15 +184,20 @@ export default {
})
window.open(href.href, '_blank')
},
secondMethod() {
// this.timer = setInterval(() => {
// this.getList();
// }, 30000)
//
onMerchantBalanceClick() {
this.merchantDialogStates.visible = true
onLineMerchant()
.then(res => {
this.merchantDialogStates.data = res.data
})
},
getList() {
// common_api.onLineCarddealer().then((response) => {
// this.tableData = response.data
// });
//
onCarddealerMarginClick() {
this.dialogVisible = true
common_api.onLineCarddealer().then((response) => {
this.tableData = response.data
});
},
//
onAutoRefreshChanged(value) {

9
src/utils/constants.js

@ -0,0 +1,9 @@
const isDev = process.env.VUE_APP_BASE_API !== "/prod-api";
const Constants = {
isDev,
wsHost: isDev ? `ws://kaka-qws.weirui0755.com/websocket` : "wss://wss.bodabay.com/websocket",
}
console.log("config", Constants)
export default Constants;

284
src/utils/ruoyi.js

@ -25,68 +25,67 @@ const baseURL = process.env.VUE_APP_BASE_API
* @return {{beginTime: string, endTime: string}}
*/
export function calcRange(array) {
let range = {};
let range = {}
if (array && array.length > 0) {
range.beginTime = parseTime(array[0]);
range.endTime = parseTime(array[1]);
range.beginTime = parseTime(array[0])
range.endTime = parseTime(array[1])
// 替换 endTime 为 23:59:59
range.endTime = range.endTime.replace(/(\d{2}:\d{2}:\d{2})/, '23:59:59');
range.endTime = range.endTime.replace(/(\d{2}:\d{2}:\d{2})/, '23:59:59')
} else {
throw new Error('Date range is empty!');
throw new Error('Date range is empty!')
}
return range;
return range
}
// 时区北京
export function BeiJingDate() {
return new Date(new Date().getTime()+(parseInt(new Date().getTimezoneOffset()/60) + 8)*3600*1000);
return new Date(new Date().getTime() + (parseInt(new Date().getTimezoneOffset() / 60) + 8) * 3600 * 1000)
}
// 通用下载方法
export function download(fileName) {
window.location.href = baseURL + "/common/download?fileName=" + encodeURI(fileName) + "&delete=" + true;
window.location.href = baseURL + '/common/download?fileName=' + encodeURI(fileName) + '&delete=' + true
}
//获取当前年月日
export function today() {
let nowDate = new Date();
let nowDate = new Date()
let date = {
year: nowDate.getFullYear(),
month: nowDate.getMonth() + 1,
date: nowDate.getDate(),
date: nowDate.getDate()
}
if (date.date <= 9) {
return date.year + '-' + 0 + date.month + '-' + 0 + date.date;
return date.year + '-' + 0 + date.month + '-' + 0 + date.date
} else {
return date.year + '-' + 0 + date.month + '-' + date.date;
return date.year + '-' + 0 + date.month + '-' + date.date
}
}
// 添加日期范围
export function addSESDateRange(params, dateRange, propName) {
var search = params;
var search = params
search.beginTime = null
search.endTime = null;
search.endTime = null
search.updateBeginTime = null
search.updateEndTime = null;
search.updateEndTime = null
if (propName) {
if (dateRange[0]) {
if (dateRange[0][0] && dateRange[0][1]) {
search.beginTime = dateRange[0][0];
search.endTime = dateRange[0][1];
search.beginTime = dateRange[0][0]
search.endTime = dateRange[0][1]
} else if (!dateRange[0][0]) {
search.beginTime = undefined;
search.endTime = undefined;
search.beginTime = undefined
search.endTime = undefined
}
}
if (dateRange[1]) {
if (dateRange[1][0] && dateRange[1][1]) {
search.updateBeginTime = dateRange[1][0];
search.updateEndTime = dateRange[1][1];
search.updateBeginTime = dateRange[1][0]
search.updateEndTime = dateRange[1][1]
} else if (!dateRange[1][0]) {
search.updateBeginTime = undefined;
search.updateEndTime = undefined;
search.updateBeginTime = undefined
search.updateEndTime = undefined
}
}
}
@ -95,16 +94,16 @@ export function addSESDateRange(params, dateRange, propName) {
// search.beginTime = dateRange[0];
// search.endTime = dateRange[1];
if (dateRange[0] && dateRange[1]) {
search.beginTime = dateRange[0];
search.endTime = dateRange[1];
search.beginTime = dateRange[0]
search.endTime = dateRange[1]
} else if (!dateRange[0]) {
search.beginTime = undefined;
search.endTime = undefined;
search.beginTime = undefined
search.endTime = undefined
}
}
}
return search;
return search
}
// 日期格式化
@ -120,7 +119,7 @@ export function parseTime(time, pattern) {
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
time = parseInt(time)
} else if (typeof time === 'string') {
time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '');
time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '')
}
if ((typeof time === 'number') && (time.toString().length === 10)) {
time = time * 1000
@ -153,91 +152,91 @@ export function parseTime(time, pattern) {
// 表单重置
export function resetForm(refName) {
if (this.$refs[refName]) {
this.$refs[refName].resetFields();
this.$refs[refName].resetFields()
}
}
// 添加日期范围
export function addDateRange(params, dateRange, propName) {
let search = params;
search.params = typeof (search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {};
dateRange = Array.isArray(dateRange) ? dateRange : [];
let search = params
search.params = typeof (search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {}
dateRange = Array.isArray(dateRange) ? dateRange : []
if (typeof (propName) === 'undefined') {
search.params['beginTime'] = dateRange[0];
search.params['endTime'] = dateRange[1];
search.params['beginTime'] = dateRange[0]
search.params['endTime'] = dateRange[1]
} else {
search.params['begin' + propName] = dateRange[0];
search.params['end' + propName] = dateRange[1];
search.params['begin' + propName] = dateRange[0]
search.params['end' + propName] = dateRange[1]
}
return search;
return search
}
// 回显数据字典
export function selectDictLabel(datas, value) {
if (value === undefined) {
return "";
return ''
}
var actions = [];
var actions = []
Object.keys(datas).some((key) => {
if (datas[key].value == ('' + value)) {
actions.push(datas[key].label);
return true;
actions.push(datas[key].label)
return true
}
})
if (actions.length === 0) {
actions.push(value);
actions.push(value)
}
return actions.join('');
return actions.join('')
}
// 回显数据字典(字符串、数组)
export function selectDictLabels(datas, value, separator) {
if (value === undefined || value.length === 0) {
return "";
return ''
}
if (Array.isArray(value)) {
value = value.join(",");
value = value.join(',')
}
var actions = [];
var currentSeparator = undefined === separator ? "," : separator;
var temp = value.split(currentSeparator);
var actions = []
var currentSeparator = undefined === separator ? ',' : separator
var temp = value.split(currentSeparator)
Object.keys(value.split(currentSeparator)).some((val) => {
var match = false;
var match = false
Object.keys(datas).some((key) => {
if (datas[key].value == ('' + temp[val])) {
actions.push(datas[key].label + currentSeparator);
match = true;
actions.push(datas[key].label + currentSeparator)
match = true
}
})
if (!match) {
actions.push(temp[val] + currentSeparator);
actions.push(temp[val] + currentSeparator)
}
})
return actions.join('').substring(0, actions.join('').length - 1);
return actions.join('').substring(0, actions.join('').length - 1)
}
// 字符串格式化(%s )
export function sprintf(str) {
var args = arguments,
flag = true,
i = 1;
str = str.replace(/%s/g, function () {
var arg = args[i++];
i = 1
str = str.replace(/%s/g, function() {
var arg = args[i++]
if (typeof arg === 'undefined') {
flag = false;
return '';
flag = false
return ''
}
return arg;
});
return flag ? str : '';
return arg
})
return flag ? str : ''
}
// 转换字符串,undefined,null等转化为""
export function parseStrEmpty(str) {
if (!str || str == "undefined" || str == "null") {
return "";
if (!str || str == 'undefined' || str == 'null') {
return ''
}
return str;
return str
}
// 数据合并
@ -245,16 +244,16 @@ export function mergeRecursive(source, target) {
for (var p in target) {
try {
if (target[p].constructor == Object) {
source[p] = mergeRecursive(source[p], target[p]);
source[p] = mergeRecursive(source[p], target[p])
} else {
source[p] = target[p];
source[p] = target[p]
}
} catch (e) {
source[p] = target[p];
source[p] = target[p]
}
}
return source;
};
return source
}
/**
* 构造树型结构数据
@ -268,43 +267,44 @@ export function handleTree(data, id, parentId, children) {
id: id || 'id',
parentId: parentId || 'parentId',
childrenList: children || 'children'
};
}
var childrenListMap = {};
var nodeIds = {};
var tree = [];
var childrenListMap = {}
var nodeIds = {}
var tree = []
for (let d of data) {
let parentId = d[config.parentId];
let parentId = d[config.parentId]
if (childrenListMap[parentId] == null) {
childrenListMap[parentId] = [];
childrenListMap[parentId] = []
}
nodeIds[d[config.id]] = d;
childrenListMap[parentId].push(d);
nodeIds[d[config.id]] = d
childrenListMap[parentId].push(d)
}
for (let d of data) {
let parentId = d[config.parentId];
let parentId = d[config.parentId]
if (nodeIds[parentId] == null) {
tree.push(d);
tree.push(d)
}
}
for (let t of tree) {
adaptToChildrenList(t);
adaptToChildrenList(t)
}
function adaptToChildrenList(o) {
if (childrenListMap[o[config.id]] !== null) {
o[config.childrenList] = childrenListMap[o[config.id]];
o[config.childrenList] = childrenListMap[o[config.id]]
}
if (o[config.childrenList]) {
for (let c of o[config.childrenList]) {
adaptToChildrenList(c);
adaptToChildrenList(c)
}
}
}
return tree;
return tree
}
/**
@ -314,19 +314,19 @@ export function handleTree(data, id, parentId, children) {
export function tansParams(params) {
let result = ''
for (const propName of Object.keys(params)) {
const value = params[propName];
var part = encodeURIComponent(propName) + "=";
if (value !== null && value !== "" && typeof (value) !== "undefined") {
const value = params[propName]
var part = encodeURIComponent(propName) + '='
if (value !== null && value !== '' && typeof (value) !== 'undefined') {
if (typeof value === 'object') {
for (const key of Object.keys(value)) {
if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') {
let params = propName + '[' + key + ']';
var subPart = encodeURIComponent(params) + "=";
result += subPart + encodeURIComponent(value[key]) + "&";
if (value[key] !== null && value[key] !== '' && typeof (value[key]) !== 'undefined') {
let params = propName + '[' + key + ']'
var subPart = encodeURIComponent(params) + '='
result += subPart + encodeURIComponent(value[key]) + '&'
}
}
} else {
result += part + encodeURIComponent(value) + "&";
result += part + encodeURIComponent(value) + '&'
}
}
}
@ -336,11 +336,11 @@ export function tansParams(params) {
// 验证是否为blob格式
export async function blobValidate(data) {
try {
const text = await data.text();
JSON.parse(text);
return false;
const text = await data.text()
JSON.parse(text)
return false
} catch (error) {
return true;
return true
}
}
@ -348,8 +348,8 @@ export async function blobValidate(data) {
* toFixed 但是不四舍五入
*/
export function toFixedWithOutRounded(num, s) {
const re = new RegExp('^-?\\d+(?:\.\\d{0,' + (s || -1) + '})?');
return num.toString().match(re)[0];
const re = new RegExp('^-?\\d+(?:\.\\d{0,' + (s || -1) + '})?')
return num.toString().match(re)[0]
}
/**
@ -374,29 +374,29 @@ export const amountFormat = (o) => {
decimalLength = 2,
decimalSeparator = '.',
thousandSeparator = ','
} = o;
} = o
// 将金额转换为数字类型
const numAmount = typeof amount === 'string' ? parseFloat(amount) : amount;
const numAmount = typeof amount === 'string' ? parseFloat(amount) : amount
if (isNaN(numAmount)) {
return '';
return ''
}
// 根据精度对金额进行四舍五入
const roundedAmount = numAmount / precision;
const roundedAmount = numAmount / precision
// 格式化小数部分
let formattedAmount = decimal ? roundedAmount.toFixed(decimalLength) : Math.floor(roundedAmount).toString();
let formattedAmount = decimal ? roundedAmount.toFixed(decimalLength) : Math.floor(roundedAmount).toString()
// 添加千分位分隔符
if (thousand) {
const parts = formattedAmount.split('.');
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousandSeparator);
formattedAmount = parts.join(decimalSeparator);
const parts = formattedAmount.split('.')
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousandSeparator)
formattedAmount = parts.join(decimalSeparator)
}
return formattedAmount;
};
return formattedAmount
}
/**
* 格式化金额, 自动进万, 百万
@ -404,65 +404,57 @@ export const amountFormat = (o) => {
* @param unit
*/
export function amountFriendlyFormat(amount, unit) {
// 百万
if (amount >= 1000000 || unit === '百万') {
return {
unit: '百万',
amount: amount / 1000000,
display: `${amount / 1000000}百万`
const result = {
unit: '',
amount: Number(toFixedWithOutRounded(amount, 2)),
display: Number(toFixedWithOutRounded(amount, 2))
}
// 千万
if (amount >= 10000000 || unit === '千万') {
result.unit = '千万'
result.amount = Number(toFixedWithOutRounded(amount / 10000000, 0))
result.display = `${result.amount} 千万`
}
// 万
if (amount >= 10000 || unit === '万') {
return {
unit: '万',
amount: amount / 10000,
display: `${amount / 10000}`
}
}
// 百
// if (amount >= 100 || unit === '百') {
// return {
// unit: '百',
// amount: amount / 100,
// display: `${amount / 100}百`
// }
// }
return {
unit: '',
amount: amount,
display: amount
};
result.unit = '万'
result.amount = Number(toFixedWithOutRounded(amount / 10000, 0))
result.display = `${result.amount}`
}
return result
}
/**
* sortBy
*/
export function sortBy(arr, key) {
return arr.sort(function (a, b) {
return a[key] - b[key];
});
return arr.sort(function(a, b) {
return a[key] - b[key]
})
}
/**
* 获取今天星期几
*/
export function getWeek() {
let week = new Date().getDay();
let week = new Date().getDay()
switch (week) {
case 0:
return "星期日";
return '星期日'
case 1:
return "星期一";
return '星期一'
case 2:
return "星期二";
return '星期二'
case 3:
return "星期三";
return '星期三'
case 4:
return "星期四";
return '星期四'
case 5:
return "星期五";
return '星期五'
case 6:
return "星期六";
return '星期六'
}
}

17
src/views/data-view/data-view.vue

@ -59,14 +59,13 @@
<template #right-table>
<data-view-table
title="在线卡数据"
:columnSizes="[14.2,14.2,14.2,14.2,14.2,14.2,14.2,]"
:columnSizes="[16,16,16,16,16,16]"
:columns="[
{label: '银行名称', key: 'bankName'},
{label: '姓名', key: 'cardHolder'},
{label: '卡商名称', key: 'username'},
{label: '已收款', key: 'todayIncomeReceived'},
{label: '剩余额度', key: 'todayRemainingAmount'},
{label: '余额', key: 'remainingAmount'},
{label: '通道', key: 'channels'},
]"
:data="data2"
@ -74,11 +73,11 @@
ref="table2"
>
<template #channels="{row}">
<horizontal-scroll-pane>
<div style="width: 100%;">
<span v-for="channelName of row.channels" :key="channelName">
{{ channelName }}
</span>
</horizontal-scroll-pane>
</div>
</template>
</data-view-table>
</template>
@ -94,6 +93,7 @@ import DataViewTable from './components/data-view-table.vue'
import { amountFormat, amountFriendlyFormat, sortBy } from '@/utils/ruoyi'
import screenfull from 'screenfull'
import HorizontalScrollPane from './components/horizontal-scroll-pane.vue'
import Constants from '@/utils/constants'
export default {
components: { HorizontalScrollPane, DataViewTable, DataViewLayout, DataViewEchart },
@ -197,7 +197,9 @@ export default {
localStorage.setItem('isMute', this.isMute)
},
connectWS() {
this.ws = new WebSocket(`ws://kaka-qws.weirui0755.com/websocket`)
this.ws = new WebSocket(Constants.wsHost)
// `ws://kaka-qws.weirui0755.com/websocket` : "wss://wss.bodabay.com/websocket"
// this.ws = new WebSocket("wss://wss.bodabay.com/websocket")
this.ws.onopen = () => {
this.ws.send(JSON.stringify({ 'type': 'add_push' }))
}
@ -250,8 +252,9 @@ export default {
this.chart3.total = chart3Total.amount
this.chart3.totalLabel = '总订单:' + chart3Total.display
const transferSuccessAmount = statisticsPush.transferSuccessAmount
const transferTotalAmount = statisticsPush.transferTotalAmount
const transferSuccessAmount = this.NumberDiv(statisticsPush.transferSuccessAmount, 100)
const transferTotalAmount = this.NumberDiv(statisticsPush.transferTotalAmount, 100)
const chart4Total = amountFriendlyFormat(transferTotalAmount)
const chart4Value = amountFriendlyFormat(transferSuccessAmount, chart4Total.unit)

4
src/views/merchant/merchant/index.vue

@ -330,7 +330,7 @@
:inactive-value=false></el-switch>
</el-form-item>
<!-- <el-form-item label="手动提单审核开关" prop="whetherReview">
<el-form-item label="手动提单审核开关" prop="whetherReview">
<el-switch v-model="form.whetherReview" active-text="" inactive-text="" active-value="Y"
inactive-value="N"></el-switch>
</el-form-item>
@ -338,7 +338,7 @@
<el-form-item label="api提单审核开关" prop="whetherReviewApi">
<el-switch v-model="form.whetherReviewApi" active-text="" inactive-text="" active-value="Y"
inactive-value="N"></el-switch>
</el-form-item> -->
</el-form-item>
<el-form-item label="谷歌秘钥" prop="merchantNo">
<span>{{ form.googleCaptcha }}</span>

Loading…
Cancel
Save