Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
edd975c6b3
|
@ -43,6 +43,7 @@
|
|||
"clipboard": "2.0.8",
|
||||
"core-js": "3.37.1",
|
||||
"decimal.js": "^10.4.3",
|
||||
"driver.js": "^1.3.5",
|
||||
"echarts": "5.4.0",
|
||||
"element-ui": "2.15.14",
|
||||
"file-saver": "2.0.5",
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 4.2 KiB |
|
@ -152,3 +152,12 @@ export function deptTreeSelect() {
|
|||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 已读导览
|
||||
export function readGuide(key) {
|
||||
return request({
|
||||
url: '/system/user/guide',
|
||||
method: 'put',
|
||||
params: { key }
|
||||
})
|
||||
}
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 63 KiB |
|
@ -72,13 +72,16 @@ export default {
|
|||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
vertical-align: middle;
|
||||
|
||||
::v-deep .el-avatar {
|
||||
display: flex;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: inherit;
|
||||
font-size: 16px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
</style>
|
32
src/components/Business/Area/AreaLink.vue
Normal file
32
src/components/Business/Area/AreaLink.vue
Normal file
|
@ -0,0 +1,32 @@
|
|||
<template>
|
||||
<base-link :id="id" :text="text" :size="size" @click="handleClick" :permissions="['bst:area:query']"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BaseLink from '@/components/BaseLink/index.vue';
|
||||
export default {
|
||||
name: 'AreaLink',
|
||||
components: {BaseLink},
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
text: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: "small"
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleClick() {
|
||||
if (this.id != null && this.checkPermi(['bst:area:query'])) {
|
||||
this.$router.push(`/view/area/${this.id}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -121,6 +121,12 @@ export const constantRoutes = [
|
|||
component: () => import('@/views/system/user/view/view.vue'),
|
||||
name: 'UserView',
|
||||
meta: { title: '用户详情' }
|
||||
},
|
||||
{
|
||||
path: 'area/:id?',
|
||||
component: () => import('@/views/bst/area/view/view.vue'),
|
||||
name: 'AreaView',
|
||||
meta: { title: '运营区详情' }
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -10,6 +10,7 @@ const getters = {
|
|||
userId: state => state.user.id,
|
||||
name: state => state.user.name,
|
||||
nickName: state => state.user.nickName,
|
||||
guides: state => state.user.guides,
|
||||
introduction: state => state.user.introduction,
|
||||
roles: state => state.user.roles,
|
||||
permissions: state => state.user.permissions,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { getInfo, login, logout } from '@/api/login';
|
||||
import { readGuide } from '@/api/system/user';
|
||||
import { getToken, removeToken, setToken } from '@/utils/auth';
|
||||
// import { Watermark } from '@pansy/watermark';
|
||||
|
||||
|
@ -15,6 +16,7 @@ const user = {
|
|||
permissions: [],
|
||||
deptId: null,
|
||||
userType: null,
|
||||
guides: [],
|
||||
},
|
||||
|
||||
mutations: {
|
||||
|
@ -41,31 +43,12 @@ const user = {
|
|||
},
|
||||
SET_NICK_NAME: (state, nickName) => {
|
||||
state.nickName = nickName;
|
||||
|
||||
// if (watermark) {
|
||||
// watermark.destroy();
|
||||
// }
|
||||
// // 创建水印
|
||||
// watermark = new Watermark({
|
||||
// // 水印文案,支持多行
|
||||
// text: nickName,
|
||||
// // 水印文案样式
|
||||
// font: {
|
||||
// fontSize: 16,
|
||||
// color: 'rgba(0, 0, 0)',
|
||||
// fontFamily: 'sans-serif'
|
||||
// },
|
||||
// // 水印之间的间距
|
||||
// gap: [300, 300],
|
||||
// // 旋转角度
|
||||
// rotate: -20,
|
||||
// // 设置水印层级
|
||||
// zIndex: 9999,
|
||||
// opacity: 0.1,
|
||||
// })
|
||||
},
|
||||
SET_USER_TYPE: (state, userType) => {
|
||||
state.userType = userType;
|
||||
},
|
||||
SET_GUIDES: (state, guides) => {
|
||||
state.guides = guides;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -105,6 +88,7 @@ const user = {
|
|||
commit('SET_AVATAR', avatar)
|
||||
commit('SET_DEPT_ID', user.deptId)
|
||||
commit('SET_USER_TYPE', user.userType)
|
||||
commit('SET_GUIDES', user.guides)
|
||||
resolve(res)
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
|
@ -134,6 +118,14 @@ const user = {
|
|||
removeToken()
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
// 添加导览
|
||||
ADD_GUIDES({commit, state}, key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
readGuide(key).then(() => {
|
||||
commit('SET_GUIDES', [...state.guides, key])
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
161
src/utils/guide.js
Normal file
161
src/utils/guide.js
Normal file
|
@ -0,0 +1,161 @@
|
|||
/**
|
||||
* 用户引导
|
||||
*/
|
||||
|
||||
import store from "@/store";
|
||||
import { driver } from "driver.js";
|
||||
import "driver.js/dist/driver.css";
|
||||
export function startGuide(guideKey) {
|
||||
let guides = store.getters.guides;
|
||||
if (guides == null || !guides.includes(guideKey)) {
|
||||
let guide = guideSet[guideKey];
|
||||
if (guide) {
|
||||
guide.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const guideSet = {
|
||||
MchIndex: {
|
||||
start() {
|
||||
const driverObj = driver({
|
||||
showProgress: true,
|
||||
animate: true,
|
||||
nextBtnText: '下一步',
|
||||
prevBtnText: '上一步',
|
||||
doneBtnText: '完成',
|
||||
closeBtnText: '关闭',
|
||||
allowClose: false,
|
||||
onDestroyed: () => {
|
||||
// 导览完成后调用接口
|
||||
store.dispatch("ADD_GUIDES", "MchIndex");
|
||||
},
|
||||
steps: [
|
||||
{
|
||||
popover: {
|
||||
title: '欢迎使用小鹿骑行管理系统',
|
||||
description: '接下来我们将带您了解系统的主要功能区域',
|
||||
side: "center",
|
||||
align: 'center'
|
||||
}
|
||||
},
|
||||
{
|
||||
element: '#mch-stat',
|
||||
popover: {
|
||||
title: '运营统计',
|
||||
description: '这里显示您的运营数据统计信息,包括订单数量、金额等关键指标。',
|
||||
side: "bottom",
|
||||
align: 'start'
|
||||
}
|
||||
},
|
||||
{
|
||||
element: '#device-stat',
|
||||
popover: {
|
||||
title: '车辆统计',
|
||||
description: '这里展示设备相关的统计信息,包括设备总数、在线状态等。',
|
||||
side: "bottom",
|
||||
align: 'start'
|
||||
}
|
||||
},
|
||||
{
|
||||
element: '#order-daily-stat',
|
||||
popover: {
|
||||
title: '每日流水统计',
|
||||
description: '这里展示每日的订单流水统计图表,帮助您了解业务趋势。',
|
||||
side: "left",
|
||||
align: 'start'
|
||||
}
|
||||
},
|
||||
{
|
||||
element: '#balance-panel',
|
||||
popover: {
|
||||
title: '账户信息',
|
||||
description: '这里显示您的账户余额、待分润金额等信息,方便您随时查看收益情况。',
|
||||
side: "right",
|
||||
align: 'start'
|
||||
}
|
||||
},
|
||||
{
|
||||
popover: {
|
||||
title: '小程序管理',
|
||||
description: `
|
||||
<div>
|
||||
<p>您还可以通过小鹿骑行小程序随时随地管理您的业务,扫码即可体验。</p>
|
||||
<img src="https://api.ccttiot.com/gh_fe8a3740ae9a_1280-1745824336524.jpg" style="width: 100%; height: auto; margin: 10px auto;position:relative;" />
|
||||
</div>
|
||||
`,
|
||||
side: "center",
|
||||
align: 'center'
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
driverObj.drive();
|
||||
}
|
||||
},
|
||||
AreaSub: {
|
||||
start() {
|
||||
const driverObj = driver({
|
||||
showProgress: true,
|
||||
animate: true,
|
||||
nextBtnText: '下一步',
|
||||
prevBtnText: '上一步',
|
||||
doneBtnText: '完成',
|
||||
closeBtnText: '关闭',
|
||||
allowClose: false,
|
||||
onDestroyed: () => {
|
||||
store.dispatch("ADD_GUIDES", "AreaSub");
|
||||
},
|
||||
steps: [
|
||||
{
|
||||
popover: {
|
||||
title: '子区域管理',
|
||||
description: '欢迎使用子区域管理功能,这里您可以管理运营区下的子区域和电子围栏。',
|
||||
side: "center",
|
||||
align: 'center'
|
||||
}
|
||||
},
|
||||
{
|
||||
element: '.sub-area-list',
|
||||
popover: {
|
||||
title: '子区域列表',
|
||||
description: '左侧显示当前运营区下的所有子区域列表,您可以在这里查看和管理子区域。',
|
||||
side: "right",
|
||||
align: 'start'
|
||||
}
|
||||
},
|
||||
{
|
||||
element: '.map-container',
|
||||
popover: {
|
||||
title: '地图操作区',
|
||||
description: '右侧地图区域是您的主要操作区域,您可以在这里进行以下操作:管理子区域、修改电子围栏、查看区域详情。',
|
||||
side: "left",
|
||||
align: 'start'
|
||||
}
|
||||
},
|
||||
{
|
||||
element: '#add-sub',
|
||||
popover: {
|
||||
title: '新增子区域',
|
||||
description: '点击按钮,即可开始在地图上绘制区域(停车区、禁行区、禁停区)',
|
||||
side: "left",
|
||||
align: 'start'
|
||||
}
|
||||
},
|
||||
{
|
||||
element: '#area-edit',
|
||||
popover: {
|
||||
title: '电子围栏操作',
|
||||
description: '点击此处可以编辑电子围栏',
|
||||
side: "left",
|
||||
align: 'start'
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
driverObj.drive();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -76,7 +76,11 @@
|
|||
<dict-tag :options="dict.type.agreement_content_type" :value="row.contentType" size="mini" style="margin-left:4px"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="运营区" align="center" prop="areaName"/>
|
||||
<el-table-column label="运营区" align="center" prop="areaName">
|
||||
<template slot-scope="d">
|
||||
<area-link :id="d.row.areaId" :text="d.row.areaName"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="简介" align="center" prop="brief"/>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime"/>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
|
@ -192,6 +196,7 @@ import Editor from "@/components/Editor/index.vue";
|
|||
import AreaRemoteSelect from "@/components/Business/Area/AreaRemoteSelect.vue";
|
||||
import UserLink from "@/components/Business/User/UserLink.vue";
|
||||
import {isSysAdmin} from "@/utils/permission";
|
||||
import AreaLink from '@/components/Business/Area/AreaLink.vue'
|
||||
|
||||
// 默认排序字段
|
||||
const defaultSort = {
|
||||
|
@ -203,7 +208,13 @@ export default {
|
|||
name: "Agreement",
|
||||
mixins: [$showColumns],
|
||||
dicts: ['agreement_type', 'agreement_content_type'],
|
||||
components: {FormCol, Editor, AreaRemoteSelect, UserLink},
|
||||
components: {FormCol, Editor, AreaRemoteSelect, UserLink, AreaLink},
|
||||
props: {
|
||||
query: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
span: 24,
|
||||
|
@ -326,6 +337,7 @@ export default {
|
|||
},
|
||||
},
|
||||
created() {
|
||||
Object.assign(this.queryParams, this.query);
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -104,7 +104,7 @@
|
|||
{{d.row[column.key]}}
|
||||
</template>
|
||||
<template v-else-if="column.key === 'name'">
|
||||
{{d.row.name}}
|
||||
<area-link :id="d.row.id" :text="d.row.name" />
|
||||
<dict-tag :options="dict.type.area_status" :value="d.row.status" size="mini"/>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'areaTimeStart'">
|
||||
|
@ -131,6 +131,13 @@
|
|||
</template>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="280">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-view"
|
||||
@click="handleView(scope.row)"
|
||||
v-has-permi="['bst:area:query']"
|
||||
>详情</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
|
@ -187,6 +194,7 @@ import { listArea, delArea } from "@/api/bst/area";
|
|||
import { $showColumns } from '@/utils/mixins';
|
||||
import AreaCustomerServiceDialog from "@/views/bst/area/components/AreaCustomerServiceDialog.vue";
|
||||
import UserLink from '@/components/Business/User/UserLink.vue';
|
||||
import AreaLink from '@/components/Business/Area/AreaLink.vue';
|
||||
// 默认排序字段
|
||||
const defaultSort = {
|
||||
prop: "createTime",
|
||||
|
@ -199,7 +207,8 @@ export default {
|
|||
dicts: ['area_status'],
|
||||
components: {
|
||||
AreaCustomerServiceDialog,
|
||||
UserLink
|
||||
UserLink,
|
||||
AreaLink
|
||||
},
|
||||
props: {
|
||||
query: {
|
||||
|
@ -269,6 +278,9 @@ export default {
|
|||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
handleView(row) {
|
||||
this.$router.push({ path: `/view/area/${row.id}` });
|
||||
},
|
||||
handleCustomerService(row) {
|
||||
this.row = row;
|
||||
this.visibleCustomerService = true;
|
||||
|
|
103
src/views/bst/area/view/view.vue
Normal file
103
src/views/bst/area/view/view.vue
Normal file
|
@ -0,0 +1,103 @@
|
|||
<template>
|
||||
<div class="app-container" v-loading="loading" >
|
||||
<el-card header="基础信息" class="card-box">
|
||||
<el-descriptions :column="4">
|
||||
<el-descriptions-item label="名称">
|
||||
{{ detail.name }}
|
||||
<dict-tag :options="dict.type.area_status" :value="detail.status" size="small" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="运营时间">
|
||||
{{ detail.areaTimeStart | dv }} - {{ detail.areaTimeEnd | dv }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="运营商">
|
||||
<user-link :id="detail.userId" :text="detail.userName" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="创建人">
|
||||
<user-link :id="detail.createId" :text="detail.createName" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="创建时间">{{ detail.createTime | dv }}</el-descriptions-item>
|
||||
<el-descriptions-item label="备注" :span="2">{{ detail.remark | dv }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
|
||||
<el-card v-if="detail.id" class="card-box">
|
||||
<el-tabs>
|
||||
<el-tab-pane label="电子围栏" lazy v-if="checkPermi(['bst:areaSub:list'])">
|
||||
<area-sub :area-id="detail.id"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="车辆列表" lazy v-if="checkPermi(['bst:device:list'])">
|
||||
<device :query="{areaId: detail.id}" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="订单列表" lazy v-if="checkPermi(['bst:order:list'])">
|
||||
<order :query="{areaId: detail.id}" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="加盟列表" lazy v-if="checkPermi(['bst:areaJoin:list'])">
|
||||
<area-join :query="{areaId: detail.id, types: [AreaJoinType.JOIN, AreaJoinType.COOPERATE]}" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="运维列表" lazy v-if="checkPermi(['bst:areaJoin:list'])">
|
||||
<area-join :query="{areaId: detail.id, types: [AreaJoinType.OPERATION]}" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="客服列表" lazy v-if="checkPermi(['bst:customerService:list'])">
|
||||
<customer-service :query="{areaId: detail.id}"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="公告协议" lazy v-if="checkPermi(['bst:agreement:list'])">
|
||||
<agreement :query="{areaId: detail.id}"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="操作日志" lazy v-if="checkPermi(['monitor:operlog:list'])">
|
||||
<oper-log :query="{bizId: detail.id, bizType: LogBizType.AREA}" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getArea } from '@/api/bst/area';
|
||||
import UserLink from '@/components/Business/User/UserLink.vue';
|
||||
import AreaSub from '@/views/bst/areaSub/index.vue';
|
||||
import Device from '@/views/bst/device/index.vue';
|
||||
import Order from '@/views/bst/order/index.vue';
|
||||
import AreaJoin from '@/views/bst/areaJoin/index.vue';
|
||||
import { AreaJoinType, LogBizType } from '@/utils/enums';
|
||||
import CustomerService from '@/views/bst/customerService/index.vue';
|
||||
import Agreement from '@/views/bst/agreement/index.vue';
|
||||
import OperLog from '@/views/monitor/operlog/index.vue';
|
||||
|
||||
export default {
|
||||
name: 'AreaView',
|
||||
dicts: ['area_status'],
|
||||
components: {
|
||||
UserLink,
|
||||
AreaSub,
|
||||
Device,
|
||||
Order,
|
||||
AreaJoin,
|
||||
CustomerService,
|
||||
Agreement,
|
||||
OperLog
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
AreaJoinType,
|
||||
LogBizType,
|
||||
detail: {},
|
||||
loading: false,
|
||||
id: null,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.id = this.$route.params.id;
|
||||
this.getDetail();
|
||||
},
|
||||
methods: {
|
||||
getDetail() {
|
||||
this.loading = true;
|
||||
getArea(this.id).then(res => {
|
||||
this.detail = res.data;
|
||||
}).finally(() => {
|
||||
this.loading = false;
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -12,7 +12,7 @@
|
|||
<el-select v-model="queryParams.type" placeholder="请选择类型" clearable @change="handleQuery">
|
||||
<template v-for="dict in dict.type.area_join_type">
|
||||
<el-option
|
||||
v-if="types.includes(dict.value)"
|
||||
v-if="queryParams.types.includes(dict.value)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
|
@ -109,6 +109,9 @@
|
|||
<template v-else-if="column.key === 'createName'">
|
||||
<user-link :id="d.row.createId" :text="d.row.createName" />
|
||||
</template>
|
||||
<template v-else-if="column.key === 'areaName'">
|
||||
<area-link :id="d.row.areaId" :text="d.row.areaName" />
|
||||
</template>
|
||||
<template v-else>
|
||||
{{d.row[column.key]}}
|
||||
</template>
|
||||
|
@ -149,7 +152,7 @@
|
|||
:id="editId"
|
||||
:init-data="initData"
|
||||
@success="getList"
|
||||
:types="types"
|
||||
:types="queryParams.types"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -160,7 +163,8 @@ import { $showColumns } from '@/utils/mixins';
|
|||
import AreaJoinEditDialog from './components/AreaJoinEditDialog';
|
||||
import UserLink from '@/components/Business/User/UserLink.vue';
|
||||
import AreaRemoteSelect from '@/components/Business/Area/AreaRemoteSelect.vue';
|
||||
|
||||
import { isEmpty } from '@/utils';
|
||||
import AreaLink from '@/components/Business/Area/AreaLink.vue';
|
||||
// 默认排序字段
|
||||
const defaultSort = {
|
||||
prop: "createTime",
|
||||
|
@ -171,7 +175,13 @@ export default {
|
|||
name: "AreaJoin",
|
||||
mixins: [$showColumns],
|
||||
dicts: ['area_join_type', 'area_join_permission'],
|
||||
components: { AreaJoinEditDialog, UserLink, AreaRemoteSelect },
|
||||
components: { AreaJoinEditDialog, UserLink, AreaRemoteSelect, AreaLink },
|
||||
props: {
|
||||
query: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 字段列表
|
||||
|
@ -218,14 +228,18 @@ export default {
|
|||
areaId: null,
|
||||
userId: null,
|
||||
remark: null,
|
||||
createId: null
|
||||
createId: null,
|
||||
types: []
|
||||
},
|
||||
types: [], // 类型列表
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.types = this.$route.query?.types?.split(',') || [];
|
||||
if (!isEmpty(this.propTypes)) {
|
||||
this.types = this.propTypes;
|
||||
}
|
||||
this.queryParams.types = this.types;
|
||||
Object.assign(this.queryParams, this.query);
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
<!-- 地图工具栏 -->
|
||||
<div class="map-tools">
|
||||
<el-button-group>
|
||||
<el-button size="mini" type="primary" icon="el-icon-plus" @click="startBoundaryEdit(null)" v-if="enableEdit" :disabled="isEditing">子区域</el-button>
|
||||
<el-button size="mini" type="warning" icon="el-icon-edit" @click="startAreaBoundaryEdit" v-if="enableEdit" :disabled="isEditing">电子围栏</el-button>
|
||||
<el-button size="mini" id="add-sub" type="primary" icon="el-icon-plus" @click="startBoundaryEdit(null)" v-if="enableEdit" :disabled="isEditing">子区域</el-button>
|
||||
<el-button size="mini" id="area-edit" type="warning" icon="el-icon-edit" @click="startAreaBoundaryEdit" v-if="enableEdit" :disabled="isEditing">电子围栏</el-button>
|
||||
<el-button size="mini" icon="el-icon-full-screen" @click="setFitView">全局查看</el-button>
|
||||
<el-button size="mini" icon="el-icon-picture" @click="toggleMapStyle">切换样式</el-button>
|
||||
<el-button size="mini" icon="el-icon-document" @click="toggleLabels">{{ showLabels ? '隐藏' : '显示' }}标签</el-button>
|
||||
|
@ -300,7 +300,6 @@ export default {
|
|||
position: absolute;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.boundary-tools {
|
||||
|
|
|
@ -186,6 +186,7 @@ import { getArea, updateArea } from '@/api/bst/area';
|
|||
import { AreaSubStatus, AreaSubType } from '@/utils/enums';
|
||||
import AreaMap from '@/views/bst/areaSub/components/AreaMap.vue';
|
||||
import AreaSubEditDialog from '@/views/bst/areaSub/components/AreaSubEditDialog.vue';
|
||||
import {startGuide} from "@/utils/guide"
|
||||
|
||||
// 默认排序字段
|
||||
const defaultSort = {
|
||||
|
@ -198,6 +199,12 @@ export default {
|
|||
mixins: [$showColumns],
|
||||
dicts: ['area_sub_type', 'area_sub_status'],
|
||||
components: {FormCol, AreaMap, AreaSubEditDialog},
|
||||
props: {
|
||||
areaId: {
|
||||
type: String,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
AreaSubStatus,
|
||||
|
@ -271,9 +278,17 @@ export default {
|
|||
};
|
||||
},
|
||||
created() {
|
||||
if (this.areaId) {
|
||||
this.queryParams.areaId = this.areaId;
|
||||
} else {
|
||||
this.queryParams.areaId = this.$route.params.areaId;
|
||||
}
|
||||
this.getArea();
|
||||
this.getList();
|
||||
|
||||
this.$nextTick(()=> {
|
||||
startGuide("AreaSub");
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
handleRowClick(row) {
|
||||
|
|
|
@ -88,6 +88,9 @@
|
|||
<template v-if="column.key === 'id'">
|
||||
{{d.row[column.key]}}
|
||||
</template>
|
||||
<template v-else-if="column.key === 'areaName'">
|
||||
<area-link :id="d.row.areaId" :text="d.row.areaName"/>
|
||||
</template>
|
||||
<template v-else-if="column.key==='isEnabled'">
|
||||
<dict-tag
|
||||
:options="dict.type.customer_service_status"
|
||||
|
@ -147,6 +150,7 @@ import { $showColumns } from '@/utils/mixins';
|
|||
import FormCol from "@/components/FormCol/index.vue";
|
||||
import CustomerServiceEditDialog from "@/views/bst/customerService/components/CustomerServiceEditDialog.vue";
|
||||
import AreaRemoteSelect from "@/components/Business/Area/AreaRemoteSelect.vue";
|
||||
import AreaLink from "@/components/Business/Area/AreaLink.vue";
|
||||
|
||||
// 默认排序字段
|
||||
const defaultSort = {
|
||||
|
@ -157,7 +161,7 @@ const defaultSort = {
|
|||
export default {
|
||||
name: "CustomerService",
|
||||
mixins: [$showColumns],
|
||||
components: {AreaRemoteSelect, CustomerServiceEditDialog, FormCol},
|
||||
components: {AreaRemoteSelect, CustomerServiceEditDialog, FormCol, AreaLink},
|
||||
dicts:['customer_service_status'],
|
||||
props: {
|
||||
query: {
|
||||
|
@ -178,7 +182,7 @@ export default {
|
|||
span: 24,
|
||||
// 字段列表
|
||||
columns: [
|
||||
{key: 'id', visible: true, label: 'ID', minWidth: null, sortable: true, overflow: false, align: 'center', width: "80"},
|
||||
{key: 'id', visible: false, label: 'ID', minWidth: null, sortable: true, overflow: false, align: 'center', width: "80"},
|
||||
{key: 'areaName', visible: true, label: '运营区', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
{key: 'name', visible: true, label: '姓名', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
{key: 'contact', visible: true, label: '联系方式', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
|
|
|
@ -226,7 +226,8 @@
|
|||
<template v-else-if="column.key === 'mchName'">
|
||||
<i class="el-icon-office-building"/>
|
||||
<user-link :id="d.row.mchId" :text="d.row.mchName" size="mini"/><br/>
|
||||
<i class="el-icon-location"/>{{d.row.areaName | dv}}
|
||||
<i class="el-icon-location"/>
|
||||
<area-link :id="d.row.areaId" :text="d.row.areaName" size="mini"/>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'lockStatus'">
|
||||
<el-tooltip content="开锁:共享模块有开锁的信号输出;电门开:车子处于开锁可骑行状态" placement="top">
|
||||
|
@ -244,9 +245,9 @@
|
|||
{{d.row.remainEndurance | dv}} KM
|
||||
</template>
|
||||
<template v-else-if="column.key === 'vehicleNum'">
|
||||
<i class="el-icon-bicycle"/>
|
||||
{{d.row.vehicleNum | dv}}<br/>
|
||||
<i class="el-icon-tickets"/>
|
||||
{{d.row.vehicleNum | dv}}<br/>
|
||||
<i class="el-icon-bicycle"/>
|
||||
{{d.row.modelName | dv}}
|
||||
</template>
|
||||
<template v-else-if="column.key === 'music'">
|
||||
|
@ -412,6 +413,7 @@ import DeviceSn from '@/views/bst/device/components/DeviceSn.vue';
|
|||
import UserLink from '@/components/Business/User/UserLink.vue';
|
||||
import DeviceLink from '@/components/Business/Device/DeviceLink.vue';
|
||||
import AreaRemoteSelect from '@/components/Business/Area/AreaRemoteSelect.vue';
|
||||
import AreaLink from '@/components/Business/Area/AreaLink.vue';
|
||||
|
||||
// 默认排序字段
|
||||
const defaultSort = {
|
||||
|
@ -423,7 +425,7 @@ export default {
|
|||
name: "Device",
|
||||
mixins: [$showColumns, $device],
|
||||
dicts: ['device_status', 'device_lock_status', 'device_iot_status', 'device_online_status', 'device_quality', 'device_music'],
|
||||
components: {FormCol, DeviceEditDialog, BooleanTag, DeviceTransferDialog, DeviceSn, UserLink, DeviceLink, AreaRemoteSelect},
|
||||
components: {FormCol, DeviceEditDialog, BooleanTag, DeviceTransferDialog, DeviceSn, UserLink, DeviceLink, AreaRemoteSelect, AreaLink},
|
||||
props: {
|
||||
query: {
|
||||
type: Object,
|
||||
|
|
|
@ -18,14 +18,14 @@
|
|||
</el-row>
|
||||
|
||||
<!-- 统计信息 -->
|
||||
<mch-stat :stat="stat" :today-stat="todayStat" :mine-stat="mineStat" :today-mine-stat="todayMineStat" />
|
||||
<mch-stat id="mch-stat" :stat="stat" :today-stat="todayStat"/>
|
||||
|
||||
<!-- 设备统计信息 -->
|
||||
<device-stat :stat="stat"/>
|
||||
<device-stat id="device-stat" :stat="stat"/>
|
||||
|
||||
<el-row :gutter="gutter" style="margin-top:12px">
|
||||
<el-col :sm="24" :md="16">
|
||||
<el-card header="每日流水统计" shadow="never">
|
||||
<el-card header="每日流水统计" shadow="never" id="order-daily-stat">
|
||||
<order-daily-stat ref="dailyStat" :query="areaQuery"/>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
@ -39,7 +39,7 @@
|
|||
<i class="el-icon-user"></i>
|
||||
我的
|
||||
</div>
|
||||
<balance-panel v-if="userInfo" :balance="userInfo.balance" :waitBonus="userStat.bonus.waitDivideAmount" :totalWithdraw="userStat.withdraw.successAmount"/>
|
||||
<balance-panel v-if="userInfo" id="balance-panel" :balance="userInfo.balance" :waitBonus="userStat.bonus.waitDivideAmount" :totalWithdraw="userStat.withdraw.successAmount"/>
|
||||
|
||||
<!-- 待办事项 -->
|
||||
<todo-list :stat="stat"/>
|
||||
|
@ -64,6 +64,7 @@ import { listSimpleArea } from '@/api/bst/area'
|
|||
import BalancePanel from '@/views/bst/index/components/BalancePanel'
|
||||
import OrderStat from '@/views/bst/index/components/OrderStat'
|
||||
import { mapGetters } from 'vuex'
|
||||
import {startGuide} from '@/utils/guide'
|
||||
|
||||
export default {
|
||||
name: 'Index',
|
||||
|
@ -99,6 +100,9 @@ export default {
|
|||
created() {
|
||||
this.getUserInfo();
|
||||
this.getAreaList();
|
||||
this.$nextTick(()=> {
|
||||
startGuide("MchIndex");
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
getAreaList() {
|
||||
|
|
|
@ -59,10 +59,10 @@ export default {
|
|||
},
|
||||
// 可退款金额
|
||||
canRefundAmount() {
|
||||
let payAmount = this.detail.payAmount || 0;
|
||||
let payedAmount = this.detail.payedAmount || 0;
|
||||
let payRefunded = this.detail.payRefunded || 0;
|
||||
let payRefunding = this.detail.payRefunding || 0;
|
||||
return payAmount - payRefunded - payRefunding;
|
||||
return payedAmount - payRefunded - payRefunding;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -67,8 +67,8 @@
|
|||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable @change="handleQuery">
|
||||
<el-form-item label="状态" prop="statusList">
|
||||
<el-select v-model="queryParams.statusList" placeholder="请选择状态" clearable @change="handleQuery" multiple>
|
||||
<el-option
|
||||
v-for="dict in dict.type.order_status"
|
||||
:key="dict.value"
|
||||
|
@ -148,7 +148,7 @@
|
|||
</template>
|
||||
<template v-else-if="column.key === 'suitName'">
|
||||
{{d.row.suitName | dv}}<br/>
|
||||
<dictd-tag :options="dict.type.suit_type" :value="d.row.suitType" size="mini"/>
|
||||
<dict-tag :options="dict.type.suit_type" :value="d.row.suitType" size="mini"/>
|
||||
<dict-tag :options="dict.type.order_status" :value="d.row.status" size="mini" style="margin-left: 4px;"/>
|
||||
<dict-tag :options="dict.type.suit_riding_rule" :value="d.row.suitRidingRule" size="mini" style="margin-left: 4px;"/>
|
||||
</template>
|
||||
|
@ -162,13 +162,24 @@
|
|||
<template v-else-if="column.key === 'totalFee'">
|
||||
<div>
|
||||
<el-row :gutter="8">
|
||||
<el-col :span="12" v-if="d.row.payedAmount" style="color: green;font-weight: bold;">实收:{{d.row.payedAmount - d.row.payRefunded - d.row.payRefunding | fix2 | dv}} 元</el-col>
|
||||
<el-col :span="12" v-if="d.row.depositFee != null">预存:{{d.row.depositFee | fix2 | dv}} 元</el-col>
|
||||
<el-col :span="12" v-if="d.row.totalFee != null">结算:{{d.row.totalFee | fix2 | dv}} 元</el-col>
|
||||
<el-col :span="12" v-if="d.row.ridingFee != null">骑行:{{d.row.ridingFee | fix2 | dv}} 元</el-col>
|
||||
<el-col :span="12" v-if="d.row.dispatchFee">调度:{{d.row.dispatchFee | fix2 | dv}} 元</el-col>
|
||||
<el-col :span="12" v-if="d.row.manageFee">管理:{{d.row.manageFee | fix2 | dv}} 元</el-col>
|
||||
<el-col :span="12" v-if="d.row.deductionFee">车损:{{d.row.deductionFee | fix2 | dv}} 元</el-col>
|
||||
<el-col :span="12" v-if="d.row.depositFee != null">预存:{{d.row.depositFee | fix2 | dv}} 元</el-col>
|
||||
<el-col :span="12" v-if="d.row.totalFee != null">
|
||||
<el-popover
|
||||
placement="bottom"
|
||||
width="200"
|
||||
trigger="hover"
|
||||
>
|
||||
<div>
|
||||
<div>骑行费:{{d.row.ridingFee | fix2 | dv}} 元</div>
|
||||
<div>调度费:{{d.row.dispatchFee | fix2 | dv}} 元</div>
|
||||
<div>管理费:{{d.row.manageFee | fix2 | dv}} 元</div>
|
||||
<div>车损费:{{d.row.deductionFee | fix2 | dv}} 元</div>
|
||||
</div>
|
||||
<div slot="reference">结算:{{d.row.totalFee | fix2 | dv}} 元 <i class="el-icon-info" /></div>
|
||||
</el-popover>
|
||||
</el-col>
|
||||
<el-col :span="12" v-if="d.row.payedAmount" style="color: green;font-weight: bold;">实收:{{d.row.payedAmount - d.row.payRefunded - d.row.payRefunding | fix2 | dv}} 元</el-col>
|
||||
<el-col :span="24" v-if="d.row.payRefunded || d.row.payRefunding" style="color: red;">
|
||||
退款:{{d.row.payRefunded | fix2 | dv}} 元
|
||||
<template v-if="d.row.payRefunding">(退款中:{{d.row.payRefunding | fix2 | dv}} 元)</template>
|
||||
|
@ -212,7 +223,8 @@
|
|||
<user-link :id="d.row.userId" :text="d.row.userPhone" size="mini"/>
|
||||
</div>
|
||||
<div v-if="d.row.areaName != null">
|
||||
<i class="el-icon-location"/>{{d.row.areaName | dv}}
|
||||
<i class="el-icon-location"/>
|
||||
<area-link :id="d.row.areaId" :text="d.row.areaName" size="mini"/>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
|
@ -283,6 +295,7 @@ import { toDescriptionFromSecond } from '@/utils/date';
|
|||
import UserLink from '@/components/Business/User/UserLink.vue';
|
||||
import DeviceLink from '@/components/Business/Device/DeviceLink.vue'
|
||||
import OrderLink from '@/components/Business/Order/OrderLink.vue'
|
||||
import AreaLink from '@/components/Business/Area/AreaLink.vue';
|
||||
|
||||
// 默认排序字段
|
||||
const defaultSort = {
|
||||
|
@ -294,7 +307,7 @@ export default {
|
|||
name: "Order",
|
||||
mixins: [$showColumns],
|
||||
dicts: ['order_status', 'suit_type', 'order_return_type', 'order_return_mode', 'suit_rental_unit', 'suit_riding_rule'],
|
||||
components: {FormCol, OrderRefundDialog, OrderVerifyDialog, UserLink, DeviceLink, OrderLink},
|
||||
components: {FormCol, OrderRefundDialog, OrderVerifyDialog, UserLink, DeviceLink, OrderLink, AreaLink},
|
||||
props: {
|
||||
query: {
|
||||
type: Object,
|
||||
|
@ -346,6 +359,7 @@ export default {
|
|||
pageSize: 20,
|
||||
orderByColumn: defaultSort.prop,
|
||||
isAsc: defaultSort.order,
|
||||
statusList: OrderStatus.valid(),
|
||||
id: null,
|
||||
no: null,
|
||||
type: null,
|
||||
|
|
|
@ -2,6 +2,95 @@
|
|||
<div class="app-container" v-loading="loading">
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="18">
|
||||
<el-card class="mb10">
|
||||
<el-row :gutter="20" type="flex">
|
||||
<el-col>
|
||||
<el-statistic title="骑行费" :value="detail.ridingFee" :precision="2" suffix="元">
|
||||
<template slot="prefix">
|
||||
<i class="el-icon-bicycle" style="color: #409EFF"></i>
|
||||
</template>
|
||||
</el-statistic>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-statistic title="预存" :value="detail.depositFee" :precision="2" suffix="元">
|
||||
<template slot="prefix">
|
||||
<i class="el-icon-money" style="color: #67C23A"></i>
|
||||
</template>
|
||||
</el-statistic>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-popover placement="bottom" width="200" trigger="hover">
|
||||
<div>
|
||||
<div>骑行费:{{detail.ridingFee | fix2 | dv}} 元</div>
|
||||
<div>调度费:{{detail.dispatchFee | fix2 | dv}} 元</div>
|
||||
<div>管理费:{{detail.manageFee | fix2 | dv}} 元</div>
|
||||
<div>车损费:{{detail.deductionFee | fix2 | dv}} 元</div>
|
||||
</div>
|
||||
<el-statistic slot="reference" :value="detail.totalFee" :precision="2" suffix="元">
|
||||
<template slot="prefix">
|
||||
<i class="el-icon-wallet" style="color: #E6A23C"></i>
|
||||
</template>
|
||||
<template slot="title">
|
||||
结算金额
|
||||
<i class="el-icon-info" style="color: #909399; margin-left: 4px; cursor: pointer"></i>
|
||||
</template>
|
||||
</el-statistic>
|
||||
</el-popover>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-statistic
|
||||
title="实收"
|
||||
:value="detail.payedAmount - detail.payRefunded - detail.payRefunding"
|
||||
:precision="2"
|
||||
suffix="元"
|
||||
value-style="color: #67C23A">
|
||||
<template slot="prefix">
|
||||
<i class="el-icon-success" style="color: #67C23A"></i>
|
||||
</template>
|
||||
</el-statistic>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-statistic
|
||||
title="总退款"
|
||||
:value="detail.payRefunded"
|
||||
:precision="2"
|
||||
suffix="元"
|
||||
value-style="color: #F56C6C">
|
||||
<template slot="prefix">
|
||||
<i class="el-icon-refresh-left" style="color: #F56C6C"></i>
|
||||
</template>
|
||||
<template v-if="detail.payRefunding" slot="suffix">
|
||||
<span style="color: #F56C6C; font-size: 12px">(退款中:{{ detail.payRefunding | fix2 | dv }} 元)</span>
|
||||
</template>
|
||||
</el-statistic>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-statistic
|
||||
title="自动退款"
|
||||
:value="detail.payAutoRefund"
|
||||
:precision="2"
|
||||
suffix="元"
|
||||
value-style="color: #F56C6C">
|
||||
<template slot="prefix">
|
||||
<i class="el-icon-timer" style="color: #F56C6C"></i>
|
||||
</template>
|
||||
</el-statistic>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-statistic
|
||||
title="人工退款"
|
||||
:value="detail.payAdminRefund"
|
||||
:precision="2"
|
||||
suffix="元"
|
||||
value-style="color: #F56C6C">
|
||||
<template slot="prefix">
|
||||
<i class="el-icon-user" style="color: #F56C6C"></i>
|
||||
</template>
|
||||
</el-statistic>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<el-row class="mb10" type="flex" justify="end">
|
||||
<el-button
|
||||
|
@ -26,7 +115,7 @@
|
|||
size="small"
|
||||
plain
|
||||
type="warning"
|
||||
icon="el-icon-wallet"
|
||||
icon="el-icon-s-check"
|
||||
@click="handleVerify(detail)"
|
||||
v-has-permi="['bst:order:verify']"
|
||||
v-show="OrderStatus.canVerify().includes(detail.status)"
|
||||
|
@ -34,15 +123,19 @@
|
|||
</el-row>
|
||||
<collapse-panel :value="true" title="基础信息">
|
||||
<el-descriptions :column="4" >
|
||||
<el-descriptions-item label="订单编号">{{ detail.no | dv}}</el-descriptions-item>
|
||||
<el-descriptions-item label="订单编号">
|
||||
{{ detail.no | dv}}
|
||||
<el-link v-clipboard:copy="detail.no" v-clipboard:success="handleCopySuccess" type="primary" icon="el-icon-document"/>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="订单状态">
|
||||
<dict-tag :options="dict.type.order_status" :value="detail.status" size="small"/>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="运营区">{{ detail.areaName | dv}}</el-descriptions-item>
|
||||
<el-descriptions-item label="运营区">
|
||||
<area-link :id="detail.areaId" :text="detail.areaName" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="创建时间">{{ detail.createTime | dv}}</el-descriptions-item>
|
||||
<el-descriptions-item label="开始时间">{{ detail.startTime | dv}}</el-descriptions-item>
|
||||
<el-descriptions-item label="结束时间">{{ detail.endTime | dv}}</el-descriptions-item>
|
||||
<el-descriptions-item label="到期时间">{{ detail.maxTime | dv}}</el-descriptions-item>
|
||||
<el-descriptions-item label="骑行时长">{{ orderDuration | dv}}</el-descriptions-item>
|
||||
<el-descriptions-item label="骑行距离">{{ detail.distance / 1000 | fix2 | dv}} 公里</el-descriptions-item>
|
||||
<el-descriptions-item label="结束原因" v-if="detail.endReason">{{ detail.endReason | dv }}</el-descriptions-item>
|
||||
|
@ -50,27 +143,10 @@
|
|||
</el-descriptions>
|
||||
</collapse-panel>
|
||||
|
||||
<collapse-panel :value="true" title="费用信息">
|
||||
<el-descriptions :column="4" >
|
||||
<el-descriptions-item label="预存">{{ detail.depositFee | fix2 | dv }} 元</el-descriptions-item>
|
||||
<el-descriptions-item label="结算金额" v-if="detail.totalFee != null">{{ detail.totalFee | fix2 | dv }} 元</el-descriptions-item>
|
||||
<el-descriptions-item label="骑行费" v-if="detail.ridingFee != null">{{ detail.ridingFee | fix2 | dv }} 元</el-descriptions-item>
|
||||
<el-descriptions-item label="调度费" v-if="detail.dispatchFee">{{ detail.dispatchFee | fix2 | dv }} 元</el-descriptions-item>
|
||||
<el-descriptions-item label="管理费" v-if="detail.manageFee">{{ detail.manageFee | fix2 | dv }} 元</el-descriptions-item>
|
||||
<el-descriptions-item label="车损费" v-if="detail.deductionFee">{{ detail.deductionFee | fix2 | dv }} 元</el-descriptions-item>
|
||||
<el-descriptions-item label="退款">
|
||||
{{ detail.payRefunded | fix2 | dv }} 元
|
||||
<template v-if="detail.payRefunding">
|
||||
<span style="color: red;">(退款中:{{ detail.payRefunding | fix2 | dv }} 元)</span>
|
||||
</template>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="实收">{{ detail.payedAmount - detail.payRefunded - detail.payRefunding | fix2 | dv }} 元</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</collapse-panel>
|
||||
|
||||
<collapse-panel :value="true" title="套餐信息">
|
||||
<el-descriptions :column="4" >
|
||||
<el-descriptions-item label="套餐名称">
|
||||
<el-descriptions-item label="套餐名称" :span="2">
|
||||
{{ detail.suitName }}
|
||||
<dict-tag :options="dict.type.suit_type" :value="detail.suitType" size="mini" style="margin-left: 4px;"/>
|
||||
<dict-tag :options="dict.type.suit_riding_rule" :value="detail.suitRidingRule" size="mini" style="margin-left: 4px;"/>
|
||||
|
@ -102,21 +178,6 @@
|
|||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</collapse-panel>
|
||||
|
||||
<!-- <collapse-panel :value="true" title="归还信息">
|
||||
<el-descriptions :column="4" >
|
||||
<el-descriptions-item label="定位方式">
|
||||
<dict-tag :options="dict.type.order_return_mode" :value="detail.returnMode" size="small"/>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="归还类型">
|
||||
<dict-tag :options="dict.type.order_return_type" :value="detail.returnType" size="small"/>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="归还时间">{{ detail.endTime }}</el-descriptions-item>
|
||||
<el-descriptions-item label="归还定位">{{ detail.returnLon | dv }}, {{ detail.returnLat | dv }}</el-descriptions-item>
|
||||
<el-descriptions-item label="起始站点">{{ detail.startAreaSubName | dv }}</el-descriptions-item>
|
||||
<el-descriptions-item label="归还站点">{{ detail.endAreaSubName | dv }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</collapse-panel> -->
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
|
@ -160,7 +221,7 @@
|
|||
<el-card class="box-card" v-if="detail.id" style="margin-top: 10px;">
|
||||
<el-tabs lazy>
|
||||
<el-tab-pane label="车辆轨迹" v-if="checkPermi(['bst:locationLog:list'])">
|
||||
<device-location :query="{orderId: detail.id, timeRange: [detail.startTime, detail.endTime == null ? detail.maxTime : detail.endTime]}" :area-id="detail.areaId" />
|
||||
<device-location :query="{orderId: detail.id, timeRange: []}" :area-id="detail.areaId" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="收益信息" v-if="checkPermi(['bst:bonus:list'])">
|
||||
<bonus :query="{bstId: detail.id, bstType: BonusBstType.ORDER}" />
|
||||
|
@ -207,6 +268,7 @@ import CommandLog from '@/views/bst/commandLog/index.vue'
|
|||
import DeviceLink from '@/components/Business/Device/DeviceLink.vue'
|
||||
import UserLink from '@/components/Business/User/UserLink.vue'
|
||||
import {getOrderDuration} from '@/views/bst/order/util'
|
||||
import AreaLink from '@/components/Business/Area/AreaLink.vue'
|
||||
|
||||
export default {
|
||||
name: 'OrderView',
|
||||
|
@ -223,7 +285,8 @@ export default {
|
|||
Operlog,
|
||||
CommandLog,
|
||||
DeviceLink,
|
||||
UserLink
|
||||
UserLink,
|
||||
AreaLink
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -249,6 +312,9 @@ export default {
|
|||
this.getDetail()
|
||||
},
|
||||
methods: {
|
||||
handleCopySuccess() {
|
||||
this.$message.success("复制成功");
|
||||
},
|
||||
toDescriptionFromSecond,
|
||||
getDetail() {
|
||||
this.loading = true
|
||||
|
@ -285,3 +351,14 @@ export default {
|
|||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.red-text {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.green-text {
|
||||
color: green;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
<template v-else-if="column.key === 'reason'">
|
||||
<order-link v-if="PayBstType.ORDER === d.row.payBstType" :id="d.row.payBstId" :text="d.row.reason" />
|
||||
<span v-else>{{d.row.reason | dv}}</span>
|
||||
<dict-tag :options="dict.type.refund_type" :value="d.row.type" size="mini" style="margin-left: 4px;"/>
|
||||
<dict-tag :options="dict.type.refund_status" :value="d.row.status" size="mini" style="margin-left: 4px;"/>
|
||||
<dict-tag :options="dict.type.pay_bst_type" :value="d.row.payBstType" size="mini" style="margin-left: 4px;"/>
|
||||
</template>
|
||||
|
@ -119,7 +120,7 @@ const defaultSort = {
|
|||
export default {
|
||||
name: "Refund",
|
||||
mixins: [$showColumns],
|
||||
dicts: ['refund_status', 'pay_bst_type'],
|
||||
dicts: ['refund_status', 'pay_bst_type', 'refund_type'],
|
||||
components: {FormCol, UserLink, OrderLink},
|
||||
props: {
|
||||
query: {
|
||||
|
|
|
@ -172,8 +172,8 @@ export default {
|
|||
|
||||
.bg-box {
|
||||
flex: 1;
|
||||
background-image: url("../assets/images/login-background.png");
|
||||
-webkit-background-image: url("../assets/images/login-background.png");
|
||||
background-image: url("https://api.ccttiot.com/fd7f9ab7c2bb4ddd816282cc91079230dbfd985b1092f-I7XJ3y-1745887744159.jpg");
|
||||
-webkit-background-image: url("https://api.ccttiot.com/fd7f9ab7c2bb4ddd816282cc91079230dbfd985b1092f-I7XJ3y-1745887744159.jpg");
|
||||
background-size: cover;
|
||||
-webkit-background-size: cover;
|
||||
background-position: center;
|
||||
|
@ -202,13 +202,18 @@ export default {
|
|||
}
|
||||
}
|
||||
.login-form {
|
||||
position: relative;
|
||||
position: absolute;
|
||||
background: #ffffff;
|
||||
width: 480px;
|
||||
padding: 200px 64px 5px;
|
||||
width: 420px;
|
||||
padding: 48px 48px 24px ;
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: calc(100vh - env(safe-area-inset-bottom));
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
height: fit-content;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.1);
|
||||
.el-input {
|
||||
height: 38px;
|
||||
input {
|
||||
|
|
|
@ -116,7 +116,11 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="请求地址" align="center" prop="operUrl" :show-overflow-tooltip="true" sortable="custom" :sort-orders="['descending', 'ascending']" />
|
||||
<el-table-column label="操作人" align="center" prop="operName" :show-overflow-tooltip="true" sortable="custom" :sort-orders="['descending', 'ascending']" />
|
||||
<el-table-column label="操作人" align="center" prop="operName" :show-overflow-tooltip="true" sortable="custom" :sort-orders="['descending', 'ascending']">
|
||||
<template slot-scope="scope">
|
||||
<user-link :id="scope.row.operUserId" :text="scope.row.operName" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="请求IP" align="center" prop="operIp" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="操作时间" align="center" prop="operTime" width="160" sortable="custom" :sort-orders="['descending', 'ascending']"/>
|
||||
<el-table-column label="消耗时间" align="center" prop="costTime" width="110" :show-overflow-tooltip="true" sortable="custom" :sort-orders="['descending', 'ascending']">
|
||||
|
@ -194,10 +198,14 @@
|
|||
|
||||
<script>
|
||||
import { cleanOperlog, delOperlog, list } from '@/api/monitor/operlog'
|
||||
import UserLink from '@/components/Business/User/UserLink'
|
||||
|
||||
export default {
|
||||
name: "Operlog",
|
||||
dicts: ['sys_oper_type', 'sys_common_status', 'log_biz_type'],
|
||||
components: {
|
||||
UserLink
|
||||
},
|
||||
props: {
|
||||
query: {
|
||||
type: Object,
|
||||
|
@ -241,11 +249,7 @@ export default {
|
|||
},
|
||||
|
||||
created() {
|
||||
this.queryParams = {
|
||||
...this.queryParams,
|
||||
...this.query
|
||||
}
|
||||
|
||||
Object.assign(this.queryParams, this.query)
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
<template>
|
||||
<el-link v-if="userType === UserType.ADMIN" type="primary" @click="handleClick" :disabled="id == null">{{name | defaultValue}}</el-link>
|
||||
<span v-else >{{name | defaultValue}}</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import { UserType } from '@/utils/constants'
|
||||
|
||||
export default {
|
||||
name: 'UserLink',
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
default: null,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
UserType() {
|
||||
return UserType
|
||||
},
|
||||
...mapGetters(['userType'])
|
||||
},
|
||||
methods: {
|
||||
handleClick() {
|
||||
this.$emit('click');
|
||||
this.$router.push({path: `/smUser/user/${this.id}`})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -119,12 +119,6 @@
|
|||
<template v-else-if="column.key === 'deptId'">
|
||||
{{d.row.dept == null ? '' : d.row.dept.deptName}}
|
||||
</template>
|
||||
<template v-else-if="column.key === 'status'">
|
||||
<dict-tag :value="d.row.status" :options="dict.type.user_status" size="small"/>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'isReal'">
|
||||
<boolean-tag :value="d.row.isReal" size="small"/>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'point'">
|
||||
{{ d.row.point | fix2 | dv }} %
|
||||
</template>
|
||||
|
@ -145,8 +139,13 @@
|
|||
<el-tag :key="index" v-if="!isEmpty(role.roleName)" size="small" style="margin-right: 4px;">{{role.roleName}}</el-tag>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else-if="['nickName', 'userName', 'email'].includes(column.key)">
|
||||
<user-link :id="d.row.userId" :text="d.row[column.key]" />
|
||||
<template v-else-if="['nickName'].includes(column.key)">
|
||||
<avatar :src="d.row.avatar" :size="24" :name="d.row.nickName" :char-index="-1" style="margin-right:4px"/>
|
||||
<user-link :id="d.row.userId" :text="d.row.nickName" />
|
||||
<dict-tag :options="dict.type.user_status" :value="d.row.status" size="mini" style="margin-left: 4px;"/>
|
||||
<boolean-tag :value="d.row.isReal" size="mini" true-text="已实名" false-text="未实名" style="margin-left: 4px;"/>
|
||||
<br/>
|
||||
<user-link :id="d.row.userId" :text="d.row.userName" />
|
||||
</template>
|
||||
<template v-else-if="column.key === 'agentName'">
|
||||
<user-link :id="d.row.agentId" :text="d.row.agentName" />
|
||||
|
@ -239,6 +238,7 @@ import BooleanTag from '@/components/BooleanTag/index.vue'
|
|||
import UserLink from '@/components/Business/User/UserLink.vue'
|
||||
import RoleSelect from '@/components/Business/Role/RoleSelect.vue'
|
||||
import UserShowPasswordDialog from '@/views/system/user/components/UserShowPasswordDialog.vue'
|
||||
import Avatar from '@/components/Avatar/index.vue'
|
||||
|
||||
// 默认排序字段
|
||||
const defaultSort = {
|
||||
|
@ -250,7 +250,7 @@ export default {
|
|||
name: "User",
|
||||
mixins: [$showColumns],
|
||||
dicts: ['user_status', 'sys_user_sex', 'user_employ_status', 'withdraw_service_type'],
|
||||
components: {UserFormDialog, FormCol, DeptSelect, BooleanTag, UserLink, RoleSelect, UserShowPasswordDialog},
|
||||
components: {UserFormDialog, FormCol, DeptSelect, BooleanTag, UserLink, RoleSelect, UserShowPasswordDialog, Avatar},
|
||||
data() {
|
||||
return {
|
||||
WithdrawServiceType,
|
||||
|
@ -300,15 +300,14 @@ export default {
|
|||
// 列信息
|
||||
columns: [
|
||||
{key: 'userId', visible: false, label: 'ID', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
{key: 'nickName', visible: true, label: '姓名', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
{key: 'userName', visible: true, label: '账号', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
{key: 'nickName', visible: true, label: '姓名', minWidth: null, sortable: true, overflow: false, align: 'left', width: "250"},
|
||||
{key: 'roles', visible: true, label: '角色', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
{key: 'point', visible: true, label: '分成比例', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
{key: 'withdrawServiceValue', visible: true, label: '提现服务费', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
{key: 'bonusDelay', visible: true, label: '到账延迟', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
{key: 'balance', 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: 'isReal', 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: 'isReal', visible: true, label: '实名状态', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
{key: 'agentName', visible: true, label: '所属代理', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
{key: 'deptName', visible: true, label: '归属部门', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
{key: 'email', visible: false, label: '邮箱', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
<line-field label="角色">
|
||||
{{ detail.roles.map(role => role.roleName).join(',') }}
|
||||
</line-field>
|
||||
<line-field label="手机号" :value="detail.phonenumber" />
|
||||
<line-field label="登录账号" :value="detail.userName" />
|
||||
<line-field label="分成比例">
|
||||
{{ detail.point | fix2 | dv }} %
|
||||
|
@ -49,10 +48,10 @@
|
|||
|
||||
<el-card class="card-box" style="margin-top: 12px;" shadow="hover" v-if="detail.userId">
|
||||
<el-tabs>
|
||||
<el-tab-pane label="设备" lazy v-if="checkPermi(['bst:device:list'])">
|
||||
<el-tab-pane label="车辆" lazy v-if="checkPermi(['bst:device:list'])">
|
||||
<device :query="{mchId: detail.userId}" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="车辆型号" lazy v-if="checkPermi(['bst:model:list'])">
|
||||
<el-tab-pane label="车型" lazy v-if="checkPermi(['bst:model:list'])">
|
||||
<model :query="{userId: detail.userId}" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="套餐" lazy v-if="checkPermi(['bst:suit:list'])">
|
||||
|
@ -61,30 +60,45 @@
|
|||
<el-tab-pane label="运营区" lazy v-if="checkPermi(['bst:area:list'])">
|
||||
<area-index :query="{userId: detail.userId}" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="消费订单" lazy v-if="checkPermi(['bst:order:list'])">
|
||||
<order :query="{userId: detail.userId}" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="收入订单" lazy v-if="checkPermi(['bst:order:list'])">
|
||||
<order :query="{bonusUserId: detail.userId}" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="车辆出租记录" lazy v-if="checkPermi(['bst:orderDevice:list'])">
|
||||
<el-tab-pane label="出租记录" lazy v-if="checkPermi(['bst:orderDevice:list'])">
|
||||
<order-device :query="{deviceMchId: detail.userId}" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="分成记录" lazy v-if="checkPermi(['bst:bonus:list'])">
|
||||
<el-tab-pane label="分成" lazy v-if="checkPermi(['bst:bonus:list'])">
|
||||
<bonus :query="{arrivalId: detail.userId, arrivalTypes: BonusArrivalType.userList()}" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="提现记录" lazy v-if="checkPermi(['bst:withdraw:list'])">
|
||||
<el-tab-pane label="提现" lazy v-if="checkPermi(['bst:withdraw:list'])">
|
||||
<withdraw :query="{userId: detail.userId}" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="账变记录" lazy v-if="checkPermi(['bst:balanceLog:list'])">
|
||||
<el-tab-pane label="账变" lazy v-if="checkPermi(['bst:balanceLog:list'])">
|
||||
<balance-log :query="{userId: detail.userId}" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="实名认证" lazy v-if="checkPermi(['bst:realName:list'])">
|
||||
<el-tab-pane label="实名" lazy v-if="checkPermi(['bst:realName:list'])">
|
||||
<real-name :query="{userId: detail.userId}" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="加盟区域" lazy v-if="checkPermi(['bst:areaJoin:list'])">
|
||||
<area-join :query="{userId: detail.userId, types: [AreaJoinType.JOIN, AreaJoinType.COOPERATE]}" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="运维区域" lazy v-if="checkPermi(['bst:areaJoin:list'])">
|
||||
<area-join :query="{userId: detail.userId, types: [AreaJoinType.OPERATION]}" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="收款账户" lazy v-if="checkPermi(['bst:account:list'])">
|
||||
<account :query="{userId: detail.userId}" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="用户APP" lazy v-if="checkPermi(['bst:userApp:list'])">
|
||||
<user-app :query="{userId: detail.userId}" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="操作日志" lazy v-if="checkPermi(['monitor:operlog:list'])">
|
||||
<oper-log :query="{operUserId: detail.userId}" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="被操作日志" lazy v-if="checkPermi(['monitor:operlog:list'])">
|
||||
<oper-log :query="{bizId: detail.userId, bizType: LogBizType.USER}" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-card>
|
||||
</div>
|
||||
|
@ -99,7 +113,7 @@ import UserStatistics from '@/views/system/user/view/components/UserStatistics'
|
|||
import CollapsePanel from '@/components/CollapsePanel'
|
||||
import BooleanTag from '@/components/BooleanTag'
|
||||
import Bonus from '@/views/bst/bonus/index.vue'
|
||||
import { BonusArrivalType } from '@/utils/enums'
|
||||
import { BonusArrivalType, AreaJoinType, LogBizType } from '@/utils/enums'
|
||||
import OrderDailyStat from '@/views/bst/index/components/OrderDailyStat.vue'
|
||||
import Device from '@/views/bst/device/index.vue'
|
||||
import AreaIndex from '@/views/bst/area/index.vue'
|
||||
|
@ -112,6 +126,8 @@ import Model from '@/views/bst/model/index.vue'
|
|||
import OrderDevice from '@/views/bst/orderDevice/index.vue'
|
||||
import Withdraw from '@/views/bst/withdraw/index.vue'
|
||||
import RealName from '@/views/bst/realName/index.vue'
|
||||
import AreaJoin from '@/views/bst/areaJoin/index.vue'
|
||||
import OperLog from '@/views/monitor/operlog/index.vue'
|
||||
|
||||
export default {
|
||||
name: 'UserView',
|
||||
|
@ -133,11 +149,15 @@ export default {
|
|||
Model,
|
||||
OrderDevice,
|
||||
Withdraw,
|
||||
RealName
|
||||
RealName,
|
||||
AreaJoin,
|
||||
OperLog
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
BonusArrivalType,
|
||||
AreaJoinType,
|
||||
LogBizType,
|
||||
detail: {
|
||||
roles: []
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue
Block a user