feat:新增功能
This commit is contained in:
parent
7868527a39
commit
363862c0ad
2
env/.env
vendored
2
env/.env
vendored
@ -12,7 +12,7 @@ VITE_APP_PUBLIC_BASE=/
|
||||
# 后台请求地址
|
||||
# http://192.168.101.20:10010
|
||||
# https://www.cdzhuojing.cn/ebike 外网
|
||||
VITE_SERVER_BASEURL = 'http://192.168.101.18:10010'
|
||||
VITE_SERVER_BASEURL = 'https://www.cdzhuojing.cn/ebike'
|
||||
# 备注:如果后台带统一前缀,则也要加到后面,eg: https://ukw0y1.laf.run/api
|
||||
|
||||
# 注意,如果是微信小程序,还有一套请求地址的配置,根据 develop、trial、release 分别设置上传地址,见 `src/utils/index.ts`。
|
||||
|
||||
@ -19,7 +19,7 @@ onShow((options) => {
|
||||
navigateToInterceptor.invoke({ url: '/' })
|
||||
}
|
||||
|
||||
// appStore.autoLogin()
|
||||
appStore.autoLogin()
|
||||
})
|
||||
onHide(() => {
|
||||
console.log('App Hide')
|
||||
|
||||
@ -1,4 +1,13 @@
|
||||
import type { AddInventoryRecordParams, AddSite, BatchAddInventoryParams, BindEbikeParams, CompleteInspectionWorkParams, CompleteMaintainType, CurrentLocationType } from './types/operator'
|
||||
import type {
|
||||
AddInventoryRecordParams,
|
||||
AddSite,
|
||||
BatchAddInventoryParams,
|
||||
BindEbikeParams,
|
||||
completeDispatchWorkType,
|
||||
CompleteInspectionWorkParams,
|
||||
CompleteMaintainType,
|
||||
CurrentLocationType,
|
||||
} from './types/operator'
|
||||
import { http } from '@/http/http'
|
||||
|
||||
/**
|
||||
@ -138,3 +147,24 @@ export function updateSiteAPI(data: AddSite) {
|
||||
export function deleteSiteAPI(query: { siteId: string }) {
|
||||
return http.get<any>(`/operations/ebikeSite/remove`, query)
|
||||
}
|
||||
|
||||
/**
|
||||
*完成调度工单
|
||||
*/
|
||||
export function completeDispatchWorkAPI(data: completeDispatchWorkType) {
|
||||
return http.post<any>(`/operations/ebikeBikeOrder/bikeDispatch`, data)
|
||||
}
|
||||
|
||||
/**
|
||||
*生成换电工单
|
||||
*/
|
||||
export function createChangeOrderAPI(ecuSn: string) {
|
||||
return http.get<any>(`/operations/ebikeBikeOrder/batterySwapOrder`, { ecuSn })
|
||||
}
|
||||
|
||||
/**
|
||||
*生成调度工单
|
||||
*/
|
||||
export function createDispatchOrderAPI(bikeCode: string) {
|
||||
return http.get<any>(`/operations/ebikeBikeOrder/dispatchSwapOrder`, { bikeCode })
|
||||
}
|
||||
|
||||
@ -67,3 +67,11 @@ export interface AddSite {
|
||||
siteType: number | string
|
||||
sitePolygon: CurrentLocationType
|
||||
}
|
||||
|
||||
//
|
||||
export interface completeDispatchWorkType {
|
||||
bikeCode: string
|
||||
remarks?: string
|
||||
fileUrls?: string[]
|
||||
siteId: string
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
<script lang="ts" setup>
|
||||
import { completeDispatchWorkAPI, getEbikeDetailForWorkAPI } from '@/api/operator'
|
||||
import { faultUrl, uploadImagesStrict } from '@/api/upload'
|
||||
import instructTools from '@/components/instructTools/instructTools.vue'
|
||||
import siteSelectList from '@/components/siteSelectList/siteSelectList.vue'
|
||||
@ -27,15 +28,28 @@ const orderDetail = ref<any>({
|
||||
},
|
||||
soc: 0,
|
||||
})
|
||||
|
||||
const formData = reactive({
|
||||
bikeCode: '',
|
||||
value: '',
|
||||
siteId: '',
|
||||
fileUrls: [],
|
||||
remarks: '',
|
||||
})
|
||||
|
||||
function handleSiteClick() {
|
||||
console.log(123)
|
||||
async function getEbikeDetailForWork() {
|
||||
uni.showLoading({
|
||||
title: '查询中',
|
||||
})
|
||||
try {
|
||||
const res = await getEbikeDetailForWorkAPI(formData.bikeCode)
|
||||
if (res) {
|
||||
orderDetail.value = res
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
// 获取站点信息
|
||||
@ -43,7 +57,7 @@ function selecSite() {
|
||||
popupRef.value.open()
|
||||
}
|
||||
|
||||
// 获取车辆信息
|
||||
// 车辆地图
|
||||
function findCar() {
|
||||
const params = {
|
||||
elng: orderDetail.value.location.longitude,
|
||||
@ -58,6 +72,7 @@ function scan() {
|
||||
scanCode({
|
||||
success: (res: any) => {
|
||||
formData.bikeCode = res.code
|
||||
getEbikeDetailForWork()
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({
|
||||
@ -68,8 +83,49 @@ function scan() {
|
||||
})
|
||||
}
|
||||
|
||||
function handleComplete() {
|
||||
function resetForm() {
|
||||
formData.bikeCode = ''
|
||||
formData.fileUrls = []
|
||||
formData.remarks = ''
|
||||
formData.siteId = ''
|
||||
orderDetail.value = {
|
||||
location: {
|
||||
latitude: 0,
|
||||
longitude: 0,
|
||||
},
|
||||
soc: 0,
|
||||
}
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
async function handleComplete() {
|
||||
if (!formData.siteId) {
|
||||
uni.showToast({
|
||||
title: '请选择站点',
|
||||
icon: 'none',
|
||||
})
|
||||
return
|
||||
}
|
||||
btnConfig.loading = true
|
||||
try {
|
||||
const res = await completeDispatchWorkAPI(formData)
|
||||
|
||||
resetForm()
|
||||
uni.showToast({
|
||||
title: '调度成功',
|
||||
icon: 'none',
|
||||
})
|
||||
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 1000)
|
||||
}
|
||||
catch (e: any) {
|
||||
console.error(e)
|
||||
}
|
||||
finally {
|
||||
btnConfig.loading = false
|
||||
}
|
||||
}
|
||||
|
||||
async function afterRead(event: any) {
|
||||
@ -127,15 +183,22 @@ function popupBack() {
|
||||
}
|
||||
|
||||
function popupChage(val: any) {
|
||||
const { siteName } = val
|
||||
console.log(val)
|
||||
const { siteName, siteId } = val
|
||||
formData.siteId = siteId
|
||||
popupBack()
|
||||
console.log(val, 'popupChage')
|
||||
selctSiteName.value = siteName
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
onLoad((query) => {
|
||||
const { bikeCode } = query
|
||||
if (bikeCode) {
|
||||
formData.bikeCode = bikeCode
|
||||
getEbikeDetailForWork()
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -210,7 +273,7 @@ onMounted(() => {
|
||||
<view class="u-m-b-15">
|
||||
调度原因
|
||||
</view>
|
||||
<uv-textarea v-model="formData.value" placeholder="请输入调度原因" />
|
||||
<uv-textarea v-model="formData.remarks" placeholder="请输入调度原因" />
|
||||
</view>
|
||||
|
||||
<!-- 调度图片 -->
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
import { executeCommandAPI } from '@/api/centerControl'
|
||||
import { createChangeOrderAPI, createDispatchOrderAPI } from '@/api/operator'
|
||||
import { getBatteryColor } from '@/utils/car'
|
||||
|
||||
const props = defineProps({
|
||||
@ -7,13 +8,39 @@ const props = defineProps({
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
tabType: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
})
|
||||
const emits = defineEmits(['close'])
|
||||
const btnType = ref('')
|
||||
const carDetail = ref<any>({
|
||||
bikeCode: '',
|
||||
distance: '',
|
||||
soc: 0,
|
||||
})
|
||||
const ActionSheetList = ref([
|
||||
{
|
||||
name: '换单工单',
|
||||
key: 'hasChangeBatteryOrder',
|
||||
disabled: false,
|
||||
loading: false,
|
||||
},
|
||||
{
|
||||
name: '调度工单',
|
||||
key: 'hasDispatchOrder',
|
||||
disabled: false,
|
||||
loading: false,
|
||||
},
|
||||
{
|
||||
name: '巡检工单',
|
||||
key: 'hasInspectionOrder',
|
||||
disabled: false,
|
||||
loading: false,
|
||||
},
|
||||
])
|
||||
const actionSheet = ref<any>(null)
|
||||
const btnNum = ref(3)
|
||||
const customStyle = computed(() => {
|
||||
return {
|
||||
@ -178,13 +205,123 @@ function completeChangeBattery() {
|
||||
}, 100)
|
||||
}
|
||||
|
||||
//
|
||||
// 关闭
|
||||
function handleClose() {
|
||||
emits('close')
|
||||
}
|
||||
|
||||
// 按钮
|
||||
function handleBtnConfig(res: any) {
|
||||
ActionSheetList.value = ActionSheetList.value.map(item => ({
|
||||
...item,
|
||||
disabled: res[item.key],
|
||||
}))
|
||||
}
|
||||
|
||||
// 生成工单
|
||||
function generateWorkOrder() {
|
||||
actionSheet.value?.open()
|
||||
}
|
||||
|
||||
// 工单选择
|
||||
async function ActionSheetSelect(e: any) {
|
||||
const { key } = e
|
||||
ActionSheetList.value.forEach((item) => {
|
||||
if (item.key === key) {
|
||||
item.loading = true
|
||||
}
|
||||
})
|
||||
switch (key) {
|
||||
case 'hasInspectionOrder':
|
||||
break
|
||||
case 'hasChangeBatteryOrder':
|
||||
createChangeOrder(key)
|
||||
break
|
||||
case 'hasDispatchOrder':
|
||||
createDispatchOrder(key)
|
||||
break
|
||||
case 'hasRepairOrder':
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
async function createChangeOrder(key: string) {
|
||||
try {
|
||||
const res = await createChangeOrderAPI(carDetail.value.ecuSn)
|
||||
uni.showToast({
|
||||
title: '工单创建成功',
|
||||
icon: 'success',
|
||||
})
|
||||
ActionSheetList.value.forEach((item) => {
|
||||
if (item.key === key) {
|
||||
item.loading = false
|
||||
item.disabled = false
|
||||
}
|
||||
})
|
||||
actionSheet.value?.close()
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err)
|
||||
ActionSheetList.value.forEach((item) => {
|
||||
if (item.key === key) {
|
||||
item.loading = false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async function createDispatchOrder(key: string) {
|
||||
try {
|
||||
const res = await createDispatchOrderAPI(carDetail.value.bikeCode)
|
||||
uni.showToast({
|
||||
title: '工单创建成功',
|
||||
icon: 'success',
|
||||
})
|
||||
ActionSheetList.value.forEach((item) => {
|
||||
if (item.key === key) {
|
||||
item.loading = false
|
||||
item.disabled = false
|
||||
}
|
||||
})
|
||||
actionSheet.value?.close()
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err)
|
||||
ActionSheetList.value.forEach((item) => {
|
||||
if (item.key === key) {
|
||||
item.loading = false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
watch(() => props.data, (newVal) => {
|
||||
carDetail.value = newVal
|
||||
}, { deep: true })
|
||||
|
||||
watch(() => props.tabType, (newVal) => {
|
||||
btnType.value = newVal
|
||||
console.log(newVal, 'tabType')
|
||||
switch (newVal) {
|
||||
case 'charge':
|
||||
btnNum.value = 3
|
||||
break
|
||||
case 'dispatch':
|
||||
btnNum.value = 3
|
||||
break
|
||||
case 'none':
|
||||
btnNum.value = 2
|
||||
break
|
||||
default:
|
||||
btnNum.value = 3
|
||||
break
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
||||
defineExpose({
|
||||
handleBtnConfig,
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -267,8 +404,11 @@ watch(() => props.data, (newVal) => {
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 车辆信息-按钮区域 -->
|
||||
<view class="button-area">
|
||||
<!-- 车辆信息-按钮区域-换电 -->
|
||||
<view
|
||||
v-if="btnType === 'charge'"
|
||||
class="button-area"
|
||||
>
|
||||
<uv-button
|
||||
:custom-style="btnCustomStyle2"
|
||||
text="车辆详情"
|
||||
@ -287,6 +427,32 @@ watch(() => props.data, (newVal) => {
|
||||
@click="completeChangeBattery"
|
||||
/>
|
||||
</view>
|
||||
<!-- 车辆信息-按钮区域-全部 -->
|
||||
<view
|
||||
v-if="btnType === 'none'"
|
||||
class="button-area"
|
||||
>
|
||||
<uv-button
|
||||
:custom-style="btnCustomStyle2"
|
||||
text="车辆详情"
|
||||
@click="handleDetail"
|
||||
/>
|
||||
<uv-button
|
||||
:custom-style="btnCustomStyle"
|
||||
type="primary"
|
||||
text="生成工单"
|
||||
@click="generateWorkOrder"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- ActionSheet 操作菜单 -->
|
||||
<uv-action-sheet
|
||||
ref="actionSheet"
|
||||
:actions="ActionSheetList"
|
||||
title="生成工单类型"
|
||||
:close-on-click-action="false"
|
||||
@select="ActionSheetSelect"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
||||
@ -42,6 +42,10 @@ const tablist = ref<any>([
|
||||
name: '维修',
|
||||
key: 'maintain',
|
||||
},
|
||||
{
|
||||
name: '全部',
|
||||
key: 'none',
|
||||
},
|
||||
])
|
||||
const bikeList = ref<any>([]) // 车辆列表
|
||||
const toolsType = ref<ToolsType>(tablist.value[0].key)// 工具类型
|
||||
@ -52,6 +56,7 @@ const carDetailsShow = reactive<any>({ // 车辆详情卡片配置
|
||||
show: false,
|
||||
key: tablist.value[0].key, // 记录工具类型
|
||||
})
|
||||
const carDetailsToolsRef = ref(null)
|
||||
|
||||
/**
|
||||
* 工单工具栏
|
||||
@ -89,6 +94,7 @@ const mapPolylines = ref([]) // 地图线
|
||||
function tabClick(item: any) {
|
||||
toolsType.value = item.key
|
||||
carDetailsShow.show = false
|
||||
carDetailsShow.key = item.key
|
||||
mapPolylines.value = []
|
||||
drawMapPoint(toolsType.value)
|
||||
}
|
||||
@ -130,6 +136,7 @@ function regionchange(e: any) {
|
||||
|
||||
// 获取车辆列表
|
||||
async function getEbikeList(regionId: string) {
|
||||
bikeList.value = []
|
||||
try {
|
||||
const res: any = await getEbikeListForWorkAPI(regionId)
|
||||
if (Array.isArray(res) && res.length > 0) {
|
||||
@ -149,10 +156,10 @@ async function getEbikeList(regionId: string) {
|
||||
|
||||
// 绘制点位信息
|
||||
function drawMapPoint(orderType: any) {
|
||||
mapMarkers.value = []
|
||||
if (!bikeList.value || bikeList.value.length === 0) {
|
||||
return
|
||||
}
|
||||
mapMarkers.value = []
|
||||
let list = []
|
||||
|
||||
// 换电
|
||||
@ -172,6 +179,10 @@ function drawMapPoint(orderType: any) {
|
||||
if (orderType === tablist.value[3].key) {
|
||||
list = bikeList.value.filter((item: any) => item.hasRepairOrder)
|
||||
}
|
||||
// 全部
|
||||
if (orderType === tablist.value[4].key) {
|
||||
list = bikeList.value
|
||||
}
|
||||
|
||||
// 绘制点位
|
||||
if (list.length > 0) {
|
||||
@ -236,12 +247,24 @@ async function handleMarkertap(e: any) {
|
||||
|
||||
// 从列表中查找对应车辆信息
|
||||
const item = mapMarkers.value.find(item => item.id === id)
|
||||
|
||||
try {
|
||||
const res: any = await getEbikeDetailForWorkAPI(item.id.toString())
|
||||
if (res) {
|
||||
carDetaile.value = res
|
||||
}
|
||||
|
||||
const car = bikeList.value.find(it => it.bikeCode === id.toString())
|
||||
if (car) {
|
||||
carDetailsToolsRef.value?.handleBtnConfig({
|
||||
hasInspectionOrder: car.hasInspectionOrder,
|
||||
hasChangeBatteryOrder: car.hasChangeBatteryOrder,
|
||||
hasDispatchOrder: car.hasDispatchOrder,
|
||||
hasRepairOrder: car.hasRepairOrder,
|
||||
})
|
||||
}
|
||||
|
||||
// 显示车辆详情
|
||||
carDetailsShow.key = toolsType.value
|
||||
toolsType.value = 'none'
|
||||
carDetailsShow.show = true
|
||||
@ -525,7 +548,6 @@ function chargeChange(res: any) {
|
||||
function changeDispatch(res: any) {
|
||||
const { seletType, data, sliderValue } = res
|
||||
const list = bikeList.value.filter((item: any) => item.hasDispatchOrder)
|
||||
console.log(res)
|
||||
|
||||
if (list.length <= 0) {
|
||||
return
|
||||
@ -676,6 +698,7 @@ async function handleRegion() {
|
||||
drawMapPolygons(selectRegionMiddle.value.regionId)
|
||||
drawMapPoint(toolsType.value)
|
||||
backRegion()
|
||||
console.log(mapMarkers.value)
|
||||
}
|
||||
function handleRegionClick(item: any) {
|
||||
selectRegionMiddle.value = item
|
||||
@ -786,6 +809,8 @@ onMounted(() => {
|
||||
<!-- 车辆详情 -->
|
||||
<carDetailsTools
|
||||
v-show="carDetailsShow.show"
|
||||
ref="carDetailsToolsRef"
|
||||
:tab-type="carDetailsShow.key"
|
||||
:data="carDetaile"
|
||||
@close="carDetailsClose"
|
||||
/>
|
||||
|
||||
@ -17,8 +17,8 @@ const TITLE_NAME = import.meta.env.VITE_APP_TITLE
|
||||
const showMm = ref(false)
|
||||
// 登录表单数据
|
||||
const formData = reactive({
|
||||
username: 'admin',
|
||||
password: '123456',
|
||||
username: '',
|
||||
password: '',
|
||||
})
|
||||
// 是否在登录
|
||||
const isLogin = ref(false)
|
||||
@ -29,6 +29,14 @@ const notifyRef = ref<any>(null)
|
||||
* 登录
|
||||
*/
|
||||
async function login() {
|
||||
if (formData.username.trim() === '') {
|
||||
notifyRef.value?.show({ safeAreaInsetTop: true, type: 'error', message: '请输入用户名' })
|
||||
return
|
||||
}
|
||||
if (formData.password.trim() === '') {
|
||||
notifyRef.value?.show({ safeAreaInsetTop: true, type: 'error', message: '请输入密码' })
|
||||
return
|
||||
}
|
||||
isLogin.value = true
|
||||
|
||||
try {
|
||||
|
||||
@ -43,7 +43,7 @@ function goDetail(type: number) {
|
||||
url = '/pages-sub/changebatteries/changebatteries'
|
||||
break
|
||||
case 3:
|
||||
url = ''
|
||||
url = '/pages-sub/warehouse/dispatch/dispatch'
|
||||
break
|
||||
case 4:
|
||||
url = '/pages-sub/work/inspectionWorkOrder/inspectionWorkOrder'
|
||||
|
||||
@ -280,7 +280,7 @@ export function drawPoint({
|
||||
option = {
|
||||
width: 35,
|
||||
height: 35,
|
||||
iconPath: '/static/images/markerG.png',
|
||||
iconPath: '/static/images/carIcon.png',
|
||||
},
|
||||
success,
|
||||
fail,
|
||||
@ -319,6 +319,18 @@ export function drawPoint({
|
||||
obj = setDispatchPoint(point, option)
|
||||
break
|
||||
}
|
||||
case 'maintain': {
|
||||
obj = repairPoint(point, option)
|
||||
break
|
||||
}
|
||||
case 'polling': {
|
||||
obj = inspectionPoint(point, option)
|
||||
break
|
||||
}
|
||||
case 'none': {
|
||||
obj = allCarPoint(point, option)
|
||||
break
|
||||
}
|
||||
default: {
|
||||
obj = commonPoint(point, option)
|
||||
break
|
||||
@ -414,6 +426,67 @@ export function setDispatchPoint(point: any, option: any) {
|
||||
return obj
|
||||
}
|
||||
|
||||
// 维修点位设置
|
||||
export function repairPoint(point: any, option: any) {
|
||||
const { bikeInfo } = point
|
||||
console.log(bikeInfo)
|
||||
|
||||
const obj = {
|
||||
id: Number(point.bikeCode),
|
||||
latitude: point.latitude,
|
||||
longitude: point.longitude,
|
||||
width: 43,
|
||||
height: 43,
|
||||
iconPath: '/static/images/markerG.png',
|
||||
label: {
|
||||
content: bikeInfo.content,
|
||||
anchorY: -32,
|
||||
anchorX: -12,
|
||||
fontSize: 9,
|
||||
color: '#0e82ff',
|
||||
},
|
||||
}
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
// 巡检点位设置
|
||||
export function inspectionPoint(point: any, option: any) {
|
||||
const { bikeInfo } = point
|
||||
console.log(bikeInfo)
|
||||
|
||||
const obj = {
|
||||
id: Number(point.bikeCode),
|
||||
latitude: point.latitude,
|
||||
longitude: point.longitude,
|
||||
width: 43,
|
||||
height: 43,
|
||||
iconPath: '/static/images/markerG.png',
|
||||
label: {
|
||||
content: bikeInfo.content,
|
||||
anchorY: -32,
|
||||
anchorX: -12,
|
||||
fontSize: 9,
|
||||
color: '#0e82ff',
|
||||
},
|
||||
}
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
// 所有车辆的点位
|
||||
export function allCarPoint(point: any, option: any) {
|
||||
const { bikeInfo } = point
|
||||
|
||||
const obj = {
|
||||
id: Number(point.bikeCode),
|
||||
latitude: point.latitude,
|
||||
longitude: point.longitude,
|
||||
...option,
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
||||
// 通用点位设置
|
||||
export function commonPoint(point: any, option: any) {
|
||||
return {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user