Parcourir la source

服务商页面提交

hxl13994548489 il y a 1 mois
Parent
commit
ac1de4a946

+ 4 - 1
src/main.js

@@ -88,8 +88,11 @@ app.config.globalProperties.$baseUrl = baseUrl //设置全局变量$baseUrl
 
 //封装全局Ajax公共函数
 app.config.globalProperties.$http = function(url, method, data, async, fun) {
+	if(!url.includes("http://localhost:8201/")){
+		url = baseUrl + url;
+	}
 	$.ajax({
-		url: baseUrl + url,
+		url: url,
 		type: method,
 		dataType: 'json',
 		contentType: "application/json",

+ 44 - 13
src/router/index.js

@@ -2,7 +2,7 @@ import {
 	createRouter,
 	createWebHashHistory
 }
-from 'vue-router'
+	from 'vue-router'
 import Login from '../views/login.vue'
 import Main from "../views/main.vue"
 import Home from "../views/home.vue"
@@ -17,26 +17,29 @@ import Order from "../views/order.vue"
 import Comment from "../views/comment.vue"
 import Voucher from "../views/voucher.vue"
 import Monitoring from "../views/monitoring.vue"
+import Service from "../views/service.vue"
+import ServiceUser from "../views/service-user.vue"
+import ServicePackage from "../views/service-package.vue"
 import NotFound from "../views/404.vue"
 
 
 const routes = [{
-		path: '/login',
-		name: 'Login',
-		component: Login
-	},
+	path: '/login',
+	name: 'Login',
+	component: Login
+},
 	{
 		path: '/',
 		name: 'Main',
 		component: Main,
 		children: [{
-				path: '/home',
-				name: 'Home',
-				component: Home,
-				meta: {
-					title: '首页',
-				}
-			},
+			path: '/home',
+			name: 'Home',
+			component: Home,
+			meta: {
+				title: '首页',
+			}
+		},
 			{
 				path: "/role",
 				name: "Role",
@@ -135,7 +138,35 @@ const routes = [{
 					title: '代金券',
 					isTab: true
 				}
-			}
+			},
+			{
+				path: '/service-user',
+				name: 'ServiceUser',
+				component: ServiceUser,
+				meta: {
+					title: '服务商',
+					isTab: true
+				}
+			},
+			{
+				path: '/service',
+				name: 'Service',
+				component: Service,
+				meta: {
+					title: '服务商',
+					isTab: true
+				}
+			},
+			{
+				path: '/service-package',
+				name: 'ServicePackage',
+				component: ServicePackage,
+				meta: {
+					title: '服务包',
+					isTab: true
+				}
+			},
+
 		]
 	},
 	{

+ 577 - 0
src/views/service-package.vue

@@ -0,0 +1,577 @@
+<template>
+	<div v-if="isAuth(['ROOT', 'ORDER:SELECT'])">
+		<el-form :inline="true" :model="dataForm" :rules="dataRule" ref="dataForm">
+			<el-form-item prop="orderId">
+				<el-input v-model="dataForm.orderId" placeholder="订单编号" size="medium" clearable="clearable" />
+			</el-form-item>
+			<el-form-item prop="driverId">
+				<el-input v-model="dataForm.driverId" placeholder="司机编号" size="medium" clearable="clearable" />
+			</el-form-item>
+			<el-form-item prop="customerId">
+				<el-input v-model="dataForm.customerId" placeholder="客户编号" size="medium" clearable="clearable" />
+			</el-form-item>
+			<el-form-item>
+				<el-date-picker
+					v-model="dataForm.date"
+					type="daterange"
+					range-separator="~"
+					start-placeholder="开始日期"
+					end-placeholder="结束日期"
+					size="medium"
+				></el-date-picker>
+			</el-form-item>
+			<el-form-item>
+				<el-select
+					v-model="dataForm.status"
+					class="input"
+					placeholder="状态"
+					size="medium"
+					clearable="clearable"
+				>
+					<el-option label="等待接单" value="1" />
+					<el-option label="已接单" value="2" />
+					<el-option label="司机已到达" value="3" />
+					<el-option label="开始代驾" value="4" />
+					<el-option label="结束代驾" value="5" />
+					<el-option label="未付款" value="6" />
+					<el-option label="已付款" value="7" />
+					<el-option label="订单已结束" value="8" />
+					<el-option label="顾客撤单" value="9" />
+					<el-option label="司机撤单" value="10" />
+					<el-option label="事故关闭" value="11" />
+					<el-option label="其他" value="12" />
+				</el-select>
+			</el-form-item>
+			<el-form-item>
+				<el-button size="medium" type="primary" @click="searchHandle()">查询</el-button>
+			</el-form-item>
+		</el-form>
+		<el-table
+			:data="dataList"
+			border
+			v-loading="dataListLoading"
+			cell-style="padding: 4px 0"
+			style="width: 100%;"
+			size="medium"
+			@expand-change="expand"
+			:row-key="getRowKeys"
+			:expand-row-keys="expands"
+		>
+			<el-table-column prop="panel" header-align="center" align="center" type="expand">
+				<template #default="scope">
+					<div class="content-container">
+						<div class="left">
+							<div class="order-table">
+								<div class="row">
+									<div class="th">客户编号</div>
+									<div class="td">{{ panel.customer.id }}</div>
+									<div class="th">客户性别</div>
+									<div class="td">{{ panel.customer.sex }}</div>
+									<div class="th">客户电话</div>
+									<div class="td">{{ panel.customer.tel }}</div>
+								</div>
+								<div class="row">
+									<div class="th">车型</div>
+									<div class="td">{{ panel.order.carType }}</div>
+									<div class="th">车牌</div>
+									<div class="td">{{ panel.order.carPlate }}</div>
+									<div class="th">车辆隶属</div>
+									<div class="td">{{ panel.order.city }}</div>
+								</div>
+								<div class="row">
+									<div class="th">司机编号</div>
+									<div class="td">{{ panel.driver.id }}</div>
+									<div class="th">司机姓名</div>
+									<div class="td">{{ panel.driver.name }}</div>
+									<div class="th">司机电话</div>
+									<div class="td">{{ panel.driver.tel }}</div>
+								</div>
+								<div class="row">
+									<div class="th">接单时间</div>
+									<div class="td">{{ panel.order.acceptTime }}</div>
+									<div class="th">到达时间</div>
+									<div class="td">{{ panel.order.arriveTime }}</div>
+									<div class="th">代驾等时</div>
+									<div class="td">{{ panel.order.waitingMinute }}</div>
+								</div>
+								<div class="row">
+									<div class="th">开始时间</div>
+									<div class="td">{{ panel.order.startTime }}</div>
+									<div class="th">结束时间</div>
+									<div class="td">{{ panel.order.endTime }}</div>
+									<div class="th">代驾时长</div>
+									<div class="td">{{ panel.order.driveMinute }}</div>
+								</div>
+								<div class="row">
+									<div class="th">代驾里程</div>
+									<div class="td">{{ panel.order.realMileage }}</div>
+									<div class="th">订单费用</div>
+									<div class="td">{{ panel.order.realFee }}</div>
+									<div class="th">状态</div>
+									<div class="td">{{ panel.order.status }}</div>
+								</div>
+								<div class="row">
+									<div class="th">费用规则</div>
+									<div class="td">{{ panel.order.chargeRule }}</div>
+									<div class="th">取消规则</div>
+									<div class="td">{{ panel.order.cancelRule }}</div>
+									<div class="th">分账规则</div>
+									<div class="td">{{ panel.order.profitsharingRule }}</div>
+								</div>
+							</div>
+						</div>
+						<div class="right"><div :id="panel.id" class="map"></div></div>
+					</div>
+				</template>
+			</el-table-column>
+			<el-table-column type="index" header-align="center" align="center" width="100" label="序号">
+				<template #default="scope">
+					<span>{{ (pageIndex - 1) * pageSize + scope.$index + 1 }}</span>
+				</template>
+			</el-table-column>
+			<el-table-column prop="id" header-align="center" align="center" min-width="200" label="订单编号" />
+			<el-table-column
+				prop="startPlace"
+				header-align="center"
+				align="center"
+				min-width="220"
+				show-overflow-tooltip="true"
+				label="代驾起点"
+			/>
+			<el-table-column
+				prop="endPlace"
+				header-align="center"
+				align="center"
+				min-width="220"
+				show-overflow-tooltip="true"
+				label="代驾终点"
+			/>
+			<el-table-column prop="realMileage" header-align="center" align="center" min-width="130" label="实际里程" />
+			<el-table-column prop="realFee" header-align="center" align="center" min-width="130" label="实际金额" />
+			<el-table-column prop="createTime" header-align="center" align="center" min-width="150" label="日期时间" />
+			<el-table-column prop="status" header-align="center" align="center" min-width="100" label="状态" />
+			<el-table-column header-align="center" align="center" width="150" label="操作">
+				<template #default="scope">
+					<el-button
+						type="text"
+						size="medium"
+						v-if="isAuth(['ROOT', 'ORDER:SELECT'])"
+						:disabled="!['结束代驾', '未付款', '已付款', '订单已结束'].includes(scope.row.status)"
+						@click="showOrderBill(scope.row.id)"
+					>
+						账单详情
+					</el-button>
+					<el-button
+						type="text"
+						size="medium"
+						v-if="isAuth(['ROOT', 'ORDER:UPDATE'])"
+						:disabled="!['等待接单', '已接单', '司机已到达', '开始代驾'].includes(scope.row.status)"
+						@click="showUpdatePanel(scope.row.id)"
+					>
+						关闭订单
+					</el-button>
+				</template>
+			</el-table-column>
+		</el-table>
+		<el-pagination
+			@size-change="sizeChangeHandle"
+			@current-change="currentChangeHandle"
+			:current-page="pageIndex"
+			:page-sizes="[10, 20, 50]"
+			:page-size="pageSize"
+			:total="totalCount"
+			layout="total, sizes, prev, pager, next, jumper"
+		></el-pagination>
+		<order-bill ref="orderBill"></order-bill>
+		<order-close ref="orderClose" @refreshDataList="loadDataList"></order-close>
+	</div>
+</template>
+
+<script>
+import OrderBill from './order_bill.vue';
+import OrderClose from './order-close.vue';
+
+import $ from 'jquery';
+import { calculateCarPlateCity } from '../utils/car_plate.js';
+let status = {
+	'1': '等待接单',
+	'2': '已接单',
+	'3': '司机已到达',
+	'4': '开始代驾',
+	'5': '结束代驾',
+	'6': '未付款',
+	'7': '已付款',
+	'8': '订单已结束',
+	'9': '顾客撤单',
+	'10': '司机撤单',
+	'11': '事故关闭',
+	'12': '其他'
+};
+export default {
+	components: {
+		OrderBill,
+		OrderClose
+	},
+	data() {
+		return {
+			dataForm: {
+				orderId: null,
+				driverId: null,
+				customerId: null,
+				date: [],
+				status: null
+			},
+			dataList: [],
+			pageIndex: 1,
+			pageSize: 10,
+			totalCount: 0,
+			dataListLoading: false,
+			dataRule: {
+				orderId: [{ required: false, pattern: '^[1-9]\\d{17}$', message: '订单编号格式错误' }],
+				driverId: [{ required: false, pattern: '^[1-9]\\d{17}$', message: '司机编号格式错误' }],
+				customerId: [{ required: false, pattern: '^[1-9]\\d{17}$', message: '客户编号格式错误' }]
+			},
+			expands: [],
+			panel: {
+				id: null,
+				customer: {
+					id: null,
+					sex: null,
+					tel: null
+				},
+				driver: {
+					id: null,
+					name: null,
+					tel: null
+				},
+				order: {
+					carPlate: null,
+					carType: null,
+					city: null,
+					acceptTime: null,
+					arriveTime: null,
+					startTime: null,
+					endTime: null,
+					waitingMinute: null,
+					driveMinute: null,
+					realMileage: null,
+					realFee: null,
+					status: null,
+					chargeRule: null,
+					cancelRule: null,
+					profitsharingRule: null
+				}
+			},
+			getRowKeys(row) {
+				return row.id;
+			},
+			gpsTimer: null
+		};
+	},
+	methods: {
+		loadDataList: function() {
+			let that = this;
+			that.dataListLoading = true;
+			let data = {
+				page: that.pageIndex,
+				length: that.pageSize,
+				orderId: that.dataForm.orderId == '' ? null : that.dataForm.orderId,
+				driverId: that.dataForm.driverId == '' ? null : that.dataForm.driverId,
+				customerId: that.dataForm.customerId == '' ? null : that.dataForm.customerId,
+				status: that.dataForm.status == '' ? null : that.dataForm.status
+			};
+			if (that.dataForm.date != null && that.dataForm.date.length == 2) {
+				let startDate = that.dataForm.date[0];
+				let endDate = that.dataForm.date[1];
+				data.startDate = dayjs(startDate).format('YYYY-MM-DD');
+				data.endDate = dayjs(endDate).format('YYYY-MM-DD');
+			}
+			that.$http('order/searchOrderByPage', 'POST', data, true, function(resp) {
+				let result = resp.result;
+				let list = result.list;
+				for (let one of list) {
+					one.status = status[one.status + ''];
+					if (!one.hasOwnProperty('realMileage')) {
+						one.realMileage = '--';
+					}
+					if (!one.hasOwnProperty('realFee')) {
+						one.realFee = '--';
+					}
+				}
+				that.dataList = list;
+				that.totalCount = Number(result.totalCount);
+				that.dataListLoading = false;
+			});
+		},
+		sizeChangeHandle(val) {
+			this.pageSize = val;
+			this.pageIndex = 1;
+			this.loadDataList();
+		},
+		currentChangeHandle(val) {
+			this.pageIndex = val;
+			this.loadDataList();
+		},
+		searchHandle: function() {
+			this.$refs['dataForm'].validate(valid => {
+				if (valid) {
+					this.$refs['dataForm'].clearValidate();
+					this.loadDataList();
+				} else {
+					return false;
+				}
+			});
+		},
+		loadPanelData: function(ref, row) {
+			let data = {
+				orderId: row.id
+			};
+			ref.$http('order/searchOrderComprehensiveInfo', 'POST', data, true, function(resp) {
+				let result = resp.result;
+				let content = result.content;
+
+				let customerInfo = result.customerInfo;
+				ref.panel.customer.id = customerInfo.id;
+				ref.panel.customer.sex = customerInfo.sex;
+				ref.panel.customer.tel = customerInfo.tel;
+
+				let driverInfo = result.driverInfo;
+				ref.panel.driver.id = driverInfo.id;
+				ref.panel.driver.name = driverInfo.name;
+				ref.panel.driver.tel = driverInfo.tel;
+
+				ref.panel.order.carPlate = content.carPlate;
+				ref.panel.order.carType = content.carType;
+				let city = calculateCarPlateCity(content.carPlate);
+				ref.panel.order.city = city;
+
+				if (content.hasOwnProperty('acceptTime')) {
+					ref.panel.order.acceptTime = content.acceptTime;
+				} else {
+					ref.panel.order.acceptTime = '--';
+				}
+				if (content.hasOwnProperty('arriveTime')) {
+					ref.panel.order.arriveTime = content.arriveTime;
+				} else {
+					ref.panel.order.arriveTime = '--';
+				}
+				if (content.hasOwnProperty('startTime')) {
+					ref.panel.order.startTime = content.startTime;
+				} else {
+					ref.panel.order.startTime = '--';
+				}
+				if (content.hasOwnProperty('endTime')) {
+					ref.panel.order.endTime = content.endTime;
+				} else {
+					ref.panel.order.endTime = '--';
+				}
+				if (content.hasOwnProperty('waitingMinute')) {
+					ref.panel.order.waitingMinute = content.waitingMinute + '分钟';
+				} else {
+					ref.panel.order.waitingMinute = '--';
+				}
+				if (content.hasOwnProperty('driveMinute')) {
+					ref.panel.order.driveMinute = content.driveMinute + '分钟';
+				} else {
+					ref.panel.order.driveMinute = '--';
+				}
+				if (content.hasOwnProperty('realMileage')) {
+					ref.panel.order.realMileage = content.realMileage + '公里';
+					row.realMileage = content.realMileage;
+				} else {
+					ref.panel.order.realMileage = '--';
+					row.realMileage = '--';
+				}
+				if (content.hasOwnProperty('realFee')) {
+					ref.panel.order.realFee = content.realFee + '元';
+					row.realFee = content.realFee;
+				} else {
+					ref.panel.order.realFee = '--';
+					row.realFee = '--';
+				}
+
+				ref.panel.order.status = status[content.status + ''];
+				row.status = status[content.status + ''];
+
+				if (result.hasOwnProperty('chargeRule')) {
+					ref.panel.order.chargeRule = result.chargeRule.code;
+				} else {
+					ref.panel.order.chargeRule = '--';
+				}
+				if (result.hasOwnProperty('cancelRule')) {
+					ref.panel.order.cancelRule = result.cancelRule.code;
+				} else {
+					ref.panel.order.cancelRule = '--';
+				}
+				if (result.hasOwnProperty('profitsharingRule')) {
+					ref.panel.order.profitsharingRule = result.profitsharingRule.code;
+				} else {
+					ref.panel.order.profitsharingRule = '--';
+				}
+
+				ref.$nextTick(function() {
+					let startPlaceLocation = content.startPlaceLocation;
+					let endPlaceLocation = content.endPlaceLocation;
+					let mapCenter = new TMap.LatLng(startPlaceLocation.latitude, startPlaceLocation.longitude);
+					let map = new TMap.Map($(`.el-table__expanded-cell #order_${row.id}`)[0], {
+						center: mapCenter, //地图显示中心点
+						zoom: 13,
+						viewMode: '2D',
+						baseMap: {
+							type: 'vector',
+							features: ['base', 'label']
+						}
+					});
+
+					let driveLine = result.driveLine;
+					let coors = driveLine.routes[0].polyline;
+					let pl = [];
+					//坐标解压(返回的点串坐标,通过前向差分进行压缩,因此需要解压)
+					let kr = 1000000;
+					for (let i = 2; i < coors.length; i++) {
+						coors[i] = Number(coors[i - 2]) + Number(coors[i]) / kr;
+					}
+					//将解压后的坐标生成LatLng数组
+					for (let i = 0; i < coors.length; i += 2) {
+						pl.push(new TMap.LatLng(coors[i], coors[i + 1]));
+					}
+
+					let polylineLayer = new TMap.MultiPolyline({
+						id: 'polyline-layer', //图层唯一标识
+						map: map, //绘制到目标地图
+						styles: {
+							style_blue: new TMap.PolylineStyle({
+								color: 'rgba(190,188,188,1)',
+								width: 6,
+								lineCap: 'round' //线端头方式
+							})
+						},
+						geometries: [
+							{
+								id: 'pl_1',
+								styleId: 'style_blue',
+								paths: pl
+							}
+						]
+					});
+
+					let markerLayer = new TMap.MultiMarker({
+						map: map,
+						styles: {
+							startStyle: new TMap.MarkerStyle({
+								width: 24,
+								height: 36,
+								anchor: { x: 16, y: 32 },
+								src: 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/start.png'
+							}),
+							endStyle: new TMap.MarkerStyle({
+								width: 24,
+								height: 36,
+								anchor: { x: 16, y: 32 },
+								src: 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/end.png'
+							}),
+							carStyle: new TMap.MarkerStyle({
+								width: 30,
+								height: 30,
+								src: '../order/driver-icon.png',
+								anchor: { x: 16, y: 32 }
+							})
+						},
+						geometries: [
+							//起点标记
+							{
+								id: '1',
+								styleId: 'startStyle',
+								position: new TMap.LatLng(startPlaceLocation.latitude, startPlaceLocation.longitude)
+							},
+							//终点标记
+							{
+								id: '2',
+								styleId: 'endStyle',
+								position: new TMap.LatLng(endPlaceLocation.latitude, endPlaceLocation.longitude)
+							}
+						]
+					});
+					if (content.status == 4) {
+						let lastGps = result.lastGps;
+						markerLayer.add([
+							{
+								id: '3',
+								styleId: 'carStyle', //指定样式id
+								position: new TMap.LatLng(lastGps.latitude, lastGps.longitude)
+							}
+						]);
+						ref.gpsTimer = setInterval(function() {
+							let data = {
+								orderId: row.id
+							};
+							ref.$http('order/searchOrderLastGps', 'POST', data, true, function(resp) {
+								if (resp.hasOwnProperty('result')) {
+									let lastGps = resp.result;
+									markerLayer.updateGeometries([
+										{
+											id: '3',
+											styleId: 'carStyle',
+											position: new TMap.LatLng(lastGps.latitude, lastGps.longitude)
+										}
+									]);
+								} else {
+									//重新加载面板数据
+									$(`.el-table__expanded-cell #order_${row.id}`).empty();
+									ref.loadPanelData(ref, row);
+									clearInterval(ref.gpsTimer);
+								}
+							});
+						}, 15 * 1000);
+					} else if (content.status >= 5 && content.status <= 8) {
+						let orderGps = result.orderGps;
+						let paths = [];
+						for (let one of orderGps) {
+							let temp = new TMap.LatLng(one.latitude, one.longitude);
+							paths.push(temp);
+						}
+						let polylineLayer = new TMap.MultiPolyline({
+							id: 'drive-polyline-layer', //图层唯一标识
+							map: map,
+							//折线样式定义
+							styles: {
+								style_blue: new TMap.PolylineStyle({
+									color: '#3777FF', //线填充色
+									width: 6 //折线宽度
+								})
+							},
+							//折线数据定义
+							geometries: [
+								{
+									id: 'pl_1',
+									styleId: 'style_blue',
+									paths: paths
+								}
+							]
+						});
+					}
+				});
+			});
+		},
+		expand: function(row, expandedRows) {
+			let that = this;
+			if (expandedRows.length > 0) {
+				that.expands = [];
+				if (row) {
+					that.expands.push(row.id);
+					that.panel.id = `order_${row.id}`;
+					that.loadPanelData(that, row);
+				} else {
+					that.expands = [];
+				}
+			}
+		}
+	},
+	created: function() {
+		this.loadDataList();
+	}
+};
+</script>
+<style lang="less" scoped="scoped">
+@import url('order.less');
+</style>

+ 155 - 0
src/views/service-user-add-or-update.vue

@@ -0,0 +1,155 @@
+<template>
+	<el-dialog :title="!dataForm.id ? '新增' : '修改'"  :close-on-click-modal="false" v-model="visible" width="600px">
+		<el-form :model="dataForm" ref="dataForm" :rules="dataRule" label-width="100px">
+			<el-form-item label="商户名称" prop="name"><el-input v-model="dataForm.name" size="medium" style="width:100%" clearable /></el-form-item>
+			<el-form-item label="商户地址" prop="address"><el-input v-model="dataForm.address" size="medium" style="width:100%" clearable /></el-form-item>
+			<el-form-item label="商户图片" prop="imageUrl">
+        <el-upload
+            class="avatar-uploader"
+            action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
+            :show-file-list="false"
+            :on-success="handleAvatarSuccess"
+            :before-upload="beforeAvatarUpload"
+        >
+          <img v-if="dataForm.imageUrl" :src="dataForm.imageUrl" class="avatar" />
+          <el-icon v-else class="avatar-uploader-icon"></el-icon>
+        </el-upload>
+       </el-form-item>
+			<el-form-item label="商户营业时间" prop="merchHours"><el-input v-model="dataForm.merchHours" style="width:100%" size="medium" maxlength="20" clearable /></el-form-item>
+      <el-form-item label="商户评分" prop="rating"><el-input v-model="dataForm.rating" style="width:100%" size="medium" maxlength="20" clearable /></el-form-item>
+      <el-form-item label="商户类型" prop="type">
+        <el-select v-model="dataForm.type" class="input" placeholder="商户类型" size="medium" clearable="clearable">
+          <el-option label="洗车" value="1" />
+          <el-option label="审车" value="2" />
+          <el-option label="代驾" value="3" />
+          <el-option label="道路救援" value="4" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="商户联系电话" prop="phoneNumber"><el-input v-model="dataForm.phoneNumber" style="width:100%" size="medium" maxlength="20" clearable /></el-form-item>
+      <el-form-item label="是否合作商户" prop="isPartner">
+        <el-select v-model="dataForm.isPartner" class="input" placeholder="是否合作商户" size="medium" clearable="clearable">
+          <el-option label="是" value="1" />
+          <el-option label="否" value="0" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="商户简介" prop="description"><el-input v-model="dataForm.description" style="width:100%" size="medium" maxlength="2000" type="textarea"  clearable /></el-form-item>
+    </el-form>
+		<template #footer>
+			<span class="dialog-footer">
+				<el-button size="medium" @click="visible = false">取消</el-button>
+				<el-button type="primary" size="medium" @click="dataFormSubmit">确定</el-button>
+			</span>
+		</template>
+	</el-dialog>
+</template>
+
+<script>
+export default {
+	data: function() {
+		return {
+			visible: false,
+			dataForm: {
+				id: null,
+				name: null,
+        imageUrl: "123",
+        merchHours: null,
+        rating: null,
+        type: null,
+        phoneNumber: null,
+        isPartner: null,
+        description: null,
+        address: null,
+			},
+			dataRule: {
+
+			}
+		};
+	},
+
+	methods: {
+		init: function(id) {
+			let that = this;
+			that.dataForm.id = id || 0;
+			that.visible = true;
+			that.$nextTick(() => {
+				that.$refs['dataForm'].resetFields();
+				if (id) {
+					that.$http('http://localhost:8201/wash-car/merchant/searchById', 'POST', { id: id }, true, function(resp) {
+            console.log(resp.rows)
+            that.dataForm.id = resp.rows.id;
+            that.dataForm.name = resp.rows.name;
+            that.dataForm.imageUrl = resp.rows.imageUrl;
+						that.dataForm.merchHours = resp.rows.merchHours;
+						that.dataForm.rating = resp.rows.rating;
+            that.dataForm.type = String(resp.rows.type);
+            that.dataForm.phoneNumber = resp.rows.phoneNumber;
+            that.dataForm.isPartner = String(resp.rows.isPartner);
+            that.dataForm.description = resp.rows.description;
+            that.dataForm.address  =resp.rows.address;
+					});
+				}
+			});
+		},
+		dataFormSubmit: function() {
+			let that = this;
+			this.$refs['dataForm'].validate(valid => {
+				if (valid) {
+          var url="";
+          if(that.dataForm.id ==null || that.dataForm.id ==""){
+            url="http://localhost:8201/wash-car/merchant/insert";
+          }else{
+            url="http://localhost:8201/wash-car/merchant/update";
+          }
+					that.$http(url, 'POST', that.dataForm, true, function(resp) {
+						if (resp.rows == 1) {
+							that.$message({
+								message: '操作成功',
+								type: 'success',
+								duration: 1200
+							});
+							that.visible = false;
+							that.$emit('refreshDataList');
+						} else {
+							that.$message({
+								message: '操作失败',
+								type: 'error',
+								duration: 1200
+							});
+						}
+					});
+				}
+			});
+		},
+	}
+};
+</script>
+
+<style lang="less" scoped="scoped">
+.avatar-uploader .avatar {
+  width: 178px;
+  height: 178px;
+  display: block;
+}
+</style>
+<style>
+.avatar-uploader .el-upload {
+  border: 1px dashed var(--el-border-color);
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+  transition: var(--el-transition-duration-fast);
+}
+
+.avatar-uploader .el-upload:hover {
+  border-color: var(--el-color-primary);
+}
+
+.el-icon.avatar-uploader-icon {
+  font-size: 28px;
+  color: #8c939d;
+  width: 178px;
+  height: 178px;
+  text-align: center;
+}
+</style>

+ 176 - 0
src/views/service-user.vue

@@ -0,0 +1,176 @@
+<template>
+  <div>
+    <el-form :inline="true" :model="dataForm" :rules="dataRule" ref="dataForm">
+      <el-form-item prop="deptName"><el-input v-model="dataForm.name" placeholder="商户名称" size="medium" class="input" clearable="clearable" /></el-form-item>
+      <el-form-item>
+        <el-button size="medium" type="primary" @click="searchHandle()">查询</el-button>
+        <el-button size="medium" type="primary"  @click="addHandle()">新增</el-button>
+        <el-button size="medium" type="danger"  @click="deleteHandle()">批量删除</el-button>
+      </el-form-item>
+    </el-form>
+    <el-table :data="dataList" border v-loading="dataListLoading" @selection-change="selectionChangeHandle" cell-style="padding: 4px 0" size="medium" style="width: 100%;">
+      <el-table-column type="selection" :selectable="selectable" header-align="center" align="center" width="50" />
+      <el-table-column type="index" header-align="center" align="center" width="100" label="序号">
+        <template #default="scope">
+          <span>{{ (pageIndex - 1) * pageSize + scope.$index + 1 }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="id" header-align="center" align="center" min-width="200" label="商户编号" />
+      <el-table-column prop="name" header-align="center" align="center" min-width="130" label="商户名称" />
+      <el-table-column prop="address" header-align="center" align="center" min-width="130" label="商户地址" />
+      <el-table-column prop="merchHours" header-align="center" align="center" min-width="150" label="商户营业时间" />
+      <el-table-column prop="type" header-align="center" align="center" min-width="150" label="商户类型" />
+      <el-table-column prop="phoneNumber" header-align="center" align="center" min-width="100" label="商户联系电话" />
+      <el-table-column prop="rating" header-align="center" align="center" min-width="100" label="商户评分" />
+      <el-table-column header-align="center" align="center" width="150" label="操作">
+        <template #default="scope">
+          <el-button type="text" size="medium"  @click="updateHandle(scope.row.id)">修改</el-button>
+          <el-button type="text" size="medium" :disabled="scope.row.emps > 0" @click="deleteHandle(scope.row.id)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <el-pagination
+        @size-change="sizeChangeHandle"
+        @current-change="currentChangeHandle"
+        :current-page="pageIndex"
+        :page-sizes="[10, 20, 50]"
+        :page-size="pageSize"
+        :total="totalCount"
+        layout="total, sizes, prev, pager, next, jumper"
+    ></el-pagination>
+    <add-or-update ref="addOrUpdate" @refreshDataList="loadDataList"></add-or-update>
+  </div>
+</template>
+
+<script>
+import AddOrUpdate from './service-user-add-or-update.vue';
+export default {
+  components: {
+    AddOrUpdate
+  },
+  data: function() {
+    return {
+      dataForm: {
+        name: null
+      },
+      dataList: [],
+      pageIndex: 1,
+      pageSize: 10,
+      totalCount: 0,
+      dataListLoading: false,
+      dataListSelections: [],
+      dataRule: {
+
+      }
+    };
+  },
+  methods: {
+    loadDataList: function() {
+      let that = this;
+      that.dataListLoading = true;
+      let data = {
+        name: that.dataForm.name,
+        page: that.pageIndex,
+        length: that.pageSize
+      };
+
+      that.$http('http://localhost:8201/wash-car/merchant/searchMerchantByPage', 'POST', data, true, function(resp) {
+        // console.log(resp.page);
+        let page = resp.page;
+        that.dataList = page.list;
+        that.totalCount = Number(page.totalCount);
+        that.dataListLoading = false;
+      });
+    },
+    searchHandle: function() {
+      this.$refs['dataForm'].validate(valid => {
+        if (valid) {
+          this.$refs['dataForm'].clearValidate();
+          if (this.dataForm.deptName == '') {
+            this.dataForm.deptName = null;
+          }
+          if (this.pageIndex != 1) {
+            this.pageIndex = 1;
+          }
+          this.loadDataList();
+        } else {
+          return false;
+        }
+      });
+    },
+    selectable: function(row, index) {
+      if (row.emps > 0) {
+        return false;
+      }
+      return true;
+    },
+    selectionChangeHandle: function(val) {
+      this.dataListSelections = val;
+    },
+    sizeChangeHandle: function(val) {
+      this.pageSize = val;
+      this.pageIndex = 1;
+      this.loadDataList();
+    },
+    currentChangeHandle: function(val) {
+      this.pageIndex = val;
+      this.loadDataList();
+    },
+    deleteHandle: function(id) {
+      let that = this;
+      let ids = id
+          ? [id]
+          : that.dataListSelections.map(item => {
+            return item.id;
+          });
+      if (ids.length == 0) {
+        that.$message({
+          message: '没有选中记录',
+          type: 'warning',
+          duration: 1200
+        });
+      } else {
+        that.$confirm(`确定要删除选中的记录?`, '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          that.$http('http://localhost:8201/wash-car/merchant/deleteDeptByIds', 'POST', { ids: ids }, true, function(resp) {
+            if (resp.rows > 0) {
+              that.$message({
+                message: '操作成功',
+                type: 'success',
+                duration: 1200,
+                onClose: () => {
+                  that.loadDataList();
+                }
+              });
+            } else {
+              that.$message({
+                message: '未能删除记录',
+                type: 'warning',
+                duration: 1200
+              });
+            }
+          });
+        });
+      }
+    },
+    addHandle: function() {
+      this.$nextTick(() => {
+        this.$refs.addOrUpdate.init();
+      });
+    },
+    updateHandle: function(id) {
+      this.$nextTick(() => {
+        this.$refs.addOrUpdate.init(id);
+      });
+    }
+  },
+  created: function() {
+    this.loadDataList();
+  }
+};
+</script>
+
+<style></style>

+ 221 - 0
src/views/service.vue

@@ -0,0 +1,221 @@
+<template>
+	<div>
+		<el-form :inline="true" :model="dataForm" :rules="dataRule" ref="dataForm">
+			<el-form-item prop="orderId">
+				<el-input v-model="dataForm.name" placeholder="商户名称" size="medium" clearable="clearable" />
+			</el-form-item>
+			<el-form-item>
+				<el-date-picker
+					v-model="dataForm.merchHours"
+					type="daterange"
+					range-separator="~"
+					start-placeholder="开始日期"
+					end-placeholder="结束日期"
+					size="medium"
+				></el-date-picker>
+			</el-form-item>
+			<el-form-item>
+				<el-select
+					v-model="dataForm.type"
+					class="input"
+					placeholder="商户类型"
+					size="medium"
+					clearable="clearable"
+				>
+					<el-option label="洗车" value="1" />
+					<el-option label="验车" value="2" />
+					<el-option label="代驾" value="3" />
+					<el-option label="道路救援" value="4" />
+				</el-select>
+			</el-form-item>
+			<el-form-item>
+				<el-button size="medium" type="primary" @click="searchHandle()">查询</el-button>
+			</el-form-item>
+		</el-form>
+		<el-table
+			:data="dataList"
+			border
+			v-loading="dataListLoading"
+			cell-style="padding: 4px 0"
+			style="width: 100%;"
+			size="medium"
+		>
+			<el-table-column type="index" header-align="center" align="center" width="100" label="序号">
+				<template #default="scope">
+					<span>{{ (pageIndex - 1) * pageSize + scope.$index + 1 }}</span>
+				</template>
+			</el-table-column>
+			<el-table-column prop="id" header-align="center" align="center" min-width="200" label="商户编号" />
+			<el-table-column prop="name" header-align="center" align="center" min-width="130" label="商户名称" />
+			<el-table-column prop="address" header-align="center" align="center" min-width="130" label="商户地址" />
+      <el-table-column prop="merchHours" header-align="center" align="center" min-width="150" label="商户营业时间" />
+      <el-table-column prop="type" header-align="center" align="center" min-width="150" label="商户类型" />
+			<el-table-column prop="phoneNumber" header-align="center" align="center" min-width="100" label="商户联系电话" />
+      <el-table-column prop="phoneNumber" header-align="center" align="center" min-width="100" label="商户评分" />
+			<el-table-column header-align="center" align="center" width="150" label="操作">
+				<template #default="scope">
+					<el-button
+						type="text"
+						size="medium"
+						@click="edit(scope.row.id)"
+					>
+						编辑
+					</el-button>
+					<el-button
+						type="text"
+						size="medium"
+						@click="deleteById(scope.row.id)"
+					>
+						删除
+					</el-button>
+				</template>
+			</el-table-column>
+		</el-table>
+		<el-pagination
+			@size-change="sizeChangeHandle"
+			@current-change="currentChangeHandle"
+			:current-page="pageIndex"
+			:page-sizes="[10, 20, 50]"
+			:page-size="pageSize"
+			:total="totalCount"
+			layout="total, sizes, prev, pager, next, jumper"
+		></el-pagination>
+		<order-bill ref="orderBill"></order-bill>
+		<order-close ref="orderClose" @refreshDataList="loadDataList"></order-close>
+	</div>
+</template>
+
+<script>
+import OrderBill from './order_bill.vue';
+import OrderClose from './order-close.vue';
+
+import $ from 'jquery';
+import { calculateCarPlateCity } from '../utils/car_plate.js';
+export default {
+	components: {
+		OrderBill,
+		OrderClose
+	},
+	data() {
+		return {
+			dataForm: {
+				orderId: null,
+				driverId: null,
+				customerId: null,
+				date: [],
+				status: null
+			},
+			dataList: [],
+			pageIndex: 1,
+			pageSize: 10,
+			totalCount: 0,
+			dataListLoading: false,
+			dataRule: {
+			},
+			panel: {
+				id: null,
+				customer: {
+					id: null,
+					sex: null,
+					tel: null
+				},
+				driver: {
+					id: null,
+					name: null,
+					tel: null
+				},
+				order: {
+					carPlate: null,
+					carType: null,
+					city: null,
+					acceptTime: null,
+					arriveTime: null,
+					startTime: null,
+					endTime: null,
+					waitingMinute: null,
+					driveMinute: null,
+					realMileage: null,
+					realFee: null,
+					status: null,
+					chargeRule: null,
+					cancelRule: null,
+					profitsharingRule: null
+				}
+			},
+			getRowKeys(row) {
+				return row.id;
+			},
+			gpsTimer: null
+		};
+	},
+	methods: {
+		loadDataList: function() {
+			let that = this;
+			that.dataListLoading = true;
+			let data = {
+				page: that.pageIndex,
+				length: that.pageSize,
+        name: that.dataForm.name == '' ? null : that.dataForm.name,
+				type: that.dataForm.type == '' ? null : that.dataForm.type,
+        merchHours: that.dataForm.merchHours == '' ? null : that.dataForm.merchHours
+			};
+			if (that.dataForm.merchHours != null && that.dataForm.merchHours.length == 2) {
+				let startDate = that.dataForm.merchHours[0];
+				let endDate = that.dataForm.merchHours[1];
+				data.startDate = dayjs(startDate).format('YYYY-MM-DD');
+				data.endDate = dayjs(endDate).format('YYYY-MM-DD');
+			}
+			that.$http('wash-car/merchant/searchMerchantByPage', 'POST', data, true, function(resp) {
+				let result = resp.result;
+				let list = result.list;
+				for (let one of list) {
+					one.status = status[one.status + ''];
+					if (!one.hasOwnProperty('realMileage')) {
+						one.realMileage = '--';
+					}
+					if (!one.hasOwnProperty('realFee')) {
+						one.realFee = '--';
+					}
+				}
+				that.dataList = list;
+				that.totalCount = Number(result.totalCount);
+				that.dataListLoading = false;
+			});
+		},
+		sizeChangeHandle(val) {
+			this.pageSize = val;
+			this.pageIndex = 1;
+			this.loadDataList();
+		},
+		currentChangeHandle(val) {
+			this.pageIndex = val;
+			this.loadDataList();
+		},
+		searchHandle: function() {
+			this.$refs['dataForm'].validate(valid => {
+				if (valid) {
+					this.$refs['dataForm'].clearValidate();
+					this.loadDataList();
+				} else {
+					return false;
+				}
+			});
+		},
+		loadPanelData: function(ref, row) {
+			let data = {
+			};
+			ref.$http('wash-car/merchant/searchMerchantByPage', 'POST', data, true, function(resp) {
+				let result = resp.result;
+				let content = result.list;
+        console.log(resp)
+			});
+		},
+	},
+	created: function() {
+		this.loadDataList();
+	}
+};
+</script>
+<style lang="less" scoped="scoped">
+@import url('order.less');
+</style>